mirror of
https://github.com/Wei-Shaw/sub2api.git
synced 2026-10-07 16:48:45 +08:00
fix: strip max_tokens from Anthropic count tokens
This commit is contained in:
@@ -582,7 +582,8 @@ func TestGatewayService_AnthropicAPIKeyPassthrough_CountTokensFiltersGenerationF
|
||||
require.Equal(t, "sys", gjson.GetBytes(sentBody, "system.0.text").String())
|
||||
require.Equal(t, "hello", gjson.GetBytes(sentBody, "messages.0.content").String())
|
||||
require.Equal(t, "tool", gjson.GetBytes(sentBody, "tools.0.name").String())
|
||||
require.Equal(t, int64(1024), gjson.GetBytes(sentBody, "max_tokens").Int())
|
||||
require.False(t, gjson.GetBytes(sentBody, "max_tokens").Exists(),
|
||||
"count_tokens 请求不得携带生成参数 max_tokens")
|
||||
require.Equal(t, "enabled", gjson.GetBytes(sentBody, "thinking.type").String())
|
||||
}
|
||||
|
||||
|
||||
@@ -596,6 +596,35 @@ func TestBuildCountTokensRequest_OAuthMimicHaiku_PreservesContextManagementEndTo
|
||||
"count_tokens 路径必须含 token-counting beta")
|
||||
}
|
||||
|
||||
func TestBuildCountTokensRequest_OAuthMimic_DropsInjectedMaxTokens(t *testing.T) {
|
||||
// OAuth mimicry injects max_tokens=128000 for normal messages requests. It is
|
||||
// invalid for Anthropic's count_tokens endpoint and must be stripped on wire.
|
||||
gin.SetMode(gin.TestMode)
|
||||
rec := httptest.NewRecorder()
|
||||
c, _ := gin.CreateTestContext(rec)
|
||||
c.Request = httptest.NewRequest(http.MethodPost, "/v1/messages/count_tokens", nil)
|
||||
|
||||
account := &Account{ID: 413, Platform: PlatformAnthropic, Type: AccountTypeOAuth,
|
||||
Credentials: map[string]any{"access_token": "oauth-tok"},
|
||||
Status: StatusActive, Schedulable: true,
|
||||
}
|
||||
normalized, _ := normalizeClaudeOAuthRequestBody(
|
||||
[]byte(`{"model":"claude-sonnet-4-5","messages":[]}`),
|
||||
"claude-sonnet-4-5", claudeOAuthNormalizeOptions{},
|
||||
)
|
||||
require.Equal(t, int64(128000), gjson.GetBytes(normalized, "max_tokens").Int(),
|
||||
"precondition: OAuth mimicry injects the Claude Code default")
|
||||
|
||||
svc := &GatewayService{cfg: &config.Config{}}
|
||||
req, _, err := svc.buildCountTokensRequest(
|
||||
context.Background(), c, account, normalized,
|
||||
"oauth-tok", "oauth", "claude-sonnet-4-5", true,
|
||||
)
|
||||
require.NoError(t, err)
|
||||
require.False(t, gjson.GetBytes(readUpstreamBodyForTest(t, req), "max_tokens").Exists(),
|
||||
"count_tokens wire body must not contain max_tokens")
|
||||
}
|
||||
|
||||
func TestBuildCountTokensRequest_APIKeyHaiku_StripsContextManagementEndToEnd(t *testing.T) {
|
||||
// API-key + haiku + 客户端 header 不带 context-management beta → final beta 不含 → strip
|
||||
gin.SetMode(gin.TestMode)
|
||||
|
||||
@@ -584,6 +584,10 @@ func sanitizeCountTokensRequestBody(body []byte) []byte {
|
||||
"stream",
|
||||
"stop_sequences",
|
||||
"stop",
|
||||
// Anthropic's /v1/messages/count_tokens accepts request-input fields only.
|
||||
// max_tokens is a generation parameter; OAuth mimicry may inject it to
|
||||
// resemble Claude Code messages requests, so it must never reach this endpoint.
|
||||
"max_tokens",
|
||||
} {
|
||||
if gjson.GetBytes(out, path).Exists() {
|
||||
if next, ok := deleteJSONPathBytes(out, path); ok {
|
||||
|
||||
Reference in New Issue
Block a user