diff --git a/backend/acct_test b/backend/acct_test new file mode 100755 index 00000000..0fcfef7e Binary files /dev/null and b/backend/acct_test differ diff --git a/backend/cmd/acct_test/main.go b/backend/cmd/acct_test/main.go new file mode 100644 index 00000000..46f187a8 --- /dev/null +++ b/backend/cmd/acct_test/main.go @@ -0,0 +1,191 @@ +// acct_test: 逐一测试所有 antigravity 账号的 v1internal:streamGenerateContent 连通性。 +// 用法: go run ./cmd/acct_test/ +package main + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io" + "net" + "net/http" + "time" + + "golang.org/x/net/proxy" +) + +const ( + upstreamBase = "https://cloudcode-pa.googleapis.com" + proxyAddr = "93.127.131.98:8760" + proxyUser = "gostuser" + proxyPass = "fastapipwd" + testModel = "gemini-3.1-pro-high" +) + +type acct struct { + id int + name string + token string + projectID string +} + +var accounts = []acct{ + {1, "bagotmirlande@gmail.com", "ya29.a0Aa7MYiptYjNXNYtMi1F_5bz1Msj_LfmJ46aUt6jgqokrs-jvbxH-OU9zzR_W8L_CSjJI2HwtUyWr33ayguQYveZWZWprv9YE4vQK1A72qYFIkl5mpxmr6WICzH6_nh7wLNGZRDxDMT_IIZt6G4oIusys1ivvPxoDJ5ZDT6gArPDX0kGclPgskqUkutgxU2_TZH1zMTNwRF5u5QaCgYKAcYSARUSFQHGX2Mi18umfQ3Z3zIYmvIQCfC49Q0213", "temporal-shoreline-98wb7"}, + {2, "elizabetperry991@gmail.com", "ya29.a0Aa7MYip1Y3FfFNEN0uxTHZPRqrSCsjbtfGCKIOnmd7jwBmkrRuuUka3JSJc3iQcs3XedICbwhuOwmwJEzPP3ruKSI11dRlWmCQ06bk9PXln8UmOrk65xGkHooAweHSgEmXKM3X1vxwktedsQrHQ95z5co_m7OuU-UVWsN_EVDxg6D1sGCLlc1d86W4rNnd-kM5IB2oO-e4RcyAaCgYKAR0SARISFQHGX2MiEy2JcvSQqpPX72OLmQUz7g0213", "global-bounty-k471v"}, + {3, "hennessyheeyoung@gmail.com", "ya29.a0Aa7MYionWnJ-Z-cRcAsrvmQOVLp03gCI-XtUFSsH6IIXv7qJlYfxs-CE2ssnT284KbEqq1yk5gixXIUEvKGy63u29PC8R8ApjJSF8gDR_HhxRKyIyAM5lWf9YB5TEVS_piRuMIbgmtOmW4sng6y4JW2fXcvitD4-_Ow8GTtw5kLIxvazYRuuyq5Qt58paRYAWmqXTgsyo2uyTgaCgYKAQ4SARQSFQHGX2MiibjlUmiRut0i1STzUcEOqw0213", "tangential-blueprint-xj5r3"}, + {4, "jafarkabiru59@gmail.com", "ya29.a0Aa7MYioDhcEKDFVfOrLUVYgGigGGo8CRiNwOs3yqF697kls5ocTCI-N2obqTUPyQS82T0_jTVuYLOKHKwXJmRCyXCJ9dxlIjRU-DoVSGd1ua_Z6MAsUf2KpMGdsfl3F92gLhynqVPWJcnQMJTfu9NMYJ73otZZzvylaA9AjA1AfoqLnAGhtYMt6hlr_4UkXF4DCHMeo72PYpkgaCgYKAeASARMSFQHGX2Milb94bDmYBlmtRHt5YHx1Aw0213", "boreal-brand-sktcc"}, + {5, "kunaomerti8776@gmail.com", "ya29.a0Aa7MYiqzpCUX3oqAd69xX7v5Df1AQKR7qhzxREWMvZgzCAMo879gow0U_zFOcznaOQ__2T20qt2ltXBBCXsL3rKKrt7yEW0__aVYhgS34_dTCRKysr2ogcLc4C2Dx_ycNHOBEjRkitsy_T3WwRSM0TtT0PRat7lhbQOZ8H2ZNVMYgUcziIVZbPdiiWbHP7uDUTga7-WoRHGbKwaCgYKAcASARMSFQHGX2Mi4_yEKDWmFok6rTqOhr7grg0213", "affable-unity-nmqqm"}, + {6, "luc56052@gmail.com", "ya29.a0Aa7MYirL_JN877SvNr7vTBd1nJ0tSykr3GSxQJqptaBLB58CwxKUnNPyByJcPbGKWyCm7ES8Hbw0AW7RtP22wIYympJouZ-ya3boZeWDOMWoW24Bl2vxmyFuDsKDvHaAVTPt9Sm2SbPr4Mht7pSBjUN3qz0YwOZp7lUb75D8plHTFivioBIo-mQJyQByEofksrwwjbDE5W5gowaCgYKAbESARcSFQHGX2MiIGQ4nZiiWc0eMD1458F9NA0213", "double-tranquility-m6tnh"}, + {7, "luisejennifer995@gmail.com", "ya29.a0Aa7MYiqis3oevgBMhPYb_nCW0zQbVC-HWwzjfJRIq-RpCGZWgv36q0CdnKVkS2ZlKD8id1OsijBd1nV9I--kDHiKrNEFBCDyrMmM3TsT24xtGk6SojDEEnjfML-yqfI2ob5U-YIXlcjaw1U3BncSXCSVjg4bSYlVrdB0nTThD2VvQX6T2S7Mf7GAZbYcyYTs3fsyxXBeriFOaAaCgYKAXsSARUSFQHGX2Mijhee21x2YECnX15KosF7rg0213", "synthetic-rookery-s8wb7"}, + {8, "mackenzieomdharry13377@gmail.com", "ya29.a0Aa7MYiqmsb7bnednJdwy_zRgz8kTR8ppbuG9USjDV6CHmK-rDog-3Y0AmnKaH5-At_uAQS6bL9rnEdNdeKv56YhsOFOP9Zsyo80D3rZbQ_URVK2rtwiZ5gjTBPf-7NeF_AqVHBXL_6omA-pSLzIWHWUiTHHjA3owWQWL1lHAskanibbM8XacrFo4y3bf2Wal_Oi4p24iGGhywgaCgYKAZYSARMSFQHGX2MimYoDE6JARRwNn7v-rMuOig0213", "lyrical-ability-ndt91"}, + {10, "michellegelais@gmail.com", "ya29.a0Aa7MYip90q7iTwDG3nNIC05hh_3s9ulvvKGh-pYA6u7idqr_vAcusoLZ6DyNvli_p7zQ-EavLcFj--fcBM9L8F7mD-C9rXka-i8gOdDwa-Z-n4MtkyCCX8OdlTPkAYydtnaA_ZrId60rBNo3M_iGFGARudKmkppNDJeUeuFpcL43dcgHnZy0P4iWEojuDj6XR0fedyi6rCG9SwaCgYKAcYSARESFQHGX2MiDCLNsMJFulFkVvS9-_15uw0213", "compelling-envoy-4471v"}, + {11, "minikenestella555@gmail.com", "ya29.a0Aa7MYipr3BSyuVhHjtgKJNE7bothl6XZCJSuUW-shFpvby52fivz7KR7-r4K3RlljAANds1rPmHdoziF9wav9xExZTHTCadeyJjzFXl2ZfII3_xaKOqeMI4n2jj7ALyR2a2nj8do6xf5l2_JcaNkxCbSnhu3VqVjhfFXJLelOLnC40UwO9mhxl5jPGFsobOF3stP9dJlP4OUjwaCgYKAUoSARASFQHGX2MiEM_cTLBqbEtSxI9Mfui_QA0213", "coastal-mechanism-3vzc3"}, + {12, "moonasher346@gmail.com", "ya29.a0Aa7MYioUYF95Ir7OBdEKCpK7RscOlLqcKOg3kWFmvPvXeiE7vwRGN9JRoPTf9ToKE8ETpcJZN12fXRxPcuI1sHT5vV4QIe5yzO8318fjKI8yJmWYdgKf2dI_GB2I_8sD_xMZpMg5fsNgVd_C3lFgWZY_SYXCYTAjMCcT4axoRNU8lpdtKj9_qRppMS7lBa3MZcGHqP9hzWWJTgaCgYKARsSARMSFQHGX2Mi9qZ17An8NlHcrqJtYXet-g0213", "model-zenith-nz4g3"}, + {13, "orvasoriadari32127@gmail.com", "ya29.a0Aa7MYioqCrp3Ub6iUggQ_EO0TDXlZvsq_ncJyP3GHbhnXknKgLzNvHTgx0QWzocqg2pCMoqj2yOLvSJKF65aeh8BbHdu6fHiJqbnYCz-8z43zmzd2rx_abgN7MI9kTJFGc_U2IuZod1ZcYoKNcOSk_N3oLACwwocbjDiiiFvdUIDfbPrOUdmmUcQnEXevXjmjEvLDqwX0oj2vQaCgYKASsSARUSFQHGX2MibWygVzmONcTNiabE4rbeig0213", "upheld-ellipse-hz4g3"}, + {14, "rebbecakamiya@gmail.com", "ya29.a0Aa7MYirJjBHlmeeBZrsURFDEliG_PxGW8_RIvrr3CBPkP7nQYd-EgjiquHLDvH_fYk3f8yit2WDzAoZJJg1MOaRsYXyvdmz2SSoPPf9JVJIon93dKdB5yCqF5d8bATdQZuqXg_I662-c3SH4vnPHkeD7EjbmR71ny3mIFNEPhPUAxGXCy-M4Tj1CuyvMe_n4hsCAt8VpThq4rwaCgYKAeYSARASFQHGX2MiK8urv_VJlTESI4qiawAyVg0213", "inductive-gravity-z43ch"}, + {15, "roccoesther630@gmail.com", "ya29.a0Aa7MYiocXy-GX00GqdlWt59SM2ZsL5T0yJvRDT9IchncV0frVJWb0dmsW-Jum89uKiSsfwKZi3sEye7gOqnZaAehoKiE8Y6c0IbnElYMvXsaaY6sGx-b8ljd-BSnzuikunwQeCuF-gRIbP9FIu7iBmegJjgS0u89qX226gR2bp05U7UaIqQ_oCG172ogfhy6nazPtRAn1YdMWAaCgYKAQ8SARcSFQHGX2MiR-EhRgm9-VFpOwioPgJYQg0213", "emerald-terminus-nw106"}, +} + +func buildTestBody(projectID string) []byte { + inner := map[string]any{ + "contents": []map[string]any{ + { + "role": "user", + "parts": []map[string]any{ + {"text": "Reply with exactly one word: OK"}, + }, + }, + }, + "systemInstruction": map[string]any{ + "parts": []map[string]any{ + {"text": "You are a helpful assistant."}, + }, + }, + "generationConfig": map[string]any{ + "maxOutputTokens": 10, + }, + } + wrapped := map[string]any{ + "project": projectID, + "requestId": "acct-test-" + testModel, + "userAgent": "antigravity", + "requestType": "agent", + "model": testModel, + "request": inner, + } + b, _ := json.Marshal(wrapped) + return b +} + +func extractText(body []byte) string { + var text string + for _, line := range bytes.Split(body, []byte("\n")) { + line = bytes.TrimSpace(line) + if bytes.HasPrefix(line, []byte("data:")) { + line = bytes.TrimSpace(bytes.TrimPrefix(line, []byte("data:"))) + } + if len(line) == 0 || line[0] != '{' { + continue + } + var d map[string]any + if json.Unmarshal(line, &d) != nil { + continue + } + // unwrap v1internal response field if present + if resp, ok := d["response"]; ok { + if rm, ok := resp.(map[string]any); ok { + d = rm + } + } + // candidates[0].content.parts[0].text + cands, _ := d["candidates"].([]any) + if len(cands) == 0 { + continue + } + cand, _ := cands[0].(map[string]any) + content, _ := cand["content"].(map[string]any) + parts, _ := content["parts"].([]any) + for _, p := range parts { + pm, _ := p.(map[string]any) + if t, ok := pm["text"].(string); ok { + text += t + } + } + } + return text +} + +func makeHTTPClient() (*http.Client, error) { + dialer, err := proxy.SOCKS5("tcp", proxyAddr, + &proxy.Auth{User: proxyUser, Password: proxyPass}, + proxy.Direct, + ) + if err != nil { + return nil, err + } + transport := &http.Transport{ + DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) { + return dialer.Dial(network, addr) + }, + } + return &http.Client{Timeout: 45 * time.Second, Transport: transport}, nil +} + +func testAccount(client *http.Client, a acct) { + body := buildTestBody(a.projectID) + apiURL := upstreamBase + "/v1internal:streamGenerateContent?alt=sse" + req, err := http.NewRequestWithContext(context.Background(), http.MethodPost, apiURL, bytes.NewReader(body)) + if err != nil { + fmt.Printf("[%2d] %-40s FAIL build_req: %v\n", a.id, a.name, err) + return + } + req.Header.Set("Authorization", "Bearer "+a.token) + req.Header.Set("Content-Type", "application/json") + req.Header.Set("User-Agent", "antigravity/1.107.0 darwin/arm64") + + t0 := time.Now() + resp, err := client.Do(req) + if err != nil { + fmt.Printf("[%2d] %-40s FAIL %dms http: %v\n", a.id, a.name, time.Since(t0).Milliseconds(), err) + return + } + defer resp.Body.Close() + + respBody, _ := io.ReadAll(resp.Body) + elapsed := time.Since(t0).Milliseconds() + + if resp.StatusCode >= 400 { + snippet := string(respBody) + if len(snippet) > 200 { + snippet = snippet[:200] + "..." + } + fmt.Printf("[%2d] %-40s FAIL %dms HTTP %d %s\n", a.id, a.name, elapsed, resp.StatusCode, snippet) + return + } + + fmt.Printf("[%2d] %-40s OK %dms\n%s\n\n", a.id, a.name, elapsed, string(respBody)) +} + +func main() { + fmt.Printf("Testing %d accounts → %s via SOCKS5 %s\n\n", len(accounts), upstreamBase, proxyAddr) + + client, err := makeHTTPClient() + if err != nil { + fmt.Printf("FATAL: socks5 dialer: %v\n", err) + return + } + + ok, fail := 0, 0 + for _, a := range accounts { + before := ok + testAccount(client, a) + if ok == before { + fail++ + } else { + ok++ + } + time.Sleep(300 * time.Millisecond) + } + fmt.Printf("\nDone — OK: %d FAIL: %d\n", ok, fail) +} diff --git a/backend/internal/domain/constants.go b/backend/internal/domain/constants.go index a57f7067..f3b451f9 100644 --- a/backend/internal/domain/constants.go +++ b/backend/internal/domain/constants.go @@ -71,7 +71,7 @@ const ( // 与前端 useModelWhitelist.ts 中的 antigravityDefaultMappings 保持一致 var DefaultAntigravityModelMapping = map[string]string{ // Claude 白名单 - "claude-opus-4-7": "claude-opus-4-7", // 官方模型 + "claude-opus-4-7": "claude-opus-4-6", // 官方模型 "claude-opus-4-6-thinking": "claude-opus-4-6-thinking", // 官方模型 "claude-opus-4-6": "claude-opus-4-6-thinking", // 简称映射 "claude-opus-4-5-thinking": "claude-opus-4-6-thinking", // 迁移旧模型