Issue: Frontend - SSE incremental messages accumulate in chat window instead of updating in-place
问题描述
在前端进入线程对话聊天界面时,当消息通过SSE推送到前端:
- tool调用的进度消息(
mcpToolCall/progress)和thinking过程消息(reasoning/textDelta, reasoning/summaryTextDelta)会一直保留在页面上,除非刷新页面
- 每一次增量更新都会产生新的条目累积在对话窗口中,导致对话窗口无限增长
期望行为
在等待最终回复turn的时候,期间的tool调用进度和thinking reason消息应该在同一个消息占位区内持续更新内容,而不是每次都新增一个消息。当最终回复出来之后,可以清理掉这些临时的增量消息,或者保持只显示一份更新后的内容。
复现步骤
- 发送一个需要调用MCP工具或者有thinking过程的请求
- 观察SSE推送每一块增量内容时,都会在对话列表中新增一个消息条目
- 对话结束后,所有增量消息都保留在页面上,导致消息列表变得很长
根因分析
在 kagent-ui/hooks/use-codex-session.ts 中:
- 当
item/started 事件到来时,代码会将每个item的scopedId push到 streamingItemRef.current[key] 数组中
- 当
item/completed 事件到来时,代码只 shift() 移除第一个,但数组中剩余的ID永远留在那里
- 这些累积的item ID对应的消息都会保存在
messagesBySession 中,不会被清理
- 对于thinking和tool progress来说,每个delta块都被当作一个独立消息添加到列表中,而不是原地更新
正确的做法应该是:对于同一个item的增量更新,始终复用同一个item ID进行原地更新。
Issue: Frontend - SSE incremental messages accumulate in chat window instead of updating in-place
问题描述
在前端进入线程对话聊天界面时,当消息通过SSE推送到前端:
mcpToolCall/progress)和thinking过程消息(reasoning/textDelta,reasoning/summaryTextDelta)会一直保留在页面上,除非刷新页面期望行为
在等待最终回复turn的时候,期间的tool调用进度和thinking reason消息应该在同一个消息占位区内持续更新内容,而不是每次都新增一个消息。当最终回复出来之后,可以清理掉这些临时的增量消息,或者保持只显示一份更新后的内容。
复现步骤
根因分析
在
kagent-ui/hooks/use-codex-session.ts中:item/started事件到来时,代码会将每个item的scopedId push到streamingItemRef.current[key]数组中item/completed事件到来时,代码只shift()移除第一个,但数组中剩余的ID永远留在那里messagesBySession中,不会被清理正确的做法应该是:对于同一个item的增量更新,始终复用同一个item ID进行原地更新。