给 DeepSeek Harness 智能体加一个"第二大脑":用更强的模型在危险命令执行前先审一遍,并把 60+ 模型通过钱包签名(x402/USDC)接入到 DSH,无需 API Key。
- 语言
- TypeScript
- License
- MIT
- 分支
- main
安装
$ dsh plugin --profile web add dsh-clawrouter在终端中运行以上命令,通过 dsh CLI 安装此插件。可在右上角切换 Profile。 第一次用 dsh?看这篇新手教程
对话式安装
帮我安装 DeepSeek Harness 插件 BlockRunAI/dsh-clawrouter:先查看仓库 https://github.com/BlockRunAI/dsh-clawrouter 确认安全性,然后执行安装命令并验证插件加载成功。
把这段指令粘贴给 DSH Web GUI 里的助手,由它代你完成安装与验证。
一句话定位
给 DeepSeek Harness 智能体配一个"第二大脑":在智能体准备执行危险操作前,让一个更强的模型先读一遍这条命令再放行;同时把 BlockRun 的 60+ 模型通过钱包签名接入到 DSH,无需 API Key、没有账号、按次以 USDC 结算。
核心能力
- 在工具执行前自动审查危险命令:递归删除、原始磁盘写入、
curl | sh、强制推送、sudo、访问~/.ssh或/etc/passwd、以及会在"以后被执行"的文件写入(git hook、CI workflow、postinstall、shell 启动文件),由更强的模型判断"放行 / 拒绝 / 升级给人类" - 注册 BlockRun 这条模型路由:用 EVM 钱包签名代替 API Key,按次通过 x402 用 USDC 支付;一个钱包即用 Claude / GPT / Gemini / Grok / Kimi 等 60+ 模型
- 提供
/spend命令,查询当前会话已产生的请求次数、输入/输出 token 与按模型分组的费用 - 提供
/review命令,把任意 diff / 方案 / 结论交给审查模型做一次性人工触发评审 - 提供
/gate命令查看闸门是否真正启用并加载了哪些规则,/gate drill可在不执行任何工具的前提下用真实审查模型做一次端到端演练 - 为路线内模型支持视觉输入与推理强度(
high/max)选择,且默认仅对实际验证过的视觉模型开放图像能力
技术实现
- 语言: TypeScript(
tsup打包 ESM,主入口lib/index.js,类型声明lib/index.d.ts) - 关键依赖:
@blockrun/llm(x402 钱包签名客户端)、@deepseek-ai/schemastery(运行时配置 schema)、@deepseek-ai/cordis(DSH 插件运行时与inject: ['llm','tools','commands']注入点) - 架构模式: 双 Bundle 插件——
cordis.patch.yml在 profile 中合成blockrun-llm(provider route 注册)与blockrun-review(tools/pre-execute监听器 +/review/gate命令);审查逻辑在执行前事件中匹配规则,被命中时异步调用更强的模型并以safe/dangerous/uncertain三档裁决,闸门只能"收紧"不能"放行" - 入口文件:
src/index.ts(provider 路由 +/spend命令)、src/review.ts(闸门 +/review/gate命令)、src/adapter.ts(BlockRun LLM 适配器,封装钱包签名与流式响应)
适用场景
当你在 DSH 中担心"Full Access 太宽松,逐条审批太繁琐"的两难时,本插件提供第三选项:默认放行一切日常操作(读 / 编辑 / 构建 / 提交),只在智能体准备执行破坏性或越权操作时让更强的模型先看一眼,被拒则给出原因给智能体去修正。同时如果你想从 DeepSeek 之外借力——例如用 Claude 做审查、用 Gemini 看图、用 GPT 验证方案——本插件提供一条无需注册账号、无需 API Key 的通道,按次付费。
前置依赖与兼容性
| 依赖 | 最低版本 | 说明 |
|---|---|---|
| DeepSeek Harness | >=0.1.0-rc.6 | peerDependencies 列出 dsh-attachment / dsh-commands / dsh-credentials / dsh-launch-environment / dsh-llm / dsh-tools 六个宿主包均要求 >=0.1.0-rc.6;dsh-attachment 在 peerDependenciesMeta 标为 optional,仅视觉能力需要 |
| Node.js | >=22.19 或 >=24 | package.json#engines.node 显式声明 `^22.19 |
| Cordis | >=4.0.1 | peerDependencies."@deepseek-ai/cordis": ">=4.0.1",DSH 内部提供 |
| Base 链 USDC | ≥ 数美元 | 钱包密钥通过 EIP-3009 授权签名按次扣款;典型闸门审查约 $0.0057,$5 USDC 大约够 2500 次审查或 5 次 100K token 的 Opus 调用 |
| 平台 | 跨平台 | 无 os / cpu 限制,无 node-pty、node:sqlite 等原生模块依赖 |
安装方式
dsh plugin --profile web add dsh-clawrouter
配置项
插件向 profile 的 cordis.patch.yml 注入两行,分别是 blockrun-llm(模型路由)与 blockrun-review(闸门)。下表"用途"列写人话。
blockrun-llm 路由配置
| 配置 | 类型 | 用途 | 默认值 |
|---|---|---|---|
provider | 字符串 | 在 DSH 中这条路由的注册名 | blockrun |
walletKeyEnv | 字符串 | 持有 EVM 钱包私钥的环境变量名;插件只读取你显式指定的变量,从不扫描磁盘 | BASE_CHAIN_WALLET_KEY |
apiUrl | 字符串 | BlockRun API 入口 | https://blockrun.ai/api |
timeoutMs | 整数 | 单次请求超时 | 300000(5 分钟) |
requestFeeUsd | 数字 | 每次请求的固定费用(用于 /spend 估算) | 0.002 |
visionModels | 字符串数组 | 允许接收图像的模型清单;默认只放实测可用的模型 | google/gemini-2.5-flash、google/gemini-3.5-flash、google/gemini-3.6-flash、moonshot/kimi-k3 |
maxOutputCeiling | 整数 | 默认输出 token 上限;网关按"请求的 max_tokens"结算,因此限制上限可避免默认就被按旗舰模型全输出上限收费 | 8192 |
auxiliaryModel | 字符串 | 用于压缩上下文、生成会话标题等"维护性"调用的廉价模型;会话正文不会被改路由 | 关闭 |
blockrun-review 闸门配置
| 配置 | 类型 | 用途 | 默认值 |
|---|---|---|---|
enabled | 布尔 | 是否真的拦截工具执行;关闭时 /review 与 /gate 仍可用 | false |
reviewerProvider | 字符串 | 审查模型走哪条 provider 路由 | blockrun |
reviewerModel | 字符串 | 审查模型 id,刻意选比智能体本身更强的 | anthropic/claude-opus-5 |
timeoutMs | 整数 | 单次审查的最大等待时间 | 30000 |
reviewerMaxTokens | 整数 | 单次审查请求的最大输出 token;网关按"请求的 max_tokens"结算,因此设限可避免一次审查被按旗舰模型 128K 输出上限收费 | 512 |
onReviewerFailure | ask | deny | 审查模型连不上时是让人审批还是直接拒绝 | ask |
extraRules | 数组 | 追加自定义规则 {name, pattern, tools?};pattern 为 JS 正则源串,写错会在加载时抛错而不是悄悄跳过 | [] |
常见问题
Q: 安装后提示 ✕ missing peer 是失败了吗?
A: 不是失败。package.json 的 peerDependencies 列出的 6 个宿主包由 Harness 自己在运行时注入——这是所有官方 Bundle 的共同做法;显式依赖会让 profile 出现 cordis 第二份副本,那反而会让 instanceof LlmError 跨副本失败、错误码全部变成 UNKNOWN。验证方式是 dsh --profile web --dump-config,应看到 blockrun-llm 与 blockrun-review 两行都被合成。
Q: 钱包密钥从哪里来?我没有 API Key 啊。
A: BlockRun 用钱包签名替代 API Key。已有 BlockRun 钱包:从 ~/.blockrun/.session 或 ~/.openclaw/blockrun/wallet.key 导出;全新用户运行 npx -y @blockrun/clawrouter 生成新钱包、给地址充少量 Base 链 USDC,再 export BASE_CHAIN_WALLET_KEY=...。插件只读取你通过 walletKeyEnv 显式指定的环境变量,从不自动扫描磁盘——避免你配置的密钥被另一个密钥"暗中覆盖"。
Q: 安装后我默认用的模型变了吗?
A: 没有变化。挂载 blockrun 路由不会改 dsh-base 默认的 deepseek-official;该路由要么由你显式选择,要么被审查闸门调用。审查模型默认是 anthropic/claude-opus-5,按次以 USDC 结算。
Q: 审查闸门会拦截哪些操作?普通 git commit 会被问吗?
A: 不会。规则刻意收窄——只拦截真正不可逆或越权的操作:递归删除、原始磁盘写入、curl … | sh、force push、git reset --hard、chmod 777、sudo、访问 ~/.ssh / ~/.aws / /etc/passwd,以及"以后会被自动执行"的文件写入(git hook、CI workflow、shell 启动文件、.gitconfig、postinstall)。日常读 / 编辑 / 构建 / 提交一律放行;命令行"提到"危险命令(grep -rn "rm -rf" docs/)也不会被误报,因为规则锚定到命令起始位置。
Q: 审查模型挂了怎么办?会被静默放行吗?
A: 不会。默认 onReviewerFailure: ask——连不上时升级为人类审批;需要无人值守自动化的用户可改成 deny,让闸门直接拒绝。deny 才让闸门"闭失败"(不放过),ask 才让闸门"开失败"(让人类把关),两者都不会在网络抖动时让危险命令溜过。
Q: /gate drill 是干嘛的?我装了但没启用闸门也能跑吗?
A: /gate drill 把 rm -rf / --no-preserve-root 送过风险匹配器与真实审查模型,但绝不交给任何工具执行。它用来证明闸门真的在工作——/review 命令即使在闸门关闭时也能注册成功,所以单看 /review 能用无法证明闸门在工作;闸门未启用时 /gate drill 会直接报错("nothing to drill")。
Q: 怎么加自定义审查规则?
A: 在 profile 的 cordis.patch.yml 给 blockrun-review 的 config.extraRules 追加 {name, pattern, tools?},pattern 为 JS 正则源串,对工具渲染后的参数做匹配;tools 为空表示对所有工具生效。规则在加载时校验编译,写错会立刻抛错而不会静默跳过。
Q: 这会让我用 DeepSeek 更便宜吗?
A: 不会,本插件不替换 DeepSeek 官方账单。BlockRun 不支持 DeepSeek 的缓存命中折扣:cache 命中的 turn 在官方直连下约 $0.000056,经过本插件在 22K 输入时约 $0.007。建议主循环继续用 DeepSeek 官方,本插件用于 DeepSeek 做不到的事(更强模型审查、调用 Claude / GPT / Gemini / Grok、x402 微支付)。
上手难度
入门 — 安装即可获得 /spend 与 60+ 模型入口;闸门默认关闭,需要手动在 cordis.patch.yml 把 enabled: true 才会介入执行流,且需要你事先配置好 BASE_CHAIN_WALLET_KEY 或经过凭证服务。
已知问题与限制
- 图像请求被拒绝而非静默丢弃:未配置
dsh-attachment时通过本路由发图像会返回UNSUPPORTED,明确指出"compose @deepseek-ai/dsh-attachment"(src/serialize.ts:128-133 / README.md:288) - 对不推理的模型设置推理强度会被本地拒绝:在网关按请求结算的前提下,
reasoning_effort字段先在本地按目录判定,未声明推理能力的模型直接UNSUPPORTED而非付费后被拒(src/adapter.ts:156-164 / README.md:213) - 已发起但未结束的请求无法被
AbortSignal中断:@blockrun/llm暂不支持把信号透传到 socket,本地中止只会停止读取;底层连接在 SDK 自己的超时到达前一直占用(src/adapter.ts:218-225 / README.md:290-291) - 本插件不持久化开销到磁盘:Harness session 日志拒绝未知事件类型,外部仓库的插件无法声明其事件可忽略;
/spend给出的只是内存统计,跨进程丢失,账本以钱包余额为准(src/spend.ts:8-21 / README.md:292) - 未启用"智能路由"虚拟模型:网关存在
blockrun/auto路由器但本插件未接线,因为虚拟模型必须声明一个上下文窗口,声明最大候选会导致较小模型被错误分配长上下文,声明最小候选又会导致每次会话过早压缩(README.md:293) - 压缩可能比模型实际能力更早触发:本路由按网关目录声明的窗口汇报容量,未实测扩报以避免静默溢出;某些模型实际窗口大于目录值(README.md:294)
- 上下文溢出按请求大小而非错误文本判定:网关把上游错误统一改写为
{"message":"API request failed"},常规文本匹配全部失效,因此本插件对返回 400 且请求体超过声明窗口的请求强制判为溢出以触发压缩(src/adapter.ts:51-54 / README.md:295) - 前一轮推理内容不回传:DeepSeek 思考模式建议在 tool-call 轮回传
reasoning_content,但本路由同时服务多厂商模型,某厂商的强制字段可能是另一厂商的拒绝字段,因此多步工具调用在推理模型上可能轻微降级(README.md:296)
A second brain for your DeepSeek Harness agent
DeepSeek is fast and cheap — keep it for the loop.
This adds what it cannot do: a stronger model reviews the dangerous command before it runs.
67 models from one wallet. No accounts. No API keys. No credit card.
English | 中文
dsh-clawrouter is a DeepSeek Harness plugin that puts a stronger model in front of your agent's dangerous actions. When the agent proposes
rm -rf ~, a reviewer model reads it and answers allow / deny / ask — enforced by the real tool executor, not by a prompt. It also registers a BlockRun provider route, so the reviewer (and any of 67 models) is reachable from one wallet with no accounts and no API keys, paid per request in USDC over x402. MIT licensed.
dsh plugin --profile web add dsh-clawrouter
Why this exists
Two things people keep asking for in the Harness discussions:
「是否有类似 Codex 或者 CC 的审查模式?即额外调用模型审查指令,以解放双手?Full Access 还是太让人担心了。」 — #421 Is there a review mode like Codex or Claude Code — call an extra model to review the command, to free up my hands? Full Access is too worrying.
「使用 Full Access 模式创建并测试插件时误删了我的整个家目录」 — #461 Testing a plugin in Full Access mode, it deleted my entire home directory.
Full Access is all-or-nothing: approve every command by hand, or approve nothing and hope. This adds a third option.
How it compares
| Approve everything | Full Access | Permission rules | dsh-clawrouter | |
|---|---|---|---|---|
| Hands-free | No | Yes | Yes | Yes |
Catches rm -rf ~ | Only if you notice | No | Only if you wrote the rule | Yes |
| Understands intent | You do | Nothing does | No — literal match | Yes, a model reads it |
| Enforced where | UI prompt | — | Executor | Executor |
| Fails | — | open | closed | to a human, never open |
| Reviews ordinary work | Everything | Nothing | Nothing | Nothing |
What it does
1. Review gate
When the agent proposes something destructive, a strong model (default anthropic/claude-opus-5) reads it and answers:
| Verdict | What happens |
|---|---|
| safe | proceeds to the normal permission chain, untouched |
| dangerous | denied, with a reason the agent can act on |
| uncertain | escalated to you — the normal approval prompt |
It only ever narrows. A call the reviewer clears still faces every sandbox, permission, and approval gate you already have — and an escalation defers to them too: if a stricter policy would have denied the call, you get that denial rather than an approval prompt. This does not replace your permission system; it sits in front of it.
Enable it in your profile's cordis.patch.yml:
- id: blockrun-review
config:
enabled: true
reviewerModel: anthropic/claude-opus-5
What gets reviewed. Deliberately narrow — a gate that fires on ordinary work gets switched off, and then it protects nobody. Reads, edits and builds are never reviewed. The shipped rules flag recursive deletes, raw disk writes, fork bombs, curl … | sh, force-pushes and hard resets, chmod 777, sudo, and anything touching ~/.ssh, ~/.aws, or /etc/passwd — plus destruction that isn't spelled rm: git clean -fdx, find … -delete, git checkout -- ., terraform destroy, and npm publish (a registry will not let you take a release back).
Mentioning a command is not running one — grep -rn "rm -rf" docs/ is not flagged — and neither is writing one: a Makefile containing rm -rf build, a cleanup script, or a README quoting git reset --hard are all ordinary work. File-body arguments (content, new_string, diff, …) are treated as data, because what a file eventually does happens when something executes it, and that execution is a separate call this gate still reads. Add your own rules:
extraRules:
- name: no-prod-deploy
pattern: "deploy\\s+--env[= ]prod"
If you mistype reviewerModel, every flagged command escalates or is denied — which looks exactly like the gate working cautiously. The failure now carries the cause, so a denial reads "BlockRun does not serve model … Did you mean …?" rather than a bare timeout, and a warning is logged wherever a log exporter is composed.
When the reviewer is unreachable, the gate escalates to you (onReviewerFailure: ask, the default). It never silently allows — a safety gate that fails open is worse than none — and never hard-blocks on a network blip. Unattended automation can set deny.
What it costs to leave on
Measured, because this is the question that decides whether you keep it enabled:
| Fires on ordinary work | never — 0 of 59, including commands that merely mention a destructive one (grep -rn "rm -rf" docs/, echo "DROP TABLE" >> notes.md) |
| Misses dangerous work | none of 39, across git, containers, clusters, cloud storage, databases, and host state |
| Catches files that execute later | git hooks, CI workflows, shell startup files, launch agents, .gitconfig, .env, npm postinstall, sandbox escalation — 10 of 10, 0 false positives across 15 ordinary file edits |
| Survives evasion | \rm -rf /, command rm, env rm, eval "rm -rf $DIR", bash -c "…", | xargs rm, and heredocs piped into a shell |
| Cost when it does fire | $0.0057 on claude-opus-5, at the 512-token reviewer cap — $0.0249 without it |
| Latency when it does fire | ~3s |
| What the reviewer sees | ~356 tokens — the flagged call, not your conversation |
That figure depends on the cap. This gateway quotes from the request — input size plus the max_tokens asked for — and settles that amount whichever way the model answers, so a review that asks for room it never uses pays for it every time the gate fires. reviewerMaxTokens (512) is what keeps a two-field JSON verdict priced like one. Before 0.10.0 the reviewer inherited claude-opus-5's advertised 128,000-token output and cost $0.28–0.33 per review; if you are on an earlier version, upgrade rather than switching to a weaker reviewer.
So during normal work it is invisible: no latency, no cost, no prompts. It bills roughly half a cent on the rare command that deserves a second opinion. Both corpora are tests, so a rule that starts flagging npm test — or stops flagging kubectl delete namespace — fails CI rather than your session.
Not every dangerous action is a shell command. Writing .git/hooks/pre-commit, .github/workflows/ci.yml, or an npm postinstall runs code later — on the next commit, the next CI run with your secrets, the next npm install on someone else's machine. These are quieter than rm -rf, and worse for it: a user watching for destruction sees nothing happen at all. Measured before those rules existed, 2 of 10 were flagged.
Recall is the ceiling on everything above: a command the matcher never flags is a command the reviewer never sees. An earlier version of this table claimed nothing was missed, measured against the six commands the rules had been written for. Against the 39 above, those same rules caught one. The corpus exists so that number can never again be taken on faith.
2. /spend
/spend
What this route has cost since the process started — total, per model, tokens and flat fees separately.
You pay for what you request, not what you get. The gateway quotes from the request — input size plus the max_tokens you ask for — and settles that quoted amount whichever way the model answers. Measured against production:
max_tokens requested | claude-opus-5 | deepseek-chat |
|---|---|---|
| 16 | $0.0020 | $0.0020 |
| 1,000 | $0.0036 | $0.0020 |
| 8,000 | $0.0211 | $0.0020 |
| 60,000 | $0.1511 | $0.0027 |
Two things follow, and the second one costs real money.
There is a floor of $0.002 — a $0.001 minimum payment plus a flat $0.001 transaction fee. Below it everything quotes the same, which is why deepseek-chat barely moves in that table: it is cheap enough that even 8,000 output tokens stays under the floor. An earlier version of this section concluded from exactly that observation that billing was per request rather than per token. It was measured only on deepseek-chat, the cheapest model on the route, where the floor hides the rate entirely.
A large max_tokens is billed even when the reply is short. This is why defaultMaxTokens is capped at maxOutputCeiling (8,192) rather than taken from a model's advertised max_output. Left uncapped, claude-opus-5 advertises 128,000, and a request carrying that default quotes $0.3211 — against $0.0216 with no cap at all and $0.0036 capped at 1,000. Eighty-nine times the cost, decided by a field the caller never set. Raise maxOutputCeiling when a workload genuinely needs long replies; you are then paying for them deliberately.
Input size drives the other half of the quote. The same request at growing prompt sizes, max_tokens held small:
| Model | small | ~22K in | ~112K in |
|---|---|---|---|
openai/gpt-4.1-nano | $0.002 | $0.005 | $0.023 |
deepseek/deepseek-chat | $0.002 | $0.007 | $0.031 |
google/gemini-3.5-flash | $0.002 | $0.066 | $0.325 |
anthropic/claude-opus-5 | $0.002 | $0.217 | $1.081 |
Everything starts at the same floor and then diverges by more than thirty-fold. A coding agent holding a 100K-token context pays roughly fifteen times the floor per call on DeepSeek — and five hundred times on Opus. /spend says so whenever your average call carries a large context, and points you at your own model's rate rather than one number. It is also blind to a request that failed after paying. Your wallet balance is the authority.
Reading a 402 quote is free, so every figure above is reproducible without spending anything.
The default requestFeeUsd is 0.002 because that is what the gateway quotes: a 402 for a ~17-token request returns {"amount":"0.002000"}. BlockRun's published pricing page currently says $0.001.
3. /review
/review <paste a diff, a plan, or the agent's conclusion>
Runs the same strong model over material you choose. For the case one user reported: the agent read the right evidence, drew the wrong conclusion, and only a direct challenge surfaced the real bug.
4. /gate — check the net is actually up
/gate # is the gate armed, and with what?
/gate drill # put a dangerous command through the live reviewer
A safety feature that is quietly off is worse than one never installed, because you stopped watching. This gate can be off while everything a user can see looks right: enabled defaults to false, a patch layer replaces a row's whole config rather than merging keys, and /review registers either way — so a working /review tells you the plugin loaded and nothing about whether tool calls are being inspected.
/gate is therefore registered whether or not the gate is armed, and says which. /gate drill sends rm -rf / --no-preserve-root through the risk matcher and the real reviewer — never to a tool — and reports each stage separately, because they fail for unrelated reasons: a rule that stopped matching is a policy problem, an unreachable reviewer is a wallet or model problem. At runtime those both collapse into "escalate", which is indistinguishable from the gate working. The drill is what tells them apart. It costs one reviewer call.
5. Vision — give your agent eyes it does not have
DeepSeek serves no vision model, so this is capability rather than savings. Attach an image and a vision model reads it:
- id: blockrun-llm
config:
visionModels: [google/gemini-3.5-flash] # the default; widen as you verify
The gateway's vision tag is not sufficient, so this plugin does not trust it. Thirty-five entries carry it. Ten were sent the same inline PNG and asked its colour:
| Model | Result |
|---|---|
google/gemini-2.5-flash, gemini-3.5-flash, gemini-3.6-flash | answered correctly |
moonshot/kimi-k3 | answered correctly |
openai/gpt-4o, gpt-4.1, gpt-5.6-sol | HTTP 400 after taking payment |
xai/grok-4.5 | HTTP 503 after taking payment |
anthropic/claude-sonnet-5, claude-opus-5 | HTTP 200, upstream 400 relayed as the model's answer |
Anthropic's is the worst of these. The call returns 200 and streams [Error: 400 {"message":"Could not process image"}] as assistant text, so the harness sees an ordinary successful turn and the agent acts on the error string as though the model wrote it. This plugin now detects that exact shape — the whole message being nothing but a relayed error — and finishes the request as a failure with the status mapped as if it had arrived as one. An answer that merely mentions an error, or a turn that also called a tool, is left alone. So a model is offered image input only when the gateway tags it vision and it appears in visionModels, which defaults to the four measured to work. Both signals must agree — the tag alone over-claims, and the list alone would keep claiming vision for a model the gateway has since retagged.
Widen it yourself as you verify others; that is a config change, not a release here.
6. Reasoning effort
Reasoning models get high and max, declared per model from the catalog's reasoning tag.
max is DeepSeek's vocabulary, which the harness adopts. OpenAI's is low | medium | high, and it returns HTTP 400 after taking payment for anything else — so max is translated to each vendor's nearest value rather than refused. Asking for the most thinking available should not fail over a spelling.
Asking a model that does not reason at all is a different case, and is refused locally, before paying: openai/gpt-4o charges and then rejects reasoning_effort outright. The catalog says which models qualify, so that costs nothing to discover.
7. 67 models from one wallet
Registers a blockrun provider route. Authentication is a wallet signature, not an API key: each request is paid per call in USDC over x402. No signup, no KYC, no credit card, no per-lab account.
That matters most for models DeepSeek does not serve — Claude, GPT, Gemini, Grok — which is exactly what a reviewer needs.
Quick Start
dsh plugin --profile web add dsh-clawrouter
export BASE_CHAIN_WALLET_KEY=0x... # or store it via the credentials service
The install prints ✕ missing peer for six harness packages. That is expected. The harness itself supplies them at runtime, and every first-party bundle declares its peers the same way — the alternative, depending on them directly, gives the profile a second copy of cordis and breaks the plugin in ways that are much harder to read. Verified on a clean install: the profile composes and dsh --profile web --dump-config lists both rows. Nothing is missing.
Where does the key come from? There is no API key to paste — authentication is a wallet signature.
- Already run a BlockRun tool? You have a wallet already. The SDK keeps it at
~/.blockrun/.session, ClawRouter at~/.openclaw/blockrun/wallet.key. Export whichever exists:export BASE_CHAIN_WALLET_KEY=$(cat ~/.blockrun/.session) - No wallet yet?
npx -y @blockrun/clawroutergenerates one and prints its address. Stop it once you have the address, send it a few USDC on Base, then export the key.
This plugin reads neither file on its own. A credential nobody configured, quietly shadowing the one they did, is exactly what the harness credentials seam exists to prevent — so it only ever reads the reference you name.
$5 of USDC on Base covers about 2,500 gate reviews, which run at the $0.002 floor — and about 5 calls carrying a 100K-token context on Opus. Both figures are the same $5; fund for the way you intend to use the route rather than for its floor. The key is a reference in configuration (walletKeyEnv), resolved per request — rotating it takes effect on the very next call, and no secret enters a config file.
Configuration
blockrun-llm — the provider route:
| Key | Default | Meaning |
|---|---|---|
provider | blockrun | harness route key to register |
walletKeyEnv | BASE_CHAIN_WALLET_KEY | credential reference holding the EVM wallet key |
apiUrl | https://blockrun.ai/api | API root |
timeoutMs | 300000 | per-request timeout |
auxiliaryModel | (off) | model for the harness's own maintenance calls — see below |
requestFeeUsd | 0.002 | flat per-request fee, used by /spend — the quoted figure, see below |
Cutting compaction cost
The harness compacts long sessions by summarizing them — and it does that on whatever model the conversation is using. On a flagship model that means paying flagship input rates to summarize, repeatedly, for the whole session.
A ~100K-token compaction runs about $0.90 on Claude Opus 5 and about $0.026 on DeepSeek V4 Flash — read from live 402 quotes at that size, consistent with the table above. Summarizing is a job a cheap model does well, and those calls share no prefix with your conversation — so moving them forfeits no prompt-cache hit:
- id: blockrun-llm
config:
auxiliaryModel: deepseek/deepseek-chat
Off by default, and it only ever affects calls the harness itself marks as maintenance (compaction, session titles). A conversation request is never redirected.
blockrun-review — the gate:
| Key | Default | Meaning |
|---|---|---|
enabled | false | whether the automatic gate intercepts tool calls |
reviewerProvider | blockrun | provider route carrying the reviewer |
reviewerModel | anthropic/claude-opus-5 | use a different, stronger model than the agent |
timeoutMs | 30000 | how long one review may take |
reviewerMaxTokens | 512 | output cap asked for per review, and billed whether or not it is used |
onReviewerFailure | ask | ask escalates to you; deny blocks (unattended runs) |
extraRules | [] | additional {name, pattern, tools} risk rules |
Mounting the route does not change your default model. dsh-base keeps deepseek-official; this route is used only where you ask for it.
Honest notes
- This will not make DeepSeek cheaper. Each request is priced from its own 402 quote — $0.002 at small sizes, climbing with input — and BlockRun does not price DeepSeek's cache-hit discount. A cache-warm agent turn costs DeepSeek about $0.000056 directly against roughly $0.007 here at 22K input tokens. Keep your DeepSeek key for the loop; use this for what DeepSeek cannot do.
- The free tier is a smoke test, not a workhorse. The free NVIDIA models may use prompts for service improvement, so do not point them at a private codebase, and never use one as the reviewer.
- A review costs a model call. It runs only on flagged calls, with a 30s ceiling.
- The reviewer sees the flagged tool call, not your whole repository.
Known limitations
- Images are refused, not silently dropped — image content through this route fails with
UNSUPPORTED; vision is planned. - Reasoning-effort selection is refused rather than quietly ignored.
- An aborted request stops delivery immediately, but the in-flight HTTP request is not itself cancelled until
@blockrun/llmaccepts anAbortSignal; the socket closes on the SDK's own timeout. - This plugin does not record what it spends. Harness session logs refuse event types a build does not know, and an out-of-repo plugin cannot mark its events ignorable, so it writes no session events. It also does not reach
~/.blockrun/cost_log.jsonl: that ledger is written by@blockrun/llm'sLLMClient, and the streaming client this adapter uses tracks its spend in memory only. Check the wallet itself for now — an earlier version of this note pointed at the ledger, which would have shown you other tools' spending rather than this one's. - Smart routing (
blockrun/auto) is not wired up, and not for lack of a router. A virtual model has to report one context window, and the harness sizes compaction from it: report the largest candidate and a turn routed to a smaller model overflows with compaction never firing; report the smallest and every session compacts far too early. Until that has an honest answer, pin a model id —auxiliaryModelalready moves the expensive maintenance calls, which is where the savings actually were. - Compaction may fire earlier than it needs to. This route reports the context window the gateway's model catalog declares. Measured against the live gateway,
openai/gpt-4.1-nanoaccepted a 450,037-token prompt and recalled a marker from the very first line — no truncation, but 3.5x the 128,000 the catalog states. The harness sizes compaction from the declared figure, so a session can compact while the model would still have taken the whole thing. Reported upstream; this plugin reports what the catalog says rather than guessing higher, because over-claiming would trade early compaction for silent overflow. - Context overflow is detected by request size, not by the error text. A real overflow comes back from the gateway as
{"message":"API request failed"}— the provider's wording is sanitized away, so the usual text detectors match nothing. After a 400, a request larger than the model's declared window is therefore treated as an overflow so compaction can recover. The text detectors still run first, so this corrects itself if the gateway stops sanitizing. - Prior-turn reasoning is not sent back. DeepSeek's thinking-mode guide says
reasoning_contentshould be returned on tool-call turns, but this one route serves 67 models from many vendors, and a field one of them requires is a field another may reject. Multi-step tool use on a reasoning model may be slightly degraded as a result; please report it if you hit it.
Development
npm test # 185 offline tests, including two real-cordis-Loader compositions
npm run test:e2e # live gateway tests — spends real USDC (~$0.02); skips without a wallet
npm run sync:models # refresh the model count in both READMEs from the live catalog
npm run test:docker # install the PUBLISHED package in a clean container and assert it composes
Developing against a linked checkout (dsh plugin add /path/to/dsh-clawrouter) pulls this package's devDependencies into the profile, giving a second copy of @deepseek-ai/dsh-llm. instanceof LlmError then fails across the two copies and the harness reports every failure as UNKNOWN instead of its real code. Test error codes from a packed tarball (npm pack) rather than a link.
The live suite is the only thing that exercises the x402 handshake, because the signature is the authentication and no mock can stand in for it. It is deliberately excluded from npm test so it never runs by accident.
Changelog
See CHANGELOG.md. Several early releases fixed silent bugs, so upgrading is worth it if you are on an earlier version.
License
查看使用指南 →
该插件的安装步骤、关键要点、FAQ 与兼容性说明(基于已收录字段派生)。
收录徽章
[](https://deepseek-plugin.org/plugins/BlockRunAI/dsh-clawrouter)把这段 markdown 粘贴到你的 GitHub README,链接回本插件详情页。徽章只声明已被本站收录,不代表安全认证。