diff --git a/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatThinkingContentPart.ts b/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatThinkingContentPart.ts index c4d66671c21..8b780c2a924 100644 --- a/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatThinkingContentPart.ts +++ b/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatThinkingContentPart.ts @@ -7,7 +7,7 @@ import { $, clearNode, getWindow, hide, scheduleAtNextAnimationFrame } from '../ import { alert } from '../../../../../../base/browser/ui/aria/aria.js'; import { DomScrollableElement } from '../../../../../../base/browser/ui/scrollbar/scrollableElement.js'; import { ScrollbarVisibility } from '../../../../../../base/common/scrollable.js'; -import { IChatMarkdownContent, IChatThinkingPart, IChatToolInvocation, IChatToolInvocationSerialized } from '../../../common/chatService/chatService.js'; +import { IChatMarkdownContent, IChatTerminalToolInvocationData, IChatThinkingPart, IChatToolInvocation, IChatToolInvocationSerialized } from '../../../common/chatService/chatService.js'; import { IChatContentPartRenderContext, IChatContentPart } from './chatContentParts.js'; import { IChatRendererContent } from '../../../common/model/chatViewModel.js'; import { ChatConfiguration, ThinkingDisplayMode } from '../../../common/constants.js'; @@ -228,6 +228,7 @@ export class ChatThinkingContentPart extends ChatCollapsibleContentPart implemen private workingSpinnerLabel: HTMLElement | undefined; private availableMessagesByCategory = new Map(); private readonly toolWrappersByCallId = new Map(); + private readonly toolIconsByCallId = new Map(); private readonly toolLabelsByCallId = new Map(); private readonly toolDisposables = this._register(new DisposableMap()); private readonly ownedToolParts = new Map(); @@ -1224,6 +1225,7 @@ ${this.hookCount > 0 ? `EXAMPLES WITH BLOCKED CONTENT (from hooks): const wrapper = this.toolWrappersByCallId.get(toolCallId); if (wrapper) { this.toolWrappersByCallId.delete(toolCallId); + this.toolIconsByCallId.delete(toolCallId); } this.appendedItemCount = Math.max(0, this.appendedItemCount - 1); @@ -1342,6 +1344,7 @@ ${this.hookCount > 0 ? `EXAMPLES WITH BLOCKED CONTENT (from hooks): if (wrapper) { wrapper.remove(); this.toolWrappersByCallId.delete(toolCallId); + this.toolIconsByCallId.delete(toolCallId); } // make sure to remove any lazy item as well @@ -1470,6 +1473,18 @@ ${this.hookCount > 0 ? `EXAMPLES WITH BLOCKED CONTENT (from hooks): // queue item to be removed if it was streaming and presentation is hidden if (isStreaming && currentState.type !== IChatToolInvocation.StateKind.Streaming) { isStreaming = false; + + // Update terminal tool icon based on sandbox wrapping state + const termData = toolInvocationOrMarkdown.toolSpecificData as IChatTerminalToolInvocationData | undefined; + if (termData?.kind === 'terminal') { + const iconEl = this.toolIconsByCallId.get(toolCallId); + if (iconEl) { + const newIcon = termData.commandLine?.isSandboxWrapped ? Codicon.terminalSecure : Codicon.terminal; + iconEl.className = 'chat-thinking-icon'; + iconEl.classList.add(...ThemeIcon.asClassNameArray(newIcon)); + } + } + if (toolInvocationOrMarkdown.presentation === 'hidden') { this.pendingRemovals.push({ toolCallId: toolInvocationOrMarkdown.toolCallId, toolLabel: currentToolLabel }); this.schedulePendingRemovalsFlush(); @@ -1628,6 +1643,7 @@ ${this.hookCount > 0 ? `EXAMPLES WITH BLOCKED CONTENT (from hooks): const isToolInvocation = toolInvocationOrMarkdown && (toolInvocationOrMarkdown.kind === 'toolInvocation' || toolInvocationOrMarkdown.kind === 'toolInvocationSerialized'); if (isToolInvocation && toolInvocationOrMarkdown.toolCallId) { this.toolWrappersByCallId.set(toolInvocationOrMarkdown.toolCallId, itemWrapper); + this.toolIconsByCallId.set(toolInvocationOrMarkdown.toolCallId, iconElement); } this.appendToWrapper(itemWrapper); diff --git a/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/runInTerminalTool.ts b/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/runInTerminalTool.ts index 4739f7e27c9..3d7614d54e6 100644 --- a/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/runInTerminalTool.ts +++ b/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/runInTerminalTool.ts @@ -274,7 +274,7 @@ export async function createRunInTerminalToolData( modelDescription, userDescription: localize('runInTerminalTool.userDescription', 'Run commands in the terminal'), source: ToolDataSource.Internal, - icon: isSandboxEnabled ? Codicon.terminalSecure : Codicon.terminal, + icon: Codicon.terminal, inputSchema: { type: 'object', properties: {