You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
gemini: 个人版 Code Assist 已停用该 OAuth 客户端(This client is no longer supported)——「+Gemini」授权成功后仍无法入池;附带 pollLogin 空指针 panic #167
Failed to sign in. Message: This client is no longer supported
for Gemini Code Assist for individuals. To continue using
Gemini, please migrate to the Antigravity suite of products:
https://antigravity.google
最终定论来自 Google 自己:This client is no longer supported for Gemini Code Assist for individuals,
官方要求迁移到 Antigravity。也就是说「复用 CLI 客户端 + authorization_code 换 refresh_token」
这条路线对个人版账号已经关闭,不是参数问题。
Activity
zrtzrt commentedon Oct 19, 2026
更正:根因不是 scope,是「旧 Gemini CLI 的 OAuth 客户端对个人用户已停用」
上一版 issue 里我把根因写成「
Scopes多带了cclog/experimentsandconfigs,导致 403」。补测之后确认:scope 只是先撞上的那堵墙,真正的墙在客户端层面,改 scope 也过不去。
现在的证据链
403 restricted_client+Unregistered scope(s): …/auth/cclogcclog是 Antigravity 的内部 scope,CLI 客户端没登记)This client is no longer supported for Gemini Code Assist for individualsopenid+cloud-platform,这个 client_id 对个人号也不再放行@google/antigravitynpm view @google/antigravity→ 404)agy)loadCodeAssist返回free-tier (Antigravity)也就是说:Google 认可的是 Antigravity 那一套 client_id + 授权流程,而不是旧 CLI 的 client_id。
WildWork 的 Gemini 渠道整套复制了旧 CLI 的 OAuth(
accounts.google.com/o/oauth2/v2/auth+ loopback 回调 +client_secret换码),所以在个人号上必然复现同一个错误,与代码质量无关。
为什么改 scope 不够
internal/gemini/constants.go的Scopes只是其中一环。把cclog/experimentsandconfigs去掉,授权页会前进到「选账号」,然后在登录后返回
no longer supported。两关的判据都在 Google 侧,且是按 client_id + 账号类型判的,客户端无法自行绕过。
顺便验证了一个反直觉的点
旧 CLI 的客户端是「installed app + 授权码」类型,不支持设备码流程;
所以「改成设备码登录」也不是替代方案(设备码只对特定 client 类型开放)。
建议的修复方向(按可行性排序)
1. 承认个人号走不通,把渠道拆成两条(推荐)
GEMINI_API_KEY),渠道凭据存 api_key 而不是 refresh_token;enterprise customers will maintain existing access,这半边是可用的。建议
login_gemini.Start先做一次loadCodeAssist预检(用当前凭据),拿到 tier 后按 tier 决定:free-tier/AI Pro直接返回可读错误,而不是等用户在浏览器里点完才看到英文报错。2. 如果要继续复用 Antigravity 的身份(技术上可行,但请先确认合规)
本次实测:Antigravity CLI 的 token 存在 macOS 钥匙串(
svce=gemini, acct=antigravity,auth_method=consumer,含refresh_token),用antigravity/4.3.0 (cmdc-pak)身份头调用https://daily-cloudcode-pa.googleapis.com/v1internal:loadCodeAssist返回 200 +currentTier: {id:"free-tier", name:"Antigravity"}。也就是说:数据面已经通了,缺的只是「把这份 token 喂进 WildWork」。
可行做法是照
internal/auth/load_gemini.go的字段,把 Antigravity 的 token 落成auths/gemini-<uid>.json。但这是复刻私有格式,Antigravity 刷新 token 时可能覆盖,需要明确的导入 UI + 失效提示,不能当成默认自动流程。
3. 若考虑走 Antigravity 官方 OAuth 申请新客户端
Antigravity 的 client(
884354919052-…)是 Web 类型:device/code返回invalid_client: Invalid client type,只能走 loopback / 授权码回调 + PKCE。这需要在 Google Cloud Console 给自己的项目申请一个 Desktop 客户端,
并把回调登记为
http://localhost:<port>/oauth-callback。风险:新客户端很可能同样拿不到 Code Assist 个人版资格(资格是按 client 白名单发的),
这条建议先拿测试账号验证再动手。
附加 bug(独立于上面的问题)
login poll panic: runtime error: invalid memory address or nil pointer dereferencepollLogin的defer读a.loginKind/a.loginStateFP/a.muLogin,而
finishLogin()(app.go:1834)在不持锁的情况下就能被另一条路径清空这些字段:StartLoginFor在flow.Start失败分支直接调finishLogin()(app.go:967-972),POST /api/login/start与/api/login/cancel并发进来时就会把「别人那一轮」的状态清空。建议把 kind/stateFP 作为参数捕获进
pollLogin,defer 只用局部值;或给 finishLogin 带代次校验。环境
com.rockswang.wild-work)@google/gemini-cli@0.64.0(按提示安装过,已验证)agy1.4.2(官方 install.sh),Google AI Pro 个人账号zrtzrt commentedon Oct 19, 2026
修复方案:照 OmniRoute 的做法,把 Gemini 渠道从「OAuth 换 refresh_token」改成「导入 Antigravity 身份(agy token)+ 走 v1internal 信封」
你说得对,API key 方案不成立:Gemini Code Assist for individuals 已经没有可用的 AI Studio 直连路径
(个人号只能走 Code Assist 的 Cloud Code 端点,而那边的准入是按 client 身份 发的)。
OmniRoute 在同样的政策变化下走的正是这条路,而且我在本机把它的协议逐字节复现成功了。
一、已经实测通过的最小调用(可直接抄)
本机 Antigravity CLI(
agy1.4.2)登录后,token 存在 macOS 钥匙串:security find-generic-password -a antigravity -w→go-keyring-base64:<json>,解出
{token:{access_token, refresh_token, expiry, token_type}, auth_method:"consumer", id_token}。用它直接打上游:
{ "project": "default-cli-project", "requestId": "agent/<epoch_ms>/<uuid>", "request": { "contents": [{ "role": "user", "parts": [{ "text": "Reply with exactly: PROXY_OK" }] }], "generationConfig": { "maxOutputTokens": 64 } }, "model": "gemini-3.8-flash-high", "userAgent": "antigravity", "requestType": "agent" }返回(实测):
要点:响应是被包了一层信封的 —— 真正的 Gemini 载荷在
response字段里,事件同时带
traceId/metadata。WildWork 现在的internal/gemini/sse.go如果按原生Gemini SSE 解析,会直接丢数据。这是需要改的第一处。
二、对应到 WildWork 的改动清单
1.
internal/auth/load_gemini.go:新增「从 Antigravity 导入」沿用现有
load_codearts.go/load_zcode.go的模式(扫描本机客户端凭据并导入),增加:security find-generic-password -a antigravity -w(服务名gemini),值形如
go-keyring-base64:<base64(json)>,解码后取token.access_token/refresh_token/expiry~/.gemini/antigravity-cli/(存在即说明 agy 已登录)~/.gemini/antigravity/auths/gemini-<uid>.json时额外存extra.auth_method = "consumer"(OAuth 刷新与 UA 都要用)extra.project = "default-cli-project"(或loadCodeAssist返回的cloudaicompanionProject)extra.ua_flavor = "cli"2.
internal/gemini/oauthclient.go:refresh 换 client现在的 refresh 用的是旧 Gemini CLI 的 client(
681255809395-…),对个人号已停用。改用 Antigravity 的 client(
agy二进制内置,共 3 枚,主用):refresh 请求头要带
User-Agent: antigravity/cli/<ver> (aidev_client; os_type=darwin; arch=arm64; auth_method=consumer)。3.
internal/gemini/envelope.go:请求要包信封当前实现是裸的
{"contents":[...]}。改成:{"project": "<project>", "requestId": "agent/<ms>/<hex>", "request": { ...原始 body... }, "model": "<upstreamModel>", "userAgent": "antigravity", "requestType": "agent"}project先用loadCodeAssist拿cloudaicompanionProject;为空时回落到default-cli-project(免费的 consumer 账号实测就是不返回 project,CLI 自己也是用这个兜底)
requestId每次请求新生成,格式agent/<epoch_ms>/<hex8>(OmniRoute 的generateAntigravityRequestId)request.sessionId:从账号 email 做 FNV-1a 64 位哈希,保证同一账号同一会话稳定4.
internal/gemini/sse.go:解信封每个
data:里的 JSON 形如{"response": {...}, "traceId": "...", "metadata": {}},要取
obj.response再当 Gemini 原生响应处理;traceId用于日志串联。5. 模型 ID
上游要带档位后缀,实测可用:
gemini-3.8-flash-highgemini-3.8-flash-mediumgemini-3.8-flash-lowgemini-pro-agent(上游 id 不同,需别名)agy models可实时列出当前账号的可用清单(gemini-3.8-flash-{high,medium,low}、claude-sonnet-4-6、claude-opus-4-6-thinking、gpt-oss-120b-medium),建议渠道模型表改成「从
fetchAvailableModels探测 + 静态兜底」。6. 失败诊断(很重要)
OmniRoute 的排查文档里记了个关键坑:agy/Cloud Code 读的是账号后端的 Country Association 字段,
不是当前出口 IP。本机实测也印证了:
换 IP 后立刻成功。所以登录/调用失败时要区分:
User location is not supported→ 账号地区关联问题,引导用户去https://policies.google.com/country-association-form 改地区
This client is no longer supported→ 还在用旧 CLI 的 client,没切到 Antigravity 身份not eligible for Antigravity→ 账号没有 Code Assist 资格三、最小可行顺序(建议 PR 拆成 3 个提交)
load_gemini.go支持从钥匙串 /~/.gemini/antigravity-cli导入 token(不动网络层)envelope.go+sse.go改成project/requestId/request结构与response解包oauthclient.go换成 Antigravity client + UA,refresh 后回写第 1 步单独就能让用户「先用 agy 登录 → 面板导入」,第 2、3 步才是完整的产品化。
四、已验证的本机事实(供你复现)
agy --version→ 1.4.2;agy -p 'Reply with exactly: AGY_OK'→AGY_OKloadCodeAssist(携带 agy token + Antigravity UA)→ 200,currentTier: {id:"free-tier", name:"Antigravity"}streamGenerateContent请求 → SSE 正常返回response.candidatesdevice/code→invalid_client: Invalid client type(确认它不支持设备码,也不是可替代路径)rockswang commentedon Oct 19, 2026
你要是验证成功的话,建议直接PR,我手上没有gemini账号
rockswang commentedon Oct 19, 2026
短期处置已落地(master
4252d48)感谢极高质量的下钻取证——两堵墙的分层(scope → client 停用)和
device/code的invalid_client佐证都采纳了。本轮落地的部分:
Scopes剔除cclog/experimentsandconfigs(internal/gemini/constants.go),消除第一堵墙403 restricted_client。已确认 Cloud Code 端点鉴权只认 access_token 不复核 scope 清单,运行时行为不变。回归:TestScopesNoInternalScopes。exchange失败时按信封字段挂geminiErrorHint引导——命中 "no longer supported" 时直说「Google 已停用该 OAuth 客户端对个人版 Code Assist 的授权,属上游政策变更,非本工具或账号问题」,避免用户按官方报错装 CLI 后撞同一堵墙。回归:TestGeminiErrorHint。暂不落地的部分(同意你的最小可行顺序,但想先解决一个前置):
streamGenerateContent全链路可通,这块证据充分;但gemini-pro-agent别名映射、fetchAvailableModels探测、以及地区关联(Country Association)的用户引导都还没有回归护栏,不想在 2.9.x 的 hotfix 线里夹带。已作为独立方向记录,预计在 2.10 线做(到时大概率直接基于你列的三步拆 PR,欢迎认领)。另外你附带的 pollLogin panic 问题正是 #168 —— 根因(pending 态 done 为 nil 仍被调用)已由 PR #169 修复(你的 #171 与它同根因同修法,感谢撤回并留下生产 A/B 数据,对 review 很有帮助)。
fix(app): pollLogin 三态分派修正——pending 态误调 nil done,v2.9.2 全渠道登录 2s 必静默死亡(…
fix(gemini): scope 剔除 Cloud Code 内部项 + OAuth 错误附可行动引导(issue #167 短期处置)
release: 版本统一为 v2.9.3——RELEASES 三节(原 2.9.3/2.9.4/2.9.5 未发版草稿)合并为一节
rockswang commentedon Oct 19, 2026
短期处置(scope 收紧 + 错误引导)随 v2.9.3 发布(tag 已打,CI 产物已出)。
Antigravity 通道(agy token 导入 / 信封改造 / 身份切换)作为独立方向规划在 2.10 线,取证链路保留在本 issue 供届时直接引用。先关闭本 issue——个人版用户当前请以错误文案里的引导为准(上游政策变更,非本工具/账号问题);有 Antigravity 集成诉求时欢迎在此 issue 或新 issue 继续跟进。
fix(gemini): 切换至 Antigravity OAuth 协议与 PKCE 授权流 (fix rockswang#167)
fix(gemini): 收紧 OAuth state 校验与规范化模型动态拉取能力 (fix rockswang#167, R122)
fix(gemini): 切换至 Antigravity OAuth 协议与 PKCE 授权流 (fix rockswang#167)
fix(gemini): 收紧 OAuth state 校验与规范化模型动态拉取能力 (fix rockswang#167, R122)
fix(gemini): 切换至 Antigravity OAuth 协议与 PKCE 授权流 (fix rockswang#167)
fix(gemini): 收紧 OAuth state 校验与规范化模型动态拉取能力 (fix rockswang#167, R122)