Session candidates labelled from projection checkpoints instead of a full log fold per keystroke, with the uncheckpointed remainder folded once and memoized while its log stays cold. The file index keeps answering while an invalidated traversal rebuilds behind the caret, and its default exclusions now cover build outputs so deep sources stay reachable. Rows carry only what distinguishes them: a file names its parent directory, a session names its workspace only when that workspace is not the current one, and a drilled listing names none because its new breadcrumb does. Resolves #3180 Related to #3154
8.4 KiB
Session References
English | 中文
Host-backed file discovery plus structured cross-session reference requests and prepared message contexts. The file-reference contract owns path-only completion records and grammar; the session-reference contract defines canonical URIs, current-surface projection, tag-safe JSON and byte retention, stable errors, and the untrusted model prompt. Host adapters use these types instead of passing their UI mention syntax into the agent core.
Sources: packages/context/file-reference/src/types.ts · packages/context/session-reference/src/types.ts
File candidates
FileReferenceCandidate is the path-only discovery result. The addressed agent supplies the working-directory scope; providers decide ranking and namespace access without reading file contents.
/** One path-only completion candidate inside the target session cwd. */
interface FileReferenceCandidate {
/** User-facing path accepted by normal prompts and filesystem tools. */
path: string
/** Directories keep completion open; files finish the mention. */
kind: 'file' | 'directory'
}
Inputs and candidates
SessionReferenceInput is the host-independent selection. The id is authoritative; the label is display metadata carried into the snapshot.
/** One source session selected by a host. */
interface SessionReferenceInput {
/** Opaque source session identity. */
sessionId: SessionId
/** Optional user-facing mention label. */
label?: string
}
SessionReferenceCandidate is host-facing discovery output. Its label uses the latest session title when present, and filtering searches that label alongside session id and cwd, never transcript text.
/** One host-facing candidate from exact session metadata. */
interface SessionReferenceCandidate {
/** Opaque source session identity. */
sessionId: SessionId
/** Latest log-backed title, falling back to the opaque session id. */
label: string
/** Source session working directory, when recorded. */
cwd?: string
/**
* True when {@link SessionReferenceCandidate.cwd} is recorded and equals the
* requesting agent's. Hosts that only surface a distinguishing location
* read this instead of comparing paths they never received.
*/
sameWorkspace: boolean
/** Source session creation time in Unix epoch milliseconds. */
createdAt: number
}
The sessionReferenceResolver/candidates Remote method serves the same discovery to browser consumers and attaches each candidate's canonical prompt mention.
/** One discovery candidate carrying its canonical prompt mention. */
interface SessionReferenceMentionCandidate extends SessionReferenceCandidate {
/** Canonical `@[label](dsh-session:…)` mention serialized into the prompt draft. */
mention: string
}
Prepared messages
Preparation preserves readable current-message content and returns at most one aggregated context.
/** Direct message content and optional referenced-session context. */
interface PreparedReferencedMessage {
/** Readable message content after host mention tokens are removed. */
content: ContentBlock[]
/** Aggregated untrusted snapshot, absent when the message has no references. */
additionalContext?: UserMessage
}
Errors
SessionReferenceError.code separates invalid configuration or input, self-reference, count limits, source-read failure, budget failure, and cancellation. Host protocols map these codes to their own error envelopes without inspecting prompt bytes.
/** Stable failure codes exposed to host adapters. */
type SessionReferenceErrorCode =
| 'SESSION_REFERENCE_INVALID_CONFIG'
| 'SESSION_REFERENCE_INVALID_REFERENCE'
| 'SESSION_REFERENCE_SELF_REFERENCE'
| 'SESSION_REFERENCE_TOO_MANY'
| 'SESSION_REFERENCE_READ_FAILED'
| 'SESSION_REFERENCE_BUDGET_EXCEEDED'
| 'SESSION_REFERENCE_CANCELLED'
Cordis API
Generated from source by scripts/gen-cordis-catalog.ts (verified fresh by pnpm run verify-cordis-catalog in doc-sync; regenerate with pnpm run gen-cordis-catalog) — the language sides differ only in locale-specific paired document paths. Signature blocks use a ts cordis-catalog fence and keep the original source JSDoc; dispatch modes are defined in the primer, and the framework-inherited ctx API lives in cordis-api/inherited.md.
ctx.fileReferences — FileReferenceService (abstract seam)
Host capability for cancellable file-reference discovery.
/**
* List file and directory candidates for one agent's working directory.
* @param agent - target agent whose session cwd bounds discovery.
* @param query - path text following `@` or `@"`.
* @param signal - caller cancellation.
* @returns deterministic path-only candidates.
*/
abstract list( agent: Agent, query: string, signal: AbortSignal, ): Promise<FileReferenceCandidate[]>
/**
* Remote face of {@link list}; the decorator cannot mark the abstract
* member, so this concrete adapter carries the identical contract.
* @param agent - target agent whose session cwd bounds discovery.
* @param query - path text following `@` or `@"`.
* @param signal - caller cancellation.
* @returns deterministic path-only candidates.
*/
@Remote('list') remoteExportList( agent: Agent, query: string, signal: AbortSignal, ): Promise<FileReferenceCandidate[]>
Types: Agent
Source: packages/context/file-reference/src/index.ts
ctx.sessionReferenceResolver — SessionReferenceResolver
Exact-read consumer that prepares immutable cross-session message context.
/**
* List reference candidates, ranked by working-directory affinity.
*
* A title comes from the projection cache when that cache holds a
* checkpoint for the session; otherwise it is folded from the session's log
* once and remembered for as long as the log stays cold. Without the cache
* composed, only the cwd-ranked head of an unfiltered listing is folded, so
* its tail cannot match a title substring.
* @param agent - target agent; self is excluded and its cwd drives ranking.
* @param query - optional case-insensitive session-id/cwd/title substring.
* @param limit - optional positive result cap.
* @param signal - optional cancellation boundary for host autocomplete teardown.
* @returns candidates labeled by latest title or, when absent, session id.
*/
async listCandidates( agent: Agent, query: string = '', limit: number = this.config.candidateLimit, signal?: AbortSignal, ): Promise<SessionReferenceCandidate[]>
/**
* Remote face of {@link listCandidates}: the configured candidate limit
* applies, and every candidate carries the canonical mention a host inserts
* into the prompt draft.
* @param agent - target agent; self is excluded and its cwd drives ranking.
* @param query - optional case-insensitive session-id/cwd/title substring.
* @param signal - caller cancellation.
* @returns mention-carrying candidates in rank order.
*/
@Remote('candidates') async remoteExportCandidates( agent: Agent, query: string, signal: AbortSignal, ): Promise<SessionReferenceMentionCandidate[]>
/**
* Snapshot all references for one accepted direct message and return one aggregated durable context.
* @param agent - target agent; references to it are rejected.
* @param content - already host-normalized readable message content.
* @param references - structured source sessions in mention order.
* @param signal - optional cancellation boundary for the active turn.
* @returns detached content and optional referenced-session context.
*/
async prepare( agent: Agent, content: ContentBlock[], references: SessionReferenceInput[], signal?: AbortSignal, ): Promise<PreparedReferencedMessage>
Types: Agent · ContentBlock