import { type ContextData, type JsonValue, type ShellResult, type UsageSnapshot, type AgentOptions, type ArtifactBody, type ArtifactRef, type BrowserSession, type BrowserSessionOptions, type CallOptions, type HumanInputOptions, type HumanInputResult, type PhaseOptions, type ScheduleOptions, type SleepArg } from "@boardwalk-labs/workflow/runtime"; import type { DesktopSession, DesktopSessionOptions, ShellOptions } from "@boardwalk-labs/workflow"; /** The loader-side curation hint for a `report_return` output-schema mismatch. Shared by the * in-process TS loader and the Python subprocess path so the author sees ONE message. */ export declare const OUTPUT_MISMATCH_HINT = "Return a value matching run()'s declared return type, or update the type and redeploy."; /** What `workflows.call` resolves at the capability seam: the child's output plus the CALLEE's * declared output schema (`null` for an untyped callee — the client passes the JSON through). */ export interface CapabilityCallResult { output: unknown; outputSchema: Record | null; } /** * The typed seam the protocol server dispatches onto — the runner's existing machinery, one * member per capability. Mirrors the SDK client's `HostInterface` so the two ends of the wire * stay symmetric. `agent` receives NATIVE `AgentOptions`: the server has already turned wire * tool declarations into executable `ToolDef`s (round-tripping `tool_invoke`) and resolved a * wire `sessionId` to its live {@link BrowserSession}. */ export interface HostCapabilities { agent(prompt: string, opts: AgentOptions | undefined): Promise; callWorkflow(slug: string, input: unknown, opts: CallOptions | undefined): Promise; runWorkflow(slug: string, input: unknown, opts: CallOptions | undefined): Promise; scheduleWorkflow(slug: string, input: unknown, opts: ScheduleOptions): Promise; sleep(arg: SleepArg): Promise; humanInput(opts: HumanInputOptions): Promise; getSecret(name: string): Promise; writeArtifact(name: string, contentType: string, body: ArtifactBody, metadata: Record | undefined): Promise; openBrowser(opts: BrowserSessionOptions | undefined): Promise; openDesktop(opts: DesktopSessionOptions | undefined): Promise; shell(cmd: string, opts: ShellOptions | undefined): Promise; phase(name: string, opts: PhaseOptions | undefined): void; idToken(audience: string): Promise; apiToken(): Promise; usage(): Promise; } /** The `bootstrap` payload: the RAW JSON input + the stored input schema (`null` when untyped — * the CLIENT applies the schema-guided revival pass) + the context DATA (never `signal`). */ export interface BootstrapData { input: JsonValue; inputSchema: Record | null; context: ContextData; } export interface WorkflowHostServerDeps { capabilities: HostCapabilities; bootstrap: BootstrapData; /** The workflow's declared output schema; `null` ⇒ the return persists unvalidated. */ outputSchema: Record | null; /** The run's cooperative-cancellation signal: on abort, every connected client is sent the * `cancel` notification (the SDK aborts `context.signal`). */ signal?: AbortSignal | undefined; /** Directory the Unix socket file is created in. Default `os.tmpdir()` — deliberately short: * `sun_path` caps a socket path at ~104 bytes on darwin. Ignored on win32 (named pipe). */ sockDir?: string | undefined; /** Host-side ceiling on ONE `tool_invoke` round-trip. Default: none — parity with the engine, * which awaits an inline tool's `execute()` without a timeout. When set, expiry throws an * ordinary Error from `execute()` (a tool-error result to the model, never run-fatal) and the * late response is discarded by id. */ toolInvokeTimeoutMs?: number | undefined; } /** * The protocol server for ONE run. `listen()` binds the socket (the runner then exports the * path as `BOARDWALK_HOST_SOCK`); `close()` tears everything down. The validated return the * program reported is read via {@link reportedReturn} after the loader completes. */ export declare class WorkflowHostServer { private readonly deps; private readonly server; private readonly connections; /** sessionId → live handle, backing `computer.browser.*` and `agent({ session })`. */ private readonly browserSessions; /** sessionId → live desktop handle, backing `computer.desktop.*` and `agent({ session })`. */ private readonly desktopSessions; private readonly validateOutput; private nextInvokeId; private sockPath; private returned; private reportFailure; private cancelled; private readonly onAbort; constructor(deps: WorkflowHostServerDeps); /** Bind the socket and resolve its path (a Unix socket path; a named pipe on win32). */ listen(): Promise; /** The bound socket path; null before `listen()`. */ get socketPath(): string | null; /** The validated value the program's loader reported via `report_return`, or null when no * return was reported (the program never finished, or returned void ⇒ the client sent null). */ reportedReturn(): JsonValue | null; /** Whether `report_return` was received at all (distinguishes "returned null" from "never * reported" for callers that care). */ hasReturn(): boolean; /** The error the most recent `report_return` attempt failed with (the output-schema mismatch), * or null when none failed / a later report succeeded. An IN-PROCESS loader re-throws this * error itself; a SUBPROCESS loader (Python) can only propagate it as a traceback + non-zero * exit, so the runner reads it back here to curate the run's failure with the original * code/message instead of the traceback's last line. */ reportReturnFailure(): Error | null; /** Push the `cancel` notification to every connected client (idempotent). */ notifyCancel(reason?: string): void; /** Tear the server down: reject in-flight tool invokes, destroy connections, unlink the socket. */ close(): Promise; private onFrame; private settleInvoke; private handleNotification; private handleRequest; private dispatch; private get caps(); /** * One handler per client→host method, each typed by ITS OWN `HostMethodParams`/`HostMethodResult` * pair via the mapped type — params arrive already narrowed (no per-case casts) and a handler * returning another method's result shape is a COMPILE error (a switch over the union couldn't * catch that). Exhaustive by construction: a new wire method fails the build until a handler * exists. `req` carries the originating connection + request id for `agent`, whose inline tools * round-trip `tool_invoke` on that same connection, correlated by this request's id. */ private readonly handlers; /** A live browser session by id, or a clear VALIDATION error for a closed/foreign one. */ private session; /** A live desktop session by id, same contract as {@link session}. */ private desktopSession; /** Resolve an agent-bound wire sessionId across BOTH tiers (browser first, then desktop). */ private computerSession; /** Validate the program's return against the declared output schema (P3.4): a mismatch fails * the run — the loader's `reportReturn` rejects and the failure is curated. `null` (a void * return) skips validation per the contract. */ private assertReturnMatchesSchema; /** Wire tool declarations → engine `ToolDef`s whose `execute()` round-trips `tool_invoke` to * the program, correlated by `call_id` = the originating agent request's own id (stringified). * Also resolves a wire `sessionId` back to its live browser session. */ private toAgentOptions; /** One host → client `tool_invoke` round-trip. Concurrent invocations multiplex by this * request's own JSON-RPC id; the optional host-side timeout abandons the call (its late * response is discarded by id) and throws an ordinary Error — a tool-error result to the * model, never run-fatal. */ private invokeTool; } /** Map a thrown value to the wire's `{code, message, data?}` (string code, engine taxonomy). * An engine-style `hint` (the one-line "what to do") rides `data.hint` so it SURVIVES the wire — * the loader's failure curation reads it back into the run's `output.error.hint` (the * hint-reaches-hosted-authors contract). */ export declare function protocolErrorOf(err: unknown): { code: string; message: string; data?: unknown; };