UNPKG

@juspay/neurolink

Version:

The pipe layer of an AI nervous system: one interface connecting provider neurons to your application, across three inference types — generate, stream and decide. `decide` returns typed, calibrated judgements from a non-generative model (~400ms, ~$0.00002

71 lines (70 loc) • 3.94 kB
/** * 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;