/** * sessions domain contract. Method signatures are the source of truth: * unary methods take the RpcRequest

narrow form and the impl echoes rpcId; everything * else references RequestPayload<'session.*'> / ResponseValue<'session.*'>. */ import type { AttachmentIdType, ImageAttachmentRef, ImageMediaType } from '@deepseek-ai/dsh-attachment' import type { SessionEvent, SessionId } from '@deepseek-ai/dsh-session/types' import type { RpcId, RpcRequest, RpcResponse } from './rpc.ts' import type { ToolEventView } from './events.ts' declare module '@deepseek-ai/dsh-llm' { interface MessageSourceMap { /** * The prompt's rpcId is passed through MessageSource into the `user/message` event * (the client uses it to reconcile the optimistically * echoed provisional message with the event stream). kind stays `'user'` — the model face * carries no transport vocabulary; rpcId is an extra durable-JSON field passed back to the client with the event. */ 'user-rpc': { kind: 'user'; rpcId: RpcId } } } /** * One history page entry: the raw event plus the optional host-computed render * intent (same semantics as the mux frame's `view` slot — a pagination-time * derivation, never persisted). */ export interface HistoryEntry { event: SessionEvent view?: ToolEventView } /** Session list entry (v1 builds no index: list does readdir+stat). */ export interface SessionSummary { sessionId: SessionId /** Persisted file mtime. */ updatedAt: number /** Status of the attached agent; always false for cold (unattached) sessions. */ running: boolean /** fork/spawn lineage (session.header.parentSession passthrough); absent for root sessions. */ parentSessionId?: SessionId /** Session working directory (header.cwd passthrough); absent when unrecorded. */ cwd?: string } /** Browser-submitted prompt content; image bytes are promoted to durable references by the host. */ export type PromptContentPart = | { type: 'text'; text: string } | { type: 'image'; mediaType: ImageMediaType; data: string; name?: string } /** Session-domain unary methods (the map keys session.* of RpcMethodMap). */ export interface SessionsApi { /** Lists persisted sessions (updatedAt descending). v1 returns everything; cursor is a reserved seat, unimplemented. */ list(request: RpcRequest<{ cursor?: string }>): Promise> /** Creates a new session (and its agent, idle and standing by). */ create(request: RpcRequest<{ cwd?: string }>): Promise> /** * Reads a window of history events; page boundaries align to message boundaries: one page = * all raw events owned by a whole number of messages (including their chunk / tool events), * never cut mid-message. The tail page (beforeSeq absent) additionally carries the in-flight * partial — chunk events already emitted for the last unfinalized message. * Each entry pairs the raw SessionEvent with the host-computed view (tool events whose * presenter produced one, evaluated against the registry at pagination time); the client * rebuilds the surface from the events with the shared fold. */ history(request: RpcRequest<{ sessionId: SessionId; beforeSeq?: number; maxMessages?: number }>): Promise> /** Sends text plus temporary base64 image uploads; the host persists images before calling the agent. */ prompt(request: RpcRequest<{ sessionId: SessionId; mode: 'queue' | 'steer'; content: PromptContentPart[] }>): Promise> /** Reads one durable image after proving that this session's log references its id. */ attachment(request: RpcRequest<{ sessionId: SessionId; attachmentId: AttachmentIdType }> ): Promise> /** Stops: clears both FIFOs + aborts the current step (1:1 with agent.cancel). */ cancel(request: RpcRequest<{ sessionId: SessionId }>): Promise> }