dsh-continue
已验证dsh-continue · v0.2.1 · MIT
Fail-closed network recovery, recommended answers, and safe unattended continuation for DeepSeek Harness.
安装
dsh plugin add dsh-continue 用 dsh --profile default --dump-config 确认 layer 已生效 —— 参见安装指南。
源码
标签
说明文档
dsh-continue
中文说明:docs/README.zh-CN.md
dsh-continue is an opt-in DeepSeek Harness plugin for safe unattended task continuation. It combines deterministic recovery after downstream retries, exact (provider, model, error-code) adaptive network learning, task-scoped configuration injection, and narrowly bounded automation for unique recommendations, binary continue prompts, valid Plan Mode exits, and plain-text continuation. It is designed for projects where transient interruptions and routine low-risk questions should not require someone to watch every turn.
The 0.2.x feature set also includes /continue status, /continue explain, pause/resume controls, durable activity and learning events, project-scoped decision memory with task-scope fallback, verified manual-decision provenance, suggest-only continuation candidates, configurable retry budgets, and fail-closed safety boundaries. Task session overrides take precedence over plugin defaults; unknown, ambiguous, risky, or unverified input is delegated to the official UI. Learning is off by default, and Continue never uses an LLM to guess what a question or error means.
Every executable capability is off by default. Installation alone changes no task interaction, retry, learning, or approval behavior.
How Continue differs from related plugins
Choose dsh-continue when the primary problem is task-level recovery and safe unattended handling of routine questions. The projects below overlap in retry or continuation terminology, but they solve different layers of the problem.
| Related plugin | Primary focus | What Continue adds or deliberately does not do |
|---|---|---|
@syncended/dsh-retry |
Generic and transient model-error retries, provider filters, exponential backoff, and Retry-After |
Continue is a task-level continuation layer: it first delegates request recovery, then handles configured network failures, recommendation prompts, binary continuation, and Plan Mode transitions. It does not replace generic model-error retry. |
dsh-client-auto-continue / dsh-auto-continue |
Web UI interruption recovery by sending a configured “continue” follow-up, with adaptive backoff, loop detection, and idempotency guards | Continue uses deterministic DSH events and structured state, does not blindly send a generic user message, and adds exact route learning, verified decision memory, recommended answers, Plan Mode handling, and fail-closed risk boundaries. |
@linxin666/dsh-chat-recovery |
Manual Web UI recovery by editing the previous message, forking a session, and retrying a failed turn | Continue automates only eligible recovery and decisions without rewriting history or forking; ambiguous or risky cases still return to the user. |
@deepseek-ai/dsh-llm-retry |
Official exact-provider agent-loop retry with durable retry events and bounded/always policies | Continue gives this lower-level retry path first refusal, then handles the higher-level network/decision workflow after it declines. It adds task policy, learning, and safety controls rather than duplicating provider retry events. |
These comparisons describe scope, not endorsements; check each project for its current release behavior. Continue never approves privileged or irreversible actions and never uses an LLM to guess what a question or error means.
dsh-camel is complementary rather than a comparison target here: install both when a project needs Camel's free-model RATE_LIMIT protection and Continue's non-rate network recovery or safe unattended decisions. By default, Camel owns rate limits and Continue owns TIMEOUT, TRANSPORT, and SERVER recovery.
Install
After the package is published to npm, add it to a profile:
dsh plugin --profile <profile-name> add dsh-continue
It can be installed with dsh-camel. No commands, settings, systemPrompt, or Plan Mode service is required for the base plugin to load; an unavailable optional service disables only its corresponding integration.
Quick start and presets
Use a task command for a one-task override:
/continue preset recommended
/continue preset resilient
/continue preset unattended-safe
The presets are ordinary task patches. They never enable learning.
| Preset | Enables |
|---|---|
recommended |
unique explicit recommended-option selection |
resilient |
transient network recovery and recommended-option selection |
unattended-safe |
resilient, binary continue confirmation, valid Plan Mode exit, and narrow plain-text continuation |
For a smaller explicit policy:
/continue set {"network":{"enabled":true},"recommended":{"enabled":true}}
/continue set {"continuation":{"enabled":true,"autoConfirmContinue":true}}
Configuration and task injection
Precedence is always:
task session override > plugin global defaults > built-in values
Set global defaults in the plugin row of cordis.patch.yml:
- id: continue
config:
defaults:
network:
enabled: true
mode: bounded
maxRetries: 5
recommended:
enabled: true
continuation:
enabled: false
A launcher, preset, or another plugin can inject an isolated policy for one task:
ctx.continue.setTaskConfig(agent, {
network: { enabled: true },
recommended: { enabled: true },
})
The patch is copied and written as a version-1 continue/config event. It survives resume and is inherited by a fork. null resets an override. Legacy version-1 config and control events remain replayable.
All input is schema- and runtime-validated. Unknown fields, invalid bounded retry policies, unsafe counts, oversized local timer delays, a multiplier below 1, and overlapping affirmative/negative labels are rejected.
Commands and control
When the optional commands service is available:
/continue status
/continue set <JSON object>
/continue off
/continue reset
/continue preset <recommended|resilient|unattended-safe>
/continue pause [<Nms|Ns|Nm|Nh>]
/continue resume
/continue explain
/continue learn <on|off|status|candidates|approve <candidate-id>|forget <record-id|--all>>
pause stops Continue-owned waiting, plain-text steering, structured automatic answers, and Plan Mode auto-approval for the task; resume re-enables eligible automation. status prints the effective policy, pause state, learning resolution, storage scope, and latest activity. explain reports the last automatic/delegated/blocked decision. off writes explicit false switches; unlike reset, it cannot re-inherit enabled global defaults.
Network recovery and Camel coexistence
Built-in network codes are TIMEOUT, TRANSPORT, and SERVER. RATE_LIMIT is deliberately excluded and is delegated to dsh-camel. Continue handles it only if the task or global policy explicitly adds RATE_LIMIT to network.codes; this configuration logs an ownership-overlap warning, so configure exactly one retry owner for that code.
Classification is deterministic, in this order:
- an unclaimed
RATE_LIMITis delegated to Camel; - an explicitly configured network code is transient;
- configured permanent code, then permanent HTTP status;
- configured retryable HTTP status;
- optional message-pattern fallback (permanent patterns before retryable patterns);
- unknown failures pass through.
On a matching transient failure, Continue first gives downstream middleware, including dsh-llm-retry and Camel, the chance to recover. If downstream already returns { kind: 'retry' }, Continue returns it unchanged and writes no retry event. Otherwise it writes the standard llm/retry and llm/retry-started events using policyKey: "dsh-continue:network:v1", waits, then retries.
The default backoff is 2 seconds, multiplier 2, local cap 60 seconds, and mode: unlimited once network recovery is enabled. Use mode: bounded with maxRetries for a limit. A valid provider Retry-After wins when enabled and is capped only by the Harness/Node single-timer limit (2147483647ms). Cancellation, unload, pause, or an ineligible policy change stops the wait. A persisted wait keeps its original deadline, preventing duplicate retry schedules.
Adaptive network learning
Network adaptation is separately configurable under learning.network. If network.enabled=true and no explicit learning-frequency or delay control is supplied, it uses safe adaptive defaults: increase ratio 2, decrease ratio 0.75, recovery streak 3, state TTL 7d. An explicit learning.enabled=false or learning.network.enabled=false disables it. Task settings override global settings.
Learned delay state is isolated by the exact (provider, model, error-code) triple. If the provider/model route cannot be verified (including a missing model), Continue safely uses static backoff and neither reads nor writes learned network state.
A recovery is recorded immediately only after the durable assistant/message for the same turn, step, provider, and model arrives. The latest continue/network-learning snapshot is authoritative: if it is malformed or expired, Continue logs once and uses static backoff rather than reviving an older learned delay.
Automatic decisions and safety boundary
recommended.enabled=true selects only a unique option ending in (Recommended) or (推荐). onMissingRecommendation is ask by default; first is only for interchangeable low-risk choices, and stop fails the unattended flow when a recommendation is absent.
continuation.enabled=true plus autoConfirmContinue=true accepts only a single-choice binary continue/stop question with exactly one configured affirmative and one configured negative label. autoApprovePlan=true only exits an active Plan Mode through the official state transition, for a plan that has a non-empty # heading. Plain-text continuation additionally requires plainTextFallback=true, a current-turn whitelist match, and no risk-pattern match; it is capped at one steer per turn by default.
All automatic paths fail closed to the official UI when the agent is not a verifiable live root, the turn/question shape is incomplete, a selection is ambiguous, a question is multi-select or free-form, a limit is reached, or any text matches the risk boundary. The plugin never approves approval/request, sandbox or privilege escalation, credentials, payments, external sends, releases/deployments, production actions, or irreversible operations. It never invents business data.
Controlled learning and project storage
Learning is off by default. /continue learn on enables the task learning master switch and decision-learning switch; if network recovery is also enabled, leave learning.network.enabled explicitly false when adaptive network learning is not wanted.
Decision memory is for exact, eligible, verified manual selections only. Records use confirmation and conflict tracking, expire by TTL, and have a maximum-use limit. The raw Harness tools/post-execute hook exposes no trustworthy human-confirmation provenance, so it fails closed by itself. A host UI may provide a continueManualDecisionSource service implementing the exported ContinueManualDecisionSource interface; only results that its verify(exec, result) method authenticates are trained. The verifier must use trusted UI-side state, not merely inspect answer shape. Missing, rejecting, or throwing verifiers never train, and plugin-generated answers are excluded independently.
Set learning.decisions.scope to project to use the optional @deepseek-ai/dsh-settings peer. The plugin registers its settings namespace once per runtime and reuses it across agents. Project identities are hashed; missing, read-only, invalid, or failing settings storage degrades to task scope with a visible status reason. /continue learn forget reports success for project scope only after the empty snapshot is stored. If that write fails, the command returns an error, status reports projectForget.state: "failed", and the current runtime blocks old project memory fail-closed; it does not claim that an erase survives restart.
Continuation-pattern candidates are always suggest-only. View them with /continue learn candidates; only /continue learn approve <candidate-id> can add an eligible candidate to this task's plain-text patterns. Approval never bypasses the risk boundary.
Events, migration, and examples
Public session events are append-only and versioned:
| Event | Purpose |
|---|---|
continue/config |
task override or reset |
continue/control |
pause or resume |
continue/network-learning |
adaptive network snapshot |
continue/decision-learning |
task decision-memory snapshot |
continue/pattern-candidate |
suggest-only candidate lifecycle |
continue/activity |
latest automatic, delegated, blocked, cancelled, or learned activity |
Version 1 config/control events continue to replay. To migrate from earlier releases, keep existing task events, upgrade the package, and explicitly opt into any new capability. Do not add RATE_LIMIT to both Camel and Continue. For an existing global profile, start with recommended, then resilient, and only enable unattended-safe after reviewing project-specific question and risk patterns.
Example task policy with project decision scope but no network adaptation:
/continue set {"network":{"enabled":true},"learning":{"enabled":true,"network":{"enabled":false},"decisions":{"enabled":true,"scope":"project","minConfirmations":2,"ttlMs":2592000000,"maxUses":50}}}