dsh-budget-handoff

usagetested: passnpmMIT

Session budget gate for DeepSeek Harness: prices every turn against the official price table, warns at 80%, stops the task at 100%, and writes a handoff snapshot so the next session can continue the work.

下载量 / Downloads
1,422
依赖体积 / node_modules
0.15 MB
测试时间 / Tested
2026-11-06
DSH 版本 / Version
0.2.2-rc.1

Install

dsh plugin --profile web add dsh-budget-handoff

Sandbox test results

StageResult
1 install✓
2 list✓
3 mount✓
4 boot—

Four stages run in an isolated sandbox: install (network on) → list → mount → boot (last three with no network).

README

dsh-budget-handoff

给 DeepSeek Harness 的会话设个预算上限:花完就停,并留下一份能接着干活的交接单。

![Stars](https://github.com/ZiOstudio/dsh-budget-handoff/stargazers)

![Forks](https://github.com/ZiOstudio/dsh-budget-handoff/network/members)

![License](LICENSE)

用法

装(一条命令,装完重启 DSH):

# 推荐:装 npm 上的预构建包(免构建脚本,也不需要 allowBuilds 批准)
dsh plugin --profile <你的profile> add dsh-budget-handoff

# 或者:直接装源码仓库
dsh plugin --profile <你的profile> add github:ZiOstudio/dsh-budget-handoff
想固定在某个版本(不随主分支漂移,便于复现同样的行为),在末尾加版本号:
```sh
dsh plugin --profile <你的profile> add dsh-budget-handoff@0.4.0
dsh plugin --profile <你的profile> add github:ZiOstudio/dsh-budget-handoff#v0.4.0
```
源码安装会从 npm 拉开发依赖来跑构建;若被 pnpm 拦下,按提示把该包加进 profile 的 allowBuilds,或直接改用上面的 npm 包。

然后在会话里直接发这三条:

你发 · 作用

/budget 5 · 本会话预算设为 5 元

/budget · 查还剩多少

/budget 20 · 不够了,提到 20 元(要填比已花掉的钱更大的数)

/budget tokens 200000 · 本会话 Token 上限设为 20 万(只有金额算不出来时才管用,见下文)

发出去会立刻回你一句:

[预算] 本会话预算已设为 5.0000 元(已用 0.0000 元)

四条要记住的:

  • 大小写随便混 —— /Budget 5、/BUDGET 5 都认
  • 空格随便打 —— /budget 5 也行;数字可以是小数,比如 /budget 0.5
  • 不花 Token —— 这三条不经过模型,改预算本身零成本
  • 每个会话各自独立 —— A 会话设 5 元、B 会话设 20 元,互不影响

你不设的话,每个会话默认给 10 元预算。(想改掉这个默认值,见下面的「配置」)

写错了它也会说话 —— /budget abc 会明确告诉你格式不对并给出用法,不会装没听见。

装的过程可能看到若干条 missing peer 告警 —— 那些 peer 由宿主提供,属结构性噪音,不影响使用。
本包自身的 peer 已声明为 optional,剩下的告警都来自宿主侧的其它包,与本插件无关。

它会怎么管你

花到 80% —— 提醒一句,不拦你

[预算] 已用 4.0234 元,达到本会话预算 5.0000 元的 80%
剩余 0.9766 元。钱花完时任务会被停下,并写一份交接快照。
要提高预算:`/budget <金额>`

任务照常往下跑,一个会话只提醒一次。

如果某一轮把消费从 80% 以下直接顶到超过 100%,这条提醒就没有机会单独出现 ——
那种情况下,下面那条拦停通知里会多一行说明。

花到 100% —— 任务当场停住

那一步不会再执行,所以界面上看起来就是「突然不出字了」。这是正常的。

同时会出现一条通知:

[预算] 预算已耗尽,任务已停止
注意:本次消费越过了 80% 预警线,但直到耗尽才停下。
累计消费:5.0234 元 / 预算:5.0000 元
交接快照已写入:
  1. <你的工作目录>\BUDGET-STOPPED-handoff-snapshot.md
  2. <$DSH_HOME>\storages\dsh-budget-handoff\last-stop.md
打开快照可以看到「干到哪了 / 动过哪些文件 / 怎么接着干」。

价目表里没有这个模型 —— 改用 Token 把关

金额是靠价目表算出来的。会话一旦切到价目表没收录的 provider/model(自建中转、新模型、别人家的

provider),金额就永远不再增长 —— 它不涨,也就永远不会超支,金额闸门等于没了。

这时候插件不会装死,而是换一把尺子:Token 数。它对每一笔调用都存在,不需要任何价格。

  • 它平时是关着的。 只有当本会话真的出现过「算不出价」的调用,Token 闸门才会启动 ——

所以全程都有价的正常会话,不会因为这条规则被提前掐断。

  • 默认上限 500 万 Token(约等于 10 元按 Flash 输出价算出来的量级,再放宽一倍)。

要调:/budget tokens 200000。

  • 缓存命中的 Token 按十分之一计。 DeepSeek 的缓存命中价是未命中价的 1/50,如果按原样计数,

一段长对话会把 500 万这个额度迅速顶满,而实际只花了几分钱。所以判闸门时缓存读取按 0.1 折算;

回执和通知里会把「折算后」和「原始」两个数一起写出来,对账时不会觉得插件少算了。

  • 换尺子这件事会在会话里明确告诉你:
[预算] 价目表里没有 workbuddy-ai/deepseek-v4.1-flash-sg 的价格
后果:本会话的金额不再累计(它不涨,也就不会再拦停),但 Token 数照记
现在的保护:Token 上限 5,000,000,已用 128,400(折算后 34,200,缓存读取按 0.1 计)
要调上限:`/budget tokens <数量>`;想恢复金额把关:补 dist/pricing.json 或换已知模型
  • 停下来的通知也会换说法,不会让你去调金额(调了也没用):
[预算] Token 用量已达上限,任务已停止
累计 Token:5,120,000 / 上限 5,000,000(折算后;原始 6,300,000,缓存读取按 0.1 计)(金额因 37 次调用无价目表而未累计)
想彻底恢复「按钱管」,两条路:把该模型的价格补进 dist/pricing.json,或者换回价目表里的模型。
补价之后金额闸门立刻恢复,Token 闸门对新会话不再启动。

停住之后 —— 打开那份交接单

在你自己的工作目录里找 BUDGET-STOPPED-handoff-snapshot.md。它长这样:

# DSH 预算交接快照

- 生成时间:2026-10-08 04:12:07.518 (UTC+8)
- 会话 ID:session-…
- 触发位置:turn=8, step=2
- 触发口径:金额(5.0234 元 / 5.0000 元)
- 累计消费:5.0234 元 / 预算 5.0000 元
- 累计 Token:812,345 / 上限 5,000,000

## 这个任务要做什么
<你在会话里说的第一句话>

## 干到哪了
- 工作目录:D:\…
- 模型已回复:12 次
- 最近动作(旧的在上,最新的在下):
  - pwsh — List files in current directory
  - edit — snapshot.test.ts

## 动过哪些文件
- `E:\repo\src\snapshot.ts`

## 怎么接着干
1. 先看上面的「动过哪些文件」,逐个确认改动是否完整。
2. 把本会话预算调大。
3. 说一句「继续」——本快照已同时注入模型上下文,模型能看到断点。

## 详细事件(最近 10 条,供排查)

它是写给「第二天醒来的你」的,不是给排查用的日志。 取不到的字段会写成「本次没有观察到文件改动」

这类明确说明,不会出现 null 字样。

想接着干 —— 提高上限,说「继续」

规则只有一条:新上限要大于已经花掉的钱。

/budget 10
[预算] 本会话预算已设为 10.0000 元(已用 5.0234 元)

然后说一句:

继续

交接单已经同时交给了模型,所以它知道上次干到哪,不用从头再来。

⚠️ 上面那个例子能成立,是因为原来设的是 5 元、花掉了 5.0234 元 —— 提到 10 元就够接着跑。
如果你是用默认的 10 元跑光的,那 /budget 10 等于没提,得填一个比 10 大的数。
不确定花了多少?先发一个 /budget 看一眼。

如果是 Token 闸门停的,调金额没用 —— 那种情况下通知里会直接告诉你 累计 Token:… / 上限 …,

照那个数发 /budget tokens <更大的数>,再说「继续」。快照的「怎么接着干」一节也会写对是哪一条。

/budget 的完整语法

你发 · 结果

/budget · 查询当前预算与已用(金额 + Token 两行)

/budget 5 · 本会话预算设为 5 元

/budget 0.5 / /budget 12.75 · 小数可以

/budget 5 · 中间多打空格无所谓

/Budget 5 / /BUDGET 5 · 大小写随便混

/budget tokens 200000 · 本会话 Token 上限设为 200,000

/budget tokens · 查询(等同于 /budget)

/budget tokens 10 · 拒绝(低于下限 1000,一次调用就超了)

/budget abc · 明确告诉你格式不对,并给出用法

/budget 0 / /budget -1 · 拒绝(低于下限 0.0001)

/budgetx 5、预算 5 · 不是命令 —— 前缀必须独立,或后面跟一个空格

重启之后 —— 账不会清零

关掉 DSH 再打开,同一个会话接着聊时,已经花掉的钱和 Token 都还在。

  • 存在哪:<$DSH_HOME>\storages\dsh-budget-handoff\sessions.json,一个会话一条记录。
  • 存什么:累计消费、四个 Token 桶、折算后的 Token、未计价调用次数,以及你给这个会话设的金额上限与 Token 上限。
  • 什么时候写:每记一笔账后最多等 2 秒(连续记账只写一次),进程正常退出时再补一次。
  • 什么时候清:超过 30 天的会话、以及只留最新 50 个会话,其余在下次启动时被丢掉。
  • 坏处也要说清楚:这个文件是明文的,里面有会话 ID 和花费数字,没有对话内容。想从零开始,删掉它即可。

账户余额耗尽怎么办

如果账户余额先于会话预算耗尽,DeepSeek 会拒绝请求。插件认得出这个信号,并走同一套收尾:

[预算] 账户余额已耗尽,任务已停止

不需要任何配置,也不需要插件去查询余额。这一步零成本:不用凭据、不发网络请求、不调模型。


为什么需要它

让 Agent 长时间干活,最后往往是两种结局:

1. 预算失控 —— 你不知道这个会话已经烧了多少钱,等发现时额度已经用完。

2. 钱照付,活没了 —— 任务被硬中断,上下文里没留下任何「干到哪了」的记录。接手的人

(或下一次会话)只能从头再来,于是又烧一遍钱。

这个插件处理的是第二种:它不只是在钱花完时踩刹车,更是在踩刹车的那一刻,把进度抢救成一份可继承的资产。

「超预算了给我发个邮件没什么用,我睡了,它还在跑。」—— 事后通知在结构上是无效的,
因为通知到达时损失已经发生。所以这里不留通知,留交接单。

配置(一般不用动)

默认预算是 10 元,默认 Token 上限 500 万。要改全局默认值,在 profile 的 cordis.patch.yml 里给插件加 config::

- insert:
    - id: dsh-budget-handoff
      name: dsh-budget-handoff
      config:
        budgetCNY: 20.0
        tokenBudget: 10000000

字段 · 类型 · 默认 · 说明

…(truncated)

Rendered from the README published on npm. Formatted only, not edited.

Versions

Published on npm::5,最后更新 2026-10-22

Links

GitHub · Homepage · npm

Same category