import type { LoadedConfig } from "../config/load.js"; import type { ThinkingLevel } from "../config/types.js"; import type { DispatchOutcome, ExtensionSurface, InvocationContext, ModelRef, WorkflowCommand } from "./types.js"; import type { ProfileStateStore } from "./state.js"; export interface RouterDeps { /** Pi's API is session-bound, so the surface is resolved per call. */ surface: (ctx: InvocationContext) => ExtensionSurface; /** Fresh read per dispatch: project trust and file validity change between commands. */ loadConfig: (ctx: InvocationContext) => LoadedConfig; hint: { pending(): boolean; acknowledge(now?: string): boolean; }; /** Slash name of the settings console, quoted in every refusal. */ settingsCommand: string; /** Command names that actually exist — a route for anything else is a typo. */ knownCommands: ReadonlySet; /** Profile demotion state store (P4, feature 63). */ profileState?: ProfileStateStore; /** Wall-clock now (P4). Default: Date.now. */ now?: () => number; } export interface Router { dispatch(command: WorkflowCommand, args: string, ctx: InvocationContext, opts?: { onProfileSwitch?: "continue" | "restart"; }): Promise; /** Pi `model_select` — distinguishes our own switch from the operator's. */ noteModelSelect(model: M): void; /** Pi `thinking_level_select` — same distinction for the thinking level. */ noteThinkingLevelSelect(level: ThinkingLevel): void; /** Pi `agent_settled` — restores whatever this turn still owns. */ settle(ctx: InvocationContext, aborted?: boolean): Promise; /** True while a routed turn owns the session. The console shows and clears it. */ inFlight(): boolean; /** * Undo a routed turn the operator can see will never settle, putting the session * back exactly as `settle()` would. Returns false when nothing was in flight. */ undoInFlight(ctx: InvocationContext): Promise; } export declare function createRouter({ surface, loadConfig, hint, settingsCommand, knownCommands, profileState, now, }: RouterDeps): Router;