fix: keep codex stdio server alive across turns
This commit is contained in:
+14
-4
@@ -1,5 +1,5 @@
|
||||
import { RunnerManagerApi, failureKindFromError, terminalStatusForFailure, errorMessage } from "./manager-api.js";
|
||||
import { runBackendTurn, type BackendAdapterOptions } from "../backend/adapter.js";
|
||||
import { createBackendSession, runBackendTurn, type BackendAdapterOptions, type BackendSession } from "../backend/adapter.js";
|
||||
import { materializeResourceBundle } from "./resource-bundle.js";
|
||||
import type { BackendEvent, BackendProfile, CommandRecord, FailureKind, JsonRecord, RunRecord, RunnerRecord, TerminalStatus } from "../common/types.js";
|
||||
import { AgentRunError } from "../common/errors.js";
|
||||
@@ -67,6 +67,7 @@ export async function runOnce(options: RunnerOnceOptions): Promise<JsonRecord> {
|
||||
let workspacePath: string | undefined;
|
||||
let materializationAttempted = false;
|
||||
let materializationFailure: { failureKind: FailureKind; terminalStatus: TerminalStatus; message: string } | null = null;
|
||||
let backendSession: BackendSession | null = null;
|
||||
|
||||
try {
|
||||
let idleSince = Date.now();
|
||||
@@ -102,7 +103,7 @@ export async function runOnce(options: RunnerOnceOptions): Promise<JsonRecord> {
|
||||
|
||||
const result = materializationFailure
|
||||
? await reportCommandFailure(api, options.runId, command.id, runner, attemptId, materializationFailure, "runner:resource-bundle")
|
||||
: await executeCommand(api, options, command, runner, attemptId, workspacePath);
|
||||
: await executeCommand(api, options, command, runner, attemptId, workspacePath, backendSession ?? (backendSession = createBackendSession(currentRun, options)));
|
||||
commandResults.push(result);
|
||||
if (options.oneShot === true) {
|
||||
const run = await api.reportStatus(options.runId, { terminalStatus: result.terminalStatus, failureKind: result.failureKind, failureMessage: null });
|
||||
@@ -117,11 +118,19 @@ export async function runOnce(options: RunnerOnceOptions): Promise<JsonRecord> {
|
||||
const finalRun = await api.reportStatus(options.runId, { terminalStatus, failureKind, failureMessage: message }) as RunRecord;
|
||||
return { runner, terminalStatus, failureKind, run: finalRun, commandsProcessed: commandResults.length, commandResults } as JsonRecord;
|
||||
} finally {
|
||||
if (backendSession) {
|
||||
try {
|
||||
const closeEvents = await backendSession.close();
|
||||
for (const event of closeEvents) await api.appendEvent(options.runId, annotateCommandEvent(event, "runner-shutdown", attemptId, runner.id));
|
||||
} catch {
|
||||
// Runner shutdown must not hide the terminal result already reported for the command.
|
||||
}
|
||||
}
|
||||
stopHeartbeat();
|
||||
}
|
||||
}
|
||||
|
||||
async function executeCommand(api: RunnerManagerApi, options: RunnerOnceOptions, command: CommandRecord, runner: RunnerRecord, attemptId: string, workspacePath: string | undefined): Promise<CommandExecutionResult> {
|
||||
async function executeCommand(api: RunnerManagerApi, options: RunnerOnceOptions, command: CommandRecord, runner: RunnerRecord, attemptId: string, workspacePath: string | undefined, backendSession: BackendSession | null): Promise<CommandExecutionResult> {
|
||||
await api.ackCommand(command.id);
|
||||
const acked = await api.getCommand(options.runId, command.id);
|
||||
if (acked.state === "cancelled") return await reportCancelled(api, options.runId, command.id, runner, attemptId, "command cancelled before backend start");
|
||||
@@ -130,7 +139,8 @@ async function executeCommand(api: RunnerManagerApi, options: RunnerOnceOptions,
|
||||
const stopCancelWatch = watchCancellation(api, options.runId, command.id, abortController);
|
||||
try {
|
||||
const latestRun = await api.getRun(options.runId);
|
||||
const result = await runBackendTurn(latestRun, command, { ...options, ...(workspacePath ? { workspacePath } : {}), abortSignal: abortController.signal });
|
||||
const backendOptions = { ...options, ...(workspacePath ? { workspacePath } : {}), abortSignal: abortController.signal };
|
||||
const result = backendSession ? await backendSession.runTurn(latestRun, command, backendOptions) : await runBackendTurn(latestRun, command, backendOptions);
|
||||
for (const event of result.events) {
|
||||
await api.appendEvent(options.runId, annotateCommandEvent(event, command.id, attemptId, runner.id));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user