Files
deepseek-harness/packages/api/session-controller
Tianyi Cui 165cc31eb8 perf(llm,host): read embedded Assistant streams per compact record
Session format v2 embeds each attempt's compact stream in
assistant/message and assistant/attempt, but Host and client consumers
still expanded it into per-member TimedStreamChunk arrays and did
per-member work; expandAssistantStream materializes the full array before
find/toReversed/break can answer. Session Stats (the projection phase of
every Session open), the token meter's usage and provider-assembly folds,
the subagent output fold, and the Session Controller image lookup still
paid O(members) allocation and time per settlement.

The Chat and Trajectory definitions were already settled from
message.content on master; the remaining per-member folds stay.

dsh-llm now exports record-level readers (first token, visible content,
visible text, last raw chunk of a type, raw chunks of a type, joined
text, run-aware assembly, per-run first-token/first-visible times) that
scan the compact records once with early exit. Session Stats reads
assistantStreamFirstTokenTime, the token meter reads
lastAssistantStreamChunk(stream, 'usage') and assembles through
assembleAssistantStream, the subagent output fold appends
joinAssistantStreamText, and the Session Controller scans
assistantStreamChunks(stream, 'block-end').

expandAssistantStream is deliberately not memoized: retaining expansions
costs roughly ten times the compact stream for the Session's lifetime.
It remains the validating path at durable boundaries.

Synthetic 200-turn v0 migration benchmark, median of five: first-open
projection 28.0 ms -> 5.4 ms, first-open total 76.9 -> 50.0 ms, peak RSS
137.2 -> 94.9 MB; reopen projection 17.8 -> 5.6 ms; all phase budgets and
the 128 MB heap constraint keep passing.
2026-09-06 12:41:25 +08:00
..

description, kind
description kind
Host and Client session control: create, resume, prompt, follow history, and project live session state. package-reference

Session Controller

English | 中文

Summary

@deepseek-ai/dsh-api-session-controller owns the Host ctx.sessionController service and the generated Client session, skills, and fileReferences Remote namespaces. It serves Session lifecycle and history, the Host-generation model catalog, workspace-path opening, user-invocable skill discovery, and Agent-scoped file references. Use it through API Gateway when a Client needs operations addressed by a Session.

Table of Contents


Use this package

History pages and follow opening snapshots carry one { type: 'event', event: SessionWireEvent } record per durable Session event. The Client retains each accepted record as one durable SessionEventLikeEntry; Assistant token boundaries remain inside the compact stream on assistant/message or assistant/attempt. Tool arguments, result content, failures, and tool/result.data.meta pass through unchanged; the controller does not resolve a Tool definition, run a presenter, or attach UI data.

Each endpoint states its activation policy. List reads only stored headers and projection-cache rows: it never calls per-session stat or opens a cold Session body. A current-format cache identity may supply every list hint; a lifecycle-matching predecessor cache may supply only its version-compatible title as a stale display fact, never as an authoritative fold seed. Search, attachment, history pages, log following, skill discovery, and workspace-path opening can inspect persistence without activating an Agent; canOpenWorkspacePath() reports native-opening availability without addressing a Session. Queue mutation and cancellation require live state; model, rename, prompt, and file-reference operations may resolve or resume an ordinary Session. Prompt admission consumes opaque receipts from the injected fileUploads Host service and resolves every same-Agent receipt before sending the complete ordered content list through ctx.attachments. Prompt retries whose requestId is already queued or logged return the original acceptance without inserting another message. Create and fork are the only operations that create a new Agent directly. The skill catalog instead uses a live Agent when present or the recorded preset's standing scope when cold, so listing never starts an Agent.

The Client adapter exposes SessionEventStream, a Gateway RemoteJournalStream bound to one ordinary or direct-subagent address. It opens follow before the initial page, publishes only contiguous replace, prepend, append, and settle-assistant changes, and repairs reconnect or sequence gaps through a tail page. Backwards paging has two verbs: loadOlder() pulls one 50-message page, and loadThrough(seq) — the turn-jump loader — loops 200-message pages until the window covers the target seq, lowering a shared target on repeated calls, stopping on a page that makes no progress, and reporting busy through the same loadingOlder snapshot bit. The Web adapter explicitly opts into cursorless Assistant frames: each opening carries the active attempt's startedAfterSeq, nextIndex, and compact stream, and every stream member becomes a Client-only assistant/live-chunk entry ordered between durable cursors. The Host captures a follower-local arrival ordinal with that baseline and suppresses buffered frames at or before the cut; a replacement Agent may restart frame revision at one. A durable assistant/message or assistant/attempt arriving after an active opening stays staged only when its seq follows startedAfterSeq and its Turn and Step match; the matching end type, seq, and index publishes one named settlement delta that retires the attempt's transient rows and adds the durable entry while earlier same-step retries remain visible. Revision, dense-index, or settlement gaps for a known attempt reopen follow, while a controller that missed the start ignores unknown-attempt frames and publishes their durable settlement normally. An abandoned end publishes a settlement delta without a durable entry so its transient rows retire immediately. A durable gap-repair page has no Assistant baseline, so its held notification reopens follow once for a paired page and baseline. Every history record covers exactly its event seq. A business, persistence, or unresolved continuity failure terminates the stream, while only physical carrier loss selects automatic resumption. SessionControlStream is a Gateway RemoteSnapshotStream; every generation opens with a complete process-local baseline, so reconnect replaces queue, jobs, and projection state instead of treating transient values as durable events. Client Agent contexts provide the identity used by the independent fileUpload service; Session objects expose lifecycle, prompt, queue, and history operations rather than file transfer.

The Session object also carries local submission echoes: session.beginSubmission inserts one into SessionSnapshot.pendingSubmissions synchronously, before the caller serializes and prompts, so a conversation UI can show the message on the submit click's own frame. The echo stores ordered image previews and durable file references. Session derives its transcript, queued, or steering placement from the current running state and requested delivery mode, then retains that placement while serialization is in flight. The prompt's requestId is the correlation identity: the Host echoes it as the durable user source's rpcId, and queue occurrences project it as SessionQueuedItem.rpcId. An echo retires one animation frame after its durable event or queue occurrence is observed, immediately when its identified prompt fails or is abandoned, and as failed on disposal. Each retirement fires onRetire exactly once; an observed retirement includes the ordered durable attachment references so the composer can release successful cards while preserving failed drafts. Echoes are Client memory only; reload and reconnect rebuild the conversation from durable events alone.


Configuration

Field Default Meaning
nativeOpen platform-detected Whether Session workspace paths can be handed to a native desktop opener

The generated configuration catalog is the exhaustive source for accepted fields and their JSDoc.


Model Experience

None, as invoked Agent commands own any model-visible effect.

KV Cache effect

No direct effect; model requests remain owned by the Agent and LLM packages.

Known Limitations and Deferred Work

  • Control baselines represent process-local state and therefore cannot reconstruct jobs after a Host restart.
  • A failed follow resumption remains visible to the caller instead of retrying indefinitely.
  • The raw browser upload is one streaming HTTP request without resumable offsets; a retry sends the file again from byte zero.
  • File-reference completion uses the shared Agent lookup and can resume a cold Session; the skills/list catalog is the non-activating alternative for skill metadata.

Dev Note

Working context for maintainers — click to expand

None.

Runtime invariant: No companion is published. Every page and frame is checked against the addressed durable Session.