UNPKG

@sema-agent/core

Version:

Stateless, task-oriented AI agent core

69 lines (68 loc) • 2.49 kB
export const MAX_LANDING_ADMISSION_ROUNDS = 4; export class LandingsNeedAdmission extends Error { landings; constructor(landings) { super("memory landings need admission"); this.landings = landings; } } const landingKey = (l) => `${l.scope}\u0000${l.slug}`; export function requireLandingsAdmitted(admitted, landings) { const pending = landings.filter((l) => !admitted.has(landingKey(l))); if (pending.length > 0) throw new LandingsNeedAdmission(pending); } export function cutPerLanding(ops, evidence, shares, finalAccount) { const cuts = []; let open; let opsAt = 0; let evidenceAt = 0; for (const s of shares) { if (s.opsEnd > opsAt || s.evidenceEnd > evidenceAt) { if (open === undefined) cuts.push((open = { ops: [], evidence: [], account: finalAccount })); open.ops.push(...ops.slice(opsAt, s.opsEnd)); open.evidence.push(...evidence.slice(evidenceAt, s.evidenceEnd)); opsAt = s.opsEnd; evidenceAt = s.evidenceEnd; } if (s.landed !== undefined && open !== undefined) { open.account = s.landed; open = undefined; } } const last = cuts[cuts.length - 1]; if (last !== undefined) last.account = finalAccount; return cuts; } export async function applyEachAlone(backend, patches, before) { const report = { applied: [], conflicts: [] }; for (const p of patches) { before(); const r = await backend.applyPatches([p]); report.applied.push(...r.applied); report.conflicts.push(...r.conflicts); } return report; } export async function admittingLandings(admit, run) { if (admit === undefined) return run(undefined); const admitted = new Set(); for (let round = 0;; round++) { try { return await run(admitted); } catch (err) { if (!(err instanceof LandingsNeedAdmission)) throw err; if (round >= MAX_LANDING_ADMISSION_ROUNDS) { throw Object.assign(new Error(`memory landings kept moving: ${err.landings.length} spelling(s) were still unadmitted after ${MAX_LANDING_ADMISSION_ROUNDS} rounds, nothing was written`), { code: "memory.landing_unstable" }); } await admit(err.landings); for (const l of err.landings) admitted.add(landingKey(l)); } } }