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:

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:

  1. tools/pre-execute: allow, deny, or ask before dispatch.
  2. tools/execute: around-dispatch waterfall.
  3. tools/post-execute: accept, replace, enrich, or block a normalized result.
  4. tool-owned finalizeContent: synchronous final model-content projection.
  5. 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 through ctx.spillStore and 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.
  • finalizeContent runs 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.