@eddyskywalker/dsh-chatgpt-subscription 0.42.0 → 0.43.1
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.
- package/CHANGELOG.md +61 -0
- package/README.md +1 -0
- package/lib/client.js +256 -182
- package/lib/client.js.map +1 -1
- package/lib/index.js +813 -237
- package/lib/types/client/command-code/CommandCodeComposerQuota.d.ts.map +1 -1
- package/lib/types/client/common/format.d.ts +16 -0
- package/lib/types/client/common/format.d.ts.map +1 -1
- package/lib/types/client/kimi-code/KimiCodeComposerQuota.d.ts.map +1 -1
- package/lib/types/client/kimi-code/KimiCodeSection.d.ts.map +1 -1
- package/lib/types/client/kimi-code/KimiQuotaCard.d.ts.map +1 -1
- package/lib/types/client/kimi-code/styles.d.ts.map +1 -1
- package/lib/types/client/locales-ru/opendesign.d.ts.map +1 -1
- package/lib/types/client/locales-ru/qoder.d.ts.map +1 -1
- package/lib/types/client/opendesign/OpenDesignSection.d.ts.map +1 -1
- package/lib/types/client/opendesign/locales.d.ts +12 -0
- package/lib/types/client/opendesign/locales.d.ts.map +1 -1
- package/lib/types/client/qoder/QoderSection.d.ts.map +1 -1
- package/lib/types/client/qoder/locales.d.ts +9 -1
- package/lib/types/client/qoder/locales.d.ts.map +1 -1
- package/lib/types/client/qoder/styles.d.ts.map +1 -1
- package/lib/types/compat.d.ts +1 -1
- package/lib/types/host/claude/types.d.ts +7 -1
- package/lib/types/host/claude/types.d.ts.map +1 -1
- package/lib/types/host/glm-coding-plan/types.d.ts +5 -1
- package/lib/types/host/glm-coding-plan/types.d.ts.map +1 -1
- package/lib/types/host/kimi-code/account-pool.d.ts +26 -1
- package/lib/types/host/kimi-code/account-pool.d.ts.map +1 -1
- package/lib/types/host/kimi-code/client.d.ts +24 -0
- package/lib/types/host/kimi-code/client.d.ts.map +1 -1
- package/lib/types/host/kimi-code/oauth.d.ts +16 -0
- package/lib/types/host/kimi-code/oauth.d.ts.map +1 -1
- package/lib/types/host/kimi-code/routes.d.ts.map +1 -1
- package/lib/types/host/opendesign/adapter.d.ts +11 -13
- package/lib/types/host/opendesign/adapter.d.ts.map +1 -1
- package/lib/types/host/opendesign/catalog.d.ts +14 -0
- package/lib/types/host/opendesign/catalog.d.ts.map +1 -1
- package/lib/types/host/opendesign/line.d.ts +17 -6
- package/lib/types/host/opendesign/line.d.ts.map +1 -1
- package/lib/types/host/opendesign/routes.d.ts.map +1 -1
- package/lib/types/host/opendesign/token-store.d.ts +91 -4
- package/lib/types/host/opendesign/token-store.d.ts.map +1 -1
- package/lib/types/host/opendesign/types.d.ts.map +1 -1
- package/lib/types/host/qoder/client.d.ts.map +1 -1
- package/lib/types/host/qoder/mapper.d.ts +74 -2
- package/lib/types/host/qoder/mapper.d.ts.map +1 -1
- package/lib/types/host/qoder/types.d.ts +6 -1
- package/lib/types/host/qoder/types.d.ts.map +1 -1
- package/lib/types/host/step-code/types.d.ts +5 -1
- package/lib/types/host/step-code/types.d.ts.map +1 -1
- package/lib/types/shared/opendesign-contracts.d.ts +24 -1
- package/lib/types/shared/opendesign-contracts.d.ts.map +1 -1
- package/lib/types/shared/qoder-contracts.d.ts +10 -0
- package/lib/types/shared/qoder-contracts.d.ts.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,66 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
## 0.43.1 - 2026-10-27
|
|
6
|
+
|
|
7
|
+
- **[qoder] 上游排队不再被说成「API 密钥无效」;额度用尽与排队分成两条路**
|
|
8
|
+
- **现象**:Qoder 线路发消息立刻失败,界面只显示「本轮运行失败 · API 密钥无效 · AUTH」,于是去重建 PAT、重新登录、换区域——而凭据一直是好的(同一把 token 调 `GET /api/v1/userinfo` 返回 200)。另一条路同样的话:额度真的用尽时(上游 code 112 + pricingUrl)显示的也是「API 密钥无效」,两条完全不同的失败在用户眼里是同一句。
|
|
9
|
+
- **为什么**:上游把「排队中」装在 **HTTP 200 的 SSE 错误信封**里(`statusCodeValue: 403`,body 带 `code 10605` / `subCode: RESOURCE_LIMIT` / `queueCount 3239` / `retryAfterSeconds 30` / `serviceAvailable false`)。插件在 mapper 里解出 `statusCodeValue` 后交给 `classifyQoderFailure`,而它把任何 403 一刀切成 AUTH;DSH 收到 AUTH 就显示通用文案「API 密钥无效」(`message.failure.auth`)。插件也不认识 `RESOURCE_LIMIT` / `10605` / `isQueued` / `retryAfterSeconds` 这几个字段,信息在整条链路上被丢弃。额度快照同样只映射三只桶,`isQuotaExceeded` 与 `upgradeUrl` 一次都没出现过——于是三只桶全是 0 时卡片显示「还有额度」,而上游其实已经把请求拒了。
|
|
10
|
+
- **改法**:(1) 分类器改为**按上游事实**判定:新增一份逐层扫描的事实集合(信封外层 + body + body 里的 `error` 对象),排队/资源不足(`RESOURCE_LIMIT`、`10605`,或 403 配容量信号)归 `SERVER`(上游容量,换账号与重新登录都救不了,只有退避重试有意义——与 kimi-code 的「引擎过载」同一判断),额度用尽(code `112`,或 403 配 `isQuotaExceeded` / `pricingUrl`)归 `QUOTA`(DSH 显示「当前请求的额度已用尽」),401 与 code `105` 仍是 `AUTH`,认不出原因的 403 仍保守归 AUTH;上游给了 `retryAfterSeconds` 就照它说(`providerRetryAfterMs`)。(2) 信封路径把**信封层与 body 一起**送进分类器——上游把事实放在哪一层并不确定,只读 body 会把「排队」读成「凭据被拒」。(3) 额度快照补上 `quotaExceeded` / `upgradeUrl`,设置页额度卡在上游说用尽时先说这件事并给出升级页(zh/en/ru 三语)。
|
|
11
|
+
- **测试**:`test/qoder-mapper.test.ts` 新增 4 例(排队归 SERVER 且带 `providerRetryAfterMs`、额度用尽归 QUOTA、认不出的 403 仍是 AUTH、429 的含义不被弱信号改写)与 4 例信封路径;`test/qoder-adapter.test.ts` 新增 1 例端到端(HTTP 200 + 错误信封 → `SERVER` 而非 `AUTH`,且账号没有被判成「要重新登录」);新增 `test/qoder-quota.test.ts`(4 例)钉住两个新字段的归一化;`test/qoder-ui.test.tsx` 新增 2 例(说用尽时额度区给出升级页,没说时不出现)。
|
|
12
|
+
|
|
13
|
+
## 0.43.0 - 2026-10-27
|
|
14
|
+
|
|
15
|
+
- **[opendesign] MiMo V2.6 与 Qwen3.7 Max 拿回思考深度选择**
|
|
16
|
+
- **现象**:OpenDesign 线路里 MiMo V2.6 Flash / Pro 的模型下拉没有任何思考档位;按同一原则把 37 行逐条比对后,`qwen3.7-max` 也一样缺。
|
|
17
|
+
- **为什么**:这三行的能力表里写着 `reasoning: false`,依据是 command-code 注册表把同族模型的档位标注为空。但「空档位」只说明没有来源声明档位,不等于模型不思考——仓库自己的规则(`docs/opendesign-line-plan.md` §3 决策 8)就是「无档位声明的模型沿用默认三档」;而同族的 cline-pass 行(`mimo-v2.5`、`mimo-v2.5-pro`、`qwen3.7-max`)明确写作 `reasoning: true`,§2 规定两表冲突时 cline-pass 的 DSH 拼写胜出。
|
|
18
|
+
- **改法**:三行去掉 `reasoning` 字段,落到 `DEFAULT_EFFORTS` 的 `low / medium / high`;其余 34 行一字未动。
|
|
19
|
+
- **测试**:`test/opendesign-catalog.test.ts` 与 `test/opendesign-adapter.test.ts` 钉住三行的 `reasoning === true` 与三档档位。
|
|
20
|
+
|
|
21
|
+
- **[opendesign] 套餐不提供的模型不再出现在模型选择器里;设置卡里可见、可强制显示**
|
|
22
|
+
- **现象**:套餐里根本没有的模型照样出现在选择器中,选中后只会换来一次拒绝。
|
|
23
|
+
- **为什么**:网关 `GET /v1/models` 返回的其实就是「这个 Key 的套餐真正提供的 id」,但同步只把它合并进 `catalogModels`,**没有把成员关系记住**,于是投影时无从判断。
|
|
24
|
+
- **改法**:设置文档新增三态的 `servedModelIds`(`null` = 从未测量,不隐藏任何模型;数组 = 最后一次成功扫描的**并集**),同步改为遍历**所有可用账号**(每次最多 8 个)取并集,任一账号失败只损失它自己那一半,全部失败则保留旧值而不是清空;适配器与状态投影共用 `line.ts` 的唯一一份可见性规则(此前 hub 卡片自己另算一份,会把套餐外模型算进「可用」)。设置卡照常列出这些模型、hint 后缀「套餐不支持」,勾选即写入 `forceVisibleModels`(强制显示),取消勾选随选择集合一起裁剪。
|
|
25
|
+
- **三语**:`unservedBadge` / `unservedHint` 补进 zh、en、ru 三份字典。
|
|
26
|
+
- **测试**:新增 `test/opendesign-line.test.ts`(整条线挂载,hub 计数等于选择器条目数),并在 catalog / adapter / routes / model-settings / section 五个套件里补并集、拒绝一侧、从未测量、强制显示、`none` 清空与 `invert` 保留、老文档兼容等用例。
|
|
27
|
+
|
|
28
|
+
- **[opendesign] 设置文档的写入串行化,并发不再互相抹字段**
|
|
29
|
+
- **为什么**:每个 mutator 都从「读到的那份整文档」派生出整份新文档,两个并发写必然有一个人把对方刚写的字段抹掉;而目录同步是 fire-and-forget(加 Key、登录完成时都会触发),它真的能落在一次勾选的「读 → 写」之间。
|
|
30
|
+
- **改法**:`OpenDesignModelSettingsStore` 用一条 Promise 队列把 `write` / `update` / `storeCatalog` / `selectModels` / `setContextWindowOverride` 的整个读→算→写串起来,公开 `write()` 拆出 `writeUnlocked()` 供内部调用以免自锁;失败只 reject 自己的调用方、队列尾被压平,一次失败不会毒化后续写入;`read()` 仍在队列之外(热路径,且排队期间早先的写都已落盘)。
|
|
31
|
+
- **证据**:红-绿——去掉队列后,`storeCatalog` 与 `selectModels` 并发**确定性**丢字段(两次红丢的还是不同字段,正是「后写者整份覆盖」的样子),顺序性用例同时失败;加锁后连跑三次皆绿。
|
|
32
|
+
|
|
33
|
+
- **[opendesign] 长思考不再在 180 秒处被掐断**
|
|
34
|
+
- **现象**:一段较长的思考之后请求被中止,界面显示「已重试模型请求(2/3)」与 `The operation was aborted due to timeout`,最终「已停止」。
|
|
35
|
+
- **为什么**:`withAttemptTimeout` 把 `AbortSignal.timeout(180_000)` 挂到 fetch 的 signal 上**从不解除**。`AbortSignal.timeout` 是绝对计时,会跟着响应体(也就是整条思考流)走,于是它实际变成了「整条回答必须在 180 秒内结束」。本机会话记录里两次尝试分别流式了 155 秒与 173 秒,都精确地在请求发出后 180 秒整被掐断,随后重试两次同样死掉。
|
|
36
|
+
- **改法**:截止改为真正的**响应头截止**——用 `AbortController` + `setTimeout` 实现并在拿到响应头(成功或失败)时立即 `clear()`,之后流量的存活交给活动可重置的空闲看门狗(300 秒**静默**,每个 chunk 重置);新增 `headerTimeoutMs` 选项,使测试能用毫秒级预算验证这一区别。
|
|
37
|
+
- **同类排查**:全仓 85 处 `AbortSignal.timeout` / 自建 `withTimeout` / `setTimeout` / `Promise.race` 逐条核对后,只有 opendesign 这一条线路把绝对计时器挂在流式请求上(cline-pass 本来就在拿到响应头后 `clear()`,其余 10 条线路的流式路径没有绝对上限);四个从未被使用的 `CHAT_TIMEOUT_MS = 300_000` 常量补上注释,写明不得用于流式请求。
|
|
38
|
+
- **测试**:`test/opendesign-adapter.test.ts` 新增两条——截止之后才开始的流仍能跑完、响应头始终不来仍会放弃(已用红-绿证明)。
|
|
39
|
+
|
|
40
|
+
- **[kimi-code] 额度徽标不再偶尔显示一长串小数**
|
|
41
|
+
- **现象**:编写器旁的「额度 xx%」有时是 `91.96000000000001%` 这种数字,而且只在**部分**读数上出现。
|
|
42
|
+
- **为什么**:徽标显示的是「剩余」,算法是 `100 - usedPercent`。`100 - 8.04` 在二进制浮点里等于 `91.96000000000001`,而代码直接把这个差值插进字符串——两位小数的 used 里约 **三分之一** 会落在这种不友好的邻居上,所以看起来「有时候」;这不是显示精度没设够,四舍五入 used 也没用,必须在**算完之后**格式化。
|
|
43
|
+
- **改法**:`common/format.ts` 新增 `formatPercent()`(最多两位、去尾零、非有限数给 `0`),Kimi 徽标的数字与 tooltip 用同一份文本,等级仍按原始剩余量判定;Kimi 账号卡片里原有的 `percentText` 也改为复用它,两条渲染路径从此只有一个舍入规则。Command Code 徽标是同一写法,一并修掉;Antigravity / Claude / Cline Pass / GLM / MiniMax / Step 的徽标本来就先 `Math.round` 到整数,不受影响。
|
|
44
|
+
- **测试**:新增 `test/format-percent.test.ts`(含 `100 - 8.04`、负数、`NaN`、按位数截断)与 `test/kimi-code-composer-quota.test.ts`(`8.04 → 91.96%`、tooltip 同文本、等级仍按原始值、钱包回退、无数据破折号)。
|
|
45
|
+
|
|
46
|
+
- **[kimi-code] 设置页去掉底部的「用量与额度」整段:套餐、窗口与读取时间已经全部并进账号卡片**
|
|
47
|
+
- **为什么删**:那一块剩下的全是重复信息——套餐名是卡片的字标、额度窗口是卡片里那一条进度条、读取时间在卡片页脚;而它唯一还在解释的那句话(「这些事实只描述当前账号」)说明的是「页面级 vs 账号级」这个已经不存在分家。
|
|
48
|
+
- **保留两样没有别处可放的东西**,贴在账号列表下方:读失败的原因(`quotaError`)与「刷新用量」按钮。否则一次失败的用量读取在界面上就彻底没有出口——卡片只会安静地显示「尚无配额数据」。
|
|
49
|
+
- **代价**:加油包余额(`extraUsage`)随这一段一起消失,卡片里没有它的位置。有余额的账号若需要,应当把它挪进账号卡片而不是恢复整段。
|
|
50
|
+
- **测试**:`test/kimi-code-quota-ui.test.tsx` 改为断言页面上不存在该分段(标题、说明、余额文案都不再出现)、每一条进度条都在账号卡片内、重试按钮与失败原因都归属账号分组。
|
|
51
|
+
|
|
52
|
+
- **[kimi-code] 账号卡片终于能显示名字:登录时读 `/me` 取名,读用量时把昵称回写到号池**
|
|
53
|
+
- **现象**:卡片标题一直是「账号 2」这类占位。标题取的是号池行上的别名,而别名只在登录时按令牌铸造;**手机号登录的账号令牌里既没有邮箱也没有昵称**,于是 `defaultAlias` 只能回落到 `账号 N`,之后没有任何路径会再改它。
|
|
54
|
+
- **为什么以前修不掉**:昵称其实一直在读——`/me` 在每次读用量时都被调用——但它只被用来取档位名,取到的 `nickname` 只留在本次快照里;而 `fetchAccountQuota` 的「池化路径不写回」是**有意**的(号池的文件归号池写),结果是谁都没把昵称交给那张卡片。
|
|
55
|
+
- **改法**:(1) 登录在落库前读一次 `/me`,把昵称/邮箱/档位并进新凭据再存盘、再入池,新账号建行即有名字;(2) `fetchAccountQuota` 新增 `onAccount` 钩子,路由据此交给 `KimiCodeAccountPool.learnAccount()`,由号池在自己那把锁里写行;(3) 别名只在**仍是占位**(`账号 N` / `主账号`)时改成昵称,用户自己起的名字不动;(4) 重新登录不再把学到的名字冲掉(此前 `addAccount` 会用新令牌重铸别名)。
|
|
56
|
+
- **形状兼容**:`/me` 在不同网关下平铺或套 `data` / `data.userInfo` / `user` 都出现过,名字与邮箱现在逐层找,`parseUserInfo` 与 `accountFromCredentials` 不再各判一套。
|
|
57
|
+
- **不用重新登录**:已有账号打开设置页(或点「刷新用量」)就会走一次读用量,昵称随即回写。
|
|
58
|
+
- **测试**:新增 9 例——嵌套/平铺两种 profile 取词、`credentialsWithProfile` 不动令牌、`onAccount` 在池化路径被调用且失败不影响额度、`learnAccount` 的占位改名/手写别名保留/重登保留,以及两条端到端(登录取名入池、status 刷新改名)。
|
|
59
|
+
|
|
60
|
+
- **[kimi-code] 用量提示条对齐到它描述的那条进度条**
|
|
61
|
+
- **现象**:悬停提示固定右对齐,箭头又缩在离右边 34px 的位置——在 41% 满的条子上,气泡挂在最右端、箭头指着 92% 的空槽,说不上对着任何东西。
|
|
62
|
+
- **改法**:气泡改成压住「已用段末端」(`--kq-tip-x` 由百分比给出),靠近两端时按气泡宽度收回来、不越出卡片;箭头改用独立的 `--kq-tip-arrow` 偏移,哪怕气泡被推回来也仍指在已用段的末端。布局尚未发生时(首帧、jsdom)两者都退回 50% 居中。
|
|
63
|
+
- **测试**:`test/kimi-code-quota-ui.test.tsx` 新增 2 例——`--kq-tip-x` 必须等于已用比例、样式规则必须从左锚点定位且箭头不写死 `right:34px`。
|
|
64
|
+
|
|
5
65
|
## 0.42.0 - 2026-10-27
|
|
6
66
|
|
|
7
67
|
- **[kimi-code] K3.1 Pro 与 Highspeed 的额度倍率由「未公布」改为记录 2x / 4x**
|
|
@@ -47,6 +107,7 @@
|
|
|
47
107
|
|
|
48
108
|
## 0.41.0 - 2026-10-26
|
|
49
109
|
|
|
110
|
+
|
|
50
111
|
- **[kimi-code] 前缀缓存不再因为工具集变化整段重建:改走消息级工具声明,加/撤工具只动历史尾部**
|
|
51
112
|
- **现象**:会话里一旦有插件中途增删工具(例如看板的 `expose`),下一次请求的前缀就整体失效。真实会话上抓到过一次:闲置 36 分钟后续跑,`prompt=622,735 / cached=1,280`,整段 62 万 token 重算;而它的下一条立刻又把 62 万读回来,说明问题不在拼前缀的方式,在"工具表变了就重写"。
|
|
52
113
|
- **为什么能修**:这条线路的缓存按内容前缀匹配,而请求前缀的顺序是 system → tools → messages。把新工具放进顶层 `tools` 等于改前缀;把它作为 `messages[].tools` 追加到历史尾部则只增长尾巴。官方 kosong 把这个能力叫 `dynamically_loaded_tools`,本仓库的 `supportsDynamicTools` 就是它。
|
package/README.md
CHANGED
|
@@ -1303,6 +1303,7 @@ MiniMax、Kimi、Codex、Claude、Command Code 和 Antigravity 的错误处理
|
|
|
1303
1303
|
| Kimi Code 额度显示为空 | 卡片会同时给出失败原因(`/v1/usages` 的 401/403/5xx 文案),按提示处理后点「刷新用量」重试;确认用的是订阅账号——开放平台的 key 在这里不会被接受 |
|
|
1304
1304
|
| Kimi Code 报「rejected the stored credential (401). Sign in again…」但发消息却是好的 | 这是**过期 access token**,不是被拒的账号:Kimi 的 access token 只有 **15 分钟**,而设置卡片过去会把号池里存着的那个 token 直接拿去查用量,因此只要 15 分钟内没走过一次 Kimi 请求,卡片就必然拿到 401。现在卡片会先刷新再请求(401 还会触发一次强制续期),因此**不必重新登录**;若卡片仍提示重新登录,才是真的刷新令牌被拒,按提示处理即可 |
|
|
1305
1305
|
| Kimi Code 账号一栏为空 | 账号身份取自 OAuth token 自身的 JWT 声明,套餐名取自 `/me`(`/usages` 自 2026-09 起不再返回 `user_level_name`)。重新登录或点「刷新用量」即可写入;若仍为空但显示「已登录」,点「测试连接」可确认凭据是否仍被接受 |
|
|
1306
|
+
| Kimi Code 账号卡片标题是「账号 2」而不是名字 | 卡片的标题就是号池里那一行的别名。别名在登录时只能由令牌铸造,而**手机号登录的账号令牌里既没有邮箱也没有昵称**,所以过去一律回落到「账号 N」。现在登录会在落库前读一次 `/me`,读用量时也会把 `/me` 的昵称回写到该行,于是标题变成昵称(邮箱账号则是邮箱);**你自己改过的名字不会被覆盖**。已有账号点一下「刷新用量」(或重开设置页)即可改名,不必重新登录 |
|
|
1306
1307
|
| Claude 相关接口返回 403 | 403 现在是**同源校验**的结果(修改状态的路由只接受同源 JSON POST)。若出现在浏览器里,检查是否从其它来源发起了请求;插件已不再有任何"确认后才能用"的门禁 |
|
|
1307
1308
|
| 授权后粘贴授权码报「请把 # 后面的部分一起复制」 | 手动流程需要 `<授权码>#<state>` **整段**。只粘贴授权码是不被接受的:用流程自己的 state 顶上会架空 state 参数、把粘贴框变成登录 CSRF 的入口,因此插件宁可报错也不猜 |
|
|
1308
1309
|
| loopback 回调收不到 / 端口绑定失败 | 端口探测失败会自动**降级为手动粘贴**(卡片会说明原因),照提示粘贴授权码即可。另:若浏览器把 `localhost` 解析到 `::1`,依赖浏览器的跨地址族回退可达本机 v4 监听,这是**假定**而非实测 |
|