agentfootprint
Version:
The explainable agent framework — backtrack a wrong answer to the exact context that caused it (evidence, not guesses). Built on footprintjs.
69 lines • 3.13 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.replayPreparedHook = void 0;
const replayHistory_js_1 = require("../../thinking/replayHistory.js");
const conventions_js_1 = require("../../lib/conventions.js");
const typedEmit_js_1 = require("./typedEmit.js");
function isHistory(value) {
return (Array.isArray(value) &&
value.every((m) => typeof m === 'object' &&
m !== null &&
'role' in m &&
'content' in m &&
typeof m.content === 'string'));
}
/** Create once per call. Retry/fallback reports append, never overwrite. */
function replayPreparedHook(scope, receiptMinted, onPersisted) {
return (preparation) => {
if (preparation.omissions.length === 0)
return;
const history = scope.$getValue?.('history');
if (isHistory(history)) {
const retired = (0, replayHistory_js_1.retireReplayHistory)(history, preparation);
if (retired !== history) {
if (scope.$setValue === undefined)
throw new Error('Replay retirement requires writable history.');
scope.$setValue('history', retired);
}
}
// The checkpoint owner sees a successfully persisted history edit before
// optional receipt/observation work. A failed grouped stage cannot map
// this write outward, including if receipt annotation itself fails.
onPersisted?.(preparation);
// This flag is set by the mint's call site, never inferred from an old
// receipt inherited by a resumed or receipt-disabled run.
if (receiptMinted && scope.$getValue !== undefined && scope.$setValue !== undefined) {
const held = scope.$getValue(conventions_js_1.RECEIPT_KEY);
if (held !== undefined)
scope.$setValue(conventions_js_1.RECEIPT_KEY, {
...held,
replayPreparations: [
...(held.replayPreparations ?? []),
{
boundary: 'provider-adapter',
phase: 'prepared',
omittedBlocks: preparation.omissions.length,
},
],
});
}
for (const omission of preparation.omissions) {
try {
(0, typedEmit_js_1.typedEmit)(scope, 'agentfootprint.agent.thinking_omitted', {
providerName: preparation.provider,
model: preparation.model,
messageIndex: omission.messageIndex,
blockIndex: omission.blockIndex,
reason: omission.reason,
phase: 'prepared',
});
}
catch {
// A broken telemetry sink cannot turn already-preserved state into
// a failed model call. The retirement above is outside this catch.
}
}
};
}
exports.replayPreparedHook = replayPreparedHook;
//# sourceMappingURL=replayHooks.js.map