bowenliang123/dsh-context
bowenliang123/dsh-contextDSH 上下文洞察面板:Context 仪表盘 + /context命令 + Context 浏览器,查看 Context的分类组成、内容详情、演进趋势、压缩/注入事件、统计等一站式 Context 全生命周期管理。
DSH Web GUI 的余额与成本小部件:侧边栏底部卡片显示账户余额、剩余比例条与今日花费;点击展开四层级成本明细(最近提问 / 本会话 / 今日·本项目 / 今日·全部),带名词解释与一键充值入口。零依赖,兼容 Node 24。
中文 | English
DeepSeek Harness (DSH) Web GUI 与桌面版通用的余额与成本小部件:侧边栏底部常驻卡片显示账户余额与今日花费,点击弹出五层级成本明细(余额 / 最近提问·标注会话名 / 今日·本会话 / 今日·本工作区 / 今日·所有工作区)。
| 侧边栏卡片(左下角常驻) | 点击弹出五层级成本 |
|---|---|
![]() | ![]() |
| 特点 | 本插件 | 同类插件(dsh-balance / dsh-token-price 等) |
|---|---|---|
| 零外部依赖 | ✅ 不 import 任何 @deepseek-ai/* 包,无原生模块 | ❌ 多数依赖 dsh SDK 包 |
| Node 24 兼容 | ✅ 天然兼容(零依赖设计),任何 profile 布局可加载 | ⚠️ 不少社区插件在 Node 24 下报错 |
| 启动稳定性 | ✅ 用官方 ctx.webServer 注册路由,不与 apiproxy 冲突 | ⚠️ 有的自建 HTTP 服务导致 dsh web 启动崩溃 |
| 常驻自动刷新 | ✅ 侧边栏卡片每 60s 自动刷新余额与成本,弹框点击即强刷 | 有的常驻徽章定时刷新 |
| 峰谷定价 | ✅ 内置官方 2026-09-10 峰谷价表,启动时与每 12h 自动从官方页刷新 | 部分支持 |
| 安全性 | ✅ API key 仅在宿主进程,loopback-only 守卫 | 参差不齐 |
一句话:零依赖、Node 24 就绪、在 dsh web 与桌面版都不拖垮启动的余额/成本小部件。
deepseekAccount(由 @deepseek-ai/dsh-deepseek-account-platform 提供,即官方「设置 → 账号与余额」页的同一来源,因此两处显示同一个数字,且不需要 API Key);未登录或旧版宿主(0.1.x)时回退到 DeepSeek 官方 GET /user/balance。展示 ¥ 余额,按阈值自动变色(充足 / 低于 lowThreshold 变黄 / 低于 criticalThreshold 变红);API key 只在宿主进程内读取(凭据服务),浏览器不接触密钥。deepseek-v4-flash,可在配置中改为 deepseek-v4-pro)与北京时间高峰/空闲时段自动切换。~/.dsh/sessions/ 下所有工作区的所有会话,累加今天的 token 用量 × 单价。lowThreshold)→ 红色(低于 criticalThreshold),一眼判断余额健康度。deepseek_billing 工具,可直接问模型"余额多少/今天花了多少"。host 半区 (lib/index.js)
ctx.webServer.register:
GET /api/dsh-balance/balance → 官方 /user/balance(loopback-only 守卫)
GET /api/dsh-balance/active-cost → 最近活跃会话的最近提问 + 今日·本会话(含会话名)
GET /api/dsh-balance/today-cost → 今日成本(双值:当前工作区 + 所有工作区)
依赖:零外部 @deepseek-ai/* import,任何 profile 布局均可解析
另有 deepseek_billing 工具供模型直接查询余额/成本
client 半区 (lib/client.js)
ctx.slots.inject("sidebar.footer.action")
→ 侧边栏底部常驻卡片(余额 + 今日花费,峰/谷时段状态圆点;侧边栏收起时变为 36×36 图标按钮)
→ 点击弹出五层级成本明细 + 峰谷标签 + ⓘ 名词解释
npm 安装(发布后):
dsh plugin --profile web add dsh-balance-widget
GitHub 仓库安装(开发调试):
git clone https://github.com/LL-cmyk-so/dsh-balance-widget.git
cd dsh-balance-widget
dsh plugin --profile web add "link:$(pwd)"
装完重启 dsh web 生效。
桌面版(DeepSeek Harness.app)同样支持,安装目标是 desktop profile:可在桌面版侧边栏的「插件」面板里安装,或把包加进 ~/.dsh/profiles/desktop/package.json 的依赖与 dsh.profile.bundles;装完重启桌面版生效。桌面版由 GUI 启动,本插件不依赖外部命令行,无需额外配置 PATH。
DSH 的插件配置统一放在这个文件里:
~/.dsh/profiles/web/cordis.patch.yml
说明:~ 是你的用户主目录(macOS 是 /Users/你的用户名)。
在 cordis.patch.yml 中追加以下内容(只改你需要的那几行,其余保持默认即可):
- id: balance-widget
name: dsh-balance-widget
config:
balanceBaseURL: https://api.deepseek.com # 官方余额接口(一般不用改)
balanceApiKeyEnv: DEEPSEEK_API_KEY # 凭据服务中的密钥 ref(一般不用改)
requestTimeoutMs: 5000 # 余额查询超时(毫秒)
modelId: deepseek-v4-flash # 成本计价模型(可改 deepseek-v4-pro)
lowThreshold: 5 # 余额低于此值(¥)图标变黄提醒
criticalThreshold: 1 # 余额低于此值(¥)图标变红警告
默认余额 低于 ¥5 变黄、低于 ¥1 变红。想改成"低于 ¥10 提醒、低于 ¥3 警告":
- id: balance-widget
name: dsh-balance-widget
config:
lowThreshold: 10
criticalThreshold: 3
改完重启 dsh web 生效。
如果主要使用 DeepSeek-V4-Pro 模型,把计价模型改掉,成本估算更准:
- id: balance-widget
name: dsh-balance-widget
config:
modelId: deepseek-v4-pro
注意:官方已公告 V4-Pro 将于北京时间 2026-09-14 12:00 下线——此后 V4-Pro 请求会被路由到 V4.1-Flash 并按 Flash 计费。若在这之后仍配置 deepseek-v4-pro,估算会偏高,建议使用默认的 Flash 档。
提示:cordis.patch.yml 可能有其他插件的配置行,追加时注意不要改动已有的行,只加新内容。
内置 DeepSeek 官方 2026-09-10 峰谷定价(元 / 百万 tokens),高峰时段为北京时间周一至周五(不含中国法定节假日) 09:00–12:00、14:00–18:00;其余时段全部为空闲时段,包括周末(含调休上班的周六/周日)与中国法定节假日全天,价格为空闲时段两倍。
| 模型 | 时段 | 缓存命中(输入) | 缓存未命中(输入) | 输出 |
|---|---|---|---|---|
| V4.1-Flash | 空闲 | 0.02 | 1.0 | 4.0 |
| V4.1-Flash | 高峰 | 0.04 | 2.0 | 8.0 |
| V4-Pro | 空闲 | 0.15 | 4.5 | 13.5 |
| V4-Pro | 高峰 | 0.30 | 9.0 | 27.0 |
官方页当前只列 deepseek-flash 与 deepseek-v4-pro 两列;deepseek-v4-flash、deepseek-v4-flash-vision-exp、deepseek-chat 等旧名仍可调用,按 Flash 价计费。插件在启动时与每 12h 从官方页重新解析,只有解析失败才回退上表。成本为估算值,实际以官方账单为准。
凡是日志里带 usage 的模型调用都按官方峰谷单价精确计价,包括容易被漏掉的那类:
assistant/message:正常对话与工具循环(每个 step 一条)compaction/summary:上下文压缩。它是一次真实模型调用(典型一次约 14 万 cache-read 输入 + 3.5k 输出 ≈ ¥0.017),日志里有 usage 但没有 turn;因此它计入当天/工作区成本,不会被算进「最近一次提问」未计入的只有日志里没有 usage 的辅助调用:会话标题生成(session/title-llm-request,约 200 tokens/次,30 天 36 次,量级 < 0.01%)——这部分无法从本地文件还原,已在估算误差内。
每次 web_search 的每个查询都会被 DSH 当作一次独立的辅助模型调用(@deepseek-ai/dsh-web-search-deepseek,走 Messages API 的 web_search_20250305 服务端工具,默认 deepseek-v4-flash,每个请求最多 maxUses 次)。而会话日志只记录派发前的 web/deepseek-search-llm-request 事件——不含 usage 字段,本地任何文件都查不到这些调用的真实 token 数。
插件因此按「请求次数 × 标定常数」计入:每次搜索 ≈ 6k 缓存未命中输入 + 2k 输出 token,即谷时 ¥0.014、峰时 ¥0.028(2026-09-22 用余额差标定:14 次搜索实测 ¥0.0133/次)。搜索会归到它所属的会话、工作区与「今日·全部」,但单次金额是估算值(±30% 量级)。
Search API 按次计费:官方自 2026-11-01 00:00(北京时间) 起对 Search / Fetch 按成功请求收费,¥5 / 1,000 次(即 ¥0.005/次);此前不收费。插件对 2026-11-01 之后的搜索请求额外计入 ¥0.005/次。注意:日志只记录请求、不记录这一次里真正发起了几次服务端搜索(上限 max_uses),所以按「每次查询 1 次搜索」估算(偏下限)。web_fetch 走本地 HTTP 抓取(dsh-web-fetch-http),不涉及官方 Fetch API,因此不计费。
本节面向 DSH Store / 插件审计,列出依赖、运行时权限、外部服务与失败边界。
依赖与兼容
@deepseek-ai/* 包,宿主端无第三方依赖peerDependencies["@deepseek-ai/dsh"]: >=0.1.2-rc.1 <0.3.0(DSH 兼容范围;0.1.5 / 0.1.7 / 0.2.0 实测通过)engines.node: ^22.19.0 || >=24.0.0peerDependencies["react"]: ^18.2.0(仅浏览器端渲染)运行时权限
files:只读 ~/.dsh/sessions/ 下的会话 JSONL(成本统计);不写入、不修改任何会话文件network:仅请求 DeepSeek 官方端点——api.deepseek.com(GET /user/balance,仅在未登录/旧版宿主时使用;已登录时余额走宿主的 deepseekAccount 服务,不产生本插件的网络请求)与 api-docs.deepseek.com 定价页(每 12h 抓取);不走任何第三方代理commands:不执行任何命令。会话解压改用 Node 内置 zstd(node:zlib,需 Node ≥22.15),不再依赖 zstd 可执行文件与 PATHcredentials:仅在回退路径上读取 DEEPSEEK_API_KEY(经宿主凭据服务解析),仅宿主进程使用、loopback-only 路由守卫;浏览器不接触密钥。已登录账号时余额不读任何密钥外部服务
deepseekAccount(DSH 0.2.0+ 且已登录账号时;余额与官方账号页同源,金额按官方规则截断到分)GET /user/balance(回退路径:未登录或旧版宿主;点击/60s 刷新时调用)失败边界
pricingSource 标记为 default(解析成功则为 synced)compaction/summary(上下文压缩)带 usage 却没有被计价。它是一次真实模型调用(典型一次约 14 万 cache-read 输入 + 3.5k 输出 ≈ ¥0.017),最近 30 天共 37 次,占对话成本约 0.64%。现按官方峰谷单价计入当天 / 工作区成本;因为它没有 turn,不会污染「最近一次提问」web_search 额外计入 ¥0.005(日志只记录请求、不记录实际发起了几次服务端搜索,故按「每次查询 1 次」估算,属偏下限)。web_fetch 走本地 HTTP,不涉及官方 Fetch API0.61913696 = 0.61913696);费率与官方页一致且 pricingSource: synced;totalTokens = input + output + cacheRead 在 925/925 条 usage 事件上成立;节假日/峰谷与时区规则回归通过session/title-llm-request,日志无 usage,量级 <0.01%);Pro 费率不随官方页自动同步(当前与官方一致);2027 年节假日表尚未发布,2027-01-01 起会退回「仅排除周末」$HOME,走真实路由 + 真实 zstd 帧 + 真实定价),断言节假日全天 ¥1.00、普通工作日峰窗 ¥2.00、节后首个工作日与午休/晚间边界均正确 —— 14/14 通过;用修复前的代码跑同一组用例,6 个节假日用例全部失败(¥2.00)deepseekAccount:当 DSH ≥ 0.2.0 且已登录 DeepSeek 账号时,余额改读这个服务——它就是官方「设置 → 账号与余额」页的数据来源,所以卡片与设置页显示同一个数字。金额按官方规则处理:正金额截断至分(55.6787307800000000 → 55.67,与设置页一致),充值余额 = 官方 value[]、赠金余额 = bonusWallets[],总额为两者之和,多币种各自成组GET /user/balance + DEEPSEEK_API_KEY,行为与 0.6.1 相同;账号读取失败会记一条 warn 说明原因DEEPSEEK_API_KEY,纯账号模式(不配 API Key)也能显示余额balanceSource 字段(deepseekAccount 或回退路径),便于确认这一次的数字从哪来account/getBalance 返回 ¥55.0685054200000000,插件卡片显示 ¥55.06 —— 逐分一致关于这个版本的背景,也说给我们自己听。 桌面版 0.2.0 上线后,官方在「设置 → 账号与余额」里放出了登录后的余额页。这说明官方已经承认"用户需要随时知道余额"这个痛点——只是它要多点几下才能看到,日常用起来仍然不如侧边栏常驻、一眼可读。
所以这一版还是做了适配:余额改读官方账号服务,与设置页逐分一致,并且不再需要 API Key。但我们心里清楚,官方既然已经把这个需求接过去了,这个插件被替代只是时间问题。有点不舍,不过工具的价值本来就应该由平台自己长出来——接下来进入告别期:后续只跟随 DSH 版本做必要的兼容性维护,不再扩展新功能。谢谢一路用它看住余额的每一天。
dsh-app-boot 的 evaluatePluginCompatibility),它把 peerDependencies 里每个 @deepseek-ai/dsh / @deepseek-ai/dsh-* 范围与运行时版本比对,且预发布版本参与范围匹配(semver.satisfies(..., { includePrerelease: true }));不匹配且未被豁免的 bundle 在启动时被静默跳过(loadProfileDirectory 收进 skippedBundles,不报错、也不改 manifest)。旧声明 >=0.1.2-rc.1 <0.2.0 恰好覆盖 0.2.0-rc.1(所以在 0.2.0-rc.1 桌面上一切正常,实测确认),但不覆盖 0.2.0 正式版——桌面版一升级,侧边栏卡片就会直接消失,插件管理器还会要求 dsh plugin allow-version 手动豁免。现放宽为 <0.3.0(实测覆盖 0.2.0 / 0.2.1 / 0.3.0-rc.1)SESSION_FORMAT_VERSION = 4,totalTokens = inputTokens + outputTokens + cacheReadTokens 在 394 条 usage 事件上全部成立(计价公式未变);sidebar.footer.action 槽位、dsh.client.platform === "web" 加载闸门、IconRefreshOutlineRegular 图标名均未变;插件用到的 19 个 --dsw-* token 全部存在(其中 15 个在 body[data-ds-dark-theme] 下重定义,弹层 portal 到 document.body 仍能继承主题);React 仍为 18.3.1;收起态 36×36 图标按钮与弹层定位照常package.json 的兼容范围声明与文档,运行代码无变化zstd 命令行,改用 Node 内置 zstd(node:zlib)。桌面版由 GUI 启动,进程 PATH 只有 /usr/bin:/bin:/usr/sbin:/sbin,找不到 Homebrew 的 zstd——此前在桌面端「今日花费 / 最近一次提问」等所有成本档位都会直接报错zstd -dc 输出字节级一致IconRefreshOutlineRegular + size 属性),旧名 IconRefreshOutline14 已不存在;把它当组件渲染会抛 React #130,而侧边栏槽位对崩溃条目的处理是整条摘掉——表现为「卡片闪一下、一点开就消失」。现按可用名解析并带本地 SVG 兜底@deepseek-ai/dsh-client-runtime 从不是真实包(0.1.5 与 0.1.7 都没有),浏览器端只依赖 react 与 shell 的 seed 模块document.body:侧边栏列是 overflow:hidden,收起态下弹层此前会被裁到只剩左边一小条;面板宽度跟随卡片(打开时实测,240px 起),并用 ResizeObserver 在拖动侧边栏 / 缩放窗口时实时跟随--dsw-shadow-lv3、--dsw-focus-ring-*)docs/screenshot-corner.png、README.en.md)。npm 包页面只渲染 README 正文、不解析仓库内的相对路径,所以在 npm 上两张截图和语言链接都是坏的。现改为绝对 URL:截图走 raw.githubusercontent.com,语言切换走 GitHub blob 链接web_search 的辅助模型调用完全不计入成本。DSH 对每次搜索只写一个派发前的 web/deepseek-search-llm-request 事件(无 usage),所以按会话日志计价的实现系统性漏算——实测 2026-09-22 一天 1073 次搜索全部没进账。现按「请求次数 × 标定常数」计价,并归入该搜索所属的会话 / 工作区 / 当日及当轮session.v3.jsonl.zstd,插件此前只认 session.jsonl.zstd,导致升级后新建的会话全部不可见——查看这类会话时弹层出现红色报错,今日成本也漏算(实测少约 36%)。现按「每个会话目录取最高代」发现日志;迁移会话保留的旧文件是新代的子集,因此只读最高代,避免整个会话被重复计算deepseek-flash 并下调价格,插件按模型名定位价格块的锚点因此落到页面脚注,同步"成功"却静默沿用旧高价,成本被高估约 1.7 倍。现改为按价格表行标签锚定,并把该列价格套用到全部 Flash 系名称pricingSource 取值为 default / synced(此前误写为 builtin)~/.dsh/sessions/ 下所有会话,累加今天(自然日)用量session- 前缀均可解析)/user/balance)+ 本会话成本(估算)+ Token 用量dsh --profile web --dump-config 应出现 balance-widget 条目curl -s http://127.0.0.1:3080/api/dsh-balance/balance 应返回 { ok, balance_infos, modelId }curl -s http://127.0.0.1:3080/api/dsh-balance/active-cost 应返回 { lastPrompt, todaySession, title, sessionId, peak, workspaceName, ... };加 ?session=SESSION_ID 可指定会话curl -s http://127.0.0.1:3080/api/dsh-balance/today-cost 应返回 { workspace: { cost, ..., cwd }, all: { cost, ... }, modelId }curl -s "http://127.0.0.1:3080/api/dsh-balance/last-cost?session=SESSION_ID" 仍可用,返回 { cost, inputTokens, outputTokens, modelId }MIT