Skip to content

feat(compaction): add modelFallbacks for compaction model resolution#52012

Closed
scottgl9 wants to merge 1 commit into
openclaw:mainfrom
scottgl9:feat/compaction-model-fallbacks
Closed

feat(compaction): add modelFallbacks for compaction model resolution#52012
scottgl9 wants to merge 1 commit into
openclaw:mainfrom
scottgl9:feat/compaction-model-fallbacks

Conversation

@scottgl9

Copy link
Copy Markdown
Contributor

Closes #52011

Summary

When the primary compaction model override is unreachable (e.g. a local vLLM server is down), compaction currently fails immediately. This adds a modelFallbacks array to AgentCompactionConfig that allows specifying fallback models tried in order before giving up.

Changes

  • src/config/types.agent-defaults.ts: Add modelFallbacks?: string[] to AgentCompactionConfig
  • src/agents/pi-embedded-runner/compact.ts: When primary resolveModelAsync fails, iterate through configured fallbacks. Auth profile is reset when fallback provider differs from primary.
  • docs/concepts/compaction.md: Document the new config option with examples

Config Example

{
  "agents": {
    "defaults": {
      "compaction": {
        "model": "vllm/qwen3-coder-next",
        "modelFallbacks": ["anthropic/claude-haiku-4-5"]
      }
    }
  }
}

Testing

  • When modelFallbacks is unset: no behavior change (backward compatible)
  • When primary model resolves: fallbacks are never tried
  • When primary model fails + fallbacks configured: tries each in order, uses first that resolves
  • When all fail: returns the original error (same as current behavior)

@openclaw-barnacle openclaw-barnacle Bot added docs Improvements or additions to documentation agents Agent runtime and tooling size: XS labels Mar 22, 2026
@greptile-apps

greptile-apps Bot commented Mar 22, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR adds modelFallbacks?: string[] to AgentCompactionConfig and updates compactEmbeddedPiSessionDirect to iterate through the fallback list when the primary compaction model fails to resolve — a useful resilience improvement for setups that use local/self-hosted compaction models. The type definition and documentation are clean additions with no issues.

There is one correctness bug in the fallback auth-profile logic worth addressing before merge:

  • Auth profile not restored on same-provider fallback (compact.ts lines 483–486): The check if (fbProvider !== params.provider) { authProfileId = undefined; } only clears the profile — it never restores it. When the primary compaction override uses a different provider (clearing authProfileId to undefined at lines 424–427) and a fallback then resolves to the original params.provider, authProfileId stays undefined. This causes getApiKeyForModel to skip the user's configured auth profile and silently fall back to unscoped key resolution, which may fail or pick up the wrong credentials.
  • Error message omits fallback attempts (P2): When all models fail the error message only reports the primary model, making debugging harder.

Confidence Score: 3/5

  • Safe to merge after fixing the auth-profile restoration bug in the fallback path; all other changes are clean.
  • The feature is well-structured and backward compatible, but the auth-profile reset logic in the fallback loop has a concrete correctness gap: when a fallback provider matches the original params.provider, the previously-cleared authProfileId is never restored to params.authProfileId. This can cause silent credential-resolution failures in a realistic config scenario (primary override on a different provider + fallback on the original provider). One targeted fix resolves the issue.
  • src/agents/pi-embedded-runner/compact.ts lines 483–486 — the auth-profile restoration condition in the fallback loop.
Prompt To Fix All With AI
This is a comment left during a code review.
Path: src/agents/pi-embedded-runner/compact.ts
Line: 483-486

Comment:
**Auth profile not restored when fallback matches original provider**

The condition only clears `authProfileId` when `fbProvider` differs from `params.provider`, but it never restores it when they match. This means if the primary compaction override uses a different provider (which already cleared `authProfileId` to `undefined` at lines 424–427), and a fallback then resolves to the original `params.provider`, `authProfileId` remains `undefined` even though `params.authProfileId` would be the correct credential to use for that provider.

This causes silent auth failures — `getApiKeyForModel` receives `profileId: undefined` and falls back to unscoped key resolution instead of the user's configured profile.

```suggestion
          if (fbProvider !== (params.provider ?? "").trim()) {
            authProfileId = undefined;
          } else {
            authProfileId = params.authProfileId;
          }
```

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: src/agents/pi-embedded-runner/compact.ts
Line: 495-497

Comment:
**Error message omits exhausted fallbacks**

When all fallbacks also fail, the error returned is either the primary model's `error` string or `Unknown model: {primaryProvider}/{primaryModelId}`. This gives the user no indication that fallback attempts were also made and failed, which can make debugging confusing.

Consider accumulating failure reasons and surfacing them in the final message, e.g.:

```ts
// After the fallback loop, if no model was resolved:
const triedModels = [`${provider}/${modelId}`, ...(fallbacks ?? [])].join(", ");
const reason = error ?? `All compaction models failed to resolve (tried: ${triedModels})`;
return fail(reason);
```

How can I resolve this? If you propose a fix, please make it concise.

Last reviewed commit: "feat(compaction): ad..."

Comment thread src/agents/pi-embedded-runner/compact.ts Outdated
Comment thread src/agents/pi-embedded-runner/compact.ts

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9a8f301e1b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/config/types.agent-defaults.ts Outdated
Comment thread src/agents/pi-embedded-runner/compact.ts Outdated
@scottgl9

Copy link
Copy Markdown
Contributor Author

Thanks for the review! Both issues addressed in 1d60b67:

  1. Auth profile restoration — Fixed. When a fallback provider matches the original params.provider, authProfileId is now restored to params.authProfileId instead of staying undefined. Added an else branch to the provider check.

  2. Error message includes fallback attempts — Fixed. When all models fail, the error now reports all tried models: All compaction models failed to resolve (tried: vllm/qwen3-coder-next, anthropic/claude-haiku-4-5).

Also fixed the TS type-check failure by avoiding mutable destructuring — now uses explicit final* variables instead of reassigning the result object.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 58b808df91

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/agents/pi-embedded-runner/compact.ts Outdated
Comment thread src/agents/pi-embedded-runner/compact.ts Outdated
@openclaw-barnacle openclaw-barnacle Bot added the gateway Gateway runtime label Mar 22, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b598c1be54

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/agents/pi-embedded-runner/compact.ts Outdated
@scottgl9
scottgl9 force-pushed the feat/compaction-model-fallbacks branch from fda22a0 to 5136655 Compare March 22, 2026 03:32

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 51366552dd

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/agents/pi-embedded-runner/compact.ts
@scottgl9
scottgl9 force-pushed the feat/compaction-model-fallbacks branch from 5136655 to 3c98c59 Compare March 22, 2026 03:46

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3c98c59b89

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/agents/pi-embedded-runner/compact.ts Outdated
@scottgl9
scottgl9 force-pushed the feat/compaction-model-fallbacks branch 2 times, most recently from 3a5c4c8 to a83b020 Compare March 24, 2026 15:42

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a83b0208cf

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/agents/pi-embedded-runner/compact.ts
@scottgl9

Copy link
Copy Markdown
Contributor Author

Conflicts resolved (merged main → branch) and all remaining review items addressed:

  • P2 — Retry fallbacks on auth resolution failure (PRRT_kwDOQb6kR852d8Gt): Fixed in 1075941. If getApiKeyForModel or prepareProviderRuntimeAuth throws for the primary model and modelFallbacks is configured, the code now iterates through fallbacks attempting both model resolution and auth for each. First fully-authenticated fallback wins; if all fail, the error surfaces all tried models. Backward compatible.

Branch: scottgl9:feat/compaction-model-fallbacks — all 10 review threads now resolved.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1075941a0a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/agents/pi-embedded-runner/compact.ts
Comment thread src/agents/pi-embedded-runner/compact.ts
@scottgl9
scottgl9 force-pushed the feat/compaction-model-fallbacks branch from 1f0584c to d86d217 Compare March 28, 2026 05:06

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d86d21796c

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/agents/pi-embedded-runner/compact.ts

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a9103aa59f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread extensions/synology-chat/src/webhook-handler.ts Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6ad4536006

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread extensions/synology-chat/src/webhook-handler.test.ts Outdated
@scottgl9
scottgl9 force-pushed the feat/compaction-model-fallbacks branch from 6ad4536 to f27c7d6 Compare April 4, 2026 00:10
@openclaw-barnacle openclaw-barnacle Bot removed docs Improvements or additions to documentation gateway Gateway runtime labels Apr 4, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 70c3c58141

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/agents/pi-embedded-runner/compact.ts Outdated
Comment thread src/agents/pi-embedded-runner/compact.ts
@scottgl9
scottgl9 force-pushed the feat/compaction-model-fallbacks branch from 70c3c58 to a7fe08d Compare April 15, 2026 01:12

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a7fe08d71a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/agents/pi-embedded-runner/compact.ts Outdated
@scottgl9
scottgl9 force-pushed the feat/compaction-model-fallbacks branch from a7fe08d to a452f00 Compare April 15, 2026 01:44

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a452f00176

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/config/zod-schema.agent-defaults.ts
Comment thread src/config/zod-schema.agent-defaults.ts
Comment thread src/config/zod-schema.agent-defaults.ts
@scottgl9
scottgl9 force-pushed the feat/compaction-model-fallbacks branch from a452f00 to c9793db Compare April 15, 2026 17:40

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c9793dba80

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines 880 to 884
const settingsManager = createPreparedEmbeddedPiSettingsManager({
cwd: effectiveWorkspace,
agentDir,
cfg: params.config,
contextTokenBudget: ctxInfo.tokens,
});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Pass context token budget into prepared settings

This call no longer provides contextTokenBudget, so createPreparedEmbeddedPiSettingsManager cannot cap compaction reserve settings to the active model window. In src/agents/pi-settings.ts, the small-context safety cap only runs when contextTokenBudget is present; without it, the default 20k reserve floor can exceed 16k-class models and drive repeated overflow/compaction behavior instead of stable compaction.

Useful? React with 👍 / 👎.

Comment on lines 625 to 629
cfg: params.config,
provider,
modelId,
modelContextTokens: readPiModelContextTokens(runtimeModel),
modelContextWindow: runtimeModelWithContext.contextWindow,
modelContextWindow: runtimeModel.contextWindow,
defaultTokens: DEFAULT_CONTEXT_TOKENS,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Include modelContextTokens in ctx window resolution

This compaction path now computes ctxInfo from runtimeModel.contextWindow only, so models that publish limits via contextTokens are ignored here and can fall back to DEFAULT_CONTEXT_TOKENS. That can inflate the token budget used for compaction and lead to oversized prompts or avoidable overflow failures; the inconsistency is visible because the queued compaction path still reads contextTokens explicitly.

Useful? React with 👍 / 👎.

@scottgl9
scottgl9 force-pushed the feat/compaction-model-fallbacks branch from c9793db to e134d3e Compare April 16, 2026 02:17

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e134d3e06a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +1120 to +1124
!compactFallbacks ||
!Array.isArray(compactFallbacks) ||
compactFallbacks.length === 0
) {
throw compactErr;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Restore think-level retry before failing compaction

This branch now throws immediately when modelFallbacks is unset, but the previous flow retried once with pickFallbackThinkingLevel (typically off -> minimal) for reasoning-required providers. In environments that rely on that compatibility retry and do not configure modelFallbacks, compaction now fails outright on provider rejections that would previously recover on the second attempt.

Useful? React with 👍 / 👎.

Comment on lines +1214 to +1218
await runPostCompactionSideEffects({
config: params.config,
sessionKey: params.sessionKey,
sessionFile: params.sessionFile,
});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Persist checkpoints after direct compaction succeeds

After a successful compact, this path now proceeds directly to side effects/metrics without persisting a compaction checkpoint snapshot. I checked src/agents/pi-embedded-runner/compact.queued.ts: checkpoint persistence there is gated behind contextEngine.info.ownsCompaction === true, while the default legacy engine delegates into compactEmbeddedPiSessionDirect, so standard compaction flows lose fresh checkpoints for sessions.compaction.list/restore.

Useful? React with 👍 / 👎.

Comment on lines 769 to 772
sessionId: params.sessionId,
agentId: sessionAgentId,
senderId: params.senderId,
senderIsOwner: params.senderIsOwner,
}),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Pass senderIsOwner into action discovery context

This discovery call no longer forwards senderIsOwner, so compaction prompt action discovery runs without ownership context even when the caller is an owner. That can suppress owner-scoped channel actions/capabilities during compaction and make tool guidance differ from normal run-time action discovery for the same session.

Useful? React with 👍 / 👎.

@scottgl9
scottgl9 force-pushed the feat/compaction-model-fallbacks branch from e134d3e to cef8926 Compare April 17, 2026 13:39

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: cef8926457

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +1221 to +1224
const tokensAfter = estimateTokensAfterCompaction({
messagesAfter: session.messages,
observedTokenCount,
fullSessionTokensBefore,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Compute post-compaction metrics from fallback session state

When session.compact(...) fails and fallback compaction succeeds, the code runs compaction on a separate fbSession (tryCompactWithModel) but then computes tokensAfter from session.messages here. Because the primary session never runs the successful fallback compact(), this can report pre-compaction token counts and propagate stale values to hooks/callers, which can in turn trigger incorrect follow-up compaction decisions.

Useful? React with 👍 / 👎.

Comment on lines +849 to 850
const systemPromptOverride = createSystemPromptOverride(appendPrompt);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Honor configured prompt overrides in compaction prompt build

This now hardwires the compaction prompt to buildEmbeddedSystemPrompt(...) and wraps it directly, but the prior flow applied resolveSystemPromptOverride(...) (and provider prompt transforms) before setting the session override. In setups that rely on agent-level systemPromptOverride or provider prompt hooks, compaction requests will diverge from normal runtime prompts and can regress provider-specific behavior.

Useful? React with 👍 / 👎.

Adds modelFallbacks?: string[] to AgentCompactionConfig. When the
primary compaction model fails (resolution, auth, or runtime), each
fallback is tried in order before giving up.

Changes:
- types.agent-defaults.ts: add modelFallbacks?: string[]
- zod-schema.agent-defaults.ts: add modelFallbacks schema
- compact.ts:
  - Model resolution fallback loop (primary model not in registry)
  - Auth fallback loop with tryAuthForModel returning hasExchange
  - Runtime fallback loop: on session.compact() throw, retry with full
    re-resolve + re-auth + createAgentSession per fallback
  - fbEffectiveModel now passes through applyLocalNoAuthHeaderOverride
    and applyAuthHeaderOverride using fbKeyInfo/fbHasExchange (P1 fix)
  - tryCompactWithModel disposes fbSession in finally block (P2 fix)
  - All error messages surface tried models list
  - Backward compatible when modelFallbacks is unset
@scottgl9
scottgl9 force-pushed the feat/compaction-model-fallbacks branch from cef8926 to 1c6b2f9 Compare April 19, 2026 22:05

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1c6b2f91d6

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +958 to 960
if (providerStreamFn) {
session.agent.streamFn = providerStreamFn;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Wrap provider stream before assigning compaction session streamFn

This direct assignment bypasses the compaction stream preparation stack that previously went through resolveEmbeddedAgentStreamFn and extra-param/provider wrappers. In provider-owned transport paths, that wrapper layer is what injects resolved runtime credentials (including exchanged keys from prepareProviderRuntimeAuth) and applies transport/extra-param behavior; without it, compaction can still fail authentication or ignore provider/runtime stream settings even after model auth succeeded.

Useful? React with 👍 / 👎.

Comment on lines +852 to +854
heartbeatPrompt: isDefaultAgent
? resolveHeartbeatPrompt(params.config?.agents?.defaults?.heartbeat?.prompt)
: undefined,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Respect heartbeat policy when setting compaction heartbeat prompt

Using resolveHeartbeatPrompt(...) here unconditionally injects a heartbeat prompt for the default agent, even when heartbeat guidance should be suppressed by policy (for example includeSystemPromptSection: false or disabled cadence). This regresses prompt parity with the existing heartbeat-system-prompt policy path and can cause /compact prompts to include unintended HEARTBEAT instructions.

Useful? React with 👍 / 👎.

@clawsweeper

clawsweeper Bot commented Apr 28, 2026

Copy link
Copy Markdown
Contributor

Thanks for the context here. I swept through the related work, and this is now duplicate or superseded.

Close as superseded: the remaining compaction/summary fallback API work is already tracked by the broader canonical issue, while this branch is conflicting, lacks real behavior proof, and would regress current-main compaction auth/session paths if merged as-is.

Canonical path: Keep the API/product decision in #56781, then land a narrow current-main implementation that preserves existing auth, stream-wrapper, checkpoint, and session-metrics behavior.

So I’m closing this here and keeping the remaining discussion on #56781.

Review details

Best possible solution:

Keep the API/product decision in #56781, then land a narrow current-main implementation that preserves existing auth, stream-wrapper, checkpoint, and session-metrics behavior.

Do we have a high-confidence way to reproduce the issue?

Yes for the current capability gap and PR regressions by source inspection: explicit agents.defaults.compaction.model remains exact on main, while the PR head diverges from current auth, stream, checkpoint, and session-state paths. I did not run a live provider outage in this read-only review.

Is this the best way to solve the issue?

No. The requested fallback behavior is reasonable, but this stale branch is not the best path because the public API is now canonicalized in a broader issue and the implementation regresses current-main compaction invariants.

Security review:

Security review needs attention: The diff has no dependency or workflow supply-chain change, but it introduces concrete auth-routing regressions in compaction credential and stream resolution.

  • [medium] Workspace-scoped compaction credentials can be bypassed — src/agents/pi-embedded-runner/compact.ts:431
    PR head calls getApiKeyForModel without workspaceDir, unlike current main, so workspace-specific auth profiles or secret resolution may be skipped during fallback compaction.
    Confidence: 0.88
  • [medium] Runtime auth stream wrapper is bypassed — src/agents/pi-embedded-runner/compact.ts:1102
    The fallback path assigns fbSession.agent.streamFn directly from the provider stream instead of the current compaction stream wrapper, so exchanged runtime credentials or provider transport shaping may not be applied.
    Confidence: 0.84

What I checked:

  • Canonical related issue remains open: The broader fallback contract for explicit compaction models and Lossless/LCM summary models is tracked in Feature request: fallback model chain for compaction and LCM summaryModel #56781, whose current ClawSweeper review says the public API shape still needs maintainer product/API review and overlaps this PR.
  • Current main intentionally keeps explicit compaction model exact: Current docs say implicit session fallback can run only when agents.defaults.compaction.model is unset; an explicit compaction model remains exact and does not inherit the session fallback chain, so this PR’s remaining product work is not implemented on main. Public docs: docs/concepts/compaction.md. (docs/concepts/compaction.md:93, b79effefee92)
  • Current source bypasses fallback when explicit compaction model is set: compactEmbeddedPiSessionDirect returns the one-shot path when hasExplicitCompactionModel(params) is true; the existing fallback wrapper only applies when there is no explicit compaction override. (src/agents/pi-embedded-runner/compact.ts:418, b79effefee92)
  • Current tests preserve no-fallback explicit-model behavior: The test named preserves explicit compaction.model behavior without session fallback asserts one model resolution and a failed result even when session model fallbacks are configured. (src/agents/pi-embedded-runner/compact.hooks.test.ts:510, b79effefee92)
  • PR is conflicting and stale against main: Live PR metadata reports mergeable: CONFLICTING for head 1c6b2f91d6089e2ba91cb7bc9fc2d7ac5ca5e34d; its latest non-bot code update predates multiple compaction/runtime changes on main. (1c6b2f91d608)
  • PR drops workspace-scoped auth lookup: PR head calls getApiKeyForModel in tryAuthForModel without the current-main workspaceDir argument, which can break workspace-scoped credentials during primary or fallback compaction auth. (src/agents/pi-embedded-runner/compact.ts:431, 1c6b2f91d608)

Likely related people:

  • jalehman: Authored the merged implicit compaction model fallback work and appears as reviewer/co-author on adjacent compaction runtime-context history, making this the closest current-main ownership trail for fallback semantics. (role: recent compaction fallback contributor and reviewer; confidence: high; commits: c09884614864, bf0f33db32c5; files: src/agents/pi-embedded-runner/compact.ts, src/agents/pi-embedded-runner/compaction-runtime-context.ts, docs/concepts/compaction.md)
  • steipete: Recent history shows model fallback preservation and config schema sharing work adjacent to any public fallback contract decision. (role: shared model fallback and config area contributor; confidence: medium; commits: f4ba9553c029, e96428b008a9; files: src/agents/model-fallback.ts, src/agents/model-fallback.test.ts, src/config/types.agent-defaults.ts)
  • oliviareid-svg: Authored the compaction model override runtime-context change that feeds the current single-target explicit compaction model behavior. (role: adjacent compaction runtime-context contributor; confidence: medium; commits: bf0f33db32c5; files: src/agents/pi-embedded-runner/compaction-runtime-context.ts, src/agents/pi-embedded-runner/compact.ts)
  • Daev Mithran: Introduced the plugin SDK LLM completion API that the broader canonical summary-model fallback issue may need to extend. (role: plugin LLM runtime introducer; confidence: medium; commits: 9e1e59717ffd; files: src/plugins/runtime/runtime-llm.runtime.ts, src/plugins/runtime/types-core.ts, src/plugin-sdk/index.ts)

Codex review notes: model gpt-5.5, reasoning high; reviewed against b79effefee92.

@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. P2 Normal backlog priority with limited blast radius. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. merge-risk: 🚨 session-state 🚨 May lose, corrupt, stale, or mis-associate session, agent, or context state. merge-risk: 🚨 auth-provider 🚨 May break OAuth, tokens, provider routing, model choice, or credentials. labels May 19, 2026
@openclaw-barnacle openclaw-barnacle Bot added the triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup. label May 19, 2026
@clawsweeper

clawsweeper Bot commented May 20, 2026

Copy link
Copy Markdown
Contributor

ClawSweeper PR egg

🎁 Pass real behavior proof to wake the egg and unlock a hatchable treat.

Where did the egg go?
  • The egg game starts only after the PR passes the real-behavior proof check.
  • Before that, no creature or rarity is rolled. The treat waits for real proof.
  • This is still just collectible flavor: proof affects review readiness, not creature quality.

@clawsweeper

clawsweeper Bot commented May 21, 2026

Copy link
Copy Markdown
Contributor

ClawSweeper applied the proposed close for this PR.

@clawsweeper clawsweeper Bot closed this May 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent runtime and tooling merge-risk: 🚨 auth-provider 🚨 May break OAuth, tokens, provider routing, model choice, or credentials. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. merge-risk: 🚨 session-state 🚨 May lose, corrupt, stale, or mis-associate session, agent, or context state. P2 Normal backlog priority with limited blast radius. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. size: XL status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: compaction model fallbacks when primary model is unreachable

1 participant