refactor(worker): extract AgentRuntime interface, shared provider helpers, and adapter registry

This commit is contained in:
Gabriel Brown
2026-07-10 18:28:41 -04:00
parent 697fb7286d
commit 38431155b2
5 changed files with 278 additions and 163 deletions
@@ -0,0 +1,49 @@
import type { NormalizedAgentEvent } from '../agent-events';
import type { streamExecInContainer } from './docker';
import type { AdapterWorkspace } from './provider';
export type AgentRuntimeName = 'codex' | 'opencode' | 'claude';
export type ExecStreamFn = typeof streamExecInContainer;
export type TurnResult = {
// Assistant text the adapter captured out-of-band (Codex --output-last-message
// file, Claude `result` event). Empty/undefined when everything streamed via onEvent.
finalMessage?: string;
// Runtime session id to persist for continuity (resume/--session/--resume).
sessionId?: string;
// Non-empty when the runtime reported a hard failure the caller must surface.
error?: string;
};
export type AgentRuntime = {
readonly name: AgentRuntimeName;
prepareAuth(workspace: AdapterWorkspace): Promise<void>;
runTurn(
workspace: AdapterWorkspace,
prompt: string,
onEvent: (event: NormalizedAgentEvent) => Promise<void>,
): Promise<TurnResult>;
abort(workspace: AdapterWorkspace): Promise<void>;
};
export type AdapterFactory = (deps?: {
execStream?: ExecStreamFn;
}) => AgentRuntime;
const factories = new Map<AgentRuntimeName, AdapterFactory>();
export const registerAdapter = (
name: AgentRuntimeName,
factory: AdapterFactory,
): void => {
factories.set(name, factory);
};
export const getAdapter = (name: AgentRuntimeName): AgentRuntime => {
const factory = factories.get(name);
if (!factory) {
throw new Error(`No agent runtime adapter registered for "${name}".`);
}
return factory();
};