UNPKG

@sema-agent/core

Version:

Stateless, task-oriented AI agent core

51 lines (50 loc) • 2.93 kB
import { type WorkflowRunListByScopeOptions, type WorkflowRunStore, type WorkflowRunSummary } from "../../core/workflow-run-store.js"; import type { WorkflowRun } from "../../orchestration/workflow.js"; import { type CorruptReadInfo } from "./corrupt-read-sink.js"; export interface FileWorkflowRunStoreOptions { /** When false, a ledger append is NOT fsync'd (the observability store is non-engine-critical). Default true. */ fsync?: boolean; /** Compact the ledger into a snapshot once it exceeds this many events (then truncate). Default 1000. */ compactEvery?: number; /** The observability ledger's seat; see {@link import("./shared-ledger.js").LedgerPaths.onCorruptRead}. */ onCorruptRead?: (info: CorruptReadInfo) => void; } export declare class FileWorkflowRunStore implements WorkflowRunStore { private readonly fsyncEnabled; private readonly compactEvery; /** RB-59: authoritative state is SHARED per canonical directory (see the note above the class). */ private readonly ledger; /** RB-145: this instance's own close latch — the refcount belongs to the DIRECTORY, not to callers. */ private closed; private get runs(); constructor(root: string, opts?: FileWorkflowRunStoreOptions); /** Serialize an op behind any in-flight op on the same id (the in-process per-id async mutex). */ private withLock; /** Commit one ledger event (append + fsync) THEN flip the in-memory map (crash-safe ordering), then * the best-effort housekeeping compaction (RB-150/RB-167) — all three steps in the base. */ private commit; put(id: string, run: WorkflowRun): Promise<void>; get(id: string): Promise<WorkflowRun | null>; update(id: string, scope: string, run: WorkflowRun, expect?: { rev: number; }): Promise<boolean>; listByScope(scope: string, opts?: WorkflowRunListByScopeOptions): Promise<WorkflowRunSummary[]>; reap(scope: string, now: number, opts?: { maxAgeMs?: number; keep?: number; }): Promise<number>; /** Force a compaction now (test/inspection): rewrite the snapshot from the authoritative map and * truncate the live ledger (RB-167's closeForSwap recipe lives in the base). */ compactNow(): void; /** Test/inspection helper: number of stored runs. */ get size(): number; /** * Release the append handle (best-effort). The LAST holder over the directory also drops its * cross-process writer fence (`<dir>/LOCK`), so a successor process can open the same run ledger. * There is no OTHER door: this store is never constructed by `FileStorageBackend`, so nothing else * ever hands its fence back — the doc line that used to credit "the backend factory" here named a * release that could not happen under any assembly, for a lock this store did not hold in the first * place (see the class note above). */ close(): void; }