Skip to content

fix: render assistant text bubble for messages with tool calls#3315

Open
xingzhiyyu wants to merge 5 commits into
bytedance:mainfrom
xingzhiyyu:main
Open

fix: render assistant text bubble for messages with tool calls#3315
xingzhiyyu wants to merge 5 commits into
bytedance:mainfrom
xingzhiyyu:main

Conversation

@xingzhiyyu
Copy link
Copy Markdown

Fixes #3251

Why

In the previous version, an AI message containing both text content and tool calls would be hidden from the normal assistant message stream. It would not be rendered directly to the user as a regular text bubble, and would instead only appear in the TOOL-CALLS panel or the Chain of Thought section.
This behavior does not match our expected UI behavior.
This PR ensures that assistant messages with text content are shown in the normal message stream, while Chain of Thought and tool calls continue to be displayed only in their respective panels.

What changed

Messages with both tool_calls and text content now produce two groups: an assistant bubble (renders the reply text) and an assistant:processing group (handles the tool call chain). Previously only the processing group was created, leaving the text trapped inside the Chain of Thought panel.
The bubble is spliced before the processing group rather than pushed to the end. This keeps lastOpenGroup() working correctly — subsequent tool results still land in the processing group.
Also added a regression test covering: tool calls + text, reasoning + tool calls + text, and plain text (no tool calls).

Surface area

  • Frontend UI — page / component / setting / interaction under frontend/
  • Backend API — endpoint / SSE event / request-response shape under backend/app
  • Agents / LangGraph — agent node, graph wiring, langgraph.json, or prompt change
  • Sandboxdocker/ or sandboxed execution
  • Skills — change under skills/
  • Dependencies — new/upgraded entry in backend/pyproject.toml or frontend/package.json (say what it buys us)
  • Default behavior change — changes existing behavior without the user opting in (default model, default setting, data shape)
  • Docs / tests / CI only — no runtime behavior change

Screenshots / Recording

image previous version can't display some normal assisant image These output texts appear after it fixed

Bug fix verification

image Previous version failed in the regression test above image while the fixed one passes in all three regression test.

Validation

Test Files 24 passed (24)
Tests 163 passed (163)
Start at 15:35:28
Duration 592ms (transform 764ms, setup 0ms, import 1.60s, tests 298ms, environment 1ms)

I recloned the repository from my fork that I used to submit this PR, then ran cd frontend && pnpm format && pnpm lint && pnpm typecheck && BETTER_AUTH_SECRET=local-dev-secret pnpm build && make test. All checks passed.

@CLAassistant
Copy link
Copy Markdown

CLAassistant commented May 29, 2026

CLA assistant check
All committers have signed the CLA.

AI messages with both tool_calls and text content were previously
missing a visible assistant bubble — the text was hidden inside the
Chain of Thought processing panel. Insert an assistant group before
the processing group so the reply text renders as a normal chat bubble
while lastOpenGroup() continues to work for subsequent tool results.
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes frontend message grouping so AI messages with both visible text and tool calls can render assistant text while preserving processing/tool-call grouping.

Changes:

  • Updates getMessageGroups() to create assistant bubbles for AI messages with content even when they also require processing.
  • Inserts the visible assistant bubble before the processing group so later tool messages still attach correctly.
  • Adds regression tests for tool calls with text, reasoning with tool calls and text, and plain text responses.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
frontend/src/core/messages/utils.ts Adjusts AI message grouping logic for content plus tool calls/reasoning.
frontend/tests/unit/core/messages/utils-regression.test.ts Adds regression coverage for assistant text visibility around tool calls.

Comment on lines +107 to +113
if (hasSubagent(message)) {
groups.push({
id: message.id,
type: "assistant:subagent",
messages: [message],
});
} else if (hasReasoning(message) || hasToolCalls(message)) {
continue;
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

@copilot Simply answer me in Chinese,can the issue be resolved by placing this branch after the "needprocessing" branch? Don‘t make any chance to the code.

xingzhiyyu added 2 commits May 29, 2026 22:19
- Move hasSubagent check before needsProcessing so subagent messages
  get an assistant bubble for visible content + subagent group for tool
  results, avoiding a dangling processing group
- Apply same pattern to hasPresentFiles: assistant bubble for text +
  present-files group for the file panel
- Update regression tests to match new expected ordering
@WillemJiang WillemJiang added question Further information is requested reviewing A maintainer is reviewing this PR labels May 30, 2026
@xingzhiyyu
Copy link
Copy Markdown
Author

xingzhiyyu commented Jun 2, 2026

我尝试改了copilot提到的问题,现在因为present file 的分支在渲染的时候同时渲染ai生成的正文的file,所以不用做其他处理直接用一个message push上去就能显示,subagent的部分生成一个正常的assistant和一个assistant:subagent,如果没理解错的话在前端这两类一个只渲染正文,另一个渲染subagent消息,同一条消息push两种就能让正文和subagent一起显示,解决了subagent消息里正文被吞的问题,但现在这种方案导致这方面的token计量可能会被高估
@WillemJiang
刚刚发现还有其他问题我再看看

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

Labels

question Further information is requested reviewing A maintainer is reviewing this PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

tool调用后会吞掉已输出的上下文

4 participants