ya8D/dsh-directive-compact ↗★ 0
@ya8d/dsh-directive-compact
基于指令驱动的 DeepSeek Harness 纯增量会话压缩与裁剪插件
AI 分析
核心用途是按用户自定义的自然语言要求压缩或裁剪会话历史。适合长对话导致 Token 爆满、需要精准保留特定上下文(如登录报错或原始指令)并丢弃无用信息的长文本任务。
安装
npx -p @deepseek-ai/dsh dsh plugin --profile web add github:ya8D/dsh-directive-compact说明文档
阅读完整 README ↗Usage
Both requirements are plain free text in any natural language. Examples:
/compact-directive keep the login-related errors, compress the rest of the middle process
/trim-directive delete all git-operation records, keep the user's original instructions and the plugin-development goal
How the two differ
/compact-directive | /trim-directive | |
|---|---|---|
| Region | Middle only; head + recent turns protected | The whole surface; nothing protected |
| Baseline | Requirement layered over a four-point summary baseline | Requirement is the sole instruction (no baseline) |
| Result | One checkpoint replacing the middle | One checkpoint replacing the whole surface |
| Use case | Routine context compression with a focus | Aggressive / surgical deletion the head-protected command cannot reach |
Operation mode (how a trim actually cuts)
/trim-directive runs every chunk in operation mode: the model sees each node numbered with its global event seq ([seq 28039] [user] …) and replies with a small operation manifest:
delete: 28039, 28045 remove whole nodes
delete-text: 28039, "..." delete an exact fragment inside one node
rewrite: 28039 replace one node (partial edits) → its full new text
summarize: 28040-28045 replace a range with a short summary
---content--- … ---end--- (the replacement text for rewrite/summarize)
> nothing to change in this chunk
The plugin then executes the manifest programmatically: untouched nodes keep their original text, deleted nodes drop, delete-text fragments are removed by exact string match, rewritten nodes take the model's content, summarized ranges take the summary. Any malformed or uncertain manifest (prose, unknown ops, out-of-range seqs, overlaps, a split tool call/result pair, missing content) falls back to a plain rewrite of the chunk — the plugin never half-executes.
When there is nothing to remove
A trim/compaction that finds nothing worth changing is a normal outcome, not a failure:
- Per-chunk declaration (trim). If the requirement changes nothing in a chunk, the model replies with exactly
>(or an empty manifest); the command layer keeps that chunk's original rendering verbatim in the checkpoint. A marker buried in other output is treated as content, not a declaration — a model that misuses the marker can only fail to shrink, never silently drop content. - Shrink validation. If the assembled checkpoint is still not smaller than the span it replaces (e.g. every chunk declared no change), the command reports a no-change success —
Nothing to trim: …/Nothing to compact: …— and leaves the conversation exactly as it was. It never loops, retries, or hangs. (This is why a directive like "delete all telemetry mentions" on a session with no telemetry returns with a message instead of churning for many minutes.)
Where the command and its effect appear
- Commands are log-only, not dialogue. Like every dsh slash command (including upstream
/compact), these commands do not appear as messages in the conversation UI. The invocation, result, and compaction lifecycle are visible in the session trace/log. - The original dialogue stays visible in the UI after a trim/compaction. The conversation transcript never erases what you already saw (dsh's design; upstream
/compactbehaves the same). The model uses the checkpointed context on its next request — to verify the effect, read the session trace, not the chat transcript.
Configuration
All fields are validated through the Cordis Config schema and settable from cordis.yml:
| Field | Default | Meaning |
|---|---|---|
keepHeadUsers | 3 | User turns kept verbatim at the head (after the fixed skeleton) when planning the compact middle. |
keepTailUsers | 3 | User turns kept verbatim at the tail; the last user utterance is always kept regardless. |
summarizationProvider | '' | Provider for the summarization call; falls back to the routed provider when empty. |
summarizationModel | '' | Model for the summarization call; falls back to the routed model when empty. |
maxTokens | 8192 | Generation cap for the /compact-directive summarization call. |