@martian-engineering/lossless-claw 0.2.8 → 0.4.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
@@ -1,6 +1,6 @@
1
1
  # lossless-claw
2
2
 
3
- Lossless Context Management plugin for [OpenClaw](https://github.com/openclaw/openclaw), based on the [LCM paper](https://papers.voltropy.com/LCM). Replaces OpenClaw's built-in sliding-window compaction with a DAG-based summarization system that preserves every message while keeping active context within model token limits.
3
+ Lossless Context Management plugin for [OpenClaw](https://github.com/openclaw/openclaw), based on the [LCM paper](https://papers.voltropy.com/LCM) from [Voltropy](https://x.com/Voltropy). Replaces OpenClaw's built-in sliding-window compaction with a DAG-based summarization system that preserves every message while keeping active context within model token limits.
4
4
 
5
5
  ## Table of contents
6
6
 
@@ -94,7 +94,12 @@ Add a `lossless-claw` entry under `plugins.entries` in your OpenClaw config:
94
94
  "config": {
95
95
  "freshTailCount": 32,
96
96
  "contextThreshold": 0.75,
97
- "incrementalMaxDepth": -1
97
+ "incrementalMaxDepth": -1,
98
+ "ignoreSessionPatterns": [
99
+ "agent:*:cron:**"
100
+ ],
101
+ "summaryProvider": "anthropic",
102
+ "summaryModel": "claude-3-5-haiku"
98
103
  }
99
104
  }
100
105
  }
@@ -102,12 +107,17 @@ Add a `lossless-claw` entry under `plugins.entries` in your OpenClaw config:
102
107
  }
103
108
  ```
104
109
 
110
+ `summaryModel` and `summaryProvider` let you pin compaction summarization to a cheaper or faster model than your main OpenClaw session model. When unset, LCM uses OpenClaw's configured default model/provider.
111
+
105
112
  ### Environment variables
106
113
 
107
114
  | Variable | Default | Description |
108
115
  |----------|---------|-------------|
109
116
  | `LCM_ENABLED` | `true` | Enable/disable the plugin |
110
117
  | `LCM_DATABASE_PATH` | `~/.openclaw/lcm.db` | Path to the SQLite database |
118
+ | `LCM_IGNORE_SESSION_PATTERNS` | `""` | Comma-separated glob patterns for session keys to exclude from LCM storage |
119
+ | `LCM_STATELESS_SESSION_PATTERNS` | `""` | Comma-separated glob patterns for session keys that may read from LCM but never write to it |
120
+ | `LCM_SKIP_STATELESS_SESSIONS` | `true` | Enable stateless-session write skipping for matching session keys |
111
121
  | `LCM_CONTEXT_THRESHOLD` | `0.75` | Fraction of context window that triggers compaction (0.0–1.0) |
112
122
  | `LCM_FRESH_TAIL_COUNT` | `32` | Number of recent messages protected from compaction |
113
123
  | `LCM_LEAF_MIN_FANOUT` | `8` | Minimum raw messages per leaf summary |
@@ -121,11 +131,67 @@ Add a `lossless-claw` entry under `plugins.entries` in your OpenClaw config:
121
131
  | `LCM_LARGE_FILE_TOKEN_THRESHOLD` | `25000` | File blocks above this size are intercepted and stored separately |
122
132
  | `LCM_LARGE_FILE_SUMMARY_PROVIDER` | `""` | Provider override for large-file summarization |
123
133
  | `LCM_LARGE_FILE_SUMMARY_MODEL` | `""` | Model override for large-file summarization |
124
- | `LCM_SUMMARY_MODEL` | *(from OpenClaw)* | Model for summarization (e.g. `anthropic/claude-sonnet-4-20250514`) |
125
- | `LCM_SUMMARY_PROVIDER` | *(from OpenClaw)* | Provider override for summarization |
134
+ | `LCM_SUMMARY_MODEL` | `""` | Model override for compaction summarization; falls back to OpenClaw's default model when unset |
135
+ | `LCM_SUMMARY_PROVIDER` | `""` | Provider override for compaction summarization; falls back to `OPENCLAW_PROVIDER` or the provider embedded in the model ref |
136
+ | `LCM_EXPANSION_MODEL` | *(from OpenClaw)* | Model override for `lcm_expand_query` sub-agent (e.g. `anthropic/claude-haiku-4-5`) |
137
+ | `LCM_EXPANSION_PROVIDER` | *(from OpenClaw)* | Provider override for `lcm_expand_query` sub-agent |
126
138
  | `LCM_AUTOCOMPACT_DISABLED` | `false` | Disable automatic compaction after turns |
127
139
  | `LCM_PRUNE_HEARTBEAT_OK` | `false` | Retroactively delete `HEARTBEAT_OK` turn cycles from LCM storage |
128
140
 
141
+ ### Expansion model override requirements
142
+
143
+ If you want `lcm_expand_query` to run on a dedicated model via `expansionModel` or `LCM_EXPANSION_MODEL`, OpenClaw must explicitly trust the plugin to request sub-agent model overrides.
144
+
145
+ Add a `subagent` policy under `plugins.entries.lossless-claw` and allowlist the canonical `provider/model` target you want the plugin to use:
146
+
147
+ ```json
148
+ {
149
+ "models": {
150
+ "openai/gpt-4.1-mini": {}
151
+ },
152
+ "plugins": {
153
+ "entries": {
154
+ "lossless-claw": {
155
+ "enabled": true,
156
+ "subagent": {
157
+ "allowModelOverride": true,
158
+ "allowedModels": ["openai/gpt-4.1-mini"]
159
+ },
160
+ "config": {
161
+ "expansionModel": "openai/gpt-4.1-mini"
162
+ }
163
+ }
164
+ }
165
+ }
166
+ }
167
+ ```
168
+
169
+ - `subagent.allowModelOverride` is required for OpenClaw to honor plugin-requested per-run `provider`/`model` overrides.
170
+ - `subagent.allowedModels` is optional but recommended. Use `"*"` only if you intentionally want to trust any target model.
171
+ - The chosen expansion target must also be available in OpenClaw's normal model catalog. If it is not already configured elsewhere, add it under the top-level `models` map as shown above.
172
+ - If you prefer splitting provider and model, set `config.expansionProvider` and use a bare `config.expansionModel`.
173
+
174
+ Plugin config equivalents:
175
+
176
+ - `ignoreSessionPatterns`
177
+ - `statelessSessionPatterns`
178
+ - `skipStatelessSessions`
179
+ - `summaryModel`
180
+ - `summaryProvider`
181
+
182
+ Environment variables still win over plugin config when both are set.
183
+
184
+ ### Summary model priority
185
+
186
+ For compaction summarization, lossless-claw resolves the model in this order:
187
+
188
+ 1. `LCM_SUMMARY_MODEL` / `LCM_SUMMARY_PROVIDER`
189
+ 2. Plugin config `summaryModel` / `summaryProvider`
190
+ 3. OpenClaw's default compaction model/provider
191
+ 4. Legacy per-call model/provider hints
192
+
193
+ If `summaryModel` already includes a provider prefix such as `anthropic/claude-sonnet-4-20250514`, `summaryProvider` is ignored for that choice. Otherwise, the provider falls back to the matching override, then `OPENCLAW_PROVIDER`, then the provider inferred by the caller.
194
+
129
195
  ### Recommended starting configuration
130
196
 
131
197
  ```
@@ -138,6 +204,87 @@ LCM_CONTEXT_THRESHOLD=0.75
138
204
  - **incrementalMaxDepth=-1** enables unlimited automatic condensation after each compaction pass — the DAG cascades as deep as needed. Set to `0` (default) for leaf-only, or a positive integer for a specific depth cap.
139
205
  - **contextThreshold=0.75** triggers compaction when context reaches 75% of the model's window, leaving headroom for the model's response.
140
206
 
207
+ ### Session exclusion patterns
208
+
209
+ 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.
210
+
211
+ Pattern rules:
212
+
213
+ - `*` matches any characters except `:`
214
+ - `**` matches anything, including `:`
215
+ - Patterns match the full session key
216
+
217
+ Examples:
218
+
219
+ - `agent:*:cron:**` excludes cron sessions for any agent, including isolated run sessions like `agent:main:cron:daily-digest:run:run-123`
220
+ - `agent:main:subagent:**` excludes all main-agent subagent sessions
221
+ - `agent:ops:**` excludes every session under the `ops` agent id
222
+
223
+ Environment variable example:
224
+
225
+ ```bash
226
+ LCM_IGNORE_SESSION_PATTERNS=agent:*:cron:**,agent:main:subagent:**
227
+ ```
228
+
229
+ Plugin config example:
230
+
231
+ ```json
232
+ {
233
+ "plugins": {
234
+ "entries": {
235
+ "lossless-claw": {
236
+ "config": {
237
+ "ignoreSessionPatterns": [
238
+ "agent:*:cron:**",
239
+ "agent:main:subagent:**"
240
+ ]
241
+ }
242
+ }
243
+ }
244
+ }
245
+ }
246
+ ```
247
+
248
+ ### Stateless session patterns
249
+
250
+ Use `statelessSessionPatterns` or `LCM_STATELESS_SESSION_PATTERNS` for sessions that should still be able to read from existing LCM context, but should never create or mutate LCM state themselves. This is useful for delegated or temporary sub-agent sessions that should benefit from retained context without polluting the database.
251
+
252
+ When `skipStatelessSessions` or `LCM_SKIP_STATELESS_SESSIONS` is enabled, matching sessions:
253
+
254
+ - skip bootstrap imports
255
+ - skip message persistence during ingest and after-turn hooks
256
+ - skip compaction writes and delegated expansion grant writes
257
+ - can still assemble context from already-persisted conversations when a matching conversation exists
258
+
259
+ Pattern rules are the same as `ignoreSessionPatterns`, and matching is done against the full session key.
260
+
261
+ Environment variable example:
262
+
263
+ ```bash
264
+ LCM_STATELESS_SESSION_PATTERNS=agent:*:subagent:**,agent:ops:subagent:**
265
+ LCM_SKIP_STATELESS_SESSIONS=true
266
+ ```
267
+
268
+ Plugin config example:
269
+
270
+ ```json
271
+ {
272
+ "plugins": {
273
+ "entries": {
274
+ "lossless-claw": {
275
+ "config": {
276
+ "statelessSessionPatterns": [
277
+ "agent:*:subagent:**",
278
+ "agent:ops:subagent:**"
279
+ ],
280
+ "skipStatelessSessions": true
281
+ }
282
+ }
283
+ }
284
+ }
285
+ }
286
+ ```
287
+
141
288
  ### OpenClaw session reset settings
142
289
 
143
290
  LCM preserves history through compaction, but it does **not** change OpenClaw's core session reset policy. If sessions are resetting sooner than you want, increase OpenClaw's `session.reset.idleMinutes` or use a channel/type-specific override.
@@ -103,6 +103,75 @@ export LCM_SUMMARY_PROVIDER=anthropic
103
103
 
104
104
  Using a cheaper/faster model for summarization can reduce costs, but quality matters — poor summaries compound as they're condensed into higher-level nodes.
105
105
 
106
+ When more than one source is present, compaction summarization resolves in this order:
107
+
108
+ 1. `LCM_SUMMARY_MODEL` / `LCM_SUMMARY_PROVIDER`
109
+ 2. Plugin config `summaryModel` / `summaryProvider`
110
+ 3. OpenClaw's default compaction model/provider
111
+ 4. Legacy per-call model/provider hints
112
+
113
+ If `summaryModel` already includes a provider prefix such as `anthropic/claude-sonnet-4-20250514`, `summaryProvider` is ignored for that choice.
114
+
115
+ ## Session controls
116
+
117
+ ### Excluding sessions entirely
118
+
119
+ 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.
120
+
121
+ - Matching uses the full session key.
122
+ - `*` matches any characters except `:`.
123
+ - `**` matches anything, including `:`.
124
+
125
+ Example:
126
+
127
+ ```bash
128
+ export LCM_IGNORE_SESSION_PATTERNS=agent:*:cron:**,agent:main:subagent:**
129
+ ```
130
+
131
+ ### Stateless sessions
132
+
133
+ 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>`.
134
+
135
+ Enable enforcement with `skipStatelessSessions` or `LCM_SKIP_STATELESS_SESSIONS=true`.
136
+
137
+ When a session key matches a stateless pattern and enforcement is enabled, LCM will:
138
+
139
+ - skip bootstrap imports
140
+ - skip ingest and after-turn persistence
141
+ - skip compaction writes
142
+ - skip delegated expansion grant writes
143
+ - still allow read-side assembly from existing persisted context
144
+
145
+ Example:
146
+
147
+ ```bash
148
+ export LCM_STATELESS_SESSION_PATTERNS=agent:*:subagent:**,agent:ops:subagent:**
149
+ export LCM_SKIP_STATELESS_SESSIONS=true
150
+ ```
151
+
152
+ Plugin config example:
153
+
154
+ ```json
155
+ {
156
+ "plugins": {
157
+ "entries": {
158
+ "lossless-claw": {
159
+ "config": {
160
+ "ignoreSessionPatterns": [
161
+ "agent:*:cron:**"
162
+ ],
163
+ "statelessSessionPatterns": [
164
+ "agent:*:subagent:**",
165
+ "agent:ops:subagent:**"
166
+ ],
167
+ "skipStatelessSessions": true
168
+ }
169
+ }
170
+ }
171
+ }
172
+ }
173
+ ```
174
+
106
175
  ## TUI conversation window size
107
176
 
108
177
  `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`.