# dsh-resume-turn DSH plugin: **resume an interrupted reply from its partial output** instead of restarting from scratch. [简体中文](./README.zh.md) · [Repository](https://github.com/Harris-Logic/dsh-resume-turn) · [Issues](https://github.com/Harris-Logic/dsh-resume-turn/issues) · MIT When a model request fails mid-stream on a slow / flaky endpoint (e.g. the AMD DeepSeek endpoint — slow inference, frequent disconnects, `TIMEOUT` / `TRANSPORT` / `SERVER` / `RATE_LIMIT`), the default `dsh-llm-retry` rebuilds the *same* request and re-runs it **from zero**: everything that had already streamed (including a long thinking chain) is thrown away, and a multi-minute attempt can be repeated several times before giving up. `dsh-resume-turn` changes that: at the failure point it collects the partial output that **already streamed** (visible text + reasoning chunks) from the session event log, injects a visible "auto-resumed" steering message that quotes that partial output and instructs the model to continue from where it stopped, and takes over recovery with `{ kind: 'retry' }` — so the next request starts from the interruption point, not from zero. ## How it works ``` agent/request-error (waterfall) ├─ user cancelled? → delegate (never auto-resume over a user stop) ├─ code not transient? → delegate ├─ no partial output? → delegate (nothing to resume; default retry is right) ├─ mid tool-call? → delegate (restart is safer for tool arguments) ├─ resume budget spent (default 3 / turn)? → delegate └─ otherwise ├─ collect current-attempt chunks (assistant/chunk events after the │ last attempt boundary) → partial text + reasoning ├─ cancellable backoff (2s, doubling, cap 30s) ├─ agent.steer(resume message) # visible "auto-resumed" row; carries │ # the partial output + "continue" instruction └─ return { kind: 'retry' } # retry rebuilds the request from the # surface, which now includes the resume message ``` ## Install (one command) ```bash # from GitHub npx @deepseek-ai/dsh plugin --profile web add github:Harris-Logic/dsh-resume-turn # or from a local checkout npx @deepseek-ai/dsh plugin --profile web add /absolute/path/to/dsh-resume-turn ``` Restart the profile (or the web host) to activate. The package declares `dsh.bundle.patch`, so the installer appends it to `dsh.profile.bundles` and its `cordis.patch.yml` plugin row is applied automatically — **no manual file edits**. `@deepseek-ai/*` modules come from the host (the very `schemastery` / `dsh-llm` instances DSH itself runs on): they are declared as optional peers and are never installed separately. ## Config The plugin has no required config. Optional keys (in the profile's `cordis.patch.yml` row `config`, or as bundle config): | key | default | meaning | |---|---|---| | `maxResumesPerTurn` | `3` | max auto-resumes per turn; beyond that, default retry takes over | | `resumeCodes` | `["TIMEOUT","TRANSPORT","SERVER","RATE_LIMIT"]` | failure codes eligible for resume | | `initialDelayMs` | `2000` | backoff before the first resume (doubles per attempt, cap 30s) | | `maxPartialChars` | `12000` | max characters of partial output quoted into the resume message | ## Interaction with dsh-llm-retry - On providers whose `retryPolicy` is `mode: always` (recommended for flaky endpoints; see the [A1 config](./README.zh.md) notes), `llm-retry` consults downstream recovery first — this plugin gets the first refusal. Returning `{ kind: 'retry' }` short-circuits the chain; returning `undefined` lets `llm-retry` schedule its own backoff. - On `mode: normal` providers this plugin is only consulted if it is ordered before `llm-retry` in the waterfall; otherwise the default restart-based retry applies unchanged. ## Limitations - Resume quotes the partial output into context; the continued answer may rephrase a boundary sentence (mitigated by the "don't repeat" instruction). - If the endpoint fails again right after a resume, attempts count against the per-turn budget; after the budget is spent the default retry takes over. - A host restart resets in-memory resume budgets/boundaries (no custom session events are appended, so stored logs stay fully readable). ## License MIT