agentfootprint
Version:
The explainable agent framework — backtrack a wrong answer to the exact context that caused it (evidence, not guesses). Built on footprintjs.
139 lines (138 loc) • 5.79 kB
TypeScript
/**
* toBacktrackTrace — serialize a ContextBugReport into the BacktrackTrace
* shape that agentThinkingUI's <BacktrackView>/<BacktrackOverlay> renders
* (the "why?" board: suspects → influence meters → ablation stamps →
* chain-of-custody rewind).
*
* Pure mapping, no UI dependency — the BacktrackTrace interfaces below
* MIRROR agentthinkingui's `types/index.d.ts` contract; both sides are
* framework-agnostic JSON. The report carries everything except two
* things only the caller knows:
*
* - `answer` (REQUIRED): the report localizes a decision but does not
* hold the decision's output text — pass what the agent said/chose.
* - `custody` (optional): the rewind player replays RECORDED STATE
* (the assembled prompt, the mutating commit). That content lives in
* the caller's artifacts (snapshot/events), not in the report — pass
* a callback to enrich confirmed suspects with evidence panes.
*
* Honesty is preserved, not added: ranks are TRUE report positions even
* when the cards are a subset (`rank`), path-only scores carry
* `upperBound` (hatched meter + starred value in the UI), honesty flags
* map verbatim, and the claims-discipline lines ride along. The mapper
* never invents a causal claim: `verdict` exists only where the report's
* ablation produced one ('inconclusive' maps to NO stamp, not a verdict).
*/
import type { ContextBugReport, Suspect } from './types.js';
export interface BacktrackCustodyHop {
readonly step: string;
readonly detail: string;
readonly at?: string;
readonly variable?: string;
/** recorded state at this hop — prompt text, commit payload, code, rule operands */
readonly content?: string;
/** exact substring of `content` highlighted as the culprit span */
readonly highlight?: string;
}
export interface BacktrackHop {
readonly key: string;
readonly kind?: 'data' | 'control';
readonly via?: string;
}
export interface BacktrackSuspectCard {
readonly kind: string;
readonly flavor?: string;
readonly name: string;
readonly text?: string;
readonly score: number;
/** true position in the report's ranking (cards may be a subset) */
readonly rank: number;
/** score is a path-only upper bound — no content signal */
readonly upperBound?: boolean;
/** the hop adjacent to the suspect (what fed the decision side) */
readonly edge?: {
readonly key?: string;
readonly weight?: number;
readonly kind?: 'data' | 'control';
};
/** the full hop chain, decision → suspect (multi-hop paths only) */
readonly path?: readonly BacktrackHop[];
readonly bornAt?: {
readonly id: string;
readonly label?: string;
readonly via?: string;
};
readonly custody?: readonly BacktrackCustodyHop[];
readonly verdict?: {
readonly kind: 'confirmed' | 'not-confirmed';
readonly flips?: number;
readonly samples?: number;
readonly claim?: string;
};
}
export interface BacktrackTrail {
readonly title?: string;
readonly custody?: readonly BacktrackCustodyHop[];
readonly claim?: string;
}
export interface BacktrackTrace {
readonly claim: string;
readonly mode: 'causal' | 'correlational';
readonly modeLabel?: string;
readonly agent?: string;
readonly model?: string;
readonly answer: {
readonly text: string;
readonly label?: string;
readonly tone?: 'error' | 'question';
};
readonly decidedAt: {
readonly id: string;
readonly label?: string;
readonly kind?: 'llm' | 'rule';
};
readonly suspects: readonly BacktrackSuspectCard[];
readonly trail?: BacktrackTrail;
readonly folded?: string;
readonly scoreNote?: string;
readonly baseline?: string;
readonly honesty?: readonly string[];
}
export interface ToBacktrackTraceOptions {
/** The decision's output text — the report doesn't hold it. */
readonly answer: {
readonly text: string;
readonly label?: string;
readonly tone?: 'error' | 'question';
};
/** Headline question. Default: derived from the trigger step. */
readonly claim?: string;
/** 'rule' renders the decision diamond instead of the brain. Default 'llm'. */
readonly decidedAtKind?: 'llm' | 'rule';
/** Override the mode chip (e.g. "exact chain · proxy ranking"). */
readonly modeLabel?: string;
readonly agent?: string;
readonly model?: string;
/** Max suspect cards. Default 6. The rest fold into one disclosed line. */
readonly maxSuspects?: number;
/**
* Card selection when the report has more suspects than `maxSuspects`.
* Default TRUE: content-evidence suspects fill the cards first (they are
* what a human can act on), structural path-only hops fold — but every
* card keeps its TRUE report rank, and the folded line discloses what
* was left out and that it ranked where it ranked. FALSE: strictly the
* report's top-N.
*/
readonly preferContentEvidence?: boolean;
/** Enrich a suspect's chain of custody with recorded-state panes. */
readonly custody?: (suspect: Suspect, trueRank: number) => readonly BacktrackCustodyHop[] | undefined;
/** Exact recorded hops for deterministic decisions (no ablation verdict). */
readonly trail?: BacktrackTrail;
/** Override the auto score note (top-2 margin tie warning). */
readonly scoreNote?: string;
}
/**
* Serialize a localizer report for agentThinkingUI's BacktrackView.
* See module doc — `answer` is required; `custody` enriches the rewind.
*/
export declare function toBacktrackTrace(report: ContextBugReport, opts: ToBacktrackTraceOptions): BacktrackTrace;