UNPKG

agentfootprint

Version:

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

104 lines • 5.68 kB
"use strict"; /** * artifacts/types — the claim-check shapes and the five-verb port. * * A tool stores its result under a REFERENCE and hands the model a claim * ticket; the model routes tickets instead of hauling data. These are the * shapes that make that sentence true: the ref (an opaque minted string), * the metadata a consumer decides from (never the bytes), and the store * port every backend implements. * * ── The constitution this port inherits (from `MemoryStore`) ──────────────── * 1. **Scope is always the first argument.** Every call takes an * {@link ArtifactScope} — the same tenant/principal/conversation tuple * memory scopes on — so stores enforce isolation at the boundary. A ref * alone opens NOTHING; a wrong scope surfaces as "no data", never as a * cross-tenant read. * 2. **`get` returns `null` for missing OR expired.** Deliberate ambiguity: * "no data" is the only actionable fact, and distinguishing the two would * let a caller reason about another scope's contents. * 3. **Reads return cursors, not unbounded arrays.** `list` pages. * 4. **Methods return Promises uniformly**, so sync adapters can become * async ones without breaking a caller. * * ── Five verbs, no more ───────────────────────────────────────────────────── * `put · head · get · delete · list`. The moment this port grows `query()` or * `transform()` we are building a database — compute belongs to the code leg, * and that refusal is written here so a future round can be refused by * citation. * * `head` earns its place because it IS the render-by-ref decision: a consumer * picks what to do from `kind` and `bytes` without paying for the payload. * * ── …and two OPTIONAL ones (9.25.0) ───────────────────────────────────────── * `putStream?` / `getStream?` are feature-detected members, not a sixth and * seventh verb: a store that cannot move a payload without holding it whole * LEAVES THEM ABSENT, and a consumer that calls one it did not detect gets a * type error rather than a runtime surprise. An adapter must never fake a * stream over bytes it already holds — a fake stream is an accepted-and- * silently-wrong promise about memory. See {@link ArtifactStreamPutInput} for * the two things streaming costs you (a stated `bytes`, and no digest). */ Object.defineProperty(exports, "__esModule", { value: true }); exports.InvalidArtifactError = exports.ArtifactIntegrityError = exports.UnknownParentRefError = void 0; // ─── Refusals ──────────────────────────────────────────────────────── /** * A `put` named a parent that does not resolve in the same scope — a foreign * key that would dangle at birth. Refused at mint, because a derivation fact * that points at nothing is worse than no fact: every later consumer would * inherit the lie. */ class UnknownParentRefError extends Error { code = 'ERR_UNKNOWN_PARENT_REF'; /** The parents that failed to resolve. */ unresolved; constructor(unresolved) { super(`[artifacts] put refused: parentRefs ${unresolved.map((r) => `'${r}'`).join(', ')} ` + `do not resolve in this scope. parentRefs are derivation FACTS validated at mint — ` + `a parent must exist (and not be expired) in the same scope when the child is born. ` + `Store the parent first, or drop it from parentRefs; head(ref) tells you what resolves.`); this.name = 'UnknownParentRefError'; this.unresolved = unresolved; } } exports.UnknownParentRefError = UnknownParentRefError; /** * A stored payload no longer matches the digest minted with it. Thrown by * `get` instead of returning the bytes — corrupt data delivered as whole data * is the accepted-and-silently-wrong failure, and the one thing a claim check * must never do is honor a ticket with someone else's parcel. */ class ArtifactIntegrityError extends Error { code = 'ERR_ARTIFACT_INTEGRITY'; ref; /** The digest minted at put. */ expected; /** The digest of what the store actually holds now. */ actual; constructor(ref, expected, actual) { super(`[artifacts] get('${ref}') refused: the stored payload no longer matches its minted ` + `digest (expected ${expected}, computed ${actual}). The bytes changed after put — ` + `a corrupted file, an external edit, or a store bug — and returning them as if whole ` + `would be silent corruption. Re-create the artifact from its source; the meta ` + `(head) is still readable.`); this.name = 'ArtifactIntegrityError'; this.ref = ref; this.expected = expected; this.actual = actual; } } exports.ArtifactIntegrityError = ArtifactIntegrityError; /** * A `put` this store cannot honor as stated — a payload JSON cannot carry, a * blank `kind`, a payload larger than the whole scope budget. Refused by name * at the door: storing an approximation would be accepted-and-silently-wrong. */ class InvalidArtifactError extends Error { code = 'ERR_INVALID_ARTIFACT'; constructor(detail) { super(`[artifacts] put refused: ${detail}`); this.name = 'InvalidArtifactError'; } } exports.InvalidArtifactError = InvalidArtifactError; //# sourceMappingURL=types.js.map