feat: scope automatic working memory to the current conversation

This commit is contained in:
Sycun committed 2026-10-12 09:59:15 +08:00
1 parent 1d2e900e88
commit 6b8bbbe91b
14 files changed
+443 -40

No files matched your search

+20
View File
@@ -16,6 +16,26 @@
不再生成独立 `.index.md` 文件,不使用正则或关键词分类扫描快照,不增加模型调用。摘要本身承担证据检索入口;它仍可能遗漏细节,原文以快照为准。
## 会话工作记录与项目共享事实的读取边界
设计依据是区分会话状态和跨会话记忆,而非把每次自动摘要直接视为共享事实。[LangChain 官方记忆概念文档](https://docs.langchain.com/oss/python/concepts/memory) 将工作状态定义为 thread-scoped,跨会话记忆使用独立 namespace;本项目保留现有项目事实结构,用保留前缀 `note/context-*` 与来源会话标识建立相应读取范围,不增加数据库迁移或额外模型提取。
| 内容 | 自动注入与默认事实工具 | 显式历史查询 |
|---|---|---|
| 普通项目事实(含已确认发现、手工 note) | 沿用原有项目共享行为 | 沿用原有行为 |
| 当前会话的自动续接记录(含该会话子代理/规划器/执行器) | 可见,标为当前会话工作记录 | 可见 |
| 同项目其他会话的自动续接记录 | 不自动注入,列表/搜索默认不返回,直接 get 要求历史标志 | `include_history=true` 可读,标为历史参考 |
| 缺少来源会话的旧续接记录 | 不作为当前工作记录返回 | 显式历史查询可读,标明未知来源 |
| 其他项目的记录 | 当前项目工具不可读 | 历史标志不能扩大项目范围或绕过 project:read |
`list_project_facts`、`search_project_facts` 与 `get_project_fact` 默认使用当前会话范围;前两者支持 `source_conversation_id` 缩小查询。过滤在数据库分页前执行,避免置顶历史记录占满一页后才被丢弃。初始主 Agent 注入、子 Agent 黑板补充以及普通/原生压缩后的索引刷新,都显式传入当前会话 ID;缺少会话 ID 时不会退回注入全部自动续接记录。
关系速览、索引行内关系提示以及 get/upsert 的关系边返回同样过滤其他会话的自动续接 key,防止通过关系边绕过默认范围。历史正文附来源会话和更新时间,不因读取自动升级为已确认事实或新的任务授权。`note/context-*` 为系统保留前缀,事实写入工具不能覆盖;废弃/恢复工具不能修改其他会话的自动续接记录。核实后的项目知识应另写独立事实 key 并保留证据。
这属于上下文注入和事实检索的默认范围,不是新的文件访问权限隔离;不删除快照、不修改既有记录,也不清洗已进入旧对话历史的内容。项目管理页面及原有不带范围参数的数据库查询仍可供有权用户查看项目全量数据。现有项目权限继续由工具授权层核验。
验证使用同项目两会话、另一个项目及未知来源旧记录:覆盖默认/显式查询、来源筛选、分页、置顶历史记录、关系边、保留 key 写保护、权限拒绝、初始主 Agent 注入,以及真实 classic/native 压缩自动保存后的索引刷新。已有黑板预算与原始用户账本测试继续运行,确保范围标识不突破长度上限、不更改用户输入。
## 原始证据不会随下一次压缩被覆盖
过去所有压缩轮次写入同一个 `transcript.txt`,后一次写入会覆盖前一次记录。现在每份压缩前历史保存到 `snapshots/transcript-<MD5前5位>-<时间戳>.txt`,例如 `transcript-a1b2c-20261012-010203.000000004+0800.txt`。时间戳带纳秒与时区,记录首次保存时间;相同内容的重试通过完整文件内容核对复用快照,不改变原快照的时间或路径。短 MD5 仅用于识别,不用作唯一性判断;前缀或时间戳碰撞时不覆盖旧文件。旧 SHA-256 文件名保持可读且可复用,不改名以免旧摘要的引用失效。`transcript.txt` 仍保留为最新记录的兼容入口,续接摘要引用的是具体快照。快照沿用现有会话记录格式,保留用户、助手与工具记录,省略不变的系统提示与工具/技能索引。