diff --git a/src/vs/workbench/contrib/void/browser/chatThreadService.ts b/src/vs/workbench/contrib/void/browser/chatThreadService.ts index 567f2b7c..af93090d 100644 --- a/src/vs/workbench/contrib/void/browser/chatThreadService.ts +++ b/src/vs/workbench/contrib/void/browser/chatThreadService.ts @@ -638,7 +638,8 @@ class ChatThreadService extends Disposable implements IChatThreadService { - // TODO!!!!!!!!! + // TOOL_TODO!!!!!!!!! call the builtin versus the MCP tool here and stringify + // const isBuiltInTool = (toolNames as string[]).includes(toolName) // const callToolFn = (toolName: string, toolParams: BuiltinToolCallParams[ToolName]) => { // if (isBuiltInTool) { 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 7e60cac8..9852d5c9 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 @@ -24,7 +24,7 @@ import { WarningBox } from '../void-settings-tsx/WarningBox.js'; import { getModelCapabilities, getIsReasoningEnabledState } from '../../../../common/modelCapabilities.js'; import { AlertTriangle, File, Ban, Check, ChevronRight, Dot, FileIcon, Pencil, Undo, Undo2, X, Flag, Copy as CopyIcon, Info, CirclePlus, Ellipsis, CircleEllipsis, Folder, ALargeSmall, TypeOutline, Text } from 'lucide-react'; import { ChatMessage, CheckpointEntry, StagingSelectionItem, ToolMessage } from '../../../../common/chatThreadServiceTypes.js'; -import { approvalTypeOfToolName, LintErrorItem, ToolApprovalType, toolApprovalTypes, ToolCallParams } from '../../../../common/toolsServiceTypes.js'; +import { approvalTypeOfToolName, BuiltinToolCallParams, LintErrorItem, ToolApprovalType, toolApprovalTypes } from '../../../../common/toolsServiceTypes.js'; import { CopyButton, EditToolAcceptRejectButtonsHTML, IconShell1, JumpToFileButton, JumpToTerminalButton, StatusIndicator, StatusIndicatorForApplyButton, useApplyStreamState, useEditToolStreamState } from '../markdown/ApplyBlockHoverButtons.js'; import { IsRunningType } from '../../../chatThreadService.js'; import { acceptAllBg, acceptBorder, buttonFontSize, buttonTextColor, rejectAllBg, rejectBg, rejectBorder } from '../../../../common/helpers/colors.js'; @@ -1420,7 +1420,7 @@ const getTitle = (toolMessage: Pick): { +const toolNameToDesc = (toolName: ToolName, _toolParams: BuiltinToolCallParams[ToolName] | undefined, accessor: ReturnType): { desc1: React.ReactNode, desc1Info?: string, } => { @@ -1431,95 +1431,95 @@ const toolNameToDesc = (toolName: ToolName, _toolParams: ToolCallParams[ToolName const x = { 'read_file': () => { - const toolParams = _toolParams as ToolCallParams['read_file'] + const toolParams = _toolParams as BuiltinToolCallParams['read_file'] return { desc1: getBasename(toolParams.uri.fsPath), desc1Info: getRelative(toolParams.uri, accessor), }; }, 'ls_dir': () => { - const toolParams = _toolParams as ToolCallParams['ls_dir'] + const toolParams = _toolParams as BuiltinToolCallParams['ls_dir'] return { desc1: getFolderName(toolParams.uri.fsPath), desc1Info: getRelative(toolParams.uri, accessor), }; }, 'search_pathnames_only': () => { - const toolParams = _toolParams as ToolCallParams['search_pathnames_only'] + const toolParams = _toolParams as BuiltinToolCallParams['search_pathnames_only'] return { desc1: `"${toolParams.query}"`, } }, 'search_for_files': () => { - const toolParams = _toolParams as ToolCallParams['search_for_files'] + const toolParams = _toolParams as BuiltinToolCallParams['search_for_files'] return { desc1: `"${toolParams.query}"`, } }, 'search_in_file': () => { - const toolParams = _toolParams as ToolCallParams['search_in_file']; + const toolParams = _toolParams as BuiltinToolCallParams['search_in_file']; return { desc1: `"${toolParams.query}"`, desc1Info: getRelative(toolParams.uri, accessor), }; }, 'create_file_or_folder': () => { - const toolParams = _toolParams as ToolCallParams['create_file_or_folder'] + const toolParams = _toolParams as BuiltinToolCallParams['create_file_or_folder'] return { desc1: toolParams.isFolder ? getFolderName(toolParams.uri.fsPath) ?? '/' : getBasename(toolParams.uri.fsPath), desc1Info: getRelative(toolParams.uri, accessor), } }, 'delete_file_or_folder': () => { - const toolParams = _toolParams as ToolCallParams['delete_file_or_folder'] + const toolParams = _toolParams as BuiltinToolCallParams['delete_file_or_folder'] return { desc1: toolParams.isFolder ? getFolderName(toolParams.uri.fsPath) ?? '/' : getBasename(toolParams.uri.fsPath), desc1Info: getRelative(toolParams.uri, accessor), } }, 'rewrite_file': () => { - const toolParams = _toolParams as ToolCallParams['rewrite_file'] + const toolParams = _toolParams as BuiltinToolCallParams['rewrite_file'] return { desc1: getBasename(toolParams.uri.fsPath), desc1Info: getRelative(toolParams.uri, accessor), } }, 'edit_file': () => { - const toolParams = _toolParams as ToolCallParams['edit_file'] + const toolParams = _toolParams as BuiltinToolCallParams['edit_file'] return { desc1: getBasename(toolParams.uri.fsPath), desc1Info: getRelative(toolParams.uri, accessor), } }, 'run_command': () => { - const toolParams = _toolParams as ToolCallParams['run_command'] + const toolParams = _toolParams as BuiltinToolCallParams['run_command'] return { desc1: `"${toolParams.command}"`, } }, 'run_persistent_command': () => { - const toolParams = _toolParams as ToolCallParams['run_persistent_command'] + const toolParams = _toolParams as BuiltinToolCallParams['run_persistent_command'] return { desc1: `"${toolParams.command}"`, } }, 'open_persistent_terminal': () => { - const toolParams = _toolParams as ToolCallParams['open_persistent_terminal'] + const toolParams = _toolParams as BuiltinToolCallParams['open_persistent_terminal'] return { desc1: '' } }, 'kill_persistent_terminal': () => { - const toolParams = _toolParams as ToolCallParams['kill_persistent_terminal'] + const toolParams = _toolParams as BuiltinToolCallParams['kill_persistent_terminal'] return { desc1: toolParams.persistentTerminalId } }, 'get_dir_tree': () => { - const toolParams = _toolParams as ToolCallParams['get_dir_tree'] + const toolParams = _toolParams as BuiltinToolCallParams['get_dir_tree'] return { desc1: getFolderName(toolParams.uri.fsPath) ?? '/', desc1Info: getRelative(toolParams.uri, accessor), } }, 'read_lint_errors': () => { - const toolParams = _toolParams as ToolCallParams['read_lint_errors'] + const toolParams = _toolParams as BuiltinToolCallParams['read_lint_errors'] return { desc1: getBasename(toolParams.uri.fsPath), desc1Info: getRelative(toolParams.uri, accessor), diff --git a/src/vs/workbench/contrib/void/common/mcpService.ts b/src/vs/workbench/contrib/void/common/mcpService.ts index 4180c5e8..a892aa39 100644 --- a/src/vs/workbench/contrib/void/common/mcpService.ts +++ b/src/vs/workbench/contrib/void/common/mcpService.ts @@ -36,8 +36,12 @@ export interface IMCPService { getCurrentMCPToolNames(): InternalToolInfo[]; - // TODO!!!!!!!!! getMCPToolDescriptors (the equivalent of tools in prompts.ts) + // TOOL_TODO!!!! implement getMCPTools here, which gets merged with builtins in prompts + callMCPTool(toolData: MCPToolCallParams): Promise<{ result: MCPGenericToolResponse }>; + + + // this is outdated: // getMCPToolFns(): MCPCallToolOfToolName; } @@ -50,12 +54,12 @@ const MCP_CONFIG_SAMPLE = { mcpServers: {} } const MCP_CONFIG_SAMPLE_STRING = JSON.stringify(MCP_CONFIG_SAMPLE, null, 2); -export interface MCPCallToolOfToolName { - [toolName: string]: (params: any) => Promise<{ - result: any | Promise, - interruptTool?: () => void - }>; -} +// export interface MCPCallToolOfToolName { +// [toolName: string]: (params: any) => Promise<{ +// result: any | Promise, +// interruptTool?: () => void +// }>; +// } class MCPService extends Disposable implements IMCPService { diff --git a/src/vs/workbench/contrib/void/common/modelCapabilities.ts b/src/vs/workbench/contrib/void/common/modelCapabilities.ts index 49b38b84..ee180dbc 100644 --- a/src/vs/workbench/contrib/void/common/modelCapabilities.ts +++ b/src/vs/workbench/contrib/void/common/modelCapabilities.ts @@ -1270,7 +1270,6 @@ const openRouterModelOptions_assumingOpenAICompat = { const openRouterSettings: VoidStaticProviderInfo = { modelOptions: openRouterModelOptions_assumingOpenAICompat, - // TODO!!! send a query to openrouter to get the price, etc. modelOptionsFallback: (modelName) => { const res = extensiveModelOptionsFallback(modelName) // openRouter does not support gemini-style, use openai-style instead diff --git a/src/vs/workbench/contrib/void/common/prompt/prompts.ts b/src/vs/workbench/contrib/void/common/prompt/prompts.ts index 51289138..fc3fad15 100644 --- a/src/vs/workbench/contrib/void/common/prompt/prompts.ts +++ b/src/vs/workbench/contrib/void/common/prompt/prompts.ts @@ -362,6 +362,12 @@ export const isAToolName = (toolName: string): toolName is ToolName => { } export const availableTools = (chatMode: ChatMode) => { + + // TOOL_TODO!!!! + // merge MCP tools with these builtin tools + + + const toolNames: ToolName[] | undefined = chatMode === 'normal' ? undefined : chatMode === 'gather' ? (Object.keys(voidTools) as ToolName[]).filter(toolName => !(toolName in approvalTypeOfToolName)) : chatMode === 'agent' ? Object.keys(voidTools) as ToolName[] diff --git a/src/vs/workbench/contrib/void/common/voidSettingsTypes.ts b/src/vs/workbench/contrib/void/common/voidSettingsTypes.ts index bdb34504..62aaae65 100644 --- a/src/vs/workbench/contrib/void/common/voidSettingsTypes.ts +++ b/src/vs/workbench/contrib/void/common/voidSettingsTypes.ts @@ -33,7 +33,7 @@ export type VoidStatefulModelInfo = { // <-- STATEFUL modelName: string, type: 'default' | 'autodetected' | 'custom'; isHidden: boolean, // whether or not the user is hiding it (switched off) -} // TODO!!! eventually we'd want to let the user change supportsFIM, etc on the model themselves +} diff --git a/src/vs/workbench/contrib/void/electron-main/llmMessage/sendLLMMessage.impl.ts b/src/vs/workbench/contrib/void/electron-main/llmMessage/sendLLMMessage.impl.ts index 1190b283..9bba271d 100644 --- a/src/vs/workbench/contrib/void/electron-main/llmMessage/sendLLMMessage.impl.ts +++ b/src/vs/workbench/contrib/void/electron-main/llmMessage/sendLLMMessage.impl.ts @@ -217,6 +217,8 @@ const openAITools = (chatMode: ChatMode) => { return openAITools } + +// convert LLM tool call to our tool format const rawToolCallObjOf = (name: string, toolParamsStr: string, id: string): RawToolCallObj | null => { if (!isAToolName(name)) return null const rawParams: RawToolParamsObj = {} diff --git a/src/vs/workbench/contrib/void/electron-main/mcpChannel.ts b/src/vs/workbench/contrib/void/electron-main/mcpChannel.ts index adc7c9ff..4ed0d65f 100644 --- a/src/vs/workbench/contrib/void/electron-main/mcpChannel.ts +++ b/src/vs/workbench/contrib/void/electron-main/mcpChannel.ts @@ -13,7 +13,7 @@ import { Client } from '@modelcontextprotocol/sdk/client/index.js'; import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js'; import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js'; import { SSEClientTransport } from '@modelcontextprotocol/sdk/client/sse.js'; -import { MCPConfigFileJSON, MCPConfigFileEntryJSON, MCPServer, MCPGenericToolResponse, MCPToolErrorResponse, MCPServerEventResponse } from '../common/mcpServiceTypes.js'; +import { MCPConfigFileJSON, MCPConfigFileEntryJSON, MCPServer, MCPGenericToolResponse, MCPToolErrorResponse, MCPServerEventResponse, MCPToolCallParams } from '../common/mcpServiceTypes.js'; import { Transport } from '@modelcontextprotocol/sdk/shared/transport.js'; import { CallToolResult } from '@modelcontextprotocol/sdk/types.js'; import { MCPUserStateOfName } from '../common/voidSettingsTypes.js'; @@ -96,7 +96,8 @@ export class MCPChannel implements IServerChannel { await this._toggleMCPServer(params.serverName, params.isOn) } else if (command === 'callTool') { - const response = await this._safeCallTool(params.serverName, params.toolName, params.params) + const p: MCPToolCallParams = params + const response = await this._safeCallTool(p.serverName, p.toolName, p.params) return response } else {