UNPKG

agentfootprint

Version:

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

56 lines • 2.43 kB
import { canonicalJson } from '../lib/canonicalJson.js'; import { sha256Hex } from '../lib/sha256.js'; /** Narrow a transport report before a checkpoint owner retains it. */ export function replayRetirements(preparation) { const seen = new Set(); return preparation.omissions.flatMap((omission) => { if (seen.has(omission.messageIndex)) return []; seen.add(omission.messageIndex); const replacement = preparation.request.messages[omission.messageIndex]; if (replacement === undefined) throw new Error('Replay omission has no matching prepared message.'); return [ { ...(omission.replayId !== undefined && { replayId: omission.replayId }), messageFingerprint: omission.messageFingerprint, thinkingBlocks: replacement.thinkingBlocks, ...(replacement.replay !== undefined && { replay: replacement.replay }), }, ]; }); } /** A local matching key, not a signature validator or public authentication. */ export function replayMessageFingerprint(message) { return sha256Hex(canonicalJson({ role: message.role, content: message.content, toolCalls: message.toolCalls, thinkingBlocks: message.thinkingBlocks, })); } /** Apply only reported thinking omissions, retaining all host-owned metadata. */ export function retireReplayHistory(history, preparation) { return applyReplayRetirements(history, replayRetirements(preparation)); } /** One identity rule for live history, retries and both checkpoint doors. */ export function applyReplayRetirements(history, retirements) { if (retirements.length === 0) return history; let changed = false; const next = history.map((message) => { const omission = retirements.find((item) => item.replayId !== undefined ? message.replay?.id === item.replayId : !message.replay?.id && replayMessageFingerprint(message) === item.messageFingerprint); if (omission === undefined || !message.thinkingBlocks?.length) return message; changed = true; return { ...message, thinkingBlocks: omission.thinkingBlocks, ...(omission.replay !== undefined && { replay: omission.replay }), }; }); return changed ? next : history; } //# sourceMappingURL=replayHistory.js.map