@sema-agent/core
Version:
Stateless, task-oriented AI agent core
65 lines (64 loc) • 2.79 kB
JavaScript
import { sessionRecordBindsIncarnation, usableSessionIncarnation } from "./layout.js";
import { thrownText } from "../thrown-value.js";
export function createSessionIncarnationSeat(input) {
const { resolve, onIncident } = input;
let faultAnnounced = false;
const separationAnnounced = new Set();
const disclose = (code, message) => {
if (onIncident === undefined)
return;
try {
const e = new Error(message);
e.code = code;
onIncident(e);
}
catch {
}
};
const incarnationOf = (sessionId) => {
if (resolve === undefined)
return undefined;
try {
const answer = resolve({ sessionId });
return usableSessionIncarnation(answer);
}
catch (err) {
if (!faultAnnounced) {
faultAnnounced = true;
disclose("memory.session_incarnation_unreadable", `the session incarnation resolver threw (${thrownText(err)}) — this run cannot tell one occupant of a session id from the next, so every durable session record binds by id alone (the conservative reading, and the behavior of a deployment that wires no resolver)`);
}
return undefined;
}
};
return {
incarnationOf,
identityRead: (sessionId) => {
const incarnation = incarnationOf(sessionId);
return {
...(incarnation !== undefined ? { incarnation } : {}),
onSeparated: (recorded) => {
if (separationAnnounced.has(sessionId))
return;
separationAnnounced.add(sessionId);
disclose("memory.session_incarnation_mismatch", `a durable record stands for session ${sessionId} but it was minted by a DIFFERENT occupant of that id (recorded incarnation ${JSON.stringify(recorded)}, this run ${JSON.stringify(incarnation)}) — it does not bind this run and the record is kept where it is. Either the id was recycled after its previous session was deleted, or the deployment's incarnation resolver is not stable for the life of one session`);
},
};
},
};
}
export function rememberForIdentity(map, sessionId, record) {
const rows = map.get(sessionId);
if (rows === undefined) {
map.set(sessionId, [record]);
return;
}
if (rows.some((r) => r.incarnation === record.incarnation))
return;
rows.push(record);
}
export function recalledForIdentity(map, sessionId, asking) {
return map.get(sessionId)?.find((r) => sessionRecordBindsIncarnation(r.incarnation, asking));
}
export function recalledForAnyIdentity(map, sessionId) {
return map.get(sessionId)?.[0];
}