UNPKG

agents

Version:

A home for your AI agents

333 lines (332 loc) • 11 kB
//#region src/harness/store/store.d.ts /** * A session store for harnesses, on a Durable Object's SQLite database. * * Any harness that runs its agent somewhere other than the object (a * container, a sandbox, a remote process) needs the same few things kept * durably next to it: which sessions exist, which operations were submitted * and how each one ended, and the session's history in whatever format the * harness speaks. This store keeps those and nothing more. It knows no * message format, no event vocabulary and no runtime: inputs, results, * session state and log entries are opaque JSON that the harness parses. * * Three record kinds: * * - **Sessions**: an id, an optional parent (a fork), and one JSON state * value the harness owns (model, cursors, resume handles). * - **Operations**: one row per submitted operation, keyed by an * idempotency id within its session, moving `queued` → `running` → * `done` | `unanswered`. Transitions are guarded in SQL, so a duplicate or * late transition is a no-op rather than a regression. * - **Logs**: named, append-ordered streams of JSON entries per session * (`"messages"`, `"engine"`, …). An entry may carry an id, and an entry * written again under the same id replaces the old one in place. Entries * larger than one SQLite row are split across continuation rows. * * The store is synchronous, like the SQL API under it, so a harness can * group several writes in `transaction()` without awaiting. * * @experimental The API may change before it stabilizes. */ /** A JSON value, as the store keeps it. */ type JsonValue = | string | number | boolean | null | readonly JsonValue[] | { readonly [key: string]: JsonValue; }; /** Where an operation is in its life. */ type OperationStatus = "queued" | "running" | "done" | "unanswered"; /** A session, as stored. */ type SessionRecord = { readonly id: string /** The session this one was forked from. */; readonly parent: | string | undefined /** Harness-owned state. `null` until the harness writes some. */; readonly state: JsonValue; readonly createdAt: number; readonly updatedAt: number; }; /** One operation, as stored. */ type OperationRecord = { readonly session: string /** The idempotency key, unique within the session. */; readonly id: string /** Submission order within the whole store. */; readonly seq: number; readonly status: OperationStatus /** What was submitted, in the harness's format. */; readonly input: JsonValue /** Harness-owned submission options and bookkeeping. */; readonly meta: JsonValue /** The harness's result for a `done` operation, else `null`. */; readonly result: JsonValue /** Why an `unanswered` operation ended. */; readonly reason: string | undefined; readonly createdAt: number; readonly settledAt: number | undefined; }; /** One log entry, as stored. */ type LogEntry = { /** Position in the log. Stable when the entry is replaced by id. */ readonly seq: number; readonly id: string | undefined; readonly data: JsonValue; readonly createdAt: number; }; /** One entry to append. */ type LogAppend = { /** Replace an existing entry with this id in place, instead of appending. */ readonly id?: string; readonly data: JsonValue; }; /** How an operation ended. */ type OperationOutcome = | { readonly status: "done"; readonly result: JsonValue; } | { readonly status: "unanswered"; readonly reason: string; }; /** `openHarnessStore`'s options. */ type HarnessStoreOptions = { /** * Prefix for the store's tables. Two harnesses in one object use two * prefixes. Must not start with `_cf_`, which Durable Objects reserve. * Default `harness_`. */ readonly prefix?: string; }; /** * Open the store over this object's SQLite database, creating its tables on * first use. Cheap: call it once per isolate and keep the result. * * @param storage - The Durable Object's storage. * @param options - Table prefix. * @returns The store. */ declare function openHarnessStore( storage: DurableObjectStorage, options?: HarnessStoreOptions ): HarnessStore; /** * The store. Construct it with `openHarnessStore`. * * @experimental The API may change before it stabilizes. */ declare class HarnessStore { #private; /** * @param storage - The Durable Object's storage. * @param options - Table prefix. */ constructor(storage: DurableObjectStorage, options: HarnessStoreOptions); /** * Run `fn` in one storage transaction. Writes inside it commit together or * not at all. * * @template T - What `fn` returns. * @param fn - Synchronous work against this store. * @returns What `fn` returned. */ transaction<T>(fn: () => T): T; /** * Create a session, or return the existing one with this id unchanged. * * @param input - The id, an optional parent, and the initial state. * `createdAt` keeps the creation time of a session imported from * elsewhere, so the session list stays in creation order; default now. * @returns The stored session. */ createSession(input: { readonly id: string; readonly parent?: string; readonly state?: JsonValue; readonly createdAt?: number; }): SessionRecord; /** * Read one session. * * @param id - The session id. * @returns The session, or `undefined` when there is none. */ session(id: string): SessionRecord | undefined; /** * Every session, oldest first. * * @returns The sessions. */ sessions(): SessionRecord[]; /** * Replace a session's harness-owned state. * * @param id - The session id. * @param state - The new state. * @returns False when there is no such session. */ setSessionState(id: string, state: JsonValue): boolean; /** * Delete a session with its operations and logs. * * @param id - The session id. * @returns False when there was no such session. */ deleteSession(id: string): boolean; /** * Durably queue an operation. Idempotent on `(session, id)`: a second * enqueue with the same id stores nothing and returns the first record. * * @param input - The session, the idempotency id, the input and options. * @returns The stored record, and whether this call created it. */ enqueue(input: { readonly session: string; readonly id: string; readonly input: JsonValue; readonly meta?: JsonValue; }): { readonly record: OperationRecord; readonly accepted: boolean; }; /** * Read one operation. * * @param session - The session id. * @param id - The operation id. * @returns The operation, or `undefined` when there is none. */ operation(session: string, id: string): OperationRecord | undefined; /** * Operations in submission order, optionally narrowed to one session and * to some statuses. * * @param filter - The session and statuses to keep. Default: all. * @returns The matching operations, oldest first. */ operations(filter?: { readonly session?: string; readonly status?: readonly OperationStatus[]; }): OperationRecord[]; /** * Move a queued operation to `running`. * * @param session - The session id. * @param id - The operation id. * @returns False when it was not queued. */ start(session: string, id: string): boolean; /** * Move a running operation back to `queued`, to run it again. * * @param session - The session id. * @param id - The operation id. * @returns False when it was not running. */ requeue(session: string, id: string): boolean; /** * Settle a queued or running operation. * * @param session - The session id. * @param id - The operation id. * @param outcome - How it ended. * @returns False when it had already settled or does not exist. */ settle(session: string, id: string, outcome: OperationOutcome): boolean; /** * Delete one operation, whatever its status. Its id may be enqueued * again. For replacing a record imported from elsewhere; a harness that * deletes an open operation must stop running it itself. * * @param session - The session id. * @param id - The operation id. * @returns False when there was no such operation. */ deleteOperation(session: string, id: string): boolean; /** * Forget a session's settled operations, as when the session starts * over. Open operations are kept. A forgotten operation's id may be * enqueued again. * * @param session - The session id. * @returns How many operations were deleted. */ deleteSettled(session: string): number; /** * Replace an operation's harness-owned bookkeeping. * * @param session - The session id. * @param id - The operation id. * @param meta - The new value. * @returns False when there is no such operation. */ setOperationMeta(session: string, id: string, meta: JsonValue): boolean; /** * Append entries to a session's log. An entry with an id that is already * in the log replaces that entry in place, keeping its position. * * @param session - The session id. * @param log - The log's name, such as `"messages"`. * @param entries - The entries, in order. * @returns The position of the last entry written, or of the log's end. */ append(session: string, log: string, entries: readonly LogAppend[]): number; /** * Read a session's log in order. * * @param session - The session id. * @param log - The log's name. * @param range - Entries after position `after` (exclusive), at most `limit`. * @returns The entries. */ read( session: string, log: string, range?: { readonly after?: number; readonly limit?: number; } ): LogEntry[]; /** * One entry by id. * * @param session - The session id. * @param log - The log's name. * @param id - The entry id. * @returns The entry, or `undefined`. */ entry(session: string, log: string, id: string): LogEntry | undefined; /** * The position of a log's last entry. * * @param session - The session id. * @param log - The log's name. * @returns The position, or 0 for an empty log. */ end(session: string, log: string): number; /** * Empty a session's log. * * @param session - The session id. * @param log - The log's name. */ clear(session: string, log: string): void; /** * Copy one session's log onto the end of another's, keeping entry ids. * * @param from - The source session. * @param to - The target session. * @param log - The log's name. */ copy(from: string, to: string, log: string): void; } //#endregion export { LogEntry as a, OperationStatus as c, LogAppend as i, SessionRecord as l, HarnessStoreOptions as n, OperationOutcome as o, JsonValue as r, OperationRecord as s, HarnessStore as t, openHarnessStore as u }; //# sourceMappingURL=store-BKM4Xm9M.d.ts.map