UNPKG

agentfootprint

Version:

The explainable agent framework — backtrack a wrong answer to the exact context that caused it (evidence, not guesses). Built on footprintjs.

123 lines • 4.79 kB
/** * The renewal feed — who used which map's contribution this pass. * * Pattern: pure functions over one pass's facts. No state. * Role: the counter the lease machine acts on. An earlier design round * shipped "a parking machine nothing ever tells to park" — this file * is the telling: it joins the previous batch's tool calls, the * cursor move, and the model's own picks to the map that owns them, * and answers with typed renewal evidence. * * The join keys already exist in the run: served tool schemas are tagged by * the contributing injection id, cursor moves carry the clause that won, and * an accepted `read_skill` pick names its skill. Nothing here guesses. */ /** * Classify a cursor-move clause into an evidence strength. Mirrors the skill * map's `CursorMoveCause` vocabulary. * * Two defaults, and the difference matters (9.59.0): * - `'stay'` and `'none'` are NOT MOVES. They answer `assumed`: the cursor is * where it already was and nothing explains why. Staying is exactly what * the recorded stuck turn did 29 times out of 30 — classifying it as * system evidence is how that turn would have been renewed forever. * - Any OTHER unrecognized clause counts as `structural`, unchanged: a future * clause is presumed to be a real routing decision, and there a wrongly * strong reading merely delays a park while a wrongly weak one parks a map * the system itself just routed to. */ export function strengthOfMove(by) { switch (by) { case 'model-pick': return 'explicit'; case 'route': case 'tool-proposal': case 'continuity': return 'structural'; case 'intent': case 'decider': return 'semantic'; case 'entry': return 'lexical'; case 'stay': case 'none': return 'assumed'; default: return 'structural'; } } /** Rank for upgrades: a stronger renewal upgrades a weaker engagement. */ const STRENGTH_RANK = { explicit: 4, structural: 3, semantic: 2, lexical: 1, assumed: 0, }; export function strongerOf(a, b) { return STRENGTH_RANK[a] >= STRENGTH_RANK[b] ? a : b; } /** * A guess decays without corroboration; system- and model-backed standings do * not. `assumed` — nobody said why — decays too: an unknown cause is the * weakest thing on the record, not the strongest. */ export function isTentative(strength) { return strength === 'lexical' || strength === 'semantic' || strength === 'assumed'; } /** * All renewal evidence one map earned this pass. Empty array = no * corroboration (which is a fact the lease machine counts, not an error). */ export function renewalEvidenceOf(map, pass) { const evidence = []; const members = new Set(map.memberIds); const owned = new Set(map.toolNames); for (const r of pass.toolResults) { if (owned.has(r.toolName)) evidence.push({ kind: 'owned-tool-called', toolName: r.toolName }); } // A cursor move BETWEEN this map's nodes (or into it) is the system routing // within the map — its warrant is live. A 'stay' is not a move and earns // nothing: staying is exactly what the stuck turn did 29 times. if (pass.moveBy !== undefined && pass.moveBy !== 'stay' && pass.moveBy !== 'none' && pass.currentNode !== undefined && members.has(pass.currentNode)) { evidence.push({ kind: 'cursor-moved', by: pass.moveBy }); } if (pass.pendingSkillPick !== undefined && members.has(pass.pendingSkillPick)) { evidence.push({ kind: 'explicit-pick', skillId: pass.pendingSkillPick }); } // PER-PASS picks only. The turn-cumulative activation list used to be read // here, which made one pick anywhere disarm the kernel for the rest of the // turn (see `EngagementPass.acceptedSkillPicks`). for (const id of pass.acceptedSkillPicks) { if (members.has(id)) evidence.push({ kind: 'member-activated', skillId: id }); } return evidence; } /** The strength of one piece of evidence. */ export function strengthOfEvidence(e) { switch (e.kind) { case 'explicit-pick': case 'member-activated': return 'explicit'; case 'owned-tool-called': return 'structural'; case 'cursor-moved': return strengthOfMove(e.by); } } /** The strongest strength across a pass's evidence, or undefined when none. */ export function strongestOf(evidence) { let best; for (const e of evidence) { const s = strengthOfEvidence(e); best = best === undefined ? s : strongerOf(best, s); } return best; } //# sourceMappingURL=evidence.js.map