fix: 等待 codex terminal 后续消息 (#234)

This commit is contained in:
Lyon
2026-06-23 17:15:50 +08:00
committed by GitHub
parent 0d9c2dad43
commit b15c860b35
2 changed files with 26 additions and 4 deletions
+21 -1
View File
@@ -470,6 +470,20 @@ async function runCodexStdioTurnWithSession(options: CodexStdioTurnOptions, sess
let terminal: { status: TerminalStatus; failureKind: FailureKind | null; message: string | null } | null = null; let terminal: { status: TerminalStatus; failureKind: FailureKind | null; message: string | null } | null = null;
let terminalResolve!: () => void; let terminalResolve!: () => void;
const terminalPromise = new Promise<void>((resolve) => { terminalResolve = resolve; }); const terminalPromise = new Promise<void>((resolve) => { terminalResolve = resolve; });
const terminalNotificationDrainMs = codexTerminalNotificationDrainMs(env);
let terminalNotificationDrainTimeout: NodeJS.Timeout | null = null;
const resolveTerminalAfterNotificationDrain = (): void => {
if (terminalNotificationDrainTimeout) clearTimeout(terminalNotificationDrainTimeout);
if (terminalNotificationDrainMs <= 0) {
terminalResolve();
return;
}
terminalNotificationDrainTimeout = setTimeout(() => {
terminalNotificationDrainTimeout = null;
terminalResolve();
}, terminalNotificationDrainMs);
terminalNotificationDrainTimeout.unref?.();
};
let client: CodexStdioClient | null = null; let client: CodexStdioClient | null = null;
const requestTimeoutMs = Math.min(positiveTimeout(options.timeoutMs), requestTimeoutCapMs); const requestTimeoutMs = Math.min(positiveTimeout(options.timeoutMs), requestTimeoutCapMs);
let stopActiveTurn: (() => void) | undefined; let stopActiveTurn: (() => void) | undefined;
@@ -676,7 +690,7 @@ async function runCodexStdioTurnWithSession(options: CodexStdioTurnOptions, sess
if (normalized.terminalEvents) deferredTerminalEvents.push(...normalized.terminalEvents); if (normalized.terminalEvents) deferredTerminalEvents.push(...normalized.terminalEvents);
if (normalized.terminal && !terminal) { if (normalized.terminal && !terminal) {
terminal = normalized.terminal; terminal = normalized.terminal;
terminalResolve(); resolveTerminalAfterNotificationDrain();
} }
}); });
try { try {
@@ -1487,6 +1501,12 @@ function codexMissingTerminalAfterToolTimeoutMs(env: NodeJS.ProcessEnv, turnTime
return positiveTimeout(turnTimeoutMs); 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);
return 250;
}
function emitCodexNotificationOtel(options: CodexStdioTurnOptions, env: NodeJS.ProcessEnv, message: JsonRecord, state: JsonRecord): void { function emitCodexNotificationOtel(options: CodexStdioTurnOptions, env: NodeJS.ProcessEnv, message: JsonRecord, state: JsonRecord): void {
const attributes = { ...state, ...notificationOtelAttributes(message) }; const attributes = { ...state, ...notificationOtelAttributes(message) };
emitCodexOtelSpan("codex_stdio.notification", options, env, attributes); emitCodexOtelSpan("codex_stdio.notification", options, env, attributes);
+5 -3
View File
@@ -226,12 +226,14 @@ for await (const line of rl) {
if (mode === "multi-agent-message-terminal-before-final") { if (mode === "multi-agent-message-terminal-before-final") {
turnCounter += 1; turnCounter += 1;
const turn = { id: `turn_selftest_${turnCounter}`, status: "completed" }; const turn = { id: `turn_selftest_${turnCounter}`, status: "completed" };
respond(message.id, { turn });
notify("turn/started", { turn }); notify("turn/started", { turn });
notify("item/agentMessage/delta", { itemId: "msg_late_progress", delta: "Progress before delayed final. " }); notify("item/agentMessage/delta", { itemId: "msg_late_progress", delta: "Progress before delayed final. " });
notify("turn/completed", { turn }); notify("turn/completed", { turn });
notify("item/completed", { item: { id: "msg_late_progress", type: "agentMessage", text: "Progress before delayed final." } }); setTimeout(() => {
notify("item/completed", { item: { id: "msg_late_final", type: "agentMessage", text: "Delayed final answer." } }); notify("item/completed", { item: { id: "msg_late_progress", type: "agentMessage", text: "Progress before delayed final." } });
respond(message.id, { turn }); notify("item/completed", { item: { id: "msg_late_final", type: "agentMessage", text: "Delayed final answer." } });
}, 20).unref?.();
continue; continue;
} }
if (mode === "web-search-progress") { if (mode === "web-search-progress") {