散步前点了下 Hermes Agent 的更新,回来后发现虽然更新成功但我的历史会话都看不到了。
开一个新会话让查一下日志以及确认下数据库目前的状况。提示词刚发出去的瞬间,历史会话就恢复了。
日志显示:sqlite3.OperationalError: no such column: s.last_read_at
也就是说读会话列表的时候发现 sessions 表缺少了一列。
这个变动是在 ec0c8d9c2 feat(state): sessions carry read/unread state 中引入的,新增一列 last_read_at 是方便界面推导出“未读”状态。这是好事,而且作者也说了”no surface exposes it yet”,所以这应该不涉及 SCHEMA 版本的更新。
但作者可能忽略了 list_sessions_rich() 这个查询本身就会依赖新列。本来查到这应该就差不多了,归因到作者给表加了新列但是忽略了兼容性似乎也没毛病。
但继续往下挖会发现,完整链条是这样的:
- SessionDB(read_only=True) 的时候是不会自动补列。
- list_sessions_rich() 的时候是只读连接的。
- Hermes 有兜底策略,只读连接后会跑一个探测查询,判断是老库的话也会补列。
- 但这个“探测查询”是硬编码的,也没有检查到 last_read_at,所以永远“通过”。
- 我新建会话的时候是 read_only=False 并触发 _init_schema,补列成功,历史会话瞬间恢复并加载。
*另外,这个“探测清单”本身就是之前挖的坑,里面硬编码的都是以前某次更新需要补的列。但显然这次提交的时候忘记维护这茬了。不过要我说,这个忘记几乎是必然发生的,属于“屎山代码”的诅咒。