agentfootprint
Version:
The explainable agent framework — backtrack a wrong answer to the exact context that caused it (evidence, not guesses). Built on footprintjs.
95 lines • 5.29 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.artifactDetailTool = void 0;
const abort_js_1 = require("../lib/abort.js");
const boundedJson_js_1 = require("../lib/boundedJson.js");
const detailRequest_js_1 = require("../artifacts/detailRequest.js");
const detailError_js_1 = require("../artifacts/detailError.js");
const detailView_js_1 = require("../artifacts/detailView.js");
const tools_js_1 = require("./tools.js");
/**
* Open bounded JSON sections through a host-authenticated reference.
*
* The host owns scope, run, source, kind, integrity and domain checks in `admit`.
* This helper never reads a store automatically or grants claim authority. Every
* call re-admits, then detaches/freezes at most 1 MiB of ordinary JSON (depth 100).
* Paths have at most 16 segments and 2048 UTF-16 characters; pages contain at most
* 20 children. Whole responses are bounded to 12 KiB UTF-8, including at most
* 4 KiB host context; inline values are at most 8 KiB. Large scalars are omitted
* whole. Bounds do not preempt synchronous host code or arbitrary Proxy traps.
*
* Callback failures use fixed refusal text. Cancellation stops waiting and late
* results cannot be served, but does not claim the underlying work stopped.
*/
function artifactDetailTool(options) {
const configured = (0, boundedJson_js_1.ownData)(options, ['name', 'admit', 'context']);
if (typeof configured.name !== 'string' ||
typeof configured.admit !== 'function' ||
(configured.context !== undefined && typeof configured.context !== 'function'))
throw new Error('Invalid artifact detail configuration.');
const name = configured.name;
const admit = configured.admit;
const context = configured.context;
return (0, tools_js_1.defineTool)({
name,
description: 'Open a bounded section of an authorized stored JSON proof. Use the complete issued ref and JSON pointer (empty path opens its root). Small sections return actual values; larger containers return child actions and exact shown/total/complete/nextOffset. Large scalars are omitted whole. Reading a section grants no additional claim authority.',
inputSchema: {
type: 'object',
additionalProperties: false,
required: ['ref', 'path'],
properties: {
ref: {
type: 'string',
description: 'Complete issued artifact reference: art_ followed by 22 base62 characters, for example art_0123456789ABCDEFGHIJKL. Never a file, URL or storage scope.',
},
path: {
type: 'string',
maxLength: detailRequest_js_1.DETAIL_LIMITS.path,
description: 'Safe JSON pointer; escape ~ as ~0 and / as ~1. Empty string opens the root; at most 16 segments.',
},
offset: {
type: 'integer',
minimum: 0,
maximum: detailRequest_js_1.DETAIL_LIMITS.offset,
description: 'Direct-child offset from nextOffset; default zero. Scalars accept only zero and are returned whole or explicitly omitted.',
},
limit: {
type: 'integer',
minimum: 1,
maximum: detailRequest_js_1.DETAIL_LIMITS.page,
description: 'Direct children per page, from 1 to 20; default 20. Follow actual child actions or nextOffset; shown/total/complete describe the page, not proof completeness.',
},
},
},
async execute(value, ctx) {
const args = (0, detailRequest_js_1.readDetailArgs)(value);
let root;
let domain;
try {
(0, abort_js_1.throwIfAborted)(ctx.signal);
const supplied = await (0, abort_js_1.untilAborted)(Promise.resolve().then(() => {
(0, abort_js_1.throwIfAborted)(ctx.signal);
return admit(args.ref, ctx);
}), ctx.signal);
(0, abort_js_1.throwIfAborted)(ctx.signal);
root = (0, boundedJson_js_1.copyJson)(supplied, detailRequest_js_1.DETAIL_LIMITS.inputBytes, true);
(0, abort_js_1.throwIfAborted)(ctx.signal);
const presented = context?.(root, args.path);
domain =
presented === undefined
? undefined
: (0, boundedJson_js_1.ownData)((0, boundedJson_js_1.copyJson)(presented, detailRequest_js_1.DETAIL_LIMITS.contextBytes, true));
(0, abort_js_1.throwIfAborted)(ctx.signal);
}
catch {
if (ctx.signal?.aborted)
throw new detailError_js_1.ArtifactDetailError('ERR_ARTIFACT_DETAIL_CANCELLED');
return (0, detailError_js_1.unavailableDetail)();
}
// Host failures are sanitized above; the pure view owns its fixed request refusals.
return (0, detailView_js_1.projectArtifactDetail)(root, args, name, domain);
},
});
}
exports.artifactDetailTool = artifactDetailTool;
//# sourceMappingURL=artifactDetailTool.js.map