@yadsh/dsh-tool-offload
DeepSeek Harness plugin that offloads large, low-judgement tool results to small
one-shot worker agents before they enter the main model context — cutting
frontier-model tokens and cost on I/O-heavy workflows without touching how your
agent picks tools.
Features
- Result processing, not tool replacement. The original tool executes
normally under the parent agent's permissions; the plugin only rewrites the
model-facing
content of successful results in tools/post-execute. The
canonical value stays untouched for programmatic consumers.
- Deterministic routing. Allowlist/denylist tool patterns, byte and
estimated-token thresholds, and ordered selection rules pick the worker and
prompt profile — no extra LLM in the routing path.
- Cheap no-tools workers. Workers start through
ctx.subagents.start on a
spawn-style provider with toolFilter: { allow: [] } — zero inherited
model-facing tools, zero authority expansion — and an exact cheap model via
agentOptions.
- Bounded parent context. The worker receives the latest user task
(byte-capped), the tool name, and the serialized arguments behind explicit
<PARENT_TASK> / <TOOL_CALL> / <TOOL_RESULT> data boundaries, with a
prompt that treats tool output as untrusted data.
- Fail-open everywhere. Worker failure, timeout, cancellation, refusal,
empty answer, or an answer that is not actually smaller — every failure mode
falls back to the original result (
fallback.mode: original by default;
truncate and error modes available).
- Recursion-proof. Workers carry no tools and delegated child sessions are
never offloaded, so an offload worker cannot spawn another offload worker.
- Bounded fan-out. Non-blocking per-agent and global worker budgets; an
exhausted budget routes results through instead of queueing.
- Observability. Structured events (
offload.started / offload.completed
/ offload.skipped / offload.worker_failed) with byte counts, reduction
ratio, and skip reasons — never raw tool content — plus in-memory counters
exposed through ctx.toolOffload.stats().
Install
Install the published npm package by name:
dsh plugin --profile <profile> add @yadsh/dsh-tool-offload
Requires a DSH release in the >=0.1.7-rc.2 <0.2.0 range with a subagent
provider that supports tool restrictions (the in-process spawn provider).
Configuration
All keys are optional; defaults in parentheses.
| Option | Type | Default | Description |
|---|
enabled | boolean | true | Master switch; false passes every result through untouched. |
routing.mode | allowlist | denylist | allowlist | allowlist offloads only routing.allow tools; denylist offloads everything except routing.deny. |
routing.allow | string[] | read, grep, search, web_fetch | Tool names matched exactly or by prefix* glob. |
routing.deny | string[] | bash | Tools never offloaded; wins over allow. |
routing.thresholds.minBytes | number | 24000 | Byte threshold; a result qualifies when either threshold is exceeded. |
routing.thresholds.minEstimatedTokens | number | 6000 | Cheap characters / 4 token estimate threshold. |
routing.rules | Rule[] | [] | Ordered rules; first match picks the worker/prompt profile or forces passthrough. Each rule: id, match.tools, match.minBytes, action (offload/passthrough), worker, prompt. |
workers | Record | — | Named worker profiles merged over the default profile. |
workers.<name>.subagentProvider | string | spawn | DSH subagent provider; must support tool restrictions. |
workers.<name>.provider / .model | string | null | null | Model route for the worker; null inherits the parent agent's route. Configure a cheap model here. |
workers.<name>.maxTokens |
Built-in routing rules map the default tool candidates to bundled prompt
profiles: web_fetch → web-reader, grep/search → search-results,
read → code-reader; everything else uses generic.
Example cordis.patch.yml profile override:
- override:
- id: dsh-tool-offload
config:
workers:
default:
provider: zai
model: glm-4.5-air
maxTokens: 4000
routing:
allow:
- read
- grep
- web_fetch
Compatibility
- DeepSeek Harness
>=0.1.7-rc.2 <0.2.0 (tested on 0.1.7-rc.2); requires the
tools/post-execute seam and the subagents/start service with a
tool-restriction-capable provider — see compatibility.json.
- Node.js
^22.19.0 || >=24.0.0.
- Only top-level ordinary tool results are offloaded; Code Mode (
run_code)
nested dispatches pass through untouched.
Development
pnpm nx run dsh-tool-offload:lint typecheck test build
pnpm nx run dsh-tool-offload:verify # package gate
The full design document (routing policy, safety model, phased plan) lives in
docs/specs/design.md;
the behavioral contract is SPEC.md.
Credits
Inspired by Spotify's
portal-ai-plugins/shunt,
which routes I/O-heavy work to cheaper worker models. This project is a
DeepSeek Harness-native implementation and does not require Spotify Portal or
AiKA. See NOTICE.md.
License
MIT