feat: Implement model-specific headers configuration for Claude
This commit is contained in:
@@ -39,7 +39,7 @@ func (a *Adaptor) GetRequestURL(info *relaycommon.RelayInfo) (string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (a *Adaptor) SetupRequestHeader(c *gin.Context, req *http.Header, info *relaycommon.RelayInfo) error {
|
func (a *Adaptor) SetupRequestHeader(c *gin.Context, req *http.Header, info *relaycommon.RelayInfo) error {
|
||||||
model_setting.GetClaudeSettings().WriteHeaders(req)
|
model_setting.GetClaudeSettings().WriteHeaders(info.OriginModelName, req)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ func (a *Adaptor) SetupRequestHeader(c *gin.Context, req *http.Header, info *rel
|
|||||||
anthropicVersion = "2023-06-01"
|
anthropicVersion = "2023-06-01"
|
||||||
}
|
}
|
||||||
req.Set("anthropic-version", anthropicVersion)
|
req.Set("anthropic-version", anthropicVersion)
|
||||||
model_setting.GetClaudeSettings().WriteHeaders(req)
|
model_setting.GetClaudeSettings().WriteHeaders(info.OriginModelName, req)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,15 +13,15 @@ import (
|
|||||||
|
|
||||||
// ClaudeSettings 定义Claude模型的配置
|
// ClaudeSettings 定义Claude模型的配置
|
||||||
type ClaudeSettings struct {
|
type ClaudeSettings struct {
|
||||||
HeadersSettings map[string][]string `json:"headers_settings"`
|
HeadersSettings map[string]map[string][]string `json:"model_headers_settings"`
|
||||||
ThinkingAdapterEnabled bool `json:"thinking_adapter_enabled"`
|
ThinkingAdapterEnabled bool `json:"thinking_adapter_enabled"`
|
||||||
ThinkingAdapterMaxTokens int `json:"thinking_adapter_max_tokens"`
|
ThinkingAdapterMaxTokens int `json:"thinking_adapter_max_tokens"`
|
||||||
ThinkingAdapterBudgetTokensPercentage float64 `json:"thinking_adapter_budget_tokens_percentage"`
|
ThinkingAdapterBudgetTokensPercentage float64 `json:"thinking_adapter_budget_tokens_percentage"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// 默认配置
|
// 默认配置
|
||||||
var defaultClaudeSettings = ClaudeSettings{
|
var defaultClaudeSettings = ClaudeSettings{
|
||||||
HeadersSettings: map[string][]string{},
|
HeadersSettings: map[string]map[string][]string{},
|
||||||
ThinkingAdapterEnabled: true,
|
ThinkingAdapterEnabled: true,
|
||||||
ThinkingAdapterMaxTokens: 8192,
|
ThinkingAdapterMaxTokens: 8192,
|
||||||
ThinkingAdapterBudgetTokensPercentage: 0.8,
|
ThinkingAdapterBudgetTokensPercentage: 0.8,
|
||||||
@@ -40,11 +40,13 @@ func GetClaudeSettings() *ClaudeSettings {
|
|||||||
return &claudeSettings
|
return &claudeSettings
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *ClaudeSettings) WriteHeaders(headers *http.Header) {
|
func (c *ClaudeSettings) WriteHeaders(originModel string, httpHeader *http.Header) {
|
||||||
for key, values := range c.HeadersSettings {
|
if headers, ok := c.HeadersSettings[originModel]; ok {
|
||||||
headers.Del(key)
|
for headerKey, headerValues := range headers {
|
||||||
for _, value := range values {
|
httpHeader.Del(headerKey)
|
||||||
headers.Add(key, value)
|
for _, headerValue := range headerValues {
|
||||||
|
httpHeader.Add(headerKey, headerValue)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ const ModelSetting = () => {
|
|||||||
let [inputs, setInputs] = useState({
|
let [inputs, setInputs] = useState({
|
||||||
'gemini.safety_settings': '',
|
'gemini.safety_settings': '',
|
||||||
'gemini.version_settings': '',
|
'gemini.version_settings': '',
|
||||||
'claude.headers_settings': '',
|
'claude.model_headers_settings': '',
|
||||||
'claude.thinking_adapter_enabled': true,
|
'claude.thinking_adapter_enabled': true,
|
||||||
'claude.thinking_adapter_max_tokens': 8192,
|
'claude.thinking_adapter_max_tokens': 8192,
|
||||||
'claude.thinking_adapter_budget_tokens_percentage': 0.8,
|
'claude.thinking_adapter_budget_tokens_percentage': 0.8,
|
||||||
@@ -30,7 +30,7 @@ const ModelSetting = () => {
|
|||||||
if (
|
if (
|
||||||
item.key === 'gemini.safety_settings' ||
|
item.key === 'gemini.safety_settings' ||
|
||||||
item.key === 'gemini.version_settings' ||
|
item.key === 'gemini.version_settings' ||
|
||||||
item.key === 'claude.headers_settings'
|
item.key === 'claude.model_headers_settings'
|
||||||
) {
|
) {
|
||||||
item.value = JSON.stringify(JSON.parse(item.value), null, 2);
|
item.value = JSON.stringify(JSON.parse(item.value), null, 2);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,9 @@ import { useTranslation } from 'react-i18next';
|
|||||||
import Text from '@douyinfe/semi-ui/lib/es/typography/text';
|
import Text from '@douyinfe/semi-ui/lib/es/typography/text';
|
||||||
|
|
||||||
const CLAUDE_HEADER = {
|
const CLAUDE_HEADER = {
|
||||||
'anthropic-beta': ['output-128k-2025-02-19', 'token-efficient-tools-2025-02-19'],
|
'claude-3-7-sonnet-20250219-thinking': {
|
||||||
|
'anthropic-beta': ['output-128k-2025-02-19', 'token-efficient-tools-2025-02-19'],
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function SettingClaudeModel(props) {
|
export default function SettingClaudeModel(props) {
|
||||||
@@ -19,7 +21,7 @@ export default function SettingClaudeModel(props) {
|
|||||||
|
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
const [inputs, setInputs] = useState({
|
const [inputs, setInputs] = useState({
|
||||||
'claude.headers_settings': '',
|
'claude.model_headers_settings': '',
|
||||||
'claude.thinking_adapter_enabled': true,
|
'claude.thinking_adapter_enabled': true,
|
||||||
'claude.thinking_adapter_max_tokens': 8192,
|
'claude.thinking_adapter_max_tokens': 8192,
|
||||||
'claude.thinking_adapter_budget_tokens_percentage': 0.8,
|
'claude.thinking_adapter_budget_tokens_percentage': 0.8,
|
||||||
@@ -82,9 +84,9 @@ export default function SettingClaudeModel(props) {
|
|||||||
<Col span={16}>
|
<Col span={16}>
|
||||||
<Form.TextArea
|
<Form.TextArea
|
||||||
label={t('Claude请求头覆盖')}
|
label={t('Claude请求头覆盖')}
|
||||||
field={'claude.headers_settings'}
|
field={'claude.model_headers_settings'}
|
||||||
placeholder={t('为一个 JSON 文本,例如:') + '\n' + JSON.stringify(CLAUDE_HEADER, null, 2)}
|
placeholder={t('为一个 JSON 文本,例如:') + '\n' + JSON.stringify(CLAUDE_HEADER, null, 2)}
|
||||||
extraText={t('示例') + JSON.stringify(CLAUDE_HEADER, null, 2)}
|
extraText={t('示例') + '\n' + JSON.stringify(CLAUDE_HEADER, null, 2)}
|
||||||
autosize={{ minRows: 6, maxRows: 12 }}
|
autosize={{ minRows: 6, maxRows: 12 }}
|
||||||
trigger='blur'
|
trigger='blur'
|
||||||
stopValidateWithError
|
stopValidateWithError
|
||||||
@@ -94,7 +96,7 @@ export default function SettingClaudeModel(props) {
|
|||||||
message: t('不是合法的 JSON 字符串')
|
message: t('不是合法的 JSON 字符串')
|
||||||
}
|
}
|
||||||
]}
|
]}
|
||||||
onChange={(value) => setInputs({ ...inputs, 'claude.headers_settings': value })}
|
onChange={(value) => setInputs({ ...inputs, 'claude.model_headers_settings': value })}
|
||||||
/>
|
/>
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
|
|||||||
Reference in New Issue
Block a user