import test from "node:test"; import assert from "node:assert/strict"; import path from "node:path"; import { fileURLToPath } from "node:url"; import { executeCodexAppServerTask, getCodexAppServerRunnerConfig, shouldUseCodexAppServerTaskRunner, } from "../local-agent/codex-app-server-runner.mjs"; const repoRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), ".."); test("codex app-server runner resumes a thread and collects streamed agent text", async () => { const runnerConfig = getCodexAppServerRunnerConfig(process.env, { codexAppServerEnabled: true, codexAppServerCommand: process.execPath, codexAppServerArgs: ["tests/fixtures/codex-app-server-runtime.mjs"], codexAppServerWorkdir: repoRoot, codexAppServerTimeoutMs: 5000, masterAgentModel: "gpt-5.4", }); const task = { taskId: "task-app-server-1", taskType: "conversation_reply", targetCodexThreadRef: "019d-app-server-thread", targetCodexFolderRef: repoRoot, executionPrompt: "继续开发并给出结果", }; assert.equal(shouldUseCodexAppServerTaskRunner(runnerConfig, task), true); const result = await executeCodexAppServerTask(runnerConfig, task); assert.equal(result.status, "completed"); assert.equal(result.threadId, "019d-app-server-thread"); assert.equal(result.cwd, repoRoot); assert.equal(result.replyBody, "APP_SERVER_REPLY:继续开发并给出结果"); assert.equal(result.transport, "stdio"); }); test("codex app-server runner stays disabled unless feature flag is explicit", () => { const runnerConfig = getCodexAppServerRunnerConfig(process.env, { codexAppServerCommand: process.execPath, codexAppServerArgs: ["tests/fixtures/codex-app-server-runtime.mjs"], }); assert.equal( shouldUseCodexAppServerTaskRunner(runnerConfig, { taskType: "conversation_reply", targetCodexThreadRef: "thread-disabled", executionPrompt: "不会执行", }), false, ); }); test("codex app-server runner fails fast when the server exits before turn completion", async () => { const previous = process.env.BOSS_CODEX_APP_SERVER_FIXTURE_EXIT_AFTER_TURN_START; process.env.BOSS_CODEX_APP_SERVER_FIXTURE_EXIT_AFTER_TURN_START = "1"; try { const runnerConfig = getCodexAppServerRunnerConfig(process.env, { codexAppServerEnabled: true, codexAppServerCommand: process.execPath, codexAppServerArgs: ["tests/fixtures/codex-app-server-runtime.mjs"], codexAppServerWorkdir: repoRoot, codexAppServerTimeoutMs: 5000, }); const result = await executeCodexAppServerTask(runnerConfig, { taskId: "task-app-server-exit", taskType: "conversation_reply", targetCodexThreadRef: "019d-app-server-thread", targetCodexFolderRef: repoRoot, executionPrompt: "不要等到超时", }); assert.equal(result.status, "failed"); assert.equal(result.canFallbackToCli, false); assert.match(result.errorMessage, /CODEX_APP_SERVER_EXITED:0/); } finally { if (previous === undefined) { delete process.env.BOSS_CODEX_APP_SERVER_FIXTURE_EXIT_AFTER_TURN_START; } else { process.env.BOSS_CODEX_APP_SERVER_FIXTURE_EXIT_AFTER_TURN_START = previous; } } });