Auto-resumes interrupted DSH Web requests: sends a queued 「继续」 after network, timeout or host-crash failures, with error classification, adaptive backoff, templated continue text and browser notifications.
Install
# from npm (prebuilt)
dsh plugin --profile web add dsh-client-auto-continue
# from GitHub (first run asks for allowBuilds approval — follow the hint, retry)
dsh plugin --profile web add github:HsiangNianian/dsh-auto-continue
GitHub-sourced plugins run build scripts on your machine at install time. Only install sources you trust, and pin a commit (github:owner/repo#sha).
README
What It Does
For DeepSeek Harness (dsh web): whenever a request in the web GUI gets interrupted by a non-human cause, the plugin simulates the user typing 「继续」 and sends it, so the agent keeps working without manual intervention. The message enters the session log exactly like a manual prompt — the model sees it, and the interrupted work resumes.
Smart recovery (all configurable):
- Error classification — transient failures (network / timeout / 5xx / 429…) are auto-resumed; permanent ones are skipped and notified, because retrying them never helps. A failure counts as permanent when its HTTP status is 401/403 or its code/message matches auth, credential/API-key, balance/quota, unknown-model, or context-length/overflow keywords. Turn classification off to resume everything
- Adaptive backoff — consecutive failures wait longer each time (cooldown × factor: 20s → 40s → 80s…), capped at the max backoff, instead of hammering a broken upstream
- Templated continue text —
continueTextsupports{code}{message}{status}{tool}{turn}placeholders, so the resume message can carry the failure context ("继续 (git push failed: UPSTREAM)") - Browser notifications — optional alerts when auto-continue fires, gives up, or hits a permanent error; the browser asks for permission on first use, and nothing is shown again after a denial
It watches the live event streams and reacts to:
| Event | Meaning |
|---|---|
turn/end → error |
Turn failed (model / network / timeout, …) |
turn/end → interrupted |
Crash-orphaned turn left behind by a host restart |
turn/end → max-tokens |
Output token ceiling reached |
host/agent-error |
Agent failure with no turn position |
Never auto-continues: user-aborted turns (aborted) or policy rejections (blocked); sessions the host already resumed itself; running sessions or sessions with queued messages; subagent sessions; anything inside the cooldown / consecutive-cap windows (configurable in the settings card, below).
How It Works
The plugin opens two extra SSE streams in the browser — events.mux (session events) and events.host (host events). The host supports multiple consumers, so this never interferes with the built-in runtime. On an interruption it waits a grace period (default 3 s) — if the host starts a new turn by itself (turn/start), the auto-continue is cancelled — then calls sessions.prompt in queue mode with the configured text.
On page load / reconnect it also scans the most recently updated sessions: a session whose last turn ended with a non-human reason within the scan window (default 15 minutes), with no later turn/start or user message, gets resumed automatically too (e.g. the host crashed while the browser was closed).
With the page open in several tabs, a localStorage mutex plus a shared per-session cooldown stamp guarantee exactly one tab sends — no duplicated 「继续」.
All knobs live in the plugin's settings card — see Configuration.
Quick Start
DSH plugins install into a profile (dsh web → web profile). Install, restart dsh web, done.
From npm (recommended)
Published as dsh-client-auto-continue:
dsh plugin --profile web add dsh-client-auto-continue
dsh web
Directly from GitHub (no clone needed)
Installs straight from the repository's default branch — built artifacts are committed, so no local clone or build step:
dsh plugin --profile web add github:HsiangNianian/dsh-auto-continue
dsh web
This tracks the
mainbranch rather than released tags — great for trying the latest changes, while the npm method above is the stable choice. Switching between install sources is just re-runningdsh plugin --profile web add <other-spec>; the profile dependency is replaced in place.
From this repository
Requires Node.js ≥ 18.
git clone https://github.com/HsiangNianian/dsh-auto-continue.git
cd dsh-auto-continue
npm install
npm run build
# the package carries its own cordis.patch.yml (dsh.bundle.patch),
# so the plugin row registers itself
dsh plugin --profile web add link:$(pwd)
dsh web
Manual (no pnpm / dsh plugin needed)
ln -sfn "$(pwd)" ~/.dsh/profiles/node_modules/dsh-client-auto-continue
# then append to ~/.dsh/profiles/web/cordis.patch.yml:
# - insert:
# - id: auto-continue
# name: 'dsh-client-auto-continue'
dsh web
Switching from a manual install to
dsh plugin add? Remove the manualinsertentry first — the bundle patch registers the row and a duplicate would conflict.
Known DSH limitation (0.1.0-rc.6): the web plugin-configuration section only exposes settings namespaces on a hardcoded allowlist in the installed
@deepseek-ai/dsh-host-apiproxybundle. Until upstream moves exposure intosettings.register(), one idempotent vendor patch is required for the settings card to appear (re-run it after reinstalling dsh):node node_modules/dsh-client-auto-continue/scripts/patch-expose.mjs dsh webThe patch script ships inside the npm package (no repo clone needed) and covers every reachable dsh installation: the profile-linked copy, a global
npm i -g @deepseek-ai/dshinstall, and the invoking directory's own. The auto-continue engine itself works without this patch — it only gates the GUI settings card.
Verify & uninstall
dsh --profile web --dump-config | grep auto-continue # config layer mounted
In the browser console (Ctrl/Cmd+Shift+I): [auto-continue] 已启动(文本="继续", …) — every detection and auto-send is logged.
dsh plugin --profile web remove dsh-client-auto-continue # npm / repo install
# or remove the symlink + the insert entry # manual install
dsh web
Configuration
Everything is configurable from the GUI — no file or console edits needed. Open Settings → Plugin configuration and find the Auto continue card.
How the card works:
- Edits are staged — nothing reaches the disk until you hit Save; an unsaved badge marks the card while drafts are pending, and Discard drops them
- A field you changed shows an Overridden badge with a per-field Reset to default button that restores the built-in value
- Boolean fields are tri-state: Inherit (use the default) / On / Off
- Invalid drafts (non-numbers, values below the minimum) block the save with a hint
- In a read-only deployment the card shows the stored values but disables every control
- Changes apply immediately after Save and persist in
~/.dsh/settings.yaml(uninstalling the plugin leaves the section behind — harmless, delete it by hand if you like)
| Field | Default | Description |
|---|---|---|
| Continue text | 继续 |
Text automatically sent after an interruption |
| Grace period (ms) | 3000 |
Wait after an interruption; cancelled if the host recovers on its own |
| Cooldown (ms) | 20000 |
Min interval between auto-continues per session (failed attempts count too) |
| Max consecutive | 3 |
Max consecutive auto-continues; stops until a user intervenes or a turn completes |
| Scan on load / reconnect | on |
Scan recently interrupted sessions on load / reconnect |
| Scan limit | 8 |
Max sessions scanned (running / subagent sessions excluded) |
| Scan window (ms) | 900000 |
Scan only considers interruptions inside this window |
| Reconnect scan delay (ms) | 5000 |
Delay before scanning after a reconnect |
| Reconnect backoff (ms) | 3000 |
SSE reconnect backoff |
| Verbose logs | on |
[auto-continue] console logs |
| Classify errors | on |
Auto-resume transient failures only; auth / balance / model errors are skipped and notified |
| Backoff factor | 2 |
Cooldown multiplier per consecutive failure (2 = 20s → 40s → 80s…) |
| Max backoff (ms) | 300000 |
Cap on the adaptive backoff interval |
| Browser notifications | off |
Notify when auto-continue fires, gives up, or hits a permanent error |
continueText accepts the placeholders {code}, {message}, {status}, {tool} (last tool call before the failure) and {turn} — e.g. 继续 ({tool}: {code}) becomes 继续 (git push: UPSTREAM).
Privacy & permissions
The plugin is browser-only and touches no files, credentials, or network beyond the dsh host:
- It opens the same two read-only event streams the web UI already uses (no extra server, no third-party endpoints)
- The only write it ever performs is
sessions.prompt— the same call the Send button makes — with the text you configured - Browser storage is limited to small
localStoragekeys for cross-tab coordination - Browser notifications are opt-in (
notifysetting) and permission is requested on first use only
Development
npm run typecheck # tsc --noEmit
npm run build # lib/client.js + lib/index.js + lib/types
npm run watch # rebuild on change; host HMR hot-reloads without a page refresh
npm run test # node tests/simulate.mjs — 12 behavioral scenarios
While npm run watch runs, the profile's client-hmr row polls lib/client.js every 500 ms and hot-reloads the plugin in the browser — no server restart needed for code changes.
Activity
Links
- Repository: github.com/HsiangNianian/dsh-auto-continue
- DeepSeek Harness: github.com/deepseek-ai/deepseek-harness
License
MIT © Hsiang Nianian
Links
More in this category
zhu1090093659/dsh-web-ui★ 1766
Plugin and skin collection for the DSH Web UI: task board, Git graph, right-side panel, remote mobile UI, pet, live token stats, and a skin center.
ccch1mneyyy/dsh-TUI★ 829
Claude Code-style full-screen terminal UI: pixel-whale header, live status line, and streaming thought expansion.
omdsh-dev/DSH-better-sidebar★ 705
Full sidebar workbench with file rendering and editing, terminal, Git, and subagents; third-party plugins can register new tabs.
huiliyi37/dsh-tianshu-tui★ 131
A terminal UI (TUI) for DeepSeek Harness.
omdsh-dev/dsh-at-file★ 117
Codex-style `@file` mentions: search workspace files in the composer and attach their contents to prompts.
Nagi-ovo/dsh-visualize★ 79
In-conversation generative UI: the model renders interactive HTML cards into the chat stream, with streaming preview and sandboxed rendering.