eve
Version:
Filesystem-first framework for durable backend AI agents that run anywhere.
107 lines (106 loc) • 5.05 kB
TypeScript
import type { EveAgentReducer } from "#client/reducer.js";
import type { ClientSession } from "#client/session.js";
import { type MessageStreamEvent } from "#protocol/message.js";
import type { CancelSessionResult, ClientAuth, HeadersValue, SendTurnPayload, ClientSessionState } from "#client/types.js";
/**
* Lifecycle state of an {@link EveAgentStore}: `ready` (idle), `resuming`
* (checking an attached session for continuation), `submitted` (turn sent,
* awaiting the first event), `streaming` (events arriving), and `error` (the
* turn failed). A new turn advances `ready` to `submitted` to `streaming` to
* `ready` (or `error`).
*/
export type EveAgentStoreStatus = "error" | "ready" | "resuming" | "streaming" | "submitted";
/**
* Prepares one outbound turn immediately before the client sends it, e.g. to
* attach fresh one-turn client state such as page context via `clientContext`.
*/
export type PrepareSend = (input: SendTurnPayload) => SendTurnPayload | Promise<SendTurnPayload>;
/**
* Immutable projected state of an {@link EveAgentStore}, read on every render.
*
* `data` is the reducer output, `events` is the raw server stream-event log for
* this session, `session` is the current serializable cursor, `status` is the
* turn lifecycle state, and `error` is the last failure (or `undefined`).
*/
export interface EveAgentStoreSnapshot<TData> {
readonly data: TData;
readonly error: Error | undefined;
readonly events: readonly MessageStreamEvent[];
readonly session: ClientSessionState | undefined;
readonly status: EveAgentStoreStatus;
}
/**
* Hooks invoked while the store processes a turn.
*
* `onEvent`, `onError`, `onFinish`, and `onSessionChange` are observe-only.
* `prepareSend` runs before each turn is sent and may return a modified
* {@link SendTurnPayload} (for example to attach one-turn client context).
*/
export interface EveAgentStoreCallbacks<TData> {
readonly onError?: (error: Error) => void;
readonly onEvent?: (event: MessageStreamEvent) => void;
readonly onFinish?: (snapshot: EveAgentStoreSnapshot<TData>) => void;
readonly onSessionChange?: (session: ClientSessionState | undefined) => void;
readonly prepareSend?: PrepareSend;
}
/**
* Configuration for constructing an {@link EveAgentStore}.
*
* Requires a {@link EveAgentReducer | reducer}, plus either connection options
* (`host`, `auth`, `headers`, `initialSession`) for a
* store-owned session or an existing {@link ClientSession} via `session`.
*
* `optimistic` (default `true`) projects submitted user messages before the
* server confirms them. `host` defaults to `""`. `initialEvents` and
* `initialSession` seed prior state on construction. Passing `session` makes
* `reset()` reuse that external session rather than create a new one.
* `initialEvents` must be an ordered prefix of the same session's stream; its
* endpoint may overlap the cursor because repeated ids are applied once.
*/
export interface EveAgentStoreInit<TData> {
readonly auth?: ClientAuth;
readonly headers?: HeadersValue;
readonly host?: string;
/** Ordered prefix of the session stream used to rehydrate projected state. */
readonly initialEvents?: readonly MessageStreamEvent[];
readonly initialSession?: ClientSessionState;
readonly optimistic?: boolean;
readonly reducer: EveAgentReducer<TData>;
readonly session?: ClientSession;
}
declare const detachStore: unique symbol;
/**
* Framework-agnostic state machine for an eve agent session.
*
* Manages the send/stream lifecycle, optimistic projection, and subscriber
* notification; framework integrations (React, Vue) wrap it with their own
* reactivity primitives.
*
* Drives one turn at a time: `send` rejects while a turn is active, and
* concurrent `resume` calls share one replay. Read the latest projection via
* the `snapshot` getter, observe changes with `subscribe`, register lifecycle
* hooks with `setCallbacks`, cancel the durable in-flight turn with `cancel`,
* and discard all state with `reset`.
*/
export declare class EveAgentStore<TData> {
#private;
constructor(init: EveAgentStoreInit<TData>);
get snapshot(): EveAgentStoreSnapshot<TData>;
setCallbacks(callbacks: EveAgentStoreCallbacks<TData>): void;
subscribe(callback: () => void): () => void;
send<TOutput = unknown>(input: SendTurnPayload<TOutput>): Promise<void>;
/** Replays this store's attached durable session and follows an in-flight turn. */
resume(): Promise<void>;
/**
* Requests cooperative cancellation of the active durable turn.
*
* If the server has not emitted `turn.started` yet, the request waits for
* that turn ID. The event stream stays attached until the turn settles.
*/
cancel(): Promise<CancelSessionResult>;
[detachStore](): void;
reset(): void;
}
/** @internal Detaches local transport without cancelling durable server work. */
export declare function detachEveAgentStore<TData>(store: EveAgentStore<TData>): void;
export {};