Skip to content

Commit 5e52a9b

Browse files
anagnorisis2peripeteiaobviyus
authored andcommitted
docs(cli-backends): document ownsNativeCompaction opt-out contract
1 parent 3d7523b commit 5e52a9b

3 files changed

Lines changed: 63 additions & 3 deletions

File tree

docs/gateway/cli-backends.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,35 @@ its own control markers and channel delivery.
372372
For CLIs that emit Claude Code stream-json compatible JSONL, set
373373
`jsonlDialect: "claude-stream-json"` on that backend's config.
374374

375+
## Native compaction ownership
376+
377+
Some CLI backends run an agent that compacts its **own** transcript, so OpenClaw must
378+
not run its safeguard summarizer against them - doing so fights the backend's own
379+
compaction and can hard-fail the turn. **Codex** (its app-server owns automatic
380+
compaction) and **Claude Code** (`claude-cli`) both work this way, and both **opt out
381+
of OpenClaw compaction**:
382+
383+
- **Codex** routes to its native-harness compaction endpoint (matched by the session's
384+
`agentHarnessId`).
385+
- **`claude-cli`** has no harness endpoint - Claude Code compacts internally - so it
386+
declares `ownsNativeCompaction: true`, and OpenClaw returns a no-op from the
387+
compaction path.
388+
389+
Either way OpenClaw **defers and never compacts these sessions.** Because the backend
390+
owns compaction, the old stopgap of setting `contextTokens: 1_000_000` purely to keep
391+
OpenClaw's safeguard from firing on a claude-cli session is **no longer needed** - the
392+
opt-out replaces it.
393+
394+
```typescript
395+
api.registerCliBackend({ id: "my-cli", ownsNativeCompaction: true /* ... */ });
396+
```
397+
398+
Only declare `ownsNativeCompaction` for a backend that genuinely owns its compaction: it
399+
must reliably bound its own transcript as it nears its context window and persist a
400+
resumable session (e.g. `--resume` / `--session-id`); otherwise a deferred session can
401+
stay over budget. (A session whose `agentHarnessId` matches the provider still routes to
402+
the harness endpoint - the no-op applies only when there is no harness endpoint.)
403+
375404
## Bundle MCP overlays
376405

377406
CLI backends do **not** receive OpenClaw tool calls directly, but a backend can

docs/plugins/cli-backend-plugins.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,10 +208,30 @@ only for behavior that really belongs to the backend.
208208
| `authEpochMode` | Decide how auth changes invalidate stored CLI sessions |
209209
| `nativeToolMode` | Declare whether the CLI has always-on native tools |
210210
| `bundleMcp` / `bundleMcpMode` | Opt into OpenClaw's loopback MCP tool bridge |
211+
| `ownsNativeCompaction` | Backend owns its own compaction - OpenClaw defers |
211212

212213
Keep these hooks provider-owned. Do not add CLI-specific branches to core when a
213214
backend hook can express the behavior.
214215

216+
### `ownsNativeCompaction`: opting out of OpenClaw compaction
217+
218+
If your backend runs an agent that compacts its **own** transcript, set
219+
`ownsNativeCompaction: true` so OpenClaw's safeguard summarizer never runs against its
220+
sessions - the CLI compaction lifecycle returns a no-op and the turn proceeds. This is
221+
the **same opt-out Codex uses** (its app-server owns automatic compaction); `claude-cli`
222+
declares it because Claude Code compacts internally with no harness endpoint. It also
223+
removes any need to inflate `contextTokens` just to keep the safeguard from firing.
224+
225+
**Only declare it when all of the following hold**, or a deferred over-budget session can
226+
stay over budget / go stale (OpenClaw no longer rescues it):
227+
228+
- the backend reliably compacts or bounds its own transcript as it nears its window;
229+
- it persists a resumable session so the compacted state survives turns
230+
(e.g. `--resume` / `--session-id`);
231+
- it is **not** a native-harness compaction session - a session whose `agentHarnessId`
232+
matches the provider routes to the harness endpoint instead; this no-op applies only
233+
when there is no harness endpoint.
234+
215235
## MCP tool bridge
216236

217237
CLI backends do not receive OpenClaw tools by default. If the CLI can consume an

src/plugins/cli-backend.types.ts

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -84,9 +84,20 @@ export type CliBackendPlugin = {
8484
contextEngineHostCapabilities?: readonly ContextEngineHostCapability[];
8585
/**
8686
* When true, the backend manages its own transcript compaction lifecycle
87-
* (e.g. Claude Code's internal auto-compaction). OpenClaw will skip its
88-
* safeguard summarizer and return a no-op from the compaction path instead
89-
* of fighting the backend's own compaction or hard-failing the turn.
87+
* (e.g. Claude Code's internal auto-compaction). OpenClaw skips its safeguard
88+
* summarizer and returns a no-op from the CLI compaction path instead of
89+
* fighting the backend's own compaction or hard-failing the turn.
90+
*
91+
* Safety contract - only declare this when ALL of the following hold, or an
92+
* over-budget session can stay over budget / go stale (OpenClaw no longer
93+
* rescues it):
94+
* - the backend reliably compacts or bounds its own transcript as it nears
95+
* its context window;
96+
* - it persists a resumable session so the compacted state survives across
97+
* turns (e.g. `--resume` / `--session-id`);
98+
* - it is NOT a native-harness compaction session - a session whose
99+
* `agentHarnessId` matches the provider still routes to the harness
100+
* endpoint, so this no-op applies only when there is no harness endpoint.
90101
*/
91102
ownsNativeCompaction?: boolean;
92103
/**

0 commit comments

Comments
 (0)