@sema-agent/core
Version:
Stateless, task-oriented AI agent core
51 lines (50 loc) • 2.93 kB
TypeScript
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;
}