UNPKG

agentfootprint

Version:

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

100 lines • 3.88 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.replayAttempts = void 0; const replayHistory_js_1 = require("../thinking/replayHistory.js"); /** * The leaf still chooses whether anything may be omitted. A retry or fallback * must remember that choice before its next attempt, even when the first wire * fails after preparation. Never adopt the whole prepared request: resolved * models, cache hints and other wire-local adjustments belong to that leaf. */ function replayAttempts(request, hooks) { let current = request; const reported = new Map(); function response(answer) { if (reported.size === 0 && !answer.replayOmissions?.length) return answer; const total = new Map(reported); const existing = answer.replayOmissions ?? []; remember(total, existing); const omissions = [...total.values()]; if (omissions.length === existing.length && omissions.every((item, index) => omissionKey(item) === omissionKey(existing[index]))) return answer; return { ...answer, replayOmissions: omissions }; } function chunk(item) { if (!item.done || item.response === undefined) return item; const answer = response(item.response); return answer === item.response ? item : { ...item, response: answer }; } function result(item) { if (item.done) return item; const value = chunk(item.value); return value === item.value ? item : { ...item, value }; } return { get request() { return current; }, /** The reliability loop explicitly owns feedback and other request changes. */ replaceRequest(next) { current = next; }, response, chunk, /** Preserve the underlying iterator's cancellation/throw protocol. */ iterator(inner) { const close = inner.return?.bind(inner); const raise = inner.throw?.bind(inner); return { next: async (...args) => result(await inner.next(...args)), ...(close && { return: async (...args) => result(await close(...args)), }), ...(raise && { throw: async (...args) => result(await raise(...args)), }), }; }, hooks: { ...hooks, onReplayPrepared(preparation) { const messages = (0, replayHistory_js_1.retireReplayHistory)(current.messages, preparation); hooks?.onReplayPrepared?.(preparation); // A failed durable write must be attempted again, not hidden by a // local omission that lets the next leaf bypass that failed hook. if (messages !== current.messages) current = { ...current, messages }; remember(reported, preparation.omissions); }, }, }; } exports.replayAttempts = replayAttempts; /** All declared metadata fields identify one report; no model content is copied. */ function omissionKey(item) { return JSON.stringify([ item.messageIndex, item.blockIndex, item.reason, item.replayId ?? null, item.messageFingerprint, ]); } function remember(target, items) { for (const item of items) { const key = omissionKey(item); if (!target.has(key)) target.set(key, { messageIndex: item.messageIndex, blockIndex: item.blockIndex, reason: item.reason, ...(item.replayId !== undefined && { replayId: item.replayId }), messageFingerprint: item.messageFingerprint, }); } } //# sourceMappingURL=replayAttempt.js.map