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.17 kB
TypeScript
/**
* statement — the library's sentence for an established typed claim, written from the cited
* reads' rows alone (design § 5.1): what was searched, and every gap said out loud.
*
* Pattern: fixed templates; the template is chosen by the ROW's shape (an `among` miss reads
* "did not find … among N names"), then by the claim's kind. One clause per cited read,
* one line each, in ordinal order.
*
* The library's own voice states ONLY what the record shows ("no cap reached"). Every
* other text is QUOTED and ATTRIBUTED to where it came from: "(declared by the tool)",
* "(fixed by the tool)", "(the tool's declared default)", "(as sent by the model)",
* "(as the tool's result says)", "(the caller's identity)". A declared fact is said as
* the tool's ("the tool declares no server cap", "the tool declares one page"). An
* unsent argument is said with calibrated words: the tool may have applied its own
* default, so this may cover only part.
*
* Quoting is the boundary: NFKC, control and format characters (bidi overrides,
* zero-width marks) removed, line breaks flattened, backticks turned into apostrophes.
* A value is capped at 64 characters plus "…"; a gap's text at the 120 its declaration
* may hold. EVERY gap is listed, never cut short in number; other lists are capped and
* counted ("and N more"), so a clause stays within `clauseLimit(gaps)`.
* Role: integrity/ layer (L3), read by `judge.ts`. `complete` states the rows READ — their
* count and identities (a fact's `entity`, or the declared id column) — never a list
* the model wrote.
*/
import type { ComposedCoverage } from '../../semantics/coverage/composedCoverage.js';
import { type TimeRange } from '../../time/range.js';
import type { NegativeKind, NegativeStatement, SearchTool, TurnCall } from './types.js';
type ComposedSearchRow = ComposedCoverage;
type DeclaredTool = SearchTool;
/** Bump with any change to a template or to how a value is rendered. */
export declare const STATEMENT_VERSION = "7";
/** The stated bounds of one value, one gap's text, and the capped lists. */
export declare const STATEMENT_LIMITS: Readonly<{
valueChars: 64;
gapChars: 120;
listItems: 12;
scopeItems: 24;
}>;
/**
* The most UTF-16 units a clause can hold for a row with `gaps` gaps: the head and at most ~60
* capped parts (each quoted value ≤ 2 × 64 + 3 units, with its label and attribution), plus
* each gap (≤ 2 × 120 + 3 units, with its attribution).
*/
export declare function clauseLimit(gaps: number): number;
/** One value as quoted data (64 code points). */
export declare const quoteValue: (value: unknown) => string;
/**
* A span (`time/range.ts`) as the statement writes it — always with its date, so a historical
* window is never read as today's: `2026-10-01 08:00–10:00Z`, or a date on each bound across
* days (`2026-10-15 10:00Z–2026-10-22 10:00Z`); undefined when it is not a pair of instants.
*/
export declare function formatSpan(span: TimeRange): string | undefined;
/** The statement for an established claim: one clause per cited read, in ordinal order. */
export declare function composeStatement(kind: NegativeKind, reads: readonly {
readonly call: TurnCall;
readonly row: ComposedSearchRow;
readonly tool?: DeclaredTool;
}[], clock: string): NegativeStatement;
/** State only the admitted read and all its limits, without asserting completeness. */
export declare function composeRecordedStatement(reads: readonly {
readonly call: TurnCall;
readonly row: ComposedSearchRow;
readonly tool?: DeclaredTool;
}[], clock: string, explanation?: {
/** Authored by the delivery boundary from the check's code, never model text. */
readonly refusal: string;
/** Only caller-scoped local observations admitted by the delivery boundary. */
readonly contraryReads: readonly {
readonly call: TurnCall;
readonly row?: ComposedSearchRow;
readonly tool?: DeclaredTool;
}[];
}): NegativeStatement;
export {};