/** * toolArgsValidation — validate LLM-produced tool args against the tool's * declared `inputSchema` BEFORE dispatch (backlog #9). * * Pattern: pure function module — no state, no events; the toolCalls stage * owns when to call it and what to do with the verdict. * Role: The model writes tool args as free-form JSON; nothing guaranteed * they match the schema the tool advertised. Dispatching garbage * surfaced as deep tool stack traces (or worse, silent misbehavior). * Validating at the boundary turns a malformed call into a * MODEL-VISIBLE structured tool result, so the LLM corrects its * args and retries on the next ReAct iteration. * * ── Honest-subset contract ──────────────────────────────────────────────── * This is NOT a full JSON Schema implementation. It enforces the core that * tool schemas in the wild actually use, and IGNORES everything else * (permissive on unknown keywords — a schema using `pattern`/`oneOf`/`$ref` * still validates the supported core, never false-rejects on the rest): * * ENFORCED: `type` (object/array/string/number/integer/boolean/null, * union arrays), `required`, `properties` (recursive), * `items` (single-schema, recursive), `enum` (primitives), * `additionalProperties: false` ONLY when explicitly set. * IGNORED: format, pattern, min/max*, oneOf/anyOf/allOf/not, $ref, * const, dependencies, … * * ── Security: never echo VALUES ─────────────────────────────────────────── * Issues name the PATH, the EXPECTED shape, and the TYPE of what arrived — * never the supplied value itself. The message flows into history (LLM), * the emit channel, and traces; arg values can carry PII or injection * payloads. Enum expectations echo SCHEMA values only (already LLM-visible * in the tools block). */ /** When to enforce: 'enforce' rejects before dispatch (default), 'warn' * emits the event but executes anyway, 'off' skips validation entirely. */ export type ToolArgValidationMode = 'enforce' | 'warn' | 'off'; /** One schema violation. `got` is a TYPE NAME, never a value. */ export interface ToolArgIssue { /** Dot/bracket path from the args root, '' for the root itself. */ readonly path: string; readonly expected: string; readonly got: string; } export interface ToolArgValidationResult { readonly ok: boolean; readonly issues: readonly ToolArgIssue[]; } /** * Validate tool-call args against the tool's `inputSchema`. * * Total function: a malformed/exotic SCHEMA never throws — anything outside * the honest subset is ignored, so the worst a bad schema can do is * under-validate (never block a legitimate call). */ export declare function validateToolArgs(args: unknown, inputSchema: Readonly> | undefined): ToolArgValidationResult; /** * Render the MODEL-VISIBLE tool result for a rejected call. Names paths, * expectations, and received TYPES — never received values. The model * already has the full schema in its tools block; pointing at the issues * is what makes the retry converge. */ export declare function formatToolArgIssues(toolName: string, issues: readonly ToolArgIssue[]): string;