UNPKG

agentfootprint

Version:

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

152 lines • 7.86 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.evidenceSnapshot = exports.finalizeEvidence = exports.captureReturnedEvidence = exports.captureDispatch = exports.readResultIdentity = exports.resultIdentityOf = void 0; /** * Internal dispatch/return/delivery receipt boundary, not mounted in the Agent. * The eventual runtime adapter reserves a namespace/run/ordinal before await, * captures at actual execute, then finalizes against the authorized served value. */ const encode_js_1 = require("../../memory/identity/encode.js"); const boundedJson_js_1 = require("../../lib/boundedJson.js"); const canonicalJson_js_1 = require("../../lib/canonicalJson.js"); const envelope_js_1 = require("../../semantics/envelope.js"); const ledger_js_1 = require("../unsupported-claim/ledger.js"); const scope_js_1 = require("./scope.js"); function resultIdentityOf(identity) { if (!(0, scope_js_1.boundedText)(identity.namespace) || !(0, scope_js_1.boundedText)(identity.runId) || !Number.isSafeInteger(identity.ordinal) || identity.ordinal < 1) throw new Error('Invalid runtime result identity.'); return `claim-result/${(0, encode_js_1.encodeIdentityField)(identity.namespace)}/${(0, encode_js_1.encodeIdentityField)(identity.runId)}/${identity.ordinal}`; } exports.resultIdentityOf = resultIdentityOf; /** Decode only canonical runtime result occurrences; no lookup or authority is inferred. */ function readResultIdentity(raw) { if (typeof raw !== 'string' || raw.length > scope_js_1.BINDING_LIMITS.resultIdText) throw new TypeError('Invalid saved result identity.'); const parts = raw.split('/'); if (parts.length !== 4 || parts[0] !== 'claim-result') throw new TypeError('Invalid saved result identity.'); const identity = Object.freeze({ namespace: (0, encode_js_1.decodePresentIdentityField)(parts[1]), runId: (0, encode_js_1.decodePresentIdentityField)(parts[2]), ordinal: Number(parts[3]), }); if (resultIdentityOf(identity) !== raw) throw new TypeError('Noncanonical saved result identity.'); return identity; } exports.readResultIdentity = readResultIdentity; /** Capture selected scope now; a later mutation of args cannot change it. */ function captureDispatch(identity, tool, executedArgs, declaration) { declaration = (0, scope_js_1.scopeDeclarationOf)(declaration); const id = resultIdentityOf(identity); if (!(0, scope_js_1.boundedText)(tool.toolName) || !(0, scope_js_1.boundedText)(tool.toolCallId) || !Number.isSafeInteger(tool.iteration) || tool.iteration < 0) throw new Error('Invalid tool identity.'); const common = { identity: { ...identity }, id, toolName: tool.toolName, toolCallId: tool.toolCallId, iteration: tool.iteration, scopeDeclaration: { id: declaration.id, version: declaration.version }, ...(declaration.periodDimension !== undefined && { periodDimension: declaration.periodDimension, }), }; try { return (0, boundedJson_js_1.copyJson)({ ...common, scope: (0, scope_js_1.executedScope)(executedArgs, declaration) }, scope_js_1.BINDING_LIMITS.scopeBytes * 2, true); } catch { return (0, boundedJson_js_1.copyJson)({ ...common, unavailable: 'missing-scope' }, scope_js_1.BINDING_LIMITS.scopeBytes * 2, true); } } exports.captureDispatch = captureDispatch; /** Preserve the returned reading before any async result rule can mutate it. */ function captureReturnedEvidence(dispatch, original) { try { const semantics = (0, envelope_js_1.readSemantics)((0, boundedJson_js_1.copyJson)(original, scope_js_1.BINDING_LIMITS.resultBytes, true)); if (semantics === undefined) throw new Error('No recognized evidence.'); return Object.freeze({ resultId: dispatch.id, semantics }); } catch { return Object.freeze({ resultId: dispatch.id, unavailable: 'invalid-evidence' }); } } exports.captureReturnedEvidence = captureReturnedEvidence; /** * returned is the return-time copy from that invocation. served is * the final model-facing payload AFTER all governance, placement and caps. * Visibility is a trusted adapter decision; equality alone grants no access. * Rewrites need a future explicit association, and are unavailable here. */ function finalizeEvidence(dispatch, returned, served, access) { const unavailable = (reason) => (0, boundedJson_js_1.copyJson)({ identity: dispatch.identity, id: dispatch.id, toolName: dispatch.toolName, toolCallId: dispatch.toolCallId, iteration: dispatch.iteration, scopeDeclaration: dispatch.scopeDeclaration, unavailable: reason, }, scope_js_1.BINDING_LIMITS.scopeBytes * 2, true); if (dispatch.id !== resultIdentityOf(dispatch.identity)) return unavailable('invalid-evidence'); if (access.completed !== true) return unavailable('incomplete-result'); if (access.resultVisible !== true || access.scopeVisible !== true) return unavailable('withheld-evidence'); if (dispatch.unavailable !== undefined) return unavailable(dispatch.unavailable); if (returned.resultId !== dispatch.id) return unavailable('unassociated-result'); if (returned.unavailable !== undefined) return unavailable(returned.unavailable); try { const raw = (0, boundedJson_js_1.copyJson)(returned.semantics, scope_js_1.BINDING_LIMITS.resultBytes, true); const semantics = (0, envelope_js_1.readSemantics)(raw); if (semantics === undefined) return unavailable('invalid-evidence'); const model = typeof served === 'string' ? JSON.parse(served.length <= scope_js_1.BINDING_LIMITS.resultBytes ? served : '') : served; const allowed = (0, boundedJson_js_1.copyJson)(model, scope_js_1.BINDING_LIMITS.resultBytes, true); const projection = (0, boundedJson_js_1.copyJson)((0, envelope_js_1.semanticsForModel)(semantics), scope_js_1.BINDING_LIMITS.resultBytes, true); if ((0, canonicalJson_js_1.canonicalJson)(allowed) !== (0, canonicalJson_js_1.canonicalJson)(projection)) return unavailable('unassociated-result'); const period = (0, envelope_js_1.periodOfSemantics)(semantics); return (0, boundedJson_js_1.copyJson)({ ...dispatch, facts: (0, ledger_js_1.claimRowsOf)(semantics, { toolName: dispatch.toolName, toolCallId: dispatch.toolCallId, iteration: dispatch.iteration, }), ...((semantics.coverage !== undefined || period !== undefined) && { coverage: (0, envelope_js_1.coverageOfSemantics)(semantics), }), ...(period !== undefined && { period }), }, scope_js_1.BINDING_LIMITS.resultBytes, true); } catch { return unavailable('invalid-evidence'); } } exports.finalizeEvidence = finalizeEvidence; /** Freeze the caller's completed evidence universe at the declaration moment. */ function evidenceSnapshot(namespace, verifiedRunIds, results) { if (!(0, scope_js_1.boundedText)(namespace) || verifiedRunIds.length > scope_js_1.BINDING_LIMITS.results || !verifiedRunIds.every(scope_js_1.boundedText) || new Set(verifiedRunIds).size !== verifiedRunIds.length || results.length > scope_js_1.BINDING_LIMITS.results) throw new Error('Invalid evidence snapshot boundary.'); return (0, boundedJson_js_1.copyJson)({ version: 1, namespace, runIds: verifiedRunIds, results }, scope_js_1.BINDING_LIMITS.snapshotBytes, true); } exports.evidenceSnapshot = evidenceSnapshot; //# sourceMappingURL=capture.js.map