eve
Version:
Filesystem-first framework for durable backend AI agents that run anywhere.
118 lines (117 loc) • 5.04 kB
TypeScript
/**
* Durable session storage.
*
* Session-mutating steps return the current snapshot inside
* {@link DurableSessionState}; Workflow step results are the atomic
* persistence boundary for session program memory. The legacy
* `"eve.session"` stream remains as a fallback for old in-flight
* sessions that only carry a small state handle.
*
* The driver workflow run is pinned to the deployment that called
* `start()`; child turn workflows run on latest. Both
* {@link DurableSessionState} and {@link DurableSessionSnapshot} carry
* a `version` so a pinned driver can ferry shapes written by newer
* steps. Adding optional fields is forward-compatible (devalue
* preserves unknown POJO fields); shape-breaking changes bump
* `version` and add a migrator.
*/
import type { ModelMessage } from "ai";
import { type HarnessEmissionState } from "#harness/emission.js";
import type { HarnessSession, SessionStateMap } from "#harness/types.js";
import type { SandboxState } from "#sandbox/state.js";
import type { JsonObject } from "#shared/json.js";
/** Current wire version for {@link DurableSessionState} and {@link DurableSessionSnapshot}. */
export declare const DURABLE_SESSION_VERSION = 1;
/**
* Serializable handle to a durable session.
*
* Carries the current session snapshot plus the small projections the
* workflow body needs without taking a step boundary: identity, the
* hook continuation token,
* `hasProxyInputRequests` (a closed-contract short-circuit that lets
* the driver skip a per-delivery proxy-routing step when no
* descendant subagent is active), and `emissionState` (so workflow-body
* framework steps can stamp protocol events
* with `{ turnId, sequence, stepIndex }` without reading the full
* durable session). All other control-plane state travels via
* {@link import("#execution/next-driver-action.js").NextDriverAction}.
* `snapshot` is optional so old stream-backed states can still read
* from the legacy `eve.session` fallback.
*/
export interface DurableSessionState {
readonly version: typeof DURABLE_SESSION_VERSION;
readonly sessionId: string;
readonly continuationToken: string;
readonly hasProxyInputRequests: boolean;
readonly emissionState: HarnessEmissionState;
readonly snapshot?: DurableSessionSnapshot;
}
/**
* Durable projection of {@link HarnessSession} embedded in state
* snapshots or legacy `eve.session` stream chunks.
*
* Omits `agent.modelReference`, `agent.tools`,
* `agent.compactionModelReference`, and the `compaction` thresholds —
* those are rebuilt every turn from `bundle.turnAgent` by
* {@link import("#execution/session.js").hydrateDurableSession}.
* `agent.system` is the last applied prompt snapshot. Before each model step,
* the execution layer replaces it from the current deployment's
* `bundle.turnAgent`.
*/
export interface DurableSession {
readonly sessionId: string;
/**
* Top user-facing session id in the dispatch chain. Optional because
* a top-level session is its own root. Persisted so a rehydrated
* subagent session still knows its root after a workflow step
* boundary.
*/
readonly rootSessionId?: string;
readonly continuationToken: string;
readonly history: ModelMessage[];
readonly limits?: HarnessSession["limits"];
readonly outputSchema?: JsonObject;
readonly state?: SessionStateMap;
readonly sandboxState?: SandboxState;
readonly subagentDepth?: number;
readonly workflowMaxSubagents?: number;
readonly agent: {
readonly system: string;
};
readonly compaction?: {
readonly lastKnownInputTokens?: number;
readonly lastKnownPromptMessageCount?: number;
};
}
/** Versioned wrapper around a {@link DurableSession} on the wire. */
export interface DurableSessionSnapshot {
readonly version: typeof DURABLE_SESSION_VERSION;
readonly session: DurableSession;
}
/** Projects a {@link HarnessSession} into the boundary-safe state value. */
export declare function projectSessionState(input: {
readonly session: HarnessSession;
}): DurableSessionState;
/**
* Reads the latest durable session snapshot and returns the
* {@link DurableSession} inside.
*
* New states carry the snapshot directly through Workflow step
* results. States without `snapshot` fall back to the legacy
* `eve.session` stream tail (`startIndex: -1`). The snapshot is
* migrated to {@link DURABLE_SESSION_VERSION} before return; unknown
* versions throw.
*
* Devalue handles encode/decode so rich types in the session (URL
* `FilePart.data`, Buffer, Date, Map, Set) round-trip structurally.
*
* MUST be called from inside a `"use step"` body.
*/
export declare function readDurableSession(state: DurableSessionState): Promise<DurableSession>;
/**
* Creates the projected {@link DurableSessionState} with the current
* snapshot embedded in the Workflow step result.
*/
export declare function createDurableSessionState(input: {
readonly session: HarnessSession;
}): DurableSessionState;