agentfootprint
Version:
The explainable agent framework — backtrack a wrong answer to the exact context that caused it (evidence, not guesses). Built on footprintjs.
130 lines • 5.61 kB
JavaScript
/**
* search/door — which result door a search tool's value came through, and the
* facts composition reads off it.
*
* Pattern: one pure reader over the three doors a tool returns through —
* `absent()`, `coverage()`, `describedResult()` — by their own
* recognizers. No fourth door.
* Role: semantics/ layer, pure.
* Emits: N/A.
*
* A search tool's coverage comes from its declaration, so a result that ALSO
* hand-writes a `checked` list is declined (`checked-beside-declared`): the
* library reads it as written, files today's row, and composes nothing — a
* row it did not compose establishes nothing. A `coverage()` wrapped around
* `absent({ checked: 'declared' })` is refused: the declaration is the
* boundary, so the absence is returned on its own.
*/
import { readSemantics } from '../../envelope.js';
import { readItemExtras } from '../items.js';
import { readPeriod, unservedPeriod } from '../period.js';
import { readAbsence, readCoverageLedger, readDeclaredAbsence, readDeclaredLedger, } from '../recognize.js';
import { refusal } from '../refusal.js';
import { valueText } from './facets.js';
import { readPaging, readResolved, } from './resultFacts.js';
const nonEmpty = (list) => Array.isArray(list) && list.length > 0;
/** A hand-written list, read as found: every entry kept (a gap is never lost). */
function handList(list, section, toolName) {
if (!Array.isArray(list))
return [];
return list.map((raw) => {
const rec = raw;
const what = typeof rec?.what === 'string' && rec.what.trim() !== '' ? rec.what : valueText(raw);
return {
what,
...(typeof rec?.why === 'string' && rec.why.trim() !== '' && { why: rec.why }),
...readItemExtras(raw, section, toolName),
};
});
}
function periodOf(wire) {
return readPeriod(unservedPeriod(wire)).period;
}
function semanticRows(sem) {
return (sem.facts?.length ?? 0) + (sem.series?.length ?? 0) + (sem.edges?.length ?? 0);
}
/** A `coverage()` around `absent({ checked: 'declared' })` declares a second boundary. */
function refuseWrappedAbsence(result) {
if (readDeclaredAbsence(result) === undefined)
return;
throw refusal("absent({ checked: 'declared' }) is returned on its own — the tool's `search` is its " +
'boundary, so a coverage() around it would declare a second one.');
}
/**
* Read `value` as one of the three doors, or `undefined` when it is none of
* them (plain data: nothing is composed).
*/
export function readSearchDoor(value, toolName) {
const declared = readDeclaredAbsence(value);
if (declared !== undefined) {
return {
outcome: 'door',
facts: {
door: 'declared-absence',
rows: 0,
resolved: readResolved(declared.resolved),
paging: readPaging(declared.paging),
period: periodOf(declared.period),
handNotChecked: handList(declared.not_checked, 'notChecked', toolName),
handCannotCover: handList(declared.cannot_cover, 'cannotCover', toolName),
absence: declared,
},
};
}
if (readAbsence(value) !== undefined)
return { outcome: 'checked-beside-declared' };
const sem = readSemantics(value);
if (sem !== undefined) {
if (nonEmpty(sem.coverage?.checked))
return { outcome: 'checked-beside-declared' };
return {
outcome: 'door',
facts: {
door: 'described',
rows: semanticRows(sem),
resolved: readResolved(sem.resolved),
paging: readPaging(sem.paging),
period: periodOf(sem.period),
handNotChecked: handList(sem.coverage?.not_checked, 'notChecked', toolName),
handCannotCover: handList(sem.coverage?.cannot_cover, 'cannotCover', toolName),
},
};
}
const declaredLedger = readDeclaredLedger(value);
if (declaredLedger !== undefined) {
refuseWrappedAbsence(declaredLedger.result);
if (readAbsence(declaredLedger.result) !== undefined) {
return { outcome: 'checked-beside-declared' };
}
const marker = declaredLedger.af_coverage;
return {
outcome: 'door',
facts: {
door: 'declared-coverage',
rows: Array.isArray(declaredLedger.result) ? declaredLedger.result.length : undefined,
period: periodOf(marker.period),
handNotChecked: handList(marker.not_checked, 'notChecked', toolName),
handCannotCover: handList(marker.cannot_cover, 'cannotCover', toolName),
ledger: declaredLedger,
},
};
}
const covered = readCoverageLedger(value);
if (covered === undefined)
return undefined;
refuseWrappedAbsence(covered.result);
if (nonEmpty(covered.af_coverage.checked) || readAbsence(covered.result) !== undefined) {
return { outcome: 'checked-beside-declared' };
}
return {
outcome: 'door',
facts: {
door: 'coverage',
rows: Array.isArray(covered.result) ? covered.result.length : undefined,
period: periodOf(covered.af_coverage.period),
handNotChecked: handList(covered.af_coverage.not_checked, 'notChecked', toolName),
handCannotCover: handList(covered.af_coverage.cannot_cover, 'cannotCover', toolName),
},
};
}
//# sourceMappingURL=door.js.map