close

Volume 2 · Chapter 30

存储与会话查询:结构化数据的两个后端

storage 域提供「键值/结构化存储」的 seam(Storage extends Service,含 sqlite 与 json 两个 provider);session-query 域是「会话列表/搜索」的查询引擎(20 页提过的 sqlite 索引在此)。加上 session-projection(会话投影)与 session-stats(统计)。

(卷一连接点) 20 页持久化后端 · 06 页日志 本域:storage / storage-sqlite / storage-json / session-query / session-query-sqlite / tool-session-query / session-projection (回心脏) 查询结果喂 UI(32 页)或模型(tool-session-query)

示例本次示例:模型查历史会话

示例轨迹 30-1 · tool-session-query 的检索
# 模型:session_query({query:'上次那个目录整理的会话'})
# → tool-session-query(1444 行)→ SessionQueryEngine(session-query/src/index.ts:81)
# → SQLite 索引(session-query-sqlite)检索标题/内容
# → 返回匹配会话列表(id、标题、时间)
# 索引数据从哪来:消费 session/event 异步构建(20 页的查询侧)
# → 模型引用某会话 → 恢复/读取该会话日志(20 页恢复路径)
# 注意:索引最终一致(30 页易错点)——刚写的事件可能还没进索引
来源:30 页 §3 + 20 页查询侧
示例轨迹 30-2 · storage 的用途
# storage(sqlite 后端)服务于随机读写:
# 某插件缓存「上次选择的模型」到 storage
# 重启后读回——与 20 页 JSONL 的追加日志互补:
# 日志是事实(可重放),storage 是派生(可重建)
来源:30 页 §3 易错点

§1挂载条目

  • session-query-sqlite → dsh-session-query-sqlite——SQLite 查询索引(20 页的「查询侧」)
  • session-projection → dsh-session-projection——会话投影(把日志投影成结构化的 UI 视图)
  • storage / storage-json / storage-sqlite——通用存储 seam(部分在 profile 层追加挂载)

§2包文件地图

规模角色
packages/storage/storage/5 文件 / 331 行Service DefinitionStorage extends Service(src/index.ts:47)
packages/storage/storage-sqlite/4 文件 / 476 行Provider:SQLite——inject = ['storage'](src/index.ts:21)
packages/storage/storage-json/5 文件 / 424 行Provider:JSON 文件后端
packages/session-query/session-query/11 文件 / 1718 行Service DefinitionSessionQueryEngine extends Service(src/index.ts:81),static inject = ['sessions'](82 行)
packages/session-query/tool-session-query/7 文件 / 1444 行Consumer:模型查询历史会话的工具

§3机制:存储 seam 与查询引擎

  1. storage = 通用结构化存储:sqlite/json 两个 provider,同一 Storage 契约。它服务于需要「随机读写」的插件(设置缓存、索引),与 20 页的 JSONL 追加日志互补。
  2. session-query = 会话检索:把会话日志同步进 SQLite 索引,支持列表/搜索(标题、时间、内容)。查询引擎的 Definition 依赖 sessions 服务(82 行)。
  3. tool-session-query = 模型的检索工具:模型可以查历史会话——这是「跨会话记忆」的一种实现。

§4关键代码

packages/session-query/session-query/src/index.ts查询引擎契约81-82
81export abstract class SessionQueryEngine extends Service {
82  static inject = ['sessions']
packages/storage/storage/src/index.ts存储服务47
47export class Storage extends Service {
81-82

查询引擎依赖 sessions——它从日志事件流构建索引(session/event 的另一消费者)。查询与存储解耦的证据:定义里没有持久化后端的影子。

47

storage 是唯一不挂进 base bundle 的「存储」——它是通用设施,由需要的插件按需挂载(可选挂载)。

§5易错点

索引与日志的一致性:查询引擎消费 session/event 异步构建索引——它永远是「最终一致」的。读查询结果做决策的代码不能假设索引实时(flush 前有窗口)。

storage 与 persistence 的分工再强调(20 页同款):追加日志(JSONL)是「事实」,随机存储(storage/sqlite)是「派生」——事实丢失可重放,派生丢失可重建。