DeepSeek Harness 插件

dsh-clawrouter

Strong-model review before risky tool calls, plus many models from one wallet.(英文原文)

跳到安装方式

来源信息

GitHub 仓库
BlockRunAI/dsh-clawrouter
最近更新
2026年8月16日
分类
安全与权限
GitHub stars
19
载体类型
plugin
目录证据
上游声明已找到 dsh.bundle
证据路径
package.json#dsh.bundle
核对版本
0.1.0-rc.8
上游核对日期
2026-08-20

该证据由上游目录提供。本站没有安装、运行或安全审核这个插件。

安装

默认先复制一段 Prompt,让 Agent 读 GitHub 仓库和源码;需要自己装时再切到命令。

复制这段 Prompt,发给 DSH、Codex 或其他 Agent,让它先读 GitHub 仓库和源码。

请先不要安装或执行任何命令。阅读这个插件的 GitHub 仓库、README 和关键源码,然后用清楚、直接的方式回答以下问题,帮助我判断它是否适合我的需求:

1. 这个插件是什么,解决什么问题;
2. 适合哪些用户和典型使用场景;
3. 安装后如何使用,并给出一个最小使用示例;
4. 有哪些已知限制,以及隐私、安全、兼容性或维护风险;
5. 给出“推荐 / 有条件推荐 / 不推荐”的明确建议和理由。

请区分仓库明确说明、根据源码推断和未知信息。证据不足时请明确说明,不要猜测或照抄 README。

GitHub:https://github.com/BlockRunAI/dsh-clawrouter
插件名:dsh-clawrouter
作者:BlockRunAI

检查来源文件

安装前先看这个插件目录里的 README 和其他文件。

文件资源管理器3 个文件
README.md来源说明 · 只读预览

<div align="center">

<img src="https://raw.githubusercontent.com/BlockRunAI/dsh-clawrouter/main/assets/banner.png" alt="dsh-clawrouter — review the dangerous command, before it runs" width="600">

<h1>A second brain for your DeepSeek Harness agent</h1>

<p>DeepSeek is fast and cheap — keep it for the loop.<br><br> <strong>This adds what it cannot do: a stronger model reviews the dangerous command before it runs.</strong><br><br> <em><!-- br:models.chatVisible -->67<!-- /br:models.chatVisible --> models from one wallet. No accounts. No API keys. No credit card.</em></p>

<br>

<img src="https://img.shields.io/badge/🛡️_Review_Before_Execute-success?style=for-the-badge" alt="Review before execute">&nbsp; <img src="https://img.shields.io/badge/🧠_Claude_Reviews_DeepSeek-black?style=for-the-badge" alt="Claude reviews DeepSeek">&nbsp; <img src="https://img.shields.io/badge/🔑_Zero_API_Keys-blue?style=for-the-badge" alt="No API keys">&nbsp; <img src="https://img.shields.io/badge/💰_x402_USDC-purple?style=for-the-badge" alt="x402 USDC">

![npm version](https://npmjs.com/package/dsh-clawrouter) ![npm downloads](https://npmjs.com/package/dsh-clawrouter) ![GitHub stars](https://github.com/BlockRunAI/dsh-clawrouter) ![CI](https://github.com/BlockRunAI/dsh-clawrouter/actions) ![TypeScript](https://typescriptlang.org) ![License: MIT](LICENSE)

![DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) ![x402 Protocol](https://x402.org) ![Base](https://base.org) ![Telegram](https://t.me/blockrunAI)

English | 中文

</div>

> 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 <!-- br:models.chatVisible -->67<!-- /br:models.chatVisible --> 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 everythingFull AccessPermission rulesdsh-clawrouter
Hands-freeNoYesYesYes
Catches rm -rf ~Only if you noticeNoOnly if you wrote the ruleYes
Understands intentYou doNothing doesNo — literal matchYes, a model reads it
Enforced whereUI promptExecutorExecutor
Failsopenclosedto a human, never open
Reviews ordinary workEverythingNothingNothingNothing

What it does

1. Review gate

When the agent proposes something destructive, a strong model (default anthropic/claude-opus-5) reads it and answers:

VerdictWhat happens
safeproceeds to the normal permission chain, untouched
dangerousdenied, with a reason the agent can act on
uncertainescalated 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 requestedclaude-opus-5deepseek-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:

Modelsmall~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:

ModelResult
google/gemini-2.5-flash, gemini-3.5-flash, gemini-3.6-flashanswered correctly
moonshot/kimi-k3answered correctly
openai/gpt-4o, gpt-4.1, gpt-5.6-solHTTP 400 after taking payment
xai/grok-4.5HTTP 503 after taking payment
anthropic/claude-sonnet-5, claude-opus-5HTTP 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. <!-- br:models.chatVisible -->67<!-- /br:models.chatVisible --> 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/clawrouter generates 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:

KeyDefaultMeaning
providerblockrunharness route key to register
walletKeyEnvBASE_CHAIN_WALLET_KEYcredential reference holding the EVM wallet key
apiUrlhttps://blockrun.ai/apiAPI root
timeoutMs300000per-request timeout
auxiliaryModel(off)model for the harness's own maintenance calls — see below
requestFeeUsd0.002flat 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