edusrez/dsh-smart-restart ↗★ 8
dsh-smart-restart
在服务重启时唤醒主代理并发送通知以恢复工作 适合服务重启后需要唤醒智能体、提示检查并继续未完成工作的用户。
安裝
$
npx -p @deepseek-ai/dsh dsh plugin --profile web add github:edusrez/dsh-smart-restart說明文件
閱讀完整 README ↗Configuration
All behavior is controlled through the plugin row's config:
| Key | Type | Default | Description |
|---|---|---|---|
enabled | boolean | true | Master switch; false skips all processing. |
stateDir | string | .smart-restart | Sub-directory under `` where marker.json, pending-notice.json and shutdown-notice.json are written. |
target | string | primary | Which agent(s) to notify when there is no pending/shutdown notice: primary | all | ``. |
wakeup | boolean | true | true → agent.followup() wakes the agent and delivers; false → agent.inject() queues model-facing context only (no wake). |
notice | string | '' | Optional custom notice text; returned verbatim when non-empty, else the default. |
restartUnit | string | '' | Systemd unit to restart when smart_restart is invoked (e.g. dsh.service or dsh-deepartments-dev.service). Since v0.5.0 it is auto-detected from /proc/self/cgroup (the plugin's own unit) when empty; an explicit value always wins. Empty with no detectable unit → the tool fails safe with a clear error. |
toolEnabled | boolean | true | Whether the smart_restart tool is registered (available to agent sessions). |
shutdownGraceMs | number | 600000 | Grace window (ms, default 10 minutes) before shutdown within which last agent activity counts as "agent-involved" for the smart shutdown auto-notification. If the last-active session was idle beyond this window on shutdown, the pin is skipped and delivery falls back to target. |
ignoredSessionPrefixes | string[] | ['head-'] | Session-id prefixes that must never be selected as the single-session "last active" PIN for the smart-shutdown auto-notification — Deepartments department-head sessions (`head- |
| `) never get a spurious pinned notice (the v0.3.1 regression). Since v0.6.0 (unreleased) the same prefixes identify the interrupted-head resume recipients: a head whose turn was genuinely cut by a restart still receives its own notice at boot (never a pin). Configurable list; default ON (heads skipped from the pin). | |||
canary | boolean | false | Opt-in canary pre-restart validation: boot an ephemeral DSH instance and abort the restart on failure. The per-call canary tool parameter overrides this for one call. |
canaryTimeoutMs | number | 45000 | Hard window (ms) for the canary boot liveness probe (default 45s); a timeout is a canary failure and aborts the restart. |
canaryPort | number | 0 | HTTP port for the ephemeral canary instance; 0 auto-picks a free port. |
canaryProfile | string | '' | Explicit dsh profile for the canary launch; empty derives it from the unit's ExecStart (--profile). |
canaryBinary | string | '' | Explicit dsh binary for the canary launch; empty derives it from the unit's ExecStart, else dsh on PATH. |
canaryStateDirOverrides | object | {} | Plugin-row id → temp dir; those rows get their stateDir redirected in the canary patch so the ephemeral never writes live state (e.g. deepartments: '' keeps the canary off live board state). Relative or empty values resolve under the canary temp dir; absolute values are used verbatim. |
canaryClientCheck | boolean | true | Post-boot client-graph validation (P1 lesson): after liveness, parse __DSH_BOOT__ from the served page and verify every row's /plugins//client.js bundle registers that row's id. A boot with no __DSH_BOOT__ (non-web surface) passes trivially. |
canaryClientTimeoutMs | number | 15000 | Whole-phase budget (ms) for the client-graph validation. |
canaryAgentCheck | boolean | true | Post-boot AGENT-LIVENESS check (R8 liveness family): every NON-RETIRED member of the deepartments catalog (posts.json) must appear alive in the runtime's live agent registry before the restart proceeds. A member registered but missing from the live registry fails the canary (a restart that lands with heads/workers missing hangs the org). No catalog (generic install) → skip. |
canaryCatalogPath | string | '/.deepartments/posts.json' | Catalog path the agent-liveness check reads (the deepartments runtime's durable registry). |
canaryRuntimeStateDir | string | '/.deepartments' | Runtime stateDir whose R8/R9 marker files the markers check reads. |
canaryPoolerCheck | boolean | true | Post-boot POOLER-HEALTH check: probes /v1/models, /usage and /__keypool/status on the ephemeral web port. A missing endpoint (HTTP 404/405 — e.g. the fb-75 pooler-capacity deploy pending) is a graceful skip, never a failure; a 5xx or unreachable endpoint fails. |
canaryPoolerTimeoutMs | number | 5000 | Whole-phase budget (ms) for the pooler-health probes. |
canaryMarkersCheck | boolean | true | Post-boot RUNTIME-MARKERS check: the R8 presence cache (presence.json) and the R9 toolset-audit sidecar (toolset-audit.jsonl) must exist and be well-formed. Absent files (generic install) skip; a malformed file fails. |
target semantics (fallback path only — a pending notice or a usable shutdown notice overrides target for that boot):
primary— the first root agent to start (the main agent). Delivery is guarded so exactly one primary is notified.all— every root agent.- `` — an exact session id, pinned to one specific agent.
Full example patch row, restating every key with a custom notice and an explicit restartUnit:
- insert:
- id: smart-restart
name: dsh-smart-restart
config:
enabled: true
stateDir: .smart-restart
target: primary
wakeup: true
notice: "The DSH service restarted. Please check for interrupted work and report your status in one line."
restartUnit: dsh.service
toolEnabled: true
shutdownGraceMs: 600000
ignoredSessionPrefixes:
- head-
canary: true
canaryTimeoutMs: 45000
canaryPort: 0
canaryProfile: ''
canaryBinary: ''
canaryStateDirOverrides:
deepartments: ''
Single delivery channel. When
wakeupis enabled the notice is delivered viaagent.followup(); when disabled, viaagent.inject(). It is never both with the same message — a followup that queues into the inbox and a parallel inject of the same message would collide with Inbox's "already pending" validation.