Files
memory-gateway/docs/superpowers/specs/2026-06-15-memory-attachment-path-mapping-design.md

3.7 KiB
Raw Blame History

Memory 附件真实路径映射设计

目标

/resources/memories/add 两种摄入方式都保存附件与 session 的映射。 /memories/search 返回结果时,根据结果 session_id 查询当前用户附件,并且只有 当附件完整文件名出现在结果 raw 的字符串字段中时,才返回该附件真实 URI。

数据模型

新增 SQLite 表 memory_attachments

  • id TEXT PRIMARY KEY
  • user_id TEXT NOT NULL
  • app_id TEXT NOT NULL DEFAULT 'default'
  • project_id TEXT NOT NULL DEFAULT 'default'
  • session_id TEXT NOT NULL
  • resource_id TEXT
  • content_type TEXT NOT NULL
  • name TEXT NOT NULL
  • internal_uri TEXT NOT NULL
  • source TEXT NOT NULL
  • sha256 TEXT
  • created_at TIMESTAMP NOT NULL
  • deleted_at TIMESTAMP

(user_id, session_id, internal_uri) 建立唯一索引,避免幂等上传产生重复映射; 以 (user_id, session_id, deleted_at) 建立查询索引。

数据库初始化时,将现有未删除 user_resources 回填为附件映射。历史 /memories/add 请求没有保存在 Gateway 数据库中,因此无法自动回填。

摄入规则

/resources

资源记录创建后,为保存的真实 file:// URI 创建附件映射:

  • session_id 使用 resource:{user_id}:{resource_id}
  • resource_id 指向资源;
  • sourceresource_upload
  • content_type、文件名、SHA256 复用资源元数据。

重复资源上传时确保已有资源对应的附件映射存在。

/memories/add

API 将已鉴权的 user_id 一并传给 service。逐条检查 message 的 content item

  • 只有字符串 content 或纯文本 item 时不创建附件;
  • uri 时记录该 URIsource=memory_add_uri
  • 没有 uri 但有 base64 时,解码并保存到 storage/{user_id}/memory_attachments/{attachment_id}/{safe_name},记录生成的 file:// URIsource=memory_add_base64
  • 同时存在 uribase64 时优先使用 uri,不重复落盘;
  • 文件名优先使用 name,否则从 URI 路径或 ext 生成安全名称。

上游 add 调用失败时,删除本次 base64 生成的文件,不写入映射。调用成功后写入 附件映射。上游请求体保持原样,不修改现有 add 行为。

搜索匹配规则

对每条标准化搜索结果:

  1. 根据已鉴权 user_id 和结果 session_id 查询未删除附件;
  2. 递归遍历 raw 中 dict、list 的字符串值;
  3. 跳过键名为 base64 的值,避免扫描大块编码数据;
  4. 使用附件完整文件名做不区分大小写的子串匹配;
  5. 仅命中的附件进入 attachments,按 internal_uri 去重;
  6. 没有 session 或没有命中时返回 attachments: []

响应附件格式:

{
  "type": "image",
  "name": "simple-multimodal-image.png",
  "internal_uri": "file:///home/tom/memory-gateway/tests/simple-multimodal-image.png"
}

episode 是 session 级记忆,因此只能在同一 session 的附件中按文件名匹配,不能 证明具体附件是向量召回的直接来源。

删除与隔离

  • 所有附件查询必须同时匹配 user_idsession_id
  • 删除 /resources 时,对应附件映射设置 deleted_at
  • 真实路径按用户明确要求直接出现在搜索结果中;
  • 不改变资源列表和详情现有的 resource:// 对外 URI。

测试

  • 资源上传创建附件映射;
  • 资源搜索仅在 raw 出现文件名时返回真实 URI
  • raw 不含文件名时返回空附件数组;
  • /memories/add 的 URI content 创建映射;
  • /memories/add 的 base64 content 落盘并创建映射;
  • 不扫描 raw 中的 base64 字段;
  • 不返回其他用户同 session 的附件;
  • 现有测试继续通过。