agentfootprint
Version:
The explainable agent framework — backtrack a wrong answer to the exact context that caused it (evidence, not guesses). Built on footprintjs.
124 lines • 5.52 kB
JavaScript
;
/**
* search/compose — ONE call's coverage, composed by the library from the
* tool's `search` declaration and the arguments the call ran with.
*
* Pattern: linear composition of small pure rules —
* door (what came back) → inEffect (each argument) → facets
* (`checked`) → gaps → complete → the reading the funnel files.
* Role: semantics/ layer, pure. Called by the dispatch funnel
* (`../../../core/agent/stages/searchCoverage.ts` · `buildSearchCoverage`) at
* every execute boundary, before `declareCoverage`.
* Emits: N/A (the funnel emits, from the reading).
*
* ## Composition can only under-claim — relative to a TRUE declaration
*
* A declaration that misdescribes the query (an undeclared qualifier, a wrong
* `complete`) is the trusted base, said out loud: the law holds relative to
* it, never to the backend.
*
* A facet enters `checked` from exactly four places — a value the call sent, a
* declared default composed as if sent, a declared fixed qualifier, the
* declared (or sent) source — plus a host-filled identity filter (which only
* narrows) and a result-declared period (which only narrows). Every
* classified argument none of them covers is a bearing gap; a cap in effect,
* a declared server cap, a page, a `partial` outcome is a completeness gap
* unless the result says otherwise. So the composed scope is never wider than
* what the declaration and the arguments say. A wrong declaration is the
* trusted base, said out loud.
*
* ## Local and remote
*
* A `search` that arrived over MCP or from a `ToolProvider` composes the same
* shape, marked `'remote'`, and is never `complete`: it establishes nothing.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.composeSearchCoverage = void 0;
const read_js_1 = require("../read.js");
const door_js_1 = require("./door.js");
const facets_js_1 = require("./facets.js");
const gaps_js_1 = require("./gaps.js");
const inEffect_js_1 = require("./inEffect.js");
const served_js_1 = require("./served.js");
/** The facts the reader files for a door, before composition overrides its lists. */
function baseFacts(served, door, toolName) {
const read = (0, read_js_1.readCoverageResult)(served, toolName)?.declared[0];
if (read !== undefined)
return read;
return {
kind: door.door === 'declared-absence' ? 'absence' : 'ledger',
coverage: { checked: [], notChecked: [], cannotCover: [] },
...(door.period !== undefined && { period: door.period }),
};
}
/**
* Compose one call's coverage from its search, or `undefined` when the value
* came through no door (plain data: nothing is composed, nothing changes).
* THROWS a refusal (`refused: …`) for a `coverage()` wrapped around a
* declared absence — at the execute boundary, that is the call's error.
*
* @example
* ```ts
* const out = composeSearchCoverage(call, absent({ what: 'x', checked: 'declared' }));
* out?.outcome === 'composed' && out.reading.declared[0]?.composed?.complete;
* ```
*/
function composeSearchCoverage(call, result) {
const door = (0, door_js_1.readSearchDoor)(result, call.toolName);
if (door === undefined)
return undefined;
if (door.outcome === 'checked-beside-declared') {
return { outcome: 'declined', code: 'checked-beside-declared' };
}
const facts = door.facts;
const readings = call.search.arguments.map((arg) => [arg, (0, inEffect_js_1.readArgument)(arg, call.args, call.hostFilled)]);
const checked = (0, facets_js_1.composeChecked)({
search: call.search,
readings,
...(facts.resolved !== undefined && { resolved: facts.resolved }),
...(facts.period !== undefined && { resultPeriod: facts.period }),
...(call.period !== undefined && { period: call.period }),
...(call.dispatchedAt !== undefined && { dispatchedAt: call.dispatchedAt }),
});
const { gaps, notChecked, cannotCover } = (0, gaps_js_1.composeGaps)({
search: call.search,
readings,
rows: facts.rows,
...(facts.paging !== undefined && { paging: facts.paging }),
...(facts.period !== undefined && { period: facts.period }),
...(call.status !== undefined && { status: call.status }),
handNotChecked: facts.handNotChecked,
handCannotCover: facts.handCannotCover,
});
const complete = call.origin === 'local' &&
call.search.complete === 'within-arguments' &&
!gaps.some(gaps_js_1.blocksComplete);
const lists = { notChecked, cannotCover };
const value = facts.absence !== undefined
? (0, served_js_1.servedAbsence)(facts.absence, checked, lists)
: facts.ledger !== undefined
? (0, served_js_1.servedLedger)(facts.ledger, checked, lists)
: result;
const base = baseFacts(value, facts, call.toolName);
const composedFacts = {
...base,
coverage: { checked, notChecked, cannotCover },
composed: {
origin: call.origin,
resultId: call.resultId,
handle: call.handle,
complete,
gaps,
},
};
return {
outcome: 'composed',
value,
reading: {
...(facts.door === 'declared-absence' && { status: 'absent' }),
declared: [composedFacts],
},
};
}
exports.composeSearchCoverage = composeSearchCoverage;
//# sourceMappingURL=compose.js.map