Skip to content

fix(memory): keep span details readable after their raw turn is deleted - #564

Open
Anson-Se wants to merge 1 commit into
MemTensor:memmy_1031/v1.2.0from
Anson-Se:fix-span-detail-missing-raw-turn
Open

Anson-Se wants to merge 1 commit into
MemTensor:memmy_1031/v1.2.0from
Anson-Se:fix-span-detail-missing-raw-turn

Conversation

@Anson-Se

Copy link
Copy Markdown
Contributor

任务与行为

  • **关联记录:**Memmy 问题清单第 60 条"span 详情假定原话一定存在,原话删掉后查看会报错"。
  • **触发场景:**在记忆面板删除一个任务。episode 被删除后,原话表 raw_turns 按外键级联,把这个任务的原话一起删掉。但从这一轮切出来的 span 不在 episode 的 L1 列表里,删任务后仍是激活状态,列表里还能看到。
  • **修改前:**打开这条 span 的详情时,代码按 span 记下的原话 id 取原话,并断言一定取得到。原话已不存在,于是抛 TypeError,接口返回 500。桌面端详情抽屉的删除按钮要等详情加载成功才显示,所以这条 span 在桌面端也删不掉。Agent 用 memmy-memory get 取它,走的是同一个读取接口,同样返回 500。
  • **修改后:**原话不存在时,span 详情的 toolCalls 返回空列表,toolCallStart、toolCallEnd 和其他字段照常返回。详情能打开,删除按钮也能正常显示。

修改范围

  • Memory/src/service/read-model/episode.ts:取原话时去掉非空断言,原话不存在时 toolCalls 为空列表,改了 2 行。
  • Memory/tests/service/evolution/span-big-turn.test.ts:新增用例。先生成 span,再通过面板删除所在的任务,确认原话已被删除、span 仍在列表里,然后读取详情,断言不报错、toolCalls 为空、其他字段照常。
  • 无前置依赖。不改接口和数据结构,不迁移数据。

验证证据

  • 分支 fix-span-detail-missing-raw-turn,起点 d101fd58(即当前 memmy_1031/v1.2.0),提交 bcf6af86。提 PR 前已 fetch 并 merge 集成分支(Already up to date)。
  • 环境:macOS arm64,Node v25.1.0,npm 11.6.2。
  • 新增用例在修改前失败:TypeError: Cannot read properties of undefined (reading 'toolCalls')(episode.ts:244);修改后通过。
  • npm run memory:test:106 个测试文件中 104 个通过、1 个跳过(仅在 Windows 上运行的安装器集成测试)、1 个失败;921 个用例中 919 个通过。失败的是 l3-world-model.test.ts 的 "keeps source IDs in evidence order and caps them at the latest 256…",原因是超时:上限 20 秒,这台机器跑全量时它要 35 秒左右。这个失败和本 PR 无关:
    • 在不含本 PR 改动的 d101fd58 上,同样条件下跑全量,也是这一条超时(35.4 秒,920 个用例中 918 个通过)。
    • 单独运行这条用例能通过,用时 13.5 秒。
  • npm run lint、npm run typecheck 通过。
  • git diff --check upstream/memmy_1031/v1.2.0...HEAD 无输出;交付差异只含上面两个文件。
  • 和 upstream/v1.1.9 做过试合并(git merge-tree),没有冲突。

已知限制

  • 删除任务时,从这个任务切出的 span 不会一起删除,仍会被召回、注入 Agent 上下文。本 PR 只保证详情能打开、能手动删除;删除任务时一并清理 span,需要另外修。新用例把"删任务后 span 仍在列表里"作为前提,那个问题修好后,这条用例要改成用别的方式让原话消失。
  • 原话缺失时,详情里的"相关步骤"为空,界面上没有"原对话已删除"之类的提示。

🤖 Generated with Claude Code

Opening a span's detail looked up the raw turn recorded on the span and
assumed it still existed. Deleting a task from the panel deletes its
episode, and the foreign key cascade removes the episode's raw turns
with it, but spans are not in the episode's L1 list, so they stay
active and listed. Opening such a span threw a TypeError and the detail
request returned 500. The desktop drawer only shows its delete button
once the detail loads, so the span could not be deleted there either.

When the raw turn is gone, the span detail now returns an empty
toolCalls list; toolCallStart, toolCallEnd and the rest of the detail
are returned as before.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Copilot AI balanced review requested due to automatic review settings September 29, 2026 04:26

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@Anson-Se

Copy link
Copy Markdown
Contributor Author

@origami-chen 麻烦审核一下这个 PR:修复删除任务后打开 span 详情会返回 500 的问题。原话已被删除时,详情照常返回,工具调用为空列表。细节见 PR 描述。谢谢!

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants