UNPKG

agentfootprint

Version:

The explainable agent framework — backtrack a wrong answer to the exact context that caused it (evidence, not guesses). Built on footprintjs.

94 lines • 4.43 kB
"use strict"; /** * findings/peel — the answer's `_findings` peel and the stream's filter, in * the ONE module an unarmed agent never loads. * * Both run `answerText.ts`'s scanner, which only `.findings()` agents use. * The stages that need it (`callLLM`, `route`) load this module through * `import()` when the arm is on — the optional-family law of docs-next's site * budget, the same as `judge.ts` and `toolChoice/compose.ts` — so a plain * agent's bundle carries none of it. Keep every static import of * `answerText.ts` inside this file and `answerText.ts` itself; * test/core/agent/findings/peel-lazy.test.ts pins that. */ Object.defineProperty(exports, "__esModule", { value: true }); exports.peelAnswerFindings = exports.withoutReservedMembers = exports.reservedMemberFilter = void 0; const types_js_1 = require("./types.js"); const reserved_js_1 = require("./reserved.js"); const answerText_js_1 = require("./answerText.js"); var answerText_js_2 = require("./answerText.js"); Object.defineProperty(exports, "reservedMemberFilter", { enumerable: true, get: function () { return answerText_js_2.reservedMemberFilter; } }); Object.defineProperty(exports, "withoutReservedMembers", { enumerable: true, get: function () { return answerText_js_2.withoutReservedMembers; } }); /** * Take the answer's `_findings` off, wherever the answer's TEXT carries it * (9.114.2; `answerText.ts` is the rule, shared with the stream). Every JSON * object in the answer that is not inside another object — the whole answer, * a code block holding one, one written in the prose — loses its own * `_findings` member and the separator that joined it, and nothing else moves: * the model's layout and the prose around it stay as written. Identity when * nothing was removed. * * The removed values are the answer's declaration: per object the LAST one * (JSON's own rule for a repeated key — what a whole-answer `JSON.parse` read * before 9.114.2), across objects in text order, their `previous` lists * joined. A value that is not JSON, or that a cut-off text left unfinished, is * dropped and counted (`malformed`), never guessed at. */ function peelAnswerFindings(raw, options) { if (typeof raw !== 'string') return { content: raw }; const { text, removed } = (0, answerText_js_1.withoutReservedMembers)(raw, types_js_1.RESERVED_ANSWER_KEY); if (removed.length === 0) return { content: raw }; const lastPerObject = new Map(); for (const member of removed) lastPerObject.set(member.object, member); let findings; let malformed = 0; let attempted = ''; let attemptedTruncated = false; for (const member of lastPerObject.values()) { const read = readRemovedValue(member); malformed += read.malformed; if (options?.captureMalformed === true && read.malformed > 0) { const remaining = 8192 - attempted.length; if (member.valueText.length > remaining) attemptedTruncated = true; if (remaining > 0) attempted += member.valueText.slice(0, remaining); } if (read.declaration !== undefined) findings = joinDeclarations(findings, read.declaration); } return { content: text, ...(findings !== undefined && { findings }), ...(malformed > 0 && { malformed }), ...(attempted.length > 0 && { attemptedMalformed: attempted }), ...(attemptedTruncated && { attemptedTruncated: true }), }; } exports.peelAnswerFindings = peelAnswerFindings; /** One removed value, read as a declaration — or counted, when it cannot be read. */ function readRemovedValue(member) { if (!member.complete) return { malformed: 1 }; let value; try { value = JSON.parse(member.valueText); } catch { return { malformed: 1 }; } return (0, reserved_js_1.readDeclaration)(value); } /** Two objects' declarations as one: later fields win, `previous` lists join in text order. */ function joinDeclarations(earlier, later) { if (earlier === undefined) return later; const previous = earlier.previous === undefined && later.previous === undefined ? undefined : [...(earlier.previous ?? []), ...(later.previous ?? [])]; return { ...earlier, ...later, ...(previous !== undefined && { previous }) }; } //# sourceMappingURL=peel.js.map