agentfootprint
Version:
The explainable agent framework — backtrack a wrong answer to the exact context that caused it (evidence, not guesses). Built on footprintjs.
61 lines (60 loc) • 2.86 kB
TypeScript
/**
* searchOf — the ONE door to a tool's `search`, judged once per tool object.
*
* Pattern: a WeakMap-cached verdict (the `hostFilled` declaration precedent).
* Role: tools/ layer. Read by the agent's registration funnel
* (`core/agent/buildToolRegistry.ts`, so a static tool is judged at
* build) and by the dispatch funnel (`core/agent/stages/
* searchCoverage.ts`, so a provider's tool is judged when first
* met). Composition never reads `tool.search` directly.
* Emits: one console warning per refused tool object (not dev-gated: a
* refused declaration is a rail that does not arm, and its symptom is
* silence — the `toolExtras` rule).
*
* `defineTool` and the MCP ingest door judge a declaration, but a hand-built
* `Tool` handed to `.tool()` skips both. So the verdict is taken HERE, by the
* same rule (`assertToolSearch`, against the tool's own `inputSchema` and the
* arguments its `period` names), and the accepted declaration is stored
* frozen (`freezeSearch`). A `defineTool` tool is remembered as built, never
* judged twice; a `hostFilled` wrapper keeps the verdict on the tool it wraps
* (its schema no longer lists the filled arguments the search classifies).
*
* A REFUSED declaration composes nothing — not a `'remote'` row. A remote row
* is a well-formed declaration the library does not trust; a refused one has
* no shape any rule vetted, so no facet may be composed from it. Its
* `checked: 'declared'` literal becomes the call's error, naming the fault.
*/
import type { ToolSearch } from '../semantics/coverage/search/types.js';
import type { Tool } from './tools.js';
/** The verdict on one tool's declaration: accepted (frozen), refused (why), or none. */
export interface SearchVerdict {
readonly search?: ToolSearch;
readonly problem?: string;
}
/**
* Remember a declaration already judged and frozen — `defineTool` calls it for
* the tool it builds. @internal
*/
export declare function rememberSearch(tool: object, search: ToolSearch): void;
/**
* Carry `from`'s verdict to `to` — a wrapper whose schema changed (`hostFilled`)
* keeps the verdict taken against the schema the search was declared for.
* @internal
*/
export declare function inheritSearch(from: Tool, to: object): void;
/**
* The tool's accepted `search`, or why it was refused, or `{}` when it
* declares none. Judged on first sight of a tool object, then remembered.
*
* @example
* ```ts
* const { search, problem } = searchOf(tool);
* if (search === undefined) return; // nothing to compose
* ```
*/
export declare function searchOf(tool: Tool): SearchVerdict;
/**
* Forget every warning issued so far.
* @internal test seam — the ledger is process-wide and warn-ONCE.
*/
export declare function _resetSearchOfWarnings(): void;