agentfootprint
Version:
The explainable agent framework — backtrack a wrong answer to the exact context that caused it (evidence, not guesses). Built on footprintjs.
76 lines • 3.48 kB
JavaScript
;
/**
* innerDescent — the ONE way the toolpack opens a record that sits BELOW the
* run it serves.
*
* Pattern: one-slot memo + param-shaped dispatch + a frame said out loud.
* Role: shared by the two entry points that descend —
* `inspect_tool_run` (the record a chart-as-tool kept of its own run)
* and `inspect_subflow` (a subflow mount's own commit log). Each entry
* point decides only WHAT it opens and how to name it; opening,
* asking and framing happen here, once, so the two descents cannot
* drift into two vocabularies.
*
* WHY THE INNER VIEW IS THE PACK ITSELF. An inner record is a run like any
* other: a commit log, an execution tree, a fold base. So the inner views are
* the pack's own tools, built over the inner artifact bag — there is no second
* implementation of "what did this step write", and the reason codes come out
* of the same basis twins, folded from the INNER record's own `initialState`.
*
* WHY ONE SLOT. Three questions into one inner record build one index; the
* memo pins at most one inner pack beyond what the snapshot already holds.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.framed = exports.askInner = exports.innerPackSlot = void 0;
/**
* One inner pack at a time, memoised by the id it was opened under. `open`
* runs only on a miss, and a refusal (a string) is never memoised — the next
* ask tries again rather than repeating a stale "could not open".
*/
function innerPackSlot(build) {
let memoId;
let memoTools;
return (id, open) => {
if (memoTools !== undefined && memoId === id)
return memoTools;
const artifacts = open();
if (typeof artifacts === 'string')
return artifacts;
memoId = id;
memoTools = build(artifacts);
return memoTools;
};
}
exports.innerPackSlot = innerPackSlot;
/**
* Ask an opened inner pack one question. Param-shaped dispatch (the
* `backtrack({ element })` precedent): the narrowest question asked wins, and
* no params at all is the entry point — the inner `run_overview`. A `key`
* without a step is "who wrote it last in there" (`who_wrote`).
*/
async function askInner(tools, question, call, context) {
const { runtimeStageId, key, variable, find, cause, nodeId } = question;
if (cause !== undefined)
return call(tools, cause, cause === 'attention_list' || nodeId === undefined ? {} : { nodeId }, context);
if (find !== undefined)
return call(tools, 'find_in_trace', { query: find }, context);
if (variable !== undefined)
return call(tools, 'backtrack', { variable }, context);
if (runtimeStageId !== undefined && key !== undefined) {
return call(tools, 'get_value', { runtimeStageId, key }, context);
}
if (runtimeStageId !== undefined)
return call(tools, 'trace_node', { runtimeStageId }, context);
// A key with no step asks who wrote it LAST in there — the writer, its value,
// and the reason codes the basis twins attach.
if (key !== undefined)
return call(tools, 'who_wrote', { key }, context);
return call(tools, 'run_overview', {}, context);
}
exports.askInner = askInner;
/** The answer, inside its frame. */
function framed(frame, body) {
return [frame.header, body, frame.next, frame.namespace].join('\n');
}
exports.framed = framed;
//# sourceMappingURL=innerDescent.js.map