diff --git a/local-agent/codex-app-server-runner.mjs b/local-agent/codex-app-server-runner.mjs index 3c26ffd..40038d8 100644 --- a/local-agent/codex-app-server-runner.mjs +++ b/local-agent/codex-app-server-runner.mjs @@ -3624,9 +3624,6 @@ export async function executeCodexAppServerTask(runnerConfig, task) { const activeTurnId = trimToDefined(turnResult?.turn?.id) || effectiveTurnRef; startActiveTurnInterruptPolling({ threadId, turnId: activeTurnId }); await turnCompleted; - if (progressEmits.length > 0) { - await Promise.allSettled(progressEmits); - } const normalizedReply = (replyBody || completedMessageText).trim(); if (interruptRequested) { diff --git a/tests/local-agent-codex-app-server-runner.test.mjs b/tests/local-agent-codex-app-server-runner.test.mjs index ea84b06..53d6400 100644 --- a/tests/local-agent-codex-app-server-runner.test.mjs +++ b/tests/local-agent-codex-app-server-runner.test.mjs @@ -631,6 +631,38 @@ test("codex app-server runner converts protocol progress events into Boss execut } }); +test("codex app-server runner does not wait for stale progress uploads after turn completion", async () => { + const fixture = await createCodexAppServerWebSocketFixture(); + try { + const runnerConfig = getCodexAppServerRunnerConfig(process.env, { + codexAppServerEnabled: true, + codexAppServerTransport: "ws", + codexAppServerUrl: fixture.url, + codexAppServerWorkdir: repoRoot, + codexAppServerTimeoutMs: 2000, + masterAgentModel: "gpt-5.4", + }); + runnerConfig.onProgress = () => new Promise(() => {}); + + const result = await Promise.race([ + executeCodexAppServerTask(runnerConfig, { + taskId: "task-app-server-stale-progress", + taskType: "conversation_reply", + targetCodexThreadRef: "019d-app-server-thread", + targetCodexFolderRef: repoRoot, + executionPrompt: "继续执行并快速完成", + }), + new Promise((resolve) => setTimeout(() => resolve({ status: "timeout" }), 300)), + ]); + + assert.notEqual(result.status, "timeout"); + assert.equal(result.status, "completed"); + assert.equal(result.replyBody, "WS_APP_SERVER_REPLY:继续执行并快速完成"); + } finally { + await fixture.close(); + } +}); + test("codex app-server runner maps guardian approval and file-change events without leaking secrets", async () => { const previous = process.env.BOSS_CODEX_APP_SERVER_FIXTURE_EMIT_GUARDIAN_EVENTS; process.env.BOSS_CODEX_APP_SERVER_FIXTURE_EMIT_GUARDIAN_EVENTS = "1";