@wenqi_bian/dsh-deepseek-balance
v0.1.3-alpha.2
Published
DeepSeek account balance monitor for DSH: polls GET /user/balance every 5s and shows the balance in the web UI (session header pill + settings card).
Maintainers
Readme
dsh-deepseek-balance
一个 DSH(DeepSeek Harness)插件:每 5 秒查询当前 DeepSeek API key 对应的账户余额,并在 Web 界面显示。
- 会话头部的金额胶囊——每个币种的总可用余额,带心跳圆点(绿色=数据新鲜,琥珀=上次查询失败正在重试,红色=余额低于阈值或已无可用余额)
- 设置页插件卡片(设置 → 插件 → 可配置)——余额详情(赠金 / 充值 / 可用性 / 更新时间)与插件配置
中文 | English
兼容性
面向 DSH v0.1.2-rc.1 与 v0.1.3-alpha.2(后者按 alpha.2 检出 72fde8ccca 验证)。两者都用 scripts/compat-probe.mjs 做了端到端验证(11/11 项:引导图、bundle 形态、状态端点、认证围栏、胶囊渲染、卡片折叠流程、控制台零报错)。
本插件消费的契约面——其余全是本地代码或平台 seed 表:
| 契约面 | 用途 |
| --- | --- |
| dsh.bundle.patch 行 + dsh.client 声明 | 宿主加载 + 浏览器 bundle 发现 |
| /plugins/??<pkg>/client.js 模块表闭包(window.__ModuleLoader__.load) | 浏览器半侧投递 |
| ctx.slots.inject/register | conversation.session.header.actions(胶囊)、settings.plugin.item(卡片) |
| ctx.connection.fetch.register | 共享 /api 载体上的宿主状态端点,载体自带 Host/Origin 围栏与浏览器认证 |
| 浏览器 fetch('/api/deepseek-balance') | 同源读取状态,不涉及任何 DSH 客户端服务 |
| ctx.settings.installSection / ctx.settingsScope.bind | 配置持久化 |
| ctx.locale.register | 中英文案 |
| ctx.credentials.resolve(可选) | DEEPSEEK_API_KEY;缺失时回退进程环境变量 |
| 平台 seed 行 react、react/jsx-runtime、@deepseek-ai/dsh-client-ui-primitives | 浏览器 bundle 外部依赖 |
刻意不用 connection.rpc.handle:它的路由注册经 cordis shadow 解析 owner ctx,在 0.1.3+ 对仓库外插件抛 cannot get property "webServer" without inject(仓库内没有生产代码用它)。exact Fetch 路由走同一载体、同一认证,且没有这层耦合。
不支持:0.1.1-rc.2 及更早——那一代使用不同的客户端运行时契约。
可对任意 DSH 构建自验(在源码检出中执行;探针不打进 npm 包):
node scripts/compat-probe.mjs http://127.0.0.1:3080 <boot-token> --browser打包事实:0.1.2-rc.1/0.1.3-alpha.* 线目前尚未发布到 npm,因此插件不携带任何运行时 @deepseek-ai/* 依赖——宿主半侧只把 @deepseek-ai/schemastery(纯校验)打进产物,其余全部从 DSH 安装解析;@deepseek-ai/* 的类型是手写 shim,从不作为 import 存在。
安装
插件不存任何密钥:与模型适配器共用同一个 DEEPSEEK_API_KEY 凭据引用(经 DSH 的凭据服务解析,再回退环境变量),因此在 Web Models 页存储或轮换的 key 会在下一次轮询立即生效。密钥只存在于宿主进程——浏览器永远只收到余额快照。
源码安装(当前)
npm install && npm run build # 构建宿主与浏览器半侧
dsh plugin --profile <name> add ./dsh-deepseek-balance
dsh --profile <name>或直接以 git 依赖安装(仓库带 prepare 构建;pnpm 安装后自动执行,若询问请放行):
dsh plugin --profile <name> add github:VinciBeans/dsh-deepseek-balancenpm 安装(首次发布后)
dsh plugin --profile <name> add @wenqi_bian/dsh-deepseek-balancenpm 包内附构建好的 lib/ 产物,安装即用,无需构建。
Quickstart
npm install
npm run build # lib/index.js(宿主)+ lib/client.js(浏览器)
dsh plugin --profile <name> add .
dsh --profile <name> --dump-config # 出现 "== @wenqi_bian/dsh-deepseek-balance" 层即成功
# 重启 dsh web,打开会话——胶囊出现在会话头部显示效果
胶囊显示 CNY 100.00,位于会话标题旁。悬停查看明细(赠金 / 充值 / 可用性 / 更新时间 / 最近错误);点击立即刷新。
| 状态 | 含义 |
| --- | --- |
| 绿点 | 上次查询成功(每次轮询心跳一下) |
| 琥珀点 | 上次查询失败,按下述退避策略继续重试 |
| 红色 | 余额低于阈值,或 is_available 为 false |
| 未配置密钥 | 未解析到 API key |
配置
设置卡片
设置 → 插件 → 可配置 → DeepSeek 余额:
| 字段 | 默认 | 含义 |
| --- | --- | --- |
| 查询间隔(毫秒) | 5000 | 轮询节奏,最小 1000 |
| 低余额阈值 | 10 | 按币种比较,低于时胶囊变红 |
| 密钥环境变量名 | DEEPSEEK_API_KEY | 凭据引用名称 |
| API 地址 | https://api.deepseek.com | GET /user/balance 的源 |
cordis.patch.yml
相同字段作为 entry 行的 config(作为基础层,设置卡片在其上覆盖):
- insert:
- id: deepseek-balance
name: '@wenqi_bian/dsh-deepseek-balance'
config:
intervalMs: 5000
lowBalanceThreshold: 10
apiKeyEnv: DEEPSEEK_API_KEY
baseUrl: https://api.deepseek.com失败行为
连续失败推迟下一次查询:第 1 次 → max(2×间隔, 10s);第 2 次 → max(3×间隔, 20s);第 3 次 → max(4×间隔, 30s),之后不再升级。任意一次成功即重置计数。胶囊保留最近一次成功值(琥珀点),tooltip 说明原因;从未成功则显示占位。401 明确提示密钥无效。浏览器标签页隐藏时暂停轮询,重新可见时立即刷新一次。
开发
npm install
npm run build # esbuild:lib/index.js(宿主)+ lib/client.js(浏览器)
npm run typecheck
npm test # node --test tests/在 DSH 源码检出里直接加载而不发布——entry 行可以直接指向源码文件:
# dev.cordis.yml
- insert:
- id: deepseek-balance
name: 'file:///E:/path/to/dsh-deepseek-balance/src/index.ts'注意:Windows 上 entry 的 name 必须写成 file:// URL(如上),POSIX 平台用绝对路径即可。
pnpm dsh web --patch ./dev.cordis.yml # 在 DSH 检出目录里执行宿主半侧由 tsx 直接加载;改动浏览器半侧后 npm run build 并刷新页面(或运行 DSH 的 client bundle watcher 免刷新)。用 pnpm dsh --profile <name> --dump-config 预览组合树。
工作原理
- 宿主半侧(
src/index.ts):注册deepseek-balance设置命名空间与私有 RPC 通道/deepseek-balance(connection.rpc.handle——因为 connection 服务在 web 服务器绑定后才激活,经延迟 inject 注册)。每次status调用从凭据链解析密钥并请求GET {baseUrl}/user/balance;失败以类型化错误码返回(no-key/unauthorized/network/api/invalid-response)。 - 浏览器半侧(
src/client/):一个引用计数共享轮询器同时驱动两个界面,经connection.rpc.call('/deepseek-balance', 'status')取数;胶囊(BalancePill.tsx)与设置卡片(BalanceCard.tsx)用 DSW 设计 token 渲染,文案跟随界面语言(ctx.locale,zh/en,回退 en)。
设计决策记录在 docs/adr;领域术语表见 CONTEXT.md。
许可
MIT——见 LICENSE。
