agentfootprint
Version:
The explainable agent framework — backtrack a wrong answer to the exact context that caused it (evidence, not guesses). Built on footprintjs.
82 lines (81 loc) • 5 kB
TypeScript
/** Canonical result vocabulary, shared by live late DATA and legacy replay.
* `offeredResultIds` lists nameable served results newest first; `undeclaredIds`
* reports the absence of a standing in wire order. Neither grants authority.
* Admission separately checks the actual request that produced the response.
* Window eviction and retirement remain the same: noise/ruled-out results
* leave the advisory list, while open/fact results remain revisable.
* `knownResults` resolves declarations without guessing a positional ID.
* All readers use `isResultMessage`, so settlement notices never become results.
*/
import type { LLMMessage } from '../../../provider-contract/types.js';
import { type PreviousResult } from './ledger.js';
import type { FindingsLedger, Standing, StandingRow } from './types.js';
/**
* The standings after which a result leaves the offer: a ticket on the wire
* under every serve mode, a count or one line in the piece — nothing left to
* re-judge. Every other current standing (`fact`, `open`) and no standing at
* all keep the id nameable.
*/
export declare const RETIRING_STANDINGS: readonly Standing[];
/**
* Is this message a tool's RESULT — the only thing a standing can be about?
* A `role: 'tool'` message the batch settlement wrote (9.113.0,
* `LLMMessage.notDispatched`) is not: the call never ran, so there is nothing
* to stand on. Read off the marker, never the sentence — which is why every
* caller hands these functions the COMMITTED conversation, not the wire,
* where `stripFrameworkFields` has already removed the marker (ids and order
* are the same either way).
*/
export declare function isResultMessage(m: LLMMessage): boolean;
/**
* The `role: 'tool'` ids on a message list, in wire order, each once — a
* settled message excluded (`isResultMessage`). A message without an id, or
* with an empty one, contributes nothing. The collapse (`serve.ts ·
* collapseJudged`) never changes an id, so the list is the same before and
* after it.
*/
export declare function servedToolCallIds(messages: readonly LLMMessage[]): readonly string[];
/**
* The served ids no standing names — each once, in the order given, whatever
* the caller repeated. `standingOf` is `foldLedger(rows).standingOf`: a
* standing declared on the ANSWER turn is in it like any other, so it
* removes the id too. The piece's `undeclared:` line; NOT the offer, which
* keeps `fact` and `open` ids (`offeredResultIds`).
*/
export declare function undeclaredIds(served: readonly string[], standingOf: ReadonlyMap<string, StandingRow>): string[];
/**
* The served ids the model may still name — each once, in the order given:
* every id whose current standing is absent or not in `RETIRING_STANDINGS`.
* `standingOf` is `foldLedger(rows).standingOf`, so a `noise` later revised
* to `fact` is nameable again and a `fact` later retired is not.
*/
export declare function nameableIds(served: readonly string[], standingOf: ReadonlyMap<string, StandingRow>): string[];
/**
* THE OFFER: the ids of the `role: 'tool'` messages on `messages` whose
* current standing on `rows` is absent, `fact` or `open`, NEWEST FIRST (the
* reverse of wire order), each once. `rows` may be absent (no declaration
* yet): every served result is then offered. Pure — safe on a deep-frozen
* history and a spread of the committed ledger. Uncapped here; the cap and
* its omission count belong to the late DATA (`context.ts`).
*/
export declare function offeredResultIds(messages: readonly LLMMessage[], rows: FindingsLedger | undefined): readonly string[];
/**
* THE IDENTITY SOURCE a standing resolves against (`ledger.ts ·
* standingRowsFrom`): the previous batch first (`AgentState.toolResults` —
* what landed this iteration, `result` verbatim), then every `role: 'tool'`
* message on the served history read as a result (`content` is the string
* the tool-calls stage appended — a placed result's ticket included, so
* `artifact:<ref>` still resolves), each id once, first entry winning. Run-
* scoped by construction: the history is the offer's own universe
* (`offeredResultIds` reads the same list), so an id copied from the offer —
* this batch's or an earlier one's — resolves to its tool name. The batch is
* read first because it is the stage's own record of what landed this
* iteration (the same string under the same id the history carries, so the
* order changes no row; it is the source the rows resolved against before
* the history joined). An id in neither is `unknownId`, as written. A tool
* message with no `toolName` yields a result with none: nothing is invented
* for it. A settled message (`isResultMessage`) is no result, so a model that
* names its id anyway files `unknownId` — the batch never holds one: a
* settled call never joins `toolResults`.
*/
export declare function knownResults(messages: readonly LLMMessage[], previousBatch?: readonly PreviousResult[]): readonly PreviousResult[];