Merge pull request #5612 from wucm667/fix/issue-5611-antigravity-paid-tier-endpoint
fix(antigravity): route paid accounts to daily endpoint
This commit is contained in:
@@ -35,3 +35,10 @@ exceptions:
|
||||
mitigation: "Proxy configuration not user-controlled; upgrade when axios releases fix"
|
||||
expires_on: "2026-07-10"
|
||||
owner: "security@your-domain"
|
||||
- package: nanoid
|
||||
advisory: "GHSA-2v37-7h3g-55p8"
|
||||
severity: high
|
||||
reason: "Custom generator with size=0 not used; all nanoid calls use default size or positive values"
|
||||
mitigation: "No zero-size custom generators in codebase; upgrade when nanoid releases fix"
|
||||
expires_on: "2026-10-13"
|
||||
owner: "security@your-domain"
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user