# DeepSeek Harness API research 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`: ```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: ```text 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.