/** * tool-assembly.ts — Cross-platform tool assembly. * * Assembles the intersection set of tools common to both OpenCode and Pi * platforms. This module MUST NOT import from any platform SDK. * * Phase 1: purely additive file. */ import type { CanonicalToolDef } from "./ports/tool-factory.ts"; import type { ISessionClient } from "./ports/session-client.ts"; import type { PlatformCapabilities } from "./capabilities.ts"; import type { DispatchManager } from "../dispatch/core/manager.ts"; import type { ResolvedRole } from "../types.ts"; import type { GraphNotifySource, GraphToolSet } from "../graph/tools/index.ts"; import type { NodeLivenessFeed } from "../graph/engine/index.ts"; export interface BuildToolsOptions { sessionClient?: ISessionClient; dispatchManager?: DispatchManager; resolvedSubagents?: Map; subagentModelKey?: Map; resolvedRoles: ResolvedRole[]; directory: string; /** * Optional engine-state persistence dir, threaded through `createGraphTools` * into every engine the graph tools construct. When set, engines persist * their state under `stateDir/.rolebox/state` (write-through persistence * seam in `createEngine`). Absent → engines run without persistence * (backward compatible). */ stateDir?: string; capabilities: PlatformCapabilities; extraTools?: Record; dispatchToolsOverride?: Record; loopToolsOverride?: Record; taskToolsOverride?: Record; /** * Optional graph-notify source (subtask 3): a prebuilt * `GraphCompletionHandler` or an owner config carrying the emperor session id * + session client. Threaded through `createGraphTools` into every engine the * graph tools construct so per-node completions AND graph-terminal transitions * (COMPLETE / BLOCKED) route to graph-notify targeting the emperor session. * Absent → graph_run builds engines with the default no-op seams (backward * compatible). `graphParentContext` budget scoping (`sessionID: graphId`) is * untouched. */ graphNotify?: GraphNotifySource; /** * Optional prebuilt {@link GraphToolSet} (subtask 2). When provided AND a * dispatchManager is present, the graph_* tools bind to THIS instance * instead of constructing a fresh toolset internally (via * `createGraphTools({ toolset })`) — so the platform assembly layer that * constructs the toolset once (tool-service / PiLightweightServiceStack) * can expose the SAME instance through HookDeps.graphTools and the graph_* * tools observe the same in-memory graph registry. Absent → the graph tools * construct their own toolset (legacy behavior). */ graphTools?: GraphToolSet; /** * Optional node-liveness feed seam (node-anomaly-detection subtask 2). * Threaded through `createGraphTools` into the toolset's engines (when the * toolset is constructed inside tool-assembly): the platform liveness wiring * heartbeats / fail-fasts graph sessions through the shared feed. Absent → * engines run without liveness recording (backward compatible). */ livenessFeed?: NodeLivenessFeed; /** * Optional soft-stall warn threshold (ms) for the heartbeat-based liveness * monitor (node-anomaly-detection subtask 6). Threaded into every engine * the graph tools construct. Absent → the monitor's default * (`min(60_000, nodeStaleTimeoutMs / 2)`). */ nodeStallWarnMs?: number; /** * Optional hard-stall grace (ms) past `nodeStallWarnMs` before a stalling * node is marked `timeout` (subtask 6). Absent → the monitor's default * (30_000). */ nodeStallGraceMs?: number; /** * Optional platform-provided acting-agent resolver (Pi / DSH). Threaded * through `createGraphTools` into the graph tool execute methods so that when * the platform never populates `context.agent`, the injected * `` still forwards the orchestrator's role instead of * falling back to `default_agent`. Receives the invoking session id (so a * per-session resolver like DSH's role switcher can resolve the active role). * Absent → `context.agent`-only (opencode, unchanged). */ getEffectiveAgent?: (sessionID?: string) => string; } /** * The four role-snapshot tool keys — the tools whose behavior is bound to the * resolved-role snapshot (`resolvedRoles`). Kept as a membership record so * the dsh plugin can both skip them in its boot registration loop * (`key in ROLE_SNAPSHOT_TOOL_KEYS`) and rebuild them as one disposable * generation on an in-process role reload. */ export declare const ROLE_SNAPSHOT_TOOL_KEYS: { readonly asset_search: true; readonly asset_inspect: true; readonly asset_validate: true; readonly reference_search: true; }; /** * Build exactly the four role-snapshot tools from a resolved-role snapshot. * * Separate from {@link buildCanonicalTools} so the dsh plugin's reload seam can * rebuild this generation alone (dispose-then-re-register) without recompiling * the rest of the canonical tool set. The boot path calls this with the same * argument, so the assembled map is unchanged. */ export declare function buildRoleSnapshotTools(resolvedRoles: ResolvedRole[]): Record; export declare function buildCanonicalTools(opts: BuildToolsOptions): Record; //# sourceMappingURL=tool-assembly.d.ts.map