diff --git a/src/vs/workbench/contrib/void/browser/chatThreadService.ts b/src/vs/workbench/contrib/void/browser/chatThreadService.ts index 8772dc23..cb3ce39b 100644 --- a/src/vs/workbench/contrib/void/browser/chatThreadService.ts +++ b/src/vs/workbench/contrib/void/browser/chatThreadService.ts @@ -761,7 +761,7 @@ class ChatThreadService extends Disposable implements IChatThreadService { const handleToolCall = async ( tool: ToolCallType, opts?: { preapproved: true, toolParams: ToolCallParams[ToolName] }, - ): Promise<{ awaitingUserApproval: boolean, canceled: boolean }> => { + ): Promise<{ awaitingUserApproval?: boolean, canceled?: boolean }> => { const toolName: ToolName = tool.name const toolParamsStr = tool.paramsStr const toolId = tool.id @@ -779,14 +779,14 @@ class ChatThreadService extends Disposable implements IChatThreadService { } catch (error) { const errorMessage = getErrorMessage(error) this._addMessageToThread(threadId, { role: 'tool', name: toolName, paramsStr: toolParamsStr, id: toolId, content: errorMessage, result: { type: 'error', params: undefined, value: errorMessage }, }) - return { awaitingUserApproval: false, canceled: false } + return {} } // 2. if tool requires approval, break from the loop, awaiting approval const requiresApproval = !this._settingsService.state.globalSettings.autoApprove if (requiresApproval && toolNamesThatRequireApproval.has(toolName)) { this._addMessageToThread(threadId, { role: 'tool_request', name: toolName, paramsStr: toolParamsStr, params: toolParams, id: toolId }) - return { awaitingUserApproval: true, canceled: false } + return { awaitingUserApproval: true } } } else { @@ -805,10 +805,10 @@ class ChatThreadService extends Disposable implements IChatThreadService { toolResult = await Promise.race([result, resolveIfCancel]) // this await is needed, typescript is bad... } catch (error) { - if (canceled) return { awaitingUserApproval: false, canceled: true } + if (canceled) return { canceled: true } const errorMessage = getErrorMessage(error) this._addMessageToThread(threadId, { role: 'tool', name: toolName, paramsStr: toolParamsStr, id: toolId, content: errorMessage, result: { type: 'error', params: toolParams, value: errorMessage }, }) - return { awaitingUserApproval: true, canceled: false } + return {} } // 4. stringify the result to give to the LLM @@ -817,12 +817,12 @@ class ChatThreadService extends Disposable implements IChatThreadService { } catch (error) { const errorMessage = this.errMsgs.errWhenStringifying(error) this._addMessageToThread(threadId, { role: 'tool', name: toolName, paramsStr: toolParamsStr, id: toolId, content: errorMessage, result: { type: 'error', params: toolParams, value: errorMessage }, }) - return { awaitingUserApproval: false, canceled: false } + return {} } // 5. add to history and keep going this._addMessageToThread(threadId, { role: 'tool', name: toolName, paramsStr: toolParamsStr, id: toolId, content: toolResultStr, result: { type: 'success', params: toolParams, value: toolResult }, }) - return { awaitingUserApproval: false, canceled: false } + return {} }; // above just defines helpers, below starts the actual function diff --git a/src/vs/workbench/contrib/void/browser/editCodeService.ts b/src/vs/workbench/contrib/void/browser/editCodeService.ts index 7d3b20f9..41e0e1ea 100644 --- a/src/vs/workbench/contrib/void/browser/editCodeService.ts +++ b/src/vs/workbench/contrib/void/browser/editCodeService.ts @@ -1244,11 +1244,11 @@ class EditCodeService extends Disposable implements IEditCodeService { // ctrlkzone should never have any conflicts } else { - // keep conflict on whole file - to keep conflict, revert the change and use those contents as original, then un-revert the change + // keep conflict on whole file - to keep conflict, revert the change and use those contents as original, then un-revert the file const currentFileStr = originalFileStr this.acceptOrRejectAllDiffAreas({ uri, removeCtrlKs: true, behavior: 'reject', _addToHistory: false }) const oldFileStr = model.getValue(EndOfLinePreference.LF) // use this as original code - this._writeURIText(uri, currentFileStr, 'wholeFileRange', { shouldRealignDiffAreas: false }) // un-revert + this._writeURIText(uri, currentFileStr, 'wholeFileRange', { shouldRealignDiffAreas: true }) // un-revert originalCode = oldFileStr } 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 637de4cd..10a9a6dc 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 @@ -224,6 +224,7 @@ const ChatModeDropdown = ({ className }: { className: string }) => { const accessor = useAccessor() const voidSettingsService = accessor.get('IVoidSettingsService') + const settingsState = useSettingsState() const options: ChatMode[] = useMemo(() => ['normal', 'gather', 'agent'], []) @@ -234,7 +235,7 @@ const ChatModeDropdown = ({ className }: { className: string }) => { return nameOfChatMode[val]} getOptionDropdownName={(val) => nameOfChatMode[val]} @@ -674,7 +675,7 @@ export const SelectedFiles = ( type ToolHeaderParams = { icon?: React.ReactNode; - title: string; + title: React.ReactNode; desc1: React.ReactNode; desc2?: React.ReactNode; isError?: boolean; @@ -1109,24 +1110,30 @@ const ReasoningWrapper = ({ isDoneReasoning, isStreaming, children }: { isDoneRe // should either be past or "-ing" tense, not present tense. Eg. when the LLM searches for something, the user expects it to say "I searched for X" or "I am searching for X". Not "I search X". +const loadingTitleWrapper = (item: React.ReactNode) => { + return + {item} + + +} const folderFileStr = (isFolder: boolean) => isFolder ? 'folder' : 'file' const toolNameToTitle = { - 'read_file': { done: 'Read file', proposed: 'Read file', running: 'Reading file...' }, - 'list_dir': { done: 'Inspected folder', proposed: 'Inspect folder', running: 'Inspecting folder...' }, - 'pathname_search': { done: 'Searched by file name', proposed: 'Search by file name', running: 'Searching by file name...' }, - 'text_search': { done: 'Searched', proposed: 'Search text', running: 'Searching...' }, + 'read_file': { done: 'Read file', proposed: 'Read file', running: loadingTitleWrapper('Reading file') }, + 'list_dir': { done: 'Inspected folder', proposed: 'Inspect folder', running: loadingTitleWrapper('Inspecting folder') }, + 'pathname_search': { done: 'Searched by file name', proposed: 'Search by file name', running: loadingTitleWrapper('Searching by file name') }, + 'text_search': { done: 'Searched', proposed: 'Search text', running: loadingTitleWrapper('Searching') }, 'create_uri': { done: (isFolder: boolean) => `Created ${folderFileStr(isFolder)}`, proposed: (isFolder: boolean) => `Create ${folderFileStr(isFolder)}`, - running: (isFolder: boolean) => `Creating ${folderFileStr(isFolder)}...` + running: (isFolder: boolean) => loadingTitleWrapper(`Creating ${folderFileStr(isFolder)}`) }, 'delete_uri': { done: (isFolder: boolean) => `Deleted ${folderFileStr(isFolder)}`, proposed: (isFolder: boolean) => `Delete ${folderFileStr(isFolder)}`, - running: (isFolder: boolean) => `Deleting ${folderFileStr(isFolder)}...` + running: (isFolder: boolean) => loadingTitleWrapper(`Deleting ${folderFileStr(isFolder)}`) }, - 'edit': { done: 'Edited file', proposed: 'Edit file', running: 'Editing file...' }, - 'terminal_command': { done: 'Ran terminal command', proposed: 'Run terminal command', running: 'Running terminal command...' } + 'edit': { done: `Edited file`, proposed: 'Edit file', running: loadingTitleWrapper('Editing file') }, + 'terminal_command': { done: `Ran terminal command`, proposed: 'Run terminal command', running: loadingTitleWrapper('Running terminal command') } } as const satisfies Record @@ -1778,7 +1785,9 @@ const ChatBubble = ({ chatMessage, isCommitted, messageIdx, isLast, chatIsRunnin } else if (role === 'tool') { const ToolResultWrapper = toolNameToComponent[chatMessage.name].resultWrapper as ResultWrapper - return + if (ToolResultWrapper) + return + return null } } diff --git a/src/vs/workbench/contrib/void/browser/react/src/void-command-bar-tsx/VoidCommandBar.tsx b/src/vs/workbench/contrib/void/browser/react/src/void-command-bar-tsx/VoidCommandBar.tsx index be9fb5d2..58e1f47d 100644 --- a/src/vs/workbench/contrib/void/browser/react/src/void-command-bar-tsx/VoidCommandBar.tsx +++ b/src/vs/workbench/contrib/void/browser/react/src/void-command-bar-tsx/VoidCommandBar.tsx @@ -21,7 +21,6 @@ export type VoidCommandBarProps = { export const VoidCommandBarMain = ({ uri, editor }: VoidCommandBarProps) => { const isDark = useIsDark() - console.log('VoidCommandBarMain', uri?.fsPath) return
diff --git a/src/vs/workbench/contrib/void/browser/toolsService.ts b/src/vs/workbench/contrib/void/browser/toolsService.ts index c43fe5af..629436a7 100644 --- a/src/vs/workbench/contrib/void/browser/toolsService.ts +++ b/src/vs/workbench/contrib/void/browser/toolsService.ts @@ -78,7 +78,7 @@ const directoryResultToString = (params: ToolCallParams['list_dir'], result: Too const entries = result.children; if (!result.hasPrevPage) { // is first page - output += `${params.rootURI}\n`; + output += `${params.rootURI.fsPath}\n`; } for (let i = 0; i < entries.length; i++) { diff --git a/src/vs/workbench/contrib/void/common/prompt/prompts.ts b/src/vs/workbench/contrib/void/common/prompt/prompts.ts index 51fb3703..ffedfe24 100644 --- a/src/vs/workbench/contrib/void/common/prompt/prompts.ts +++ b/src/vs/workbench/contrib/void/common/prompt/prompts.ts @@ -16,10 +16,10 @@ import { EndOfLinePreference } from '../../../../../editor/common/model.js'; export const tripleTick = ['```', '```'] export const editToolDesc_toolDescription = `\ -A high level description of the change you'd like to make in the file. This description will be handed to a dumber, faster model that will quickly apply the change.\ -Make sure to include all necessary information to make the change in this description, since it is the only context given to the fast-apply model that will actually write the change.\ -The best description you can give is a single code block of the form:\n${tripleTick[0]}\n// ... existing code ...\n{{change 1}}\n// ... existing code ...\n{{change2}}\n// ... existing code ...\n{{change 3}}\n...\n${tripleTick[1]}. \ -Wrap all code in triple backticks. Do NOT output the whole file here if possible, and try to write as LITTLE code as needed to describe the change.` +A high level description of the change you'd like to make in the file. \ +Your output should be of the form:\n${tripleTick[0]}\n// ... existing code ...\n{{change 1}}\n// ... existing code ...\n{{change2}}\n// ... existing code ...\n{{change 3}}\n...\n${tripleTick[1]}. \ +(wrap your output in triple backticks). Do NOT output the whole file here, and write as little as possible. If a change seems big, break it up into smaller edits. \ +Your description will be handed to a dumber, faster model that will quickly apply the change, so try to be brief, but also make sure to include enough information to accurately describe the change.` 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 2b23c0cb..27e99357 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 @@ -206,7 +206,7 @@ const _sendOpenAICompatibleChat = ({ messages: messages_, onText, onFinalMessage if (!toolCallOfIndex[index]) toolCallOfIndex[index] = { name: '', paramsStr: '', id: '' } toolCallOfIndex[index].name += tool.function?.name ?? '' toolCallOfIndex[index].paramsStr += tool.function?.arguments ?? ''; - toolCallOfIndex[index].id = tool.id ?? '' + toolCallOfIndex[index].id += tool.id ?? '' } // message const newText = chunk.choices[0]?.delta?.content ?? ''