fix: keep codex sessions reusable after turn failures

This commit is contained in:
Codex
2026-06-03 00:28:41 +08:00
parent c51180eef6
commit f69ef55ddc
5 changed files with 79 additions and 11 deletions
+20 -7
View File
@@ -428,14 +428,27 @@ async function runCodexStdioTurnWithSession(options: CodexStdioTurnOptions, sess
terminalResolve();
};
options.abortSignal?.addEventListener("abort", abortTurn, { once: true });
const timeout = setTimeout(() => {
const turnIdleTimeoutMs = positiveTimeout(options.timeoutMs);
let idleTimeout: NodeJS.Timeout | null = null;
const refreshTurnActivity = (): void => {
if (terminal) return;
terminal = { status: "failed", failureKind: "backend-timeout", message: `codex stdio turn timed out after ${options.timeoutMs}ms` };
emitEvent({ type: "error", payload: { failureKind: terminal.failureKind, message: terminal.message, phase: "turn:timeout" } });
client?.stop();
terminalResolve();
}, positiveTimeout(options.timeoutMs));
if (idleTimeout) clearTimeout(idleTimeout);
idleTimeout = setTimeout(() => {
if (terminal) return;
terminal = { status: "failed", failureKind: "backend-timeout", message: `codex stdio turn idle timed out after ${turnIdleTimeoutMs}ms without activity` };
emitEvent({ type: "error", payload: { failureKind: terminal.failureKind, message: terminal.message, phase: "turn:idle-timeout" } });
client?.stop();
terminalResolve();
}, turnIdleTimeoutMs);
};
const stopTurnIdleTimeout = (): void => {
if (!idleTimeout) return;
clearTimeout(idleTimeout);
idleTimeout = null;
};
refreshTurnActivity();
const stopNotifications = session.addNotificationHandler((message) => {
refreshTurnActivity();
const normalized = normalizeCodexNotification(message, suppressedNotifications);
if (normalized.threadId) threadId = normalized.threadId;
if (normalized.turnId) turnId = normalized.turnId;
@@ -516,7 +529,7 @@ async function runCodexStdioTurnWithSession(options: CodexStdioTurnOptions, sess
stopActiveTurn?.();
stopNotifications();
options.abortSignal?.removeEventListener("abort", abortTurn);
clearTimeout(timeout);
stopTurnIdleTimeout();
}
if (!terminal) terminal = { status: "failed", failureKind: "backend-response-invalid", message: "codex app-server finished without terminal status" };
if (terminal.status !== "completed") emitEvents(await session.close());