UNPKG

@sema-agent/core

Version:

Stateless, task-oriented AI agent core

145 lines (144 loc) • 6.47 kB
import { createHash } from "node:crypto"; export function canonical(node) { if (Array.isArray(node)) return `[${node.map(canonical).join(",")}]`; if (node === null || typeof node !== "object") return JSON.stringify(node); const keys = Object.keys(node).sort(); return `{${keys.map((k) => `${JSON.stringify(k)}:${canonical(node[k])}`).join(",")}}`; } export function digestOf(node) { return `sha256:${createHash("sha256").update(canonical(node)).digest("hex")}`; } export function catalogDigestOf(catalog) { return digestOf({ ...catalog, bands: [...catalog.bands].sort((a, b) => a.id.localeCompare(b.id)), messages: [...catalog.messages].sort((a, b) => a.id.localeCompare(b.id)), sections: [...catalog.sections].sort((a, b) => a.rank - b.rank), }); } export function promptIdentityOf(layers) { return digestOf({ catalog: layers.catalog, renderers: layers.renderers, overlays: digestOf({ center: layers.center ?? null, deploy: layers.deploy ?? null, task: layers.task ?? null }), binding: layers.binding, }); } export const PROMPT_EPOCH_ACTIVATIONS = Object.freeze(["session_start", "compaction", "code_change", "selection_change"]); export const PROMPT_EPOCH_CHANGES = Object.freeze(["catalog", "renderers", "deploy", "task", "published_schema"]); const DIGEST = /^sha256:[0-9a-f]{64}$/; const isDigest = (v) => typeof v === "string" && DIGEST.test(v); const RETIRED_DESCRIPTOR_FIELDS = Object.freeze(["artifactDigest", "packId", "assemblyApi", "centerArtifactDigest"]); function normalizeLayers(raw) { if (raw === null || typeof raw !== "object" || Array.isArray(raw)) return undefined; const r = raw; for (const k of Object.keys(r)) if (!["catalog", "renderers", "center", "deploy", "task", "binding"].includes(k)) return undefined; if (!isDigest(r.catalog) || !isDigest(r.binding)) return undefined; for (const k of ["center", "deploy", "task"]) if (r[k] !== undefined && !isDigest(r[k])) return undefined; const rv = r.renderers; if (rv === null || typeof rv !== "object" || Array.isArray(rv)) return undefined; const entries = Object.entries(rv); if (entries.length > 64 || entries.some(([k, v]) => k.length === 0 || k.length > 64 || typeof v !== "number" || !Number.isInteger(v) || v < 1 || v > 1_000_000)) return undefined; return { catalog: r.catalog, renderers: Object.fromEntries(entries), ...(r.center !== undefined ? { center: r.center } : {}), ...(r.deploy !== undefined ? { deploy: r.deploy } : {}), ...(r.task !== undefined ? { task: r.task } : {}), binding: r.binding, }; } export function normalizePromptEpoch(raw) { if (raw === null || typeof raw !== "object") return undefined; const r = raw; if (typeof r.epoch !== "number" || !Number.isInteger(r.epoch) || r.epoch < 1 || r.epoch > 1_000_000_000) return undefined; if (!isDigest(r.identity)) return undefined; const layers = normalizeLayers(r.layers); if (layers === undefined || promptIdentityOf(layers) !== r.identity) return undefined; if (!PROMPT_EPOCH_ACTIVATIONS.some((a) => a === r.activatedBy)) return undefined; const activatedBy = r.activatedBy; let changed; if (r.changed !== undefined) { if (activatedBy !== "code_change" || !Array.isArray(r.changed) || r.changed.length === 0) return undefined; if (r.changed.some((c) => !PROMPT_EPOCH_CHANGES.some((w) => w === c)) || new Set(r.changed).size !== r.changed.length) return undefined; changed = [...r.changed]; } if (r.sourceRevision !== undefined && (layers.center === undefined || typeof r.sourceRevision !== "string" || r.sourceRevision.length === 0 || r.sourceRevision.length > 500)) return undefined; return { epoch: r.epoch, identity: r.identity, layers, activatedBy, ...(changed !== undefined ? { changed } : {}), ...(r.sourceRevision !== undefined ? { sourceRevision: r.sourceRevision } : {}), }; } export function readStoredPromptEpoch(raw) { const descriptor = normalizePromptEpoch(raw); if (descriptor !== undefined) return { kind: "pin", descriptor }; if (raw === null || typeof raw !== "object") return undefined; const r = raw; if (!RETIRED_DESCRIPTOR_FIELDS.some((f) => f in r)) return undefined; return { kind: "legacy", centerPinned: isDigest(r.centerArtifactDigest) }; } function changedLayers(a, b) { const out = []; if (a.catalog !== b.catalog) out.push("catalog"); if (canonical(a.renderers) !== canonical(b.renderers)) out.push("renderers"); if (a.deploy !== b.deploy) out.push("deploy"); if (a.task !== b.task) out.push("task"); return out; } function descriptorOf(epoch, layers, activatedBy, extra) { return { epoch, identity: promptIdentityOf(layers), layers, activatedBy, ...(extra.changed !== undefined && extra.changed.length > 0 ? { changed: [...extra.changed] } : {}), ...(layers.center !== undefined && extra.sourceRevision !== undefined ? { sourceRevision: extra.sourceRevision } : {}), }; } export function prepareEpochRecord(stored, layers, ctx) { if (stored === undefined) return descriptorOf(1, layers, ctx.priorConversation ? "code_change" : "session_start", ctx); if (stored.kind === "legacy") return descriptorOf(1, layers, "code_change", { ...ctx, ...(stored.centerPinned ? { changed: ["published_schema"] } : {}) }); const pinned = stored.descriptor; if (pinned.identity === promptIdentityOf(layers)) return undefined; const changed = changedLayers(pinned.layers, layers); return descriptorOf(pinned.epoch + 1, layers, changed.length > 0 ? "code_change" : "selection_change", { ...ctx, changed }); } export function selectCompactionEpoch(current, layers, sourceRevision) { if (current !== undefined && current.identity === promptIdentityOf(layers)) { const { changed: _recordOnly, ...restated } = current; return { ...restated, activatedBy: "compaction" }; } return descriptorOf((current?.epoch ?? 0) + 1, layers, "compaction", sourceRevision !== undefined ? { sourceRevision } : {}); }