From b256f911418626ab084af30a8079f4dbda49af5d Mon Sep 17 00:00:00 2001 From: feitianbubu Date: Thu, 11 Jun 2026 20:16:00 +0800 Subject: [PATCH] fix(gateway): intercept max_tokens=1 haiku probes for streaming requests too --- backend/internal/handler/gateway_handler.go | 21 +++++++++---------- .../handler/gateway_handler_intercept_test.go | 6 +++--- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/backend/internal/handler/gateway_handler.go b/backend/internal/handler/gateway_handler.go index d0e2c6b730..59e578bac3 100644 --- a/backend/internal/handler/gateway_handler.go +++ b/backend/internal/handler/gateway_handler.go @@ -169,7 +169,7 @@ func (h *GatewayHandler) Messages(c *gin.Context) { // 设置 max_tokens=1 + haiku 探测请求标识到 context 中 // 必须在 SetClaudeCodeClientContext 之前设置,因为 ClaudeCodeValidator 需要读取此标识进行绕过判断 - if isMaxTokensOneHaikuRequest(reqModel, parsedReq.MaxTokens, reqStream) { + if isMaxTokensOneHaikuRequest(reqModel, parsedReq.MaxTokens) { ctx := service.WithIsMaxTokensOneHaikuRequest(c.Request.Context(), true, h.metadataBridgeEnabled()) c.Request = c.Request.WithContext(ctx) } @@ -360,7 +360,7 @@ func (h *GatewayHandler) Messages(c *gin.Context) { // 检查请求拦截(预热请求、SUGGESTION MODE等) if account.IsInterceptWarmupEnabled() { - interceptType := detectInterceptType(body, reqModel, parsedReq.MaxTokens, reqStream, isClaudeCodeClient) + interceptType := detectInterceptType(body, reqModel, parsedReq.MaxTokens, isClaudeCodeClient) if interceptType != InterceptTypeNone { if selection.Acquired && selection.ReleaseFunc != nil { selection.ReleaseFunc() @@ -638,7 +638,7 @@ func (h *GatewayHandler) Messages(c *gin.Context) { // 检查请求拦截(预热请求、SUGGESTION MODE等) if account.IsInterceptWarmupEnabled() { - interceptType := detectInterceptType(body, reqModel, parsedReq.MaxTokens, reqStream, isClaudeCodeClient) + interceptType := detectInterceptType(body, reqModel, parsedReq.MaxTokens, isClaudeCodeClient) if interceptType != InterceptTypeNone { if selection.Acquired && selection.ReleaseFunc != nil { selection.ReleaseFunc() @@ -1824,10 +1824,10 @@ func isHaikuModel(model string) bool { } // isMaxTokensOneHaikuRequest 检查是否为 max_tokens=1 + haiku 模型的探测请求 -// 这类请求用于 Claude Code 验证 API 连通性 -// 条件:max_tokens == 1 且 model 包含 "haiku" 且非流式请求 -func isMaxTokensOneHaikuRequest(model string, maxTokens int, isStream bool) bool { - return maxTokens == 1 && isHaikuModel(model) && !isStream +// 这类请求用于 Claude Code 验证 API 连通性(流式/非流式均会出现,如 cc-switch v3.9.0 起的健康检查探测为流式) +// 条件:max_tokens == 1 且 model 包含 "haiku" +func isMaxTokensOneHaikuRequest(model string, maxTokens int) bool { + return maxTokens == 1 && isHaikuModel(model) } // detectInterceptType 检测请求是否需要拦截,返回拦截类型 @@ -1835,11 +1835,10 @@ func isMaxTokensOneHaikuRequest(model string, maxTokens int, isStream bool) bool // - body: 请求体字节 // - model: 请求的模型名称 // - maxTokens: max_tokens 值 -// - isStream: 是否为流式请求 // - isClaudeCodeClient: 是否已通过 Claude Code 客户端校验 -func detectInterceptType(body []byte, model string, maxTokens int, isStream bool, isClaudeCodeClient bool) InterceptType { - // 优先检查 max_tokens=1 + haiku 探测请求(仅非流式) - if isClaudeCodeClient && isMaxTokensOneHaikuRequest(model, maxTokens, isStream) { +func detectInterceptType(body []byte, model string, maxTokens int, isClaudeCodeClient bool) InterceptType { + // 优先检查 max_tokens=1 + haiku 探测请求(流式/非流式均适用) + if isClaudeCodeClient && isMaxTokensOneHaikuRequest(model, maxTokens) { return InterceptTypeMaxTokensOneHaiku } diff --git a/backend/internal/handler/gateway_handler_intercept_test.go b/backend/internal/handler/gateway_handler_intercept_test.go index 9e7d77a1dd..c51935299f 100644 --- a/backend/internal/handler/gateway_handler_intercept_test.go +++ b/backend/internal/handler/gateway_handler_intercept_test.go @@ -14,10 +14,10 @@ import ( func TestDetectInterceptType_MaxTokensOneHaikuRequiresClaudeCodeClient(t *testing.T) { body := []byte(`{"messages":[{"role":"user","content":[{"type":"text","text":"hello"}]}]}`) - notClaudeCode := detectInterceptType(body, "claude-haiku-4-5", 1, false, false) + notClaudeCode := detectInterceptType(body, "claude-haiku-4-5", 1, false) require.Equal(t, InterceptTypeNone, notClaudeCode) - isClaudeCode := detectInterceptType(body, "claude-haiku-4-5", 1, false, true) + isClaudeCode := detectInterceptType(body, "claude-haiku-4-5", 1, true) require.Equal(t, InterceptTypeMaxTokensOneHaiku, isClaudeCode) } @@ -30,7 +30,7 @@ func TestDetectInterceptType_SuggestionModeUnaffected(t *testing.T) { "system":[] }`) - got := detectInterceptType(body, "claude-sonnet-4-5", 256, false, false) + got := detectInterceptType(body, "claude-sonnet-4-5", 256, false) require.Equal(t, InterceptTypeSuggestionMode, got) }