From 7546bccaa347a3bbf61e96701eeba0f9922c8d68 Mon Sep 17 00:00:00 2001 From: oliviareid-svg Date: Sun, 29 Mar 2026 10:01:13 +0800 Subject: [PATCH] fix(compaction): resolve model override in runtime context for all context engines The compaction.model config override was only resolved inside compactEmbeddedPiSessionDirect (compact.ts), which is only reached by the legacy context engine. Custom context engines with their own compact() implementation never saw the override, causing overflow and timeout recovery to use the session's default model instead. Move the override resolution into buildEmbeddedCompactionRuntimeContext so the runtime context always carries the correct compaction model regardless of which context engine handles the compact() call. Fixes #56649 Co-Authored-By: Claude Opus 4.6 --- .../compaction-runtime-context.ts | 51 +++++++++++++++++-- 1 file changed, 48 insertions(+), 3 deletions(-) diff --git a/src/agents/pi-embedded-runner/compaction-runtime-context.ts b/src/agents/pi-embedded-runner/compaction-runtime-context.ts index 5f64089f63b..f854eb2c817 100644 --- a/src/agents/pi-embedded-runner/compaction-runtime-context.ts +++ b/src/agents/pi-embedded-runner/compaction-runtime-context.ts @@ -27,6 +27,45 @@ export type EmbeddedCompactionRuntimeContext = { ownerNumbers?: string[]; }; +/** + * Resolve the compaction model override from config, falling back to the + * caller-supplied provider/model. This ensures the runtime context always + * carries the correct compaction model regardless of which context engine + * handles the actual compact() call. + */ +function resolveCompactionModel(params: { + config?: OpenClawConfig; + provider?: string | null; + modelId?: string | null; + authProfileId?: string | null; +}): { provider: string | undefined; model: string | undefined; authProfileId: string | undefined } { + const override = params.config?.agents?.defaults?.compaction?.model?.trim(); + if (!override) { + return { + provider: params.provider ?? undefined, + model: params.modelId ?? undefined, + authProfileId: params.authProfileId ?? undefined, + }; + } + const slashIdx = override.indexOf("/"); + if (slashIdx > 0) { + const overrideProvider = override.slice(0, slashIdx).trim(); + const overrideModel = override.slice(slashIdx + 1).trim() || undefined; + // When switching provider via override, drop the primary auth profile to + // avoid sending the wrong credentials. + const authProfileId = + overrideProvider !== (params.provider ?? "")?.trim() + ? undefined + : (params.authProfileId ?? undefined); + return { provider: overrideProvider, model: overrideModel, authProfileId }; + } + return { + provider: params.provider ?? undefined, + model: override, + authProfileId: params.authProfileId ?? undefined, + }; +} + export function buildEmbeddedCompactionRuntimeContext(params: { sessionKey?: string | null; messageChannel?: string | null; @@ -50,6 +89,12 @@ export function buildEmbeddedCompactionRuntimeContext(params: { extraSystemPrompt?: string; ownerNumbers?: string[]; }): EmbeddedCompactionRuntimeContext { + const resolved = resolveCompactionModel({ + config: params.config, + provider: params.provider, + modelId: params.modelId, + authProfileId: params.authProfileId, + }); return { sessionKey: params.sessionKey ?? undefined, messageChannel: params.messageChannel ?? undefined, @@ -58,15 +103,15 @@ export function buildEmbeddedCompactionRuntimeContext(params: { currentChannelId: params.currentChannelId ?? undefined, currentThreadTs: params.currentThreadTs ?? undefined, currentMessageId: params.currentMessageId ?? undefined, - authProfileId: params.authProfileId ?? undefined, + authProfileId: resolved.authProfileId, workspaceDir: params.workspaceDir, agentDir: params.agentDir, config: params.config, skillsSnapshot: params.skillsSnapshot, senderIsOwner: params.senderIsOwner, senderId: params.senderId ?? undefined, - provider: params.provider ?? undefined, - model: params.modelId ?? undefined, + provider: resolved.provider, + model: resolved.model, thinkLevel: params.thinkLevel, reasoningLevel: params.reasoningLevel, bashElevated: params.bashElevated,