dsh-web
zhu1090093659/dsh-webDeepSeek Harness(DSH)Web 插件聚合生态包 · 一切皆插件,创意工坊分发(dsh-market.com)
Model-driven context-window rollover bundle for the DeepSeek Harness: fresh working context, durable notes, verbatim recent tail, no summarization
A DeepSeek Harness bundle for model-driven context self-management: the model can deliberately end one working context window and continue in a fresh one while preserving durable state — with no summarization.
fresh working context + durable model-managed notes + small recent raw tail + recoverable full history
Inspired by the context-management architecture in openai/codex (the
new_context tool, token-budget compaction without a summarizer, history/notes
separation) and pi-posthorse. Codex is the architectural reference; DSH is the
implementation authority — everything runs through DSH's own surface-replace
protocol and compaction transaction.
Web profile: rollover only runs in the
standard-rolloverpreset.Installing this bundle is not enough on its own. The Web profile composes compaction from the session's agent preset, and the default preset (
standard) stays exactly as shipped: it keeps the built-in summarizer and gets no rollover tools and no rollover guidance — nonew_context, noget_context_remaining, nonotes, nohistory. Astandardsession cannot roll over at all.To use it, open a new session and select "Standard + rollover (experimental)" in the preset picker before sending the first message — a session's preset is frozen once its first turn runs.
Headless and other rosterless profiles are the exception: they have no preset roster, so the host engine serves every session and there is nothing to pick.
The plugin provides the active ctx.compaction engine (it disables
dsh-compaction-basic in its bundle patch). On the Web profile the engine
must additionally live in the session's agent preset — see
Web profiles below. A rollover is a real DSH
compaction: compaction/start → compaction/summary → one replacement
user/message with full source provenance → compaction/end — but the
"summary" is a deterministic checkpoint (durable notes plus an optional
handoff), never an LLM call. Raw session events stay persisted; a
token-budgeted recent tail stays verbatim on the surface; deriveMessages()
rebuilds automatically.
Responsibilities stay split (the Codex lesson):
| Concern | Owner |
|---|---|
| Request a boundary | new_context tool (records a pending request only) |
| Cross the boundary | agent/pre-step (before the next model request) and agent/turn-stopping |
| Track windows | rollover count + summary seqs read from the durable log |
| Measure pressure | ctx.tokenMeter + the routed model's context window |
| Replace the surface | commitRollover inside DSH's compaction transaction |
| Preserve selected state | notes tool (markdown files per session) |
| Recover old details | history tool (search/read over shadowed surface events) |
new_context({ handoff? }) — request a context boundary at the next safe
point. The handoff (bounded) becomes part of the new window's checkpoint. The
boundary is crossed at a safe lifecycle point, never mid-tool-batch.get_context_remaining() — honest headroom: tokens left before the hard
window and before the automatic rollover, or "not measured yet".notes — list | read | write | append | search over per-session
markdown files under <dsh home>/notes/<session id>/. Nothing is written
automatically; the model decides what survives.history — search | read over conversation that left the active
surface. Targeted recovery, not wholesale reconstruction.new_context
with a short handoff at a phase boundary (research → implementation, etc.).thresholdRatio of the window the engine
rolls over automatically with durable notes and the recent verbatim tail.
Below that, a one-per-window checkpoint reminder suggests saving notes
and rolling over.CONTEXT_WINDOW_EXCEEDED forces a
rollover with the same notes + tail checkpoint and retries the request./compact keeps working — it performs the same standalone
notes + tail rollover on an idle agent.Only the model-driven path carries a handoff. The engine never writes one for pressure, overflow, or manual rollovers: producing a handoff itself would mean either an LLM summarization call or copying older user messages into the fresh window, and the second option revives stale requests. Those paths preserve intent through notes and the recent verbatim tail instead.
new_context, get_context_remaining, notes, history)
and one system-prompt section — on headless profiles in every session; on
the Web profile only inside standard-rollover sessions (other presets stay
exactly as shipped).<dsh home>/notes/<sessionId>/.
Nothing else on disk is written; no network calls, no telemetry.compaction-basic is disabled by the bundle patch).
Session logs stay fully compatible in both directions.The plugin typechecks against both host lines: the development checkout and
its installed profiles (0.1.6-alpha.1, via generated tsconfig paths) and the
newest packages published to public npm (0.0.1-rc.1, the
pnpm typecheck:compat probe against compat/node_modules). Runtime
differences are bridged in src/compat.ts:
snapshotEvents() (newer line) or events (published);eventAt(seq) versus indexing that array;heuristicTokens (newer line) or tokens;{ startSeq, endSeq } (newer line) or
{ start, end }, probed once per process because each line rejects the
other's field names.Note the published @deepseek-ai/dsh-* packages are a partial mirror: some
of their peers reference packages that were never published publicly, so a
standalone npm-only host graph cannot be assembled. That is expected — the
plugin's peers resolve from the running dsh host's installation closure, and
installing the plugin itself into a profile fetches only this package.
From npm (recommended):
dsh plugin --profile <profile> add dsh-context-rollover
# or, without the dsh CLI:
pnpm --dir "$DSH_HOME/profiles/<profile>" add dsh-context-rollover
A custom profile initializes with just dsh-base; the bundle's patch applies
automatically because the package declares dsh.bundle.patch. After the first
install (a bundle-membership change is a boot-time composition), start the
profile once — the plugin's peer packages resolve from the running host's
installation closure, never from npm.
From GitHub instead of npm:
dsh plugin --profile <profile> add github:athif23/dsh-context-rollover
From a local checkout (development, see the HMR section below):
dsh plugin --profile <profile> add D:/path/to/dsh-context-rollover
Windows note: if the plugin loads but its @deepseek-ai/* imports fail at
runtime after an install from Git Bash, pnpm may have materialized broken
link: junctions (a Git Bash/Windows path-mangling bug). Recreate them with
cmd /c mklink /J as described in the HMR section below — the same fix
applies to any linked sibling package in the profile.
The bundle's cordis.patch.yml disables dsh-compaction-basic and mounts the
context-rollover engine itself. command-compact, the token meter, and the
compaction invariant companions need no changes — they depend only on
ctx.compaction.
Headless and other base-only profiles are done after the install above: the
host engine is the session's engine, no roster exists, and nothing stands
down. The Web profile is different — its sessions compose compaction from
their agent preset, not from the host — so the bundle additionally
registers a shipped standard-rollover preset ("Standard + rollover
(experimental)" in the picker) beside the deployment's own set. Restart the
host once after install, then open new sessions on it to try the
experiment; standard stays the default. Pick the preset while the session is
still blank: the creation header is deep-frozen, and a session may only
change preset before its first turn runs, so an already-started standard
session cannot be moved onto rollover.
No commands, no profile edits. Two behaviors make that hold:
standard
session the shipped summarizer runs alone (previously the two backends
raced each pressure signal); on standard-rollover the preset's rollover
engine runs alone; headless sessions keep the host engine.modelSurface: 'always', so it is the only
source of rollover tools and guidance in its sessions. On preset
deployments the host row (modelSurface: 'auto') registers neither, so
standard and minimal sessions never see rollover-framed instructions.Custom thresholds belong to your own preset copy (the supported customization
flow: copy standard-rollover in the picker and edit the context-rollover
row) — the shipped preset carries the defaults below. If a deployment
restates the whole agent-presets config in a later patch layer, that layer
wins and hides the shipped preset; re-adding the bundle's root there
restores it. Uninstalling the bundle removes the preset: sessions already on
it keep running, new ones must pick another preset.
Maintainers: presets/standard-rollover/ is generated, not authored —
re-run pnpm preset:sync after harness updates and commit the refresh. The
sync keeps everything else byte-identical and fails loud when the shipped
standard shape drifts.
Configuration (cordis.yml config on the plugin row):
- insert:
- id: context-rollover
name: dsh-context-rollover
config:
thresholdRatio: 0.9 # automatic rollover point (fraction of window)
reminderThresholdRatio: 0.75 # one-time checkpoint reminder point
retainRatio: 0.1 # recent verbatim tail (fraction of window)
retainTokens: null # absolute tail budget; overrides retainRatio
handoffMaxChars: 20000
notesEnabled: true
historyEnabled: true
notesDir: null # base dir override; default <dsh home>/notes
modelSurface: auto # auto (host rows) | always (preset rows)
The fast loop runs DSH from your checkout with the plugin linked from this directory and Cordis HMR watching the source:
Create a dedicated profile and link this package
dsh plugin --profile rollover-dev add D:/path/to/dsh-context-rollover
(A custom profile initializes with just dsh-base; the bundle's patch
applies automatically because the package declares dsh.bundle.patch.)
Enable the hmr row in $DSH_HOME/profiles/rollover-dev/cordis.patch.yml
(patch rows replace whole configs, so restate root):
- id: hmr
config:
root: ['.', 'D:/path/to/dsh-context-rollover/src']
debounce: 100
The base bundle mounts hmr disabled by default; the timer row it needs
is already active.
Run DSH from source
cd /path/to/deepseek-harness
pnpm run build # once; Typert host artifacts are required
pnpm dsh --profile rollover-dev
Source launch runs through tsx (node --import tsx/esm), which is what makes
hot reload of TypeScript plugin sources work.
Edit src/*.ts in this package — the affected plugin reloads in place;
registrations (tools, system-prompt sections, event listeners) unwind and
reapply through Cordis effects. Profile patch edits also recompose live
(patchReload: live is the default for custom profiles).
Restart is still required for: initial bundle installation, bundle
membership changes (dsh.plugin add/remove), framework-level dependency
changes (Cordis falls back to loader.exit()), and anything HMR cannot
safely swap.
link: junctions and Git Bashpnpm install in a profile run from Git Bash mangles link:D:/...
specifiers into junctions with invalid targets (the drive colon is treated
as relative). If a profile's linked plugins fail to load after an install,
recreate the junctions with the real targets:
cmd /c mklink /J "%DSH_HOME%\profiles\web\node_modules\dsh-context-rollover" "D:\path\to\dsh-context-rollover"
(or run the install from PowerShell/cmd). This package's own runtime peers
are junctions into the shared installation closure at
$DSH_HOME/profiles/node_modules/@deepseek-ai/*. That is what lets the
engine share the host's module instances: a service plugin that extends
CompactionEngine must import the exact classes the host loaded, so
resolving its @deepseek-ai/* imports through the same closure as the host
is load-bearing, not an optimization.
The sibling DSH checkout is the source of truth: tsconfig.base.json paths are
generated into tsconfig.dsh-paths.json and vitest aliases execute everything
from TypeScript source — the same source plane DSH's own suites use. Vendored
packages typecheck against their built declarations so skipLibCheck absorbs
their relaxed strictness.
pnpm install
pnpm test # surface, notes, history, engine integration, tool rendering
pnpm typecheck
Tests mount the real session store, token meter, tool runtime, agent loop, and
the compaction invariant companions, so every committed rollover is
validated against DSH's own invariants. The integration test proves the
semantic experiment end to end: the model researches, calls new_context
mid-turn, and the fresh window carries notes + handoff + recent tail while the
turn continues.
Session.append cannot mark a plugin's
custom event types ignorable, so unknown plugin events on a session log
would make that log unreadable by any DSH build without the plugin. Only
known event types (compaction/*, user/message) are written.<compaction> checkpoint provenance is reused, so transcript UIs
recognize rollover checkpoints like any compaction.MIT