agentfootprint
Version:
The explainable agent framework — backtrack a wrong answer to the exact context that caused it (evidence, not guesses). Built on footprintjs.
126 lines • 6.84 kB
TypeScript
/**
* The tool calls of THIS run — one `ToolCallFact` each, in call order.
*
* Outcome, from typed fields only (never a `why` prose):
* - `not-dispatched` — `tool_end.notDispatched` (a batch settled on a pause);
* - `declined` — a person was asked and declined: a before-tool deny on
* the call a RESUMED leg answers (its start is in the
* earlier leg), or a `checkin.decision` with
* `approved: false`;
* - `refused` — BEFORE-tool only: `tool_end.notExecuted`, a deny
* `middleware.decision` with `moment: 'before-tool'`, or a
* `permission.check` for this call that did not allow;
* - `failed` — `tool_end.error`;
* - `unknown` — a start with no recorded end;
* - `ran` — otherwise. An AFTER-tool deny keeps `ran` and sets
* `withheldBy`: the tool ran and the model read the
* rule's refusal (`notExecuted` covers before-tool rules
* only, and its absence proves nothing).
*
* Emptiness is read from what the MODEL read — `modelResult ?? result` — and
* never judged on a withheld result. The reader is the ONE emptiness reader
* (`core/agent/emptiness.ts` · `readEmptiness`), handed the door this
* record holds for the call: its absence (the delivered status, `tools.absent`),
* its boundary (`tools.coverage_declared`) and its described envelope
* (`tools.semantics_declared`).
*/
import type { RecordPointer, SentenceVar, ToolCallFact } from '../types.js';
import { type ViewEvent } from '../view.js';
import { type EmptinessReading, type ReadContext } from './common.js';
/**
* At most this many calls are LISTED in `facts.calls`; the rest are counted.
* A cap on what is listed, never on what is judged: the checks, the error
* counts and the withheld count read every call (`CallsRead.all`).
*/
export declare const MAX_CALLS = 50;
export type CoverageSectionKey = 'checked' | 'notChecked' | 'cannotCover';
export interface CoverageItemRead {
readonly section: CoverageSectionKey;
/** The item's words — `''` when the record keeps them out (`keptOut`, below). */
readonly what: string;
readonly short?: string;
readonly kind?: 'existence' | 'scope';
/**
* Present and `true` when the record keeps the item's WORDS out (a
* redaction policy left its placeholder on `what` — under the vocabulary,
* the value-kind rule, `redaction/knownStrings.ts`): the item exists, with
* its `kind`, and a reader says its words are kept out, never prints them.
*/
readonly keptOut?: true;
/**
* Pointer base: the declaration that holds the item — its event
* (`tools.absent` / `tools.coverage_declared`), or, for a call before a
* pause, its row of the committed `coverageDeclared` state.
*/
readonly base: (...keys: readonly (string | number)[]) => RecordPointer;
readonly position: number;
}
export interface CoverageRead {
readonly kind: 'absent' | 'coverage';
/** The declaration's events — empty when it was read from the committed state. */
readonly events: readonly ViewEvent[];
/** Where the declaration's head is: its tool name when the record holds one, else its call id. */
readonly head: RecordPointer;
readonly lookedFor?: {
readonly text: string;
readonly pointer: RecordPointer;
};
/** EVERY declared item — the checks judge them all; the rows print what the item budget allows. */
readonly items: readonly CoverageItemRead[];
readonly tryInsteadTool?: {
readonly tool: string;
readonly pointer: RecordPointer;
};
}
/** One call, as the row readers need it (the fact plus the events behind it). */
export interface CallRead {
readonly fact: ToolCallFact;
readonly start?: ViewEvent;
readonly end?: ViewEvent;
/** The decision or permission row that refused / withheld it. */
readonly ruleEvent?: ViewEvent;
readonly coverage?: CoverageRead;
/** The `tools.semantics_declared` row: the described envelope as the record keeps it. */
readonly described?: ViewEvent;
readonly emptiness: EmptinessReading;
readonly findings?: ViewEvent;
/** Where the tool's NAME is on the record (its start, its declaration, or its history message). */
readonly toolPointer?: RecordPointer;
/** The tool's name as a sentence var — clipped at `FACT_TEXT_CHARS`, pointing at the full name. */
readonly tool: SentenceVar;
/** The full tool name (`''` when unnamed) — for declaration lookups; never printed unclipped. */
readonly toolName: string;
/** No event of the call names its tool — counted as unread, never dropped. */
readonly unnamed?: true;
}
export interface CallsRead {
/** EVERY call of this run, in call order — what the checks and counts judge. */
readonly all: readonly CallRead[];
/** The first `MAX_CALLS` of them — what `facts.calls` lists. */
readonly calls: readonly CallRead[];
/** Calls past `MAX_CALLS`, counted, not listed. */
readonly omitted: number;
/** Ids of every call of this run (listed or not) — the in-view reader skips them. */
readonly ids: ReadonlySet<string>;
}
/** The committed state's coverage key: every declaration the run's tools made, tracked. */
export declare const COVERAGE_STATE_KEY = "coverageDeclared";
/**
* A call's declaration as the committed state keeps it — its rows of
* `coverageDeclared` (tracked state: a limit is a fact about the answer, so it
* rides every recording, `core/agent/types.ts` · `coverageDeclared`).
* What a call BEFORE a pause declared is read here: its events are in the
* earlier leg, its rows are in this record's state.
*/
export declare function readStateCoverage(rows: readonly unknown[], toolCallId: string, served: boolean): CoverageRead | undefined;
/** The permission verdicts that stop a call before it runs. */
export declare const PERMISSION_REFUSALS: ReadonlySet<unknown>;
/** The one leaf on `tool_end` that says how the call ended, as the account read it. */
export declare function endPointer(end: ViewEvent, emptiness: EmptinessReading): RecordPointer;
/** Every call of this run, first-seen order (a resumed leg's paused call has only an end). */
export declare function readCalls(ctx: ReadContext): CallsRead;
/** The declaration's head: its tool name when the row holds one, else the call id it was joined by. */
export declare function coverageHead(coverage: CoverageRead): RecordPointer;
/** Pointer to one coverage item's leaf. */
export declare const itemAt: (item: CoverageItemRead, field: 'what' | 'short' | 'kind') => RecordPointer;
//# sourceMappingURL=calls.d.ts.map