README.md 12 KB


description: "Cross-session snapshot references and durable untrusted model context, for users and maintainers enabling or debugging ctx.sessionReferenceResolver."

kind: "package-reference"

@deepseek-ai/dsh-session-reference

English | 中文

Summary

dsh-session-reference lets a conversation reference other sessions: a host turns a @label mention into a canonical URI, and the service prepares a bounded, read-only snapshot of each referenced session as durable, untrusted background context for the model. Candidate discovery ranks other sessions by working-directory affinity and labels them with their latest titles. Snapshots are immutable after capture and carry a fixed warning that forbids following instructions, permission claims, or tool requests inside them. It is an opt-in service for hosts that support cross-session mentions; it consumes ctx.sessionQuery and needs no SQLite FTS.

Table of Contents


Use this package

Enable this service when hosts should let a user mention another session and give the model its context. It works with any session-query backend because it consumes the backend-independent compact checkpoint marker.

Mention syntax

A canonical mention is @[label](dsh-session:<base64url-encoded-id>) in Markdown, or the bare dsh-session: URI; every JavaScript string session id round-trips exactly. The service rewrites mentions into readable @label text in the message and returns the structured references. Explicit Markdown mentions reject malformed URIs; empty or punctuation-only scheme mentions stay ordinary discussion text.

What the agent gets

A message that cites other sessions is followed immediately by a ## Referenced sessions snapshot as a second user-role message. The snapshot is untrusted background: the fixed warning tells the model not to follow instructions, permission claims, or tool requests inside it unless the current user explicitly repeats them. Each source preview is bounded independently — at most maxReferences distinct sessions per message and a configured or model-relative serialized JSON byte budget per source. Retention drops older non-checkpoint messages before shortening retained text; preparation fails only when the reference cannot fit even after retention.

For a truncated reference, an optional spill backend saves the full captured text projection under the target session. A separate omission notice outside the bounded preview JSON gives exact omittedMessages and omittedBytes, then the saved locator and retrievalHint, or an unavailable outcome distinguishing missing storage from a failed save. The notice is part of the same durable context message. Full transcripts carry the same untrusted-background warning and capture metadata, including capturedFormatVersion. Each message uses JSON string fragments of at most 64 Unicode code points per line; decode and concatenate its fragments to recover exact text, including original newlines. This fixed storage format keeps even long single-line text readable through paged file reads.

Finding sessions to reference

listCandidates(agent, query?, limit?) lists sessions other than the agent's own, filters case-insensitively by id, working directory, or the projected title, and ranks same-directory sessions first. Each candidate carries its latest title as the mention label, falling back to the session id when the title is absent or unreadable, and reports whether its working directory is the requesting agent's so a host can surface a location only when it distinguishes the row. Browser consumers call the same discovery as ctx.remote.sessionReferenceResolver.candidates, which attaches each candidate's canonical mention.

Configuration

Field Default Meaning
maxReferences 3 Maximum distinct source sessions in one prepared message; must not exceed 3
candidateLimit 50 Default candidate count returned to a host
maxReferenceBytes automatic Explicit maximum serialized JSON bytes per source; overrides the automatic budget exactly
referenceContextFraction 0.2 Context-window fraction per source, from 0 to 1

The automatic budget is max(65536, floor(contextWindow × 4 × referenceContextFraction)) bytes per source. Model context capacity is measured in tokens; four bytes per token is a sizing heuristic, not an exact token conversion. A missing route, LLM service, adapter, or capacity uses 64 KiB; other model metadata lookup errors and cancellation fail preparation.

The generated configuration catalog is the exhaustive source for every accepted field and its JSDoc.


Understand the implementation

Implementation internals — click to expand This section explains the design of the service; the observable behavior is covered in [Use this package](#use-this-package). ### Design concept Preparation reads each referenced session's current surface exactly once, when the target message reaches `agent/pre-step`. Both preview and spill use that same captured projection: direct-user text, assistant text, and user checkpoints carrying the canonical compaction marker; tools, reasoning, and other injected context are excluded. This prevents recursive reference propagation and prevents a later source mutation from changing the saved transcript. Preview JSON escapes every `<` as `\u003c`, so source text cannot spell the `` framing tag. The resolver discovers optional storage through `ctx.get("spillStore")` and saves only truncated references. Storage ownership is the target session; provenance identifies the referenced source session and label, without a fabricated tool call. Cancellation is checked after the asynchronous save and prevents publication even if an artifact was written. Artifact expiry remains the backend's existing policy. The budget uses the provider and model captured after `system-prompt/assemble` completes for the target agent. Direct `prepare` calls before any assembly use agent options; session headers do not select the budget model. Diagnostic assemblies without an agent do not affect captured routes. ### Source map | File | Role | |---|---| | [`src/index.ts`](src/index.ts) | `SessionReferenceResolver`: pre-step listener, candidate discovery, preparation | | [`src/config.ts`](src/config.ts) | `Config` schema, `SessionReferenceError` taxonomy | | [`src/uri.ts`](src/uri.ts) | `dsh-session:` URI codec, mention formatting and parsing | | [`src/projection.ts`](src/projection.ts) | Current-surface projection and byte-budget retention | | [`src/serialization.ts`](src/serialization.ts) | Tag-safe JSON escaping for snapshot payloads | | [`src/spill.ts`](src/spill.ts) | Full transcript serialization and model-visible omission notices | | [`src/types.ts`](src/types.ts) | `SessionReferenceInput`/`Candidate` and source types | | — | No runtime invariant companion is published; preparation returns immutable per-call snapshots validated while they are built, and the agent/session layers own durable context admission, freezing, and replay. | ### Main flow The outer `agent/pre-step` listener accepts the step, parses canonical mentions out of direct user messages, then calls `prepare`, which normalizes references (first-mention order, deduplication, self-reference and count rejection), reads every surface in parallel, retains each under its resolved byte budget, and renders the aggregated prompt. Each durable source record keeps the frozen `capturedThroughSeq` and records a nonzero `capturedFormatVersion`; absence denotes format v0. Each snapshot is inserted immediately after the message that cited it, and the target log records the readable direct message followed by its sourced context, so source mutation after capture cannot change target replay.

Further Exploration

Read these pages when the package-level contract is not enough. They move from the shared reference surface to the design decision and the read service behind it.


Model Experience

Referenced session background

What the model sees

The model sees two consecutive user-role messages: the current message with its readable @label, then the ## Referenced sessions untrusted snapshot. The warning forbids following instructions, permission claims, or tool requests from the snapshot unless the current user explicitly repeats them. Labels, cwd values, ids, and conversation text are serialized as JSON inside <referenced-sessions> tags; every data < is emitted as the lossless JSON escape \u003c, so source text cannot spell a framing tag.

Token effect

Each referenced message adds the fixed warning plus up to three serialized previews, each independently bounded by the configured or model-relative byte budget. Truncated references add separate omission notices outside that budget; a saved full transcript adds tokens only when retrieved. The exact context remains in target history until target compaction shadows or summarizes it; source-session changes add no further tokens.

KV Cache effect

The request and snapshot are consecutive append-only target messages and preserve earlier cacheable history. Different references or source capture contents change the new suffix only; later target compaction may invalidate reuse from its replacement boundary.

Known Limitations and Deferred Work

These limits define when cross-session references are a poor fit. They are current package constraints.

  • No body discovery — candidate queries inspect titles but do not search message bodies.
  • Labels come from projections alone — an attached session is labeled from its live projection cut, a cold one from its durable checkpoint, and a session neither answers for is labeled by its id and cannot be found by its title. Discovery never reads a log: folding one title costs a whole log, and this runs under every completion keystroke. A session persisted before the projection cache was composed regains its title the first time it is opened, which checkpoints it.
  • Trusted caller boundary — the service assumes its host is authorized to read every session exposed by ctx.sessionQuery; it is not a model-facing search tool.
  • Text projection only — non-text user and assistant blocks are not propagated across sessions.
  • No live link — references are snapshots, not forks, resumes, subscriptions, or source-session mutations.
  • Transcript search is line-based — a literal phrase can straddle JSON-fragment lines or include escaped characters; decode and concatenate a message's fragments for exact text matching. Saved artifacts may expire under the backend's policy.

Dev Note

Working context for maintainers — click to expand None.