mirror of
https://github.com/Wei-Shaw/sub2api.git
synced 2026-10-14 12:02:27 +08:00
Merge pull request #5920 from wucm667/fix/issue-5884-antigravity-sonnet46
fix(antigravity): define Sonnet 4.5 to 4.6 compatibility routing
This commit is contained in:
@@ -105,11 +105,11 @@ var DefaultAntigravityModelMapping = map[string]string{
|
||||
"claude-opus-4-6": "claude-opus-4-6-thinking", // 简称映射
|
||||
"claude-opus-4-5-thinking": "claude-opus-4-6-thinking", // 迁移旧模型
|
||||
"claude-sonnet-4-6": "claude-sonnet-4-6",
|
||||
"claude-sonnet-4-5": "claude-sonnet-4-5",
|
||||
"claude-sonnet-4-5-thinking": "claude-sonnet-4-5-thinking",
|
||||
"claude-sonnet-4-5": "claude-sonnet-4-5", // 显式 canonical 选择透传
|
||||
"claude-sonnet-4-5-thinking": "claude-sonnet-4-6", // 迁移旧兼容别名
|
||||
// Claude 详细版本 ID 映射
|
||||
"claude-opus-4-5-20251101": "claude-opus-4-6-thinking", // 迁移旧模型
|
||||
"claude-sonnet-4-5-20250929": "claude-sonnet-4-5",
|
||||
"claude-sonnet-4-5-20250929": "claude-sonnet-4-6", // 迁移旧模型
|
||||
// Claude Haiku → Sonnet(无 Haiku 支持)
|
||||
"claude-haiku-4-5": "claude-sonnet-4-6",
|
||||
"claude-haiku-4-5-20251001": "claude-sonnet-4-6",
|
||||
|
||||
@@ -43,6 +43,21 @@ func TestDefaultAntigravityModelMapping_ContainsNewClaudeModels(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestDefaultAntigravityModelMapping_PreservesExplicitSonnet45AndMigratesLegacyAliases(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
cases := map[string]string{
|
||||
"claude-sonnet-4-5": "claude-sonnet-4-5",
|
||||
"claude-sonnet-4-5-thinking": "claude-sonnet-4-6",
|
||||
"claude-sonnet-4-5-20250929": "claude-sonnet-4-6",
|
||||
}
|
||||
for model, want := range cases {
|
||||
if got := DefaultAntigravityModelMapping[model]; got != want {
|
||||
t.Fatalf("expected model %q to map to %q, got %q", model, want, got)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestDefaultAntigravityModelMapping_Gemini31ProAliases(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
|
||||
@@ -43,8 +43,9 @@ import (
|
||||
var sseDataPrefix = regexp.MustCompile(`^data:\s*`)
|
||||
|
||||
const (
|
||||
testClaudeAPIURL = "https://api.anthropic.com/v1/messages?beta=true"
|
||||
chatgptCodexAPIURL = "https://chatgpt.com/backend-api/codex/responses"
|
||||
testClaudeAPIURL = "https://api.anthropic.com/v1/messages?beta=true"
|
||||
chatgptCodexAPIURL = "https://chatgpt.com/backend-api/codex/responses"
|
||||
defaultAntigravityTestModel = "claude-sonnet-4-6"
|
||||
)
|
||||
|
||||
// TestEvent represents a SSE event for account testing
|
||||
@@ -2311,11 +2312,7 @@ func (s *AccountTestService) routeAntigravityTest(c *gin.Context, account *Accou
|
||||
func (s *AccountTestService) testAntigravityAccountConnection(c *gin.Context, account *Account, modelID string) error {
|
||||
ctx := c.Request.Context()
|
||||
|
||||
// 默认模型:Claude 使用 claude-sonnet-4-5,Gemini 使用 gemini-3-pro-preview
|
||||
testModelID := modelID
|
||||
if testModelID == "" {
|
||||
testModelID = "claude-sonnet-4-5"
|
||||
}
|
||||
testModelID := antigravityConnectionTestModel(modelID)
|
||||
|
||||
if s.antigravityGatewayService == nil {
|
||||
return s.sendErrorAndEnd(c, "Antigravity gateway service not configured")
|
||||
@@ -2346,6 +2343,13 @@ func (s *AccountTestService) testAntigravityAccountConnection(c *gin.Context, ac
|
||||
return nil
|
||||
}
|
||||
|
||||
func antigravityConnectionTestModel(modelID string) string {
|
||||
if modelID == "" {
|
||||
return defaultAntigravityTestModel
|
||||
}
|
||||
return modelID
|
||||
}
|
||||
|
||||
// buildGeminiAPIKeyRequest builds request for Gemini API Key accounts
|
||||
func (s *AccountTestService) buildGeminiAPIKeyRequest(ctx context.Context, account *Account, modelID string, payload []byte) (*http.Request, error) {
|
||||
apiKey := account.GetCredential("api_key")
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
//go:build unit
|
||||
|
||||
package service
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestAntigravityConnectionTestModel(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
require.Equal(t, "claude-sonnet-4-6", antigravityConnectionTestModel(""))
|
||||
require.Equal(t, "gemini-3.1-pro-preview", antigravityConnectionTestModel("gemini-3.1-pro-preview"))
|
||||
}
|
||||
@@ -69,10 +69,10 @@ func TestAntigravityGatewayService_GetMappedModel(t *testing.T) {
|
||||
expected: "claude-sonnet-4-6",
|
||||
},
|
||||
{
|
||||
name: "默认映射 - claude-sonnet-4-5-20250929 → claude-sonnet-4-5",
|
||||
name: "默认映射 - claude-sonnet-4-5-20250929 → claude-sonnet-4-6",
|
||||
requestedModel: "claude-sonnet-4-5-20250929",
|
||||
accountMapping: nil,
|
||||
expected: "claude-sonnet-4-5",
|
||||
expected: "claude-sonnet-4-6",
|
||||
},
|
||||
|
||||
// 3. 默认映射中的透传(映射到自己)
|
||||
@@ -89,7 +89,7 @@ func TestAntigravityGatewayService_GetMappedModel(t *testing.T) {
|
||||
expected: "claude-sonnet-4-6",
|
||||
},
|
||||
{
|
||||
name: "默认映射透传 - claude-sonnet-4-5",
|
||||
name: "显式 canonical 选择 - claude-sonnet-4-5 透传",
|
||||
requestedModel: "claude-sonnet-4-5",
|
||||
accountMapping: nil,
|
||||
expected: "claude-sonnet-4-5",
|
||||
@@ -113,10 +113,19 @@ func TestAntigravityGatewayService_GetMappedModel(t *testing.T) {
|
||||
expected: "claude-opus-4-6-thinking",
|
||||
},
|
||||
{
|
||||
name: "默认映射透传 - claude-sonnet-4-5-thinking",
|
||||
name: "默认映射 - claude-sonnet-4-5-thinking → claude-sonnet-4-6",
|
||||
requestedModel: "claude-sonnet-4-5-thinking",
|
||||
accountMapping: nil,
|
||||
expected: "claude-sonnet-4-5-thinking",
|
||||
expected: "claude-sonnet-4-6",
|
||||
},
|
||||
{
|
||||
name: "账户显式目标只映射一步 - custom-sonnet → claude-sonnet-4-5",
|
||||
requestedModel: "custom-sonnet",
|
||||
accountMapping: map[string]string{
|
||||
"custom-sonnet": "claude-sonnet-4-5",
|
||||
"claude-sonnet-4-5": "claude-sonnet-4-6",
|
||||
},
|
||||
expected: "claude-sonnet-4-5",
|
||||
},
|
||||
{
|
||||
name: "默认映射透传 - gemini-2.5-flash",
|
||||
|
||||
@@ -844,17 +844,28 @@ func TestSetAntigravityModelRateLimits_GeminiWritesFamilyScope(t *testing.T) {
|
||||
require.Equal(t, antigravityGeminiModelRateLimitKey, repo.modelRateLimitCalls[1].modelKey)
|
||||
}
|
||||
|
||||
func TestSetAntigravityModelRateLimits_ClaudeDoesNotWriteGeminiScope(t *testing.T) {
|
||||
func TestSetAntigravityModelRateLimits_DoesNotDoubleMapCustomChain(t *testing.T) {
|
||||
repo := &stubAntigravityAccountRepo{}
|
||||
svc := &AntigravityGatewayService{}
|
||||
account := &Account{ID: 790, Platform: PlatformAntigravity}
|
||||
account := &Account{
|
||||
ID: 790,
|
||||
Platform: PlatformAntigravity,
|
||||
Credentials: map[string]any{
|
||||
"model_mapping": map[string]any{
|
||||
"custom-sonnet": "claude-sonnet-4-5",
|
||||
"claude-sonnet-4-5": "claude-sonnet-4-6",
|
||||
},
|
||||
},
|
||||
}
|
||||
resetAt := time.Now().Add(30 * time.Second)
|
||||
canonicalModel := resolveFinalAntigravityModelKey(context.Background(), account, "custom-sonnet")
|
||||
require.Equal(t, "claude-sonnet-4-5", canonicalModel)
|
||||
|
||||
success := svc.setAntigravityModelRateLimits(
|
||||
context.Background(),
|
||||
repo,
|
||||
account,
|
||||
"claude-sonnet-4-5",
|
||||
canonicalModel,
|
||||
"[test]",
|
||||
429,
|
||||
resetAt,
|
||||
@@ -866,6 +877,33 @@ func TestSetAntigravityModelRateLimits_ClaudeDoesNotWriteGeminiScope(t *testing.
|
||||
require.Equal(t, "claude-sonnet-4-5", repo.modelRateLimitCalls[0].modelKey)
|
||||
}
|
||||
|
||||
func TestSetModelRateLimitAndClearSession_UsesUpstreamReportedModelMetadata(t *testing.T) {
|
||||
repo := &stubAntigravityAccountRepo{}
|
||||
svc := &AntigravityGatewayService{accountRepo: repo}
|
||||
account := &Account{
|
||||
ID: 791,
|
||||
Platform: PlatformAntigravity,
|
||||
Credentials: map[string]any{
|
||||
"model_mapping": map[string]any{
|
||||
"claude-sonnet-4-5": "claude-sonnet-4-6",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
svc.setModelRateLimitAndClearSession(&handleModelRateLimitParams{
|
||||
ctx: context.Background(),
|
||||
prefix: "[test]",
|
||||
account: account,
|
||||
statusCode: 429,
|
||||
}, &antigravitySmartRetryInfo{
|
||||
RetryDelay: 30 * time.Second,
|
||||
ModelName: "claude-sonnet-4-5",
|
||||
})
|
||||
|
||||
require.Len(t, repo.modelRateLimitCalls, 1)
|
||||
require.Equal(t, "claude-sonnet-4-5", repo.modelRateLimitCalls[0].modelKey)
|
||||
}
|
||||
|
||||
func TestAntigravityRetryLoop_PreCheck_SwitchesWhenRateLimited(t *testing.T) {
|
||||
upstream := &recordingOKUpstream{}
|
||||
account := &Account{
|
||||
|
||||
Reference in New Issue
Block a user