longyu065/dsh-session-index ↗★ 1
dsh-session-index
会话全文索引插件:监听 session/event 构建跨会话索引,提供 session_search / session_index_stats 工具,优先使用框架自带 ctx.sessionQuery (SQLite FTS5)
安装
npx -p @deepseek-ai/dsh dsh plugin --profile web add github:longyu065/dsh-session-index说明文档
阅读完整 README ↗dsh-session-index
DeepSeek Harness 的会话全文索引插件(组合包 / dsh.bundle)。
监听 session/event 事件流,把每一段会话里的用户消息、助手回复、工具调用/结果、会话标题
抽取成可检索文档,构建跨会话倒排索引,并通过 session_search / session_index_stats
两个工具暴露给模型 —— 让 agent 能"回忆"之前任何一次对话里说过什么、做过什么。
功能
| 能力 | 说明 |
|---|---|
| 实时增量 | 每个 session/event 追加立即入索引(按 sessionId#seq 幂等去重) |
| 历史回填 | 启动时先索引内存活动会话,再按水位线用 ctx.sessionPersistence.readFrom(id, fromSeq) 增量补全落盘旧会话 —— 弥补 session/event 不重放已恢复会话历史事件的缺口 |
| 混合检索 | preferFts 开启时,FTS5 + 内存索引并跑、按会话去重合并:框架 ctx.sessionQuery(SQLite FTS5)负责英文/词级召回,内置二元组索引补足中文召回(FTS5 unicode61 不做中文切词) |
| 富卡片 | presentCall/presentResult + output.presentationMeta 投影成 Web UI 的 card:'search' 卡片:按会话分组的可展开命中列表(组头=会话 id+标题,组内=命中片段) |
| 持久化 | 索引文档按 JSONL 追加到 $DSH_HOME/session-index/.jsonl,重启只补增量 |
| 会话销毁清理 | session/disposed 时同步移除该会话全部文档与索引文件 |
| 隐私开关 | indexReasoning(默认关,不索引 CoT 思考文本)、indexToolResults(默认开) |
索引内容:user/message、assistant/message 的 text(reasoning 可选)、tool/call(工具名+参数)、tool/result、session/title。
仓库结构
dsh-session-index/ # 包根 = 仓库根(组合包,dsh.bundle)
├── src/session-index.ts # 插件源码(单文件,可擦除 TS,Node 22.18+ 原生类型剥离即可加载)
├── index.js # 编译产物(build 生成,随包分发)
├── cordis.patch.yml # ① 挂载插件 ② 把框架自带 FTS5 从 openAt:never 启用为 first-search
├── test-index.mjs # 引擎独立测试(不启动 dsh):65 项断言
├── tsconfig.json / package.json / LICENSE / .gitignore
└── README.md
安装
# ① 打包(在仓库根目录)
pnpm pack # 产出 dsh-session-index-0.1.0.tgz
# ② 装进 profile(web = 桌面端用的 profile)
dsh plugin --profile web add ./dsh-session-index-0.1.0.tgz
# ③ 重启桌面应用 / dsh web
组合包自带 patch 层会额外覆盖 dsh-base 里 session-query-sqlite 行的配置:
把框架自带 FTS5 从默认的 openAt: never 改成 openAt: first-search + 持久化路径
$DSH_HOME/session-query.sqlite,从而 自动进入混合检索。
想关掉就在自己 profile 的 里再覆盖该行(patch 按层后写覆盖前写)。