@martian-engineering/lossless-claw 0.6.3 → 0.7.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 CHANGED
@@ -30,11 +30,23 @@ Nothing is lost. Raw messages stay in the database. Summaries link back to their
30
30
 
31
31
  ## Commands And Skill
32
32
 
33
- The plugin now ships a bundled `lossless-claw` skill plus a small native command surface:
33
+ The plugin now ships a bundled `lossless-claw` skill plus a small plugin command surface for supported OpenClaw chat/native command providers:
34
34
 
35
35
  - `/lcm` shows version, enablement/selection state, DB path and size, summary counts, and summary-health status
36
36
  - `/lcm doctor` scans for broken or truncated summaries
37
- - `/lossless` is an alias for `/lcm` on native command surfaces
37
+ - `/lossless` is an alias for `/lcm` on supported native command surfaces
38
+
39
+ These are plugin slash/native commands, not root shell CLI subcommands. Supported examples:
40
+
41
+ - `/lcm`
42
+ - `/lcm doctor`
43
+ - `/lossless`
44
+
45
+ Not currently supported as root CLI commands:
46
+
47
+ - `openclaw lcm`
48
+ - `openclaw lossless`
49
+ - `openclaw /lcm`
38
50
 
39
51
  The bundled skill focuses on configuration, diagnostics, architecture, and recall-tool usage. Its reference set lives under `skills/lossless-claw/references/`.
40
52
 
@@ -70,7 +82,7 @@ openclaw plugins install --link /path/to/lossless-claw
70
82
 
71
83
  The install command records the plugin, enables it, and applies compatible slot selection (including `contextEngine` when applicable).
72
84
 
73
- > **Note:** If your OpenClaw config uses `plugins.allow`, make sure both `lossless-claw` and any active plugins you rely on remain allowlisted. In some setups, narrowing the allowlist can prevent plugin-backed integrations from loading, even if `lossless-claw` itself is installed correctly. Restart the gateway after plugin config changes.
85
+ > **Note:** If your OpenClaw config uses `plugins.allow`, allowlist the plugin id `lossless-claw` plus any other active plugins you rely on. Do not add command tokens or aliases like `lossless` or `/lcm` to `plugins.allow`; that setting only accepts plugin ids. In some setups, narrowing the allowlist can prevent plugin-backed integrations from loading, even if `lossless-claw` itself is installed correctly. Restart the gateway after plugin config changes.
74
86
 
75
87
  ### Configure OpenClaw
76
88
 
@@ -32,6 +32,8 @@ Summaries are lossy by design. The "Expand for details about:" footer at the end
32
32
 
33
33
  Search across messages and/or summaries using regex or full-text search.
34
34
 
35
+ Use `mode: "full_text"` for keyword or topical recall. Wrap exact multi-word phrases in quotes to preserve phrase matching. Keep the default `sort: "recency"` for recent events, switch to `sort: "relevance"` when looking for the best older match on a topic, and use `sort: "hybrid"` when you want relevance without giving up recency entirely.
36
+
35
37
  **Parameters:**
36
38
 
37
39
  | Param | Type | Required | Default | Description |
@@ -44,6 +46,7 @@ Search across messages and/or summaries using regex or full-text search.
44
46
  | `since` | string | | — | ISO timestamp lower bound |
45
47
  | `before` | string | | — | ISO timestamp upper bound |
46
48
  | `limit` | number | | 50 | Max results (1–200) |
49
+ | `sort` | string | | `"recency"` | `"recency"`, `"relevance"`, or `"hybrid"` for full-text ranking |
47
50
 
48
51
  **Returns:** Array of matches with:
49
52
  - `id` — Message or summary ID
@@ -59,6 +62,9 @@ Search across messages and/or summaries using regex or full-text search.
59
62
  # Full-text search across all conversations
60
63
  lcm_grep(pattern: "database migration", mode: "full_text", allConversations: true)
61
64
 
65
+ # Older-topic recall ranked by FTS relevance
66
+ lcm_grep(pattern: "\"error handling\" retries", mode: "full_text", sort: "relevance")
67
+
62
68
  # Regex search in summaries only
63
69
  lcm_grep(pattern: "config\\.threshold.*0\\.[0-9]+", scope: "summaries")
64
70
 
@@ -167,7 +173,7 @@ Add instructions to your agent's system prompt so it knows when to use LCM tools
167
173
  ## Memory & Context
168
174
 
169
175
  Use LCM tools for recall:
170
- 1. `lcm_grep` — Search all conversations by keyword/regex
176
+ 1. `lcm_grep` — Search all conversations by keyword/regex. Prefer `mode: "full_text"` for topic recall, quote exact phrases, use `sort: "relevance"` for older-topic lookups, and `sort: "hybrid"` when recency should still matter.
171
177
  2. `lcm_describe` — Inspect a specific summary (cheap, no sub-agent)
172
178
  3. `lcm_expand_query` — Deep recall with sub-agent expansion
173
179
 
@@ -1,272 +1,274 @@
1
- # Configuration guide
1
+ # Configuration
2
2
 
3
- ## Quick start
3
+ Lossless-claw reads plugin configuration from `plugins.entries.lossless-claw.config`.
4
4
 
5
- Install the plugin with OpenClaw's plugin installer:
5
+ Configuration precedence is:
6
6
 
7
- ```bash
8
- openclaw plugins install @martian-engineering/lossless-claw
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're running from a local OpenClaw checkout:
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
- ```bash
14
- pnpm openclaw plugins install @martian-engineering/lossless-claw
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
- For local development of this plugin, link your working copy:
64
+ Notes on the example:
18
65
 
19
- ```bash
20
- openclaw plugins install --link /path/to/lossless-claw
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
- `openclaw plugins install` handles plugin registration/enabling and slot selection automatically.
73
+ ## Install and enable
24
74
 
25
- Set recommended environment variables:
75
+ Install with OpenClaw's plugin installer:
26
76
 
27
77
  ```bash
28
- export LCM_FRESH_TAIL_COUNT=32
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
- Restart OpenClaw.
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:
81
+ If you are running from a local OpenClaw checkout:
112
82
 
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
83
+ ```bash
84
+ pnpm openclaw plugins install @martian-engineering/lossless-claw
85
+ ```
127
86
 
128
- LCM uses the same model as the parent OpenClaw session for summarization by default. You can override this:
87
+ For local plugin development, link a working copy:
129
88
 
130
89
  ```bash
131
- # Use a specific model for summarization
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
90
+ openclaw plugins install --link /path/to/lossless-claw
135
91
  ```
136
92
 
137
- Using a cheaper/faster model for summarization can reduce costs, but quality matters — poor summaries compound as they're condensed into higher-level nodes.
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. |
138
108
 
139
- When more than one source is present, compaction summarization resolves in this order:
109
+ ### Compaction thresholds and summary sizing
140
110
 
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
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. |
145
128
 
146
- If `summaryModel` already includes a provider prefix such as `anthropic/claude-sonnet-4-20250514`, `summaryProvider` is ignored for that choice.
129
+ ### Model selection, execution, and prompts
147
130
 
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.
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. |
149
142
 
150
- ## Session controls
143
+ ### Fallbacks, circuit breaking, and safety rails
151
144
 
152
- ### Excluding sessions entirely
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. |
153
150
 
154
- ### `/new` vs `/reset`
151
+ ### Nested objects
155
152
 
156
- Lossless-claw treats the two OpenClaw reset commands differently:
153
+ #### `cacheAwareCompaction`
157
154
 
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`.
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. |
160
161
 
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.
162
+ #### `dynamicLeafChunkTokens`
163
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.
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`. |
165
168
 
166
- - Matching uses the full session key.
167
- - `*` matches any characters except `:`.
168
- - `**` matches anything, including `:`.
169
+ ### Cache-aware incremental compaction
169
170
 
170
- Example:
171
+ When cache-aware compaction is enabled:
171
172
 
172
- ```bash
173
- export LCM_IGNORE_SESSION_PATTERNS=agent:*:cron:**,agent:main:subagent:**
174
- ```
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`
175
177
 
176
- ### Stateless sessions
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.
177
179
 
178
- Use `statelessSessionPatterns` or `LCM_STATELESS_SESSION_PATTERNS` for sessions that should be able to read from LCM without writing to it. This is especially useful for sub-agent sessions, which use real OpenClaw keys like `agent:<agentId>:subagent:<uuid>`.
180
+ ## Behavior notes
179
181
 
180
- Enable enforcement with `skipStatelessSessions` or `LCM_SKIP_STATELESS_SESSIONS=true`.
182
+ ### Summary model resolution
181
183
 
182
- When a session key matches a stateless pattern and enforcement is enabled, LCM will:
184
+ Compaction summarization resolves candidates in this order:
183
185
 
184
- - skip bootstrap imports
185
- - skip ingest and after-turn persistence
186
- - skip compaction writes
187
- - skip delegated expansion grant writes
188
- - still allow read-side assembly from existing persisted context
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`
189
191
 
190
- Example:
191
-
192
- ```bash
193
- export LCM_STATELESS_SESSION_PATTERNS=agent:*:subagent:**,agent:ops:subagent:**
194
- export LCM_SKIP_STATELESS_SESSIONS=true
195
- ```
192
+ If `summaryModel` already contains a provider prefix such as `anthropic/claude-sonnet-4-20250514`, `summaryProvider` is ignored for that candidate.
193
+
194
+ ### Session pattern matching
195
+
196
+ `ignoreSessionPatterns` and `statelessSessionPatterns` use full session keys.
197
+
198
+ - `*` matches any characters except `:`
199
+ - `**` matches anything, including `:`
196
200
 
197
- Plugin config example:
201
+ Example:
198
202
 
199
203
  ```json
200
204
  {
201
- "plugins": {
202
- "entries": {
203
- "lossless-claw": {
204
- "config": {
205
- "ignoreSessionPatterns": [
206
- "agent:*:cron:**"
207
- ],
208
- "statelessSessionPatterns": [
209
- "agent:*:subagent:**",
210
- "agent:ops:subagent:**"
211
- ],
212
- "skipStatelessSessions": true
213
- }
214
- }
215
- }
216
- }
205
+ "ignoreSessionPatterns": [
206
+ "agent:*:cron:**"
207
+ ],
208
+ "statelessSessionPatterns": [
209
+ "agent:*:subagent:**",
210
+ "agent:ops:subagent:**"
211
+ ],
212
+ "skipStatelessSessions": true
217
213
  }
218
214
  ```
219
215
 
220
- ## TUI conversation window size
216
+ ### `/new` and `/reset`
221
217
 
222
- `LCM_TUI_CONVERSATION_WINDOW_SIZE` (default `200`) controls how many messages `lcm-tui` loads per keyset-paged conversation window when a session has an LCM `conversation_id`.
218
+ Lossless-claw treats OpenClaw reset commands differently:
223
219
 
224
- - Smaller values reduce render/query cost for very large conversations.
225
- - Larger values show more context per page but increase render time.
220
+ - `/new` keeps the active LCM conversation and prunes active context according to `newSessionRetainDepth`
221
+ - `/reset` archives the active conversation row and creates a fresh active row for the same stable `sessionKey`
226
222
 
227
- ## Database management
223
+ This keeps long-term history available while still giving users a real clean-slate reset.
228
224
 
229
- The SQLite database lives at `LCM_DATABASE_PATH` (default `~/.openclaw/lcm.db`).
225
+ ## Environment-only knobs outside plugin config
230
226
 
231
- ### Inspecting the database
227
+ These settings are not part of `plugins.entries.lossless-claw.config`, but they still affect the system:
228
+
229
+ | Env var | Default | Purpose |
230
+ | --- | --- | --- |
231
+ | `LCM_TUI_CONVERSATION_WINDOW_SIZE` | `200` | Number of messages `lcm-tui` loads per keyset-paged conversation window. |
232
+
233
+ ## Database operations
234
+
235
+ The SQLite database lives at `databasePath` or `LCM_DATABASE_PATH`. The default path is `${HOME}/.openclaw/lcm.db`.
236
+
237
+ Inspect it with:
232
238
 
233
239
  ```bash
234
240
  sqlite3 ~/.openclaw/lcm.db
235
241
 
236
- # Count conversations
237
242
  SELECT COUNT(*) FROM conversations;
238
-
239
- # See context items for a conversation
240
243
  SELECT * FROM context_items WHERE conversation_id = 1 ORDER BY ordinal;
241
-
242
- # Check summary depth distribution
243
244
  SELECT depth, COUNT(*) FROM summaries GROUP BY depth;
244
-
245
- # Find large summaries
246
245
  SELECT summary_id, depth, token_count FROM summaries ORDER BY token_count DESC LIMIT 10;
247
246
  ```
248
247
 
249
- ### Backup
250
-
251
- The database is a single file. Back it up with:
248
+ Back it up with:
252
249
 
253
250
  ```bash
254
251
  cp ~/.openclaw/lcm.db ~/.openclaw/lcm.db.backup
255
- ```
256
-
257
- Or use SQLite's online backup:
258
-
259
- ```bash
260
252
  sqlite3 ~/.openclaw/lcm.db ".backup ~/.openclaw/lcm.db.backup"
261
253
  ```
262
254
 
263
- ## Per-agent configuration
255
+ ## Disabling lossless-claw
264
256
 
265
- In multi-agent OpenClaw setups, each agent uses the same LCM database but has its own conversations (keyed by session ID). The plugin config applies globally; per-agent overrides use environment variables set in the agent's config.
257
+ To disable the plugin but keep it installed:
266
258
 
267
- ## Disabling LCM
259
+ ```json
260
+ {
261
+ "plugins": {
262
+ "entries": {
263
+ "lossless-claw": {
264
+ "enabled": false
265
+ }
266
+ }
267
+ }
268
+ }
269
+ ```
268
270
 
269
- To fall back to OpenClaw's built-in compaction:
271
+ To switch back to OpenClaw's legacy context engine instead:
270
272
 
271
273
  ```json
272
274
  {
@@ -277,5 +279,3 @@ To fall back to OpenClaw's built-in compaction:
277
279
  }
278
280
  }
279
281
  ```
280
-
281
- Or set `LCM_ENABLED=false` to disable the plugin while keeping it registered.