import type { DomainName } from "../constants.js"; /** * Wrong-filter-name → correction table, used to turn a `.strict()` schema * rejection into something the model can act on in one turn (SEP-1303: input * validation failures must surface as *tool* errors so the model can * self-correct, not as opaque protocol errors). * * Why this exists: the six main search endpoints take filter names that must * match the BoondManager API query parameters verbatim (see CLAUDE.md * §*Search Filter Naming*). The schemas are `.strict()`, so a wrong name is * rejected rather than silently ignored — but "Unrecognized key: * \"mainManagers\"" tells the model *that* it was wrong, never *what to use * instead*. Every entry below is a confusion we have actually seen (or that * the API's own naming invites), mapped to the correct name plus the one-line * reason the correct name behaves differently. * * The messages are consumed by `unknownFilterMessage()`, which the search * schemas install as their unrecognized-key error (see * `src/tools/validation-wrapper.ts`). Keep them short: they are read by a * model mid-call, not by a human reading docs. */ export interface FilterAlias { /** Input name to use instead. Absent when the filter simply does not exist on that endpoint. */ correct?: string; /** One-line reason / usage note. Should say what the correct filter *does*, not just its name. */ hint: string; /** Dictionary resource URI to read when the value is a state/type id. */ dictionary?: string; } /** * Endpoints whose filter vocabulary differs (states/types are named after the * entity). Everything else only gets the global table. */ export type SearchEndpoint = Extract; /** Confusions that are wrong on every endpoint. */ export declare const GLOBAL_FILTER_ALIASES: Readonly>; /** * Endpoint-specific confusions. `states` and `typeOf` are the two names the * model reaches for by default; on four of the six endpoints they are prefixed * with the entity, on `/contacts` it is `typesOf` (with the s), and * `/companies` has no type filter at all. */ export declare const ENDPOINT_FILTER_ALIASES: Readonly>>>; /** Resolve a wrong filter name to its correction, endpoint-specific table first. */ export declare function resolveFilterAlias(key: string, endpoint?: SearchEndpoint): FilterAlias | undefined; /** * Closest accepted key within 2 edits (case/separator-insensitive), for typos * the alias table doesn't know about (`pagesize`, `keywordType`, …). */ export declare function closestKey(key: string, validKeys: readonly string[]): string | undefined; /** * Build the text returned to the model when a search call carries unknown * filter names. Shape, per unknown key: * * Filtre inconnu « mainManagers » → utiliser `perimeterManagers` (…). * * plus, when the correction is a state/type filter, the dictionary resource to * read for the ids. Ends with the accepted filter list so the model can retry * from the error alone rather than re-reading the whole tool schema. * * A correction is only printed when the replacement is **actually accepted by * this endpoint**. The wrapper runs on every search tool, not just the six * perimeter-aware ones, and the global table is written for those: telling * `boond_invoices_search` to use `perimeterAgencies` (which it does not accept) * sends the model into a second rejection, after which it typically drops the * filter and reports a company-wide list as if it were scoped. */ export declare function unknownFilterMessage(keys: readonly string[], validKeys: readonly string[], endpoint?: SearchEndpoint): string; //# sourceMappingURL=filter-aliases.d.ts.map