/**
 * On-demand tool discovery (`tools.discovery: true`).
 *
 * Instead of sending every external MCP tool's full schema on every request,
 * the model receives the hot set (built-in tools, per-call tools, explicitly
 * requested tools, and previously discovered tools) plus ONE `search_tools`
 * meta-tool whose description embeds a compact name+summary catalog of the
 * deferred tools. Calling `search_tools` loads matching tools:
 *  - immediately into the live tool record — the AI SDK path re-reads the
 *    record between agent-loop steps, and the native loops (Vertex
 *    Gemini/Claude, AI Studio, chat-completions, direct Anthropic) re-resolve
 *    against it on a dispatch miss and refresh their wire declarations per
 *    step — so discovered tools are callable on the very next step, and
 *  - into the session pin set (all providers include them in full on every
 *    subsequent call of the session).
 *
 * The record additionally carries a symbol-keyed {@link DeferredToolResolver}
 * (see `resolveDeferredTool`) so a loop can hydrate a cataloged tool the
 * model called directly by name WITHOUT a prior search_tools call — the
 * catalog advertises exact names, so models legitimately do this.
 *
 * Evidence for this design: catalogs past ~30-50 tools measurably degrade
 * tool-selection accuracy, and deferral+search both cuts definition tokens by
 * ~85% and RAISES selection accuracy (Anthropic MCP-eval 49%→74% on Opus 4).
 * The catalog construction (byte-stable, name-sorted, char-budgeted with a
 * degradation ladder) mirrors the proven skills-index pattern in
 * src/lib/skills/skillTools.ts.
 */
import type { Tool } from "../types/index.js";
/**
 * Above this many tools, a WARN suggests enabling `tools.discovery` when it
 * is off. Chosen from the measured degradation range (30-50 tools).
 */
export declare const LARGE_CATALOG_WARN_THRESHOLD = 40;
/** True when the value is a search_tools meta-tool generated by this module. */
export declare function isDiscoveryMetaTool(tool: unknown): boolean;
/**
 * Partition a (post-gate) tools record for discovery: deferrable tools that
 * are not pinned are removed from the record and replaced by one
 * `search_tools` meta-tool. Returns the hot record; when nothing is
 * deferrable the input record is returned unchanged.
 *
 * The returned record is mutated by search_tools on hydration (call-scoped —
 * BaseProvider builds a fresh merged record per call), which is what makes
 * discovered tools callable on subsequent steps of the same agent loop on
 * providers that re-read the record between steps.
 */
export declare function partitionToolsForDiscovery(tools: Record<string, Tool>, args: {
    /** External-tool names present in `tools` that are allowed to defer. */
    deferrableNames: string[];
    /** Session-pinned names (previously discovered) — never deferred. */
    pinnedNames: ReadonlySet<string>;
    /** Called with newly discovered names — persists session pins. */
    onHydrate: (names: string[]) => void;
}): Record<string, Tool>;
/**
 * Hydrate-and-return a deferred tool by name, when `record` was produced by
 * `partitionToolsForDiscovery` and `name` is in its deferred catalog.
 * Returns `undefined` for records without a resolver (discovery off) and for
 * names that are genuinely unknown — callers keep their hallucinated-name
 * handling for that case.
 */
export declare function resolveDeferredTool(record: Record<string, Tool> | undefined, name: string): Tool | undefined;
/**
 * Live tool lookup for native agent loops on a dispatch miss: first re-reads
 * the record (a tool hydrated by search_tools after the loop built its
 * pre-step snapshot), then falls back to auto-hydrating from the deferred
 * catalog. Returns `undefined` only when the name is genuinely unknown.
 */
export declare function resolveLiveTool(record: Record<string, Tool> | undefined, name: string): Tool | undefined;
