From b3ef14dbfc0ee1265b7dd454b4ee931b67e3e145 Mon Sep 17 00:00:00 2001 From: Jim Dawdy Date: Sun, 10 May 2026 18:26:38 -0500 Subject: [PATCH] fix: address code review findings - failover-policy.test.ts: move 4 new it() blocks inside describe() (they were orphaned outside the block and would not execute) - run.ts: add idleTimedOut to the assistantFailoverDecision call site (missing required field caused TypeScript error and reproduced the freeze for the initial-decision code path in the outer loop) - assistant-failover.ts: treat idleTimedOut same as timedOut in markFailedProfile to avoid incorrect profile failure recording - assistant-failover.ts: add warn log when idle timeout rotates a profile - assistant-failover.ts: extend resolveAssistantFailoverErrorMessage to accept idleTimedOut so surface_error emits "LLM request timed out." instead of the generic "LLM request failed." --- src/agents/pi-embedded-runner/run.ts | 1 + src/agents/pi-embedded-runner/run/assistant-failover.ts | 9 +++++++-- .../pi-embedded-runner/run/failover-policy.test.ts | 3 ++- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/agents/pi-embedded-runner/run.ts b/src/agents/pi-embedded-runner/run.ts index b62a689d5913..82cceb135d78 100644 --- a/src/agents/pi-embedded-runner/run.ts +++ b/src/agents/pi-embedded-runner/run.ts @@ -2355,6 +2355,7 @@ export async function runEmbeddedPiAgent( failoverFailure, failoverReason: assistantFailoverReason, timedOut, + idleTimedOut, timedOutDuringCompaction, timedOutDuringToolExecution, profileRotated: false, diff --git a/src/agents/pi-embedded-runner/run/assistant-failover.ts b/src/agents/pi-embedded-runner/run/assistant-failover.ts index 1dd0bf171219..0e31f5e78b5f 100644 --- a/src/agents/pi-embedded-runner/run/assistant-failover.ts +++ b/src/agents/pi-embedded-runner/run/assistant-failover.ts @@ -98,7 +98,8 @@ export async function handleAssistantFailover(params: { if (decision.action === "rotate_profile") { const failedProfileId = params.lastProfileId; - const failureReason = params.timedOut ? "timeout" : params.assistantProfileFailureReason; + const failureReason = + params.timedOut || params.idleTimedOut ? "timeout" : params.assistantProfileFailureReason; const markFailedProfile = async () => { if (!failedProfileId || !failureReason || failureReason === "timeout") { return; @@ -157,6 +158,9 @@ export async function handleAssistantFailover(params: { if (params.timedOut && !params.isProbeSession && failedProfileId) { params.warn(`Profile ${failedProfileId} timed out. Trying next account...`); } + if (params.idleTimedOut && !params.isProbeSession && failedProfileId) { + params.warn(`Profile ${failedProfileId} idle timeout (model silent). Trying next account...`); + } if (params.cloudCodeAssistFormatError && failedProfileId) { params.warn( `Profile ${failedProfileId} hit Cloud Code Assist format error. Tool calls will be sanitized on retry.`, @@ -280,6 +284,7 @@ function resolveAssistantFailoverErrorMessage(params: { sessionKey?: string; activeErrorContext: { provider: string; model: string }; timedOut: boolean; + idleTimedOut: boolean; rateLimitFailure: boolean; billingFailure: boolean; authFailure: boolean; @@ -294,7 +299,7 @@ function resolveAssistantFailoverErrorMessage(params: { }) : undefined) || params.lastAssistant?.errorMessage?.trim() || - (params.timedOut + (params.timedOut || params.idleTimedOut ? "LLM request timed out." : params.rateLimitFailure ? "LLM request rate limited." diff --git a/src/agents/pi-embedded-runner/run/failover-policy.test.ts b/src/agents/pi-embedded-runner/run/failover-policy.test.ts index ec8790ed0289..370cbd663751 100644 --- a/src/agents/pi-embedded-runner/run/failover-policy.test.ts +++ b/src/agents/pi-embedded-runner/run/failover-policy.test.ts @@ -127,6 +127,7 @@ describe("resolveRunFailoverDecision", () => { failoverFailure: true, failoverReason: "format", timedOut: false, + idleTimedOut: false, timedOutDuringCompaction: false, timedOutDuringToolExecution: false, profileRotated: false, @@ -148,6 +149,7 @@ describe("resolveRunFailoverDecision", () => { failoverFailure: true, failoverReason: "format", timedOut: false, + idleTimedOut: false, timedOutDuringCompaction: false, timedOutDuringToolExecution: false, profileRotated: false, @@ -297,7 +299,6 @@ describe("resolveRunFailoverDecision", () => { reason: null, }); }); -}); it("rotates profile on LLM idle timeout before falling back", () => { // idleTimedOut = model produced no tokens; no provider API error was classified.