/** * RPC runtime pool — one `dreb --mode rpc` child process per live session. * * dreb's RPC mode is strictly one-session-per-process (switch_session repoints * the same process; it never multiplexes), so the pool spawns N children keyed * by an opaque runtime key. The telegram bridge is the in-repo precedent. */ import { RpcClient, type RpcDashboardSnapshot } from "@dreb/coding-agent/rpc"; import { type BackgroundAgentDto, type FleetRuntimeSnapshotDto, type FleetSnapshotEventDto, MAX_COMPLETED_BACKGROUND_AGENTS, type RuntimeInfoDto, type SessionStateDto } from "../shared/protocol.js"; /** Resolve the absolute path to the dreb CLI (RpcClient defaults to a cwd-relative path). */ export declare function resolveDrebCliPath(): string; export type RuntimeEventListener = (key: string, event: Record) => void; /** Listener for coalesced, synchronous fleet runtime snapshots. */ export type FleetSnapshotListener = (event: FleetSnapshotEventDto) => void; export { MAX_COMPLETED_BACKGROUND_AGENTS }; export interface DashboardRuntimeSnapshot { key: string; barrierSeq: number; snapshot: RpcDashboardSnapshot; } export interface RuntimeHandle { key: string; cwd: string; client: RpcClient; /** Session start time (ms epoch) — stable tiebreak for deterministic fleet ordering. */ createdAt: number; lastActivity: number; /** Needs-attention sources, keyed so they can be cleared independently. */ attention: Map; /** Last runtime-level error, persisted server-side so fleet refreshes stay honest. */ error?: string; /** Provider error currently responsible for error/attention; retry may clear only this source. */ providerError?: string; /** Last authoritative state, patched only with event-derivable fields between RPC reads. */ lastState?: SessionStateDto; /** Monotonic revision for confirmed model/thinking mutations. */ settingsRevision: number; /** Resume-path fallback; events must never invent or overwrite session identity. */ sessionFileFallback?: string; /** Background agents seen via events (agentId → latest info). */ backgroundAgents: Map; } export declare const DEFAULT_DASHBOARD_BARRIER_TTL_MS: number; export declare const DEFAULT_DASHBOARD_BARRIER_LIMIT = 1000; export declare const DEFAULT_FLEET_SNAPSHOT_DEBOUNCE_MS = 200; export interface RuntimePoolOptions { cliPath?: string; /** Extra args for every runtime (e.g. --provider). */ baseArgs?: string[]; /** RpcClient factory override for tests. */ clientFactory?: (options: { cliPath: string; cwd: string; args: string[]; }) => RpcClient; logger?: (line: string) => void; /** Bounds unclaimed RPC snapshot ordering records. */ dashboardBarrierTtlMs?: number; dashboardBarrierLimit?: number; /** Injectable clock for deterministic barrier-expiry tests. */ now?: () => number; /** Coalescing delay for event-derived fleet snapshot emissions. */ fleetSnapshotDebounceMs?: number; } export declare class RuntimePool { private readonly runtimes; private readonly listeners; private readonly fleetSnapshotListeners; private readonly cliPath; private readonly baseArgs; private readonly clientFactory; private readonly logger; /** * A single lazily-spawned utility runtime used to service settings/model/ * agent-type endpoints when no user session is live. Kept out of `runtimes` * (and therefore out of the fleet) so it never shows as a session card. */ private readonly utilities; private readonly utilityPromises; private readonly starting; private readonly startupPromises; private readonly exitedHandles; /** Snapshot ordering records observed synchronously from RpcClient stdout. */ private readonly dashboardBarriers; private readonly dashboardBarrierTtlMs; private readonly dashboardBarrierLimit; private readonly now; private readonly fleetSnapshotDebounceMs; private dashboardBarrierPruneTimer; private fleetSnapshotTimer; private closing; constructor(options?: RuntimePoolOptions); /** Subscribe to events from every runtime, tagged with the runtime key. */ onEvent(listener: RuntimeEventListener): () => void; /** Subscribe to debounced, in-memory fleet snapshots. */ onFleetSnapshot(listener: FleetSnapshotListener): () => void; /** * Build the fleet's live-runtime view without RPC or disk access. Map * insertion order is retained intentionally; the UI owns presentation order. */ fleetSnapshot(): FleetRuntimeSnapshotDto[]; list(): RuntimeHandle[]; get(key: string): RuntimeHandle | undefined; /** Apply a confirmed model mutation to both the child and the pool snapshot. */ setModel(handle: RuntimeHandle, provider: string, modelId: string): Promise<{ model: { provider: string; id: string; }; thinkingLevel: string; availableThinkingLevels: string[]; settingsRevision: number; }>; /** Apply a confirmed thinking mutation to both the child and the pool snapshot. */ setThinkingLevel(handle: RuntimeHandle, level: Parameters[0]): Promise<{ ok: true; settingsRevision: number; }>; /** * Record the EventHub sequence synchronously when the RPC snapshot marker * arrives. The marker line precedes its response on stdout, so this runs * before the RpcClient response continuation even across separate chunks. */ recordDashboardBarrier(runtimeKey: string, snapshotId: string, seq: number): void; /** * Capture a parent-session recovery snapshot and pair it with the sequence * captured at its RPC marker. This deliberately does not infer ordering from * await: later EventHub publications naturally have higher sequence numbers. */ snapshotDashboard(handle: RuntimeHandle): Promise; private dashboardBarrierKey; private pruneDashboardBarriers; private scheduleDashboardBarrierPrune; private scheduleFleetSnapshot; /** Spawn a new runtime in `cwd`, optionally opening an existing session file. */ create(cwd: string, sessionPath?: string): Promise; private startSessionRuntime; /** Stop a runtime and remove it from the pool. */ stop(key: string): Promise; /** * Return any live runtime suitable for process-global settings work, spawning * a hidden utility runtime (in the home directory) if no user session exists. * This is what lets the settings page — models, agent types, defaults — work * with zero sessions open, instead of 503-ing. */ ensureUtilityRuntime(cwd?: string): Promise; private startUtilityRuntime; stopAll(): Promise; private handleRuntimeExit; private isLiveHandle; private handleEvent; /** * Events intentionally patch only fields they can prove. Session identity, * session file, configuration, and context usage remain from the last RPC * baseline (or the stable creation fallback) until a later reconciliation. */ private updateStateFromEvent; private recordRuntimeError; private recordProviderError; private clearProviderError; private pruneCompletedBackgroundAgents; private fallbackState; private describeFleetRuntime; private seedBackgroundAgents; /** Snapshot a runtime for the fleet endpoint. */ describe(handle: RuntimeHandle): Promise; } //# sourceMappingURL=runtime-pool.d.ts.map