dsh-plugin-monitor
Đã xác minhdsh-plugin-monitor · v0.1.1 · MIT
Event monitor for DeepSeek Harness — background processes and WebSocket streams whose output lines wake the agent as asynchronous events.
Cài đặt
dsh plugin add dsh-plugin-monitor Xác nhận layer đã áp bằng dsh --profile default --dump-config — xem hướng dẫn cài plugin.
Mã nguồn
Phát hành lên npm mà không có repository công khai. Hãy kiểm tra nội dung package trước khi cài.
Thẻ
Tác giả
Readme
dsh-plugin-monitor
An event monitor for DeepSeek Harness: arm a background watch — a shell command or a WebSocket — and every stdout line (or text frame) is delivered to the owning agent session as an asynchronous event. The agent keeps working or goes idle; inference happens only when something actually arrives.
Modeled on Claude Code's Monitor tool. The motivating use case is real-time agent-to-agent
messaging (e.g. Grapevine channels), where the alternative — a timed self-wakeup loop — costs a
model turn per empty poll and adds up to a full interval of latency per message.
Status
Working, and verified end to end. A DeepSeek Harness agent has held a live conversation over a
grapevine channel through this plugin — woken per message without polling, with batching, labels,
and job_kill all confirmed against a real dev profile. See the acceptance scenario and its
result in docs/design.md.
What dsh already has, and what this adds
The dsh background-job runtime (ctx.jobs) already owns job ids, cancellation, incremental
reads (readOutput() / job_output), and wake-on-completion for an idle owner. Separately,
agent.inject() appends context to the next model request — explicitly not a wake-up.
This plugin extends that from completion-only to per-output event. Delivery is
agent.send(event, 'next-step', true) — the runtime's waking send, which folds an event into
ongoing work and opens a turn when the owner is idle. The registry has no per-output
notification and needs none: the producer owns the stream in-process. Around that sit the
operational details that make it survivable:
- line/frame granularity — each output line is one event
- short-window batching (~200ms) so multi-line bursts arrive as one notification
- rate limiting with auto-kill on firehoses
- a per-monitor label carried in every notification
- timeout by default, opt-in session-length persistence, stoppable via
job_kill
Development
Bun + Biome for local development (the published package is plain JS in dist/, so this is
invisible to consumers):
bun install
bun run build # tsc → dist/
bun run check # biome
Install into a dsh profile from a local checkout — note dsh plugin add forwards to pnpm
on the consumer side, and git installs need the prepare script allowlisted in the consumer's
pnpm-workspace.yaml; neither constrains this repo's own tooling:
dsh plugin --profile dev add /path/to/dsh-plugin-monitor
Add it to the profile you actually boot — the web UI runs the web profile, so installing
into dev and then launching the web UI is a correct command aimed at the wrong target. Verify
before launching:
dsh --dump-config | grep monitor
Tuning the delivery budgets
Optional. The defaults are the policy for almost everyone; override only if a
source legitimately needs more headroom, as a config: block on the profile entry:
- id: monitor
name: dsh-plugin-monitor
config:
maxEventBytes: 32768 # bytes in one delivered event (default 16 KiB)
throttleBytes: 262144 # bytes per 10s before throttling (default 128 KiB)
killBytes: 1048576 # bytes per 10s before the monitor is stopped (default 512 KiB)
spillBytes: 524288 # capacity for event-clipped output (default 256 KiB)
Config is validated at load, so a mistyped budget fails the boot rather than the
first overflowing event. Output clipped from an event is recoverable with
job_output <id>; the event says how many bytes were delivered and which spill
block holds the rest.
If tool calls start failing after installing this
A symptom worth recognising, because it looks like this plugin and is not:
Cannot read properties of undefined (reading 'prepare')
Every tool call in the profile fails, including ones unrelated to this plugin. It means two copies
of @deepseek-ai/dsh-tools are loaded: its dispatcher is keyed by a module-local Symbol(), so
the copies cannot see each other's scheduler. This is a known upstream issue —
deepseek-harness discussions #1849,
#3033,
#2078.
This package declares no runtime dependencies precisely to avoid causing it. If it happens anyway, check for a rival copy and remove or link it:
ls $DSH_HOME/profiles/<name>/node_modules/@deepseek-ai
It is most likely when the harness is installed globally rather than under $DSH_HOME.
Layout
src/index.ts— plugin entry (name,inject,apply); registers themonitortool and the system-prompt section that tells the model events arrive unpromptedsrc/events.ts— batching, rate limiting, and waking delivery to the owning agentsrc/command.ts— shell-command producer (own process group, so cancel kills pipelines)src/websocket.ts— WebSocket producer (one event per text frame)src/lines.ts— line splitting across chunk boundariescordis.patch.yml— configuration layer applied when the bundle is added to a profiledocs/design.md— design notes and open questions