# 📦 @goodandready/dsh-dsml-artifact-guard

Fail-Open Stream Sanitizer for Leaked Protocol DSML Closing Tags in DeepSeek Harness

npm version license DSH Plugin Node version

GoodAndReady Showcase

🇬🇧 English🇷🇺 Русский🇨🇳 中文说明

If you like this plugin, please star it on GitHub — it shows me that the plugin is useful to you and motivates me to keep developing it.

🐛 If you find a bug or would like to request a feature, open a GitHub issue in any language — I will review your proposal and implement useful suggestions in a future plugin version.
--- ## ⚡ Overview & The Problem When interacting with certain upstream model providers or API gateways, raw DSML (DeepSeek Markup Language) tool-invocation protocol tags can leak into the assistant's visible text stream. Users frequently see trailing protocol clutter like: ```text Done. All tests have passed. ``` These leaked closing tags visually pollute the chat bubble, cause Markdown rendering glitches, and can confuse downstream agents or clipboard exports. **`@goodandready/dsh-dsml-artifact-guard`** is a lightweight, host-only runtime stream interceptor for DeepSeek Harness that cleans up these terminal artifacts in real time before they reach the user interface: 1. **Synchronous Stream Contract Preservation**: Cordis requires stream interceptors to return an `AsyncIterable` synchronously. Making interceptors `async` returns a `Promise` that crashes the harness turn with `stream is not async iterable`. This guard adheres strictly to the synchronous hook contract. 2. **Split Chunk Buffer Pipeline**: Protocol tags often arrive split across multiple TCP or WebSocket text deltas. The guard maintains a small sliding buffer (`KEEP = 96` bytes) to reliably match and strip multi-chunk tails. 3. **100% Fail-Open Safety**: Never drops legitimate user or assistant text. Legitimate discussions about DSML syntax or internal tool calls are preserved intact. 4. **Targeted Provider & Model Scoping**: Restricts processing specifically to the provider and model configurations that exhibit tag leakage, passing other model traffic through with zero overhead. --- ## 🏗️ Architecture ```mermaid graph TD subgraph DSH ["DeepSeek Harness Runtime"] Turn["Agent Turn Execution
(LLM Stream Request)"] ChatUI["Chat UI Stream Consumer
(Renders clean markdown text)"] end subgraph Guard ["@goodandready/dsh-dsml-artifact-guard"] Hook["Synchronous llm/stream Hook
(Returns AsyncIterable synchronously)"] ScopeCheck{"Scope Match?
(providerId & modelId)"} PassThrough["Raw Stream Pass-Through
(Zero overhead for other models)"] Buffer["Sliding Tail Buffer
(Preserves trailing 96 bytes across deltas)"] Detector{"Terminal Artifact?
(Matches leaked DSML tail at finish)"} Sanitize["Sanitize Mode
(Strips leaked closing tags)"] Audit["Audit Mode
(Emits ctx.logger warning only)"] end Turn -->|llm/stream hook| Hook Hook --> ScopeCheck ScopeCheck -->|No| PassThrough ScopeCheck -->|Yes| Buffer PassThrough --> ChatUI Buffer --> Detector Detector -->|No Artifact| ChatUI Detector -->|Artifact detected: sanitize| Sanitize --> ChatUI Detector -->|Artifact detected: audit| Audit --> ChatUI ``` --- ## ✨ Features & Capabilities ### 1. Synchronous Hook Guarantee Under Cordis and DSH service lifecycles, event listeners on `llm/stream` must return the transformed stream synchronously. An asynchronous hook wrapper will return a `Promise`, causing the runtime dispatcher to immediately throw `TypeError: stream is not async iterable`. `dsh-dsml-artifact-guard` wraps the stream generator in a pure synchronous registration. ### 2. Multi-Chunk Tail Buffering In real-world streaming, the artifact ` ` is frequently fractured into fragments: * Chunk 1: `All tasks complete. ` * Chunk 3: `` The guard retains a minimal 96-byte window until the next chunk or `finish` event arrives, ensuring fractured tags are seamlessly detected and sanitized as a single terminal artifact. ### 3. Fail-Open Architecture * If the text contains genuine prose about DSML (e.g. `<|DSML|tool_calls>example`), it is **never** removed. * Non-text chunks (`tool-call-delta`, `usage`, `finish`) are forwarded immediately without delay. * Any malformed chunk structure passes through transparently to preserve session stability. ### 4. Flexible Operating Modes * **`sanitize`** *(default)*: Strips terminal DSML closing tags and logs a warning with the count of removed artifacts. * **`audit`**: Emits diagnostic logs with `ctx.logger.info(...)` without modifying the user-visible stream. * **`disabled`**: Bypasses processing entirely. ### 5. Native Web UI Settings Card Registered directly in the DeepSeek Harness `settings.plugin.item` slot (`lib/client.js`): * **Reactive Configuration**: Adjust `mode`, `providerId`, and `modelId` on the fly without restarting the harness, powered by reactive `scope.watch`. * **Snapshot State Awareness**: Gracefully handles snapshot loading, ready, and unavailable states. * **Protection Bypass Warning**: Displays a prominent `OFF` badge and warning banner when the guard is set to `disabled`. ### 6. One-Click In-Place Auto-Updater A canonical HTTP management route (`/api/dsh-dsml-artifact-guard/update`) mounted via `lib/updater.js`: * **SemVer Inspection**: Queries the registry and compares versions with full pre-release support. * **Loopback & Same-Origin Protection**: Write mutations (`POST`) are strictly restricted to local loopback connections with valid origin headers. * **Clean Invocation**: Executes package updates safely without risky CLI bypass flags. ### 7. Full Dark & Light Theme Compliance All client UI styles are strictly tokenized via DeepSeek Harness `--dsw-alias-...` CSS custom properties and `color-mix()` functions with zero hardcoded hex or rgba color literals. High contrast and accessibility are guaranteed in both Dark and Light themes, guarded by automated regression tests (`test/theme.test.js`). --- ## 📦 Installation Install into your DeepSeek Harness web profile: ```bash dsh plugin --profile web add @goodandready/dsh-dsml-artifact-guard ``` Restart your DeepSeek Harness instance. --- ## ⚙️ Configuration (`settings.yaml`) Configure provider and model targets in `settings.yaml` or through the Web UI: ```yaml # settings.yaml dsh-dsml-artifact-guard: mode: sanitize providerId: "your-provider-id" modelId: "your-model-id" ``` ### Configuration Parameters | Parameter | Type | Default | Description | |:---|:---|:---|:---| | `mode` | `string` | `"sanitize"` | Operation mode: `"sanitize"` (strip tags), `"audit"` (log only), or `"disabled"` | | `providerId` | `string` | `"opencode-go"` | Target provider identifier exhibiting leaked tags | | `modelId` | `string` | `"deepseek-v4-flash"` | Target model identifier exhibiting leaked tags | ### HTTP Management Endpoints | Method | Endpoint | Access | Description | |:---|:---|:---|:---| | `GET` | `/api/dsh-dsml-artifact-guard/update` | Web UI / Localhost | Retrieves current version, latest registry version, and update status | | `POST` | `/api/dsh-dsml-artifact-guard/update` | Loopback & Same-Origin | Triggers in-place package update via DSH CLI | --- ## 🧪 Testing Run the automated test suite covering split chunks, audit vs sanitize modes, scope matching, and synchronous hook contracts: ```bash npm test npm run check ``` --- ## 📄 License MIT © [GooDAnDReaDY](https://github.com/GooDAnDReaDY) --- For a complete release history and version migration notes, see [CHANGELOG.md](CHANGELOG.md).