fix: 延后 codex turn completion 事件 (#233)

This commit is contained in:
Lyon
2026-06-23 17:05:29 +08:00
committed by GitHub
parent 2d8376f274
commit 0d9c2dad43
3 changed files with 27 additions and 4 deletions
+7 -4
View File
@@ -457,6 +457,7 @@ async function runCodexStdioTurnWithSession(options: CodexStdioTurnOptions, sess
let assistantText = "";
const assistantDeltaProgress = createAssistantDeltaProgressState();
const completedAssistantMessages: CompletedAssistantMessage[] = [];
const deferredTerminalEvents: BackendEvent[] = [];
const suppressedNotifications = createSuppressedNotificationSummary();
let waitingFor = "codex-app-server";
let lastNotificationMethod: string | null = null;
@@ -672,6 +673,7 @@ async function runCodexStdioTurnWithSession(options: CodexStdioTurnOptions, sess
completedAssistantMessages.push(normalized.completedAssistantMessage);
emitEvent(assistantMessageEventForCompleted(normalized.completedAssistantMessage, completedAssistantMessages.length));
}
if (normalized.terminalEvents) deferredTerminalEvents.push(...normalized.terminalEvents);
if (normalized.terminal && !terminal) {
terminal = normalized.terminal;
terminalResolve();
@@ -798,6 +800,7 @@ async function runCodexStdioTurnWithSession(options: CodexStdioTurnOptions, sess
if (finalAssistant) emitEvent(assistantFinalResponseEvent(finalAssistant));
else if (completedAssistantMessages.length === 0) emitEvents(assistantMessageEventsForTurn(assistantText, false));
emitEvents(suppressedNotificationEvents(suppressedNotifications));
emitEvents(deferredTerminalEvents);
emitEvent({ type: "terminal_status", payload: { terminalStatus: terminal.status, failureKind: terminal.failureKind, message: terminal.message } });
await liveEventWrite;
return { terminalStatus: terminal.status, failureKind: terminal.failureKind, failureMessage: terminal.message, events: events.map((event) => ({ ...event, payload: redactJson(event.payload) })), ...(threadId ? { threadId } : {}), ...(turnId ? { turnId } : {}) };
@@ -943,7 +946,7 @@ function escapeRegExp(value: string): string {
return value.replace(/[.*+?^${}()|[\]\\]/gu, "\\$&");
}
function normalizeCodexNotification(message: JsonRecord, suppressed: SuppressedNotificationSummary): { events: BackendEvent[]; assistantDelta?: { itemId: string | null; text: string }; completedAssistantMessage?: CompletedAssistantMessage; threadId?: string; turnId?: string; terminal?: { status: TerminalStatus; failureKind: FailureKind | null; message: string | null } } {
function normalizeCodexNotification(message: JsonRecord, suppressed: SuppressedNotificationSummary): { events: BackendEvent[]; terminalEvents?: BackendEvent[]; assistantDelta?: { itemId: string | null; text: string }; completedAssistantMessage?: CompletedAssistantMessage; threadId?: string; turnId?: string; terminal?: { status: TerminalStatus; failureKind: FailureKind | null; message: string | null } } {
const method = typeof message.method === "string" ? message.method : "unknown";
const params = asRecordAt(message, "params");
if (method === "thread/started") {
@@ -999,9 +1002,9 @@ function normalizeCodexNotification(message: JsonRecord, suppressed: SuppressedN
const error = asRecordAt(turn, "error");
const messageText = typeof error.message === "string" ? redactText(error.message) : null;
const failureKind = status === "completed" ? null : status === "cancelled" ? "cancelled" : classifyCodexErrorRecord(Object.keys(error).length > 0 ? error : { message: turn.status }, "backend-failed");
const events: BackendEvent[] = [{ type: "backend_status", payload: { phase: method, terminalStatus: status } }];
if (failureKind) events.push({ type: "error", payload: { failureKind, error: redactJson(error), phase: method } });
return { events, terminal: { status, failureKind, message: messageText } };
const terminalEvents: BackendEvent[] = [{ type: "backend_status", payload: { phase: method, terminalStatus: status } }];
if (failureKind) terminalEvents.push({ type: "error", payload: { failureKind, error: redactJson(error), phase: method } });
return { events: [], terminalEvents, terminal: { status, failureKind, message: messageText } };
}
return { events: [{ type: "backend_status", payload: { phase: method } }] };
}