DSH plugin session query: bounded reads, traces and search

Plugin DevelopmentPublished 2026-10-17Author: DeepSeek Plugin Market
DeepSeek HarnessDSH pluginsession-queryfull-text searchcursorevent traces
How a DSH plugin queries sessions: a live-preferred corpus, AND/OR filters, grouped search with cursors, bounded reads and replacement chains.

DSH plugin session query has two faces: exact reads and trace relationships, which are backend-independent, and full-text search, whose index lifetime belongs to the provider. Both share the live-preferred premise — when an id exists in memory and on disk, data comes from the live source, with live and persisted flags reported separately. The most common misuse is filter combination semantics: arrays AND together, values within a clause OR together, ranges are inclusive; and text clauses scan semantic text literally rather than acting as executable FTS syntax.

Bottom line: exact reads, filters and traces share one abstract service; the provider owns indexing and swapping it keeps the vocabulary.

  1. Backend-independent: bounded reads, filters, traces, lineage and title observation.
  2. Backend-related: full-text observation, reconciliation, ranking, cursor generations and query execution.
  3. One entry point: everything hangs off ctx.sessionQuery.
  4. Selection: exact reads when you need a specific event and its context; search when you need "which sessions mention X."
  5. Rule of thumb: require stable order and exact seqs for reads, relevance ranking for search.

DSH plugin logical records: availability flags and one-shot snapshots

Bottom line: SessionRecord reports availability; the snapshot types are observations, not subscriptions.

TypeContentsUse
SessionRecordheader + live + persistedListing and provenance
SessionLogSnapshotheader, inherited count, validated raw logRestore preflight
SessionSurfaceSnapshotheader, captured seq, surface eventsExact surface read
  1. Listings cover the corpus: listSessions() returns deterministic newest-first records.
  2. Snapshots are one-shot: re-read to refresh.
  3. Surface classification: current, shadowed, log-only distinguish current context, replaced context and raw-log-only.
  4. Title observation follows the same rule: batch results come in request order, one failure affects only that id, and cancellation rejects the whole call.
  5. Do not treat persisted as live: persisted-only sessions go through cold reads with different semantics.

DSH plugin filters: AND, OR and literal text scans

Bottom line: arrays AND, clauses OR, ranges inclusive; text is a literal scan, not an executable query language.

ts
const sessions = await ctx.sessionQuery.filterSessions([
  { kind: 'cwd', values: ['/work/a', '/work/b'] },
  { kind: 'created-at', from, to },
])
  1. Session filters: id, cwd, created-at, parent, availability.
  2. Event filters: seq, time, type, surface, text.
  3. Text rule: literal, Unicode case-insensitive, whitespace-flexible.
  4. Semantic text scope: messages, tool calls and results, todos, failures and status details are included; reasoning blocks, blocked prompts, structural events and stream chunks are not.
  5. Ordering: filterEvents returns matching documents by ascending seq.

DSH plugin full-text search: grouped hits, in-session hits and cursors

Bottom line: cross-session search groups by strongest event; in-session search returns events and always the target header.

  1. Cross-session: searchSessions({ query, sessionFilters, eventFilters, limit, cursor }), each group carrying bestMatch.
  2. In-session: searchEvents({ sessionId, query, filters, limit, cursor }), returning the target header even with zero hits.
  3. Query is data: text is interpreted as data, never as executable FTS syntax.
  4. Cursor binding: a cursor is bound to the normalized query, metadata filters and limit; changing any of them restarts the search.
  5. Metadata filters only: provider filters exclude text scanning and apply before ranking.
  6. Pagination: items plus an optional nextCursor, absent on the last page.

DSH plugin bounded reads, event traces and lineage

Bottom line: reads give raw windows, traces give replacement chains and citations, lineage gives ancestors and descendant trees.

  1. Bounded reads: a request specifies the target seq plus before/after counts and returns a window with startSeq/endSeq; the result carries a header rather than availability flags.
  2. Replacement relations: replacedBy is the immediate replacer, replacementChain reaches the final replacement, and replacedEventSeqs lists positional nodes this event removed.
  3. Citation relations: sourceEventSeqs are earlier cited events, derivedEventSeqs are later events citing this one.
  4. Lineage: ancestors nearest-first, descendants as a recursive forest; complete: false supplies unresolvedParentId rather than pretending to be a root.
  5. Stable errors: EVENT_NOT_FOUND, INVALID_CURSOR, STALE_CURSOR, SEARCH_DISABLED, INDEX_FAILED and SOURCE_CONFLICT are codes — branch on them, not on message text.

DSH plugin session query troubleshooting

Bottom line: separate no results, slow results and odd order — filter semantics, indexing and ordering contracts.

  1. No results — check AND/OR semantics and whether text was treated as syntax.
  2. Zero in-session hits — normal: items is empty but the header is still returned.
  3. Stale cursor — the query or limit changed; restart the search.
  4. Unexpected order — search ranks by relevance; only exact reads are seq-ascending.
  5. Incomplete lineage — read complete and unresolvedParentId; do not invent a root.
  6. Repair status, stated honestly: record types, filter semantics, search requests and error codes follow the official Session query page; confirm signatures against its Cordis API and your version.

Sources: Session query, session-query package, Session persistence.

FAQ

In DSH plugin session query, which wins between live and persisted data?

DSH plugin sessionQuery is live-preferred: when an id exists both in memory and on disk, records and events come from the live source. SessionRecord exposes live and persisted availability separately so you can see where data came from.

How do DSH plugin session filters combine arrays and values, with AND or OR?

In DSH plugin session filtering, items in a filter array are ANDed while values inside one clause are ORed, and ranges are inclusive. A text clause scans extracted semantic text literally, case-insensitively, with flexible whitespace.

How do searchSessions and searchEvents differ in DSH plugin search results?

DSH plugin searchSessions groups the corpus by the strongest matching event and includes a bestMatch per group, while searchEvents searches one session and always returns the target header even with zero hits. Both paginate with opaque cursors bound to the normalized request.

How much context do before and after give in a DSH plugin bounded read?

A DSH plugin bounded read centers on the target seq and includes the requested number of raw events before and after, returning a window with start and end seqs. It gives raw log context rather than the projected surface.

What is the difference between replacedBy and replacementChain in DSH plugin traces?

In DSH plugin event traces, replacedBy gives only the immediate replacer's seq, while replacementChain follows direct replacers through to the final positional replacement. Use the chain when you need the final replacement.

Related Terms

SessionQueryEngine
SessionQueryEngine is the abstract service behind ctx.sessionQuery, providing live-preferred exact reads, filters, traces and full-text search. Exact reads and traces are backend-independent while index lifetimes belong to the provider.— https://deepseek-harness.github.io/deepseek-harness/reference/subsystems/session-query
SessionEventSurface
SessionEventSurface classifies an event within the folded surface as current model context, shadowed context, or log-only presence, using the values current, shadowed and log-only.— https://deepseek-harness.github.io/deepseek-harness/reference/subsystems/session-query
SessionSearchCursor
SessionSearchCursor is a provider-owned opaque continuation token bound to the normalized query, metadata filters and result limit. Changing any of them invalidates the cursor.— https://deepseek-harness.github.io/deepseek-harness/reference/subsystems/session-query
SessionLineageTrace
SessionLineageTrace describes the known ancestors and descendant forest of one logical session, ancestors ordered nearest-first. Its completeness field makes a known root mutually exclusive with a missing parent.— https://deepseek-harness.github.io/deepseek-harness/reference/subsystems/session-query

Sources