diff --git a/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatToolPartUtilities.ts b/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatToolPartUtilities.ts index 03c147cf35124..9ba9846de1a9f 100644 --- a/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatToolPartUtilities.ts +++ b/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatToolPartUtilities.ts @@ -17,7 +17,7 @@ export function isMcpToolInvocation(toolInvocation: IChatToolInvocation | IChatT */ export function shouldShimmerForTool(toolInvocation: IChatToolInvocation | IChatToolInvocationSerialized): boolean { if (isMcpToolInvocation(toolInvocation)) { - return true; + return !IChatToolInvocation.isComplete(toolInvocation); } if (toolInvocation.toolId === 'copilot_askQuestions' || toolInvocation.toolId === 'vscode_askQuestions') { return false; diff --git a/src/vs/workbench/contrib/chat/browser/widget/chatListRenderer.ts b/src/vs/workbench/contrib/chat/browser/widget/chatListRenderer.ts index 573b0b05d41e6..ea350214eac24 100644 --- a/src/vs/workbench/contrib/chat/browser/widget/chatListRenderer.ts +++ b/src/vs/workbench/contrib/chat/browser/widget/chatListRenderer.ts @@ -1025,6 +1025,11 @@ export class ChatListItemRenderer extends Disposable implements ITreeRenderer part.kind === 'toolInvocation' && !IChatToolInvocation.isComplete(part) && isMcpToolInvocation(part))) { + return false; + } + // Show if no content, only "used references", ends with a complete tool call, or ends with complete text edits and there is no incomplete tool call (edits are still being applied some time after they are all generated) const lastPart = findLast(partsToRender, part => part.kind !== 'markdownContent' || part.content.value.trim().length > 0); diff --git a/src/vs/workbench/contrib/chat/test/browser/widget/chatContentParts/chatToolProgressPart.test.ts b/src/vs/workbench/contrib/chat/test/browser/widget/chatContentParts/chatToolProgressPart.test.ts index 3125d372e868b..535b44dcd182b 100644 --- a/src/vs/workbench/contrib/chat/test/browser/widget/chatContentParts/chatToolProgressPart.test.ts +++ b/src/vs/workbench/contrib/chat/test/browser/widget/chatContentParts/chatToolProgressPart.test.ts @@ -182,7 +182,7 @@ suite('ChatToolProgressSubPart', () => { }); test('adds shimmer styling for active MCP tool progress', () => { - const mcpTool = createSerializedToolInvocation({ + const mcpTool = createToolInvocation({ source: { type: 'mcp', label: 'Weather MCP', @@ -221,4 +221,28 @@ suite('ChatToolProgressSubPart', () => { assert.strictEqual(part.domNode.querySelector('.shimmer-progress'), null); }); + + test('does not add shimmer styling for completed MCP tool progress', () => { + const mcpTool = createSerializedToolInvocation({ + source: { + type: 'mcp', + label: 'Weather MCP', + serverLabel: 'Weather', + instructions: undefined, + collectionId: 'collection', + definitionId: 'definition' + }, + toolId: 'weather_lookup' + }); + + const part = disposables.add(instantiationService.createInstance( + ChatToolProgressSubPart, + mcpTool, + createRenderContext(false), + mockMarkdownRenderer, + new Set() + )); + + assert.strictEqual(part.domNode.querySelector('.shimmer-progress'), null); + }); });