DeepSeek Harness API research
August 20, 2026 ยท View on GitHub
Research date: 2026-08-20
Tested runtime
- Local installation:
@deepseek-ai/dsh@0.1.0-rc.8 - Related local packages:
@deepseek-ai/dsh-tools@0.1.0-rc.8,@deepseek-ai/cordis@4.0.1 - Runtime: Node.js 22.19.0 on Windows
- The project is still a developer preview. Compatibility-breaking changes are explicitly expected by upstream.
The local installed declarations and implementation are the authority for the MVP. The upstream repository was used to confirm the architecture and bundle model:
- https://github.com/deepseek-ai/deepseek-harness
- https://github.com/deepseek-ai/deepseek-harness/blob/master/docs/architecture.md
- https://github.com/deepseek-ai/deepseek-harness/blob/master/docs/development.md
Bundle contract
An installable bundle declares a patch in package.json:
{
"type": "module",
"main": "lib/index.js",
"dsh": {
"bundle": { "patch": "./cordis.patch.yml" }
}
}
cordis.patch.yml inserts the host plugin as a normal Cordis row. A host plugin
exports name, optional inject, a config schema (Config), and apply.
Profiles stack official bundles, installed third-party bundles, the profile
patch, the home patch, and command-line overlays. The composed result can be
inspected with dsh --profile web --dump-config.
Tool lifecycle in rc.8
The public @deepseek-ai/dsh-tools contract exposes:
tools/pre-execute: allow, deny, or ask before dispatch.tools/execute: around-dispatch waterfall.tools/post-execute: accept, replace, enrich, or block a normalized result.- tool-owned
finalizeContent: synchronous final model-content projection. tools/result: a frozen, lossless-JSON observer event.
PostToolDecision permits an accept decision to replace either content or
value, but never both. Replacing content changes the final model-facing
projection without changing the validated canonical value. A failed result may
also receive replacement content, but its value cannot be replaced.
Feasibility result
Yes: tools/post-execute is the correct documented seam for inspecting and
replacing model-facing tool output without modifying DSH Core.
The plugin must call next() first and operate on decision.content ?? result.content. It should return only content, preserve
additionalContexts, and never return value. This preserves the canonical
business value for downstream programmatic consumers.
Important upstream overlap
RC.8 already includes two related mechanisms:
@deepseek-ai/dsh-spill-policy: at the default 50,000-byte threshold, saves oversized plain text throughctx.spillStoreand replaces model content with a bounded head/tail preview and retrieval locator.@deepseek-ai/dsh-compaction-tool-result-pruner: later prunes historical tool results under compaction pressure (default threshold 8,192 characters).
The spill policy is deliberately content-agnostic. It preserves boundaries, not middle-of-log evidence. The pruner acts later, after the result has already entered and potentially been resent in context.
dsh-tool-squeeze therefore runs as a normal (non-prepended) post-execute
listener. The official spill policy is prepended and delegates via next(), so
the intended order is:
tool render -> dsh-tool-squeeze -> official spill-policy bound -> materialize
The plugin stores the original through the official spill service before replacing content. If retention is required and storage is unavailable or fails, it returns the original output (fail-open).
Durable data conclusion
The canonical successful JSON value remains untouched. The durable session
result contains the final model-facing content, so content replacement alone
does not guarantee that the original formatted text remains in session history.
For reversibility, the MVP stores the original formatted text with
ctx.spillStore and includes its locator in the compression notice. This uses
the official retention path and avoids inventing a second storage subsystem.
UI and settings
The bundle contract can also declare a dsh.client entry and Web platform
injections. That is unnecessary for the compression core. The MVP remains a
host-only plugin and exports a validated config schema; a dashboard and slash
command are deferred until the core behavior and compatibility are stable.
Compatibility risks
- DSH is a developer preview; the tool lifecycle may change between RCs.
finalizeContentruns after post-execute and is tool-owned. A tool can theoretically replace content after this plugin. Integration tests cover the current rc.8 materialization path, and the package pins its peer range to rc.8.- Mixed non-text content is passed through because flattening images or other blocks would be unsafe.
- Nested code-mode dispatch logging has a separate lifecycle. V0.1 handles top-level model-facing results only; official spill continues to protect the durable sub-dispatch log.