@whatsmore-nf/dsh-context-steward
English | 中文
A DeepSeek Harness plugin that treats the fixed-capacity context window as a scarce
cognitive resource and schedules it: within a hard token budget it protects
attention bandwidth for the agent's current key decisions, tiers compression by
value density, consolidates completed phases, and keeps a structured fact vault
so evicted source text stays recallable.
It ships as a Cordis Service registered at ctx.contextSteward, with a
schemastery-declared static Config and static inject, following the same
plugin shape as the official Harness plugins (e.g. @deepseek-ai/dsh-compaction-basic).
Relationship to official compaction
Official dsh-compaction-* compacts the conversation body itself. This plugin
is the complementary layer: it schedules injected memory — deduplicating
repeated observations, tiered compression, phase consolidation, key-decision
bandwidth guarantees, and fact recall — before the compacted snapshot is
injected into the model-visible context. Both can run side by side.
Install
Via Harness plugin CLI (same as other official plugins):
dsh plugin --profile web add @whatsmore-nf/dsh-context-steward@latest
Or directly via npm:
npm install @whatsmore-nf/dsh-context-steward
The plugin needs the Harness runtime (@deepseek-ai/cordis, @deepseek-ai/dsh-agent,
@deepseek-ai/dsh-llm, @deepseek-ai/dsh-session) as peer dependencies; a
Harness profile already provides them.
Load
Add a row to a cordis.yml / cordis.patch.yml bundle:
- id: dsh-context-steward
name: '@whatsmore-nf/dsh-context-steward'
config:
capacity: 8000
enabled: true
inject: true
Loading registers the ctx.contextSteward Service and wires it automatically
to the Harness lifecycle events (see Events).
Config (ContextStewardConfig)
Every key is optional; missing keys fall back to the resolved defaults below.
Unknown keys, wrong types, and out-of-range ratios fail plugin load
(resolveConfig rejects them, mirroring official plugins).
| Key | Default | Meaning |
|---|
capacity | 4000 | Token budget of the injected compressed context (the fixed bandwidth cap). |
reserved | 0 | System tokens excluded from the compressible region. |
decisionGuarantee | floor(capacity × 0.35) | Attention bandwidth floor: max tokens the working set may occupy while a key decision is protected. |
halfLifeMs | 600000 | Time-decay half-life (10 min) for recency weighting. |
adaptiveRecency | true | Adapt the half-life to observed decision cadence. |
minAdaptiveHalfLifeMs | 10000 | Lower bound of the adaptive half-life. |
maxAdaptiveHalfLifeMs | 3600000 | Upper bound of the adaptive half-life. |
adaptiveThresholds | true | Self-tune demote/promote thresholds from churn. |
churnWindowMs | 60000 | Churn observation window for threshold tuning. |
tuneStep | 0.03 | Threshold tuning step. |
demoteThreshold | 0.35 | Score below which working items are demoted to the cold pool. |
promoteThreshold | 0.55 | Score above which cold items are promoted back to the working set. |
workingRenderRatio | 0.5 | Share of the render budget given to the working set. |
maxProtectedDecisions | 4 | Max protected decision snapshots kept verbatim (older ones age out). |
coldCompactScore | 0.4 | Minimum score for cold-pool tiered compression. |
rehydrateThreshold | 0.6 |
Usage
Service form (inside the Harness)
import type { Context } from '@deepseek-ai/cordis'
import ContextSteward from '@whatsmore-nf/dsh-context-steward'
export const name = 'context-steward'
export const inject = ['sessions']
export function apply(ctx: Context): void {
const plugin = ctx.plugin(ContextSteward, { capacity: 8000 })
// Optional: plug in an LLM semantic summarizer (async prewarm during pre-step idle time,
// upgrading compression from heuristics to structured summaries)
// plugin.asyncSummarize = async (content, depth) => await llm.complete(
// buildCompactionPrompt({ context: [content] }), { maxTokens: depth >= 3 ? 160 : 80 },
// )
}
The Service is available as ctx.contextSteward; per-session schedulers are
obtained with ctx.contextSteward.scheduler(session).
Standalone form (demo / unit tests, no Harness runtime)
import { createContextStewardPlugin } from '@whatsmore-nf/dsh-context-steward'
const plugin = createContextStewardPlugin({ capacity: 8000 })
plugin.hooks.onAppend?.({ id: 'u1', kind: 'user', content: '目标是部署服务', timestamp: 0 })
plugin.hooks.onDecision?.({ goal: '部署服务', currentStep: '选型', attentionFocus: ['部署', '服务'] })
const prompt = plugin.hooks.onBeforePrompt?.() // 注入压缩后的上下文
Scheduler core
CognitiveResourceScheduler is exported standalone: ingest(), checkpoint(),
setPhase(), consolidatePhase(), compiledContext(), query(),
exportArchive(), exportState() / restoreState() — see the type
declarations for the full surface.
Events
When enabled is true, the plugin subscribes to:
| Event | Purpose |
|---|
session/event | Feed model-visible user/assistant/tool events into the scheduler (dedupe, tiered compression, fact extraction, bandwidth accounting). Self-injected compressed context is skipped. |
agent/pre-step | Treat the upcoming step as a key decision: attention re-ranking, then inject the compressed snapshot. |
agent/request-error | On CONTEXT_WINDOW_EXCEEDED failure, feed the overflow as an observation so the next snapshot perceives it. |
agent/disposed | Export the archive, log closing metrics, and release the session state. |
License
MIT