Skip to content

Commit db576c4

Browse files
committed
refactor(agents): trim native compaction ownership follow-up
1 parent 5e52a9b commit db576c4

5 files changed

Lines changed: 18 additions & 50 deletions

File tree

docs/gateway/cli-backends.md

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -376,20 +376,16 @@ For CLIs that emit Claude Code stream-json compatible JSONL, set
376376

377377
Some CLI backends run an agent that compacts its **own** transcript, so OpenClaw must
378378
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**:
379+
compaction and can hard-fail the turn.
382380

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.
381+
`claude-cli` has no harness endpoint - Claude Code compacts internally - so it declares
382+
`ownsNativeCompaction: true`, and OpenClaw returns a no-op from the compaction path.
383+
Native-harness sessions such as Codex keep routing to their harness compaction endpoint
384+
instead.
388385

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.
386+
Because the backend owns compaction, the old stopgap of setting
387+
`contextTokens: 1_000_000` purely to keep OpenClaw's safeguard from firing on a
388+
claude-cli session is **no longer needed** - the opt-out replaces it.
393389

394390
```typescript
395391
api.registerCliBackend({ id: "my-cli", ownsNativeCompaction: true /* ... */ });
@@ -398,8 +394,7 @@ api.registerCliBackend({ id: "my-cli", ownsNativeCompaction: true /* ... */ });
398394
Only declare `ownsNativeCompaction` for a backend that genuinely owns its compaction: it
399395
must reliably bound its own transcript as it nears its context window and persist a
400396
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.)
397+
stay over budget. Matching `agentHarnessId` sessions still route to the harness endpoint.
403398

404399
## Bundle MCP overlays
405400

docs/plugins/cli-backend-plugins.md

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -217,20 +217,18 @@ backend hook can express the behavior.
217217

218218
If your backend runs an agent that compacts its **own** transcript, set
219219
`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.
220+
sessions - the CLI compaction lifecycle returns a no-op and the turn proceeds. `claude-cli`
221+
declares it because Claude Code compacts internally with no harness endpoint. Native-harness
222+
sessions such as Codex keep routing to their harness compaction endpoint instead.
224223

225224
**Only declare it when all of the following hold**, or a deferred over-budget session can
226225
stay over budget / go stale (OpenClaw no longer rescues it):
227226

228227
- the backend reliably compacts or bounds its own transcript as it nears its window;
229228
- it persists a resumable session so the compacted state survives turns
230229
(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.
230+
- it is not a native-harness compaction session - matching `agentHarnessId` sessions
231+
route to the harness endpoint instead.
234232

235233
## MCP tool bridge
236234

src/agents/command/cli-compaction.test.ts

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -76,12 +76,6 @@ describe("runCliTurnCompactionLifecycle", () => {
7676

7777
beforeEach(async () => {
7878
tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-cli-compaction-"));
79-
// Default backends to non-owning so the context-engine compaction-path tests
80-
// exercise that path. On current main resolveCliBackendConfig("claude-cli")
81-
// resolves the (now ownsNativeCompaction) backend even in unit tests, which
82-
// would otherwise route every claude-cli compaction test through the #88315
83-
// defer no-op. The ownsNativeCompaction-specific tests override this with an
84-
// owning backend to exercise the defer.
8579
setCliCompactionTestDeps({ resolveCliBackendConfig: () => null });
8680
});
8781

src/agents/command/cli-compaction.ts

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
applyAgentAutoCompactionGuard as applyAgentAutoCompactionGuardImpl,
1414
resolveEffectiveCompactionMode,
1515
} from "../agent-settings.js";
16+
import { resolveCliBackendConfig as resolveCliBackendConfigImpl } from "../cli-backends.js";
1617
import { classifyCompactionReason } from "../embedded-agent-runner/compact-reasons.js";
1718
import { buildEmbeddedCompactionRuntimeContext } from "../embedded-agent-runner/compaction-runtime-context.js";
1819
import {
@@ -29,7 +30,6 @@ import { ensureSelectedAgentHarnessPlugin as ensureSelectedAgentHarnessPluginImp
2930
import { maybeCompactAgentHarnessSession as maybeCompactAgentHarnessSessionImpl } from "../harness/selection.js";
3031
import type { AgentMessage } from "../runtime/index.js";
3132
import { SessionManager } from "../sessions/session-manager.js";
32-
import { resolveCliBackendConfig as resolveCliBackendConfigImpl } from "../cli-backends.js";
3333
import {
3434
clearCliSessionInStore as clearCliSessionInStoreImpl,
3535
recordCliCompactionInStore as recordCliCompactionInStoreImpl,
@@ -529,18 +529,12 @@ export async function runCliTurnCompactionLifecycle(params: {
529529
return params.sessionEntry;
530530
}
531531

532-
// When the backend declares native compaction ownership but has no harness
533-
// compaction endpoint (e.g. claude-cli — Claude Code compacts its own
534-
// transcript internally), skip both native-harness and context-engine
535-
// compaction. The backend will handle it; OpenClaw returns a no-op.
536532
const resolvedBackend = cliCompactionDeps.resolveCliBackendConfig(params.provider, params.cfg);
537533
if (
538534
resolvedBackend?.ownsNativeCompaction &&
539535
!isNativeHarnessCompactionSession(params.sessionEntry, params.provider)
540536
) {
541-
log.info(
542-
`CLI backend "${params.provider}" owns native compaction — deferring to backend`,
543-
);
537+
log.info(`CLI backend "${params.provider}" owns native compaction — deferring to backend`);
544538
return params.sessionEntry;
545539
}
546540

src/plugins/cli-backend.types.ts

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -83,21 +83,8 @@ export type CliBackendPlugin = {
8383
*/
8484
contextEngineHostCapabilities?: readonly ContextEngineHostCapability[];
8585
/**
86-
* When true, the backend manages its own transcript compaction lifecycle
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.
86+
* Backend-owned compaction for non-harness CLI sessions.
87+
* Set only when the backend bounds its own transcript and persists resumable state.
10188
*/
10289
ownsNativeCompaction?: boolean;
10390
/**

0 commit comments

Comments
 (0)