Bläddra i källkod

fix(claude): send adaptive thinking type

Use adaptive thinking for Claude requests and rewrite passthrough bodies that still contain the legacy enabled type.

Co-Authored-By: Codex <noreply@anthropic.com>
master
fengsilin 1 vecka sedan
förälder
incheckning
481b43cfc5
2 ändrade filer med 24 tillägg och 7 borttagningar
  1. +5
    -5
      relay/channel/claude/relay-claude.go
  2. +19
    -2
      relay/claude_handler.go

+ 5
- 5
relay/channel/claude/relay-claude.go Visa fil

@@ -163,7 +163,7 @@ func RequestOpenAI2ClaudeMessage(c *gin.Context, textRequest dto.GeneralOpenAIRe

// BudgetTokens 为 max_tokens 的 80%
claudeRequest.Thinking = &dto.Thinking{
Type: "enabled",
Type: "adaptive",
BudgetTokens: common.GetPointer[int](int(float64(claudeRequest.MaxTokens) * model_setting.GetClaudeSettings().ThinkingAdapterBudgetTokensPercentage)),
}
// TODO: 临时处理
@@ -179,17 +179,17 @@ func RequestOpenAI2ClaudeMessage(c *gin.Context, textRequest dto.GeneralOpenAIRe
switch textRequest.ReasoningEffort {
case "low":
claudeRequest.Thinking = &dto.Thinking{
Type: "enabled",
Type: "adaptive",
BudgetTokens: common.GetPointer[int](1280),
}
case "medium":
claudeRequest.Thinking = &dto.Thinking{
Type: "enabled",
Type: "adaptive",
BudgetTokens: common.GetPointer[int](2048),
}
case "high":
claudeRequest.Thinking = &dto.Thinking{
Type: "enabled",
Type: "adaptive",
BudgetTokens: common.GetPointer[int](4096),
}
}
@@ -205,7 +205,7 @@ func RequestOpenAI2ClaudeMessage(c *gin.Context, textRequest dto.GeneralOpenAIRe
budgetTokens := reasoning.MaxTokens
if budgetTokens > 0 {
claudeRequest.Thinking = &dto.Thinking{
Type: "enabled",
Type: "adaptive",
BudgetTokens: &budgetTokens,
}
}


+ 19
- 2
relay/claude_handler.go Visa fil

@@ -71,7 +71,7 @@ func ClaudeHelper(c *gin.Context, info *relaycommon.RelayInfo) (newAPIError *typ

// BudgetTokens 为 max_tokens 的 80%
request.Thinking = &dto.Thinking{
Type: "enabled",
Type: "adaptive",
BudgetTokens: common.GetPointer[int](int(float64(request.MaxTokens) * model_setting.GetClaudeSettings().ThinkingAdapterBudgetTokensPercentage)),
}
// TODO: 临时处理
@@ -127,13 +127,30 @@ func ClaudeHelper(c *gin.Context, info *relaycommon.RelayInfo) (newAPIError *typ
return nil
}

// Fix thinking.type for models that only support "adaptive" (e.g. claude-sonnet-4-6, claude-opus-4-6).
// Anthropic returns 400 if thinking.type="enabled" is sent to these models.
if request.Thinking != nil && request.Thinking.Type == "enabled" {
request.Thinking.Type = "adaptive"
}

var requestBody io.Reader
if model_setting.GetGlobalSettings().PassThroughRequestEnabled || info.ChannelSetting.PassThroughBodyEnabled {
storage, err := common.GetBodyStorage(c)
if err != nil {
return types.NewErrorWithStatusCode(err, types.ErrorCodeReadRequestBodyFailed, http.StatusBadRequest, types.ErrOptionWithSkipRetry())
}
requestBody = common.ReaderOnly(storage)
// In passthrough mode, fix thinking.type in the raw JSON body.
if request.Thinking != nil && request.Thinking.Type == "adaptive" {
bodyBytes, readErr := io.ReadAll(storage)
if readErr == nil {
bodyBytes = bytes.Replace(bodyBytes, []byte(`"thinking":{"type":"enabled"`), []byte(`"thinking":{"type":"adaptive"`), 1)
requestBody = bytes.NewBuffer(bodyBytes)
} else {
requestBody = bytes.NewBuffer(nil)
}
} else {
requestBody = common.ReaderOnly(storage)
}
} else {
convertedRequest, err := adaptor.ConvertClaudeRequest(c, info, request)
if err != nil {


Laddar…
Avbryt
Spara