@sema-agent/core
Version:
Stateless, task-oriented AI agent core
377 lines (376 loc) • 18.8 kB
JavaScript
import { existsSync, readdirSync, renameSync } from "node:fs";
import { join } from "node:path";
import { uuidv7 } from "../../engine/session/uuid.js";
import { atomicWriteFileSync, lockedStrictUpdate, readStrictSidecar, ControlPlaneCorruptError, ensureDirExists } from "./layout.js";
import { thrownText } from "../thrown-value.js";
export function deriveSupersededSet(headers, opts = {}) {
const byId = new Map();
for (const h of headers)
byId.set(h.id, h);
const out = new Map();
for (const h of headers) {
const d = h.distilled;
if (d === undefined || d.supersedes.length === 0)
continue;
if (opts.excluded?.(h.id) === true)
continue;
if (h.rev !== d.carrierRev)
continue;
for (const edge of d.supersedes) {
const target = byId.get(edge.id);
if (target === undefined)
continue;
if (target.scope !== h.scope)
continue;
if (target.rev !== edge.rev)
continue;
if (!out.has(edge.id))
out.set(edge.id, h.id);
}
}
return out;
}
export function memorySupersededNote(carrierId) {
return `note: a newer consolidated entry supersedes this one — memory entry ${carrierId} carries the current form; this entry remains readable as evidence.`;
}
export const MEMORY_SEARCH_SUPERSEDED_TAG = "[superseded]";
export const CONSOLIDATION_DEFAULTS = {
supersedeRatioCap: 0.25,
supersedeAbsoluteFloor: 4,
maxProductsPerRun: 64,
maxInputsPerProduct: 32,
maxDirectedPatchesPerPlan: 32,
minRunIntervalMs: 24 * 60 * 60 * 1000,
minSessionsBetweenRuns: 5,
scanRefusalRatioCap: 0.25,
scanRefusalMaxPerPlan: 8,
};
export const CONSOLIDATION_FORCE_THROTTLE_FLOOR_MS = 60_000;
export const CONSOLIDATION_SESSION_RING_MAX = 64;
export const CONSOLIDATION_SEAT_FREEZE_GRACE_MS = 10 * 60_000;
function coded(message, code) {
const e = new Error(message);
e.code = code;
return e;
}
export function screenConsolidationOptions(raw, provenance) {
if (provenance === "off") {
throw coded(`MemoryEngineOptions.consolidation cannot be enabled under provenance: "off" — the consolidation fold law must be able to mint origin markers (a marked input's product would otherwise commit unmarked). Enable provenance "carry" or remove the consolidation options.`, "config.memory_consolidation_provenance_off");
}
const num = (name, v, check, want) => {
if (v === undefined)
return CONSOLIDATION_DEFAULTS[name];
if (typeof v !== "number" || !Number.isFinite(v) || !check(v)) {
const got = typeof v === "number" ? String(v) : v === null ? "null" : typeof v;
throw coded(`MemoryEngineOptions.consolidation.${name} must be ${want} when present (got ${got}) — an unevaluable knob is refused loudly, never folded to the default.`, "config.memory_consolidation");
}
return v;
};
const screened = {
supersedeRatioCap: num("supersedeRatioCap", raw.supersedeRatioCap, (n) => n > 0 && n <= 1, "a number in (0, 1]"),
supersedeAbsoluteFloor: num("supersedeAbsoluteFloor", raw.supersedeAbsoluteFloor, (n) => Number.isInteger(n) && n >= 0, "a non-negative integer"),
maxProductsPerRun: num("maxProductsPerRun", raw.maxProductsPerRun, (n) => Number.isInteger(n) && n >= 1, "a positive integer"),
maxInputsPerProduct: num("maxInputsPerProduct", raw.maxInputsPerProduct, (n) => Number.isInteger(n) && n >= 1, "a positive integer"),
maxDirectedPatchesPerPlan: num("maxDirectedPatchesPerPlan", raw.maxDirectedPatchesPerPlan, (n) => Number.isInteger(n) && n >= 1, "a positive integer"),
minRunIntervalMs: num("minRunIntervalMs", raw.minRunIntervalMs, (n) => n > 0, "a positive number of milliseconds"),
minSessionsBetweenRuns: num("minSessionsBetweenRuns", raw.minSessionsBetweenRuns, (n) => Number.isInteger(n) && n >= 0, "a non-negative integer"),
scanRefusalRatioCap: num("scanRefusalRatioCap", raw.scanRefusalRatioCap, (n) => n > 0 && n <= 1, "a number in (0, 1]"),
scanRefusalMaxPerPlan: num("scanRefusalMaxPerPlan", raw.scanRefusalMaxPerPlan, (n) => Number.isInteger(n) && n >= 1, "a positive integer"),
allowInstructionProducts: raw.allowInstructionProducts === true,
multiNode: raw.multiNode === true,
...(raw.lease !== undefined ? { lease: raw.lease } : {}),
};
if (raw.multiNode !== undefined && raw.multiNode !== true) {
throw coded(`MemoryEngineOptions.consolidation.multiNode must be exactly true when present (a posture declaration, not a boolean knob).`, "config.memory_consolidation");
}
if (raw.allowInstructionProducts !== undefined && raw.allowInstructionProducts !== true) {
throw coded(`MemoryEngineOptions.consolidation.allowInstructionProducts must be exactly true when present (a posture declaration, not a boolean knob — absent means the instruction-form gate stays closed).`, "config.memory_consolidation");
}
if (screened.multiNode && screened.lease === undefined) {
throw coded(`MemoryEngineOptions.consolidation.multiNode declared without a lease seat — a multi-node deployment MUST inject the host's global lease (the local plan-seat CAS does not reach across nodes). Inject consolidation.lease or remove the multiNode declaration.`, "config.memory_consolidation_lease_required");
}
if (raw.lease !== undefined && typeof raw.lease.acquire !== "function") {
throw coded(`MemoryEngineOptions.consolidation.lease.acquire must be a function.`, "config.memory_consolidation");
}
return screened;
}
export function supersessionFuseCeiling(activeSetSize, opts) {
if (activeSetSize <= 1)
return 0;
return Math.min(activeSetSize - 1, Math.max(opts.supersedeAbsoluteFloor, Math.floor(opts.supersedeRatioCap * activeSetSize)));
}
export function scanRefusalCeiling(submittedProducts, opts) {
if (submittedProducts <= 0)
return 0;
return Math.min(Math.max(1, Math.floor(opts.scanRefusalRatioCap * submittedProducts)), opts.scanRefusalMaxPerPlan);
}
export function consolidationTypeEligible(type) {
return type !== "episodic" && type !== "procedural";
}
export const CONSOLIDATION_GATE_FILE = "consolidation-gate.json";
export const CONSOLIDATION_PLANS_DIR = "consolidation-plans";
export const CONSOLIDATION_INTENTS_FILE = "consolidation-intents.json";
function coerceGateFile(raw) {
if (raw === undefined)
return { v: 1, scopes: {} };
if (typeof raw !== "object" || raw === null || raw.v !== 1 || typeof raw.scopes !== "object" || raw.scopes === null) {
throw new ControlPlaneCorruptError("memory consolidation gate store has an unrecognized shape (fail-closed sidecar)");
}
const scopes = raw.scopes;
const out = { v: 1, scopes: {} };
for (const [scope, rowRaw] of Object.entries(scopes)) {
if (typeof rowRaw !== "object" || rowRaw === null)
throw new ControlPlaneCorruptError(`memory consolidation gate store row for scope ${JSON.stringify(scope)} is malformed (fail-closed sidecar)`);
const r = rowRaw;
const sessions = r["sessions"];
if (typeof sessions !== "object" ||
sessions === null ||
typeof sessions.count !== "number" ||
!Array.isArray(sessions.ring ?? []) ||
(sessions.ring !== undefined && !sessions.ring.every((s) => typeof s === "string")) ||
typeof r["epoch"] !== "number" ||
!Number.isInteger(r["epoch"])) {
throw new ControlPlaneCorruptError(`memory consolidation gate store row for scope ${JSON.stringify(scope)} is malformed (fail-closed sidecar)`);
}
out.scopes[scope] = rowRaw;
}
return out;
}
function freshRow() {
return { sessions: { count: 0, ring: [] }, epoch: 0 };
}
export function updateConsolidationGate(controlDir, fn) {
return lockedStrictUpdate(controlDir, CONSOLIDATION_GATE_FILE, "memory consolidation gate store", coerceGateFile, fn);
}
export function readConsolidationGateFile(controlDir) {
return coerceGateFile(readStrictSidecar(controlDir, CONSOLIDATION_GATE_FILE, "memory consolidation gate store"));
}
export function consolidationGateFileExists(controlDir) {
return existsSync(join(controlDir, CONSOLIDATION_GATE_FILE));
}
export function recommendationUnconsumed(row) {
return row.lastRecommendedAt !== undefined && (row.lastRunAt === undefined || row.lastRecommendedAt > row.lastRunAt);
}
export function sessionsSinceExcludingCurrent(row) {
return Math.max(0, (row?.sessions.count ?? 0) - 1);
}
export function recordConsolidationSession(controlDir, scope, sessionId, opts, now) {
return updateConsolidationGate(controlDir, (file) => {
const row = file.scopes[scope] ?? freshRow();
if (row.sessions.ring.includes(sessionId)) {
return { result: { recommended: false, sessionsSince: sessionsSinceExcludingCurrent(row) } };
}
row.sessions.count += 1;
row.sessions.ring.push(sessionId);
if (row.sessions.ring.length > CONSOLIDATION_SESSION_RING_MAX)
row.sessions.ring.splice(0, row.sessions.ring.length - CONSOLIDATION_SESSION_RING_MAX);
const at = now();
const banked = sessionsSinceExcludingCurrent(row);
const timeOpen = row.lastRunAt === undefined || at - row.lastRunAt >= opts.minRunIntervalMs;
const sessionsOpen = banked >= opts.minSessionsBetweenRuns;
const edgeArmed = !recommendationUnconsumed(row);
let recommended = false;
if (timeOpen && sessionsOpen && edgeArmed) {
recommended = true;
row.lastRecommendedAt = at;
}
file.scopes[scope] = row;
return { next: file, result: { recommended, sessionsSince: banked } };
});
}
export function recordActiveSetBaseline(controlDir, scope, size, ratioCap, _now) {
return updateConsolidationGate(controlDir, (file) => {
const row = file.scopes[scope] ?? freshRow();
const prev = row.activeSetBaseline;
row.activeSetBaseline = size;
file.scopes[scope] = row;
const collapsed = prev !== undefined && prev > 0 && size < prev && (prev - size) / prev > ratioCap ? { from: prev, to: size } : undefined;
return { next: file, result: collapsed !== undefined ? { collapsed } : {} };
});
}
export function isValidConsolidationPlanId(value) {
return /^[A-Za-z0-9][A-Za-z0-9_-]{7,63}$/.test(value);
}
function planPath(controlDir, planId) {
if (!isValidConsolidationPlanId(planId)) {
throw new ControlPlaneCorruptError(`consolidation plan id ${JSON.stringify(planId.slice(0, 80))} fails the id grammar — a plan id doubles as a control-plane file name and must never be joined as a path`);
}
return join(controlDir, CONSOLIDATION_PLANS_DIR, `${planId}.json`);
}
export function writeConsolidationPlan(controlDir, plan) {
ensureDirExists(join(controlDir, CONSOLIDATION_PLANS_DIR));
atomicWriteFileSync(planPath(controlDir, plan.planId), `${JSON.stringify(plan, null, 2)}\n`);
}
const CONSOLIDATION_PLAN_STATES = new Set(["open", "applying", "completed", "conflict", "discarded"]);
const CONSOLIDATION_DIRECTED_STATES = new Set(["pending", "applied", "satisfied", "conflict"]);
const CONSOLIDATION_INTENT_STATES = new Set(["pending", "settled", "abandoned"]);
function planShapeInvalid(raw, planId) {
if (typeof raw !== "object" || raw === null)
return "not an object";
const p = raw;
if (p["v"] !== 1 && p["v"] !== 2)
return "unrecognized version";
if (p["planId"] !== planId)
return "planId mismatch";
if (typeof p["scope"] !== "string" || p["scope"].length === 0)
return "missing scope";
if (typeof p["requestId"] !== "string")
return "missing requestId";
if (typeof p["createdAt"] !== "number")
return "missing createdAt";
if (typeof p["visibleMarked"] !== "boolean")
return "missing visibleMarked";
if (typeof p["state"] !== "string" || !CONSOLIDATION_PLAN_STATES.has(p["state"]))
return "unrecognized state";
if (!Array.isArray(p["products"]) || !p["products"].every((e) => typeof e === "object" && e !== null && typeof e.id === "string"))
return "malformed products";
const productIds = p["products"].map((e) => e.id);
const states = p["productStates"];
if (typeof states !== "object" || states === null)
return "malformed productStates";
const stateKeys = Object.keys(states);
if (stateKeys.length !== productIds.length || !productIds.every((id) => states[id] === "pending" || states[id] === "applied" || states[id] === "conflict")) {
return "productStates do not cover the product set one-to-one";
}
if (!Array.isArray(p["directed"]) ||
!p["directed"].every((d0) => {
if (typeof d0 !== "object" || d0 === null)
return false;
const d = d0;
if (typeof d["id"] !== "string" || typeof d["intentRequestId"] !== "string" || typeof d["baseRev"] !== "string")
return false;
if (d["op"] !== "update" && d["op"] !== "delete")
return false;
if (typeof d["state"] !== "string" || !CONSOLIDATION_DIRECTED_STATES.has(d["state"]))
return false;
if (d["op"] === "update") {
if (typeof d["plannedPostRev"] !== "string")
return false;
if (d["state"] === "pending" && (typeof d["entry"] !== "object" || d["entry"] === null))
return false;
}
else if (d["entry"] !== undefined)
return false;
return true;
})) {
return "malformed directed set";
}
const intentIds = new Set();
if (!Array.isArray(p["intents"]) ||
!p["intents"].every((i0) => {
if (typeof i0 !== "object" || i0 === null)
return false;
const i = i0;
if (typeof i["requestId"] !== "string")
return false;
intentIds.add(i["requestId"]);
return typeof i["state"] === "string" && CONSOLIDATION_INTENT_STATES.has(i["state"]);
})) {
return "malformed intents";
}
if (!p["directed"].every((d) => intentIds.has(d.intentRequestId)))
return "directed patch references an undeclared intent";
const freezeRefused = p["freezeRefusedInputIds"];
if (freezeRefused !== undefined && (!Array.isArray(freezeRefused) || !freezeRefused.every((x) => typeof x === "string"))) {
return "malformed freezeRefusedInputIds";
}
if (p["mintExposure"] !== undefined && p["mintExposure"] !== "partitioned")
return "malformed mintExposure echo";
if ((p["v"] === 2) !== (freezeRefused !== undefined)) {
return p["v"] === 2 ? "v2 plan without its freezeRefusedInputIds member" : "freezeRefusedInputIds on a v1 plan";
}
if (!Array.isArray(p["audit"]))
return "malformed audit trail";
return undefined;
}
export function readConsolidationPlan(controlDir, planId) {
if (!isValidConsolidationPlanId(planId))
return { state: "absent" };
const path = planPath(controlDir, planId);
if (!existsSync(path))
return { state: "absent" };
try {
const raw = readStrictSidecar(join(controlDir, CONSOLIDATION_PLANS_DIR), `${planId}.json`, "memory consolidation plan");
const bad = planShapeInvalid(raw, planId);
if (bad !== undefined)
return { state: "corrupt", detail: bad };
return { state: "ok", plan: raw };
}
catch (err) {
return { state: "corrupt", detail: thrownText(err) };
}
}
export function listConsolidationPlanIds(controlDir) {
const dir = join(controlDir, CONSOLIDATION_PLANS_DIR);
if (!existsSync(dir))
return [];
try {
return readdirSync(dir)
.filter((f) => f.endsWith(".json") && !f.endsWith(".corrupt.json"))
.map((f) => f.slice(0, -".json".length))
.filter((id) => isValidConsolidationPlanId(id));
}
catch {
return [];
}
}
export function quarantineCorruptPlan(controlDir, planId) {
if (!isValidConsolidationPlanId(planId))
return undefined;
const from = planPath(controlDir, planId);
if (!existsSync(from))
return undefined;
const name = `${planId}.corrupt.json`;
try {
renameSync(from, join(controlDir, CONSOLIDATION_PLANS_DIR, name));
return name;
}
catch {
return undefined;
}
}
function coerceIntentFile(raw) {
if (raw === undefined)
return { v: 1, rows: {} };
if (typeof raw !== "object" || raw === null || raw.v !== 1 || typeof raw.rows !== "object" || raw.rows === null) {
throw new ControlPlaneCorruptError("memory consolidation intent-credential account has an unrecognized shape (fail-closed sidecar)");
}
return raw;
}
export function recordIntentCredentials(controlDir, rows) {
if (rows.length === 0)
return [];
return lockedStrictUpdate(controlDir, CONSOLIDATION_INTENTS_FILE, "memory consolidation intent-credential account", coerceIntentFile, (file) => {
const written = [];
for (const row of rows) {
if (file.rows[row.requestId] !== undefined)
continue;
file.rows[row.requestId] = row;
written.push(row.requestId);
}
return written.length > 0 ? { next: file, result: written } : { result: written };
});
}
export function readIntentCredentials(controlDir) {
const raw = readStrictSidecar(controlDir, CONSOLIDATION_INTENTS_FILE, "memory consolidation intent-credential account");
return coerceIntentFile(raw).rows;
}
export function deriveProductSlug(name, fallback) {
const base = (name ?? "").toLowerCase().replace(/[^a-z0-9._-]+/g, "-").replace(/^[-.]+|[-.]+$/g, "");
return base.length > 0 ? base : fallback;
}
export class ConsolidationRefusedError extends Error {
code;
reasons;
occurrenceId;
constructor(code, message, reasons = []) {
super(reasons.length > 0 ? `${message}\n${reasons.map((r) => ` - ${r}`).join("\n")}` : message);
this.code = code;
this.reasons = reasons;
this.occurrenceId = uuidv7();
}
}
export function productAddPatch(product) {
return { op: "add", id: product.id, entry: product, guard: "absent" };
}
export const CONSOLIDATION_RUN_STOP_REASONS = Object.freeze(["converged", "fuse_residue", "max_cycles", "parked", "refused", "driver_failed", "mint_invalidated", "purity_violation"]);