agentfootprint
Version:
The explainable agent framework — backtrack a wrong answer to the exact context that caused it (evidence, not guesses). Built on footprintjs.
55 lines (54 loc) • 2.89 kB
TypeScript
/**
* Earlier answers' tool results that were IN FRONT OF THE MODEL when it
* answered — proven by the record's witness, never by end-of-run state.
*
* The witness rule, in typed terms:
* N = the `iteration` of the LAST `stream.llm_start` before `turn_end` (the
* answering iteration). Context assembly for an iteration PRECEDES its
* `iteration_start`, and `context.injected` carries no iteration of its
* own, so the rule keys on the compose STAGE:
* the witnesses are the `context.injected` rows with `slot: 'messages'`,
* `source: 'tool-result'`, `sourceId: <toolCallId>` whose
* `meta.runtimeStageId` equals that of the `context.slot_composed` with
* `slot: 'messages'` and `iteration: N`.
* The content is parsed from the matching `history` message (by `toolCallId`).
*
* Only EARLIER answers' results: `distance` (messages a PERSON wrote after the
* result, up to and including the current one — `common.ts` · `isPersonEntry`,
* never a frame the library wrote in the user role) must be at least 1, and a call of this run
* is never "in view" — on the flagship recording the answering compose also
* witnesses this run's own `get_array_inventory` result (`events[68]`), which
* must never become an in-view line.
*/
import type { InViewFact, SentenceVar } from '../types.js';
import { type RecordingView, type ViewEvent } from '../view.js';
import { type EmptinessReading, type ReadContext } from './common.js';
/** At most this many in-view results are listed, newest first. */
export declare const MAX_IN_VIEW = 3;
export interface InViewRead {
readonly fact: InViewFact;
/** The full tool name (the fact carries it cut at 200) and its sentence var, clipped and pointed. */
readonly toolName: string;
readonly tool: SentenceVar;
readonly witness: ViewEvent;
readonly historyIndex: number;
readonly reading: EmptinessReading;
}
/** N — the answering iteration. `undefined` when no `llm_start` is recorded. */
export declare function answeringIteration(view: RecordingView): number | undefined;
/** The witness rows of the answering iteration's messages compose. */
export declare function witnessesOf(view: RecordingView, iteration: number | undefined): ViewEvent[];
export interface InViewAll {
/** Every in-view result, newest first — the checks read all of them. */
readonly all: readonly InViewRead[];
readonly listed: readonly InViewRead[];
/** In view but past `MAX_IN_VIEW`. */
readonly more: number;
/**
* Earlier results the record shows were in view (a witness names them) but
* that cannot be read: the record keeps the history out. Their emptiness
* cannot be told, and the account says so (`signals.ts`).
*/
readonly keptOut: number;
}
export declare function readInView(ctx: ReadContext, callIds: ReadonlySet<string>): InViewAll;