From 934a3ffcba35e074672732d38d46af0b2e3c92af Mon Sep 17 00:00:00 2001 From: John Hagler Date: Fri, 20 Mar 2026 13:38:23 -0400 Subject: [PATCH] Auto-reply: address bot review edge cases --- src/auto-reply/reply/agent-runner-memory.ts | 7 +++--- .../reply/agent-runner-utils.test.ts | 22 ++++++++++++++++++- src/auto-reply/reply/agent-runner-utils.ts | 8 +++++++ 3 files changed, 33 insertions(+), 4 deletions(-) diff --git a/src/auto-reply/reply/agent-runner-memory.ts b/src/auto-reply/reply/agent-runner-memory.ts index 47200b64340..819143e6262 100644 --- a/src/auto-reply/reply/agent-runner-memory.ts +++ b/src/auto-reply/reply/agent-runner-memory.ts @@ -282,13 +282,14 @@ export async function runMemoryFlushIfNeeded(params: { return sandboxCfg.workspaceAccess === "rw"; })(); - const isCli = isCliProvider(params.followupRun.run.provider, params.cfg); + const compactionFallbackOptions = resolveCompactionModelFallbackOptions(params.followupRun.run); + const isCli = isCliProvider(compactionFallbackOptions.provider, params.cfg); const canAttemptFlush = memoryFlushWritable && !params.isHeartbeat && !isCli; let entry = params.sessionEntry ?? (params.sessionKey ? params.sessionStore?.[params.sessionKey] : undefined); const contextWindowTokens = resolveMemoryFlushContextWindowTokens({ - modelId: params.followupRun.run.model ?? params.defaultModel, + modelId: compactionFallbackOptions.model ?? params.defaultModel, agentCfgContextTokens: params.agentCfgContextTokens, }); @@ -478,7 +479,7 @@ export async function runMemoryFlushIfNeeded(params: { .join("\n\n"); try { await runWithModelFallback({ - ...resolveCompactionModelFallbackOptions(params.followupRun.run), + ...compactionFallbackOptions, runId: flushRunId, run: async (provider, model, runOptions) => { const { embeddedContext, senderContext, runBaseParams } = buildEmbeddedRunExecutionParams({ diff --git a/src/auto-reply/reply/agent-runner-utils.test.ts b/src/auto-reply/reply/agent-runner-utils.test.ts index 60b1f8ec218..6cb343cd19a 100644 --- a/src/auto-reply/reply/agent-runner-utils.test.ts +++ b/src/auto-reply/reply/agent-runner-utils.test.ts @@ -98,10 +98,30 @@ describe("agent-runner-utils", () => { provider: "openrouter", model: "anthropic/claude-sonnet-4-5", agentDir: run.agentDir, - fallbacksOverride: ["fallback-model"], + fallbacksOverride: ["openrouter/fallback-model"], }); }); + it("rebases model-only fallbacks onto the compaction provider", () => { + const run = makeRun({ + sessionKey: "agent:agent-1:main", + config: { + agents: { + list: [{ id: "agent-1", model: { fallbacks: ["fallback-model", "anthropic/haiku"] } }], + defaults: { + compaction: { + model: "openrouter/anthropic/claude-sonnet-4-5", + }, + }, + }, + }, + }); + + const resolved = resolveCompactionModelFallbackOptions(run); + + expect(resolved.fallbacksOverride).toEqual(["openrouter/fallback-model", "anthropic/haiku"]); + }); + it("keeps the primary provider when compaction model override omits a provider", () => { const run = makeRun({ sessionKey: "agent:agent-1:main", diff --git a/src/auto-reply/reply/agent-runner-utils.ts b/src/auto-reply/reply/agent-runner-utils.ts index 4641ea5409a..612679a7b7a 100644 --- a/src/auto-reply/reply/agent-runner-utils.ts +++ b/src/auto-reply/reply/agent-runner-utils.ts @@ -180,10 +180,18 @@ export function resolveCompactionModelFallbackOptions(run: FollowupRun["run"]) { const provider = override.slice(0, slashIdx).trim(); const model = override.slice(slashIdx + 1).trim(); if (provider && model) { + const fallbacksOverride = resolved.fallbacksOverride?.map((fallback) => { + const trimmed = fallback.trim(); + if (!trimmed || trimmed.includes("/")) { + return trimmed; + } + return `${provider}/${trimmed}`; + }); return { ...resolved, provider, model, + fallbacksOverride, }; } }