import type { ComponentType } from 'react'; import type { TChatMessage, TMessageContent, ToolMessageContentData } from "../../types/messages.js"; import { type MessageRendererRegistry } from "../messageTypeRegistry.js"; export type ToolSchemaResult = { success: true; data: TArgs; } | { success: false; error: { message: string; }; }; export type ToolSchema = { validate: (input: unknown) => ToolSchemaResult; }; export type ToolComponentProps = { args: TArgs; result?: TResult; submitResult: (result: TResult) => void; }; export type ToolExecutionStatus = 'success' | 'error' | 'cancelled'; /** * Discriminated outcome returned by a tool's `execute` callback. * A tool may also return a bare `TResult`; it is then treated as * `{status: 'success', result}` to keep simple cases boilerplate-free. */ export type ToolExecutionOutcome = { status: 'success'; result: TResult; } | { status: 'error'; result?: TResult; error?: { message: string; }; } | { status: 'cancelled'; result?: TResult; }; export type ToolDefinition = { name: TName; description: string; parameters: Record; schema: ToolSchema; component: ComponentType>; /** * Run after the user submits a result inside the tool component. * Return: * - `TResult` (or a Promise of one) for a successful execution; * - a `ToolExecutionOutcome` to explicitly report `error` * or `cancelled`. A thrown error is surfaced as `{status: 'error'}`. */ execute?: (params: { args: TArgs; result: TResult; toolCallId: string; }) => TResult | ToolExecutionOutcome | Promise>; }; export type RuntimeToolDefinition = { name: TName; description: string; parameters: Record; validate: (input: unknown) => ToolSchemaResult; /** * Rendered as `` JSX. Hooks placed at the top of this * component work normally because it is a real React component, not a * function called inside another render path. */ Renderer: ComponentType>; execute: (params: { args: unknown; result: unknown; toolCallId: string; }) => unknown | ToolExecutionOutcome | Promise>; }; export type Toolset = Record; export type ToolPartContentData = ToolMessageContentData & { toolCallId: string; args?: TArgs; result?: TResult; }; export type ToolPartContent = TMessageContent<'tool', ToolPartContentData>; export type ToolsetResultEvent = { toolCallId: string; toolName: string; status: ToolExecutionStatus; result: unknown; error?: { message: string; }; }; /** * Wrap a typed tool definition into an erased runtime entry that the * toolset renderer can dispatch by `toolName`. The literal `name` is * preserved as a type parameter so `createToolset` can derive its keys. */ export declare function defineTool(definition: ToolDefinition): RuntimeToolDefinition; /** * Build a `Toolset` from a list of `defineTool(...)` results. Keys are * derived from `definition.name`, so the call site cannot drift between * a literal-object key and the embedded `name`. The return type narrows * its keys to the union of literal tool names, giving name-autocomplete * on lookups. Throws on duplicates. */ export declare function createToolset[]>(...tools: T): { [K in T[number]['name']]: RuntimeToolDefinition; }; /** * Map a `Toolset` to the OpenAI `tools[]` shape so chat clients can pass * tool definitions to the model without reimplementing the conversion. */ export declare function toolsetToOpenAIDefinitions(toolset: Toolset): Array<{ type: 'function'; function: { name: string; description: string; parameters: Record; }; }>; export type CreateToolsetRendererOptions = { onToolResult: (event: ToolsetResultEvent) => void; /** * Existing registry whose entries should be preserved. A shallow copy * is taken; the input reference is never mutated. */ registry?: MessageRendererRegistry; }; /** * Build a `MessageRendererRegistry` whose `tool` renderer dispatches * by `toolName` into the provided toolset. Unknown tools and invalid * args fall back to a generic ``. Errors * thrown inside `execute` are surfaced via an `error` outcome. */ export declare function createToolsetRenderer(toolset: Toolset, options: CreateToolsetRendererOptions): MessageRendererRegistry; /** * Merge a tool result into the matching `tool` part of the chat history. * Honors `event.status` so the part reflects success / error / cancelled. * For backward compatibility, a missing `status` is treated as `'success'`. * Returns the original array reference when nothing matched, so React state * setters can skip needless updates. */ export declare function applyToolResult(messages: TChatMessage[], event: ToolsetResultEvent): TChatMessage[];