Skip to content

Fix: final response markdown not rendered during streaming#326497

Open
tamuratak wants to merge 6 commits into
microsoft:mainfrom
tamuratak:fix_length_mismatch
Open

Fix: final response markdown not rendered during streaming#326497
tamuratak wants to merge 6 commits into
microsoft:mainfrom
tamuratak:fix_length_mismatch

Conversation

@tamuratak

@tamuratak tamuratak commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

Fix: final response markdown not rendered during streaming

Close #324774 #324608 #325601

Bug: With workbench.reduceMotion enabled, the final markdown content fails to display during streaming when a response goes through thinking → tool invocation → markdown. The content briefly disappears and only reappears after the response is finalized.

Root cause: The progressive and final rendering paths in ChatListItemRenderer produced content arrays of different lengths. The progressive path was missing codeCitations/errorDetails slots, and changesSummary/turnPills/workingProgress were conditionally appended. The diff() algorithm compares by index, so the length mismatch caused the final markdown to be matched against the wrong rendered part, preventing it from rendering.

Fix: Introduce IChatTailPlaceholder — a sentinel value that occupies a fixed position in the content array when a slot has no data. A shared appendTailPlaceholders helper ensures both progressive and final paths always produce identical-length arrays with the same slot order: codeCitations → errorDetails → changesSummary → turnPills → workingProgress. The "Thinking" shimmer is also suppressed for markdown-only responses where no thinking or tool activity is present.

Repro steps:

  1. Set workbench.reduceMotion to on.
  2. Run an extension chat participant that produces the following stream:
stream.push(new vscode.ChatResponseThinkingProgressPart('Thinking ...', 'toolcall2-1'));
await sleep(100);
const part1 = new vscode.ChatToolInvocationPart('my-tool', 'call-1');
part1.enablePartialUpdate = true;
part1.isComplete = false;
part1.invocationMessage = 'Running tool...';
stream.push(part1);
const part2 = new vscode.ChatToolInvocationPart('my-tool', 'call-1');
part2.enablePartialUpdate = true;
part2.isComplete = true;
part2.pastTenseMessage = 'Tool completed';
stream.push(part2);
await sleep(100);
stream.markdown('\n\nfinal response\n');
  1. Observe that "final response" is missing during streaming. (With reduceMotion off, it works due to the progressive rendering word-count path.)

Written with GitHub Copilot + MiMo-V2.5-Pro

CC: @justschen

Copilot AI review requested due to automatic review settings July 19, 2026 00:43

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Fixes missing final chat markdown during streaming by aligning progressive and final renderer content arrays.

Changes:

  • Adds a dedicated tail-slot placeholder.
  • Stabilizes renderer slot ordering.
  • Adjusts working-progress visibility.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.

File Description
chatViewModel.ts Defines the tail placeholder content type.
chatListRenderer.ts Aligns rendering slots and updates progress behavior.

Comment thread src/vs/workbench/contrib/chat/browser/widget/chatListRenderer.ts Outdated
Comment thread src/vs/workbench/contrib/chat/browser/widget/chatListRenderer.ts Outdated
Comment thread src/vs/workbench/contrib/chat/browser/widget/chatListRenderer.ts
Comment thread src/vs/workbench/contrib/chat/browser/widget/chatListRenderer.ts
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.

Copilot Chat (agent mode): final assistant message intermittently dropped/not rendered after tool calls

3 participants