实时消息流里失败的工具调用仍显示绿色对勾——#3204 ① 只收敛了轨迹面板那一半
- Dominant language
- TypeScript
- Stars
- 0
- Forks
- 0
- Avg merge
- 1h 7m
- Merged PRs (30d)
- 969
Description
## 现象
同一次工具调用,**同一屏上两处给出相反结论**:
- 展开的执行轨迹里:外层折叠行 `run-trace-entry[data-status="failed"]`,内层工具卡
`data-tool-status="failed"` + 红色感叹号 —— 对的(#3204 ① 已修的那一半)。
- **实时消息流**里(`copilotkit-v2-tool-calls-group`,用户先看到的就是这里):同一次
调用的卡片是 `complete` + **绿色对勾**。
## 根因(已定位到行)
`apps/web/lib/chat-workbench/tool-outcome.ts`:
```ts
export function useToolCardStatus(frameworkStatus: "inProgress" | "executing" | "complete"): ToolCardStatus {
const journal = useJournalToolOutcome();
if (journal === null) return frameworkStatus; // ← 这里
return journal === "failed" ? "failed" : journal === "running" ? "executing" : "complete";
}
```
`JournalToolOutcomeContext` 只由轨迹面板 `apps/web/components/chat/workbench/task-timeline.tsx`
下发。实时消息流的工具卡(`apps/web/components/chat/copilotkit-v2-assistant-message.tsx`)
不在那棵树里 ⇒ 拿到 `null` ⇒ **回落到框架三态**。而框架三态
(`inProgress | executing | complete`,来自 `@copilotkit/react-core/v2`)**没有失败态**,
上游 AG-UI 的 `ToolCallResultEventSchema` 只有 `content`、没有 `error`/`isError`
(`node_modules/@ag-ui/core/dist/index.d.ts`)。于是失败在 `render()` 边界上被丢掉、
又被重新发明成"成功"。
## 为什么这不是「缺省」而是缺口
`tool-outcome.ts` 的头注把这条回落写成「`null` = 不在执行轨迹里,没有事实可用」。
**但这一轮里事实是有的**——同一屏的轨迹面板正拿着它(同一个 runId、同一个 toolCallId)。
不是"没有事实可用",是"这棵树没接上那份事实"。#3204 ① 要收敛的正是这个形状,只收敛了一半。
## 复现
本仓确定性替身已具备(本 PR 新加):`CHAT_READ_E2E.deepAgentToolFailureTrigger`
——run 正常收尾,其中一次工具调用的 ToolMessage 带 `status: "error"`。
## 已落地的门
`apps/web/e2e/chat-path-d1-failed-tool-card-status.spec.ts` 第二条用例逐字写着这条判据,
按本仓既有先例(#2997 方案 B,A3/C8 两次)挂 `test.fixme`:**不删断言、不改宽、
不 `test.skip`**。本 issue 修好后把 `fixme` 改回 `test` 即可,spec 正文一个字不用动。
## 修法方向(未定,供讨论)
把权威状态的下发范围从"轨迹面板这棵树"扩到"这一轮的所有工具卡"——消息流那棵树同样
按 `toolCallId` 能查到执行日志条目,缺的是 provider,不是数据。
Contributor guide
No contributing guide indexed for this repository
Research direction
Start with apps/web/lib/chat-workbench/tool-outcome.ts, then trace how JournalToolOutcomeContext is provided by task-timeline.tsx and consumed by copilotkit-v2-assistant-message.tsx. Run apps/web/e2e/chat-path-d1-failed-tool-card-status.spec.ts and inspect its second test and existing fixme pattern. Done means the real-time card shows failed status for the deterministic tool failure and the fixme can become test without changing the assertion.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- frontend, testing-qa
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 68/100