import type { JSONSchema7 } from 'json-schema';
import type { Agent } from '../voice/agent.js';
import type { RunContext, UnknownUserData } from '../voice/run_context.js';
declare const TOOL_SYMBOL: unique symbol;
declare const FUNCTION_TOOL_SYMBOL: unique symbol;
declare const PROVIDER_TOOL_SYMBOL: unique symbol;
declare const TOOLSET_SYMBOL: unique symbol;
declare const HANDOFF_SYMBOL: unique symbol;
export type JSONValue = null | string | number | boolean | JSONObject | JSONArray;
export type JSONArray = JSONValue[];
export type JSONObject = {
    [key: string]: JSONValue;
};
export type ToolInputSchema<T = JSONObject> = {
    _output: T;
} | {
    '~standard': {
        types?: {
            output: T;
        };
    };
} | JSONSchema7;
/**
 * Infer the output type from a ToolInputSchema.
 * Adapted from Vercel AI SDK's InferSchema type.
 * Source: https://github.com/vercel/ai/blob/main/packages/provider-utils/src/schema.ts#L72-L79
 */
export type InferToolInput<T> = T extends {
    _output: infer O;
} ? O : T extends {
    '~standard': {
        types?: {
            output: infer O;
        };
    };
} ? O : any;
/**
 * Tool argument type for a (possibly absent) parameters schema. When `parameters` is omitted the
 * generic defaults to `undefined`, yielding an empty-args type; otherwise the args are inferred
 * from the schema via {@link InferToolInput}. Wrapped in tuples to keep the check non-distributive.
 * @internal
 */
export type ToolArgs<Schema> = [Schema] extends [undefined] ? Record<string, never> : InferToolInput<Schema>;
export type ToolType = 'function' | 'provider';
export type ToolChoice = 'auto' | 'none' | 'required' | {
    type: 'function';
    function: {
        name: string;
    };
};
export type DuplicateMode = 'allow' | 'reject' | 'replace' | 'confirm';
export declare const CONFIRM_DUPLICATE_PARAM = "lk_agents_confirm_duplicate";
export declare class ToolError extends Error {
    constructor(message: string);
}
export declare const ToolFlag: {
    readonly NONE: 0;
    readonly IGNORE_ON_ENTER: number;
    readonly CANCELLABLE: number;
};
export type ToolFlag = (typeof ToolFlag)[keyof typeof ToolFlag];
export interface AgentHandoff {
    /**
     * The agent to handoff to.
     */
    agent: Agent;
    /**
     * The return value of the tool.
     */
    returns?: any;
    [HANDOFF_SYMBOL]: true;
}
export declare function handoff(options: {
    agent: Agent;
    returns?: any;
}): AgentHandoff;
export interface ToolOptions<UserData = UnknownUserData> {
    /**
     * RunContext for the current agent session.
     */
    ctx: RunContext<UserData>;
    /**
     * The ID of the tool call.
     */
    toolCallId: string;
    /**
     * An abort signal that indicates that the overall operation should be aborted.
     */
    abortSignal: AbortSignal;
}
export type ToolExecuteFunction<Parameters extends JSONObject, UserData = UnknownUserData, Result = unknown> = (args: Parameters, opts: ToolOptions<UserData>) => Promise<Result>;
export interface Tool {
    /**
     * The type of the tool.
     * @internal Either user-defined function tool or provider-side tool.
     */
    type: ToolType;
    /**
     * Stable identifier used to key the tool inside a `ToolContext`. For function tools this
     * mirrors `name`; for provider tools this is the provider tool id.
     */
    id: string;
    [TOOL_SYMBOL]: true;
}
export declare abstract class ProviderTool implements Tool {
    readonly type: "provider";
    readonly id: string;
    readonly [TOOL_SYMBOL]: true;
    readonly [PROVIDER_TOOL_SYMBOL]: true;
    constructor({ id }: {
        id: string;
    });
}
export interface FunctionTool<Parameters extends JSONObject = JSONObject, UserData = UnknownUserData, Result = unknown> extends Tool {
    type: 'function';
    /**
     * The name of the tool. Used to identify it inside a `ToolContext` and exposed to the LLM
     * as the function name to call. Also surfaced as the inherited `Tool.id`.
     */
    name: string;
    /**
     * The description of the tool. Will be used by the language model to decide whether to use the tool.
     */
    description: string;
    /**
     * The schema of the input that the tool expects. The language model will use this to generate the input.
     * It is also used to validate the output of the language model.
     * Use descriptions to make the input understandable for the language model.
     */
    parameters: ToolInputSchema<Parameters>;
    /**
     * An async function that is called with the arguments from the tool call and produces a result.
     * It also carries context about current session, user-defined data, and the tool call id, etc.
     */
    execute: ToolExecuteFunction<Parameters, UserData, Result>;
    flags: number;
    onDuplicate: DuplicateMode;
    [FUNCTION_TOOL_SYMBOL]: true;
}
/**
 * A function tool without `id`/`name`. Returned by {@link tool} when `name` is omitted; the
 * containing object key supplies the name when registered via an object-map tool definition.
 */
export type AnonFunctionTool<Parameters extends JSONObject = JSONObject, UserData = UnknownUserData, Result = unknown> = Omit<FunctionTool<Parameters, UserData, Result>, 'id' | 'name'> & {
    id?: never;
    name?: never;
};
export interface ToolCalledEvent<UserData = UnknownUserData> {
    ctx: RunContext<UserData>;
    arguments: Record<string, unknown>;
}
export interface ToolCompletedEvent<UserData = UnknownUserData> {
    ctx: RunContext<UserData>;
    output?: {
        type: 'output';
        value: unknown;
    } | {
        type: 'error';
        value: Error;
    };
}
/** Context passed to a {@link Toolset}'s `setup` hook when it activates. */
export interface ToolsetContext {
    /**
     * Replace the toolset's tools. Useful for dynamic sources
     * (e.g. an MCP server) whose tools are discovered after `setup` or change at runtime.
     */
    updateTools(tools: readonly ToolContextEntry[]): void;
}
/**
 * Function tools of a `ToolContext`, sorted by name for deterministic provider payloads.
 * Provider tools are intentionally excluded — callers that need them iterate `flatten()`.
 * @internal
 */
export declare function sortedToolEntries<UserData = UnknownUserData>(toolCtx: ToolContext<UserData>): Array<[string, FunctionTool<any, UserData, any>]>;
/** Function tool names of a `ToolContext`, sorted for deterministic output. @internal */
export declare function sortedToolNames(toolCtx: ToolContext | undefined): string[];
/**
 * A stateful collection of tools sharing a lifecycle. Tools registered through a `Toolset` are
 * flattened into the surrounding `ToolContext`, while the `Toolset` itself is tracked so its
 * `setup()` / `aclose()` hooks can be invoked by the agent runtime.
 */
export declare class Toolset {
    #private;
    readonly [TOOLSET_SYMBOL]: true;
    constructor({ id, tools }: {
        id: string;
        tools: readonly ToolContextEntry[];
    });
    /**
     * For when your tools share something that needs setup or cleanup, like a DB pool, an open MCP
     * client, or listeners on a shared bus. `setup` runs once at activation, `aclose` once at
     * teardown. If the tool list itself is dynamic (e.g. an MCP server), push it from `setup` via
     * {@link ToolsetContext.updateTools}.
     *
     * @example Static tool list with a shared backing resource
     * ```ts
     * function createPostgresToolset(connectionUrl: string): Toolset {
     *   const pool = new pg.Pool({ connectionString: connectionUrl });
     *   return Toolset.create({
     *     id: 'postgres',
     *     tools: [queryOrders, queryCustomers],
     *     aclose: () => pool.end(),
     *   });
     * }
     * ```
     *
     * @example Dynamic tool list bound to an external source
     * ```ts
     * function createMcpToolset(url: string): Toolset {
     *   const client = new MCPClient({ url });
     *   return Toolset.create({
     *     id: 'mcp_remote',
     *     // setup connects and wires listeners that push the server's tools whenever they change;
     *     // the runtime re-advertises without re-running anything.
     *     setup: async ({ updateTools }) => {
     *       const sync = async () => updateTools(await client.listTools());
     *       client.on('connect', sync);
     *       client.on('tool_list_changed', sync);
     *       await client.connect();
     *     },
     *     tools: [],
     *     aclose: () => client.disconnect(),
     *   });
     * }
     * ```
     */
    static create(options: ToolsetCreateOptions): Toolset;
    get id(): string;
    get tools(): readonly ToolContextEntry[];
    /**
     * Replace the toolset's current tools. Backs {@link ToolsetContext.updateTools}; the runtime
     * re-flattens and re-advertises after calling it.
     *
     * @internal
     */
    _setTools(tools: readonly ToolContextEntry[]): void;
    setup(_ctx: ToolsetContext): Promise<void>;
    aclose(): Promise<void>;
}
/** Options accepted by `Toolset.create()` — id + tools plus optional setup/teardown hooks. */
export interface ToolsetCreateOptions {
    id: string;
    /**
     * One-time async initialization run when the toolset activates — e.g. connecting to a server
     * and wiring listeners. Push a changed tool list via {@link ToolsetContext.updateTools}.
     */
    setup?: (ctx: ToolsetContext) => Promise<void>;
    /** The toolset's initial tools. */
    tools: readonly ToolContextEntry[];
    /** Invoked when the toolset is being torn down. Release awaitable resources here. */
    aclose?: () => Promise<void>;
}
/**
 * Tool context or data that can be normalized into one. Used by APIs that accept an already-built
 * context as well as direct tool lists or tool maps.
 */
export type ToolContextLike<UserData = UnknownUserData> = ToolContext<UserData> | ToolContextInit<UserData>;
/**
 * Initial tool data accepted by `ToolContext` constructors and update methods.
 */
export type ToolContextInit<UserData = UnknownUserData> = readonly ToolContextEntry<UserData>[] | ToolDefinitionMap<UserData>;
/**
 * Object shorthand for declaring anonymous function tools keyed by their model-visible names.
 */
export type ToolDefinitionMap<UserData = UnknownUserData> = {
    readonly [toolName: string]: AnonFunctionTool<any, UserData, any>;
};
export declare function toToolContext<UserData = UnknownUserData>(input: ToolContextLike<UserData>): ToolContext<UserData>;
export declare function toToolContext<UserData = UnknownUserData>(input: ToolContextLike<UserData> | undefined): ToolContext<UserData> | undefined;
export declare function normalizeToolContextInit<UserData = UnknownUserData>(input: ToolContextInit<UserData>): ToolContextEntry<UserData>[];
export type ToolContextEntry<UserData = any> = FunctionTool<any, UserData, any> | ProviderTool | Toolset;
export declare class ToolContext<UserData = UnknownUserData> {
    private _tools;
    private _functionToolsMap;
    private _providerTools;
    private _toolsets;
    constructor(tools?: ToolContextInit<UserData>);
    static empty<UserData = UnknownUserData>(): ToolContext<UserData>;
    /** A copy of all function tools in the tool context, including those in tool sets. */
    get functionTools(): Record<string, FunctionTool<any, UserData, any>>;
    /** A copy of all provider tools in the tool context, including those in tool sets. */
    get providerTools(): ProviderTool[];
    /** A copy of all toolsets registered in the context. */
    get toolsets(): readonly Toolset[];
    /**
     * A copy of the raw tool list this context was constructed with.
     */
    get tools(): readonly ToolContextEntry<UserData>[];
    /** Flatten the tool context to a list of tools. */
    flatten(): Tool[];
    getFunctionTool(id: string): FunctionTool<any, UserData, any> | undefined;
    hasTool(id: string): boolean;
    updateTools(tools: ToolContextInit<UserData>): void;
    private _updateTools;
    private _syncFlattened;
    /** Hide tools from the callable set while keeping their toolsets intact. @internal */
    _exclude(tools: readonly Tool[]): void;
    /** Return a copy containing only flattened callable/provider entries. @internal */
    _flattenedCopy(): ToolContext<UserData>;
    copy(): ToolContext<UserData>;
    equals(other: ToolContext): boolean;
}
export declare function isSameToolChoice(choice1: ToolChoice | null, choice2: ToolChoice | null): boolean;
/**
 * Create a function tool. Parameters are inferred from the schema; omit `parameters` for a tool
 * that takes no arguments.
 */
export declare function tool<UserData = UnknownUserData, Schema extends ToolInputSchema<any> | undefined = undefined, // eslint-disable-line @typescript-eslint/no-explicit-any -- Generic constraint needs to accept any JSONObject type
Result = unknown>({ name, description, parameters, execute, flags, onDuplicate, }: {
    /** Unique name the model calls the tool by. Must be non-empty. */
    name: string;
    /** Natural-language description that tells the model when to use this tool. */
    description: string;
    /**
     * Input schema for the tool's arguments — either a Zod object schema (args
     * are type-inferred) or a raw JSON Schema. Omit for a tool that takes no
     * arguments.
     */
    parameters?: Schema;
    /**
     * Called when the model invokes the tool. Receives the parsed arguments (an
     * empty object when `parameters` is omitted) and a {@link RunContext}
     * (`ctx`); the returned value is sent back to the model.
     */
    execute: ToolExecuteFunction<ToolArgs<Schema>, UserData, Result>;
    /**
     * Bitmask of {@link ToolFlag}s, e.g. `ToolFlag.CANCELLABLE` to allow the call
     * to be cancelled mid-flight. Defaults to `ToolFlag.NONE`.
     */
    flags?: number;
    /**
     * How a concurrent duplicate call of this tool is handled while one is still
     * running: `'allow'` | `'reject'` | `'replace'` | `'confirm'`. Defaults to
     * `'allow'`.
     */
    onDuplicate?: DuplicateMode;
}): FunctionTool<ToolArgs<Schema>, UserData, Result>;
/**
 * Create an anonymous (name-less) function tool. Parameters are inferred from the schema; omit
 * `parameters` for a tool that takes no arguments.
 */
export declare function tool<UserData = UnknownUserData, Schema extends ToolInputSchema<any> | undefined = undefined, // eslint-disable-line @typescript-eslint/no-explicit-any -- Generic constraint needs to accept any JSONObject type
Result = unknown>({ description, parameters, execute, flags, onDuplicate, }: {
    /** Omitted in object syntax; the containing object key becomes the tool name. */
    name?: never;
    /** Natural-language description that tells the model when to use this tool. */
    description: string;
    /**
     * Input schema for the tool's arguments — either a Zod object schema (args
     * are type-inferred) or a raw JSON Schema. Omit for a tool that takes no
     * arguments.
     */
    parameters?: Schema;
    /**
     * Called when the model invokes the tool. Receives the parsed arguments (an
     * empty object when `parameters` is omitted) and a {@link RunContext}
     * (`ctx`); the returned value is sent back to the model.
     */
    execute: ToolExecuteFunction<ToolArgs<Schema>, UserData, Result>;
    /**
     * Bitmask of {@link ToolFlag}s, e.g. `ToolFlag.CANCELLABLE` to allow the call
     * to be cancelled mid-flight. Defaults to `ToolFlag.NONE`.
     */
    flags?: number;
    /**
     * How a concurrent duplicate call of this tool is handled while one is still
     * running: `'allow'` | `'reject'` | `'replace'` | `'confirm'`. Defaults to
     * `'allow'`.
     */
    onDuplicate?: DuplicateMode;
}): AnonFunctionTool<ToolArgs<Schema>, UserData, Result>;
export declare function isTool(tool: any): tool is Tool;
export declare function isFunctionTool(tool: unknown): tool is FunctionTool;
export declare function isProviderTool(tool: any): tool is ProviderTool;
export declare function isToolset(value: any): value is Toolset;
export declare function isToolError(error: any): error is ToolError;
export declare function isAgentHandoff(handoff: any): handoff is AgentHandoff;
export {};
//# sourceMappingURL=tool_context.d.ts.map