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 Definition:Storage 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 Definition:SessionQueryEngine extends Service(src/index.ts:81),static inject = ['sessions'](82 行) |
packages/session-query/tool-session-query/ | 7 文件 / 1444 行 | Consumer:模型查询历史会话的工具 |
§3机制:存储 seam 与查询引擎
- storage = 通用结构化存储:sqlite/json 两个 provider,同一 Storage 契约。它服务于需要「随机读写」的插件(设置缓存、索引),与 20 页的 JSONL 追加日志互补。
- session-query = 会话检索:把会话日志同步进 SQLite 索引,支持列表/搜索(标题、时间、内容)。查询引擎的 Definition 依赖 sessions 服务(82 行)。
- tool-session-query = 模型的检索工具:模型可以查历史会话——这是「跨会话记忆」的一种实现。
§4关键代码
81export abstract class SessionQueryEngine extends Service {
82 static inject = ['sessions']
47export class Storage extends Service {
81-82
查询引擎依赖 sessions——它从日志事件流构建索引(session/event 的另一消费者)。查询与存储解耦的证据:定义里没有持久化后端的影子。
47
storage 是唯一不挂进 base bundle 的「存储」——它是通用设施,由需要的插件按需挂载(可选挂载)。
§5易错点
索引与日志的一致性:查询引擎消费 session/event 异步构建索引——它永远是「最终一致」的。读查询结果做决策的代码不能假设索引实时(flush 前有窗口)。
storage 与 persistence 的分工再强调(20 页同款):追加日志(JSONL)是「事实」,随机存储(storage/sqlite)是「派生」——事实丢失可重放,派生丢失可重建。