agentfootprint
Version:
The explainable agent framework — backtrack a wrong answer to the exact context that caused it (evidence, not guesses). Built on footprintjs.
53 lines (52 loc) • 2.99 kB
TypeScript
/**
* The park card — what the MODEL is told when a map is parked.
*
* Pattern: pure function over plain data. No I/O, no scope, no engine.
* Role: the kernel's model-visible surface. Everything else the kernel
* produces lands on the RECORD (skip reasons, `map.parked` events),
* which a human reads afterwards. The model reads none of it.
*
* ── The defect this exists for (9.59.0) ──────────────────────────────────
* Parking was invisible on the wire, and on the default posture it was worse
* than invisible — it was CONTRADICTED. `.maps()` documents that parking stops
* "the prompt fragment AND tools"; with `scopeTools` false (the default for
* flat graphs) only the fragment stopped, and every one of the
* parked map's tool schemas kept riding. So the model saw four tools it was
* being invited to call, belonging to a skill whose instructions had silently
* vanished, with nothing anywhere saying why or how to get them back.
*
* A door the model cannot see is not a door. Re-engagement was reachable in
* principle and unreachable in practice, because nothing told the model that
* re-picking a skill it appears to already be in means anything at all.
*
* ── What the card says, and why each part is there ───────────────────────
* CURSOR and ENGAGEMENT are printed as SEPARATE fields. That is the whole
* teaching move: the model is shown the distinction rather than left to infer
* a contradiction from a skill that is both "where I am" and "not talking".
* Then the REASON, so the state is not arbitrary. Then the WAY BACK, named as
* a concrete call, with the one sentence that stops it being read as a cursor
* move: it changes engagement, not position.
*
* Kept to a few lines on purpose. This rides every call while a map is parked,
* and a verbose status block would spend the tokens parking just saved.
*/
import type { EngagementPlan, MapEngagement } from './types.js';
/**
* Render the model-visible card for a set of parked maps.
*
* Returns `undefined` when nothing is parked — the caller then adds nothing to
* the prompt at all, which keeps the unparked path byte-identical.
*
* `mayName` is the caller's role filter (`isHiddenSkill`, negated): a member
* skill the role may not read is never named, and a parked map with no member
* left to name gets no card line at all (may omit, never deny).
*/
export declare function parkCard(plan: EngagementPlan, engagement: MapEngagement | undefined, mayName?: (skillId: string) => boolean): string | undefined;
/**
* The injection id the card is served under.
*
* A stable, reserved id so the card is one identifiable row on the record
* (composition, budget, the context ledger) rather than an anonymous string
* appended to somebody else's fragment.
*/
export declare const PARK_CARD_ID = "agentfootprint:map-status";