@sema-agent/core
Version:
Stateless, task-oriented AI agent core
46 lines (45 loc) • 1.86 kB
JavaScript
import { SessionError, } from "../harness/types.js";
import { StoredSession } from "./session.js";
import { uuidv7 } from "./uuid.js";
export function createSessionId() {
return uuidv7();
}
export function createTimestamp() {
return new Date().toISOString();
}
export function toSession(storage) {
return new StoredSession(storage);
}
function rerootIfHeadless(storage, entries) {
const head = entries[0];
if (head === undefined || head.parentId === null)
return entries;
if (entries.some((e) => e.id === head.parentId))
return entries;
if (storage.getFloorId?.() !== head.id)
return entries;
return [{ ...head, parentId: null }, ...entries.slice(1)];
}
export async function getEntriesToFork(storage, options) {
if (!options.entryId) {
return rerootIfHeadless(storage, await storage.getEntries());
}
const target = await storage.getEntry(options.entryId);
if (!target) {
throw new SessionError("invalid_fork_target", `Entry ${options.entryId} not found`);
}
let effectiveLeafId;
if ((options.position ?? "before") === "at") {
effectiveLeafId = target.id;
}
else {
if (target.type !== "message" || target.message.role !== "user") {
throw new SessionError("invalid_fork_target", `Entry ${options.entryId} is not a user message`);
}
effectiveLeafId = target.parentId;
if (effectiveLeafId !== null && storage.getFloorId?.() === target.id) {
throw new SessionError("invalid_fork_target", `Entry ${options.entryId} is the floor of a bounded session window — forking "before" it would branch from history this session did not load. Fork "at" it, or wake the session unbounded first.`);
}
}
return rerootIfHeadless(storage, await storage.getPathToRoot(effectiveLeafId));
}