/** * Ambient session context (Phase 62, STEP-62-01). * * `SessionService` carries the "current session" through the Effect * environment so every agent and function inside a workflow reads and writes * the same conversation history without threading a `conversationId` / * `previousMessages[]` by hand. * * The current session lives in a `FiberRef>`. Setting it * with `withSession` uses `Effect.locally`, so the value is scoped to that * effect and **inherited by child fibers** — the steps of a workflow, whether * run sequentially or forked concurrently, all observe the same session, while * sibling workflows on other fibers stay isolated (no cross-fiber leak). * * This step is additive: the service is standalone and not yet wired into the * runtime or agent execution (STEP-62-02 / STEP-62-03). */ import { Context, Effect, Layer, Option, Schema } from 'effect'; import { ContextStorageService } from './service'; /** * A conversation-session identifier. Branded so it can't be confused with an * arbitrary string; maps 1:1 onto the storage layer's `conv_${UUID}` ids. */ export declare const SessionId: Schema.brand; export type SessionId = Schema.Schema.Type; /** Coerce a raw id into a branded `SessionId`. */ export declare const makeSessionId: (id: string) => SessionId; /** A handle to an open session. Minimal for now; may carry metadata later. */ export interface SessionHandle { readonly id: SessionId; } export interface SessionService { /** * Open a session: resume the given id, or (when omitted) mint a fresh one via * the storage layer's id generator. Returns a handle to pass to * `withSession`. Opening does not by itself make the session ambient. */ readonly open: (id?: string) => Effect.Effect; /** The ambient session on the current fiber, if any. */ readonly current: Effect.Effect>; /** * Run `effect` with `session` as the ambient session. The binding is scoped * to `effect` and inherited by its child fibers; callers outside are * unaffected. */ readonly withSession: (session: SessionHandle | string, effect: Effect.Effect) => Effect.Effect; /** * Auto-create (when `id` is omitted) or resume (when given) a session, run * `effect` inside it, and return both the session handle and the result. The * handle lets the caller echo the id back for later resumption. This is the * "session auto-created on first input, resumable by id anytime" entry point. */ readonly use: (id: string | undefined, effect: Effect.Effect) => Effect.Effect<{ readonly session: SessionHandle; readonly result: A; }, E, R | ContextStorageService>; } export declare const SessionService: Context.Tag; /** * Resolve the conversation id a workflow should run under: the `explicit` id * when given, otherwise the ambient session id (when a `SessionService` is in * context and a session is open), otherwise `undefined`. * * Uses `Effect.serviceOption` so it adds no requirement — callers that run * without a `SessionService` simply get the explicit id or `undefined`. This is * the shared precedence (explicit > ambient) used by the pipeline and graph * execution paths. */ export declare const resolveAmbientConversationId: (explicit?: string) => Effect.Effect; /** * Live implementation. Scoped because the ambient `FiberRef` is created once * per runtime and shared by every fiber that runs against it. */ export declare const SessionServiceLive: Layer.Layer; //# sourceMappingURL=session-service.d.ts.map