dsh-context-guardian 0.1.0-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +321 -0
- package/LICENSE +21 -0
- package/README.md +255 -0
- package/THIRD_PARTY_NOTICES.md +26 -0
- package/cg_recall.js +552 -0
- package/configure.py +186 -0
- package/context_guardian.py +1636 -0
- package/cordis.patch.yml +41 -0
- package/docs/dsh-integration.md +110 -0
- package/engine.js +608 -0
- package/index.js +253 -0
- package/modules/cg_bridge.py +251 -0
- package/package.json +74 -0
- package/requirements.txt +4 -0
- package/vendor/LICENSE.dsh-compaction-instant +28 -0
- package/vendor/compiler.js +851 -0
- package/vendor/region.js +455 -0
package/cordis.patch.yml
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# The dsh-context-guardian bundle patch. Applied after @deepseek-ai/dsh-base
|
|
2
|
+
# and before the profile's own cordis.patch.yml; override by id
|
|
3
|
+
# (`context-guardian`) in a later layer. A later layer REPLACES the whole
|
|
4
|
+
# `config` value (no deep merge) -- restate every key you keep.
|
|
5
|
+
#
|
|
6
|
+
# The row references the package BY NAME, never by relative path.
|
|
7
|
+
#
|
|
8
|
+
# Precedence for every key: environment variable (the existing GUARDIAN_*
|
|
9
|
+
# names, so the proxy's .env and .bat launchers mean the same thing here) >
|
|
10
|
+
# DSH settings namespace `context-guardian` > this row's config > default.
|
|
11
|
+
#
|
|
12
|
+
# PHASE 1 SCAFFOLD: this row loads the plugin shell only. It does not yet
|
|
13
|
+
# touch compaction -- @deepseek-ai/dsh-compaction-basic stays exactly as the
|
|
14
|
+
# profile has it.
|
|
15
|
+
- insert:
|
|
16
|
+
- id: context-guardian
|
|
17
|
+
name: dsh-context-guardian
|
|
18
|
+
config:
|
|
19
|
+
# Python for the optional bridge to context_guardian.py (span archive,
|
|
20
|
+
# proxy config). '' = $GUARDIAN_PYTHON, then a .venv beside this
|
|
21
|
+
# package, then python / python3 on PATH.
|
|
22
|
+
python: ''
|
|
23
|
+
# Model context window the ratios below are measured against.
|
|
24
|
+
numCtx: 32768
|
|
25
|
+
# Hard trigger (GUARDIAN_COMPACT_THRESHOLD).
|
|
26
|
+
compactThreshold: 0.85
|
|
27
|
+
# Proactive trigger when the agent goes idle (Phase 3c).
|
|
28
|
+
idleCompactRatio: 0.45
|
|
29
|
+
# Most recent messages never compacted (GUARDIAN_KEEP_RECENT_MESSAGES).
|
|
30
|
+
keepRecentMessages: 8
|
|
31
|
+
# Tokens held back for the reply (GUARDIAN_RESERVE_OUTPUT).
|
|
32
|
+
reserveOutput: 8192
|
|
33
|
+
# Span archive. '' = $GUARDIAN_SPAN_DIR, then the proxy's own default.
|
|
34
|
+
spanDir: ''
|
|
35
|
+
maxRecallTokens: 16000
|
|
36
|
+
maxSearchHits: 50
|
|
37
|
+
# Tools whose compiled line keeps its key argument; [] = the compiler's
|
|
38
|
+
# DEFAULT_ARG_TOOLS.
|
|
39
|
+
toolArgTools: []
|
|
40
|
+
# Tools that produce no compiled line at all.
|
|
41
|
+
hideTools: []
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
# Context Guardian inside DSH
|
|
2
|
+
|
|
3
|
+
## What you get
|
|
4
|
+
|
|
5
|
+
- Compaction that cannot brick a conversation: the stock LLM summary runs first; if it fails, returns nothing, or cannot fit in the window, the span is compiled deterministically instead (no model call, milliseconds)
|
|
6
|
+
- Every checkpoint line carries a `seq` pointer; `recall` and `search` tools (for the model) and `/recall`, `/context` commands (for you) read the original text back from the append-only session log
|
|
7
|
+
- Harness-injected context (workspace instructions, skill list, runtime notes) is left out of checkpoints and named by seq
|
|
8
|
+
- Idle pressure trigger: above 45% of the window it compacts when the agent goes idle
|
|
9
|
+
- Every compacted span is archived on disk in the same format the Context Guardian proxy uses
|
|
10
|
+
|
|
11
|
+
## Why it exists
|
|
12
|
+
|
|
13
|
+
On a build machine with a 32,768-token local model, every DSH session log counted on 2026-09-20: 314 compaction attempts, 48 succeeded; 145 ended with `summarization produced no text summary content`; 116 ended in a context overflow of the summariser's own request, because it replays system prompt + tools + the whole span and asks for output on top. Deterministic checkpointing eliminates both failure modes.
|
|
14
|
+
|
|
15
|
+
## Two pieces, two planes
|
|
16
|
+
|
|
17
|
+
DSH mounts compaction inside the AGENT PRESET (the `compaction` group), not in the profile. So there are two entry files: `index.js` is the profile bundle (settings + optional Python bridge), `engine.js` is one row inside your agent preset. `engine.js` imports nothing from DSH, so it works from a checkout anywhere on disk.
|
|
18
|
+
|
|
19
|
+
## Install the engine (5 minutes)
|
|
20
|
+
|
|
21
|
+
1. Get the code: `git clone https://github.com/LuminariSoftwares/context-guardian` (or use your existing checkout). Note the absolute path.
|
|
22
|
+
|
|
23
|
+
2. Make your own agent preset if you do not have one: copy the shipped `standard` preset folder to `<DSH_HOME>/.agent-presets/<your-id>/` (it contains `agent.cordis.yml` and `preset.yml`). `<DSH_HOME>` is `~/.dsh` unless you set the `DSH_HOME` environment variable.
|
|
24
|
+
|
|
25
|
+
3. Back up `agent.cordis.yml`, then add this row at the END of the `config:` list of the group whose `id` is `compaction` (after `tool-result-pruner`), indented exactly like its siblings:
|
|
26
|
+
```yaml
|
|
27
|
+
- id: context-guardian
|
|
28
|
+
name: 'file:///C:/path/to/context-guardian/engine.js'
|
|
29
|
+
config:
|
|
30
|
+
mode: llm-then-deterministic
|
|
31
|
+
numCtx: 32768
|
|
32
|
+
idleCompactRatio: 0.45
|
|
33
|
+
tools: [recall, search]
|
|
34
|
+
```
|
|
35
|
+
In the shipped preset the sibling rows (`- id: tool-result-pruner`) start at 4 spaces; match whatever yours use.
|
|
36
|
+
Note: `name` is a `file:///` URL to YOUR checkout (forward slashes, also on Windows), or a path starting with `./` relative to the preset folder if you copy `engine.js`, `cg_recall.js` and `vendor/compiler.js` next to it. `numCtx` must be your model's real context window.
|
|
37
|
+
|
|
38
|
+
4. Start a NEW session with that preset selected. No restart is needed: DSH re-mounts a preset whose file changed when the next session starts.
|
|
39
|
+
|
|
40
|
+
5. Success looks like: typing `/` in the message box lists `recall` and `context`; the file `logs/guardian_dsh.jsonl` in the checkout (or your `logPath`) gets a line with `"event":"installed"`.
|
|
41
|
+
|
|
42
|
+
## Check it works
|
|
43
|
+
|
|
44
|
+
1. In a session type `/context` and pick it: you get a pressure line like `context: ~14089 of 32768 tokens (43%), tier watch`.
|
|
45
|
+
|
|
46
|
+
2. Work until the agent goes idle above 45%: `guardian_dsh.jsonl` gets `idle-check`, `compaction/start`, `deterministic` or `llm`, `compaction/end` with `"error":null`, and `idle-compaction` with `before` and `after` token counts.
|
|
47
|
+
|
|
48
|
+
3. `/recall result <seq>` with a seq taken from a checkpoint line like `* read "scripts/x.py" (seq 29 -> result 42)` prints the original tool result. Example: idle trigger at 71%, 15 nodes, ~14,012 -> ~584 tokens, surface 23,395 -> 10,043 tokens, 23 ms, no model call.
|
|
49
|
+
|
|
50
|
+
## Options
|
|
51
|
+
|
|
52
|
+
| option | default | environment override | what it does |
|
|
53
|
+
|--------|---------|----------------------|--------------|
|
|
54
|
+
| mode | llm-then-deterministic | GUARDIAN_DSH_MODE | try LLM summary; fall back to deterministic on failure, empty output, or overflow |
|
|
55
|
+
| numCtx | 32768 | GUARDIAN_NUM_CTX | your model's context window in tokens |
|
|
56
|
+
| reserveOutput | 8192 | GUARDIAN_RESERVE_OUTPUT | space held for the summarizer's output |
|
|
57
|
+
| idleCompactRatio | 0.45 | GUARDIAN_IDLE_COMPACT_RATIO | trigger compaction when idle and pressure exceeds this fraction |
|
|
58
|
+
| idleDelayMs | 4000 | GUARDIAN_IDLE_DELAY_MS | wait this many milliseconds after the agent goes idle before checking pressure |
|
|
59
|
+
| checkpointMaxTokens | 3000 | GUARDIAN_CHECKPOINT_MAX_TOKENS | deterministic checkpoint length cap, adjusted down at high pressure |
|
|
60
|
+
| textTokens | 200 | GUARDIAN_TEXT_TOKENS | tokens allowed per text block in checkpoint |
|
|
61
|
+
| userTextTokens | 400 | GUARDIAN_USER_TEXT_TOKENS | tokens allowed per user message in checkpoint |
|
|
62
|
+
| toolCallTokens | 32 | GUARDIAN_TOOL_CALL_TOKENS | tokens allowed per tool call in checkpoint |
|
|
63
|
+
| toolResultExcerptTokens | 64 | GUARDIAN_TOOL_RESULT_TOKENS | tokens allowed per tool result excerpt in checkpoint |
|
|
64
|
+
| maxRecallTokens | 16000 | GUARDIAN_MAX_RECALL_TOKENS | maximum tokens per recall (capped at numCtx / 4) |
|
|
65
|
+
| maxSearchHits | 50 | GUARDIAN_MAX_SEARCH_HITS | maximum search results returned |
|
|
66
|
+
| keywordTerms | 25 | GUARDIAN_KEYWORD_TERMS | keyword index entries in checkpoint |
|
|
67
|
+
| filesListed | 15 | GUARDIAN_FILES_LISTED | file modifications to list in checkpoint |
|
|
68
|
+
| keepSpans | 500 | GUARDIAN_KEEP_SPANS | how many archived spans to keep on disk |
|
|
69
|
+
| spanDir | logs/guardian_spans | GUARDIAN_SPAN_DIR | directory for span archives |
|
|
70
|
+
| logPath | logs/guardian_dsh.jsonl | GUARDIAN_DSH_LOG | append-only event log (JSON lines) |
|
|
71
|
+
| tools | [recall, search] | GUARDIAN_DSH_TOOLS | which tools to expose to the model |
|
|
72
|
+
| toolArgTools | [] (the compiler's default list) | GUARDIAN_TOOL_ARG_TOOLS | tools whose checkpoint line keeps its key argument (comma-separated in the env var) |
|
|
73
|
+
| hideTools | [] | GUARDIAN_HIDE_TOOLS | tools that get no checkpoint line at all |
|
|
74
|
+
| dropSources | agent-instructions, skill-catalog, @deepseek-ai/dsh-system-prompt, repeat-tool-reminder | GUARDIAN_DROP_SOURCES | harness-injected message kinds left out of checkpoints |
|
|
75
|
+
|
|
76
|
+
Precedence: environment variable > preset row config > default. The `maxRecallTokens` option is additionally capped at a quarter of `numCtx`.
|
|
77
|
+
|
|
78
|
+
## Commands and tools
|
|
79
|
+
|
|
80
|
+
| command or tool | usage | what it does |
|
|
81
|
+
|-----------------|-------|--------------|
|
|
82
|
+
| /recall | /recall 3-7, /recall result 3, /recall checkpoint 1, /recall find text | restore original text behind a seq pointer |
|
|
83
|
+
| /context | /context | show context pressure, cache stats, compaction savings estimate |
|
|
84
|
+
| recall (tool) | called by model | restore original text to the model |
|
|
85
|
+
| search (tool) | called by model | find where something was said; returns seqs for recall |
|
|
86
|
+
| context_rewrite_cost (tool) | called by model | report pressure and compaction cost-benefit (opt-in) |
|
|
87
|
+
| context_compact (tool) | called by model | request compaction at end of this turn (opt-in) |
|
|
88
|
+
|
|
89
|
+
## Updating the engine without restarting DSH
|
|
90
|
+
|
|
91
|
+
Node caches an imported file for the life of the process. After you change `engine.js`, change the row's `name` to end in `engine.js?v=2` (then `?v=3`, ...) and start a new session; the `installed` line in `guardian_dsh.jsonl` shows the engine revision that loaded.
|
|
92
|
+
|
|
93
|
+
## Turn it off
|
|
94
|
+
|
|
95
|
+
Set environment variable `GUARDIAN_DSH_MODE=off` before starting DSH, or delete the row. Stock compaction-basic behaviour returns; nothing else changes.
|
|
96
|
+
|
|
97
|
+
## Migrating from dsh-openwolf / dsh-compaction-instant / dsh-trim
|
|
98
|
+
|
|
99
|
+
- openwolf's pre-compaction snapshot is covered by the `precompact-<seq>.json` file written next to the span archive plus the FILES WRITTEN list in each checkpoint
|
|
100
|
+
- compaction-instant's compiler is vendored here (MIT, see vendor/LICENSE.dsh-compaction-instant) and keeps the same `recall`/`search` contract
|
|
101
|
+
- dsh-trim's result shaping lives in the companion plugin dsh-tool-guardian. Do not run compaction-instant and this engine in the same preset.
|
|
102
|
+
|
|
103
|
+
## Troubleshooting
|
|
104
|
+
|
|
105
|
+
| symptom | cause | fix |
|
|
106
|
+
|---------|-------|-----|
|
|
107
|
+
| `/context` says the token meter is not available | the preset does not provide `tokenMeter` to the row | keep the row INSIDE the `compaction` group of a preset copied from `standard` |
|
|
108
|
+
| typing `/recall result 42` sends the text to the model | engine older than cg-engine-3 is loaded | use the `?v=N` step above and start a new session |
|
|
109
|
+
| new sessions fail to start after editing the preset | YAML indentation of the new row is wrong | restore your backup of `agent.cordis.yml`, re-add the row with the same indentation as `tool-result-pruner` |
|
|
110
|
+
| no `guardian_dsh.jsonl` appears | the session is not using your preset | pick the preset in the new-session screen, or set it as default in DSH settings (`agent-presets: default: <your-id>`) |
|