/** * Library-level: spawn a child and return a handle. * * Returns: { * wait() — Promise<{ text, usage, cost, error, events }> * onLine(fn) — subscribe to every JSONL event from child stdout * kill(sig?) — terminate the child * pid — child process id * } * * Use this from library code; the LLM-callable tool below wraps it with blocking semantics. */ export type ChildEvent = Record & { type?: string; text?: string; ts?: string; data?: any; }; /** * Library-level: spawn a child and return a handle. * * Returns: { * wait() — Promise<{ text, usage, cost, error, events }> * onLine(fn) — subscribe to every JSONL event from child stdout * kill(sig?) — terminate the child * pid — child process id * } * * Use this from library code; the LLM-callable tool below wraps it with blocking semantics. */ export type SpawnChildOptions = { /** * - Path to a bareagent config JSON file. */ config?: string | undefined; /** * - Optional JSON input passed to the child on stdin. */ input?: any; /** * - Override the bareagent CLI path. */ cliPath?: string | undefined; /** * - Force-kill child after this many ms (wall-clock hard ceiling). */ timeoutMs?: number | undefined; /** * - Force-kill child after this many ms with NO output on either * stdout or stderr (heartbeat/liveness watchdog). The clock arms at spawn and resets on every JSONL * line, so a child doing real work is never killed, but one that hangs silently is. Opt-in * (0/undefined disables); independent of `timeoutMs`, which remains the absolute ceiling. */ idleTimeoutMs?: number | undefined; /** * - bareagent Stream — child:stderr events get re-emitted here. */ stream?: import("../src/stream").Stream | undefined; }; export type Stream = import("../src/stream").Stream; /** * LLM-callable spawn tool. Blocks; returns the child's final result. * * @param {object} [options] * @param {string} [options.cliPath] - Override the bareagent CLI path (default: ./bin/cli.js relative to this file). * @param {number} [options.timeoutMs] - Force-kill child after this many ms (default 10 min, wall-clock ceiling). * @param {number} [options.idleTimeoutMs] - Force-kill child after this many ms of no stdout/stderr output * (heartbeat watchdog; default off). Resets on every line, so slow-but-working children survive. * @param {Stream} [options.stream] - bareagent Stream instance — child:stderr events get re-emitted here. * @returns {{tool: import('../types').ToolDef, spawnChild: typeof spawnChild}} * @when you want an LLM-callable spawn tool so a model can fork child bareagents itself — governed per-family by bareguard * @fails returns {tool, spawnChild}; the tool blocks per child and child stderr is re-emitted as child:stderr on the wired Stream. * @example * const { tool } = createSpawnTool(); * const loop = new Loop({ provider, tools: [tool] }); */ export function createSpawnTool(options?: { cliPath?: string | undefined; timeoutMs?: number | undefined; idleTimeoutMs?: number | undefined; stream?: import("../src/stream").Stream | undefined; }): { tool: import("../types").ToolDef; spawnChild: typeof spawnChild; }; /** * Library-level: spawn a child and return a handle. * * Returns: { * wait() — Promise<{ text, usage, cost, error, events }> * onLine(fn) — subscribe to every JSONL event from child stdout * kill(sig?) — terminate the child * pid — child process id * } * * Use this from library code; the LLM-callable tool below wraps it with blocking semantics. * * @typedef {Record & {type?: string, text?: string, ts?: string, data?: any}} ChildEvent * * @typedef {object} SpawnChildOptions * @property {string} [config] - Path to a bareagent config JSON file. * @property {*} [input] - Optional JSON input passed to the child on stdin. * @property {string} [cliPath] - Override the bareagent CLI path. * @property {number} [timeoutMs] - Force-kill child after this many ms (wall-clock hard ceiling). * @property {number} [idleTimeoutMs] - Force-kill child after this many ms with NO output on either * stdout or stderr (heartbeat/liveness watchdog). The clock arms at spawn and resets on every JSONL * line, so a child doing real work is never killed, but one that hangs silently is. Opt-in * (0/undefined disables); independent of `timeoutMs`, which remains the absolute ceiling. * @property {Stream} [stream] - bareagent Stream — child:stderr events get re-emitted here. * * @param {SpawnChildOptions} [opts] * @when you want to fork a child bareagent process programmatically and get a handle — heavyweight delegation, not the in-process recurse default * @fails bounded by timeoutMs (wall-clock) and opt-in idleTimeoutMs (heartbeat); the result carries idleKilled if the watchdog fired. Threads BAREGUARD env vars to the child. * @example * const handle = spawnChild({ config, input }); * const result = await handle.wait(); */ export function spawnChild({ config, input, cliPath, timeoutMs, idleTimeoutMs, stream }?: SpawnChildOptions): { wait: () => Promise<{ text: any; usage: any; cost: any; error: any; events: ChildEvent[]; exitCode: any; signal: any; idleKilled: boolean; }>; onLine: (fn: (event: ChildEvent) => void) => () => void; kill: (sig?: NodeJS.Signals) => void; pid: number | undefined; };