mirror of
https://github.com/Wei-Shaw/sub2api.git
synced 2026-09-24 16:05:44 +08:00
fix: normalize antigravity gemini 3.1 pro routing
This commit is contained in:
@@ -68,6 +68,9 @@ const (
|
||||
SubscriptionStatusSuspended = "suspended"
|
||||
)
|
||||
|
||||
// AntigravityGemini31ProAgentModel is the upstream route for Gemini 3.1 Pro High.
|
||||
const AntigravityGemini31ProAgentModel = "gemini-pro-agent"
|
||||
|
||||
// DefaultAntigravityModelMapping 是 Antigravity 平台的默认模型映射
|
||||
// 当账号未配置 model_mapping 时使用此默认值
|
||||
// 与前端 useModelWhitelist.ts 中的 antigravityDefaultMappings 保持一致
|
||||
@@ -103,10 +106,12 @@ var DefaultAntigravityModelMapping = map[string]string{
|
||||
"gemini-3-flash-preview": "gemini-3-flash",
|
||||
"gemini-3-pro-preview": "gemini-3-pro-high",
|
||||
// Gemini 3.1 白名单
|
||||
"gemini-3.1-pro-high": "gemini-3.1-pro-high",
|
||||
"gemini-3.1-pro-low": "gemini-3.1-pro-low",
|
||||
AntigravityGemini31ProAgentModel: AntigravityGemini31ProAgentModel,
|
||||
"gemini-3.1-pro": AntigravityGemini31ProAgentModel,
|
||||
"gemini-3.1-pro-high": AntigravityGemini31ProAgentModel,
|
||||
"gemini-3.1-pro-low": "gemini-3.1-pro-low",
|
||||
// Gemini 3.1 preview 映射
|
||||
"gemini-3.1-pro-preview": "gemini-3.1-pro-high",
|
||||
"gemini-3.1-pro-preview": AntigravityGemini31ProAgentModel,
|
||||
// Gemini 3.1 image 白名单
|
||||
"gemini-3.1-flash-image": "gemini-3.1-flash-image",
|
||||
// Gemini 3.1 image preview 映射
|
||||
|
||||
@@ -43,6 +43,28 @@ func TestDefaultAntigravityModelMapping_ContainsNewClaudeModels(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestDefaultAntigravityModelMapping_Gemini31ProAliases(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
cases := map[string]string{
|
||||
AntigravityGemini31ProAgentModel: AntigravityGemini31ProAgentModel,
|
||||
"gemini-3.1-pro": AntigravityGemini31ProAgentModel,
|
||||
"gemini-3.1-pro-high": AntigravityGemini31ProAgentModel,
|
||||
"gemini-3.1-pro-preview": AntigravityGemini31ProAgentModel,
|
||||
"gemini-3.1-pro-low": "gemini-3.1-pro-low",
|
||||
}
|
||||
|
||||
for from, want := range cases {
|
||||
got, ok := DefaultAntigravityModelMapping[from]
|
||||
if !ok {
|
||||
t.Fatalf("expected mapping for %q to exist", from)
|
||||
}
|
||||
if got != want {
|
||||
t.Fatalf("unexpected mapping for %q: got %q want %q", from, got, want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestDefaultBedrockModelMapping_ContainsNewClaudeModels(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
|
||||
@@ -580,6 +580,7 @@ func (a *Account) resolveModelMapping(rawMapping map[string]any) map[string]stri
|
||||
"gemini-3.1-pro-high",
|
||||
"gemini-3.1-pro-low",
|
||||
})
|
||||
applyAntigravityGemini31ProAliases(result)
|
||||
}
|
||||
return result
|
||||
}
|
||||
@@ -646,6 +647,61 @@ func ensureAntigravityDefaultPassthroughs(mapping map[string]string, models []st
|
||||
}
|
||||
}
|
||||
|
||||
func applyAntigravityGemini31ProAliases(mapping map[string]string) {
|
||||
target := strings.TrimSpace(mapping[domain.AntigravityGemini31ProAgentModel])
|
||||
if target == "" {
|
||||
return
|
||||
}
|
||||
|
||||
aliases := []struct {
|
||||
model string
|
||||
legacyTargets map[string]struct{}
|
||||
}{
|
||||
{
|
||||
model: "gemini-3.1-pro",
|
||||
legacyTargets: map[string]struct{}{
|
||||
"gemini-3.1-pro": {},
|
||||
},
|
||||
},
|
||||
{
|
||||
model: "gemini-3.1-pro-high",
|
||||
legacyTargets: map[string]struct{}{
|
||||
"gemini-3.1-pro-high": {},
|
||||
},
|
||||
},
|
||||
{
|
||||
model: "gemini-3.1-pro-preview",
|
||||
legacyTargets: map[string]struct{}{
|
||||
"gemini-3.1-pro-preview": {},
|
||||
"gemini-3.1-pro-high": {},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, alias := range aliases {
|
||||
current, exists := mapping[alias.model]
|
||||
if exists {
|
||||
if _, legacy := alias.legacyTargets[current]; legacy {
|
||||
mapping[alias.model] = target
|
||||
}
|
||||
continue
|
||||
}
|
||||
if mappingHasWildcardForModel(mapping, alias.model) {
|
||||
continue
|
||||
}
|
||||
mapping[alias.model] = target
|
||||
}
|
||||
}
|
||||
|
||||
func mappingHasWildcardForModel(mapping map[string]string, model string) bool {
|
||||
for pattern := range mapping {
|
||||
if matchWildcard(pattern, model) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func normalizeRequestedModelForLookup(platform, requestedModel string) string {
|
||||
trimmed := strings.TrimSpace(requestedModel)
|
||||
if trimmed == "" {
|
||||
|
||||
@@ -4,6 +4,8 @@ package service
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/Wei-Shaw/sub2api/internal/domain"
|
||||
)
|
||||
|
||||
func TestMatchWildcard(t *testing.T) {
|
||||
@@ -320,6 +322,86 @@ func TestAccountGetMappedModel(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestAccountGetModelMapping_AntigravityNormalizesGemini31ProAliases(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
account := &Account{
|
||||
Platform: PlatformAntigravity,
|
||||
Credentials: map[string]any{
|
||||
"model_mapping": map[string]any{
|
||||
domain.AntigravityGemini31ProAgentModel: domain.AntigravityGemini31ProAgentModel,
|
||||
"gemini-3.1-pro-high": "gemini-3.1-pro-high",
|
||||
"gemini-3.1-pro-preview": "gemini-3.1-pro-high",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
mapping := account.GetModelMapping()
|
||||
|
||||
if got := mapping["gemini-3.1-pro"]; got != domain.AntigravityGemini31ProAgentModel {
|
||||
t.Fatalf("expected gemini-3.1-pro to map to %q, got %q", domain.AntigravityGemini31ProAgentModel, got)
|
||||
}
|
||||
if got := mapping["gemini-3.1-pro-high"]; got != domain.AntigravityGemini31ProAgentModel {
|
||||
t.Fatalf("expected gemini-3.1-pro-high to map to %q, got %q", domain.AntigravityGemini31ProAgentModel, got)
|
||||
}
|
||||
if got := mapping["gemini-3.1-pro-preview"]; got != domain.AntigravityGemini31ProAgentModel {
|
||||
t.Fatalf("expected gemini-3.1-pro-preview to map to %q, got %q", domain.AntigravityGemini31ProAgentModel, got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAccountGetModelMapping_AntigravityPreservesGemini31ProOverrides(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
account := &Account{
|
||||
Platform: PlatformAntigravity,
|
||||
Credentials: map[string]any{
|
||||
"model_mapping": map[string]any{
|
||||
domain.AntigravityGemini31ProAgentModel: domain.AntigravityGemini31ProAgentModel,
|
||||
"gemini-3.1-pro-high": "custom-high",
|
||||
"gemini-3.1-pro-preview": "custom-preview",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
mapping := account.GetModelMapping()
|
||||
|
||||
if got := mapping["gemini-3.1-pro-high"]; got != "custom-high" {
|
||||
t.Fatalf("expected gemini-3.1-pro-high override to be preserved, got %q", got)
|
||||
}
|
||||
if got := mapping["gemini-3.1-pro-preview"]; got != "custom-preview" {
|
||||
t.Fatalf("expected gemini-3.1-pro-preview override to be preserved, got %q", got)
|
||||
}
|
||||
if got := mapping["gemini-3.1-pro"]; got != domain.AntigravityGemini31ProAgentModel {
|
||||
t.Fatalf("expected gemini-3.1-pro alias to default to %q, got %q", domain.AntigravityGemini31ProAgentModel, got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAccountGetModelMapping_AntigravityGemini31ProAliasesRespectWildcard(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
account := &Account{
|
||||
Platform: PlatformAntigravity,
|
||||
Credentials: map[string]any{
|
||||
"model_mapping": map[string]any{
|
||||
domain.AntigravityGemini31ProAgentModel: domain.AntigravityGemini31ProAgentModel,
|
||||
"gemini-3.1-*": "custom-wildcard",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
mapping := account.GetModelMapping()
|
||||
|
||||
if got := mapping["gemini-3.1-pro"]; got != "" {
|
||||
t.Fatalf("expected gemini-3.1-pro exact alias to stay unset when wildcard exists, got %q", got)
|
||||
}
|
||||
if got := mapping["gemini-3.1-pro-high"]; got != "" {
|
||||
t.Fatalf("expected gemini-3.1-pro-high exact alias to stay unset when wildcard exists, got %q", got)
|
||||
}
|
||||
if got := mapping["gemini-3.1-pro-preview"]; got != "" {
|
||||
t.Fatalf("expected gemini-3.1-pro-preview exact alias to stay unset when wildcard exists, got %q", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAccountResolveMappedModel(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
|
||||
Reference in New Issue
Block a user