dsh-idle-watchdog

workflownpmMIT

Posts a follow-up prompt into opted-in chats that fall silent, and offers a secret-protected HTTP API that posts a message into any chat. Requires Node.js 22.5+.

下载量 / Downloads
577

Install

dsh plugin --profile web add dsh-idle-watchdog

Sandbox test

This plugin has not been tested yet. Submit a test →

README

DSH-Idle-Watchdog

![npm](https://www.npmjs.com/package/dsh-idle-watchdog)

A DeepSeek Harness (DSH) web-profile plugin with two jobs:

1. Idle nudges. Chats you opt in are watched. When one goes quiet for longer than your idle window and its agent is idle, the watchdog posts a followup prompt into that same chat, up to a cap, until you reply.

2. External prompt API. One small, secret-protected HTTP endpoint lets scripts, cron jobs, webhooks or another machine post a message into any chat by id, id-prefix or exact title, waking a cold (not loaded) chat through DSH's own resume path when you allow it.

Why

Long autonomous chats stall for boring reasons: the model stopped after a plan, a tool call failed, a rate limit ended a turn, or the agent simply asked "shall I continue?" while you were away. The watchdog nudges such a chat back to work, with a cap so it never loops forever, and quiet hours and backoff so it stays polite. The API is the other half: anything that is not a human can still talk to a chat (a nightly job finishing, a CI webhook, a monitoring alert) without you building your own session plumbing.

POST /dsh-idle-watchdog/api/prompt
  { "chat": "nightly report", "message": "The sweep finished. Summarize failures and propose fixes." }
-> 202 { "ok": true, "chat": "session-4c1760...", "via": "title", "resumed": false }

Install (DSH web profile)

Install from npm: dsh plugin --profile web add dsh-idle-watchdog, or from GitHub: dsh plugin --profile web add github:lucagiftzek/DSH-Idle-Watchdog.

dsh plugin --profile web add dsh-idle-watchdog
# or from GitHub: dsh plugin --profile web add github:lucagiftzek/DSH-Idle-Watchdog
# then restart dsh-web: the host half is mounted at boot only

The package declares dsh.bundle, so dsh plugin add lists dsh-idle-watchdog in dsh.profile.bundles.

Or from a local checkout (linked, not copied: keep the checkout where it lives):

git clone https://github.com/lucagiftzek/DSH-Idle-Watchdog ~/plugins/DSH-Idle-Watchdog
cd ~/plugins/DSH-Idle-Watchdog && pnpm install      # or npm install

cd ~/.dsh/profiles/web                              # your DSH web profile
# 1. add to package.json:
#      "dependencies": { "dsh-idle-watchdog": "link:/absolute/path/to/DSH-Idle-Watchdog" }
#      "dsh": { "profile": { "bundles": [ "dsh-idle-watchdog" ] } }   (append to the existing list)
pnpm install
# 2. restart dsh-web: the host half is mounted at boot only

The official installer also works with a checkout: dsh plugin --profile web add link:/absolute/path/to/DSH-Idle-Watchdog.

After the restart, reload the web UI. The Idle Watchdog section appears in Settings. The browser half hot-reloads; only the server half needs the restart. Requires Node 22.5 or newer and a DSH build with the agents, settings and webServer services.

Configuration

Everything is in Settings, Idle Watchdog, and applies live. Where it is stored depends on the DSH line:

  • DSH 0.1.5 and older: the dsh-idle-watchdog namespace of ~/.dsh/settings.yaml (hand-editable).
  • DSH 0.1.7 / 0.2.x and newer: the plugin row idle-watchdog in the profile patch, ~/.dsh/profiles/web/cordis.patch.yml (- id: idle-watchdog / config:). On the first boot after an upgrade the old dsh-idle-watchdog section is imported once from settings.yaml.imported, never over a row that already has values.
  • No settings service: ~/.dsh/idle-watchdog/settings.json.

/status reports which store is active (settingsStore: settings, profile-row or fallback-file).

API secret file. The prompt API secret has a version-independent home: ~/.dsh/idle-watchdog/api-secret (mode 0600; override the path with DSH_IDLE_WATCHDOG_SECRET_FILE). Precedence: env DSH_IDLE_WATCHDOG_SECRET, then the file, then the stored api.secret setting. Saving a secret in Settings writes the file; on 0.2.x the secret never goes into the profile patch, and the upgrade import moves an old api.secret into the file. Scripts read it with IW_SECRET=${DSH_IDLE_WATCHDOG_SECRET:-$(cat ~/.dsh/idle-watchdog/api-secret)}.

Setting · Meaning · Default

enabled · Master switch (per-chat opt-in is still required) · true

idleMinutes · Minutes of silence before a nudge (1 to 10080) · 20

maxNudges · Nudges per idle period; your reply refills the budget (0 to 20, 0 = never nudge) · 3

tickSeconds · How often the watchdog scans (5 to 3600) · 30

defaultPrompt · Text posted when a chat has no prompt of its own · a short English nudge

notifyOnCap · Post one folded notice when the cap is hit · true

chats · Watched chats: id, label, enabled, prompt (override), idleMinutes (override, 0 = global) · none watched

api.secret · Shared secret for the prompt API; unset means the API fails closed · unset

api.rateLimitPerMinute · Prompt calls per minute per source IP (1 to 600) · 30

wakeColdForApi · API may resume a chat that is not currently loaded · true

skipWhenGoalActive · Never nudge a chat whose goal-round driver is armed and active · false

onlyAfterError · Nudge only after the agent reported an error since the last human message · false

backoffFactor · Window multiplier per nudge sent in a period; 2 doubles the wait each time (1 to 10) · 1 (constant)

backoffMaxMinutes · Upper bound on the backed-off window; 0 = no bound · 0

quietHours.enabled · No idle nudges inside the daily window below · false

quietHours.start / .end · HH:MM, may wrap midnight (22:00 to 07:00) · 22:00 / 07:00

quietHours.timezone · IANA zone such as Europe/Berlin; blank = server local time · blank

The behaviour options added in 1.1 (skipWhenGoalActive, onlyAfterError, backoff, quiet hours) default to the old behaviour, so upgrading

…(truncated)

Rendered from the README published on npm. Formatted only, not edited.

Versions

Published on npm::3,最后更新 2026-11-01

Links

GitHub · Homepage · npm

Same category