chore: 插件更名为 dsh-balance,README 增加支持矩阵

- 目录/包名 deepseek-balance → dsh-balance(cordis.patch.yml、dsh.plugin.json、
  install.sh、client 加载 id、host 日志标签同步更新)
- README 增加支持的供应商表格(provider/供应商/展示/密钥/接口)
This commit is contained in:
GeekRicardo
2026-08-18 18:49:42 +08:00
parent a68b9a37e5
commit ac56c4743d
7 changed files with 51 additions and 50 deletions
+24 -23
View File
@@ -1,31 +1,35 @@
# deepseek-balance
# dsh-balance
DeepSeek Harness web 插件:在**输入框下方状态栏**展示当前供应商的余额/用量,按 **provider** 实时切换。
DeepSeek Harness web 插件:在**输入框下方状态栏**展示当前供应商的余额/用量,按 **provider** 实时切换(2 秒轮询),余额/用量 5 分钟缓存
| 当前模型 provider | 展示内容 | 数据源 |
| --- | --- | --- |
| `deepseek`DeepSeek 官方) | `● 本会话 ¥X.XX · ● 余额 ¥465.xx` | `DEEPSEEK_API_KEY``GET api.deepseek.com/user/balance` |
| `kimi-coding`Kimi For Coding | `5小时 3% 4h15m · 7天 31% 6d0h · 5分钟前` | `KIMI_CODING_API_KEY``GET api.kimi.com/coding/v1/usages` |
| `opencode-go`OpenCode Go | `5小时 2% 3h50m · 7天 9% 4d2h · 30天 26% 22d1h · 5分钟前` | `OPENCODE_GO_API_KEY``GET opencode.ai/zen/go/v1/usage` |
| 其他 provider | 不显示(返回 null | — |
## 支持的供应商
## 实时性(v2+ 优化)
| provider | 供应商 | 展示内容 | 密钥 | 接口 |
| --- | --- | --- | --- | --- |
| `deepseek` / `deepseek-official` | DeepSeek 官方 | `● 本会话 ¥X.XX · ● 余额 ¥465.46` | `DEEPSEEK_API_KEY` | `GET api.deepseek.com/user/balance` |
| `kimi-coding` | Kimi For Coding | `5小时 3% 4h15m · 7天 31% 6d0h · 5分钟前` | `KIMI_CODING_API_KEY`(兼容 `KIMI_CODE_API_KEY`/`KIMI_API_KEY` | `GET api.kimi.com/coding/v1/usages` |
| `opencode-go` | OpenCode Go | `5小时 8% 3h · 7天 3% 5d0h · 30天 1% 27d · 5分钟前` | `OPENCODE_GO_API_KEY`(兼容 `OPENCODE_API_KEY` | `GET opencode.ai/zen/go/v1/usage` |
| 其他 provider | — | 不显示(返回 null | — | — |
- **2 秒轮询**:切换模型/切换对话后最多 2 秒更新,不再等 60 秒
- **按 provider 判断**:用 `agentDefaultModel.currentSelection()`(当前选中,切换即更新),不再用「最近一次请求的模型」,避免切了模型但没发消息时读数停留在旧模型。
> `deepseek` 与 `deepseek-official` 是 DeepSeek 官方的两条 provider 路由(DSH 自带 `dsh-llm-deepseek` 与 pi-ai catalog),余额接口相同,都展示官方余额
## 实时性
- **2 秒轮询**:切换模型/切换对话后最多 2 秒更新。
- **按 provider 判断**:用 `agentDefaultModel.currentSelection()`(当前选中,切换即更新),不依赖「最近一次请求的模型」。
- **5 分钟缓存**:余额/用量实际查询每 5 分钟一次(host 端按 provider 缓存),切走再切回强制刷新一次。
- 切换对话:client 按 `sessionId` 变化重新加载DeepSeek 本会话花费按 session 分别累计。
- 切换对话:client 按 `sessionId` 重新加载DeepSeek 本会话花费按 session 分别累计`llm/stream` token × models.dev 单价估算)
## 一键安装
```bash
curl -fsSL https://raw.githubusercontent.com/GeekRicardo/deepseek-balance/main/install.sh | bash
curl -fsSL https://raw.githubusercontent.com/GeekRicardo/dsh-balance/main/install.sh | bash
```
脚本做的事(可先 `--dry-run` 预览):
1.`~/.dsh/profiles/web/package.json` 写入依赖 `"deepseek-balance": "github:GeekRicardo/deepseek-balance"`
2.`deepseek-balance` 追加进 `dsh.profile.bundles`
1.`~/.dsh/profiles/web/package.json` 写入依赖 `"dsh-balance": "github:GeekRicardo/dsh-balance"`
2.`dsh-balance` 追加进 `dsh.profile.bundles`
3. `cd ~/.dsh/profiles/web && pnpm install`
4. 校验 bundles 已注册,提示重启。
@@ -38,8 +42,8 @@ pm2 restart dsh-web # 若用 pm2 托管;否则用你的启动方式重启
## 卸载
```bash
# 1. 从 ~/.dsh/profiles/web/package.json 的 dsh.profile.bundles 移除 "deepseek-balance"
# 2. 移除 dependencies 里的 "deepseek-balance"
# 1. 从 ~/.dsh/profiles/web/package.json 的 dsh.profile.bundles 移除 "dsh-balance"
# 2. 移除 dependencies 里的 "dsh-balance"
# 3. cd ~/.dsh/profiles/web && pnpm install
# 4. 重启 DSH
```
@@ -47,24 +51,21 @@ pm2 restart dsh-web # 若用 pm2 托管;否则用你的启动方式重启
## 前置条件
- DeepSeek Harness 已初始化 web profile`~/.dsh/profiles/web` 存在)。
- `~/.dsh/.credentials.yaml` 里配置对应供应商的密钥
- DeepSeek`DEEPSEEK_API_KEY`
- Kimi Coding`KIMI_CODING_API_KEY`(也兼容 `KIMI_CODE_API_KEY` / `KIMI_API_KEY`,可选 `KIMI_CODE_BASE_URL` 覆盖)
- OpenCode Go`OPENCODE_GO_API_KEY`(也兼容 `OPENCODE_API_KEY`
- `~/.dsh/.credentials.yaml` 里配置对应供应商的密钥(见上表)。
- Node.js ≥ 20、pnpm 可用。
## 工作原理
| 半区 | 职责 |
| --- | --- |
| Host | 监听 `llm/stream` 按 session 累计 DeepSeek 官方模型的 token;经 `credentials` 读密钥,按 provider 查对应接口DeepSeek `/user/balance`、Kimi `/coding/v1/usages`5 分钟缓存;注册 `/deepseek-balance/status` HTTP route |
| Host | 监听 `llm/stream` 按 session 累计 DeepSeek 官方模型的 token;经 `credentials` 读密钥,按 provider 查对应接口;5 分钟缓存;注册 `/dsh-balance/status` HTTP route |
| Client | 在 `conversation.composer.dock` 槽位渲染状态栏,`fetch` 轮询该 route2s),按 provider 分发渲染 |
### DeepSeek 计费口径(重要)
- DeepSeek 官方 API **不返回金额**,只返回 token 数。金额是 `token × 单价` 的**估算**,不是账单。
- 单价来自第三方 [models.dev](https://models.dev)(USD/百万 token),按模型前缀匹配;拉取失败回落到内置单价;汇率固定 7.2。
- 本会话花费是**内存态**插件加载后的下一次模型调用开始累计,重启清零,不持久化。
- 本会话花费是**内存态**,插件加载后开始累计,重启清零,不持久化。
### Kimi Coding 用量口径(重要)
+4 -4
View File
@@ -1,7 +1,7 @@
# deepseek-balance bundle patch
# dsh-balance bundle patch
#
# 安装后(dependencies + dsh.profile.bundles 均含 deepseek-balance),
# 安装后(dependencies + dsh.profile.bundles 均含 dsh-balance),
# 启动时 profile boot 会合并本 patch,把插件行插入 host composition。
- insert:
- id: deepseek-balance
name: 'deepseek-balance'
- id: dsh-balance
name: 'dsh-balance'
+2 -2
View File
@@ -1,9 +1,9 @@
{
"name": "deepseek-balance",
"name": "dsh-balance",
"description": "DeepSeek Harness web 插件:状态栏展示 DeepSeek 余额与本会话估算花费",
"version": "1.0.0",
"entry": {
"name": "deepseek-balance",
"name": "dsh-balance",
"inject": []
},
"client": {
+7 -7
View File
@@ -1,13 +1,13 @@
#!/usr/bin/env bash
# =============================================================================
# deepseek-balance 一键安装脚本(macOS / Linux / Windows Git Bash
# dsh-balance 一键安装脚本(macOS / Linux / Windows Git Bash
#
# 包只在 GitHub、不发 npm,因此本脚本直接把 github 依赖写进 profile 的
# package.jsondependencies + dsh.profile.bundles),再 pnpm install 拉取。
# 下次启动 DSH 时 profile boot 会读取包内 cordis.patch.yml 自动挂载插件行。
#
# 用法:
# curl -fsSL https://raw.githubusercontent.com/GeekRicardo/deepseek-balance/main/install.sh | bash
# curl -fsSL https://raw.githubusercontent.com/GeekRicardo/dsh-balance/main/install.sh | bash
#
# 或下载后本地运行:bash install.sh [--dry-run] [--restart]
#
@@ -22,10 +22,10 @@ set -euo pipefail
for arg in "$@"; do
if [ "$arg" = "-h" ] || [ "$arg" = "--help" ]; then
cat <<'EOF'
deepseek-balance 一键安装脚本
dsh-balance 一键安装脚本
用法:
curl -fsSL https://raw.githubusercontent.com/GeekRicardo/deepseek-balance/main/install.sh | bash
curl -fsSL https://raw.githubusercontent.com/GeekRicardo/dsh-balance/main/install.sh | bash
或:bash install.sh [--dry-run] [--restart]
--dry-run 只打印将要执行的操作,不写任何文件
@@ -40,8 +40,8 @@ done
DSH_HOME="${DSH_HOME:-${HOME:-${USERPROFILE:-}}/.dsh}"
PROFILE_DIR="$DSH_HOME/profiles/web"
PKG_JSON="$PROFILE_DIR/package.json"
PKG="deepseek-balance"
GH_DEP="github:GeekRicardo/deepseek-balance"
PKG="dsh-balance"
GH_DEP="github:GeekRicardo/dsh-balance"
DRY_RUN=false
RESTART=false
@@ -116,7 +116,7 @@ if ! node -e '
const bundles = p.dsh?.profile?.bundles ?? [];
process.exit(bundles.includes(process.argv[2]) ? 0 : 1);
' "$PKG_JSON" "$PKG"; then
die "deepseek-balance 未出现在 dsh.profile.bundles 中,挂载未注册,请检查 pnpm install 输出。"
die "dsh-balance 未出现在 dsh.profile.bundles 中,挂载未注册,请检查 pnpm install 输出。"
fi
say "bundle 已注册:dsh.profile.bundles 包含 ${PKG}(下次启动自动挂载)"
+4 -4
View File
@@ -1,5 +1,5 @@
window.__ModuleLoader__.load({
id: "deepseek-balance",
id: "dsh-balance",
factory: (require) => {
var module = { exports: {} };
var exports = module.exports;
@@ -7,7 +7,7 @@ window.__ModuleLoader__.load({
var inject = ["slots"];
var STYLE_ID = "deepseek-balance-style";
var STYLE_ID = "dsh-balance-style";
var cssText =
".dsb-readout { display: inline-flex; align-items: center; gap: 10px; font-size: 11px; line-height: 1.5; " +
"color: var(--dsw-alias-label-secondary); white-space: nowrap; user-select: none; } " +
@@ -272,7 +272,7 @@ window.__ModuleLoader__.load({
var alive = true;
function load() {
var qs = sessionId ? "?sessionId=" + encodeURIComponent(String(sessionId)) : "";
fetch("/deepseek-balance/status" + qs)
fetch("/dsh-balance/status" + qs)
.then(function (r) {
return r.json();
})
@@ -312,7 +312,7 @@ window.__ModuleLoader__.load({
ensureStyle();
ctx.slots.inject("conversation.composer.dock", function () {
return ctx.slots.register(
{ name: "conversation.composer.dock", id: "deepseek-balance", order: 10, label: "余额" },
{ name: "conversation.composer.dock", id: "dsh-balance", order: 10, label: "余额" },
function (props) {
return React.createElement(StatusReadout, { sessionId: props && props.sessionId });
},
+6 -6
View File
@@ -1,4 +1,4 @@
// deepseek-balance — host faceDeepSeek + Kimi Coding 双供应商)
// dsh-balance — host faceDeepSeek + Kimi Coding 双供应商)
//
// 职责(全部进程内、可逆):
// 1. 监听 `llm/stream` 瀑布事件,按 session 累计 DeepSeek 官方模型的 token 用量。
@@ -8,7 +8,7 @@
// provider = kimi-coding → 展示 Kimi Coding 订阅用量(KIMI_CODING_API_KEY
// GET https://api.kimi.com/coding/v1/usages5 小时窗口 / 每周配额 / 刷新时间)。
// 4. 两类余额/用量都按 provider 做 5 分钟内存缓存;切走再切回强制刷新一次。
// 5. 注册 /deepseek-balance/status HTTP route 供 client 2 秒轮询。
// 5. 注册 /dsh-balance/status HTTP route 供 client 2 秒轮询。
const inject = ["webServer", "credentials", "subprocess"];
@@ -130,7 +130,7 @@ function apply(ctx) {
try {
recordUsage(options, usage);
} catch (error) {
console.error("deepseek-balance: record usage failed", error);
console.error("dsh-balance: record usage failed", error);
}
}
}
@@ -206,7 +206,7 @@ function apply(ctx) {
pricing.source = "live";
}
} catch (error) {
console.error("deepseek-balance: fetch pricing failed, using fallback", error);
console.error("dsh-balance: fetch pricing failed, using fallback", error);
} finally {
pricingPromise = null;
}
@@ -583,7 +583,7 @@ function apply(ctx) {
() =>
ctx.webServer.register({
kind: "exact",
path: "/deepseek-balance/status",
path: "/dsh-balance/status",
handler: async (req, res) => {
if (!isTrusted(req)) {
writeJson(res, 403, { ok: false, error: "forbidden" });
@@ -598,7 +598,7 @@ function apply(ctx) {
}
},
}),
"deepseek-balance: /deepseek-balance/status route",
"dsh-balance: /dsh-balance/status route",
);
}
+4 -4
View File
@@ -1,7 +1,7 @@
{
"name": "deepseek-balance",
"version": "1.0.0",
"description": "DeepSeek Harness web 插件:输入框下方状态栏展示当前供应商的余额/用量 —— DeepSeek 官方账户余额 + 本会话估算花费,或 Kimi Coding 订阅用量(5小时/7天/刷新时间)。按 provider 判断、2 秒轮询实时切换。",
"name": "dsh-balance",
"version": "1.1.0",
"description": "DeepSeek Harness web 插件:输入框下方状态栏展示当前供应商的余额/用量 —— DeepSeek 官方余额 + 本会话花费、Kimi Coding 订阅用量(5小时/7天)、OpenCode Go 订阅用量(5小时/7天/30天)。按 provider 判断、2 秒轮询实时切换、5 分钟缓存。",
"type": "module",
"main": "lib/index.js",
"exports": {
@@ -36,7 +36,7 @@
},
"repository": {
"type": "git",
"url": "https://github.com/GeekRicardo/deepseek-balance"
"url": "https://github.com/GeekRicardo/dsh-balance"
},
"peerDependencies": {
"react": "^18.2.0"