UNPKG

agentfootprint

Version:

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

110 lines • 4.79 kB
/** * runbook/walk — the recorded walk: projection law, counters, mint. * * Pattern: pure projection (`projectWalk`) + one guarded side effect * (`mintWalk`, which files the artifact and NEVER fails the answer). * Role: core/runbook. The walk is not a debugging extra — a procedure that * cannot show how it reached a verdict is a procedure somebody has * to take on trust. * Emits: nothing (the artifact capability emits its own `artifacts.*`). * * THE CAP LAW, and why a head slice is the wrong cap: in a chart walk the * per-key reads and writes come FIRST and the decisions come LAST, so a * naive head slice over a fleet sweep keeps four hundred writes and drops * every decision — a walk with the walking taken out. When the whole thing * does not fit, the CONTROL FLOW survives (stages, forks, subflows, and * every `condition` entry carrying its decide() evidence) and the projection * is DECLARED, so a reader knows which of the two they are holding. */ import { CHART_WALK_ARTIFACT_KIND, chartWalkPutInput } from '../../artifacts/recordingArtifact.js'; /** The default row cap — a readable artifact, not an archive. The count is * always reported, so a truncated walk says it is truncated instead of * looking like a short run. */ export const DEFAULT_WALK_CAP = 500; function toWalkRow(entry, step) { return { step, type: entry.type, depth: entry.depth, stage: entry.stageName ?? null, stage_id: entry.stageId ?? null, runtime_stage_id: entry.runtimeStageId ?? null, subflow: entry.subflowId ?? null, text: entry.text, }; } /** Apply the cap law. Counters are about the WHOLE narrative (`total`), so a * projected walk cannot read as a short run. */ export function projectWalk(entries, cap) { const full = entries.length <= cap; const projection = full ? 'full' : 'control-flow'; const chosen = full ? entries : entries.filter((entry) => entry.type !== 'step'); const rows = chosen.slice(0, cap).map(toWalkRow); return { rows, projection, shown: rows.length, total: entries.length, complete: rows.length === entries.length, }; } /** The descriptor's standing sentence, plus the projection clause when the * control flow is what survived. */ function walkNote(projection) { return ("The chart's own walk, one row per execution step. The `condition` rows carry the " + 'rule that matched, the values it compared and the branch it chose — that is where a ' + 'verdict can be checked rather than taken on trust.' + (projection === 'control-flow' ? ' This one is the CONTROL-FLOW projection: the walk did not fit, so the stages, ' + 'forks, subflows and decisions are here and the per-key reads and writes are not.' : '')); } /** * File the walk and build the descriptor. THE SPINE ALWAYS GETS A * DESCRIPTOR: with no store attached, or when the mint fails, the counters * still travel and the note names why there is no ticket — a failed mint * costs the TICKET, never the answer and never the counts. */ export async function mintWalk(ctx, projected, facts) { const base = { rows: projected.rows.length, steps_executed: facts.stepsExecuted, projection: projected.projection, shown: projected.shown, total: projected.total, complete: projected.complete, walk_segment: 'full', }; if (!ctx.hasArtifacts || projected.rows.length === 0) { return { ...base, note: projected.rows.length === 0 ? 'The run produced no narrative entries, so there was no walk to file.' : walkNote(projected.projection) + ' No artifact store is attached to this run, so the walk was recorded but not ' + 'filed — the counters above are still the truth about it.', }; } try { const meta = await ctx.artifacts.put(chartWalkPutInput([...projected.rows], { toolName: facts.toolName, toolCallId: facts.toolCallId, ...(facts.runId !== undefined && { runId: facts.runId }), })); return { ref: meta.ref, kind: CHART_WALK_ARTIFACT_KIND, ...base, note: walkNote(projected.projection), }; } catch (err) { return { ...base, note: walkNote(projected.projection) + ` The walk could not be filed (${err instanceof Error ? err.message : String(err)}) — ` + 'the mint failure cost the ticket, never the answer.', }; } } //# sourceMappingURL=walk.js.map