/**
 * `run_code` — the single meta-tool that collapses N tool calls into
 * one model round-trip. The model emits a JavaScript program; we
 * execute it inside a `vm` sandbox where every other tool is exposed
 * as `tools.<name>(args) => Promise<...>`, and only what the program
 * passes to `text(...)` (plus the resolved return value) flows back
 * to the model.
 *
 * Why `node:vm` instead of `isolated-vm`:
 *   - The model is the koi's own brain, not adversarial input. We
 *     don't need a process-level boundary, just a clean global
 *     surface that hides `process`, `require`, `fetch`, etc.
 *   - `isolated-vm` is a native module — every EC2 deploy would need
 *     a prebuild for the target platform. `node:vm` is built-in.
 *   - Execution still runs in the koi process, so per-tool side
 *     effects (sessions, file writes, sandbox bash) work unchanged.
 *
 * Lifetime: each `run_code` call spins up a fresh context. There's no
 * persistent state between calls — the model can stitch one program
 * across many tools, but if it wants to remember something across
 * turns it has to call `text()`.
 */
import type { TSchema } from "@sinclair/typebox";
import type { AgentTool as KoiTool } from "@mariozechner/pi-agent-core";
/**
 * Schema for the model-facing tool. We keep it boring on purpose so
 * the model doesn't waste tokens on irrelevant params.
 */
declare const RUN_CODE_PARAMETERS: TSchema;
export interface RunCodeToolDeps {
    /** All other tools that should be reachable from inside the sandbox. */
    inner: KoiTool[];
    /** Optional hook fired when a wrapped tool call starts; lets us
     *  surface the same UI bubbles the conversational loop would. */
    onInnerStart?: (toolName: string, args: unknown) => void;
    onInnerEnd?: (toolName: string, isError: boolean) => void;
}
interface ExecutionOutcome {
    texts: string[];
    progress: string[];
    returnValue: unknown;
    toolCalls: Array<{
        name: string;
        durationMs: number;
        isError: boolean;
    }>;
    totalDurationMs: number;
}
/**
 * Build the single meta-tool that replaces the koi's tool surface
 * when code-mode is enabled. The inner tool set is captured at
 * construction time — the same set the conversational loop would
 * see — so behavior is consistent.
 */
export declare function createRunCodeTool(deps: RunCodeToolDeps): KoiTool<typeof RUN_CODE_PARAMETERS, ExecutionOutcome>;
export {};
