@jayyuen66/dsh-session-rescue

sessionnpmMIT

Automatic recovery when a turn ends badly: resume after a transient failure, continue after output truncation, re-run after an unfinished todo list, plus a request-level 429 backstop and a client dock with edit-resend, manual retry and stop-and-re-ask.

下载量 / Downloads
447

Install

dsh plugin --profile web add @jayyuen66/dsh-session-rescue

Sandbox test

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

README

<p align="center">

<img src="https://cdn.jsdelivr.net/gh/JayYuen666/dsh-session-rescue@main/icon.svg" width="96" height="96" alt="dsh-session-rescue logo" />

</p>

<h1 align="center">dsh-session-rescue</h1>

<p align="center"><em>When a turn ends badly, the session picks itself back up: auto-resume after transient failures, auto-continue after truncation, catch-up for open todo lists — plus manual rescue actions below the input box.</em></p>

<p align="center">

<a href="https://www.npmjs.com/package/@jayyuen66/dsh-session-rescue"><img src="https://img.shields.io/npm/v/@jayyuen66/dsh-session-rescue?style=flat-square&logo=npm&logoColor=white" alt="npm version" /></a>

<a href="https://www.npmjs.com/package/@jayyuen66/dsh-session-rescue"><img src="https://img.shields.io/npm/d18m/@jayyuen66/dsh-session-rescue?style=flat-square" alt="npm downloads (total)" /></a>

<a href="https://github.com/JayYuen666/dsh-session-rescue/actions/workflows/ci.yml"><img src="https://img.shields.io/github/actions/workflow/status/JayYuen666/dsh-session-rescue/ci.yml?branch=main&style=flat-square&label=ci" alt="ci" /></a>

<img src="https://img.shields.io/badge/license-MIT-4c1?style=flat-square" alt="MIT" />

<img src="https://img.shields.io/badge/node-%3E%3D24.9-4c1?style=flat-square&logo=nodedotjs&logoColor=white" alt="node" />

<img src="https://img.shields.io/badge/dsh-%5E0.2.1--rc.5-658EFF?style=flat-square" alt="dsh" />

<a href="https://github.com/deepseek-ai/deepseek-harness"><img src="https://img.shields.io/badge/powered_by_dsh-4D6BFE?style=flat-square&logo=deepseek&logoColor=white" alt="powered by dsh" /></a>

</p>

<p align="center">

<img src="https://skillicons.dev/icons?i=typescript,nodejs,react,vitest,githubactions" alt="tech stack" />

</p>

<p align="center">

<a href="https://github.com/JayYuen666"><img src="https://img.shields.io/badge/GitHub-JayYuen666-181717?style=flat-square&logo=github&logoColor=white" alt="GitHub" /></a>

<a href="mailto:cqwkkj@gmail.com"><img src="https://img.shields.io/badge/Email-cqwkkj@gmail.com-EA4335?style=flat-square&logo=gmail&logoColor=white" alt="Email" /></a>

<a href="https://twitter.com/JayYuen666"><img src="https://img.shields.io/badge/Twitter-X%2FJayYuen666-000000?style=flat-square&logo=x&logoColor=white" alt="Twitter/X" /></a>

<a href="./README.zh-CN.md"><img src="https://img.shields.io/badge/lang-简体中文-658EFF?style=flat-square" alt="简体中文" /></a>

</p>

A dsh plugin: three automatic user-role injections when a turn ends badly (transient failure / max-tokens truncation / an open todo list), a request-level 429 backstop, and a client dock with manual rescue actions and a settings card. Zero model tools, zero HTTP routes of its own.

<img src="https://api.iconify.design/lucide/file-text.svg?color=%23658EFF&height=22" height="22" width="22" align="absmiddle" alt="" /> Contents

  • [What it does](#what-it-does)
  • [How a decision is made](#how-a-decision-is-made)
  • [Install](#install)
  • [Shared version floor](#shared-version-floor)
  • [Verify it is live](#verify-it-is-live)
  • [What it does not provide](#what-it-does-not-provide)
  • [Enabling it in dsh](#enabling-it-in-dsh)
  • [The three automatic actions](#the-three-automatic-actions)
  • [Settings](#settings)
  • [Public interface](#public-interface)
  • [Data and privacy](#data-and-privacy)
  • [Known boundaries](#known-boundaries)
  • [FAQ](#faq)
  • [Development](#development)
  • [License](#license)

<img src="https://api.iconify.design/lucide/shield.svg?color=%23658EFF&height=22" height="22" width="22" align="absmiddle" alt="" /> What it does

  • Three automatic injections when a turn ends badly, each with its own delay / cooldown / quota gates (lib/resume-scheduler.ts, cooldowns tracked per kind):
  • resume — agent/error whose failure classifyFailure (lib/failure-classify.ts) judges transient; the message lands after resumeDelayMs.
  • continue — the turn ended with reason.kind === "max-tokens"; "continue from the truncation" lands after continueDelayMs.
  • unfinished — the turn ended completed, but the todo list that turn itself wrote still holds open items (lib/turn-review.ts, a purely structural signal, no text guessing); the catch-up message lands after unfinishedDelayMs.
  • Every injection is a role: "user" message with source: { kind: "plugin:session-rescue" } sent through agent.followup() — the model keeps running, so tokens and quota keep being spent.
  • A request-level 429 backstop, engaged only when the host resolved no retryPolicy for that provider: it listens on agent/request-error (waterfall) and returns { kind: "retry" } on rate limiting, so the host re-sends that request inside the same turn.
  • Fixed backoff ladder (defaults 2 s / 5 s / 10 s / 20 s / 30 s, at most 5 retries per session — deployment values); a provider Retry-After wins over the ladder, and anything above the cap is not waited out but delegated back to next(). The counter resets when the turn closes.
  • When a policy exists the official llm-retry owns the retry (code filtering, provider retry-after, jitter, durable events). The deepseek adapter resolves a policy even when none is configured, so this ladder only ever engages for adapters that resolve none.
  • A client dock below the input box: edit-resend (this session) / fork-resend (new branch) / stop-and-reask / manual retry and continue-output / a countdown banner / a per-session switch. Stop-and-reask queues your re-ask first and then cancels, so the message survives the cancel; the manual retry stays disabled while the host's built-in retry is still in progress.
  • Connection-aware: an injection whose send failed (transport trouble) is suspended instead of dropped, shown as a reconnecting banner, and re-armed with its remaining delay once the connection returns.
  • /state polling is a self-scheduling two-tier loop: 1 s while a pending

…(truncated)

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

Versions

Published on npm::9,最后更新 2026-11-05

Links

GitHub · Homepage · npm

Same category