openclaw - 💡(How to fix) Fix compaction.model config not passed through safeguard compaction path [1 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
openclaw/openclaw#43854Fetched 2026-04-08 00:18:36
View on GitHub
Comments
1
Participants
2
Timeline
1
Reactions
2
Author
Timeline (top)
commented ×1

Root Cause

In reply-DeXK9BLT.js line 38904, the safeguard compaction path calls:

session.compact(params.customInstructions)

The legacy context engine's compact() method (line 5252) then calls compactEmbeddedPiSessionDirect() with:

const runtimeContext = params.runtimeContext ?? {};
const result = await compactEmbeddedPiSessionDirect({
    ...runtimeContext,
    sessionId: params.sessionId,
    // ...
});

Since only customInstructions (a string) is passed, runtimeContext is {}, and params.config inside compactEmbeddedPiSessionDirect is undefined. This means compactionModelOverride at line 93302 is always undefined, and the function falls back to the session's own provider/model.

Code Example

session.compact(params.customInstructions)

---

const runtimeContext = params.runtimeContext ?? {};
const result = await compactEmbeddedPiSessionDirect({
    ...runtimeContext,
    sessionId: params.sessionId,
    // ...
});
RAW_BUFFERClick to expand / collapse

Bug

agents.defaults.compaction.model is set to anthropic/claude-sonnet-4-6 but compaction always uses the session's primary model instead.

Root cause

In reply-DeXK9BLT.js line 38904, the safeguard compaction path calls:

session.compact(params.customInstructions)

The legacy context engine's compact() method (line 5252) then calls compactEmbeddedPiSessionDirect() with:

const runtimeContext = params.runtimeContext ?? {};
const result = await compactEmbeddedPiSessionDirect({
    ...runtimeContext,
    sessionId: params.sessionId,
    // ...
});

Since only customInstructions (a string) is passed, runtimeContext is {}, and params.config inside compactEmbeddedPiSessionDirect is undefined. This means compactionModelOverride at line 93302 is always undefined, and the function falls back to the session's own provider/model.

Impact

  • Sessions using slow models (e.g., gpt-5.4 with thinking: high) cannot be compacted by a faster model
  • The 300s EMBEDDED_COMPACTION_TIMEOUT_MS is exceeded, compaction fails silently, and the session enters a repeat-response loop
  • Setting compaction.model in config has no effect

Expected behavior

compactEmbeddedPiSessionDirect should receive the full config so compaction.model is respected.

Environment

  • OpenClaw 2026.3.8
  • Primary model: openai-codex/gpt-5.4 with thinking: high
  • Compaction model (configured but not used): anthropic/claude-sonnet-4-6
  • Session repeatedly hits 160K tokens and enters a compaction timeout → repeat response loop

extent analysis

Fix Summary

Pass the full session config (including compaction.model) to the compaction routine so that compactEmbeddedPiSessionDirect can honour the override instead of falling back to the primary model.


Step‑by‑Step Fix Plan

1. Extend the session.compact API

Add an optional config argument that forwards the session’s runtime config.

// reply‑DeXK9BLT.js  (around line 38904)
async function compactSession(session, customInstructions) {
  // New: pull the full config from the session (or from agents.defaults)
  const compactionConfig = session.getConfig?.() ?? agents.defaults?.compaction ?? {};

  // Pass both the custom instructions *and* the config forward
  await session.compact(customInstructions, compactionConfig);
}

2. Update Session.prototype.compact

Modify the legacy context engine to accept the extra config param and forward it as runtimeContext.

// legacy context engine (around line 5252)
Session.prototype.compact = async function (customInstructions, config = {}) {
  // keep existing param shape for callers that don’t pass config
  const params = {
    customInstructions,
    sessionId: this.id,
    config,               // <-- new field
    // any other existing fields …
  };

  // Preserve original behaviour for backward‑compatibility
  const runtimeContext = { config };   // will be spread in the next call
  const result = await compactEmbeddedPiSessionDirect({
    ...runtimeContext,
    sessionId: params.sessionId,
    // …other args unchanged
  });
  return result;
};

3. Make compactEmbeddedPiSessionDirect read the override

Add a safe fallback that reads config.compaction.model (or the global default) when compactionModelOverride is missing.

// compactEmbeddedPiSessionDirect (around line 93302)
async function compactEmbeddedPiSessionDirect({ sessionId, config = {}, ...rest }) {
  // Existing logic …
  const compactionModelOverride =
        config?.compaction?.model ??
        agents.defaults?.compaction?.model;   // global fallback

  const modelToUse = compactionModelOverride ?? sessionPrimaryModel(sessionId);
  // use

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

FAQ

Expected behavior

compactEmbeddedPiSessionDirect should receive the full config so compaction.model is respected.

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING