fix(codex): remove missing-terminal-after-tool authority (#244)

This commit is contained in:
Lyon
2026-06-24 18:10:52 +08:00
committed by GitHub
parent 3771c2b71a
commit 4a552f49d8
5 changed files with 15 additions and 85 deletions
-54
View File
@@ -471,7 +471,6 @@ async function runCodexStdioTurnWithSession(options: CodexStdioTurnOptions, sess
const turnStartedAt = Date.now();
let lastActivityAt = turnStartedAt;
let lastToolCall: JsonRecord | null = null;
let missingTerminalAfterToolReported = false;
let threadId: string | undefined = options.threadId;
let turnId: string | undefined;
let terminal: { status: TerminalStatus; failureKind: FailureKind | null; message: string | null } | null = null;
@@ -567,11 +566,9 @@ async function runCodexStdioTurnWithSession(options: CodexStdioTurnOptions, sess
const turnHardTimeoutMs = positiveTimeout(options.timeoutMs);
const turnIdleTimeoutMs = turnHardTimeoutMs;
const idleWarningMs = codexIdleWarningMs(env, turnIdleTimeoutMs);
const missingTerminalAfterToolTimeoutMs = codexMissingTerminalAfterToolTimeoutMs(env, turnIdleTimeoutMs);
let hardTimeout: NodeJS.Timeout | null = null;
let idleTimeout: NodeJS.Timeout | null = null;
let idleWarningTimeout: NodeJS.Timeout | null = null;
let missingTerminalAfterToolTimeout: NodeJS.Timeout | null = null;
let lastToolCallAt: number | null = null;
const turnHardTimeoutAttrs = (): JsonRecord => ({
waitingFor,
@@ -604,46 +601,6 @@ async function runCodexStdioTurnWithSession(options: CodexStdioTurnOptions, sess
hardTimeout = setTimeout(failTurnHardTimeout, turnHardTimeoutMs);
hardTimeout.unref?.();
};
const missingTerminalAfterToolAttrs = (): JsonRecord => ({
waitingFor,
idleMs: Math.max(0, Date.now() - lastActivityAt),
timeoutMs: missingTerminalAfterToolTimeoutMs,
lastNotificationMethod,
threadId: threadId ?? null,
turnId: turnId ?? null,
terminalStatus: terminal?.status ?? null,
retryable: false,
retryAttempt: null,
retryMaxAttempts: 0,
retryExhausted: true,
lastToolCall,
});
const reportMissingTerminalAfterTool = (): void => {
if (!lastToolCall || missingTerminalAfterToolReported) return;
missingTerminalAfterToolReported = true;
emitCodexOtelSpan("codex_stdio.missing_terminal_after_tool", options, env, missingTerminalAfterToolAttrs());
};
const clearMissingTerminalAfterToolTimeout = (): void => {
if (!missingTerminalAfterToolTimeout) return;
clearTimeout(missingTerminalAfterToolTimeout);
missingTerminalAfterToolTimeout = null;
};
const failMissingTerminalAfterTool = (): void => {
if (terminal || !lastToolCall) return;
reportMissingTerminalAfterTool();
terminal = { status: "failed", failureKind: "backend-timeout", message: `codex app-server did not emit turn/completed within ${missingTerminalAfterToolTimeoutMs}ms after tool activity` };
const attrs = { ...missingTerminalAfterToolAttrs(), terminalStatus: terminal.status, failureKind: terminal.failureKind };
emitEvent({ type: "error", payload: { failureKind: terminal.failureKind, message: terminal.message, phase: "turn:missing-terminal-after-tool-timeout", timeoutMs: missingTerminalAfterToolTimeoutMs, retryable: false, retryAttempt: null, retryMaxAttempts: 0, retryExhausted: true, lastToolCall } });
emitCodexOtelSpan("codex_stdio.missing_terminal_after_tool_timeout", options, env, attrs, { status: "error", error: terminal.message });
beginInterruptAndStop("missing terminal after tool timeout", "turn:missing-terminal-after-tool-timeout");
resolveTerminalNow();
};
const scheduleMissingTerminalAfterToolTimeout = (): void => {
if (!lastToolCall) return;
clearMissingTerminalAfterToolTimeout();
missingTerminalAfterToolTimeout = setTimeout(failMissingTerminalAfterTool, missingTerminalAfterToolTimeoutMs);
missingTerminalAfterToolTimeout.unref?.();
};
const scheduleIdleWarning = (): void => {
if (idleWarningTimeout) clearTimeout(idleWarningTimeout);
idleWarningTimeout = setTimeout(() => {
@@ -651,7 +608,6 @@ async function runCodexStdioTurnWithSession(options: CodexStdioTurnOptions, sess
const idleMs = Math.max(0, Date.now() - lastActivityAt);
const attrs = { waitingFor, idleMs, lastNotificationMethod, threadId: threadId ?? null, turnId: turnId ?? null, terminalStatus: null };
emitCodexOtelSpan("codex_stdio.idle_warning", options, env, attrs);
reportMissingTerminalAfterTool();
}, idleWarningMs);
idleWarningTimeout.unref?.();
};
@@ -678,7 +634,6 @@ async function runCodexStdioTurnWithSession(options: CodexStdioTurnOptions, sess
idleTimeout = null;
if (idleWarningTimeout) clearTimeout(idleWarningTimeout);
idleWarningTimeout = null;
clearMissingTerminalAfterToolTimeout();
};
scheduleTurnHardTimeout();
refreshTurnActivity();
@@ -694,8 +649,6 @@ async function runCodexStdioTurnWithSession(options: CodexStdioTurnOptions, sess
if (toolSummary?.status === "completed" || toolSummary?.status === "failed") {
lastToolCall = toolSummary;
lastToolCallAt = Date.now();
missingTerminalAfterToolReported = false;
scheduleMissingTerminalAfterToolTimeout();
}
exposeActiveTurn(normalized.turnId ? "turn-notification" : "notification");
emitEvents(normalized.events);
@@ -813,7 +766,6 @@ async function runCodexStdioTurnWithSession(options: CodexStdioTurnOptions, sess
}
}
if (!terminal) {
reportMissingTerminalAfterTool();
terminal = { status: "failed", failureKind: "backend-response-invalid", message: "codex app-server did not emit turn/completed" };
}
} catch (error) {
@@ -1542,12 +1494,6 @@ function codexIdleWarningMs(env: NodeJS.ProcessEnv, turnTimeoutMs: number): numb
return Math.max(250, Math.floor(turnTimeoutMs / 2));
}
function codexMissingTerminalAfterToolTimeoutMs(env: NodeJS.ProcessEnv, turnTimeoutMs: number): number {
const configured = Number(env.AGENTRUN_CODEX_MISSING_TERMINAL_AFTER_TOOL_TIMEOUT_MS);
if (Number.isFinite(configured) && configured > 0) return Math.max(250, Math.floor(configured));
return positiveTimeout(turnTimeoutMs);
}
function codexTerminalNotificationDrainMs(env: NodeJS.ProcessEnv): number {
const configured = Number(env.AGENTRUN_CODEX_TERMINAL_NOTIFICATION_DRAIN_MS);
if (Number.isFinite(configured) && configured >= 0) return Math.floor(configured);