dsh-session-find: Cross-session Original Text Retrieval Plugin

Introduction

DSH’s built-in session_search and sidebar search use SQLite FTS5’s unicode61 tokenizer. This tokenizer splits words based on Unicode whitespace and punctuation, so whole Chinese sentences are usually not broken down into searchable tokens. Consequently, queries like “When did I say XXX in a previous conversation” generally cannot be found. If you need to find historical sessions by exact wording, the built-in search cannot help.

dsh-session-find is the plugin designed to address this problem: it bypasses the FTS5 tokenizer and directly scans the raw .jsonl.zstd logs in $DSH_HOME/sessions for substring matching. It can hit on whole Chinese sentences and locates results to the session, turn, step, and role. The plugin is maintained by quecai-niu, licensed under MIT, falls under the “Memory” category, is placed in the community plugins directory, and is not an official application.

Below is an introduction to its capabilities, installation methods, and actual usage.

Two Entry Points

The plugin provides two entry points that share the same search core (lib/search.js) with a single set of logic.

Entry Point Purpose
Right sidebar panel Opened by clicking the magnifying glass button on the right edge of the session header. Search, filter by role; double-clicking a hit jumps to that session and scrolls to the sentence, with a blue pulse highlight for 2.6 seconds.
session_find tool A tool directly callable by the model. Users can say, “Help me find when XXX was said in a conversation.”

The panel is for browser interaction, while the tool is for model invocation; both are two forms of the same search capability.

Coverage and Hit Information

The content is separated into 7 role types:

User · Assistant · Thinking (Model reasoning) · Tool Call · Tool Result · Title · Pending Message

Each hit provides the following information:

  • Session title and sessionId. Titles may have duplicates; the ID is the unique identifier.
  • Event seq, referring to a specific event.
  • Turn number, step number, role, and ISO 8601 time.
  • Context snippets of N characters on each side of the hit position.

Log Format and Implementation Details

Session log filenames are of the form session.v<N>.jsonl.zstd, and the content consists of multiple zstd frames appended sequentially. Node’s zstdDecompressSync only decompresses the first frame, so the plugin must slice by the frame magic number 28 B5 2F FD and decompress frame by frame, otherwise, subsequent frame content will be missed.

The turn number is primarily taken from data.turn attached to the turn/start event (the authoritative value); it falls back to an incrementing counter only if that value is missing.

Read-only Design

The plugin does not modify session logs or any configuration. It maintains an index cache at $DSH_HOME/cache/dsh-session-find/index.json, updated incrementally based on (mtimeMs, size). Deleting this directory forces a rebuild of the index.

Installation and Enablement

Install using the official command:

dsh plugin --profile <profile> add dsh-session-find

Or insert into the profile’s cordis.patch.yml:

- insert:
    - id: session-find
      name: dsh-session-find

After installation, DSH needs to be restarted; the host-side tool is loaded at startup.

Typical Usage

Right sidebar panel: Click the magnifying glass button in the top right, enter the literal text to search, and filter by role; double-click a hit, and the plugin will switch to the corresponding session and scroll to the sentence.

On the model side, simply express the intent, for example, “Help me find when the API Key rotation plan was mentioned.” The parameters for the session_find tool are as follows:

Parameter Type Description
query string (Required) Literal text to search, case-insensitive, max 512 characters
roles string[] Search only within these roles
session string A segment to limit by session ID
limit number Max number of results, default 20, max 50
context number Characters to keep on each side of the snippet, default 100, max 2000

There is a total output budget of 24000 characters. Exceeding this will truncate the output and explain the remaining number of items and suggestions for narrowing the search.

HTTP Routes

The browser panel uses the following three read-only routes:

GET /session-find/api/search?q=...&roles=用户,助手&limit=50&context=100&session=xxx&case=1&nocache=1
GET /session-find/api/sessions
GET /session-find/api/health

It is worth noting that the panel’s scroll positioning relies on the data-chat-turn and [data-conversation-scroll] attributes of the chat area. These attributes are not official public APIs and may be renamed after DSH updates. If you plan to develop the panel secondarily or write scripts to call these routes, you must first confirm if the current DSH version still retains these attributes.

Applicable Scenarios and Notes

Suitable for the following situations:

  • Large number of historical sessions, built-in search can’t find Chinese whole sentences, need literal search of original text.
  • Need to locate specific turns, steps, and roles, not just see a title.
  • Need to initiate retrieval directly with natural language on the model side.

Pay attention to the following points when using:

  • The plugin runs with the permissions of the current DSH process; its capability boundary is what the process can read from $DSH_HOME. Confirm this meets expectations before installation.
  • Check the plugin source code and license before installation. This plugin is MIT; the repository address is at the end of the article.
  • Jump precision depends on the DOM contract. If this fails, the plugin will fall back to “switch session only, do not scroll” without raising an error. Therefore, if you see a jump without scrolling, be aware that a version change might be the cause.
  • Cross-session jumping involves a wait: uses MutationObserver to wait until the target session content is mounted, with a timeout of 8 seconds. During this time, the UI is not blocked.
  • Events outside of turns, such as titles and pending messages, cannot be scrolled to; the plugin will explicitly indicate this.

Conclusion

The value of dsh-session-find lies in filling the gap left by the built-in FTS5 tokenizer: changing cross-session search from “by word” to “by literal”, and providing actionable location information while maintaining read-only status.

  • Plugin Directory Page: https://www.skillhub.cn/plugins/quecai-niu/dsh-session-find
  • GitHub Repository: https://github.com/quecai-niu/dsh-session-find
羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

Xiaoye