@eddyskywalker/dsh-chatgpt-subscription 0.8.5 → 0.9.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. package/CHANGELOG.md +44 -0
  2. package/README.md +94 -38
  3. package/lib/client.js +2126 -1693
  4. package/lib/client.js.map +1 -1
  5. package/lib/index.js +7935 -2956
  6. package/lib/types/client/claude/ClaudeComposerQuota.d.ts +33 -0
  7. package/lib/types/client/claude/ClaudeComposerQuota.d.ts.map +1 -0
  8. package/lib/types/client/{zhipu/ZhipuSection.d.ts → claude/ClaudeSection.d.ts} +2 -2
  9. package/lib/types/client/claude/ClaudeSection.d.ts.map +1 -0
  10. package/lib/types/client/claude/locales.d.ts +444 -0
  11. package/lib/types/client/claude/locales.d.ts.map +1 -0
  12. package/lib/types/client/claude/styles.d.ts +15 -0
  13. package/lib/types/client/claude/styles.d.ts.map +1 -0
  14. package/lib/types/client/index.d.ts +1 -1
  15. package/lib/types/client/index.d.ts.map +1 -1
  16. package/lib/types/host/claude/__probe-assert.d.ts +2 -0
  17. package/lib/types/host/claude/__probe-assert.d.ts.map +1 -0
  18. package/lib/types/host/claude/account-pool.d.ts +580 -0
  19. package/lib/types/host/claude/account-pool.d.ts.map +1 -0
  20. package/lib/types/host/claude/adapter.d.ts +267 -0
  21. package/lib/types/host/claude/adapter.d.ts.map +1 -0
  22. package/lib/types/host/claude/adopt.d.ts +292 -0
  23. package/lib/types/host/claude/adopt.d.ts.map +1 -0
  24. package/lib/types/host/claude/client.d.ts +513 -0
  25. package/lib/types/host/claude/client.d.ts.map +1 -0
  26. package/lib/types/host/claude/mapper.d.ts +510 -0
  27. package/lib/types/host/claude/mapper.d.ts.map +1 -0
  28. package/lib/types/host/claude/model-catalog.d.ts +365 -0
  29. package/lib/types/host/claude/model-catalog.d.ts.map +1 -0
  30. package/lib/types/host/claude/oauth.d.ts +393 -0
  31. package/lib/types/host/claude/oauth.d.ts.map +1 -0
  32. package/lib/types/host/claude/routes.d.ts +128 -0
  33. package/lib/types/host/claude/routes.d.ts.map +1 -0
  34. package/lib/types/host/claude/token-store.d.ts +312 -0
  35. package/lib/types/host/claude/token-store.d.ts.map +1 -0
  36. package/lib/types/host/claude/types.d.ts +237 -0
  37. package/lib/types/host/claude/types.d.ts.map +1 -0
  38. package/lib/types/host/common/account-pool.d.ts +40 -0
  39. package/lib/types/host/common/account-pool.d.ts.map +1 -1
  40. package/lib/types/host/kimi-code/adapter.d.ts.map +1 -1
  41. package/lib/types/host/kimi-code/client.d.ts +28 -0
  42. package/lib/types/host/kimi-code/client.d.ts.map +1 -1
  43. package/lib/types/host/kimi-code/routes.d.ts.map +1 -1
  44. package/lib/types/index.d.ts +10 -7
  45. package/lib/types/index.d.ts.map +1 -1
  46. package/lib/types/shared/__probe-claude-import.d.ts +2 -0
  47. package/lib/types/shared/__probe-claude-import.d.ts.map +1 -0
  48. package/lib/types/shared/claude-contracts.d.ts +337 -0
  49. package/lib/types/shared/claude-contracts.d.ts.map +1 -0
  50. package/package.json +1 -1
  51. package/lib/types/client/zhipu/ZhipuComposerQuota.d.ts +0 -26
  52. package/lib/types/client/zhipu/ZhipuComposerQuota.d.ts.map +0 -1
  53. package/lib/types/client/zhipu/ZhipuSection.d.ts.map +0 -1
  54. package/lib/types/client/zhipu/locales.d.ts +0 -275
  55. package/lib/types/client/zhipu/locales.d.ts.map +0 -1
  56. package/lib/types/client/zhipu/styles.d.ts +0 -12
  57. package/lib/types/client/zhipu/styles.d.ts.map +0 -1
  58. package/lib/types/host/zhipu/account-pool.d.ts +0 -43
  59. package/lib/types/host/zhipu/account-pool.d.ts.map +0 -1
  60. package/lib/types/host/zhipu/adapter.d.ts +0 -93
  61. package/lib/types/host/zhipu/adapter.d.ts.map +0 -1
  62. package/lib/types/host/zhipu/client.d.ts +0 -153
  63. package/lib/types/host/zhipu/client.d.ts.map +0 -1
  64. package/lib/types/host/zhipu/mapper.d.ts +0 -111
  65. package/lib/types/host/zhipu/mapper.d.ts.map +0 -1
  66. package/lib/types/host/zhipu/model-catalog.d.ts +0 -73
  67. package/lib/types/host/zhipu/model-catalog.d.ts.map +0 -1
  68. package/lib/types/host/zhipu/routes.d.ts +0 -33
  69. package/lib/types/host/zhipu/routes.d.ts.map +0 -1
  70. package/lib/types/host/zhipu/token-store.d.ts +0 -112
  71. package/lib/types/host/zhipu/token-store.d.ts.map +0 -1
  72. package/lib/types/host/zhipu/types.d.ts +0 -125
  73. package/lib/types/host/zhipu/types.d.ts.map +0 -1
  74. package/lib/types/shared/zhipu-contracts.d.ts +0 -164
  75. package/lib/types/shared/zhipu-contracts.d.ts.map +0 -1
package/CHANGELOG.md CHANGED
@@ -2,6 +2,50 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ - **修复 Kimi Code 设置卡片「过一段时间就报 `rejected the stored credential (401)`」**:这不是登录态过期,而是**卡片拿着一个已经过期的 access token 去查用量**,并把服务端的 401 读成了「凭据被拒绝」。
6
+ - **根因一:卡片从不刷新号池凭据**。`/status`、`/quota`、`/connection/test` 都把号池里的 credentials 原样交给 `fetchAccountQuota`,而它只在**没有**传入凭据时才会刷新——号池的刷新只发生在模型请求路径上(`getEffectiveAccount`)。Kimi 的 access token 只有 **900 秒**(实测本机凭据 `exp - iat = 900`),于是「15 分钟没发过 Kimi 消息」=「打开设置页必现 401」。实测本机两份存储:镜像里的 token 有效,号池里的 access token 已过期——正是这一条。
7
+ - **根因二:同一枚轮换 refresh token 被两条路径各自刷新**。单凭据文件是号池主账号的**镜像**,但目录加载会绕过号池去刷它(`loadProviderModels` → `ensureAccessToken(store)`,且 stale-while-revalidate 会在后台再刷一次)。Kimi 的 refresh token 轮换后旧的即作废,于是镜像先刷成功就把号池那份变成死令牌;适配器下次刷新拿到 `invalid_grant`,账号被标 `authStatus=expired` 移出轮换,而进程内的「已拒绝」墓碑只在**重新登录**时清除——必须重新登录才能恢复。官方 CLI 正是为同一问题加了跨进程文件锁。
8
+ - **修法**:号池新增 `getFreshCredential(accountId)`(按 id 取凭据、到期前刷新、写回池并镜像)与 `renewCredential(accountId)`(**无条件**续期);`AccountPoolCore` 两者共用一条 `credentialFor` 路径,失败分类与 `getEffectiveAccount` 一致(refresh 被判死刑才标记账号)。卡片三条路径全部改走它。
9
+ - **401 现在会先续期再判定**:`fetchAccountQuota` 收到 401 时用一次强制续期再重试一次,只有**第二次** 401 才是「重新登录」。单账号路径只在存储里仍是**同一枚** refresh token 时才续期——已被别人轮换过的令牌不再花掉。续期后的凭据会用于随后的 `/me` 与落盘,避免刚换到的新 token 立刻被旧 token 覆盖。
10
+ - **目录加载不再碰镜像**:`loadProviderModels` 新增 `credentialProvider` 接缝,适配器与路由在装了号池时传入号池的活跃凭据;带池时**完全不再回退**到单凭据文件,没有活跃账号时宁可返回空目录也不去轮换镜像里的令牌。无池部署行为不变(自刷新仍是它唯一的凭据来源)。
11
+ - **验证**:`tsc` 三个项目 0 错误;`npm test` **110 文件 / 1582 项通过、0 失败**(新增 9 条)。把源码 stash 回修复前,其中 6 条失败,确认断言不是空转。
12
+
13
+ - **移除 Claude 线路的「合规告知 + 确认门禁」**:设置卡片顶部那段必须显式接受的告知、`/claude/api/consent` 路由、以及**主机侧门禁**全部删除。
14
+ - **为什么必须整体删除而不是只删界面**:那条门禁不是纯 UI——它决定**适配器是否注册**,未接受时 `login`/`adopt`/`accounts`/`quota`/`connection/test`/`catalog/refresh`/`settings`(POST)/`login/input` 一律 403。**只删告知框会留下门禁、却再没有地方能确认它,等于把这条线路锁死。** 现在 `claimClaudeRoute` **无条件注册**(保留原有的路由争用处理:`try/catch` + `claudeConflict` 上报 + `llm/adapters-updated` 重新认领)。
15
+ - **风险事实不变,只是不再要求点击**:Anthropic 现行条款仍明确不允许第三方应用提供 Claude.ai 登录、也不允许代用户经 Free/Pro/Max 凭据转发请求,本插件**仍未获任何授权或认可**。README 保留了如实说明,并写明「此前版本有确认步骤,现已移除;移除的只是那一步交互,不改变上述事实」。
16
+ - **用户已有数据必须继续可读**——这是本次最需要小心的点,因为**已确认过的用户磁盘上确实写有 `consent` 键**(实测本机 `~/.dsh/storages/claude-models.json` 含 `{accepted:true, acceptedAt:..., version:"1"}`)。已加测试锁定:含旧 `consent` 键的设置文档**仍能正常解析、其余字段完好**,两条读取路径(手写文件回退解析器、命名空间 schema)都覆盖。手写解析器本就逐字段显式读取、不拒绝未知键,因此无需修改,但现在有测试固定这一行为。
17
+ - **一处纠正**:实现中途曾误以为「zod 默认剥离未知键」。实测本仓库使用的 `@deepseek-ai/schemastery` **会保留**未知键于 scope 值内,只是 `registerClaudePreferenceStore.status()` 按已知字段重建对象,因此陈旧键不会逃逸到状态响应、卡片或路由;文件回退路径则在下一次保存时丢弃它。**结果与预期一致,机制与当初描述不同**,已按实测记录。
18
+ - **验证**:`tsc` 三个项目**均 0 错误**;`npm test` **110 文件 / 1573 项通过、0 失败**(删除 1 个只测该特性的测试文件 367 行,新增 5 条把「不再有门禁」钉死的用例);其中一条端到端用例证明一个从前被拦下的 settings POST 在**完全没有确认状态**时成功,并校验落盘键集合不含 `consent`。源码中仅剩 2 处 `consent` 字样,属于 **antigravity 线路自己的 OAuth `prompt:'consent'` 参数**,与本次无关、按边界未动。
19
+ - **新增模型 Claude Opus 5.5(`claude-opus-5-5`)**,规格取自 Anthropic 官方文档(2026-09-22 发布):1M 上下文 / 128K 输出 / 支持图片输入 / 档位 `low`–`max`。
20
+ - **它不能关闭思考**:官方文档明确 `thinking:{type:"disabled"}` 与 `{type:"enabled",budget_tokens:N}` **都返回 400**,只能省略 `thinking` 或发 `{type:"adaptive"}`。因此能力表标记为**不可关闭思考**,并有测试固定。
21
+ - **它的默认档位是 `medium`**(其它带 effort 的模型默认 `high`),因此**没有被归入 `mid-convo` 分支**——该分支会强制发送 `output_config.effort='high'`,对 Opus 5.5 等于**静默抬高一档、增加开销**。代码注释记录了这条推理,测试另有断言把 `mid-convo` 集合钉死为原有的两个 id,使「再加一个强制档位模型」必须是一次经过审视的改动。
22
+ - **不受影响的破坏性变更**:官方同时列出「不支持强制工具调用(`tool_choice` 为 `any`/`tool` 返回 400)」。已核实**本仓库 mapper 从不发送 `tool_choice`**,因此不受影响(此为查证结果,非假定)。
23
+ - **保真锁没有被削弱**:原测试硬断言「恰好 14 行且 id 与参照快照完全相等」,而本机快照(`@earendil-works/pi-ai@0.85.1`)**早于 Opus 5.5**。改法是:快照内每条仍逐字段比对(强度不变);id 相等改为**同相对顺序的子序列匹配**;超出快照的 id 必须出现在测试内显式的 `LOCALLY_CURATED_MODEL_IDS` 清单上,并有**反向断言**(表里任何超出快照的 id 若不在清单上即失败),从而**臆造或拼错的 id 无法蒙混**。`DEFAULT_VISIBLE_MODEL_IDS` 现以 `claude-opus-5-5` 开头。
24
+ - **变异验证**:臆造 id、转录字段漂移、转录行乱序、把第三个模型标成 `mid-convo`、以及新增一条未登记的 id —— 五种篡改**均会导致测试失败**。
25
+ - **未联网核实的项**:模型行本身的字段值来自官方文档(非实测);服务端的 actual effort 默认与 400 行为**未在真实账号上验证**。
26
+
27
+
28
+ - **GLM(智谱 Coding Plan)线路被 Claude(订阅)线路取代**:移除 provider `zhipu-coding-plan` 的全部实现(`src/host/zhipu/`、`src/client/zhipu/`、`src/shared/zhipu-contracts.ts` 与三个 zhipu 测试文件),新增 provider `claude-subscription`,以 **Claude Pro / Max 订阅的 OAuth 登录态**访问 Anthropic Messages 接口(不使用 API Key、不按量计费)。设置页第六个标签由 **GLM** 换成 **Claude**。
29
+ - ⚠️ **合规前提,且已在 UI 上如实告知**:Anthropic 现行条款写明 *"Anthropic does not permit third-party developers to offer Claude.ai login into their own applications, or to route requests through Free, Pro, or Max plan credentials on behalf of their users"*,并声明保留不经预告的执法权;已有开源项目被下架、有账号因此被限制。本插件**未获 Anthropic 任何授权或认可**,且**告知不改变条款效力**——风险由使用者承担。卡片文案据实措辞,并明确写出「未经授权」而非暗示合规。
30
+ - **门禁在 Host 侧强制,不是界面上的一个勾**:未接受时 `login` / `adopt` / `accounts` / `quota` / `connection/test` / `catalog/refresh` / settings POST / `login/input` **一律 403**,且**不读取本机 Claude Code 凭据、不注册适配器**(模型不出现在选择器里);只有 `GET /status` 与 consent 接口开放,否则用户看不到也无法接受那段告知。撤销接受会**注销适配器**、中止在飞登录、停止额度轮询,但**保留已存凭据而使其不可用**(不静默删除用户数据)。以上每一条都有测试。
31
+ - **协议事实的出处是"本机可复核的引用",不是自评**:OAuth 端点、client_id、鉴权头、Claude Code 身份块、工具名归一化表、模型能力表,全部取自本机随 harness 安装的 `@earendil-works/pi-ai@0.85.1`(lockfile integrity `b9bcce47…`,harness checkout `477b4f4205` = `dsh-v0.1.7-rc.2`)的 `dist/` 产物,均在代码注释与测试中带行号引用。**没有发出过任何真实 OAuth 或 Messages 请求**:本机无 Claude 凭据、无 Claude Code 安装,因此真实可用性**未经验证**(见下)。
32
+ - **本实现不照抄参照实现的一处安全缺陷**:参照实现把 PKCE verifier 直接当作 OAuth `state`(`dist/auth/oauth/anthropic.js:209` 的 `state: verifier`),会把本应保密的 verifier 写进授权 URL、地址栏、浏览器历史与剪贴板。本线路是两次**独立**随机抽样,并有测试断言授权 URL 中不出现原始 verifier(该测试先从真实的兑换请求里取出 verifier,因此否定断言不是空转)。
33
+ - **思考形态有四类,顺序决定成败**:`mid-convo`(`compat.supportsMidConvoEffort === true`,**排在最前且无条件**)→ `{type:'adaptive', block_binding:{prefix_mismatch_behavior:'drop_block'}}` **外加** `output_config.effort`;`adaptive` → `{type:'adaptive'}`;`budget` → `{type:'enabled', budget_tokens}`;`none` → 不发。**`claude-fable-5-1` 与 `claude-opus-5` 同时带 `forceAdaptiveThinking`**,因此把它们当成普通 `adaptive` 会**静默丢掉 `block_binding` 与 `output_config`**——看起来完全正确,而参照实现自己的注释写明该缺失会导致**持续 400**。这条缺陷是在实现过程中被独立核对发现并修正的,并补了反向对照(改回旧值即失败),因为它原本连"保真锁"一起锁错了。
34
+ - **预算算术按参照实现转录**(`MIN_ANSWER_TOKENS = 1024`、`DEFAULT_THINKING_BUDGETS`、`clampReasoning` 把 `xhigh`/`max` 夹到 `high`、以及 caller 侧与 wire 侧两道钳制),并测试了两个陷阱:`undefined` 的输出上限**不得**被当成 0(否则思考预算吞掉整个响应上限、回答没有余量),以及传入的必须是**已解析**的上限。
35
+ - **思考块带签名则原样回放**(`redacted_thinking` 同样回放),**无签名则丢弃**——这是思考模式下多轮工具调用的前提;有真正的多轮集成测试(`thinking → tool_use → tool_result → 续轮`),不是手搭 fixture。工具名出站按 Claude Code 规范大小写归一化、入站按大小写无关匹配回原名;**归一化后碰撞则放弃归一化**,避免把结果投给错误的工具。
36
+ - **两条登录路径是两个流程**:授权码与签发它的 `redirect_uri` 绑定,因此模式在流程开始时确定、中途切换即作废重发。默认**手动粘贴**(授权页把码显示在屏幕上),loopback 为可选并绑定 `127.0.0.1`。**一次授权只兑换一次**(compare-and-set:浏览器回调与粘贴同时到达时只有一方兑换,另一方得 409;已结算得 410 且不兑换);**错误的 state 只拒绝那一个请求**,不终止合法登录。刷新是**单飞**的,否则到期瞬间一批请求会各自轮换刷新令牌全部作废。
37
+ - **账号身份是两层,令牌绝不作键**:不可变的 `internalId` 是唯一路由键;`identityKeys`(uuid / email / 派生 seed)只增不换,同一账号再次登录**合并**而非产生幽灵账号。**唯一例外的限制被如实写明并有测试**:服务端既无 uuid 也无 email 时无法自动识别同一账号,卡片会标注并提供**手动合并**——不伪造稳定 id。
38
+ - **收编本机 Claude Code 登录是可选且默认关闭的只读操作**:开启前只探测文件是否存在(不读内容),开启后才读取;得到的是**快照,永不由本插件刷新**——Claude Code 刷新同一枚轮换令牌,两个进程各自刷新会互相作废,而进程内单飞**解决不了跨进程竞态**,因此"永不刷新"是唯一正确答案而非优化。**绝不写入或删除 Claude Code 的任何文件**;managed 与 adopted 冲突时合并为一条且 managed 胜出,**adopted 标记不得残留**(残留会让该账号永远不再刷新)。
39
+ - **额度两套单位,分别换算且有交叉锁**:`/api/oauth/usage` 的 `utilization` 是**已用百分比 0–100**,而 `anthropic-ratelimit-unified-*-utilization` 响应头是**分数 0–1**、重置时间是 **epoch 秒**(与 body 的 ISO 字符串不同)。**`utilization: 0` 是「尚未使用」的正常态,不是额度耗尽**;两套单位不会被混淆(有测试证明同一状态的两种表达得到相同结果)。键集随账号类型变化且含会漂移的开关代号,因此只读已知键、**缺失不当作 0**。
40
+ - **换号两条硬约束**:只在**凭据失败**或**账号级限流**时换号——全局限流 / 过载 / 5xx **绝不换号**(其它账号共享同一全局限制);**一旦已有输出产出就绝不换号**(否则重复文本或重复工具调用),改为直接报错。最多 3 次。
41
+ - **`xhigh` 原样透传,不做收敛**:`ReasoningEffortId` 在 dsh-llm 中是无约束 brand(`brandString(id)`,注释明写 no validation),本仓库已有四条线路使用 `xhigh`。写一张多余的收敛表会把用户选的档位静默降级——这条曾一度被误判为"harness 词表不支持",经读定义后纠正。
42
+ - **移除是纯代码移除,不动用户数据**:`storages/zhipu-*.json` 与 `dsh-zhipu` 设置命名空间**原样留在磁盘、不再被读取**(不删除、不迁移、不加提示)。**兄弟线路不受影响**:`command-code` 与 `workbuddy` 目录中的 `zai-org/GLM-5.3`、`glm-5.3` 等是它们各自上游的**真实模型名**,全部保留(约 42 处,有命令核对数量未变)。
43
+ - **旧会话的恢复行为**:选择仍指向已删除 provider 的旧会话,发送时会被 harness 以 `session/model-unavailable`("Select an available model before sending a message.")拒绝——这是 harness 内建行为,**不新增桥接**。恢复方式就是在模型选择器里另选一个模型。本机已核实无默认模型指向该 provider。
44
+ - **验证**:`tsc -p tsconfig.host.json` / `tsconfig.client.json` / `test/tsconfig.json` 三个项目**均 0 错误**;`npm test` **全绿**,无回归;`npm run build` 成功;`pnpm-lock.yaml` / `pnpm-workspace.yaml` **无 diff**(未改依赖)。新增约 11 个源文件与 12 个测试文件、约 260 项测试。
45
+ - **未经核实的项(必须如实记录)**:(1) **真实订阅端到端从未执行**——登录、令牌刷新、多轮工具调用、图片、额度读取、取消登录均未在真实账号上跑过,因此该线路应被视为**未经端到端验证**;(2) `/api/oauth/usage` 的确切键集与限流行为来自二手来源,整个 pnpm 树中不存在;(3) Claude Code 凭据文件的确切布局来自二手来源,且本机不存在该文件,收编路径只能靠 fixture 构造性验证;(4) macOS 钥匙串服务名未核实且明确列为非目标。以上各项均在代码注释中标注为来源等级,不冒充为本机事实。
46
+ - **回滚**:本条替代 `0.8.5`。如需退回带 GLM 线路的版本,安装 `@eddyskywalker/dsh-chatgpt-subscription@0.8.5` 即可;该版本的 GLM 凭据与设置仍在本机磁盘上,可直接复用。
47
+
48
+
5
49
  - **修复 issue #18:在 DSH Desktop 0.1.7-rc.2 启用本插件时报 `fiber state 5`、导致三条 web 行「未激活」**。报错原文是 `dsh: warning: 3 entries did not activate`,点名 `web`、`web-search-deepseek`、`web-fetch-http`,且**只有装了本插件才会出现**。根因是**启用路径上的启动时序**,不是本插件把 `web` 弄坏了。
6
50
  - **`fiber state 5` 是 `UNLOADING`**(`FiberState`:0 PENDING / 1 LOADING / 2 ACTIVE / 3 FAILED / 4 DISPOSED / 5 UNLOADING)。harness 的 `inactiveEntries()`(`packages/boot/app-boot/src/index.ts:857`)把任何非 ACTIVE / PENDING / FAILED 的行渲染成 `fiber state N`;「未激活」是它对**卸载中**这一瞬态的措辞,不是加载失败。
7
51
  - **为什么是这三行**:`web-search-deepseek` 与 `web-fetch-http` 都 `inject: ['web']`,所以 `web` 一旦重启,它们必然跟着卸载。它们是**被牵连**的,不是各自出错的。
package/README.md CHANGED
@@ -14,7 +14,7 @@
14
14
  - [Kimi Code 线路](#kimi-code-线路)
15
15
  - [Command Code 线路](#command-code-线路)
16
16
  - [WorkBuddy 线路](#workbuddy-线路)
17
- - [GLM(智谱 Coding Plan)线路](#glm智谱-coding-plan线路)
17
+ - [Claude(订阅)线路](#claude订阅线路)
18
18
  - [子代理模型授权](#子代理模型授权0215-起)
19
19
  - [随包分发的 Agent Preset](#随包分发的-agent-preset)
20
20
  - [升级、降级与卸载](#升级降级与卸载)
@@ -84,17 +84,23 @@
84
84
  - **流中断即失败**:上游必然以 `finish_reason` 或 `data: [DONE]` 结束,两者都缺失说明连接中途断开,此时抛出错误而不是把半截文本当成完整回答;
85
85
  - 额度来自 `/billing/meter/get-user-resource`,卡片展示套餐名、本周期已用/上限、剩余额度与重置时间;设置页为「设置 → 订阅服务 → WorkBuddy」标签页,对话输入框右侧有该线路的额度胶囊。
86
86
 
87
- **GLM(智谱 Coding Plan)线路**
88
-
89
- - 注册 `zhipu-coding-plan` Provider,接入**智谱 / Z.ai 的 GLM Coding Plan 订阅**。该 ID 特意与用户常用的自定义 OpenAI 兼容线路 `zai` / `zhipu` 分开,安装插件不会覆盖或隐藏原有自定义 API;
90
- - **订阅接口与开放平台是两套东西**:Coding Plan 的模型接口是 OpenAI 兼容的 `{base}/api/coding/paas/v4`,**不是** 通用付费的 `/api/paas/v4`——把开放平台的 Key 或后者当 base URL 用会被判为鉴权失败。国区(`open.bigmodel.cn`)与国际区(`api.z.ai`)的 Key **互不通用**,因此区域是**凭据属性**:添加时显式选择,卡片逐条标注,模型请求走该账号自己的 host;
91
- - **添加 Key 前先验证**:`POST /zhipu/api/accounts/add` 先用该 Key 读一次部署自己的模型目录,未通过就不落盘,并直接告出「Key 大概来自哪个控制台」——这是这个产品最常见的一次配错。整个登录只花一次上游读(验证用的目录会被缓存);
92
- - **多账号号池,与另外四条线路同源**:走共享内核 `AccountPoolCore`(`src/host/common/account-pool.ts`)并复用同一张设置卡片(`src/client/common/AccountPoolCard`),因此具备**顺序耗尽 / 轮询调度 / 粘性会话**三种策略、429 冷却换号、账号级失效(保留账号、重新添加即恢复)、设为主账号、账号备注与清除冷却。账号 id 是 **Key 摘要 + 区域**,别名只显示「区域 + Key 后四位」,明文 Key 既不进别名也不进 id,更不会出现在卡片上(有测试锁定);
93
- - **模型能力逐模型查表**(`src/host/zhipu/model-catalog.ts`):是否接受图片、有哪些思考档位、能否关闭思考都由该表决定,运行时以订阅侧 `GET /models` 为准(只覆盖上下文窗口,能力不被上游列表改写)。图片能力不能按族名推断——**`glm-5.3-flash` 接受图片而 `glm-5.3` 不接受**;档位也不能——`glm-5.3` 有三档而 `glm-5.2` 只有两档,`glm-4.7` / `glm-4.5-air` 这类 toggle 模型根本不收 `reasoning_effort`;
94
- - **思考档位只发上游认的值**:上游对 GLM-5.x 只接受 `low` / `high` / `max`,其余取值**直接报错**(不是被忽略)。DSH 的档位词表比这宽,因此每个取值都先收敛到该模型自己的档位表再发出;收敛按**两套词表统一排序**,`minimal` 这类「比 low 更省」的档位会落到 `low` 而不是被当成未知值弹到中间档——否则用户选了最省的一档反而会换来 `high`,既不符合意图又更费额度。关闭思考的值本线路一律不发:GLM-5.3 / GLM-5.3-FLASH / GLM-4.7 把 `thinking.type: "disabled"` 判为错误,省略该字段就是它们的 `enabled` 默认;
95
- - **额度来自订阅自己的监控接口**:`{base}/api/monitor/usage/quota/limit` 给 5 小时与每周两个额度窗口(外加月度 MCP 工具调用次数),`{base}/api/biz/subscription/list` 给套餐名。这两个接口的鉴权用的是**不带 `Bearer` 前缀的裸 Key**(实测:带前缀判 401,裸 Key 通过),与模型接口的 `Bearer` 形式不同,因此两条 header 各自成函数。窗口按上游的 `unit`/`number` 描述换算成分钟后再命名,兼容 `TOKENS_LIMIT` 与新版 `CREDIT_LIMIT` 两种拼写;
96
- - **瞬时失败按错误类别重试**(`src/host/zhipu/adapter.ts`):上游 5xx、`code 1230/1234` 与服务过载归为可重试并走有界退避(最多 3 次,1.5s 起步、15s 上限、0.2 抖动),429 会带上上游 `Retry-After`。而 **401/403 与 `code 1000/1003/1001`(Key 失效)、`code 1311`(套餐不含该模型)、`code 1309`(套餐已过期)明确不重试**——它们与「额度窗口用尽」同样是 429,但只有后者值得重试,因此分类读响应正文的 `code` 而不只看状态码,并给出可操作的提示(换模型 / 续费 / 重新添加 Key);
97
- - 模型勾选、思考深度、上下文窗口覆盖与额度在「设置 → 订阅服务 → GLM」标签页中配置,输入框右侧另有额度胶囊(取**最紧的那个窗口**,因为 5 小时窗口和每周窗口会各自先耗尽)。
87
+ **Claude(订阅)线路**
88
+
89
+ - 注册 `claude-subscription` Provider,以 **Claude Pro / Max 订阅的 OAuth 登录态**访问 Claude 模型(Anthropic Messages 接口),**不使用 API Key、也不按量计费**;
90
+ - ⚠️ **风险须知(插件不设确认步骤,但事实不变)**:Anthropic 现行条款明确写明**不允许第三方应用提供 Claude.ai 登录、也不允许代用户经 Free / Pro / Max 凭据转发请求**,并保留不经预告的执法权;已有开源项目被下架、有账号因此被限制。**本插件未获 Anthropic 任何授权或认可**,使用风险由使用者自行承担。此前版本在卡片上设有确认步骤与配套主机门禁,两者均已移除;移除的只是那一步交互,**不改变上述事实**;
91
+ - **这不是抄一个 token 就能用**:订阅令牌要求请求**完整模仿 Claude Code 的身份**,否则会被服务端拒绝或分类判别——`Authorization: Bearer` 且 **`x-api-key` 必须缺省**、`user-agent: claude-cli/<版本>`、`x-app: cli`、`anthropic-beta` 至少含 `oauth-2025-04-20` 与 `claude-code-20250219`、`system` 的**首个块必须是 Claude Code 身份声明**。这些都在代码里显式实现并有测试锁定;
92
+ - **OAuth 用 PKCE,且 state 与 verifier 独立生成**。这一点特意**不照抄参照实现**:本机参照实现把 PKCE verifier 直接当作 OAuth `state`(`state: verifier`),那会把本应保密的 verifier 写进授权 URL、地址栏、浏览器历史乃至剪贴板。本线路是两次独立随机抽样,并有测试断言授权 URL 中**不出现原始 verifier**;
93
+ - **两条登录路径,模式在流程开始时确定且不可中途切换**:默认是**手动粘贴**(授权页把码显示在屏幕上,粘贴 `<code>#<state>`;也容错接受整条重定向 URL)。可选 loopback 回调,绑定 `127.0.0.1` 并顺序探测可用端口(Windows 的保留端口段会让固定端口绑定失败)。端口探测失败**降级为手动**而不是报错。切换模式等于作废当前流程并重新发起——授权码与签发它的那次请求的 `redirect_uri` 绑定,这是该流程最常见的失败;
94
+ - **一次授权只兑换一次**:浏览器回调与手动粘贴可能同时到达,用 compare-and-set 保证只有一方发起兑换(另一方得到「正在处理中」,已结算的流程得到 410 且**不做任何兑换**)。错误的 `state` **只拒绝那一个请求**,不会终止正在进行的合法登录。回调服务器只绑 loopback、只应答 `/callback`、只接受本机来源;
95
+ - **刷新是单飞的**:并发请求共享同一次刷新。否则到期瞬间的一批请求会各自轮换刷新令牌,除第一个之外全部作废(上游会给出终局判定)。刷新令牌轮换后**先读回校验再落盘**;
96
+ - **模型能力逐模型查表**(`src/host/claude/model-catalog.ts`),**不从模型名推断**。该表转录自本机随 harness 安装的参照目录,**只证明抄录忠实,不证明服务端提供这些模型**——服务端自己的 `GET /v1/models` 才是权威,且它**只覆盖上下文窗口**,能力字段不被改写;
97
+ - **思考形态有四类,顺序决定成败**(`thinkingMode`):`mid-convo` → `{type:'adaptive', block_binding:{prefix_mismatch_behavior:'drop_block'}}` 外加 `output_config.effort`;`adaptive` → `{type:'adaptive'}`;`budget` → `{type:'enabled', budget_tokens}`(预算算术按参照实现转录,思考预算计入 `max_tokens`,**必须为回答留出至少 1024 token**);`none` → 不发思考字段。**`mid-convo` 排在最前且无条件**——`claude-fable-5-1` 与 `claude-opus-5` 同时带 `forceAdaptiveThinking`,把它们当成普通 `adaptive` 会**静默丢掉 `block_binding` 与 `output_config`**,而参照实现自己的注释写明该缺失会导致**持续 400**;
98
+ - **思考块带签名则原样回放**(这是思考模式下多轮工具调用的前提;`redacted_thinking` 同样回放),**无签名则丢弃**。工具名在出站时按 Claude Code 规范大小写归一化、入站时按大小写无关匹配回用户工具名;若两个工具归一化后碰撞,则**放弃归一化**原样发送,避免把结果投给错误的工具;
99
+ - **多账号号池,与其它线路同源**:走共享内核 `AccountPoolCore` 并复用同一张设置卡片,具备顺序耗尽 / 轮询调度 / 粘性会话、429 冷却换号、账号级失效保留、设为主账号与备注。**账号身份是两层**:不可变的 `internalId` 是唯一路由键,`identityKeys`(uuid / email / 派生 seed)是**只增不换**的别名集,同一账号再次登录会**合并**而不是产生幽灵账号。**唯一例外的诚实说明**:当服务端既没返回 uuid 也没返回 email 时无法自动识别同一账号,卡片会把该账号标注出来并提供**手动合并**;
100
+ - **可选择性收编本机已有的 Claude Code 登录(默认关闭)**:开启前只做一次「文件是否存在」的探测,**不读取内容**;只有你显式开启后才读取。收编得到的是一份**快照**,**永不由本插件刷新**——Claude Code 刷新的是同一枚轮换令牌,两个进程各自刷新会互相作废,而进程内的单飞解决不了跨进程竞态。快照过期后卡片会提示你**回 Claude Code 重新登录后再收编**,并且**绝不会写入或删除 Claude Code 的任何文件**;
101
+ - **额度面有两个来源、两套单位**:主来源 `GET /api/oauth/usage` 的 `utilization` 是**已用百分比 0–100**;而 `/v1/messages` 响应头 `anthropic-ratelimit-unified-5h-utilization` 是**分数 0–1**、重置时间是 **epoch 秒**。两套单位分别换算并有交叉测试证明它们描述同一状态。**`utilization: 0` 表示「尚未使用」,是正常状态,不是额度耗尽**;两者都不会混淆。有真实流量时以响应头为准以降低查询频率,但卡片仍会按 `QUOTA_FULL_REFRESH_MS` 做一次完整读取;
102
+ - **换号的两条硬约束**:只在**凭据失败**或**账号级限流**时换号——全局限流、过载与 5xx **绝不换号**(其它账号共享同一全局限制)。**一旦已有输出产出就绝不换号**(否则会重复文本或重复工具调用),改为直接报错。换号最多 3 次;
103
+ - 模型勾选、思考深度、上下文窗口覆盖与额度在「设置 → 订阅服务 → Claude」标签页中配置,输入框右侧另有额度胶囊(取**剩余最紧的那个窗口**)。
98
104
 
99
105
  **设置页**
100
106
  - 展示账号(脱敏 email、套餐、账号 ID 后四位)、连接状态、额度与订阅增强功能开关;
@@ -383,43 +389,85 @@ DSH 设置页的「Subagent」卡片会把勾选的模型写成会话级的允
383
389
 
384
390
  与其它线路一样,所有修改状态的路由只接受同源 JSON POST,并校验 `Origin` 与 `Host`。
385
391
 
386
- ## GLM(智谱 Coding Plan)线路
392
+ ## Claude(订阅)线路
393
+
394
+ ### 风险须知(请先读)
395
+
396
+ 本线路以 **Claude Pro / Max 订阅登录**访问模型。Anthropic 现行条款写明**不允许第三方应用提供 Claude.ai
397
+ 登录、也不允许代用户经 Free / Pro / Max 凭据转发请求**,并保留不经预告的执法权;**本插件未获 Anthropic
398
+ 任何授权或认可**,你的账号**可能因此被限制、暂停或终止**。
387
399
 
388
- 1. 在你要用的平台上订阅 **GLM Coding Plan**,并在对应控制台创建 API Key:[Z.ai](https://z.ai/manage-apikey/apikey-list)(国际区)或 [智谱开放平台](https://open.bigmodel.cn/)(国区);
400
+ 此前版本在设置卡片上设有一个必须显式接受的确认步骤,并配套一条主机侧门禁;**该步骤与门禁均已移除**,
401
+ 现在打开卡片即可直接使用。移除的只是那一步交互——上面这段事实、以及由此产生的风险,都不因移除而改变。
402
+ 是否使用请自行判断并承担后果。
403
+
404
+ ### 登录
405
+
406
+ 1. 订阅 **Claude Pro 或 Max**,并确保你能在浏览器里登录 claude.ai;
389
407
  2. 重启 DSH,让 Host 加载本插件;
390
- 3. 打开 **设置 → 订阅服务 → GLM**;
391
- 4. 在「添加账号」里**先选区域**(国际区 / 国区),粘贴 Key 后点「保存并验证」——验证不通过就不会写入,并会提示 Key 应来自哪个控制台;
408
+ 3. 打开 **设置 → 订阅服务 → Claude**;
409
+ 4. 点「登录 Claude 订阅」。默认走**手动粘贴**:浏览器打开授权页后会把授权码显示在屏幕上,把
410
+ `<授权码>#<state>` 整段复制粘贴回来即可(也接受直接粘贴整条重定向 URL)。若使用 loopback 回调模式,
411
+ 本机一个可用端口会被自动探测并绑定 `127.0.0.1`;
392
412
  5. 按需勾选模型、设置默认思考深度与上下文窗口。
393
413
 
394
- `zhipu-coding-plan` 会像其他 Provider 一样出现在 DSH 模型选择器中,并可与名为 `zai` / `zhipu` 的自定义 API 同时存在。**上下文窗口**默认取该模型官方声明的窗口(GLM-5.x 系列为 1M),可逐模型覆盖(用于 DSH 的压缩与溢出判断,支持 `1M` / `512K` / `200000` 等写法);**默认思考深度**只对该模型声明了档位时生效,选项为上游真正接受的 `low` / `high` / `max`。
414
+ `claude-subscription` 会像其他 Provider 一样出现在 DSH 模型选择器中。**上下文窗口**默认取内置能力表声明的窗口,
415
+ 可逐模型覆盖(用于 DSH 的压缩与溢出判断,支持 `1M` / `512K` / `200000` 等写法);**默认思考深度**只对声明了
416
+ 档位的模型生效。**档位原样透传**(`ReasoningEffortId` 在 harness 里是无约束 brand,本仓库多条线路都直接使用
417
+ `xhigh`),不做任何收敛,以免把用户选的档位静默降级。
418
+
419
+ **模型表**共 15 条:14 条转录自本机随 harness 安装的参照目录,另加 1 条**本地新增**的 **Claude Opus 5.5**
420
+ (`claude-opus-5-5`,官方 2026-09-22 发布,1M 上下文 / 128K 输出 / 支持图片,档位 `low`–`max`)。
421
+ 它有一条**与其它模型不同的硬约束**:**思考永远开启、不能关闭**——官方文档明确 `thinking:{type:"disabled"}`
422
+ 与 `{type:"enabled",budget_tokens:N}` **都会返回 400**,因此能力表把它标为不可关闭思考,档位表是控制思考深度的
423
+ 唯一手段。它的**默认档位是 `medium`**(其余带 effort 的模型默认 `high`),这一点被刻意保留:本仓库有两类模型走
424
+ 「强制 effort」分支,若把 Opus 5.5 一并归入,就会**静默把每次请求抬高一档、花更多钱**,因此它走的是普通 adaptive
425
+ 分支。
395
426
 
396
- **上游接口**(前缀 `{base}` 为该账号区域的 host):
427
+ ### 收编本机已有的 Claude Code 登录(可选,默认关闭)
428
+
429
+ 如果你本机已经登录过 Claude Code,可以点「收编本机登录」把它作为一条账号导入,省去再次登录。
430
+ 两点必须清楚:
431
+
432
+ - 开启前插件只探测**文件是否存在**,不读取内容;只有你显式开启后才读取;
433
+ - 导入的是**快照**,**本插件永不再刷新它**。Claude Code 刷新的是同一枚轮换令牌,两个进程各自刷新会互相
434
+ 作废,进程内的单飞机制解决不了跨进程竞态。快照过期后请**回 Claude Code 重新登录,再收编一次**;
435
+ - 本插件**绝不写入或删除** Claude Code 的任何文件;「停止收编」只移除插件这边的记录。
436
+
437
+ ### 上游接口
397
438
 
398
439
  | 用途 | 路径 | 鉴权 |
399
440
  | --- | --- | --- |
400
- | 模型生成 | `POST {base}/api/coding/paas/v4/chat/completions` | `Authorization: Bearer <Key>` |
401
- | 模型目录(也是添加 Key 时的验证接口) | `GET {base}/api/coding/paas/v4/models` | `Authorization: Bearer <Key>` |
402
- | 额度窗口 | `GET {base}/api/monitor/usage/quota/limit` | `Authorization: <Key>`(**无 `Bearer`**) |
403
- | 套餐信息 | `GET {base}/api/biz/subscription/list` | `Authorization: <Key>`(**无 `Bearer`**) |
441
+ | 模型生成 | `POST https://api.anthropic.com/v1/messages?beta=true` | `Authorization: Bearer <access token>`,**且 `x-api-key` 必须缺省** |
442
+ | 模型目录 | `GET https://api.anthropic.com/v1/models` | 同上 |
443
+ | 订阅额度 | `GET https://api.anthropic.com/api/oauth/usage` | 同上,另带 `user-agent: claude-code/<版本>` |
444
+ | 授权 / 令牌 | `https://claude.ai/oauth/authorize`、`https://platform.claude.com/v1/oauth/token` | PKCE S256(端点可用环境变量覆盖) |
404
445
 
405
- 两区 host 分别是 `https://open.bigmodel.cn`(国区)与 `https://api.z.ai`(国际区)。请求只带本插件自己的 UA,不冒充官方客户端。
446
+ 请求带有 Claude Code 身份头(`user-agent`、`x-app`、`anthropic-beta`),并在 `system` 首块声明 Claude Code 身份。
447
+ 这是订阅令牌被服务端接受的前提,已在代码与测试中显式锁定。
406
448
 
407
- ### 插件路由(GLM Coding Plan)
449
+ ### 插件路由(Claude 订阅)
408
450
 
409
- 所有路由都以 `/zhipu/api` 为前缀:
451
+ 所有路由都以 `/claude/api` 为前缀:
410
452
 
411
453
  | 方法 | 路径 | 说明 |
412
454
  | --- | --- | --- |
413
- | GET | `/status` | 账号、额度、模型目录与路由归属 |
414
- | POST | `/accounts/add` | 验证并保存一个 API Key(可选 `alias`) |
415
- | POST | `/accounts/remove` | 删除当前账号(单凭据模式) |
416
- | POST | `/accounts/action` | 号池动作:`set-primary` / `set-alias` / `delete` / `clear-cooldown` / `clear-auth-failure` / `strategy` |
417
- | GET / POST | `/quota` | 强制刷新额度(POST)或读取当前状态(GET) |
455
+ | GET | `/status` | 账号、额度、模型目录、登录流程与路由归属 |
456
+ | POST | `/login` | 开始 OAuth 登录,立即返回流程状态(不阻塞) |
457
+ | GET | `/login/status` | 轮询登录流程状态(客户端每 2 秒一次,无 SSE) |
458
+ | POST | `/login/cancel` | 取消登录并释放回调端口 |
459
+ | POST | `/login/input` | 提交手动粘贴的授权码 / 重定向 URL |
460
+ | POST | `/adopt` | 收编本机 Claude Code 登录(只读,作快照入池) |
461
+ | POST | `/adopt/disable` | 停止收编(不触碰 Claude Code 的文件) |
462
+ | GET / POST | `/quota` | 读取或强制刷新额度;失败以 `quotaError` 呈现而非请求失败 |
418
463
  | GET / POST | `/models`、`/settings` | 读取或更新勾选模型、上下文窗口、默认思考深度与选中账号 |
419
464
  | POST | `/catalog/refresh` | 强制刷新模型目录 |
420
- | POST | `/connection/test` | 向上游对话接口发一次最小流式请求测试连接 |
465
+ | POST | `/connection/test` | 向上游发一次最小请求测试连接 |
466
+ | POST | `/accounts` | 号池动作:`set-primary` / `set-alias` / `delete` / `clear-cooldown` / `clear-auth-failed` / `strategy` |
467
+ | POST | `/logout` | 注销(号池感知) |
421
468
 
422
- 与其它线路一样,所有修改状态的路由只接受同源 JSON POST,并校验 `Origin` 与 `Host`;响应里永远不含 API Key(只含 Key 后四位)。
469
+ 与其它线路一样,所有修改状态的路由只接受同源 JSON POST,并校验 `Origin` 与 `Host`。**响应里永远不含
470
+ access token / refresh token / 授权码 / PKCE verifier**(有测试锁定)。
423
471
 
424
472
  ## 安全边界
425
473
 
@@ -427,7 +475,11 @@ Antigravity 的 access token / refresh token 使用独立的系统凭据存储
427
475
 
428
476
  **WorkBuddy token 仅在 Host 内处理,从不进入浏览器**(`/workbuddy/api` 响应不含 `accessToken` / `refreshToken`,有测试锁定)。桌面扫描账号仍使用 CodeBuddy 自己的登录态文件:续期只原子写回其 `auth` 块;从本插件删除时只隐藏/恢复,绝不删除原文件。通过浏览器授权添加的账号归本插件所有,保存在独立系统凭据存储中:Windows CurrentUser DPAPI(`$DSH_HOME/storages/workbuddy-accounts.json.dpapi`)、macOS 登录钥匙串、Linux Secret Service;这类账号可在设置页真正删除。
429
477
 
430
- **GLM Coding Plan 的 API Key 同样只在 Host 内处理,从不进入浏览器**(`/zhipu/api` 响应只含后四位提示,不含 Key 本身,有测试锁定)。它保存在独立系统凭据存储中:Windows CurrentUser DPAPI(`$DSH_HOME/storages/zhipu-credentials.json.dpapi`)、macOS 登录钥匙串、Linux Secret Service;号池另用一份同样加密的文件 `$DSH_HOME/storages/zhipu-pool.json`,账号 id 与别名都只是 Key 的摘要与后四位。
478
+ **Claude 订阅的 access token / refresh token 同样只在 Host 内处理,从不进入浏览器**(`/claude/api` 的响应只含非机密事实,有测试锁定)。它保存在独立系统凭据存储中:Windows CurrentUser DPAPI(`$DSH_HOME/storages/claude-credentials.json.dpapi`)、macOS 登录钥匙串、Linux Secret Service;号池另用一份同样加密的文件 `$DSH_HOME/storages/claude-pool.json`。凭据文档是**多账号**结构,账号身份由不可变的 `internalId` 与只增不换的别名集共同表达,**任何路由键都不是令牌或其摘要**(令牌会轮换,用它做键会产生幽灵账号)。每次写入都**先读回校验再落盘**,校验失败会抛错且不破坏既有数据。
479
+
480
+ **收编(adopt)是只读的**:本插件从不创建、修改、移动或删除 Claude Code 的任何文件;它只读取。收编得到的快照**永不由本插件刷新**(原因见上文)。
481
+
482
+ macOS 钥匙串服务名为 `Claude Code-credentials`(**未核实**,本仓库不读取它:一份第三方指南与真实客户端对该名称说法不一致,因此它被明确列为非目标)。
431
483
 
432
484
  升级后首次访问 Antigravity 凭据时,会读取旧 `storages/antigravity-oauth.json`,加密保存并读回校验;成功后删除旧 JSON,通常无需重新登录。失败会保留旧文件并报告错误,不会回退到明文存储。注销同时清理旧文件和新凭据。Linux 需要 `secret-tool`(libsecret 工具包)及可用、已解锁的 Secret Service 钥匙环;无桌面服务的主机也需要配置该服务。系统凭据存储保护落盘数据,不防御当前用户下已获权限的进程。
433
485
 
@@ -502,10 +554,14 @@ npm pack --dry-run
502
554
  | Kimi Code 报 502 `Upstream model provider is temporarily unavailable` | 上游模型供应商的瞬时故障,与账号、模型、凭据都无关:插件会按 DSH retry policy 自动重试(最多 3 次,并遵守上游 `Retry-After`);连续失败可稍后再试或换用同账号下其他模型 |
503
555
  | Kimi Code 报 429 `engine is currently overloaded` | 服务容量问题(工作日 14:00–17:00 高峰更常见),会自动退避重试;若响应里带 `error.type = exceeded_current_quota_error` 则属于配额耗尽,插件不会重试而是提示补充额度 |
504
556
  | Kimi Code 额度显示为空 | 卡片会同时给出失败原因(`/v1/usages` 的 401/403/5xx 文案),按提示处理后点「刷新用量」重试;确认用的是订阅账号——开放平台的 key 在这里不会被接受 |
557
+ | Kimi Code 报「rejected the stored credential (401). Sign in again…」但发消息却是好的 | 这是**过期 access token**,不是被拒的账号:Kimi 的 access token 只有 **15 分钟**,而设置卡片过去会把号池里存着的那个 token 直接拿去查用量,因此只要 15 分钟内没走过一次 Kimi 请求,卡片就必然拿到 401。现在卡片会先刷新再请求(401 还会触发一次强制续期),因此**不必重新登录**;若卡片仍提示重新登录,才是真的刷新令牌被拒,按提示处理即可 |
505
558
  | Kimi Code 账号一栏为空 | 账号身份取自 OAuth token 自身的 JWT 声明,套餐名取自 `/me`(`/usages` 自 2026-09 起不再返回 `user_level_name`)。重新登录或点「刷新用量」即可写入;若仍为空但显示「已登录」,点「测试连接」可确认凭据是否仍被接受 |
506
- | GLM 添加 Key 报「rejected the API key」 | Key 与所选**区域**不匹配,或它不是 Coding Plan 的 Key。错误文案会指明应来自哪个控制台(`api.z.ai` 或 `open.bigmodel.cn`):换区域重试,并确认订阅生效;开放平台按量付费的 Key 在订阅接口上不被接受 |
507
- | GLM 报 `code 1311`(套餐不含该模型) / `code 1309`(套餐已过期) | 这两个都是账号权益问题而非瞬时故障,插件不会重试:前者换一个模型,后者去官网续费。两者与「额度窗口用尽」共用 429 状态码,插件按响应正文的 `code` 区分处理 |
508
- | GLM 报 `code 1214`(参数被拒) | 多为该模型不支持的思考档位或不可读的图片:`glm-5.3` 不接受图片(用 `glm-5.3-flash`),档位只有 `low` / `high` / `max`。卡片只会列出该模型真正声明过的能力 |
509
- | GLM 额度显示为空或「该账号没有可用的配额数据」 | 监控接口可用但该账号没有生效的套餐;确认订阅已开通,再点「刷新用量」。卡片会同时显示接口本身的失败原因(如 401 / 5xx 文案) |
510
- | GLM 模型不出现在选择器里 | 卡片上若显示「模型路由已被其他 Provider 占用」,从占用方(自定义的 `zai` / `zhipu` 线路)移除该 Provider,插件会在下一次路由变更时自动接管;否则检查是否勾选了模型 |
559
+ | Claude 相关接口返回 403 | 403 现在是**同源校验**的结果(修改状态的路由只接受同源 JSON POST)。若出现在浏览器里,检查是否从其它来源发起了请求;插件已不再有任何"确认后才能用"的门禁 |
560
+ | 授权后粘贴授权码报「请把 # 后面的部分一起复制」 | 手动流程需要 `<授权码>#<state>` **整段**。只粘贴授权码是不被接受的:用流程自己的 state 顶上会架空 state 参数、把粘贴框变成登录 CSRF 的入口,因此插件宁可报错也不猜 |
561
+ | loopback 回调收不到 / 端口绑定失败 | 端口探测失败会自动**降级为手动粘贴**(卡片会说明原因),照提示粘贴授权码即可。另:若浏览器把 `localhost` 解析到 `::1`,依赖浏览器的跨地址族回退可达本机 v4 监听,这是**假定**而非实测 |
562
+ | 模型请求报持续 400 / 「You're out of extra usage」 | 可能是身份或版本门槛:订阅令牌要求 Claude Code 身份头与 `system` 首块,且服务端会校验你申报的客户端版本(过旧会答 `claude_code_version_too_old`)。可用 `DSH_CLAUDE_CLI_VERSION` 抬高申报版本;该错误被归类为**请求问题而非凭据问题**,不会把你登出 |
563
+ | 额度显示为空 / 某项显示「—」 | 额度接口的键集随账号类型变化,未提供的窗口会显示为未知而**不会伪造 0**。注意 **`utilization` 是已用百分比,0% 表示尚未使用(正常态)**,不是额度耗尽;真正的耗尽会以 429 与响应头状态呈现。接口被限流时卡片保留上次成功快照并标注时间 |
564
+ | 收编后提示「本机 Claude Code 登录已过期」 | 这是设计如此:收编的是**快照**,插件永不刷新它(Claude Code 刷新同一枚轮换令牌,两个进程各自刷新会互相作废)。回 Claude Code 重新登录后**再收编一次**即可 |
565
+ | 账号被标为「无法识别账号身份」 | 服务端这个账号既没返回 uuid 也没返回 email,插件无法在再次登录时自动认出它。用卡片上的**手动合并**把它并入既有账号;这是已知限制,插件不会用假 id 掩盖它 |
566
+ | 模型不出现在选择器里 | 依次检查:卡片是否显示「模型路由已被其他 Provider 占用」(另一适配器持有该 id 时本插件会如实报告冲突而非抛错);以及模型是否已勾选 |
511
567
  | Kimi Code 发送视频却没有画面 | `k3-256k` 不支持视频,切到 `k3` 或 `kimi-for-coding`;容器须在白名单内(mp4/mpeg/mov/avi/x-flv/mpg/webm/wmv/3gpp);若该模型走的是 Anthropic 线路,视频会降级为文字(该协议没有文档化的视频块)。以上情况模型都会收到明确的文字说明,据此向你说明而不是凭空回答 |