import { AIError } from "../errors/ai-error.mjs"; import { BaseResult } from "../contracts/result/base-result.type.mjs"; import { BaseReport } from "../contracts/result/base-report.type.mjs"; import { ToolContract } from "./tool.mjs"; import { StandardSchemaV1 } from "@standard-schema/spec"; //#region ../ai/src/tool/executable-as-tool.d.ts /** * Envelope every executable's `execute()` resolves to. Agent, workflow, * and supervisor results all satisfy this shape — `data` / `error` * carry the outcome while `usage` and `report` are always present — * which is exactly what {@link compositeAsTool} needs to nest the inner * run under the outer tool-call node. */ type ExecutableEnvelope = BaseResult & { data?: TOutput; error?: AIError; report: BaseReport; }; /** * Structural view of an executable primitive (agent / workflow / * supervisor) when it is dropped straight into an agent's `tools: []` * array WITHOUT being wrapped via `.asTool()` first. * * Only the fields the auto-adapt path reads are declared: * - `name` — becomes the LLM tool name (required; anonymous executables * are rejected at author time, mirroring `.asTool()`). * - `description` — the "when would the model pick this?" line. * - `inputSchema` — opt-in Standard Schema typing the tool's arguments. * Surfaced on `WorkflowInstance` / `SupervisorContract` from the new * optional `inputSchema` config field. Absent for agents (which take * a plain string prompt). * - `execute` — the dispatch entry every `ExecutableContract` exposes. * * `invoke` is declared `never` so a `ToolContract` (which HAS `invoke`) * can never be mistaken for an executable by the {@link isExecutableTool} * guard. */ type ExecutableTool = { readonly name: string; readonly description?: string; readonly inputSchema?: StandardSchemaV1; execute(input: TInput, options?: unknown): Promise>; invoke?: never; }; /** * Entry accepted in an agent's `tools: []` array — either an already- * built `ToolContract` (the `.asTool()` / `ai.tool()` path) or a raw * executable primitive the framework auto-adapts on the caller's * behalf. */ type AgentToolEntry = ToolContract | ExecutableTool; /** * Type guard distinguishing a raw executable primitive from a built * `ToolContract`. An executable exposes `execute()` and no `invoke()`; * a `ToolContract` exposes `invoke()`. The `invoke` check is the * load-bearing discriminator — `.asTool()`-wrapped composites keep * their own `execute` too, so checking `execute` alone is insufficient. */ declare function isExecutableTool(entry: unknown): entry is ExecutableTool; /** * Adapt a raw executable primitive (agent / workflow / supervisor) into * a `ToolContract` so an agent can dispatch it inside its tool-call * loop WITHOUT the caller writing `.asTool()`. Derives the LLM tool * manifest from the executable's own `name` + `description` + * (optional) `inputSchema`, then dispatches through the executable's * `execute()` — the inner report nests under the outer tool-call node * exactly like an explicit `.asTool()` wrapper. * * Throws `AgentExecutionError` at author time when the executable lacks * a usable `name` — the agent's tool surface needs a stable id, the * same constraint `.asTool()` enforces. */ declare function executableToTool(executable: ExecutableTool): ToolContract; /** * Normalize an agent's `tools: []` array into a uniform * `ToolContract[]` for the runtime. Already-built `ToolContract`s * (`.asTool()` / `ai.tool()`) pass through untouched; raw executable * primitives are auto-adapted via {@link executableToTool}. * * Returns `undefined` when no tools were supplied so the agent's * existing `config.tools ?? []` fallbacks stay byte-identical. */ declare function normalizeAgentTools(tools: ReadonlyArray | undefined): ToolContract[] | undefined; //#endregion export { AgentToolEntry, ExecutableTool, executableToTool, isExecutableTool, normalizeAgentTools }; //# sourceMappingURL=executable-as-tool.d.mts.map