feat: Implement model-specific headers configuration for Claude

This commit is contained in:
1808837298@qq.com
2025-02-28 16:47:31 +08:00
parent d306394f33
commit 45c56b5ded
5 changed files with 23 additions and 19 deletions

View File

@@ -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
} }

View File

@@ -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
} }

View File

@@ -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)
}
} }
} }
} }

View File

@@ -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);
} }

View File

@@ -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>