refactor(worker): extract AgentRuntime interface, shared provider helpers, and adapter registry
This commit is contained in:
@@ -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();
|
||||
};
|
||||
Reference in New Issue
Block a user