@eddyskywalker/dsh-chatgpt-subscription 0.43.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 +8 -0
- package/lib/client.js +76 -38
- package/lib/client.js.map +1 -1
- package/lib/index.js +194 -22
- package/lib/types/client/locales-ru/qoder.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/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/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,14 @@
|
|
|
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
|
+
|
|
5
13
|
## 0.43.0 - 2026-10-27
|
|
6
14
|
|
|
7
15
|
- **[opendesign] MiMo V2.6 与 Qwen3.7 Max 拿回思考深度选择**
|
package/lib/client.js
CHANGED
|
@@ -15965,6 +15965,10 @@ window.__ModuleLoader__.load({
|
|
|
15965
15965
|
quotaSignedOut: "登录后这里显示账号的额度。",
|
|
15966
15966
|
quotaErrorLabel: "额度读取失败",
|
|
15967
15967
|
quotaNoUnit: "",
|
|
15968
|
+
/** 上游明说额度用尽:它是账号层面的事实,三只桶全是 0 时只有它能说清为什么被拒。 */
|
|
15969
|
+
quotaExceeded: "额度已用尽",
|
|
15970
|
+
quotaExceededHint: "上游说这个账号的额度已经用尽,请求会被拒。额度恢复之前发消息会失败:可以等周期重置,或在额度页升级套餐。",
|
|
15971
|
+
quotaUpgradeLink: "打开升级页面",
|
|
15968
15972
|
cacheSection: "缓存用量",
|
|
15969
15973
|
cacheStatScope: "本机统计(token 维度,自本进程启动累计):它回答「缓存帮了多少忙」,不是上游账单。",
|
|
15970
15974
|
cacheDesc: "Qoder 服务端自动做前缀缓存;命中量从响应的 usage.prompt_tokens_details.cached_tokens 读出(缺失时读顶层 cached_tokens)。本线路订阅没有公开的 token 单价,整页只显示 token 数字,不显示金额。",
|
|
@@ -16085,6 +16089,9 @@ window.__ModuleLoader__.load({
|
|
|
16085
16089
|
quotaSignedOut: "Sign in to see the account's quota here.",
|
|
16086
16090
|
quotaErrorLabel: "Quota read failed",
|
|
16087
16091
|
quotaNoUnit: "",
|
|
16092
|
+
quotaExceeded: "Quota exhausted",
|
|
16093
|
+
quotaExceededHint: "Upstream says this account's quota is exhausted, so requests get rejected. Sending a message fails until the quota resets: wait for the period to reset, or upgrade the plan on the quota page.",
|
|
16094
|
+
quotaUpgradeLink: "Open the upgrade page",
|
|
16088
16095
|
cacheSection: "Cache usage",
|
|
16089
16096
|
cacheStatScope: "Local statistics (tokens, accumulated since this process started): it answers \"how much the cache helped\", not the upstream bill.",
|
|
16090
16097
|
cacheDesc: "Qoder caches prefixes automatically server-side; hits are read from usage.prompt_tokens_details.cached_tokens (falling back to a top-level cached_tokens). There is no public per-token price for the subscription, so this page shows token counts only, never money.",
|
|
@@ -17198,49 +17205,71 @@ window.__ModuleLoader__.load({
|
|
|
17198
17205
|
children: busy === "quota" ? t.quotaRefreshing : t.quotaEmpty
|
|
17199
17206
|
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
17200
17207
|
className: "dsha-quota-card",
|
|
17201
|
-
children: [
|
|
17202
|
-
|
|
17203
|
-
|
|
17204
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
17205
|
-
className: "dshq-fact",
|
|
17206
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t.quotaExpiresAt }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: quota.expiresAt !== null ? formatDate$1(quota.expiresAt) : "—" })]
|
|
17207
|
-
}),
|
|
17208
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
17209
|
-
className: "dshq-fact",
|
|
17210
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t.quotaReadAt }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: formatDate$1(quota.fetchedAt) })]
|
|
17211
|
-
}),
|
|
17212
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
17213
|
-
className: "dshq-fact",
|
|
17214
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t.quotaRegion }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: regionText(quota.region, t) })]
|
|
17215
|
-
})
|
|
17216
|
-
]
|
|
17217
|
-
}), quota.buckets.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
17218
|
-
className: "dsha-empty",
|
|
17219
|
-
children: t.quotaEmpty
|
|
17220
|
-
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
17221
|
-
className: "dshq-quota-list",
|
|
17222
|
-
children: quota.buckets.map((bucket, index) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
17223
|
-
className: "dshq-quota-row",
|
|
17208
|
+
children: [
|
|
17209
|
+
quota.quotaExceeded && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
17210
|
+
className: "dshq-quota-exhausted",
|
|
17224
17211
|
children: [
|
|
17225
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("
|
|
17226
|
-
className: "dshq-quota-
|
|
17227
|
-
children:
|
|
17212
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
17213
|
+
className: "dshq-quota-exhausted-title",
|
|
17214
|
+
children: t.quotaExceeded
|
|
17228
17215
|
}),
|
|
17229
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("
|
|
17230
|
-
className: "dshq-quota-
|
|
17231
|
-
children:
|
|
17216
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
17217
|
+
className: "dshq-quota-exhausted-hint",
|
|
17218
|
+
children: t.quotaExceededHint
|
|
17232
17219
|
}),
|
|
17233
|
-
|
|
17234
|
-
|
|
17235
|
-
|
|
17236
|
-
|
|
17237
|
-
|
|
17238
|
-
percentText(bucket.used / bucket.total)
|
|
17239
|
-
]
|
|
17220
|
+
quota.upgradeUrl !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("a", {
|
|
17221
|
+
href: quota.upgradeUrl,
|
|
17222
|
+
target: "_blank",
|
|
17223
|
+
rel: "noreferrer noopener",
|
|
17224
|
+
children: t.quotaUpgradeLink
|
|
17240
17225
|
})
|
|
17241
17226
|
]
|
|
17242
|
-
},
|
|
17243
|
-
|
|
17227
|
+
}),
|
|
17228
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
17229
|
+
className: "dshq-fact-grid",
|
|
17230
|
+
children: [
|
|
17231
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
17232
|
+
className: "dshq-fact",
|
|
17233
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t.quotaExpiresAt }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: quota.expiresAt !== null ? formatDate$1(quota.expiresAt) : "—" })]
|
|
17234
|
+
}),
|
|
17235
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
17236
|
+
className: "dshq-fact",
|
|
17237
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t.quotaReadAt }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: formatDate$1(quota.fetchedAt) })]
|
|
17238
|
+
}),
|
|
17239
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
17240
|
+
className: "dshq-fact",
|
|
17241
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t.quotaRegion }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: regionText(quota.region, t) })]
|
|
17242
|
+
})
|
|
17243
|
+
]
|
|
17244
|
+
}),
|
|
17245
|
+
quota.buckets.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
17246
|
+
className: "dsha-empty",
|
|
17247
|
+
children: t.quotaEmpty
|
|
17248
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
17249
|
+
className: "dshq-quota-list",
|
|
17250
|
+
children: quota.buckets.map((bucket, index) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
17251
|
+
className: "dshq-quota-row",
|
|
17252
|
+
children: [
|
|
17253
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
17254
|
+
className: "dshq-quota-name",
|
|
17255
|
+
children: quotaBucketText(bucket.kind, t)
|
|
17256
|
+
}),
|
|
17257
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
17258
|
+
className: "dshq-quota-value",
|
|
17259
|
+
children: bucketAmountText(bucket, t)
|
|
17260
|
+
}),
|
|
17261
|
+
bucket.used !== null && bucket.total !== null && bucket.total > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
17262
|
+
className: "dshq-quota-meta",
|
|
17263
|
+
children: [
|
|
17264
|
+
t.quotaUsed,
|
|
17265
|
+
" ",
|
|
17266
|
+
percentText(bucket.used / bucket.total)
|
|
17267
|
+
]
|
|
17268
|
+
})
|
|
17269
|
+
]
|
|
17270
|
+
}, bucket.kind + ":" + index))
|
|
17271
|
+
})
|
|
17272
|
+
]
|
|
17244
17273
|
}),
|
|
17245
17274
|
moreNotes(t.moreNotes, [t.quotaDesc])
|
|
17246
17275
|
]
|
|
@@ -21098,6 +21127,9 @@ window.__ModuleLoader__.load({
|
|
|
21098
21127
|
quotaSignedOut: "Войдите, чтобы увидеть здесь квоту аккаунта.",
|
|
21099
21128
|
quotaErrorLabel: "Не удалось прочитать квоту",
|
|
21100
21129
|
quotaNoUnit: "",
|
|
21130
|
+
quotaExceeded: "Квота исчерпана",
|
|
21131
|
+
quotaExceededHint: "Апстрим сообщает, что квота этого аккаунта исчерпана, поэтому запросы отклоняются. Отправка сообщения не удастся, пока квота не восстановится: дождитесь сброса периода или смените тариф на странице квоты.",
|
|
21132
|
+
quotaUpgradeLink: "Открыть страницу тарифа",
|
|
21101
21133
|
cacheSection: "Расход кеша",
|
|
21102
21134
|
cacheStatScope: "Локальная статистика (в токенах, с начала работы процесса): она отвечает, насколько помог кеш, и не является счётом апстрима.",
|
|
21103
21135
|
cacheDesc: "Qoder кеширует префиксы на сервере автоматически; попадания читаются из usage.prompt_tokens_details.cached_tokens (при отсутствии — из верхнеуровневого cached_tokens). У подписки нет публичной цены за токен, поэтому страница показывает только токены, без денег.",
|
|
@@ -23383,6 +23415,12 @@ window.__ModuleLoader__.load({
|
|
|
23383
23415
|
.dshq-quota-name{color:var(--dsw-alias-label-primary);font-size:12px;min-width:104px}
|
|
23384
23416
|
.dshq-quota-value{color:var(--dsw-alias-label-secondary);font-size:12px}
|
|
23385
23417
|
.dshq-quota-meta{color:var(--dsw-alias-label-tertiary);font-size:11px}
|
|
23418
|
+
/* 额度用尽:账号层面的一条事实(上游明说),与三只桶的数字并排给出。 */
|
|
23419
|
+
.dshq-quota-exhausted{margin-top:11px}
|
|
23420
|
+
.dshq-quota-exhausted-title{color:var(--dsw-alias-label-primary);font-size:12px;font-weight:600}
|
|
23421
|
+
.dshq-quota-exhausted-hint{color:var(--dsw-alias-label-secondary);font-size:12px;line-height:1.5;margin-top:4px}
|
|
23422
|
+
.dshq-quota-exhausted a{color:var(--dsw-alias-label-link,#397ee8);font-size:12px;text-decoration:none}
|
|
23423
|
+
.dshq-quota-exhausted a:hover{text-decoration:underline}
|
|
23386
23424
|
/* 快照卡里的几行事实:紧凑网格,一格一件事,行高一致。 */
|
|
23387
23425
|
.dshq-fact-grid{display:grid;gap:9px 20px;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));margin-top:11px}
|
|
23388
23426
|
.dshq-fact{display:flex;flex-direction:column;gap:3px;min-width:0}
|