agentfootprint
Version:
The explainable agent framework — backtrack a wrong answer to the exact context that caused it (evidence, not guesses). Built on footprintjs.
69 lines • 3.79 kB
TypeScript
/**
* The manifest bridge — which arm did this run belong to, according to the RUN
* rather than according to the experimenter.
*
* Before 9.41.0 an arm label was bookkeeping: the consumer set a variable to
* `'rerank'`, built an agent it believed re-ranked, and nothing in the library
* could contradict it. `agentfootprint.agent.run_configured` names the adapters
* and strategies a run is about to use, so the belief became checkable — and
* {@link ArmFacets} is deliberately spelled in that event's own vocabulary so
* the check is a field-by-field comparison and not a translation layer.
*
* Two directions, both here:
* - **verify** — `checkArmApplied(arm, manifest)`: the arm said `retrieval:
* 'rerank'`; did the run agree? A contradiction costs the arm its verdict
* (`compare.ts`), because a difference measured between two arms that were
* secretly one configuration is not evidence about either.
* - **classify** — `matchArm(arms, manifest)`: hand it a recorded run's
* manifest and it says which declared arm that run belongs to. This is the
* door for grouping runs a study already made, offline, out of saved
* recordings.
*
* ## Absence is a contradiction, not a wildcard
*
* The manifest's own rule is that an absent field means "not configured", never
* a guessed default. So an arm declaring `window: 'tokenBudget'` against a
* manifest with no `window` is a MISMATCH, reported with `observed` absent. The
* alternative — treating absence as "could be anything" — would let a run with
* no window stage pass as the token-budget arm, which is exactly the mis-wiring
* this file exists to catch.
*/
import type { RunManifestLike } from '../../recorders/observability/recordedManifest.js';
import type { ArmFacetMismatch, ArmFacets, StrategyArm } from './types.js';
/**
* Project a manifest onto the arm-facet vocabulary — the inverse of what an arm
* declares. Memory rows collapse to the FIRST one; a study varying retrieval
* across several mounted memories should declare `memory.id` and read the rows
* itself rather than trust a projection to pick.
*/
export declare function armFacetsFromManifest(manifest: RunManifestLike): ArmFacets;
/**
* A stable label for a set of facets — sorted `key=value`, so two runs of one
* configuration produce the same string whatever order the fields were written
* in. Useful as a grouping key for N recorded runs.
*/
export declare function armLabel(facets: ArmFacets): string;
/**
* Compare one arm's DECLARED facets against a run's manifest. Empty result =
* the run agreed with everything the arm claimed.
*
* Only declared facets are compared. An arm is a claim about the facets it
* names and says nothing about the rest — checking undeclared fields would fail
* every arm for differing from the manifest in ways it never claimed.
*/
export declare function checkArmApplied(arm: StrategyArm, manifest: RunManifestLike): readonly ArmFacetMismatch[];
/**
* Which declared arm does this run belong to? The offline door: group N
* recorded runs into arms by what each run's own manifest says.
*
* Rules, all conservative:
* - only arms that DECLARE facets are candidates (an arm naming nothing matches
* every run and would swallow the whole study);
* - a candidate matches when the manifest contradicts none of its facets;
* - the MOST SPECIFIC match wins (most declared facets), and a tie returns
* `undefined` — two arms fitting one run equally well is an ambiguity, and
* guessing which the experimenter meant is exactly the bookkeeping this
* function replaces.
*/
export declare function matchArm(arms: readonly StrategyArm[], manifest: RunManifestLike): StrategyArm | undefined;
//# sourceMappingURL=manifest.d.ts.map