DeepSeek Harness Hub
← 返回列表

xinghe-1018/dsh-token-plan-quota

DeepSeek Harnessspec-screened在 GitHub 查看 ↗
未验证

在 DeepSeek Harness 的输入框工具行里,显示「你正在用的那家还剩多少额度」。

尚未跑自动兼容性验证,可查看页面内的依赖与入口分析。 · 最近上游提交 2026/9/19 · 已提供中文文档

跟随当前模型供应商的额度徽标:DeepSeek、千问 Token Plan、阿里云费用中心取官方真值,Moonshot / OpenRouter 已接官方端点但字段未用真 Key 核对;其余只报本实例实测。不折算 Credits、不估算余量。

综合分
30.7
GitHub 分
30.7
用户评分
★ Stars
1
周下载量
安装插件(需先安装 dsh CLI 引擎:npm install -g @deepseek-ai/dsh)
dsh plugin --profile web add xinghe-1018/dsh-token-plan-quota
该插件未发布到 npm,走 GitHub 源安装(pnpm 若拦截 prepare 脚本,按其提示在 pnpm-workspace.yaml 的 allowBuilds 中放行后重跑)
数据截至 2026/9/20(元数据每日更新 · 实装验证按队列轮转,单条结论的验证时间见上方)
用户评分
还没有人投票,来当第一个
订阅周报,不错过优质插件更新
每周一封 · 高评分插件 + 新用户活动

README

dsh-token-plan-quota

| English

在 DeepSeek Harness 的输入框工具行里,显示「你正在用的那家还剩多少额度」。

做它的起因很具体:阿里云 / 千问 Token Plan 有额度,却没有公开的额度接口——只能走控制台数据网关
(Cookie 会话),所以生态里的同类插件普遍不碰它。本插件把那套契约内置了,顺手也把有官方接口的几家
(DeepSeek、Moonshot、OpenRouter、阿里云费用中心)按真值接上。

三条口径,一眼看完:

| 口径 | 表现 |
|---|---|
| 有官方接口 → 真值 | 有分母就画余量条、报百分比;没分母就只报数——DeepSeek 余额没有"总量"这个分母,所以不画条 |
| 没有官方接口 → 标「实测」 | 只报经过本实例的 token / 次数。不折算 Credits、不按历史推算剩余、永不画条、永不报百分比 |
| 零配置 | 装完按你实际在用的供应商路由决定开哪些源;不用写 sources,也不用手填 providers |

输入框工具行里的徽标是个小胶囊,跟随当前模型的供应商切换(名字/速度/天数都在 tooltip 里):

▓▓ 75%                  官方给了分母 → 画条、报百分比
123.5万 tok  实测        没有官方分母 → 只报用了多少,绝不画条、绝不报百分比

① 徽标跟随当前模型的供应商切换——这一家官方接口给真值,切到没有官方额度接口的那家就退回「实测」:

徽标跟随模型在两家供应商之间切换

② 明细面板:官方余量卡(有官方分母才画条、才给百分比)+ 一张卡里的多窗口计量条:

明细面板:官方余量卡与多窗口计量条

③ 面板可以拖成悬浮小窗(拖标题栏,双击复位):

面板拖成悬浮小窗

④ Cookie 掉线时退回「实测」卡:官方卡变成一张写清原因的错误卡、不带任何数字,兜底的实测卡留在徽标上——
没有官方分母就不画条、不报百分比:

Cookie 掉线时退回实测卡

⑤ 按钱计费的模型也认得:DeepSeek 的余额是官方真值,但它没有"总量"这个分母 ⇒ 不画条、不报百分比,
只把「还剩多少钱、充过多少、赠过多少」原样报出来:

按钱计费的官方余额卡:没有分母就不画条

⑥ 用过的模型会显示额度:官方接口真给了分母的,才画余量条、才报百分比和周期重置日:

Token Plan 官方余量卡:有分母才画条

⑦ 切到本实例没用过的模型时不会显示额度:这一家没有官方额度接口,而实测账目里还没有它的调用记录
—— 于是徽标写「无官方额度数据」,面板只说清为什么没有,不会顺手编一个数:

没有官方额度、也没有调用记录时的实测卡

上面七张图里的余额、token 数、日期全部是合成示例,不是任何真实账号的额度(本插件不会把真实数字放进公开仓库)。
英文套只有六张:⑦ 那句解释文案宿主目前只有中文(见 ROADMAP),与其给它编一句英文,不如少一张图。
想自己复现或换图:scripts/shots/README.md。

它不做什么

这是本插件的立场,比功能列表更重要:

- 不折算 Credits,不做抵扣率,不"按历史推算剩余";
- 没有"我自己填一个额度上限"的窗口:分母只能来自官方接口,手填的上限就是编数,所以本插件没有任何
表达"周期 + 上限"的键。token-plan-window 不是自建窗口预设,它是千问 Token Plan 的本地实测账本
(不打网络,只记经过本实例的调用);
- 没有官方分母就没有百分比:实测卡永不画余量条、永不显示百分比,只报「窗口内用了多少 token / 多少次」;
- 档位配置不等于你的额度:一个窗口只有在这个套餐真回了读数时才存在(上游 quota-config 里躺着的
five_hour 上限不代表这个账号有 5 小时窗口);
- 认不准就不开:自动检测宁可少一张卡,也不会把别家的余额数字顶在你正在用的模型上;
- 不做会产生计费的探活;只用只读端点;
- 不读别的 CLI 的登录态(见明确不做的三类)。

安装

dsh plugin --profile web add dsh-token-plan-quota          # npm 包名
dsh plugin --profile web add github:xinghe-1018/dsh-token-plan-quota
dsh plugin --profile web add ./dsh-token-plan-quota        # 本地目录

dsh plugin 是 pnpm 直传到 profile 目录;本插件零第三方依赖、无构建步骤,所以不会撞上 pnpm ≥10 的
prepare 脚本白名单。装完重启一次 dsh web(bundle 与客户端入口在启动时组装)。

运行时唯一的外部资源是三枚 CDN 字体 link,加载失败自动落系统字体栈,不影响功能。

支持哪些厂家

| 厂家 | 额度来源 | 徽标上看到什么 | 验证到什么程度 |
|---|---|---|---|
| DeepSeek | ✅ 官方 /user/balance(Bearer) | 余额 + 充值 + 赠款(真值) | 真实 Key 实测 |
| 千问 Token Plan | ⚠️ 控制台数据网关(Cookie 会话,非公开 API) | 已用 % + 进度条(与订阅页同源);Cookie 没配/过期 → 退回实测卡 | 真账号实测 |
| Moonshot / Kimi 开放平台 | ✅ 官方 /v1/users/me/balance(Bearer,.cn CNY / .ai USD 两区) | 余额 + 充值 + 赠款(真值) | 端点存在性实测;字段名未用真 Key 核对 |
| OpenRouter | ✅ 官方 /api/v1/credits(Bearer) | 余额(USD)=累计充值 − 累计花费 | 端点存在性实测;字段名未用真 Key 核对 |
| 阿里云费用中心 | ✅ BssOpenApi(AK/SK 签名) | 账户余额 / 资源包余量(真值) | 逐字段对过官方 OpenAPI 元数据 |
| MiniMax、普通 Key 的 OpenAI / Gemini 等 | ❌ 官方无 Key 化额度端点 | 实测卡(只报 token/次数) | 常见路径实测过,均无端点 |

逐条端点、信封字段、单位与百分比方向陷阱见 docs/upstream-contracts.md。

只看 API host,不看控制台域名:platform.kimi.com、platform.moonshot.cn、
bailian.console.aliyun.com 这类网页控制台域名一律不参与识别——插件查的是余额接口,落在路由
baseURL 指向的 API host(api.moonshot.cn / api.moonshot.ai)上。Kimi 开放平台的 Key 与 Moonshot
开放平台是同一套账号与余额体系,所以 Key 配好后要走 api.moonshot.;若你的 baseURL 写成别的域名,
检测认不出,会退回实测卡。想强制开官方卡,别只写源名——要把它绑到你真正的路由 id 上,否则默认
panelScope: "current" 下这张卡查得到却不露面(预设自带的 providers 是 moonshot 这类通用名,不含你的路由名):

{ "sources": [{ "id": "moonshot-balance", "providers": ["kimi-open-cn"] }] }

(下表最后一列请注意:这一家的字段名还没用真 Key 核对过,强制开出来若数字不对,用 probe 对字段名。
providers 落空时宿主日志会直接提醒,不至于一边是空白面板、一边让人瞎猜。)

与相邻插件的区别

生态里已有做同类事的插件,主要是成本统计 / 费用估算方向(例如 dsh-cost-meter、dsh-token-monitor)。
本插件不抢那块,它的口径是只报真值或明确标注的实测,不折算、不估算,徽标跟随当前模型的供应商切换,
并且内置了阿里云 / 千问 Token Plan 的控制台余量契约——那一家有额度却没有公开接口,正是本插件当初被做
出来的原因。要费用报表请选前者;要“我正在用的这家还剩多少”,选这个。

零配置自动检测

宿主在用的供应商路由就是唯一事实来源,所以你不用写 sources,也不用手填 providers——历史上正是这两个
字段各写各的,导致“卡查得到却永远看不见”。识别按可信度排序,命中即停:

| 依据 | 说明 |
|---|---|
| baseURL 的 host | 最可信:路由实际打到哪。api.moonshot.cn → Moonshot 大陆区,openrouter.ai → OpenRouter,Token Plan 网关 → 千问 |
| 路由 id / 名称关键词 | 只在拿不到 host 时降级使用(出厂的 deepseek-official 就靠这条) |
| Key 前缀 | 最后的线索(sk-or- → OpenRouter) |
| 都没命中 | 给每条认不出的路由各挂一张 window: 实测源:徽标不空,只报本地 token/次数 |

本文里 provider、路由 id、providers 数组里的字符串是同一个东西:宿主 llm.listProviders() 返回的
id(比较时忽略大小写,. _ / 一律当 -)。所以 window:minimax-cn 的实测卡只在路由 id 为
minimax-cn 的模型下出现,检测自动挂的兜底卡也叫这个名字(window:minimax-cn)——两个写法指同一张卡。

两条不变量:

- 你写过的永远赢,但它是一层叠加,不是替换。autoDetect: true(默认)时,你写的 sources 先落地,
检测再补齐你没管的部分——不会因为多写了一条就把它不认识的卡全清掉。“已覆盖”只有三种精确含义:
① 你某条源的 providers 里含这个路由 id → 该路由不再追加任何源;② 你有一条同名 id 的源 → 检测不再开
同名源(skipped 记 id-taken-by-configured);③ 你写了 {"id":"","enabled":false} → 这个名字
永不再自动开(skipped 记 disabled-by-config)。此外还有第四种可能:凭据解析不到的源整个不开
(skipped 记 no-credential,并列出试过哪些引用名;不挂错误卡占地方)。
autoDetect: false 才是“以你写的为唯一事实”。
- 可解释。每张自动开出的卡带 detected: {by, rule, host, fallback},标题 tooltip 写
「按 api.moonshot.ai 自动识别 · 区 international」;快照的 detection 块交代在用路由、开了什么、
谁因何被跳过、谁没被认出——排查“这家怎么不显示”只看这一处(它只在
GET /token-plan-quota/summary 的返回里,明细面板不显示这一坨)。老宿主没有 llm 服务时静默退回配置语义。

界面

- 徽标跟随模型:订阅宿主现成的 sessions.list → modelDirectories 运行时 store,模型一切换立刻改卡,
不轮询、不打网络。优先级:有数字的官方卡 > 有数字的实测卡 > 报错的官方卡(提示去配 Cookie)。
- 一家只展示一张额度卡:官方卡有数字时收起自动挂的实测兜底卡;官方卡变错误卡时兜底必须回来。
收合发生在看得见数据的显示层,不在规划期——否则 Cookie 一过期徽标就空白。
- 一张卡可以有多个窗口:宿主按主次排进 card.meters(这是快照里的卡形状,不是手写条目的配置键),
meters[0] 与顶层数值同源、由标题行与大条表达,
其余窗口各出一行「标签 · 剩余/总额 · 已用% · 重置日」带自己的细渐变条。
- 明细是常驻小窗:可拖(按住标题栏)、可缩(右下角握柄)、位置与尺寸记进 localStorage、双击标题栏归位。
点哪儿都不会关掉它——关闭只由标题栏那颗 ✕、再点徽标或 Esc 决定。不做「点外面就关」:那是下拉菜单的语义,
而且靠选择器识别宿主输入区必然漏(线上产物里连 data-composer-card 都不存在)。
- 视觉:幽灵小控件,无边框、无状态圆点、无表情符号,余量渐变条即状态(≥70% 绿、40–70% 蓝、 卡、以及内置的 token-plan-window
(就是千问那条账本)。三者默认窗口 7 天,windowDays 可改;重置时刻由本实例第一次调用起算,
点「清本周期账本」重新起算。

配置

主配置 ~/.dsh/token-plan-quota.json——宿主每次查询前重读,改完不用重启(也可写在插件行 config,
JSON 优先级更高):

{
"autoDetect": true,
"refreshMinutes": 10,
"pollSeconds": 10,
"panelScope": "current",
"debug": false
}

下表 18 行:17 行是代码里 DEFAULTS 的键,另 1 行 moonshotRegion 不在 DEFAULTS 中——它是 Moonshot 源
通过 regionConfigKey 读取的区选择器。一个键一行,单位都写在键名里(Minutes/Seconds/Ms)。

| 键 | 默认 | 含义 |
|---|---|---|
| autoDetect | true | 按宿主在用路由自动补齐数据源。写 sources 不会把它关掉:你写的是一条叠加层,检测照样补齐你没管的路由,所以 "sources": [] 只表示"我没额外要求"(与不写等价)。设 false 才是"以你写的为唯一事实":此时什么都不写 → 回落到内置两条 deepseek-balance + token-plan-window;写 "sources": [] → 一张卡都没有 |
| sources | 无(交给检测) | 数据源清单,按顺序显示。内置源名(8 个):deepseek-balance(DeepSeek 余额)、token-plan-console(千问控制台余量,Cookie)、token-plan-window(千问本地实测账本,非自建窗口)、moonshot-balance(Moonshot/Kimi 余额)、openrouter-credits(OpenRouter 余额)、account-balance(阿里云账户余额)、fr-instances(阿里云资源包实例列表)、resource-package(阿里云资源包额度列表);或简写 window:(给任意供应商挂实测窗口);或完全自定义对象(见自定义源) |
| moonshotRegion | china-mainland | Moonshot 区:china-mainland(api.moonshot.cn,CNY)/ international(api.moonshot.ai,USD)。两区 Key 不互通,选错会 401(卡片会直接提示切区);host 与币种成对切换,不做自动探测 |
| refreshMinutes | 10 | 官方源的快照缓存分钟数:TTL = 分钟 × 60 秒,下限 15 秒,所以 "refreshMinutes": 3 就是每 3 分钟回源一次(想比 1 分钟更勤没有意义,秒级刷新请看 pollSeconds)。点面板「更新于」或带 ?fresh=1 可强制回源 |
| pollSeconds | 10 | 前端轮询秒数——只管界面多久取一次快照,实测与吞吐每次实时重算;调小让徽标速度更跟手,不会多打上游 |
| panelScope | current | 明细面板范围:current 只列 providers 里含当前路由 id 的卡 + 本实例实测;all 列全部源。所以 current 下看不到阿里云那三条——账户余额与资源包没有供应商归属,永远不进按路由过滤的视图,要看它们就设 "all" |
| showInstanceWindow | true | 明细里是否带「本实例实测用量 + 限流重试观测」这一块。它不是某个数据源的开关,也不影响 window: 卡 |
| exposeTool | true | 是否注册模型可调用工具 token_plan_quota |
| debug | false | 明细里常驻回显上游响应的字段骨架(值打码、跳过凭据字段名)。与 GET /token-plan-quota/probe?source= 输出同一份东西,区别是 debug 常驻、probe 按需单次且不用改配置 |
| endpoint | business.aliyuncs.com | 仅阿里云费用中心三个源使用:OpenAPI 接入点(国际站要换)。会自动剥掉 https:// 与末尾斜杠 |
| regionId | 无 | 仅阿里云使用:OpenAPI 的 RegionId |
| accessKeyIdRef | ALIBABA_CLOUD_ACCESS_KEY_ID | 仅阿里云使用:AccessKeyId 的凭据引用名 |
| accessKeySecretRef | ALIBABA_CLOUD_ACCESS_KEY_SECRET | 仅阿里云使用:AccessKeySecret 的凭据引用名 |
| securityTokenRef | 无 | 仅阿里云使用:STS 临时凭据的引用名(用 AK/SK 长期凭据时留空) |
| configPath | $DSH_HOME/token-plan-quota.json | 外部 JSON 配置位置(~/ 落 OS 家目录,$DSH_HOME/ 落 harness 家目录) |
| usagePath | $DSH_HOME/token-plan-quota.usage.json | 本实例账本落盘位置 |
| minIntervalMs | 1200 | 出站最小间隔(毫秒),全局节流 |
| timeoutMs | 15000 | 单次上游请求超时(毫秒,下限 1000) |

只想关掉某一张卡

sources 的一项既可以写成内置源名(字符串),也可以写成对象——选项只有对象形式带得上去,所以想关掉某一张卡,
要把那一项改成对象。这是一条排除项,不是整张清单的替换:autoDetect 保持 true,其余卡照常补齐。

{
"autoDetect": true,
"sources": [
{ "id": "deepseek-balance", "enabled": false },
{ "id": "fr-instances", "enabled": false }
]
}

- 对自动检测开出来的源同样有效:写了 {"id":"moonshot-balance","enabled":false},检测就不会再把这张卡补
回来,诊断块的 skipped 里留一条 disabled-by-config——「没认出来」和「你关掉了」这两种情况得分得开。
- 关的是这一条源,不是这个供应商——但"这家还剩什么"取决于它在不在规则表里,这一条必须说白:
- 认得出的厂家(DeepSeek / Moonshot / OpenRouter)各自只有一条官方源,关掉它就没有这张卡:
实测兜底窗口只挂在认不出的路由上,不会因此补上来。
- 千问是唯一的例外:它同时有 token-plan-console(官方)与 token-plan-window(实测)两条预设,
关掉前者,后者照旧在。
- 认不出的厂家(MiniMax 这类)本来就只有一张 window: 卡,要关它就点它的名:
{"id":"window:minimax-cn","enabled":false}( 就是路由 id,见上节)。
- 不想逐张关,就把 autoDetect 设 false 之后自己列全清单。两种做法都行,你写过的永远赢。

凭据

按顺序解析:DSH 凭据服务 → 环境变量 → ~/.dsh/.credentials.yaml → ~/.dsh/.env,每次查询重新解析,
换 Key 不用重启。

| 源 | 引用名 |
|---|---|
| DeepSeek | DEEPSEEK_API_KEY |
| Moonshot | MOONSHOT_API_KEY(须与区配对;自动检测会优先沿用路由 profile 点名的引用名,如 MOONSHOT_CN_API_KEY) |
| OpenRouter | OPENROUTER_API_KEY(sk-or-v1-…) |
| 千问 Token Plan 余量 | BAILIAN_CONSOLE_COOKIE(+ 可选 BAILIAN_CONSOLE_SECTOKEN 兜底) |
| 阿里云 | ALIBABA_CLOUD_ACCESS_KEY_ID / ALIBABA_CLOUD_ACCESS_KEY_SECRET |

Key 引用名可在 sources 条目里用 bearerRef / cookieRef 覆盖。

想看到千问的真实余量(订阅页那种「剩余量 65.1% / 总额度 10,000」):登录打开
订阅页 → F12 Network → 复制任一请求的
整行 Cookie: → 存成一行 BAILIAN_CONSOLE_COOKIE:  → 点面板「更新于」刷新。Cookie 通常能用几周,
过期后该源报错并自动退回实测卡,重贴即恢复。

自定义源

上游给了新端点、或你想把某个控制台接口接进来,不用等本插件更新——kind: "single" + fields/derive
就能覆盖"余额是差值"这类形态:

{
"sources": [{
"id": "my-balance", "label": "我的余额", "kind": "single", "metric": "money",
"url": "https://example.com/api/account", "method": "GET", "bearerRef": "MY_API_KEY",
"unit": "USD",
"fields": { "credits": ["data.total_credits", "total_credits"], "usage": ["data.total_usage", "total_usage"] },
"derive": { "total": "credits", "used": "usage", "remaining": "credits - usage" },
"providers": ["my-provider"]
}]
}

derive 只认「一个 +/-、两侧是 fields 里的引用名或数字」;任何一个操作数取不到就整条空,绝不猜数补上。
fields 的槽位名随你起(credits/usage 只是示例),它同时也是 derive 表达式里能引用的变量名;
每个槽位给多条候选路径是有意为之(同一家 API 版本间 data 信封加不加都见过)。

手写条目的全部可用键
Unrecognized keys do not throw errors; they simply have no effect (the entry object is merged in as-is), so the symptom of a mistyped key name is "the card is blank" rather than a startup failure.
This table is the authoritative list:

| Key | Where it is used | Description |
|---|---|---|
| id | Required | Source identifier; it is also the cache key and the parameter for probe?source=. If two entries use the same id, they share the cache and stack into two cards (a warning is logged); rename the second one |
| kind | Recommended | single (one reading; this is the value if omitted) / list (multiple resource list) / window (this instance's measured window, no network request) |
| label / labelEn | Title | label is the card title; if omitted, it falls back to the entry's id. When the UI language is English, labelEn is preferred (this applies to panel card headers and multi-window meter bars); only if it is unavailable does it fall back to label—the client does not translate for you, so if you want an English title, write labelEn in the entry |
| url | single / list | Endpoint. If url is written, it is an HTTP source; if url is not written and it is not a built-in source name, it is treated as Alibaba Cloud OpenAPI RPC (requires action + version) |
| method | HTTP | Defaults to GET |
| headers | HTTP | Additional request headers, merged with accept: application/json |
| jsonBody / formBody | HTTP (for POST) | JSON request body / application/x-www-form-urlencoded request body |
| bearerRef / cookieRef | HTTP | Credential reference names. Bearer type only recognizes bearerRef; cookie session type only recognizes cookieRef—it will not use a plan Key to substitute for a Cookie (or vice versa), because that would only produce a misleading error card |
| action / version / params | RPC | OpenAPI Action, version number, query parameters (params will be flattened). RPC type missing action or version will directly produce an error card |
| paginate | RPC | { "mode": "page", "request": "PageNum", "pageSize": "PageSize", "total": ["TotalCount"] }, or { "mode": "token", "request": "NextToken", "response": ["NextToken"] }; page mode pages at most 10 pages |
| fields | single | Variable name → candidate path array; only those that resolve a value enter the derive scope |
| extract | single | Paths when the upstream directly provides values: remaining, total, unit. They can also be referenced by derive |
| derive | single | Only the three keys remaining / total / used are consumed; when used is not written, if both remaining and total are present, the difference is calculated automatically |
| extra | single | Secondary information; key names are up to you; toppedUp/granted/cash/credit/quotaLimit have predefined copy |
| list / item | list | list is the array candidate path; within item you can provide name/id/remaining/total/used/unit/status/expiresAt/startsAt/cycleType/capacityType/haystack |
| metric | Display basis | money / credits / count. Default values differ by builder: handwritten single sources are money, list sources are credits, and window is count—if you want to display by token/count, write it explicitly |
| unit | Display | Fallback when the upstream does not provide a unit (such as USD); when metric:"money" and the upstream does not provide one, it falls back to CNY |
| providers | Panel ownership | Which route ids this belongs to (see "provider is the route id" above). Under panelScope:"current", if the current route is not in the list, this card is not displayed; if it is written but none match the routes in use, the host log will remind you (so you do not have to guess at a blank panel); the window: shorthand is filled in automatically |
| windowDays | window | Measured window days, default 7, minimum 1 |
| regions / region | Multi-region providers | regions is "region name → field overrides for that region (host and currency are swapped as a pair)", and region selects which region; an incorrect region will warn and fall back to the first one |
| enabled | Any | false disables this entry (no need to delete the whole block just to temporarily turn off a source) |

Keys outside the table are for built-in presets only; do not copy them when writing manually: builder, apiPrefix, consoleSite, gatewayAction, gatewayProduct,
infoUrl, secTokenRef, dashboardURL, regionConfigKey, errorHints, keywords follow each vendor's specific signing/CSRF/
envelope flow and only apply to the corresponding preset. In particular: the multi-row window in the panel (the two rows "5 hours" + "weekly") is currently only
produced by token-plan-console; a handwritten entry has only one reading; if you want to display two windows, write two sources.
For a measured window, use {"kind":"window","providers":["my-provider"],"label":"My Window","windowDays":30},
or the shorthand window:. For the complete checklist for onboarding a new vendor, see docs/adding-a-provider.md.

If the card is blank and there is no error, check in this order

1. GET /token-plan-quota/probe?source= (or temporarily enable "debug": true) — first look at which field names the upstream actually returned;
2. Check the key names character by character against the authoritative key table above: unrecognized keys do not throw errors, they simply have no effect, and the symptom is a blank card rather than a startup failure;
3. fields 的路径是否真命中了这份响应(信封加不加 data 见过两种),derive 引用的名字是否都取到了数
——任一操作数缺失就整条空;
4. 如果这张卡根本没出现,那通常不是空卡问题:凭据解析不到的源整个不开(不挂错误卡占地方),
或者被 panelScope: current 挡在视野外。看快照的 detection 块,它会写明谁被跳过、为什么。

吞吐速度(实测,不估算)

宿主包一层 llm/stream,记录首分片到 usage 分片的活跃时长。两个口径严格分开:

- 速度(生成/解码):lastTps = 输出 tokens ÷ 活跃秒;genTps = 近 5 分钟 Σ输出 ÷ Σ活跃秒
(活跃总时长  | 上游响应字段骨架(排查用) |

只接受同源请求,永不回传密钥。模型侧有 token_plan_quota 工具(status / refresh / reset)。

配合 429:settings.yaml 里给该 provider 配 retryPolicy(把 QUOTA 纳入 retryableCodes,
initialDelayMs == maxDelayMs + jitterRatio: 0 可把退避压成固定间隔)。明细的「自动重试观测」显示真实
发生的重试次数、等待秒数与生效策略——读 llm/retry 持久事件的 policyKey,不估算。

已知边界

- 实测窗口只含经过本 DSH 实例的调用:别的设备/工具消耗的额度不在内,官方折算率也不公开,
所以它只报 token/次数,不报「剩余额度」。
- 上游控制台做过「额度重置」后,本实例窗口不会自动感知,用 token_plan_quota(reset)重新起算。
- 观测计数是本次进程启动以来的;持久事实仍在会话日志里。
- 座位退化:外壳没声明 conversation.input.left 时退到 conversation.input.dock;
老外壳拿不到 react-dom 时面板退回内联 CSS 锚定,拖拽悬浮禁用。
- Moonshot / OpenRouter 的字段名尚未用真实 Key 核对(只有官方文档 + 端点存在性背书)。

明确不做的三类

以下形态需要读取其它 CLI 的本地登录态或额外强凭据,因权限与账号风险不在本插件射程内,
也不接受相关 PR——需要的人请用上面的「自定义源」自己配:

- 智谱 GLM 团队模式(Bigmodel-Organization / Bigmodel-Project)
- Kimi Code 的浏览器 Cookie / ~/.kimi-code/credentials/
- Codex·ChatGPT / Gemini CLI 的 OAuth token(~/.codex/auth.json、~/.gemini/oauth_creds.json)

免责声明

千问 Token Plan 的余量卡走的是控制台数据网关(Cookie 会话),不是公开发布的官方 API:
上游随时可能改动或拒绝;若其服务条款禁止此类访问,请不要启用该源(把 token-plan-console 从
sources 去掉,或关掉 autoDetect 后不写它)。Cookie 只从本地解析、只在进程内使用、
绝不进任何路由响应——细节见 SECURITY.md。

开发

npm run check                      # 下面七步一次跑完
node test/host.mjs                 # 379 项,离线
node test/client.mjs               # 207 项,假 React/DOM/fetch
node test/guards.mjs               # 80 项,门禁自身的行为矩阵(应报 / 应放行)
node scripts/check-manifest.mjs    # 清单自检(安装性、出站主机、许可证、零依赖)
node scripts/check-docs.mjs        # README 的可核实声明必须与代码一致
node scripts/check-refs.mjs        # 活文档里不得出现「文件:行号」引用
node scripts/check-submission.mjs  # 插件目录站投稿条目的自检

check-docs 不是装饰:它把「DEFAULTS 17 个键、配置表 18 行、8 个数据源、声明 8 个出站主机、测试 379/207 项 + guards 80 项」这些写在 README
里的数字拿去和代码与实跑结果对,数字漂了就 CI 红(已用反向用例验证它真的会失败)。

测试跨平台(临时目录取 os.tmpdir(),不依赖真实 ~/.dsh),CI 跑 node 20/22 × ubuntu/windows/macos,
外加"解包后能加载"的冒烟(npm pack → 解 tar → import lib/index.js)。
贡献流程与产品口径见 CONTRIBUTING.md,发版三步(GitHub topic / npm / 插件目录站)见
RELEASE.md。

这个仓库自己也按一套写下来的工程循环在走。这些目录在仓库里,但不随 npm 包发布:specs/(三条规格周期——
ROADMAP 对账、发布面链接、门禁加固)、workflow/(相位模板与三 lens 评审清单)、AGENTS.md(给 agent 的常驻指令)、
.specify/(Spec Kit 的规格与宪法)。要看原文走绝对链接:
workflow、
AGENTS.md、
宪法。

许可

MIT

上游仓库有新提交时邮件通知你(每天最多一封,无更新不打扰),随时一键退订。

💬 加入 DPharness 群聊

插件用法、部署报错、新插件第一时间同步——群里问,比一个人翻文档快。

点击加入 QQ 群
DPharness 群聊二维码,手机 QQ 扫码进群
扫码进群