78 lines
4.0 KiB
TypeScript
78 lines
4.0 KiB
TypeScript
import type { BackendEvent, BackendTurnResult, CommandRecord, InitialPromptAssembly, RunRecord } from "../common/types.js";
|
|
import { CodexStdioBackendSession, runCodexStdioTurn, type CodexStdioTurnOptions } from "./codex-stdio.js";
|
|
import { backendProfileSpec } from "../common/backend-profiles.js";
|
|
|
|
export interface BackendActiveTurnControl {
|
|
threadId: string;
|
|
turnId: string;
|
|
steer(prompt: string): Promise<void>;
|
|
interrupt(): Promise<void>;
|
|
}
|
|
|
|
export interface BackendAdapterOptions {
|
|
codexCommand?: string;
|
|
codexArgs?: string[];
|
|
codexHome?: string;
|
|
workspacePath?: string;
|
|
abortSignal?: AbortSignal;
|
|
initialPrompt?: InitialPromptAssembly;
|
|
onEvent?: (event: BackendEvent) => void | Promise<void>;
|
|
onActiveTurn?: (control: BackendActiveTurnControl) => void | (() => void);
|
|
env?: NodeJS.ProcessEnv;
|
|
}
|
|
|
|
export interface BackendSession {
|
|
runTurn(run: RunRecord, command: CommandRecord, options?: BackendAdapterOptions): Promise<BackendTurnResult>;
|
|
close(): Promise<BackendTurnResult["events"]>;
|
|
}
|
|
|
|
export async function runBackendTurn(run: RunRecord, command: CommandRecord, options: BackendAdapterOptions = {}): Promise<BackendTurnResult> {
|
|
const spec = backendProfileSpec(run.backendProfile);
|
|
if (!spec || spec.backendKind !== "codex-app-server-stdio") {
|
|
return { terminalStatus: "failed", failureKind: "backend-failed", failureMessage: `unsupported backendProfile ${run.backendProfile}`, events: [{ type: "error", payload: { failureKind: "backend-failed", backendProfile: run.backendProfile } }] };
|
|
}
|
|
return runCodexStdioTurn(backendTurnOptions(run, command, options));
|
|
}
|
|
|
|
export function createBackendSession(run: RunRecord, options: BackendAdapterOptions = {}): BackendSession | null {
|
|
const spec = backendProfileSpec(run.backendProfile);
|
|
if (!spec || spec.backendKind !== "codex-app-server-stdio") return null;
|
|
const session = new CodexStdioBackendSession();
|
|
return {
|
|
runTurn: async (nextRun, command, turnOptions = {}) => session.runTurn(backendTurnOptions(nextRun, command, { ...options, ...turnOptions })),
|
|
close: async () => session.close(),
|
|
};
|
|
}
|
|
|
|
export function backendTurnOptions(run: RunRecord, command: CommandRecord, options: BackendAdapterOptions = {}): CodexStdioTurnOptions {
|
|
const prompt = typeof command.payload.prompt === "string" ? command.payload.prompt : JSON.stringify(command.payload);
|
|
const sandboxOverride = codexShellSandboxOverride(options.env ?? process.env);
|
|
const turnOptions: CodexStdioTurnOptions = {
|
|
backendProfile: run.backendProfile,
|
|
prompt,
|
|
cwd: options.workspacePath ?? (typeof run.workspaceRef.path === "string" ? run.workspaceRef.path : process.cwd()),
|
|
approvalPolicy: run.executionPolicy.approval,
|
|
sandbox: sandboxOverride ?? run.executionPolicy.sandbox,
|
|
requestedSandbox: run.executionPolicy.sandbox,
|
|
sandboxOverrideSource: sandboxOverride ? "AGENTRUN_CODEX_SHELL_SANDBOX" : null,
|
|
timeoutMs: run.executionPolicy.timeoutMs,
|
|
};
|
|
if (typeof command.payload.model === "string") turnOptions.model = command.payload.model;
|
|
if (typeof command.payload.threadId === "string" && command.payload.threadId.trim()) turnOptions.threadId = command.payload.threadId.trim();
|
|
else if (typeof run.sessionRef?.threadId === "string" && run.sessionRef.threadId.trim()) turnOptions.threadId = run.sessionRef.threadId.trim();
|
|
if (options.codexCommand) turnOptions.command = options.codexCommand;
|
|
if (options.codexArgs) turnOptions.args = options.codexArgs;
|
|
if (options.env) turnOptions.env = options.env;
|
|
if (options.initialPrompt) turnOptions.initialPrompt = options.initialPrompt;
|
|
if (options.codexHome) turnOptions.codexHome = options.codexHome;
|
|
if (options.abortSignal) turnOptions.abortSignal = options.abortSignal;
|
|
if (options.onEvent) turnOptions.onEvent = options.onEvent;
|
|
if (options.onActiveTurn) turnOptions.onActiveTurn = options.onActiveTurn;
|
|
return turnOptions;
|
|
}
|
|
|
|
function codexShellSandboxOverride(env: NodeJS.ProcessEnv): string | null {
|
|
const value = env.AGENTRUN_CODEX_SHELL_SANDBOX?.trim();
|
|
return value && value.length > 0 ? value : null;
|
|
}
|