agentfootprint
Version:
The explainable agent framework — backtrack a wrong answer to the exact context that caused it (evidence, not guesses). Built on footprintjs.
121 lines • 6.1 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.projectStoredCause = void 0;
const boundedJson_js_1 = require("../lib/boundedJson.js");
const causeCapture_js_1 = require("./causeCapture.js");
const causeProjection_js_1 = require("./causeProjection.js");
const storedCauseBinding_js_1 = require("./storedCauseBinding.js");
const storedCauseSources_js_1 = require("./storedCauseSources.js");
function savedNodes(history) {
const nodes = new Map();
const paths = new Map();
const pending = [
{ node: history.executionTree, path: ['executionTree'] },
];
let visited = 0;
while (pending.length) {
const current = pending.pop();
if (!current)
break;
const { node, path } = current;
if (++visited > 4096 || node === null || typeof node !== 'object' || Array.isArray(node))
throw Error('Invalid saved tree.');
for (const field of ['stageReads', 'stageWrites']) {
const view = (0, causeCapture_js_1.captureOwn)(node, field);
if (view !== undefined &&
(view === null ||
typeof view !== 'object' ||
Array.isArray(view) ||
![Object.prototype, null].includes(Object.getPrototypeOf(view))))
throw Error('Invalid saved captured view.');
}
const id = (0, causeCapture_js_1.captureOwn)(node, 'runtimeStageId');
if (id !== undefined) {
if (typeof id !== 'string' || !id.length || id.length > 128 || nodes.has(id))
throw Error('Ambiguous saved tree.');
nodes.set(id, node);
// JSON arrays of literal segments are injective; dotted/slashed business keys stay whole.
paths.set(JSON.stringify(path), id);
}
const next = (0, causeCapture_js_1.captureOwn)(node, 'next');
if (next !== undefined)
pending.push({ node: next, path: [...path, 'next'] });
const children = (0, causeCapture_js_1.captureOwn)(node, 'children');
if (children !== undefined) {
if (!Array.isArray(children) || children.length > 4096)
throw Error('Invalid saved tree.');
for (let index = children.length - 1; index >= 0; index--)
pending.push({ node: children[index], path: [...path, 'children', String(index)] });
}
}
const readKeys = new Map();
// FootPrint already validated the paths and their digest. Only project their recorded meaning.
for (const path of history.absent ?? []) {
const id = paths.get(JSON.stringify(path.slice(0, -2)));
if (id === undefined)
throw Error('Missing saved observation owner.');
if (path[path.length - 2] !== 'stageReads')
continue;
const keys = readKeys.get(id) ?? [];
const key = path[path.length - 1];
if (key === undefined)
throw Error('Missing saved observation key.');
keys.push(key);
readKeys.set(id, keys);
}
return { nodes, readKeys };
}
/** A narrow graph projection over admitted producer history, never a synthetic RuntimeSnapshot. */
function projectStoredCause(value, runId, maxBytes) {
try {
// Reuse the shared data-only copier. Its detached tree/sidecar/log are retained privately together.
const history = (0, boundedJson_js_1.copyJson)(value, maxBytes * 4, true, 256);
if (history.runId !== runId || !Array.isArray(history.commitLog))
return { status: 'unknown', reason: 'native-capture' };
if (history.commitLog.length > 4096)
return { status: 'unknown', reason: 'projection-incomplete' };
const version = (0, causeCapture_js_1.captureOwn)(history.capture, 'version');
if ((version !== 1 && version !== 2) ||
(version === 1 && (0, causeCapture_js_1.captureOwn)(history, 'readSources') !== undefined))
return { status: 'unknown', reason: 'native-capture' };
const sources = version === 2 ? (0, storedCauseSources_js_1.storedCauseSources)(history) : undefined;
if (typeof sources === 'string')
return { status: 'unknown', reason: sources };
const { nodes, readKeys } = savedNodes(history);
// These are facts from this one history; no runtime-only fields or alternate history are synthesized.
const basis = {
runId: history.runId,
capture: history.capture,
logAddress: (0, causeCapture_js_1.captureOwn)(history.capture, 'logAddress'),
commitValues: (0, causeCapture_js_1.captureOwn)((0, causeCapture_js_1.captureOwn)(history.capture, 'modes'), 'commitValues'),
writeProvenance: (0, causeCapture_js_1.captureOwn)((0, causeCapture_js_1.captureOwn)(history.capture, 'modes'), 'writeProvenance'),
commitLog: history.commitLog,
recorders: history.recorders,
};
const projected = (0, causeProjection_js_1.projectCauseBasis)(basis, nodes, undefined, {
readKeys,
...(history.initialState === undefined ? {} : { initialState: history.initialState }),
...(sources === undefined ? {} : { sources }),
});
if (projected === undefined || projected === 'truncated')
return { status: 'unknown', reason: 'projection-incomplete' };
if ([
'missing-attestation',
'invalid-attestation',
'run-mismatch',
'scope-not-covered',
'incomplete-extent',
'capture-limited',
].includes(projected.capture.reason))
return { status: 'unknown', reason: 'native-capture' };
return {
status: 'ready',
cause: (0, storedCauseBinding_js_1.bindStoredCause)(projected.graph, projected.capture, history, version),
};
}
catch {
return { status: 'unknown', reason: 'projection-incomplete' };
}
}
exports.projectStoredCause = projectStoredCause;
//# sourceMappingURL=storedCauseProjection.js.map