@martian-engineering/lossless-claw 0.6.3 → 0.8.0
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/README.md +26 -6
- package/docs/agent-tools.md +16 -5
- package/docs/configuration.md +223 -214
- package/openclaw.plugin.json +123 -0
- package/package.json +1 -1
- package/skills/lossless-claw/SKILL.md +3 -2
- package/skills/lossless-claw/references/architecture.md +12 -0
- package/skills/lossless-claw/references/config.md +135 -3
- package/skills/lossless-claw/references/diagnostics.md +13 -0
- package/src/assembler.ts +17 -5
- package/src/compaction.ts +161 -53
- package/src/db/config.ts +102 -4
- package/src/db/connection.ts +35 -7
- package/src/db/features.ts +24 -5
- package/src/db/migration.ts +257 -78
- package/src/engine.ts +1007 -110
- package/src/estimate-tokens.ts +80 -0
- package/src/lcm-log.ts +37 -0
- package/src/plugin/index.ts +493 -101
- package/src/plugin/lcm-command.ts +288 -7
- package/src/plugin/lcm-doctor-apply.ts +1 -3
- package/src/plugin/lcm-doctor-cleaners.ts +655 -0
- package/src/plugin/shared-init.ts +59 -0
- package/src/prune.ts +391 -0
- package/src/retrieval.ts +8 -9
- package/src/startup-banner-log.ts +1 -0
- package/src/store/compaction-telemetry-store.ts +156 -0
- package/src/store/conversation-store.ts +6 -1
- package/src/store/fts5-sanitize.ts +25 -4
- package/src/store/full-text-sort.ts +21 -0
- package/src/store/index.ts +8 -0
- package/src/store/summary-store.ts +21 -14
- package/src/summarize.ts +55 -34
- package/src/tools/lcm-describe-tool.ts +9 -4
- package/src/tools/lcm-expand-query-tool.ts +609 -200
- package/src/tools/lcm-expand-tool.ts +9 -4
- package/src/tools/lcm-grep-tool.ts +22 -8
- package/src/types.ts +1 -0
package/docs/configuration.md
CHANGED
|
@@ -1,272 +1,283 @@
|
|
|
1
|
-
# Configuration
|
|
1
|
+
# Configuration
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Lossless-claw reads plugin configuration from `plugins.entries.lossless-claw.config`.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Configuration precedence is:
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
1. Environment variables
|
|
8
|
+
2. `plugins.entries.lossless-claw.config`
|
|
9
|
+
3. Built-in defaults from [`src/db/config.ts`](../src/db/config.ts)
|
|
10
10
|
|
|
11
|
-
If you
|
|
11
|
+
Most installations only need to override a handful of keys. If you want a complete starting point, use the full example below and then delete entries you do not need.
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
## Complete `plugins.entries.lossless-claw.config` example
|
|
14
|
+
|
|
15
|
+
```json
|
|
16
|
+
{
|
|
17
|
+
"enabled": true,
|
|
18
|
+
"databasePath": "/Users/alice/.openclaw/lcm.db",
|
|
19
|
+
"ignoreSessionPatterns": [],
|
|
20
|
+
"statelessSessionPatterns": [],
|
|
21
|
+
"skipStatelessSessions": true,
|
|
22
|
+
"contextThreshold": 0.75,
|
|
23
|
+
"freshTailCount": 64,
|
|
24
|
+
"newSessionRetainDepth": 2,
|
|
25
|
+
"leafMinFanout": 8,
|
|
26
|
+
"condensedMinFanout": 4,
|
|
27
|
+
"condensedMinFanoutHard": 2,
|
|
28
|
+
"incrementalMaxDepth": 1,
|
|
29
|
+
"leafChunkTokens": 20000,
|
|
30
|
+
"bootstrapMaxTokens": 6000,
|
|
31
|
+
"leafTargetTokens": 2400,
|
|
32
|
+
"condensedTargetTokens": 2000,
|
|
33
|
+
"maxExpandTokens": 4000,
|
|
34
|
+
"largeFileThresholdTokens": 25000,
|
|
35
|
+
"summaryProvider": "",
|
|
36
|
+
"summaryModel": "",
|
|
37
|
+
"largeFileSummaryProvider": "",
|
|
38
|
+
"largeFileSummaryModel": "",
|
|
39
|
+
"expansionProvider": "",
|
|
40
|
+
"expansionModel": "",
|
|
41
|
+
"delegationTimeoutMs": 120000,
|
|
42
|
+
"summaryTimeoutMs": 60000,
|
|
43
|
+
"timezone": "America/Los_Angeles",
|
|
44
|
+
"pruneHeartbeatOk": false,
|
|
45
|
+
"maxAssemblyTokenBudget": 30000,
|
|
46
|
+
"summaryMaxOverageFactor": 3,
|
|
47
|
+
"customInstructions": "",
|
|
48
|
+
"circuitBreakerThreshold": 5,
|
|
49
|
+
"circuitBreakerCooldownMs": 1800000,
|
|
50
|
+
"fallbackProviders": [],
|
|
51
|
+
"cacheAwareCompaction": {
|
|
52
|
+
"enabled": true,
|
|
53
|
+
"maxColdCacheCatchupPasses": 2,
|
|
54
|
+
"hotCachePressureFactor": 4,
|
|
55
|
+
"hotCacheBudgetHeadroomRatio": 0.2
|
|
56
|
+
},
|
|
57
|
+
"dynamicLeafChunkTokens": {
|
|
58
|
+
"enabled": true,
|
|
59
|
+
"max": 40000
|
|
60
|
+
}
|
|
61
|
+
}
|
|
15
62
|
```
|
|
16
63
|
|
|
17
|
-
|
|
64
|
+
Notes on the example:
|
|
18
65
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
66
|
+
- Values shown are the runtime defaults when a fixed default exists.
|
|
67
|
+
- `databasePath` shows the expanded default path shape. Use an absolute path in config rather than `~`.
|
|
68
|
+
- `timezone` has no fixed hardcoded default; at runtime it resolves from `TZ` first, then the system timezone. The example uses `America/Los_Angeles`.
|
|
69
|
+
- `maxAssemblyTokenBudget` has no default. The example uses `30000` as a realistic cap for a 32k-class model.
|
|
70
|
+
- `databasePath` is the preferred key. `dbPath` is an accepted alias.
|
|
71
|
+
- `largeFileThresholdTokens` is the preferred key. `largeFileTokenThreshold` is an accepted alias.
|
|
22
72
|
|
|
23
|
-
|
|
73
|
+
## Install and enable
|
|
24
74
|
|
|
25
|
-
|
|
75
|
+
Install with OpenClaw's plugin installer:
|
|
26
76
|
|
|
27
77
|
```bash
|
|
28
|
-
|
|
29
|
-
export LCM_NEW_SESSION_RETAIN_DEPTH=2
|
|
30
|
-
export LCM_INCREMENTAL_MAX_DEPTH=-1
|
|
78
|
+
openclaw plugins install @martian-engineering/lossless-claw
|
|
31
79
|
```
|
|
32
80
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
## Tuning guide
|
|
36
|
-
|
|
37
|
-
### Context threshold
|
|
38
|
-
|
|
39
|
-
`LCM_CONTEXT_THRESHOLD` (default `0.75`) controls when compaction triggers as a fraction of the model's context window.
|
|
40
|
-
|
|
41
|
-
- **Lower values** (e.g., 0.5) trigger compaction earlier, keeping context smaller but doing more LLM calls for summarization.
|
|
42
|
-
- **Higher values** (e.g., 0.85) let conversations grow longer before compacting, reducing summarization cost but risking overflow with large model responses.
|
|
43
|
-
|
|
44
|
-
For most use cases, 0.75 is a good balance.
|
|
45
|
-
|
|
46
|
-
### Fresh tail count
|
|
47
|
-
|
|
48
|
-
`LCM_FRESH_TAIL_COUNT` (default `32`) is the number of most recent messages that are never compacted. These raw messages give the model immediate conversational continuity.
|
|
49
|
-
|
|
50
|
-
- **Smaller values** (e.g., 8–16) save context space for summaries but may lose recent nuance.
|
|
51
|
-
- **Larger values** (e.g., 32–64) give better continuity at the cost of a larger mandatory context floor.
|
|
52
|
-
|
|
53
|
-
For coding conversations with tool calls (which generate many messages per logical turn), 32 is recommended.
|
|
54
|
-
|
|
55
|
-
### /new retain depth
|
|
56
|
-
|
|
57
|
-
`LCM_NEW_SESSION_RETAIN_DEPTH` (default `2`) controls what survives OpenClaw's `/new` command.
|
|
58
|
-
|
|
59
|
-
- `-1` keeps all existing context items, making `/new` a transcript-only reset from lossless-claw's perspective.
|
|
60
|
-
- `0` drops only fresh-tail message items and keeps all summaries.
|
|
61
|
-
- `1` drops d0 summaries and keeps d1+.
|
|
62
|
-
- `2` drops d0 and d1 summaries, keeping d2+ project-arc context. This is the recommended default.
|
|
63
|
-
- `3+` keeps only deeper, more abstract summaries.
|
|
64
|
-
|
|
65
|
-
`/new` never deletes the summaries themselves. It only prunes `context_items`, so the summary DAG remains available for later retrieval and expansion.
|
|
66
|
-
|
|
67
|
-
### Leaf fanout
|
|
68
|
-
|
|
69
|
-
`LCM_LEAF_MIN_FANOUT` (default `8`) is the minimum number of raw messages that must be available outside the fresh tail before a leaf pass runs.
|
|
70
|
-
|
|
71
|
-
- Lower values create summaries more frequently (more, smaller summaries).
|
|
72
|
-
- Higher values create larger, more comprehensive summaries less often.
|
|
73
|
-
|
|
74
|
-
### Condensed fanout
|
|
75
|
-
|
|
76
|
-
`LCM_CONDENSED_MIN_FANOUT` (default `4`) controls how many same-depth summaries accumulate before they're condensed into a higher-level summary.
|
|
77
|
-
|
|
78
|
-
- Lower values create deeper DAGs with more levels of abstraction.
|
|
79
|
-
- Higher values keep the DAG shallower but with more nodes at each level.
|
|
80
|
-
|
|
81
|
-
### Incremental max depth
|
|
82
|
-
|
|
83
|
-
`LCM_INCREMENTAL_MAX_DEPTH` (default `0`) controls whether condensation happens automatically after leaf passes.
|
|
84
|
-
|
|
85
|
-
- **0** — Only leaf summaries are created incrementally. Condensation only happens during manual `/compact` or overflow.
|
|
86
|
-
- **1** — After each leaf pass, attempt to condense d0 summaries into d1.
|
|
87
|
-
- **2+** — Deeper automatic condensation up to the specified depth.
|
|
88
|
-
- **-1** — Unlimited depth. Condensation cascades as deep as needed after each leaf pass. Recommended for long-running sessions.
|
|
89
|
-
|
|
90
|
-
### Summary target tokens
|
|
91
|
-
|
|
92
|
-
`LCM_LEAF_TARGET_TOKENS` (default `1200`) and `LCM_CONDENSED_TARGET_TOKENS` (default `2000`) control the target size of generated summaries.
|
|
93
|
-
|
|
94
|
-
- Larger targets preserve more detail but consume more context space.
|
|
95
|
-
- Smaller targets are more aggressive, losing detail faster.
|
|
96
|
-
|
|
97
|
-
The actual summary size depends on the LLM's output; these values are guidelines passed in the prompt's token target instruction.
|
|
98
|
-
|
|
99
|
-
### Leaf chunk tokens
|
|
100
|
-
|
|
101
|
-
`LCM_LEAF_CHUNK_TOKENS` (default `20000`) caps the amount of source material per leaf compaction pass.
|
|
102
|
-
|
|
103
|
-
- Larger chunks create more comprehensive summaries from more material.
|
|
104
|
-
- Smaller chunks create summaries more frequently from less material.
|
|
105
|
-
- This also affects the condensed minimum input threshold (10% of this value).
|
|
106
|
-
|
|
107
|
-
### Maximum assembly token budget
|
|
108
|
-
|
|
109
|
-
`LCM_MAX_ASSEMBLY_TOKEN_BUDGET` (default: none) caps the token budget used for context assembly and compaction threshold evaluation. When set, this takes precedence over both the 128k fallback and runtime-provided budgets.
|
|
110
|
-
|
|
111
|
-
Set this if you're using a model with a smaller context window:
|
|
112
|
-
|
|
113
|
-
- **8k models:** `LCM_MAX_ASSEMBLY_TOKEN_BUDGET=7000`
|
|
114
|
-
- **32k models:** `LCM_MAX_ASSEMBLY_TOKEN_BUDGET=30000`
|
|
115
|
-
- **128k+ models:** No need to set (128k fallback is appropriate)
|
|
116
|
-
|
|
117
|
-
### Summary size cap
|
|
118
|
-
|
|
119
|
-
`LCM_SUMMARY_MAX_OVERAGE_FACTOR` (default: `3`) controls the hard ceiling on summary sizes relative to the target tokens (`leafTargetTokens` for leaf summaries, `condensedTargetTokens` for condensed summaries).
|
|
120
|
-
|
|
121
|
-
If a summary exceeds `overage_factor * target_tokens`, it is deterministically truncated. A warning is logged when any summary exceeds `1.5 * target_tokens`.
|
|
122
|
-
|
|
123
|
-
- **Lower values** (e.g., 2) enforce tighter summaries but may truncate more often with weaker summarizer models.
|
|
124
|
-
- **Higher values** (e.g., 5) allow more LLM flexibility but risk storing oversized summaries.
|
|
125
|
-
|
|
126
|
-
## Model selection
|
|
127
|
-
|
|
128
|
-
LCM uses the same model as the parent OpenClaw session for summarization by default. You can override this:
|
|
81
|
+
If you are running from a local OpenClaw checkout:
|
|
129
82
|
|
|
130
83
|
```bash
|
|
131
|
-
|
|
132
|
-
export LCM_SUMMARY_MODEL=anthropic/claude-sonnet-4-20250514
|
|
133
|
-
export LCM_SUMMARY_PROVIDER=anthropic
|
|
134
|
-
export LCM_SUMMARY_BASE_URL=https://api.anthropic.com
|
|
84
|
+
pnpm openclaw plugins install @martian-engineering/lossless-claw
|
|
135
85
|
```
|
|
136
86
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
When more than one source is present, compaction summarization resolves in this order:
|
|
140
|
-
|
|
141
|
-
1. `LCM_SUMMARY_MODEL` / `LCM_SUMMARY_PROVIDER`
|
|
142
|
-
2. Plugin config `summaryModel` / `summaryProvider`
|
|
143
|
-
3. OpenClaw's default compaction model/provider
|
|
144
|
-
4. Legacy per-call model/provider hints
|
|
145
|
-
|
|
146
|
-
If `summaryModel` already includes a provider prefix such as `anthropic/claude-sonnet-4-20250514`, `summaryProvider` is ignored for that choice.
|
|
147
|
-
|
|
148
|
-
For delegated `lcm_expand_query` runs, you can extend the sub-agent wait window with `delegationTimeoutMs` (plugin config) or `LCM_DELEGATION_TIMEOUT_MS` (environment variable). The default is `120000` milliseconds.
|
|
149
|
-
|
|
150
|
-
## Session controls
|
|
151
|
-
|
|
152
|
-
### Excluding sessions entirely
|
|
153
|
-
|
|
154
|
-
### `/new` vs `/reset`
|
|
155
|
-
|
|
156
|
-
Lossless-claw treats the two OpenClaw reset commands differently:
|
|
157
|
-
|
|
158
|
-
- `/new` keeps the active LCM conversation and prunes active context according to `newSessionRetainDepth`.
|
|
159
|
-
- `/reset` archives the active conversation row and creates a fresh active row for the same stable `sessionKey`.
|
|
160
|
-
|
|
161
|
-
This preserves lossless history while still giving users a real clean-slate command.
|
|
162
|
-
Lossless-claw applies `/new` through `before_reset`, then uses `session_end` to catch the broader rollover cases OpenClaw can emit: `/reset`, idle or daily session rotation, compaction-driven session replacement, and deletions. OpenClaw's command handlers still own the user-facing post-command disclosure text.
|
|
163
|
-
|
|
164
|
-
Use `ignoreSessionPatterns` or `LCM_IGNORE_SESSION_PATTERNS` to keep low-value sessions completely out of LCM. Matching sessions do not create conversations, do not store messages, and do not participate in compaction or delegated expansion grants.
|
|
165
|
-
|
|
166
|
-
- Matching uses the full session key.
|
|
167
|
-
- `*` matches any characters except `:`.
|
|
168
|
-
- `**` matches anything, including `:`.
|
|
169
|
-
|
|
170
|
-
Example:
|
|
87
|
+
For local plugin development, link a working copy:
|
|
171
88
|
|
|
172
89
|
```bash
|
|
173
|
-
|
|
90
|
+
openclaw plugins install --link /path/to/lossless-claw
|
|
174
91
|
```
|
|
175
92
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
93
|
+
## Reference
|
|
94
|
+
|
|
95
|
+
### Core storage and session behavior
|
|
96
|
+
|
|
97
|
+
| Key | Type | Default | Env override | Purpose |
|
|
98
|
+
| --- | --- | --- | --- | --- |
|
|
99
|
+
| `enabled` | `boolean` | `true` | `LCM_ENABLED` | Enables or disables lossless-claw without uninstalling it. |
|
|
100
|
+
| `databasePath` | `string` | `${HOME}/.openclaw/lcm.db` | `LCM_DATABASE_PATH` | Preferred path for the SQLite database. |
|
|
101
|
+
| `dbPath` | `string` | alias of `databasePath` | `LCM_DATABASE_PATH` | Legacy alias for `databasePath`. Prefer `databasePath` in new config. |
|
|
102
|
+
| `ignoreSessionPatterns` | `string[]` | `[]` | `LCM_IGNORE_SESSION_PATTERNS` | Session-key glob patterns that skip LCM entirely. |
|
|
103
|
+
| `statelessSessionPatterns` | `string[]` | `[]` | `LCM_STATELESS_SESSION_PATTERNS` | Session-key glob patterns that may read from LCM but never write to it. |
|
|
104
|
+
| `skipStatelessSessions` | `boolean` | `true` | `LCM_SKIP_STATELESS_SESSIONS` | Enforces `statelessSessionPatterns` when enabled. |
|
|
105
|
+
| `newSessionRetainDepth` | `integer` | `2` | `LCM_NEW_SESSION_RETAIN_DEPTH` | Controls what survives `/new`. `-1` keeps all context, `0` keeps summaries only, higher values keep only deeper summaries. |
|
|
106
|
+
| `timezone` | `string` | `TZ` or system timezone | `TZ` | IANA timezone used for timestamp rendering in summaries. |
|
|
107
|
+
| `pruneHeartbeatOk` | `boolean` | `false` | `LCM_PRUNE_HEARTBEAT_OK` | Retroactively removes `HEARTBEAT_OK` turn cycles from persisted storage. |
|
|
108
|
+
|
|
109
|
+
### Compaction thresholds and summary sizing
|
|
110
|
+
|
|
111
|
+
| Key | Type | Default | Env override | Purpose |
|
|
112
|
+
| --- | --- | --- | --- | --- |
|
|
113
|
+
| `contextThreshold` | `number` | `0.75` | `LCM_CONTEXT_THRESHOLD` | Fraction of the active model context window that triggers compaction. |
|
|
114
|
+
| `freshTailCount` | `integer` | `64` | `LCM_FRESH_TAIL_COUNT` | Number of newest messages always kept raw. |
|
|
115
|
+
| `leafMinFanout` | `integer` | `8` | `LCM_LEAF_MIN_FANOUT` | Minimum number of raw messages required before a leaf pass runs. |
|
|
116
|
+
| `condensedMinFanout` | `integer` | `4` | `LCM_CONDENSED_MIN_FANOUT` | Number of same-depth summaries needed before condensation is attempted. |
|
|
117
|
+
| `condensedMinFanoutHard` | `integer` | `2` | `LCM_CONDENSED_MIN_FANOUT_HARD` | Hard floor for condensation grouping during maintenance and repair flows. |
|
|
118
|
+
| `incrementalMaxDepth` | `integer` | `1` | `LCM_INCREMENTAL_MAX_DEPTH` | Maximum automatic condensation depth after leaf compaction. Use `0` for leaf-only and `-1` for unlimited depth. |
|
|
119
|
+
| `leafChunkTokens` | `integer` | `20000` | `LCM_LEAF_CHUNK_TOKENS` | Maximum source-token budget for a leaf compaction chunk. |
|
|
120
|
+
| `bootstrapMaxTokens` | `integer` | `max(6000, floor(leafChunkTokens * 0.3))` | `LCM_BOOTSTRAP_MAX_TOKENS` | Maximum parent-history tokens imported when a new LCM conversation bootstraps. |
|
|
121
|
+
| `leafTargetTokens` | `integer` | `2400` | `LCM_LEAF_TARGET_TOKENS` | Prompt target for leaf summary size. |
|
|
122
|
+
| `condensedTargetTokens` | `integer` | `2000` | `LCM_CONDENSED_TARGET_TOKENS` | Prompt target for condensed summary size. |
|
|
123
|
+
| `summaryMaxOverageFactor` | `number` | `3` | `LCM_SUMMARY_MAX_OVERAGE_FACTOR` | Hard ceiling multiplier before oversized summaries are deterministically truncated. |
|
|
124
|
+
| `largeFileThresholdTokens` | `integer` | `25000` | `LCM_LARGE_FILE_TOKEN_THRESHOLD` | Preferred key for the token threshold that routes text attachments into large-file summarization. |
|
|
125
|
+
| `largeFileTokenThreshold` | `integer` | alias of `largeFileThresholdTokens` | `LCM_LARGE_FILE_TOKEN_THRESHOLD` | Legacy alias accepted by the runtime. Prefer `largeFileThresholdTokens` in new config. |
|
|
126
|
+
| `maxAssemblyTokenBudget` | `integer` | unset | `LCM_MAX_ASSEMBLY_TOKEN_BUDGET` | Optional hard cap for assembly and threshold evaluation, useful with smaller-context models. |
|
|
127
|
+
| `maxExpandTokens` | `integer` | `4000` | `LCM_MAX_EXPAND_TOKENS` | Default token cap for `lcm_expand_query` responses. |
|
|
128
|
+
|
|
129
|
+
### Model selection, execution, and prompts
|
|
130
|
+
|
|
131
|
+
| Key | Type | Default | Env override | Purpose |
|
|
132
|
+
| --- | --- | --- | --- | --- |
|
|
133
|
+
| `summaryModel` | `string` | `""` | `LCM_SUMMARY_MODEL` | Summarizer model override. Bare model names reuse the chosen provider; `provider/model` strings force a specific provider. |
|
|
134
|
+
| `summaryProvider` | `string` | `""` | `LCM_SUMMARY_PROVIDER` | Provider hint used only when `summaryModel` is a bare model name. |
|
|
135
|
+
| `largeFileSummaryModel` | `string` | `""` | `LCM_LARGE_FILE_SUMMARY_MODEL` | Large-file summarizer model override. |
|
|
136
|
+
| `largeFileSummaryProvider` | `string` | `""` | `LCM_LARGE_FILE_SUMMARY_PROVIDER` | Large-file summarizer provider hint for bare model names. |
|
|
137
|
+
| `expansionModel` | `string` | `""` | `LCM_EXPANSION_MODEL` | `lcm_expand_query` sub-agent model override. |
|
|
138
|
+
| `expansionProvider` | `string` | `""` | `LCM_EXPANSION_PROVIDER` | `lcm_expand_query` sub-agent provider hint for bare model names. |
|
|
139
|
+
| `delegationTimeoutMs` | `integer` | `120000` | `LCM_DELEGATION_TIMEOUT_MS` | Maximum time to wait for delegated expansion work. |
|
|
140
|
+
| `summaryTimeoutMs` | `integer` | `60000` | `LCM_SUMMARY_TIMEOUT_MS` | Maximum time to wait for one model-backed summarizer call. |
|
|
141
|
+
| `customInstructions` | `string` | `""` | `LCM_CUSTOM_INSTRUCTIONS` | Extra natural-language instructions injected into every summarization prompt. |
|
|
142
|
+
|
|
143
|
+
### Fallbacks, circuit breaking, and safety rails
|
|
144
|
+
|
|
145
|
+
| Key | Type | Default | Env override | Purpose |
|
|
146
|
+
| --- | --- | --- | --- | --- |
|
|
147
|
+
| `fallbackProviders` | `Array<{ provider: string; model: string }>` | `[]` | `LCM_FALLBACK_PROVIDERS` | Explicit provider/model fallback chain for compaction summarization. Format for env vars is `provider/model,provider/model`. |
|
|
148
|
+
| `circuitBreakerThreshold` | `integer` | `5` | `LCM_CIRCUIT_BREAKER_THRESHOLD` | Consecutive auth failures before the summarization circuit breaker trips. |
|
|
149
|
+
| `circuitBreakerCooldownMs` | `integer` | `1800000` | `LCM_CIRCUIT_BREAKER_COOLDOWN_MS` | Cooldown before the summarization circuit breaker resets automatically. |
|
|
150
|
+
|
|
151
|
+
### Nested objects
|
|
152
|
+
|
|
153
|
+
#### `cacheAwareCompaction`
|
|
154
|
+
|
|
155
|
+
| Key | Type | Default | Env override | Purpose |
|
|
156
|
+
| --- | --- | --- | --- | --- |
|
|
157
|
+
| `cacheAwareCompaction.enabled` | `boolean` | `true` | `LCM_CACHE_AWARE_COMPACTION_ENABLED` | Defers incremental leaf compaction more aggressively when prompt-cache telemetry indicates a hot cache. |
|
|
158
|
+
| `cacheAwareCompaction.maxColdCacheCatchupPasses` | `integer` | `2` | `LCM_MAX_COLD_CACHE_CATCHUP_PASSES` | Maximum bounded catch-up passes allowed in one maintenance cycle when cache telemetry is cold. |
|
|
159
|
+
| `cacheAwareCompaction.hotCachePressureFactor` | `number` | `4` | `LCM_HOT_CACHE_PRESSURE_FACTOR` | Multiplier applied to the hot-cache leaf trigger before raw-history pressure overrides cache preservation. |
|
|
160
|
+
| `cacheAwareCompaction.hotCacheBudgetHeadroomRatio` | `number` | `0.2` | `LCM_HOT_CACHE_BUDGET_HEADROOM_RATIO` | Minimum fraction of the real token budget that must remain free before hot-cache incremental compaction is skipped entirely. |
|
|
161
|
+
|
|
162
|
+
#### `dynamicLeafChunkTokens`
|
|
163
|
+
|
|
164
|
+
| Key | Type | Default | Env override | Purpose |
|
|
165
|
+
| --- | --- | --- | --- | --- |
|
|
166
|
+
| `dynamicLeafChunkTokens.enabled` | `boolean` | `true` | `LCM_DYNAMIC_LEAF_CHUNK_TOKENS_ENABLED` | Enables dynamic working leaf chunk sizes for busier sessions. |
|
|
167
|
+
| `dynamicLeafChunkTokens.max` | `integer` | `max(leafChunkTokens, floor(leafChunkTokens * 2))` | `LCM_DYNAMIC_LEAF_CHUNK_TOKENS_MAX` | Upper bound for the dynamic working chunk size. With the default `leafChunkTokens=20000`, this resolves to `40000`. |
|
|
168
|
+
|
|
169
|
+
### Cache-aware incremental compaction
|
|
170
|
+
|
|
171
|
+
When cache-aware compaction is enabled:
|
|
172
|
+
|
|
173
|
+
- hot cache stretches the incremental leaf trigger to `dynamicLeafChunkTokens.max`
|
|
174
|
+
- hot cache skips incremental maintenance entirely when the assembled context is still comfortably below the real token budget
|
|
175
|
+
- hot cache also gets a short hysteresis window so one ambiguous turn does not immediately discard a recently healthy cache signal
|
|
176
|
+
- cold cache still allows bounded catch-up passes via `cacheAwareCompaction.maxColdCacheCatchupPasses`
|
|
177
|
+
|
|
178
|
+
When incremental leaf compaction still runs on a hot cache, follow-on condensed passes are suppressed so the maintenance cycle only pays for the leaf pass that was explicitly justified.
|
|
179
|
+
|
|
180
|
+
## Behavior notes
|
|
181
|
+
|
|
182
|
+
### Summary model resolution
|
|
183
|
+
|
|
184
|
+
Compaction summarization resolves candidates in this order:
|
|
185
|
+
|
|
186
|
+
1. `LCM_SUMMARY_MODEL` and `LCM_SUMMARY_PROVIDER`
|
|
187
|
+
2. `plugins.entries.lossless-claw.config.summaryModel` and `summaryProvider`
|
|
188
|
+
3. OpenClaw's default compaction model
|
|
189
|
+
4. Legacy per-call provider and model hints
|
|
190
|
+
5. `fallbackProviders`
|
|
191
|
+
|
|
192
|
+
If `summaryModel` already contains a provider prefix such as `anthropic/claude-sonnet-4-20250514`, `summaryProvider` is ignored for that candidate.
|
|
193
|
+
|
|
194
|
+
Runtime-managed OAuth providers are supported here too. In particular, `openai-codex` and `github-copilot` auth profiles can be used for summary and expansion calls without a separate API key.
|
|
195
|
+
|
|
196
|
+
A practical starting point for cost-sensitive setups is:
|
|
197
|
+
|
|
198
|
+
```env
|
|
199
|
+
LCM_SUMMARY_MODEL=openai/gpt-5.4-mini
|
|
200
|
+
LCM_EXPANSION_MODEL=openai/gpt-5.4-mini
|
|
201
|
+
```
|
|
179
202
|
|
|
180
|
-
|
|
203
|
+
### Session pattern matching
|
|
181
204
|
|
|
182
|
-
|
|
205
|
+
`ignoreSessionPatterns` and `statelessSessionPatterns` use full session keys.
|
|
183
206
|
|
|
184
|
-
-
|
|
185
|
-
-
|
|
186
|
-
- skip compaction writes
|
|
187
|
-
- skip delegated expansion grant writes
|
|
188
|
-
- still allow read-side assembly from existing persisted context
|
|
207
|
+
- `*` matches any characters except `:`
|
|
208
|
+
- `**` matches anything, including `:`
|
|
189
209
|
|
|
190
210
|
Example:
|
|
191
211
|
|
|
192
|
-
```bash
|
|
193
|
-
export LCM_STATELESS_SESSION_PATTERNS=agent:*:subagent:**,agent:ops:subagent:**
|
|
194
|
-
export LCM_SKIP_STATELESS_SESSIONS=true
|
|
195
|
-
```
|
|
196
|
-
|
|
197
|
-
Plugin config example:
|
|
198
|
-
|
|
199
212
|
```json
|
|
200
213
|
{
|
|
201
|
-
"
|
|
202
|
-
"
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
"agent:*:subagent:**",
|
|
210
|
-
"agent:ops:subagent:**"
|
|
211
|
-
],
|
|
212
|
-
"skipStatelessSessions": true
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
}
|
|
214
|
+
"ignoreSessionPatterns": [
|
|
215
|
+
"agent:*:cron:**"
|
|
216
|
+
],
|
|
217
|
+
"statelessSessionPatterns": [
|
|
218
|
+
"agent:*:subagent:**",
|
|
219
|
+
"agent:ops:subagent:**"
|
|
220
|
+
],
|
|
221
|
+
"skipStatelessSessions": true
|
|
217
222
|
}
|
|
218
223
|
```
|
|
219
224
|
|
|
220
|
-
|
|
225
|
+
### `/new` and `/reset`
|
|
226
|
+
|
|
227
|
+
Lossless-claw treats OpenClaw reset commands differently:
|
|
228
|
+
|
|
229
|
+
- `/new` keeps the active LCM conversation and prunes active context according to `newSessionRetainDepth`
|
|
230
|
+
- `/reset` archives the active conversation row and creates a fresh active row for the same stable `sessionKey`
|
|
231
|
+
|
|
232
|
+
This keeps long-term history available while still giving users a real clean-slate reset.
|
|
233
|
+
|
|
234
|
+
## Environment-only knobs outside plugin config
|
|
221
235
|
|
|
222
|
-
|
|
236
|
+
These settings are not part of `plugins.entries.lossless-claw.config`, but they still affect the system:
|
|
223
237
|
|
|
224
|
-
|
|
225
|
-
|
|
238
|
+
| Env var | Default | Purpose |
|
|
239
|
+
| --- | --- | --- |
|
|
240
|
+
| `LCM_TUI_CONVERSATION_WINDOW_SIZE` | `200` | Number of messages `lcm-tui` loads per keyset-paged conversation window. |
|
|
226
241
|
|
|
227
|
-
## Database
|
|
242
|
+
## Database operations
|
|
228
243
|
|
|
229
|
-
The SQLite database lives at `
|
|
244
|
+
The SQLite database lives at `databasePath` or `LCM_DATABASE_PATH`. The default path is `${HOME}/.openclaw/lcm.db`.
|
|
230
245
|
|
|
231
|
-
|
|
246
|
+
Inspect it with:
|
|
232
247
|
|
|
233
248
|
```bash
|
|
234
249
|
sqlite3 ~/.openclaw/lcm.db
|
|
235
250
|
|
|
236
|
-
# Count conversations
|
|
237
251
|
SELECT COUNT(*) FROM conversations;
|
|
238
|
-
|
|
239
|
-
# See context items for a conversation
|
|
240
252
|
SELECT * FROM context_items WHERE conversation_id = 1 ORDER BY ordinal;
|
|
241
|
-
|
|
242
|
-
# Check summary depth distribution
|
|
243
253
|
SELECT depth, COUNT(*) FROM summaries GROUP BY depth;
|
|
244
|
-
|
|
245
|
-
# Find large summaries
|
|
246
254
|
SELECT summary_id, depth, token_count FROM summaries ORDER BY token_count DESC LIMIT 10;
|
|
247
255
|
```
|
|
248
256
|
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
The database is a single file. Back it up with:
|
|
257
|
+
Back it up with:
|
|
252
258
|
|
|
253
259
|
```bash
|
|
254
260
|
cp ~/.openclaw/lcm.db ~/.openclaw/lcm.db.backup
|
|
255
|
-
```
|
|
256
|
-
|
|
257
|
-
Or use SQLite's online backup:
|
|
258
|
-
|
|
259
|
-
```bash
|
|
260
261
|
sqlite3 ~/.openclaw/lcm.db ".backup ~/.openclaw/lcm.db.backup"
|
|
261
262
|
```
|
|
262
263
|
|
|
263
|
-
##
|
|
264
|
+
## Disabling lossless-claw
|
|
264
265
|
|
|
265
|
-
|
|
266
|
+
To disable the plugin but keep it installed:
|
|
266
267
|
|
|
267
|
-
|
|
268
|
+
```json
|
|
269
|
+
{
|
|
270
|
+
"plugins": {
|
|
271
|
+
"entries": {
|
|
272
|
+
"lossless-claw": {
|
|
273
|
+
"enabled": false
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
```
|
|
268
279
|
|
|
269
|
-
To
|
|
280
|
+
To switch back to OpenClaw's legacy context engine instead:
|
|
270
281
|
|
|
271
282
|
```json
|
|
272
283
|
{
|
|
@@ -277,5 +288,3 @@ To fall back to OpenClaw's built-in compaction:
|
|
|
277
288
|
}
|
|
278
289
|
}
|
|
279
290
|
```
|
|
280
|
-
|
|
281
|
-
Or set `LCM_ENABLED=false` to disable the plugin while keeping it registered.
|