DeepSeek Harness 插件

dsh-media-guard

Deterministic aggregate media budgets and safe request projections for DeepSeek Harness (DSH)(英文原文)

跳到安装方式

来源信息

GitHub 仓库
spyfree/dsh-media-guard
最近更新
2026年8月20日
分类
安全与权限
GitHub stars
0
载体类型
plugin
目录证据
上游声明已找到 dsh.bundle
证据路径
package.json#dsh.bundle
核对版本
0.1.0-rc.8
上游核对日期
2026-08-20

该证据由上游目录提供。本站没有安装、运行或安全审核这个插件。

安装

默认先复制一段 Prompt,让 Agent 读 GitHub 仓库和源码;需要自己装时再切到命令。

复制这段 Prompt,发给 DSH、Codex 或其他 Agent,让它先读 GitHub 仓库和源码。

请先不要安装或执行任何命令。阅读这个插件的 GitHub 仓库、README 和关键源码,然后用清楚、直接的方式回答以下问题,帮助我判断它是否适合我的需求:

1. 这个插件是什么,解决什么问题;
2. 适合哪些用户和典型使用场景;
3. 安装后如何使用,并给出一个最小使用示例;
4. 有哪些已知限制,以及隐私、安全、兼容性或维护风险;
5. 给出“推荐 / 有条件推荐 / 不推荐”的明确建议和理由。

请区分仓库明确说明、根据源码推断和未知信息。证据不足时请明确说明,不要猜测或照抄 README。

GitHub:https://github.com/spyfree/dsh-media-guard
插件名:dsh-media-guard
作者:spyfree

检查来源文件

安装前先看这个插件目录里的 README 和其他文件。

文件资源管理器3 个文件
README.md来源说明 · 只读预览

dsh-media-guard

Request image optimization, intelligent retention, and observability for DeepSeek Harness (DSH).

dsh-media-guard optimizes the provider-bound image view before every agent-loop model call. It inventories attachment references, compresses oversized images, deduplicates by content address, preserves current-turn and user media first, and replaces media that still cannot fit with factual Evidence Notes. The durable session log and original attachments are never modified; compressed variants are added through DSH's immutable attachment store.

DSH 0.1.0-rc.8 already supplies the baseline safety layer this plugin originally filled: attachment admission rejects unsafe per-image/per-message inputs, and offloadRequestImages() lets the official Pi AI and DeepSeek adapters cap aggregate Base64 image payload at 20 MiB by replacing the oldest images. Media Guard is therefore an optimization, retention-policy, and observability layer, not a claim that DSH lacks request-size protection. Its remaining advantages are compression instead of immediate removal, content-address deduplication, current-turn/source-aware retention, tighter configurable budgets, Evidence Notes, reporting, and uniform coverage of third-party adapters that do not call DSH's helper.

This is the DSH port of pi-media-guard; the planner, fair-share math, evidence notes, and failure policy are shared line for line where the hosts allow.

> Alpha: this line implements the ledger, planner, sharp-backed compression, budget-driven externalization, the llm/stream projection, and a local report UI. The request path, attachment API, client bundle, optional webServer seam, and coexistence with rc.8 offloadRequestImages() are tested against @deepseek-ai/dsh-* 0.1.0-rc.8. DSH itself is a developer preview and its APIs may still move.

How it works

  • Registers on the llm/stream waterfall and acts only on agent-loop-built requests (isAgentLoopRequest). Hand-built calls — vision bridges' VLM traffic, compaction, replay — pass through untouched, and so does the plugin's own projected re-dispatch, which terminates recursion.
  • Accounting is zero-byte-cost: DSH image blocks carry content-addressed attachment references (sha256:…) with exact byte sizes and dimensions, so the ledger, dedup, and budget math never read image data. Only images selected for compression are read through ctx.attachments.
  • Oversized images are constrained with this package's own sharp dependency, encoded as WebP, and saved back through ctx.attachments.saveImage. Variants are cached by source content address and target, so duplicates and later matching requests reuse the same stored ref.
  • When the projection changes anything, a fresh request is dispatched via ctx.llm.stream(...) — the frozen loop-built request and the stored session are untouched; only the provider-bound view changes.
  • In protect mode, the serialized budget is capped to the mirrored adapter maxRequestImageBytes, so an official rc.8 adapter normally sees an already-safe request and does not perform a second, invisible oldest-first removal.
  • If the projection itself fails, an intentionally simpler emergency path strips every image leaf. The guard never silently falls back to sending the oversized original.

Install

dsh plugin --profile <name> add dsh-media-guard

Restart the profile afterwards. The bundle inserts a media-guard row into DSH's existing home composer status strip; no configuration is required for the defaults.

Installing straight from a git host (dsh plugin --profile <name> add github:spyfree/dsh-media-guard) builds dist/ via the package's self-contained prepare script; pnpm ≥ 10 will ask you to allowlist that build in the profile's pnpm-workspace.yaml on first install, exactly as DSH's packaging guide describes.

Default behavior

  • Runs in protect mode before every agent-loop provider request.
  • Applies a conservative default budget: 8 media blocks, 2 MiB serialized (Base64) / 1.5 MiB decoded aggregate, 512 KiB serialized per image.
  • Preserves current-turn media before older media; user media before tool media.
  • Deduplicates identical images by their content address; later copies become duplicate notes.
  • Replaces overflow media leaves with deterministic Evidence Notes (hash, size, dimensions, origin, reason — no invented descriptions, no directives).
  • Preserves message count, order, roles, ids, sources, and tool-call/result pairing.
  • Emits a media-guard/report event after each guarded call and keeps a bounded, metadata-only in-memory history for the report UI; never logs or emits image bytes.

The default budget is a conservative optimization policy, not a claim about any provider's maximum body size. It sits well below DSH's official-adapter default of 20 MiB, so Media Guard acts first and the core helper is normally a no-op. Raise it per route only together with the route's actual adapter ceiling.

Configuration

Override the plugin row from your profile's cordis.patch.yml with a flat patch entry targeting the row id (the same form DSH's own bundles use):

- id: media-guard
  config:
    mode: protect            # observe | optimize | protect
    log: false               # true prints a one-line summary per projection
    budget:
      maxMediaBlocks: 8
      maxSerializedMediaBytes: 2097152
      maxDecodedMediaBytes: 1572864
      maxSerializedBytesPerImage: 524288
    adapterMaxRequestImageBytes: 20971520 # mirror adapter setting; rc.8 default
    profiles:                  # keyed by the request's provider route id
      my-vision-gateway:
        maxSerializedMediaBytes: 12582912
        maxDecodedMediaBytes: 9437184
        adapterMaxRequestImageBytes: 12582912 # mirror this route's adapter
    statusPollIntervalMs: 2000 # home-row refresh cadence

A profiles entry is more specific than the top-level budget, so for the fields it declares it wins on its route even when both are set. adapterMaxRequestImageBytes does not configure DSH's adapter; mirror the value from that adapter's route configuration. Media Guard caps its resolved maxSerializedMediaBytes to the matching global or route value. The global default is 20 MiB, matching the official rc.8 Pi AI and DeepSeek adapters. If an adapter is configured below that, mirror its lower value here; if a third-party adapter has a different bound, declare that route explicitly.

Modes:

  • observe: inventory and report only;
  • optimize: compress but do not externalize;
  • protect: compress, then externalize overflow media (default).

In observe and optimize, over-budget images deliberately remain after Media Guard, so an official adapter may still apply its own oldest-first offload. The report describes Media Guard's output, not that later adapter-only step. Use protect with a correctly mirrored ceiling when the UI must describe the final image selection. No plugin can introspect a deployment-defined adapter setting, which is why a non-default adapter ceiling must be mirrored in configuration.

enabled: false bypasses the guard entirely. Every config field is validated individually; an invalid value falls back to its protective default and is reported — a broken config can never widen a budget or switch the guard off.

Unlike the Pi original there are no built-in provider profiles: DSH provider routes are deployment-defined, so every route gets the conservative default until you declare a profile for it.

Report UI

The main DSH home page now carries a compact, live Media Guard row under the composer, in the same conversation.composer.dock strip as DSH's own stats line. It is scoped to the active session, refreshes from that session's metadata-only report endpoint, and shows the current pressure, images kept, serialized-media budget, compression, deduplication or externalization counts, and an input over limit marker when the original request crossed the budget. For example:

media near limit now · 4/4 images kept · 1.5M/2.0M · 2 compressed · input over limit

This is the primary at-a-glance surface; it does not open a new page.

When the profile includes DSH's Web server (the normal web profile), open:

http://<your-dsh-host>:<port>/media-guard

The page is the detailed, optional view: it shows process-lifetime totals and the 100 most recent guarded requests. It polls the same read-only JSON endpoint at /media-guard/api/reports using the configured cadence. The home row adds the active session's sessionId query parameter; the detailed page deliberately leaves it off and therefore shows the process-wide history. Both surfaces contain metadata only; report history is held in memory and resets when DSH restarts. The home-row cadence is configured with statusPollIntervalMs; the API advertises the validated value to the browser bundle. Session-scoped latest summaries are retained for at most the most recent 100 session identities; process-wide totals remain lifetime totals. In a headless profile the optional route is simply not registered, while the guard and media-guard/report event continue to work.

Marketplace discovery

The package declares its DSH bundle, server-plugin kind, optional Web-server peer, and privacy disclosure in package.json. The GitHub repository carries the dsh-plugin topic used by DSH marketplace scanners; after a push, topic-based marketplaces normally refresh it on their next indexing cycle. No install script is used—the official profile package flow builds and registers cordis.patch.yml.

Anonymous regression

The test suite reproduces the original four-image failure distribution:

1.82 MB + 0.74 MB + 1.21 MB + 2.80 MB = 6,567,972 Base64 bytes

Without a codec, protect brings the request under the default 2 MiB aggregate budget deterministically. The regression's deterministic codec keeps all four visual inputs available at 1,600,000 serialized bytes; the shipped sharp codec is separately tested against the same serialized-byte contract and always falls back to normal externalization when it cannot meet a target.

Development

Requires Node.js 22.19 or newer, matching DSH's own engines requirement.

npm install
npm test
npm run typecheck
npm run lint
npm run build

Security and privacy

Plugins run with the user's full local permissions. Review code before installation. This plugin reads only compression candidates through DSH's verified attachment API, stores compressed variants through the same API, sends no telemetry, and never logs attachment contents, payloads, or credentials. Reports and diagnostics carry metadata only. Stored variants follow the attachment store's retention policy; the in-memory report history resets on restart.

License

MIT