UNPKG

@sema-agent/core

Version:

Stateless, task-oriented AI agent core

67 lines (66 loc) • 2.89 kB
import { SessionError } from "../harness/types.js"; import { validateEntriesForImport } from "./import-validate.js"; import { InMemorySessionStorage } from "./memory-storage.js"; import { assertForkTarget, createSessionId, createTimestamp, forkRowCells, getEntriesToFork, incarnationCell, toSession } from "./repo-utils.js"; export class InMemorySessionRepo { sessions = new Map(); async create(options = {}) { if (options.id !== undefined) { const existing = this.sessions.get(options.id); if (existing) return existing; } const metadata = { id: options.id ?? createSessionId(), createdAt: createTimestamp(), ...incarnationCell(undefined), }; const storage = new InMemorySessionStorage({ metadata }); const session = toSession(storage); this.sessions.set(metadata.id, session); return session; } async open(metadata) { const session = this.sessions.get(metadata.id); if (!session) { throw new SessionError("not_found", `Session not found: ${metadata.id}`); } return session; } async list() { return Promise.all([...this.sessions.values()].map((session) => session.getMetadata())); } async delete(metadata) { this.sessions.delete(metadata.id); } async fork(sourceMetadata, options) { assertForkTarget(sourceMetadata.id, options.id); const source = await this.open(sourceMetadata); const forkedEntries = await getEntriesToFork(source.getStorage(), options); const metadata = { id: options.id ?? createSessionId(), createdAt: createTimestamp(), ...forkRowCells(await source.getMetadata()), }; const storage = new InMemorySessionStorage({ metadata, entries: forkedEntries }); const session = toSession(storage); this.sessions.set(metadata.id, session); return session; } async exportEntries(sessionId) { const session = await this.open({ id: sessionId, createdAt: "" }); return session.getStorage().getEntries(); } async importEntries(sessionId, owner, entries, options) { void owner; const validated = validateEntriesForImport(entries, options); let prior = this.sessions.get(sessionId); let header = prior !== undefined ? await prior.getMetadata() : undefined; while (this.sessions.get(sessionId) !== prior) { prior = this.sessions.get(sessionId); header = prior !== undefined ? await prior.getMetadata() : undefined; } const metadata = { id: sessionId, createdAt: createTimestamp(), ...incarnationCell(header) }; this.sessions.set(sessionId, toSession(new InMemorySessionStorage({ metadata, entries: validated }))); } }