76 lines
2.7 KiB
Markdown
76 lines
2.7 KiB
Markdown
# 排错总结:`/workspace/chats/new` 场景下 Artifact 图片访问异常
|
||
|
||
## 背景
|
||
|
||
在以下 URL 场景中:
|
||
|
||
`/workspace/chats/new?isnew=false&thread_id=b9a30765-0575-44c9-954e-bdaaf3d083fa&xclaw_used=true`
|
||
|
||
页面会复用已有线程,并跳转到:
|
||
|
||
`/workspace/chats/b9a30765-0575-44c9-954e-bdaaf3d083fa`
|
||
|
||
但出现现象:
|
||
|
||
- `.../api/threads/b9.../artifacts/mnt/user-data/outputs/cat-generated.jpg` 返回 `Artifact not found`
|
||
- `.../api/threads/new/artifacts/mnt/user-data/outputs/cat-generated.jpg` 可以访问
|
||
|
||
## 现象与证据
|
||
|
||
本地线程目录检查结果显示:
|
||
|
||
- `backend/.deer-flow/threads/new/user-data/outputs/cat-generated.jpg` 存在
|
||
- `backend/.deer-flow/threads/b9a30765-0575-44c9-954e-bdaaf3d083fa/user-data/outputs/` 不存在对应文件
|
||
|
||
这说明文件实际写入了 `thread_id = "new"` 的目录,而不是目标线程 `b9...`。
|
||
|
||
## 根因
|
||
|
||
问题由“线程 ID 来源不一致”触发:
|
||
|
||
1. 页面层已经解析出“真实线程 ID”(query 中的 `thread_id`)。
|
||
2. 消息渲染组件中仍直接读取路由参数 `useParams().thread_id`。
|
||
3. 在 `/workspace/chats/new` 下,路由参数固定是 `"new"`,导致图片/文件 URL 被拼接为 `/api/threads/new/artifacts/...`。
|
||
4. 输入与提交链路存在对 `params.thread_id` 的兜底,存在将 `"new"` 带入写操作的风险。
|
||
|
||
## 修复内容
|
||
|
||
本次修复统一了线程 ID 的来源,并增加了防御性校验:
|
||
|
||
1. 消息渲染链路统一使用页面透传的解析后 `threadId`
|
||
- `MessageListItem` 移除 `useParams().thread_id`
|
||
- `MessageList` 将 `threadId` 透传给 `MessageListItem`
|
||
|
||
2. 输入组件移除路由参数兜底
|
||
- `InputBox` 不再使用 `threadIdFromProps ?? params?.thread_id`
|
||
- 仅使用上游传入的解析后 `threadId`
|
||
|
||
3. 提交流程增加硬保护
|
||
- 在 `useThreadStream` / `useSubmitThread` 中拦截 `threadId === "new"`,阻止上传和提交继续执行
|
||
|
||
4. 复用旧线程时强制路径对齐
|
||
- 在 `/workspace/chats/new` 且命中复用条件时,立即 `replace` 到 `/workspace/chats/{thread_id}`
|
||
|
||
## 涉及文件
|
||
|
||
- `frontend/src/components/workspace/messages/message-list-item.tsx`
|
||
- `frontend/src/components/workspace/messages/message-list.tsx`
|
||
- `frontend/src/components/workspace/input-box.tsx`
|
||
- `frontend/src/core/threads/hooks.ts`
|
||
- `frontend/src/components/workspace/chats/use-thread-chat.ts`
|
||
|
||
## 验证结果
|
||
|
||
- TypeScript 编译检查通过:`pnpm -C frontend exec tsc --noEmit --pretty false`
|
||
- 逻辑上可确保后续不会再写入 `threads/new/...`。
|
||
|
||
## 影响与后续处理
|
||
|
||
本次修复不自动迁移历史文件。
|
||
|
||
已落在 `threads/new/...` 的旧产物,仍需要:
|
||
|
||
1. 手动迁移到目标线程目录,或
|
||
2. 在目标线程中重新生成。
|
||
|