UNPKG

agentfootprint

Version:

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

98 lines • 5.06 kB
"use strict"; /** * artifacts/minting — the shared half of every adapter's `put`. * * Validate the input, prove the parents, measure the bytes, compute the * digest when asked, mint the ref, stamp the meta. Three adapters call this * one pipeline so a put refused by `inMemoryArtifacts` is refused in the same * words by `sqliteArtifacts` — one law, three storage mechanics. * * What stays with the adapter: holding the bytes, applying the retention * plan, answering the other four verbs. */ Object.defineProperty(exports, "__esModule", { value: true }); exports.prepareArtifact = void 0; const naming_js_1 = require("./naming.js"); const payload_js_1 = require("./payload.js"); const retention_js_1 = require("./retention.js"); const axis_js_1 = require("../time/axis.js"); const types_js_1 = require("./types.js"); /** * Validate a put and build the meta it mints. * * @param input the caller's put. * @param resolveParent scope-bound existence check for parent validation. * @param retention the adapter's policy — stamps `expiresAt` (stated, never sprung). * @param now the adapter's clock, injected so tests own time. * @throws InvalidArtifactError for input this library cannot store faithfully. * @throws UnknownParentRefError for a parent that does not resolve in scope. */ async function prepareArtifact(input, resolveParent, retention, now) { if (typeof input.kind !== 'string' || input.kind.trim() === '') { throw new types_js_1.InvalidArtifactError(`kind is ${JSON.stringify(input.kind)}. kind is the consumer vocabulary a redeemer ` + `decides from ('dataset/rows', 'chart/spec') — a blank one makes every head() useless. ` + `Name what this artifact IS.`); } if (typeof input.mediaType !== 'string' || input.mediaType.trim() === '') { throw new types_js_1.InvalidArtifactError(`mediaType is ${JSON.stringify(input.mediaType)}. Name the payload's MIME type ` + `('application/json', 'text/csv', …) so a consumer can decode without guessing.`); } if (input.expiresAt !== undefined && (!Number.isFinite(input.expiresAt) || input.expiresAt <= now)) { throw new types_js_1.InvalidArtifactError(`expiresAt = ${String(input.expiresAt)} is not a future unix-ms timestamp. An artifact ` + `born expired would resolve for nobody; state a future time, or omit the field.`); } if (input.digest !== undefined && input.digest !== 'sha-256') { throw new types_js_1.InvalidArtifactError(`digest = ${JSON.stringify(input.digest)} is not an algorithm this store computes. ` + `'sha-256' is the one shipped; omit the field for no digest.`); } // A declared time axis is judged, never repaired: a ticket whose // description the store had "fixed" would carry a promise nobody made. if (input.timeAxis !== undefined) { const issues = (0, axis_js_1.timeAxisIssues)(input.timeAxis); if (issues.length > 0) throw new types_js_1.InvalidArtifactError(issues.join(' ')); } // Parents are FACTS, proven at birth — a foreign key that cannot dangle. if (input.parentRefs !== undefined && input.parentRefs.length > 0) { const unresolved = []; for (const parent of input.parentRefs) { if (!(0, naming_js_1.isArtifactRef)(parent) || !(await resolveParent(parent))) unresolved.push(parent); } if (unresolved.length > 0) throw new types_js_1.UnknownParentRefError(unresolved); } // Measure (and refuse the unserializable) BEFORE minting, so a refused put // never burns a ref. const bytes = (0, payload_js_1.measureArtifactBytes)(input.data); const digest = input.digest === 'sha-256' ? await (0, payload_js_1.computeArtifactDigest)(input.data) : undefined; const expiresAt = (0, retention_js_1.resolveExpiresAt)(input.expiresAt, retention, now); const meta = { ref: (0, naming_js_1.mintArtifactRef)(), kind: input.kind, mediaType: input.mediaType, bytes, createdAt: now, ...(input.label !== undefined && { label: input.label }), ...(digest !== undefined && { digest }), ...(expiresAt !== undefined && { expiresAt }), ...(input.origin !== undefined && { origin: input.origin }), ...(input.parentRefs !== undefined && input.parentRefs.length > 0 && { parentRefs: [...input.parentRefs] }), ...(input.timeAxis !== undefined && { timeAxis: copyTimeAxis(input.timeAxis) }), }; return { meta, bytes }; } exports.prepareArtifact = prepareArtifact; /** The ticket keeps its OWN copy — a caller mutating its declaration after * the put must not rewrite a minted description. */ function copyTimeAxis(axis) { const { aggregate } = axis; return { ...axis, ...(aggregate !== undefined && typeof aggregate === 'object' && { aggregate: { ...aggregate } }), }; } //# sourceMappingURL=minting.js.map