Skip to content

Commit 18f4a2d

Browse files
doedewaldtsallyom
authored andcommitted
fix: surface explicit error on LLM idle timeout to prevent ghost turns
1 parent 7863643 commit 18f4a2d

1 file changed

Lines changed: 7 additions & 15 deletions

File tree

  • src/agents/pi-embedded-runner

src/agents/pi-embedded-runner/run.ts

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2500,15 +2500,6 @@ export async function runEmbeddedPiAgent(
25002500
});
25012501
const timedOutDuringPrompt =
25022502
timedOut && !timedOutDuringCompaction && !timedOutDuringToolExecution;
2503-
const hasPartialAssistantTextAfterPromptTimeout =
2504-
timedOutDuringPrompt &&
2505-
(attempt.assistantTexts ?? []).some((text) => text.trim().length > 0) &&
2506-
!attempt.clientToolCalls &&
2507-
!attempt.yieldDetected &&
2508-
!attempt.didSendViaMessagingTool &&
2509-
!attempt.didSendDeterministicApprovalPrompt &&
2510-
!attempt.lastToolError &&
2511-
(attempt.toolMetas?.length ?? 0) === 0;
25122503
const attemptToolSummary = buildTraceToolSummary({
25132504
toolMetas: attempt.toolMetas,
25142505
hadFailure: Boolean(attempt.lastToolError),
@@ -2519,20 +2510,20 @@ export async function runEmbeddedPiAgent(
25192510
});
25202511

25212512
// Timeout aborts can leave the run without payloads or with only a
2522-
// partial assistant fragment. Emit an explicit timeout error instead.
2513+
// partial assistant fragment. Emit an explicit timeout error instead,
2514+
// preserving any tool payloads that succeeded before the timeout.
25232515
if (
2524-
timedOutDuringPrompt &&
2525-
!hasMessagingToolDeliveryEvidence(attempt) &&
2526-
(!payloadsWithToolMedia?.length || hasPartialAssistantTextAfterPromptTimeout)
2527-
) {
2516+
timedOutDuringPrompt &&
2517+
!hasMessagingToolDeliveryEvidence(attempt)
2518+
) {
25282519
const timeoutText = idleTimedOut
25292520
? "The model did not produce a response before the model idle timeout. " +
25302521
"Please try again, or increase `models.providers.<id>.timeoutSeconds` for slow local or self-hosted providers."
25312522
: "Request timed out before a response was generated. " +
25322523
"Please try again, or increase `agents.defaults.timeoutSeconds` in your config.";
25332524
const replayInvalid = resolveReplayInvalidForAttempt(null);
25342525
const livenessState = resolveRunLivenessState({
2535-
payloadCount: hasPartialAssistantTextAfterPromptTimeout ? 0 : payloads.length,
2526+
payloadCount: payloads.length,
25362527
aborted,
25372528
timedOut,
25382529
attempt,
@@ -2544,6 +2535,7 @@ export async function runEmbeddedPiAgent(
25442535
});
25452536
return {
25462537
payloads: [
2538+
...(payloadsWithToolMedia || []),
25472539
{
25482540
text: timeoutText,
25492541
isError: true,

0 commit comments

Comments
 (0)