From 09f5f1fad1b75ee2a9f090934ad178722f63e7da Mon Sep 17 00:00:00 2001 From: Andrew Pareles Date: Thu, 22 May 2025 17:22:07 -0700 Subject: [PATCH] better result display --- .../contrib/void/browser/chatThreadService.ts | 13 +------------ .../react/src/sidebar-tsx/SidebarChat.tsx | 13 ++++++------- .../contrib/void/browser/terminalToolService.ts | 16 ++++++++-------- .../workbench/contrib/void/common/mcpService.ts | 16 ++++++++++++++++ 4 files changed, 31 insertions(+), 27 deletions(-) diff --git a/src/vs/workbench/contrib/void/browser/chatThreadService.ts b/src/vs/workbench/contrib/void/browser/chatThreadService.ts index e50e841f..eb1a6883 100644 --- a/src/vs/workbench/contrib/void/browser/chatThreadService.ts +++ b/src/vs/workbench/contrib/void/browser/chatThreadService.ts @@ -713,18 +713,7 @@ class ChatThreadService extends Disposable implements IChatThreadService { } // For MCP tools, handle the result based on its type else { - const toolResult_ = toolResult as RawMCPToolCall - if (toolResult_.event === 'text') { - toolResultStr = toolResult_.text - } else if (toolResult_.event === 'image') { - toolResultStr = `[Image: ${toolResult_.image.mimeType}]` - } else if (toolResult_.event === 'audio') { - toolResultStr = `[Audio content]` - } else if (toolResult_.event === 'resource') { - toolResultStr = `[Resource content]` - } else { - toolResultStr = JSON.stringify(toolResult) - } + toolResultStr = this._mcpService.stringifyResult(toolResult as RawMCPToolCall) } } catch (error) { const errorMessage = this.toolErrMsgs.errWhenStringifying(error) diff --git a/src/vs/workbench/contrib/void/browser/react/src/sidebar-tsx/SidebarChat.tsx b/src/vs/workbench/contrib/void/browser/react/src/sidebar-tsx/SidebarChat.tsx index aabc9120..fa5a5fc9 100644 --- a/src/vs/workbench/contrib/void/browser/react/src/sidebar-tsx/SidebarChat.tsx +++ b/src/vs/workbench/contrib/void/browser/react/src/sidebar-tsx/SidebarChat.tsx @@ -1428,7 +1428,9 @@ const getTitle = (toolMessage: Pick = { toolMessage: Exclude, { type: 'invalid_params' }>, messageIdx: number, threadId: string } const MCPToolWrapper = ({ toolMessage }: WrapperProps) => { const accessor = useAccessor() - const commandService = accessor.get('ICommandService') + const mcpService = accessor.get('IMCPService') const title = getTitle(toolMessage) const desc1 = toolMessage.name @@ -1870,14 +1872,11 @@ const MCPToolWrapper = ({ toolMessage }: WrapperProps) => { if (toolMessage.type === 'success' || toolMessage.type === 'tool_request') { const { result } = toolMessage + const resultStr = result ? mcpService.stringifyResult(result) : 'null' componentParams.children = disposables.forEach(d => d.dispose())) + + + // read result if timed out, since we didn't get it (could clean this code up but it's ok) + if (resolveReason?.type === 'timeout') { + const terminalId = isPersistent ? params.persistentTerminalId : params.terminalId + result = await this.readTerminal(terminalId) + } + if (!isPersistent) { interrupt() } if (!resolveReason) throw new Error('Unexpected internal error: Promise.any should have resolved with a reason.') - // read result if timed out, since we didn't get it (could clean this code up but it's ok) - if (resolveReason.type === 'timeout') { - const terminalId = isPersistent ? params.persistentTerminalId : params.terminalId - result = await this.readTerminal(terminalId) - } - - - if (!isPersistent) result = `$ ${command}\n${result}` result = removeAnsiEscapeCodes(result) // trim diff --git a/src/vs/workbench/contrib/void/common/mcpService.ts b/src/vs/workbench/contrib/void/common/mcpService.ts index 3920aa3d..03785e8e 100644 --- a/src/vs/workbench/contrib/void/common/mcpService.ts +++ b/src/vs/workbench/contrib/void/common/mcpService.ts @@ -36,6 +36,7 @@ export interface IMCPService { getMCPTools(): InternalToolInfo[] | undefined; callMCPTool(toolData: MCPToolCallParams): Promise<{ result: RawMCPToolCall }>; + stringifyResult(result: RawMCPToolCall): string } export const IMCPService = createDecorator('mcpConfigService'); @@ -286,6 +287,21 @@ class MCPService extends Disposable implements IMCPService { }) } + stringifyResult(result: RawMCPToolCall): string { + let toolResultStr: string + if (result.event === 'text') { + toolResultStr = result.text + } else if (result.event === 'image') { + toolResultStr = `[Image: ${result.image.mimeType}]` + } else if (result.event === 'audio') { + toolResultStr = `[Audio content]` + } else if (result.event === 'resource') { + toolResultStr = `[Resource content]` + } else { + toolResultStr = JSON.stringify(result) + } + return toolResultStr + } // toggle MCP server and update isOn in void settings public async toggleServerIsOn(serverName: string, isOn: boolean): Promise {