Introduction

When running PTC (Program Tool Calling) sessions in DeepSeek Harness (DSH), the model primarily writes programs and calls tools via the built-in run_code. As conversations grow longer, the host’s automatic compaction trims history based on size, without understanding that “the first forty messages just finished one subtask, while the last ten are about something else.” When the context is crowded, the model still needs to carry details from completed stages for further reasoning, leading to increased costs and window pressure.

The community plugin dsh-block-ptc (maintained by mengwEX) introduces a “block” protocol for PTC scenarios: the model opens blocks itself, works within them, and replaces messages inside the block with a self-written summary at the appropriate time, retaining information needed for subsequent work. This article introduces its positioning, mechanism, installation, and typical usage. For facts, please refer to the GitHub Repository and the SkillHub Directory Page. SkillHub is a community plugin directory and has no official affiliation with DeepSeek or Hunyuan.

What is This

dsh-block-ptc is a profile bundle for DSH PTC Mode: it adds block markers to run_code and provides block_compact within the program, allowing the model to control “which segment of history can be collapsed into a summary.” The current npm version is 0.4.0; starting from 0.4.0, only block_compact({ ids, content }) is supported. The old block_summary tool and summary/single id parameters are no longer supported. After upgrading, you must restart DSH and start a new Block PTC session.

The plugin has zero runtime dependencies (no external imports other than node:crypto) and is licensed under MIT. In classification, it is often categorized under “model reasoning” capabilities: essentially, it is context organization, not a change of model or inference backend.

Core Mechanism

The DSH PTC presentation layer only allows the model to directly call run_code. Therefore, the block protocol is written into the tool description, and the compaction API is called within the program:

run_code({ description: "[block: <ids>] <goal>", code })   // The only tool the model can directly call
await tools.block_compact({ ids, content })                  // Called within the program

The following steps explain what the plugin does in a session.

  1. The [block: <ids>] prefix in the run_code.description header declares the block IDs advanced by this program segment; these IDs apply to the entire assistant message (including preceding thinking/text) and its tool results; IDs from multiple run_code calls in the same assistant message are unioned.
  2. tools.block_compact({ ids, content }) replaces the entire range from the earliest to the latest occurrence of any target ID with the content submitted by the model (retaining the summary).
  3. The summary inherits the union of IDs from that range, minus the compacted target IDs; summaries still carrying IDs can participate in subsequent compaction again; summaries with no remaining IDs are retained.
  4. If a tool call pair within the range has not yet finished, the request will queue to wait for the result; if the range contains protected system/developer messages, the entire range refuses compaction, and the prefix will not be silently replaced.

Illustration (range replacement from README):

A A B A C B  -- compact([A]) --> S[B] C B
S[B] C B    -- compact([B]) --> T[C]
T[C]        -- compact([C]) --> U[]

For humans: the session log remains append-only, and the original text of each turn is still there; the model’s next request sees the summary instead of the original text within the block. In the Web UI, summaries are rendered as compaction checkpoint nodes. The plugin does not run a separate summarization model; the summary content is written by the model itself in the block_compact call.

Comparison with automatic compaction: automatic compaction decides based on token pressure and size; block compaction is actively closed by the model at subtask boundaries. The README also warns: replacing history with summaries after a block is closed may invalidate cache suffixes, and a smaller context does not guarantee a higher cache hit rate or a lower bill; the tokensFreed reported by the plugin is not a provider-side cache hit measurement.

Environment Requirements

  • DeepSeek Harness ≥ 0.2.1-rc.2 (peer has no upper limit; this version was used for live verification)
  • Cordis ≥ 4.0.5
  • Node ≥ 22 (see package.json engines)

Please be aware before installing: DSH plugins run with the permissions of the current DSH process. Before installing the bundle, you should review the source code and the MIT license yourself to ensure it meets your security and compliance requirements.

Installation and Activation

The plugin is a profile bundle: after installation, it adds a line to dsh.profile.bundles and adds a new agent preset block-ptc, without modifying the built-in ptc preset.

It is recommended to install from npm: find dsh-block-ptc in the Harness Plugin Manager, or execute via an agent that has the Plugin Manager tool enabled:

plugin_manager  install_bundle  dsh-block-ptc

The package is published on npm. After installation is complete:

  1. Restart the application once (the loader caches plugin modules based on the resolved URL; without a restart, it may still be the old generation module).
  2. Select Block PTC in the session preset and start a new session.

Uninstallation:

plugin_manager  remove_bundle  dsh-block-ptc

Then restart. If you only want to disable it without deleting the package, you can use plugin_manager set_bundle dsh-block-ptc enabled=false.

Typical Usage

The README suggests: first complete the discussion or implementation within a certain block, then when turning to other work, organize the blocks where “the original text is no longer needed.” The intended dialogue flow is as follows—first explain the tokenizer, then move to the lexer, and prompt the model to organize the earlier block before the lexer starts:

Explain how the tokenizer works.

After that discussion: move on to the lexer; organize the earlier block if its original content is no longer needed.

Expected behavior includes: the model marks the working range with run_code containing [block: …]; at the appropriate time, it calls tools.block_compact({ ids, content }) within the program to replace the corresponding range with a self-written summary; you can still see the complete history in the transcript, while the context for the model’s subsequent requests is the compacted view.

If you upgrade to 0.4.0 and still use the old API, you need to change it to block_compact({ ids, content }) and start a new Block PTC session.

Use Cases and Notes

More Suitable For: Long-chain PTC tasks, work that can be divided into sub-stages (research a section, implement a section, then discuss the next section), where you want the model to retain “summaries useful for its own subsequent work” at boundaries, rather than waiting for the host to uniformly compact based on size.

Limitations to Note (excerpted from the README design notes and known limitations sections; it is advisable to read through the repository documentation before use):

  • The block protocol relies on the presentation mode where PTC exposes only run_code; if the preset is changed or host behavior changes, you need to verify it yourself.
  • The relationship between compaction, caching, and billing is a mechanism explanation, not a benchmark test; do not treat tokensFreed as a vendor cache metric.
  • Method existence checks cannot guarantee that event semantics, preset configurations, or model behavior are completely consistent with new versions of DSH.

Conclusion

dsh-block-ptc hands over the decision of “which segment of dialogue can be collapsed into a summary” to the model. Under the PTC single-tool surface, it uses block_compact to maintain a context that allows continued reasoning, while keeping the human-side transcript complete and traceable. To install or view update notes, please visit the SkillHub Directory Page and GitHub: mengwEX/dsh-block-ptc (The README includes a Chinese version README.zh.md).