fix(antigravity): route paid accounts to daily endpoint

This commit is contained in:
wucm667
2026-08-14 02:40:18 +08:00
parent fbfdcef818
commit e7a3c1202e
2 changed files with 63 additions and 13 deletions
@@ -48,17 +48,14 @@ type antigravityRetryLoopResult struct {
// resolveAntigravityForwardBaseURL 解析转发用 base URL。
//
// 默认使用生产端点 cloudcode-pa.googleapis.com(antigravity.BaseURLs 的首个地址,
// 与账号 OAuth 登录/测试连接所用的 antigravity.BaseURL 一致)。
// 显式环境变量优先。未配置时,LoadCodeAssist 返回 paidTier 的付费账号使用
// daily 端点,其他账号继续使用生产端点,避免免费账号的 OAuth token 出现 401。
//
// 历史上这里改用 ForwardBaseURLs()(把 daily/sandbox 排到首位)并默认取首个地址,
// 导致网关把带生产 OAuth token 的请求发到 daily-cloudcode-pa.sandbox.googleapis.com,
// 上游拒绝 → 账号被 401「Invalid bearer token」/502 打入临时不可调度且无法恢复
// (见 #3611 / #2962)。后台「测试连接」用的是生产端点,所以「测试成功但网关 401」。
//
// daily/sandbox 端点仅供内部联调,需显式设置
// GATEWAY_ANTIGRAVITY_FORWARD_BASE_URL=daily(或 sandbox)才启用。
func resolveAntigravityForwardBaseURL() string {
func resolveAntigravityForwardBaseURL(account *Account) string {
baseURLs := antigravity.BaseURLs
if len(baseURLs) == 0 {
return ""
@@ -67,9 +64,28 @@ func resolveAntigravityForwardBaseURL() string {
if (mode == "daily" || mode == "sandbox") && len(baseURLs) > 1 {
return baseURLs[1]
}
if mode == "" && accountHasAntigravityPaidTier(account) && len(baseURLs) > 1 {
return baseURLs[1]
}
return baseURLs[0]
}
func accountHasAntigravityPaidTier(account *Account) bool {
if account == nil || account.Credentials == nil {
return false
}
planType, ok := account.Credentials["plan_type"].(string)
if !ok {
return false
}
switch strings.ToLower(strings.TrimSpace(planType)) {
case "pro", "ultra":
return true
default:
return false
}
}
// smartRetryAction 智能重试的处理结果
type smartRetryAction int
@@ -488,7 +504,7 @@ func (s *AntigravityGatewayService) antigravityRetryLoop(p antigravityRetryLoopP
}
}
baseURL := resolveAntigravityForwardBaseURL()
baseURL := resolveAntigravityForwardBaseURL(p.account)
if baseURL == "" {
return nil, errors.New("no antigravity forward base url configured")
}
@@ -1009,9 +1009,7 @@ func TestIsAntigravityAccountSwitchError(t *testing.T) {
}
}
func TestResolveAntigravityForwardBaseURL_DefaultDaily(t *testing.T) {
t.Setenv(antigravityForwardBaseURLEnv, "")
func TestResolveAntigravityForwardBaseURL(t *testing.T) {
oldBaseURLs := append([]string(nil), antigravity.BaseURLs...)
defer func() {
antigravity.BaseURLs = oldBaseURLs
@@ -1019,10 +1017,46 @@ func TestResolveAntigravityForwardBaseURL_DefaultDaily(t *testing.T) {
prodURL := "https://prod.test"
dailyURL := "https://daily.test"
antigravity.BaseURLs = []string{dailyURL, prodURL}
antigravity.BaseURLs = []string{prodURL, dailyURL}
resolved := resolveAntigravityForwardBaseURL()
require.Equal(t, dailyURL, resolved)
tests := []struct {
name string
env string
account *Account
want string
}{
{
name: "pro defaults to daily", account: &Account{Credentials: map[string]any{"plan_type": " Pro "}},
want: dailyURL,
},
{
name: "ultra defaults to daily", account: &Account{Credentials: map[string]any{"plan_type": "ULTRA"}},
want: dailyURL,
},
{name: "free defaults to prod", account: &Account{Credentials: map[string]any{"plan_type": "free"}}, want: prodURL},
{name: "abnormal defaults to prod", account: &Account{Credentials: map[string]any{"plan_type": "Abnormal"}}, want: prodURL},
{name: "unknown defaults to prod", account: &Account{Credentials: map[string]any{"plan_type": "enterprise"}}, want: prodURL},
{name: "malformed defaults to prod", account: &Account{Credentials: map[string]any{"plan_type": map[string]any{"name": "pro"}}}, want: prodURL},
{name: "missing defaults to prod", account: &Account{Credentials: map[string]any{}}, want: prodURL},
{name: "nil account defaults to prod", account: nil, want: prodURL},
{
name: "daily override wins for free tier", env: " daily ",
account: &Account{Credentials: map[string]any{"plan_type": "free"}},
want: dailyURL,
},
{
name: "prod override wins for paid tier", env: " PROD ",
account: &Account{Credentials: map[string]any{"plan_type": "pro"}},
want: prodURL,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
t.Setenv(antigravityForwardBaseURLEnv, tt.env)
require.Equal(t, tt.want, resolveAntigravityForwardBaseURL(tt.account))
})
}
}
func TestAntigravityAccountSwitchError_Error(t *testing.T) {