DeepSeek Harness Plugin Hub

Publish and manage complete Harness Profiles. Discover Plugins for your next setup.

Explore

PluginsPresetsDocsNews

Community

Publish a pluginContactReport an issue

Resources

Plugin Hub on GitHubDeepSeek HarnessSystem statusPrivacy notice
© 2026 DeepSeek Harness Plugin HubPowered byPaxTech

Independent and unofficial. Not affiliated with, authorized by, or endorsed by DeepSeek.

DeepSeek Harness Plugin Hub
ProfilesPluginsCategoriesNewsDocsSign inManage Profiles
ProfilesPluginsCategoriesNewsDocsSign in
← Plugins

dsh-warm

Warm

DeepSeek Harness host plugin: prompt-cache warmer. While a session's agent loop is blocked inside a tool execution (bash, wait_agent, job_output, ...), re-dispatches the session's last conversation request through the llm waterfall with max_tokens=1 every interval so the provider's prompt-cache pref

The plugin will be installed here. Keep web if you are unsure.

npx -y @deepseek-ai/dsh plugin --profile web add dsh-warm@0.2.0
READMECompatibilityVersions

Description

DeepSeek Harness host plugin: prompt-cache warmer. While a session's agent loop is blocked inside a tool execution (bash, wait_agent, job_output, ...), re-dispatches the session's last conversation request through the llm waterfall with max_tokens=1 every interval so the provider's prompt-cache prefix stays warm; never warms idle sessions or user-input tools. Journal + budget at $DSH_HOME/storages/dsh-warm/.

Compatibility and provenance

Warm is published as dsh-warm and currently resolves to version 0.2.0. The Hub verifies its manifest and preserves the exact installation source for reproducible installs.

DSH compatibility
*
Runtime surfaces
web
Release source
npm
Registry updated
10/20/2026

Versions

0.2.0stable
10/20/2026
0.1.0stable
10/18/2026

Related plugins

Loading related plugins…

Latest
0.2.0
DSH
*
HMR
Process restart
Tree shaking
Safe tree shaking not declared
Unpacked size
70 kB
Files
11
Surface
web
License
MIT
Source
npm
GitHub
★ 0
Weekly downloads
0
Last push
10/29/2026
View source ↗
README badge

Click the badge to copy Markdown for your README.

Do you maintain this Plugin?Claim benefit · Priority security scan

Verify the GitHub repository declared in package.json to manage this listing. After you claim it, Hub will prioritize a security scan of the current version and publish the result when it passes.

Claim this Plugin →
Report an issue

Related plugins

More verified plugins in models-usage.

Experimental Cot Translation Bundle@deepseek-ai/dsh-experimental-cot-translation-bundleExperimental machine translation of expanded reasoningOur Free Model@ebony-vinyl/dsh-our-free-modelOur Free Model — Install this plugin in dsh to use cutting-edge models including DeepSeek V4.1 Flash and Kimi K3, with no login, registration, or API Key required. The desktop version also offers an EAC co-payment channel; starting with 2.0, it supports ten account channels: LobsterAI, Qoder, TRAE, Usage@linxin666/dsh-usageUsage statistics plugin for the dsh web GUI: per-provider balance and coding-plan quota detection plus a live token usage ledger, with a compact price glance card above the sidebar's Settings rowConnect Workbuddydsh-connect-workbuddyConnects locally signed-in WorkBuddy models (domestic and international versions) to DeepSeek Harness, automatically reading each model’s points multiplier from the upstream catalog on every refresh, with per-model image input toggles, multi-account switching, automatic account rotation from an acco

README

dsh-warm

Prompt-cache warmer for DeepSeek Harness, a host plugin. It keeps a session's provider prompt-cache prefix warm while, and only while, the session's agent loop is blocked inside a tool execution (long bash, job_output, wait_agent on teammates, and similar waits).

It re-dispatches the session's last conversation request through the host llm/stream waterfall with maxTokens: 1 on a fixed interval, then discards the 1-token response. The tool's result lands on the still-warm prefix, so the next real request bills cache-hit input instead of re-prefilling ~90k tokens at miss price and paying the full TTFT again.

Why only tool blocks

Measured on this setup (2026-10-17, live probe against api.mistral.ai, zai-glm-5-3; 50 days of ledgers, 350 sessions):

  • TTL is provider-specific. Mistral's lasts 5 to 7 min here (hit at 302 s, miss at 424 s, and hits refresh the TTL), which is why the interval table is per provider.
  • Tool and teammate waits resume for sure, since the loop continues the moment the tool settles. Over 50 days that nets +$7.15 and about 1 h of TTFT recovered, with zero tail risk.
  • Idle sessions mostly never come back. 344 of 350 sessions were never resumed, and naive OpenCode-style idle warming nets −$6.91 / 50 days. So idle sessions and user-input tools (ask_user_question) are never warmed here.

A cache hit bills at a 90 % discount on this provider ($1.40/M miss, $0.14/M hit). Each ping costs about $0.014 per 100k-token prefix and saves a ~$0.126 re-prefill plus 25 to 40 s of TTFT when the block outlasts the TTL.

How the replay stays byte-identical

The loop-built request arrives at the llm/stream waterfall deep-frozen, a pure function of the session log. The warmer captures that exact object and later sends a fresh shallow copy that shares the frozen fields, changing only:

  • maxTokens: 1, a sampling field that is not part of the cached input prefix,
  • signal, the captured call's signal chained (AbortSignal.any) with the ping timeout, so a user interrupt aborts an in-flight ping too.

The same adapter that served the real call serializes the ping, so the input prefix is byte-identical and the provider serves it from cache. This is the same cache-reusing auxiliary-call pattern the harness itself uses for compaction summarization. The ping is a hand-built call (the loop's markAgentLoopRequest WeakSet identity does not carry over to the copy) and it traverses the full waterfall, so routing adapters behave identically and dsh-cost-meter bills its usage like any other call. The ledger stays honest.

Install

dsh plugin --profile web add dsh-warm                      # from npm
dsh plugin --profile web add github:JanEickholt/dsh-warm  # from GitHub, no npm needed

Or as a local plugin (link protocol):

  1. profiles/<profile>/package.json: add "dsh-warm": "link:/absolute/path/to/dsh-warm" to dependencies and "dsh-warm" to dsh.profile.bundles.
  2. pnpm install inside the profile directory.
  3. Restart the harness from a terminal (e.g. systemctl --user restart <your-dsh-unit>). A restart kills the host process; never trigger it from inside a session.

The plugin's dsh.bundle.patch (cordis.patch.yml) inserts the loader row automatically; no cordis.patch.yml edit needed.

Configuration

$DSH_HOME/storages/dsh-warm/config.json (written with defaults on first load; edit + restart). The ping interval is per provider, because the interval must sit under that provider's own prompt-cache TTL:

{
  "enabled": true,
  "dryRun": false,
  "maxPings": 5,
  "providers": {
    "mistral":   { "intervalMs": 240000, "ttlMs": 302000 },
    "openai":    { "intervalMs": 240000, "ttlMs": 300000 },
    "anthropic": { "intervalMs": 240000, "ttlMs": 300000 }
  },
  "excludeTools": ["ask_user_question"],
  "minPrefixChars": 12000,
  "maxConcurrentPings": 2,
  "dailyPingBudget": 300,
  "pingTimeoutMs": 90000,
  "stats": { "enabled": true }
}
fielddefaultmeaning
enabledtruemaster switch
dryRunfalsejournal would-be pings, dispatch nothing. Watch mode for a first deploy.
providerssee abovepresence in the table = warm this provider; each entry needs its own intervalMs and may override maxPings and ttlMs
maxPings5ping cap per tool block when a provider entry doesn't override it (the prefix is stale past maxPings × intervalMs anyway)
excludeTools["ask_user_question"]user-idle-like waits with uncertain resume
minPrefixChars12000skip tiny prefixes (≈chars/4 tokens); preventing a miss on them is not worth a ping
maxConcurrentPings2global in-flight guard; over-cap pings retry in 5 s without consuming a slot
dailyPingBudget300hard stop per UTC day, counted over real dispatch attempts (expected need ≈30/day)
pingTimeoutMs90000abort a stalled ping stream
providers.*.ttlMsadopted per known providerthe provider's cache TTL floor, used by stats classification; intervalMs when a provider has no measured value. Warns when ttlMs <= intervalMs (the grid can never bridge the TTL)
stats.enabledtruestats counting + stats.json + the /api/dsh-warm/stats route's snapshot

Why these three providers

Interval defaults are tied to each provider's own cache behavior. Measure before adding more:

  • mistral was measured on this setup (2026-10-17 live probe, zai-glm-5-3): hit at 302 s, miss at 424 s, so 240 s leaves about a minute of headroom.
  • openai documents its cache as lasting "generally between 5 minutes and up to an hour"; 240 s stays under the short end.
  • anthropic documents a 5-minute TTL, refreshed on use; 240 s fits.
  • deepseek is deliberately absent. Its automatic disk cache outlives any sane ping grid (reports range from minutes to hours, and DeepSeek publishes no TTL), so a ping there every 4 minutes is pure waste. Add an entry only after measuring an actual TTL on your account.
  • opencode-go / other proxies are absent because their TTL is unmeasured. Probe first, then add e.g. "opencode-go": { "intervalMs": 120000 }".

A pre-table config (warmProviders + intervalMs) migrates automatically into the per-provider table with a console warning.

Stats

dsh-warm keeps its own ledger of what warming bought and what it wasted, independent of any other plugin. It shows up in three places: a stats.json file, a documented HTTP route, and a small client bundle.

Counters (kept per UTC day and all-time; failed is all-time only):

countermeaning
warmspings dispatched
needlesswasted: the follow-up request arrived within the provider TTL anyway, so the prefix was still warm without the ping
noFollowupwasted: the tool block ended with no follow-up request at all (the turn went idle, or the session was disposed)
expiredwasted: the follow-up needed the warm prefix but came more than TTL after the last successful ping, so the cache had already dropped
failedpings that errored (counted separately, never as waste)
savedCacheTokenscache-read tokens of the last successful ping in a block whose follow-up was necessary and arrived within TTL, i.e. what warming verifiably bought

Approximations, by design: classification compares request/ping timestamps against the configured ttlMs, not provider-side cache state. A ping that reported a miss (cacheReadTokens 0) is never credited. After a crash (no clean dispose) the boot reseeds warms/failed from warm.jsonl but leaves outcome counters at zero, because outcomes need the follow-up request that happened after the journal line. Stats are written to storages/dsh-warm/stats.json (atomic rename, UTC-day buckets).

Toggle: "stats": { "enabled": true }, on by default. Off means no counting, no stats.json, and the route below serves "statsEnabled": false, "stats": null so consumers can render the state instead of guessing.

GET /api/dsh-warm/stats serves a stable schema for third-party consumers (say a dsh-context-insights card; both plugins stay fully independent, this route is the only coupling, and it fails open when dsh-warm is absent). The shape changes only behind a schema bump:

{
  "schema": 1,
  "statsEnabled": true,
  "stats": {
    "today":   { "day": "2026-10-20", "warms": 3, "needless": 0, "noFollowup": 1, "expired": 0, "savedCacheTokens": 1152 },
    "allTime": { "warms": 12, "needless": 1, "noFollowup": 2, "expired": 1, "savedCacheTokens": 4608 },
    "byDay":   { "2026-10-20": { "warms": 3, "needless": 0, "noFollowup": 1, "expired": 0, "savedCacheTokens": 1152 } },
    "failed": 0
  },
  "config": {
    "providers": { "mistral": { "intervalMs": 240000, "ttlMs": 302000 } },
    "budget": { "dailyPingBudget": 300, "maxPingsPerBlock": 5 },
    "dryRun": false
  }
}

The route sits behind the harness's authenticated /api fence (no separate auth; same fence as the harness's own routes) and exists whenever the plugin is enabled, also when stats are off, so the toggle state is visible.

Client bundle: the package ships a web client (dsh.client, a plain CJS factory, no build step). A "Warm" row in the sidebar footer opens a detail panel with today and all-time counters, the provider grid, and the budget; it polls while open. A dsh-warm card on the Plugins page shows the same data. Both surfaces only read the route; nothing is stored client-side.

Observability

  • storages/dsh-warm/warm.jsonl holds one line per ping: provider usage (cacheReadTokens > 0 means a hit), latency, errors, dry-run markers. It rolls at 5 MB, and the budget counter boots from today's lines.
  • storages/dsh-warm/stats.json holds the stats counters above (see Stats), atomic-written, resilient to crashes.
  • Host console: a load banner with the resolved config, plus rate-limited failure warnings.
  • dsh-cost-meter's ledger includes every ping (session-attributed via sessionId), so the economics stay verifiable against reality.

Known limitations

  • Provider scope: only providers with an entry in the providers table are warmed, and each needs a measured or documented TTL floor. deepseek and opencode-go are absent by default for that reason (see the configuration section).
  • The re-dispatch goes through the profile's main llm service; a provider adapter registered only on an isolated service would serialize differently (none exist in this profile today).
  • The 302 s TTL floor is a Mistral measurement for zai-glm-5-3; other providers need their own probe before being added to the providers table.