agentfootprint
Version:
The explainable agent framework — backtrack a wrong answer to the exact context that caused it (evidence, not guesses). Built on footprintjs.
76 lines (75 loc) • 4.02 kB
TypeScript
/**
* search/declaration — the ONE rule a `Tool.search` declaration is held to.
*
* Pattern: one validator, two doors (the `assertResultCeiling` precedent):
* `defineTool` refuses at definition, and the MCP ingest door
* (`mcp/toolExtras.ts` · `readToolExtras`) asks the same function
* and drops a declaration it refuses. A declaration nobody vetted —
* a remote `_meta` bag — must land on a message, never a TypeError.
* Role: semantics/ layer, pure. Throws `Error` naming the tool, the field
* and the code (`unclassified-argument`, `unknown-argument`,
* `gaps-without-bears`, `fixed-without-said`, `when-omitted-shape`,
* `statement-text-refused`).
* Emits: N/A.
*
* Why so strict: a declaration is untrusted text from the tool author, and the
* composer builds every coverage row from it. An argument nobody classified
* would be ground nobody accounts for; a default that is neither a value nor
* `{ any: true }` would be read as one of them by a guess. Every such shape is
* refused here, at the line the author wrote, not at the first "not found" of
* the first incident.
*/
import { type PeriodShapes } from '../../../time/periodForm.js';
import type { SearchRole, SearchScalar, ToolSearch } from './types.js';
/** The closed role set, tied to {@link SearchRole} in both directions. */
export declare const SEARCH_ROLES: readonly SearchRole[];
/** What the declaration is judged against, besides itself. */
export interface SearchDeclarationContext {
/** The tool's `inputSchema` — every one of its properties needs a role. */
readonly inputSchema: Readonly<Record<string, unknown>>;
/**
* The arguments the tool's `period` names, when it declares one — a
* `period`-role argument must be one of them. Absent: no `period` declared.
*/
readonly periodArguments?: readonly string[];
}
/** A finite number, a string or a boolean — what a default or a qualifier may be. */
export declare function isSearchScalar(v: unknown): v is SearchScalar;
/** `{ any: true }` exactly — no other key, no other value. */
export declare function isAnyValue(v: unknown): v is {
readonly any: true;
};
/**
* The declaration as it is STORED — a deep copy, frozen, each argument's
* `said` a null-prototype map — so nothing downstream can mutate it and no
* value a call sends can reach an inherited property through it
* (`valueWords.ts`). `defineTool` and the MCP ingest door store this, after
* `assertToolSearch` accepted the declaration.
*/
export declare function freezeSearch(search: ToolSearch): ToolSearch;
/**
* The arguments a tool's `period` names — its single argument, its zone
* argument and every argument of its forms — or `undefined` when it declares
* no period. What a `period`-role search argument must be one of.
*/
export declare function periodArgumentsOf(period: PeriodShapes | undefined): readonly string[] | undefined;
/**
* Refuse a `search` this library cannot honour, at definition time — naming
* the tool, the field and the code. `undefined` declares nothing and passes.
*
* @example
* ```ts
* assertToolSearch('list_incidents', search, { inputSchema });
* ```
*/
export declare function assertToolSearch(toolName: string, search: ToolSearch | undefined, context: SearchDeclarationContext): void;
/**
* EVERY declaration text that can reach a statement the library writes, as it
* lands there: the source's and the subject's `what`; each fixed qualifier and
* each declared default as `name: value` (one per value of a list); each
* classified argument's name (a sent value is the call's, quoted by the
* writer, never declaration text); each gap's `what` and `why`. A new field
* that reaches a statement joins THIS list, so it meets the one rule.
* Assumes a declaration whose shape `assertToolSearch` already accepted.
*/
export declare function statementTextsOf(search: ToolSearch): ReadonlyArray<readonly [string, string]>;