
















@@ -1060,6 +1060,7 @@ export async function runCodexAppServerAttempt(
10601060let turnCompletionIdleTimer: ReturnType<typeof setTimeout> | undefined;
10611061let turnCompletionIdleWatchArmed = false;
10621062let turnCompletionIdleWatchPinnedByTerminalError = false;
1063+let turnCompletionIdleTimeoutOverrideMs: number | undefined;
10631064let turnAssistantCompletionIdleTimer: ReturnType<typeof setTimeout> | undefined;
10641065let turnAssistantCompletionIdleWatchArmed = false;
10651066let turnAssistantCompletionLastActivityAt = Date.now();
@@ -1195,8 +1196,9 @@ export async function runCodexAppServerAttempt(
11951196) {
11961197return;
11971198}
1199+const timeoutMs = turnCompletionIdleTimeoutOverrideMs ?? turnCompletionIdleTimeoutMs;
11981200const idleMs = Math.max(0, Date.now() - turnCompletionLastActivityAt);
1199-if (idleMs < turnCompletionIdleTimeoutMs) {
1201+if (idleMs < timeoutMs) {
12001202scheduleTurnCompletionIdleWatch();
12011203return;
12021204}
@@ -1209,15 +1211,15 @@ export async function runCodexAppServerAttempt(
12091211threadId: thread.threadId,
12101212 turnId,
12111213 idleMs,
1212-timeoutMs: turnCompletionIdleTimeoutMs,
1214+ timeoutMs,
12131215lastActivityReason: turnCompletionLastActivityReason,
12141216 ...turnCompletionLastActivityDetails,
12151217});
12161218embeddedAgentLog.warn("codex app-server turn idle timed out waiting for completion", {
12171219threadId: thread.threadId,
12181220 turnId,
12191221 idleMs,
1220-timeoutMs: turnCompletionIdleTimeoutMs,
1222+ timeoutMs,
12211223lastActivityReason: turnCompletionLastActivityReason,
12221224 ...turnCompletionLastActivityDetails,
12231225});
@@ -1273,7 +1275,8 @@ export async function runCodexAppServerAttempt(
12731275return;
12741276}
12751277const elapsedMs = Math.max(0, Date.now() - turnCompletionLastActivityAt);
1276-const delayMs = Math.max(1, turnCompletionIdleTimeoutMs - elapsedMs);
1278+const timeoutMs = turnCompletionIdleTimeoutOverrideMs ?? turnCompletionIdleTimeoutMs;
1279+const delayMs = Math.max(1, timeoutMs - elapsedMs);
12771280turnCompletionIdleTimer = setTimeout(fireTurnCompletionIdleTimeout, delayMs);
12781281turnCompletionIdleTimer.unref?.();
12791282}
@@ -1351,6 +1354,7 @@ export async function runCodexAppServerAttempt(
13511354turnCompletionLastActivityAt = Date.now();
13521355turnCompletionLastActivityReason = reason;
13531356turnCompletionLastActivityDetails = options?.details;
1357+turnCompletionIdleTimeoutOverrideMs = undefined;
13541358if (options?.attemptProgress) {
13551359turnAttemptLastProgressAt = turnCompletionLastActivityAt;
13561360turnAttemptLastProgressReason = reason;
@@ -1380,6 +1384,7 @@ export async function runCodexAppServerAttempt(
13801384const disarmTurnCompletionIdleWatch = () => {
13811385turnCompletionIdleWatchArmed = false;
13821386turnCompletionIdleWatchPinnedByTerminalError = false;
1387+turnCompletionIdleTimeoutOverrideMs = undefined;
13831388clearTurnCompletionIdleTimer();
13841389};
13851390@@ -1396,9 +1401,14 @@ export async function runCodexAppServerAttempt(
13961401scheduleTurnAssistantCompletionIdleWatch();
13971402};
139814031399-const armTurnCompletionIdleWatch = (options?: { pinnedByTerminalError?: boolean }) => {
1404+const armTurnCompletionIdleWatch = (options?: {
1405+pinnedByTerminalError?: boolean;
1406+timeoutMs?: number;
1407+}) => {
14001408turnCompletionIdleWatchArmed = true;
14011409turnCompletionIdleWatchPinnedByTerminalError = options?.pinnedByTerminalError === true;
1410+turnCompletionIdleTimeoutOverrideMs =
1411+options?.timeoutMs !== undefined ? Math.max(1, Math.floor(options.timeoutMs)) : undefined;
14021412scheduleTurnCompletionIdleWatch();
14031413};
14041414@@ -1520,6 +1530,11 @@ export async function runCodexAppServerAttempt(
15201530notification,
15211531turnCrossedToolHandoff,
15221532);
1533+const postToolRawAssistantCompletionNeedsTerminalGuard =
1534+isCurrentTurnNotification &&
1535+turnCrossedToolHandoff &&
1536+isRawAssistantCompletionNotification(notification) &&
1537+activeTurnItemIds.size === 0;
15231538const shouldRearmCompletionIdleWatchAfterLastCurrentTurnItem =
15241539isCurrentTurnNotification &&
15251540notification.method === "item/completed" &&
@@ -1537,6 +1552,8 @@ export async function runCodexAppServerAttempt(
15371552disarmTurnAssistantCompletionIdleWatch();
15381553} else if (isCurrentTurnNotification && assistantCompletionCanRelease) {
15391554armTurnAssistantCompletionIdleWatch(describeNotificationActivity(notification));
1555+} else if (postToolRawAssistantCompletionNeedsTerminalGuard) {
1556+armTurnCompletionIdleWatch({ timeoutMs: turnAssistantCompletionIdleTimeoutMs });
15401557} else if (unblockedAssistantCompletionRelease) {
15411558armTurnAssistantCompletionIdleWatch(describeNotificationActivity(notification));
15421559} else if (shouldRearmCompletionIdleWatchAfterLastCurrentTurnItem) {
@@ -1561,6 +1578,7 @@ export async function runCodexAppServerAttempt(
15611578isCurrentTurnNotification &&
15621579!trackedDynamicToolCompletion &&
15631580!rawToolOutputCompletion &&
1581+!postToolRawAssistantCompletionNeedsTerminalGuard &&
15641582!shouldRearmCompletionIdleWatchAfterLastCurrentTurnItem
15651583) {
15661584// The short completion-idle watchdog guards blind gaps after Codex
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。