agentfootprint
Version:
The explainable agent framework — backtrack a wrong answer to the exact context that caused it (evidence, not guesses). Built on footprintjs.
90 lines • 4.76 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.withFindingsAdmission = exports.assertAnswerReferences = exports.FindingsAnswerRefusal = void 0;
const admission_js_1 = require("./admission.js");
class FindingsAnswerRefusal extends Error {
teaching;
constructor(teaching) {
super('Findings reference admission refused the answer.');
this.teaching = teaching;
}
}
exports.FindingsAnswerRefusal = FindingsAnswerRefusal;
/** Throws only after the caller has preserved the attempted standings. */
function assertAnswerReferences(scope, declaration, malformed = 0) {
const refusal = (0, admission_js_1.findingsReferenceRefusal)(declaration, scope.findingsRequest?.[0], scope.iteration, malformed);
if (refusal !== undefined)
throw new FindingsAnswerRefusal(refusal);
}
exports.assertAnswerReferences = assertAnswerReferences;
function withFindingsAdmission(decider, enforcement, recordStandings, announce, willJudgeAnswer) {
return async (scope) => {
const emission = scope.llmLatestContent;
try {
// Do not give an output callback an invalid raw proposal. A callback's
// own rewrite is checked again by the shared peel before any judge.
if (willJudgeAnswer(scope)) {
const { peelAnswerFindings } = await Promise.resolve().then(() => __importStar(require('./peel.js')));
const peeled = peelAnswerFindings(emission);
if ((0, admission_js_1.findingsReferenceRefusal)(peeled.findings, scope.findingsRequest?.[0], scope.iteration, peeled.malformed) !== undefined)
await recordStandings(scope); // records, then throws the same refusal
}
return await decider(scope);
}
catch (error) {
if (!(error instanceof FindingsAnswerRefusal))
throw error;
// A host output denial is terminal. The peel already preserved the
// invalid attempted findings; neither a retry nor a replacement denial
// may work around the owner's decision to withhold this answer.
if (scope.messageDeniedPhase === 'output' && scope.messageDeniedReason !== undefined) {
announce(scope, 'final', 'host output denial remains terminal; findings retained as diagnostics');
return 'final';
}
const attempt = (scope.outputAttempts?.length ?? 0) + 1;
if (enforcement !== undefined &&
attempt <= enforcement.retries &&
scope.iteration < scope.maxIterations &&
scope.wrapUpAsked !== true &&
!(scope.costBudgetHit && scope.costBudgetOnExceed === 'halt')) {
scope.outputSchemaFailure = { attempt, stage: 'schema-validate', error: error.teaching };
scope.llmLatestContent = emission;
announce(scope, 'output-retry', 'findings reference refused; spending a configured output retry');
return 'output-retry';
}
// This is a terminal verdict, not a replacement successful answer.
// Already streamed drafts remain drafts; Phase A does not buffer them.
scope.messageDeniedReason = error.teaching;
scope.messageDeniedPhase = 'output';
scope.messageDeniedBy = 'findings-reference-admission';
scope.llmLatestContent = error.teaching;
announce(scope, 'final', 'findings reference refused; no configured correction allowance remains');
return 'final';
}
};
}
exports.withFindingsAdmission = withFindingsAdmission;
//# sourceMappingURL=answerAdmission.js.map