diff --git a/src/vs/workbench/contrib/void/browser/convertToLLMMessageService.ts b/src/vs/workbench/contrib/void/browser/convertToLLMMessageService.ts index ea9bc60c..9810f4bf 100644 --- a/src/vs/workbench/contrib/void/browser/convertToLLMMessageService.ts +++ b/src/vs/workbench/contrib/void/browser/convertToLLMMessageService.ts @@ -483,8 +483,8 @@ class ConvertToLLMMessageService extends Disposable implements IConvertToLLMMess }) const includeXMLToolDefinitions = !specialToolFormat - const runningTerminalIds = this.terminalToolService.listTerminalIds() - const systemMessage = chat_systemMessage({ workspaceFolders, openedURIs, directoryStr, activeURI, runningTerminalIds, chatMode, includeXMLToolDefinitions }) + const persistentTerminalIDs = this.terminalToolService.listTerminalIds() + const systemMessage = chat_systemMessage({ workspaceFolders, openedURIs, directoryStr, activeURI, persistentTerminalIDs, chatMode, includeXMLToolDefinitions }) return systemMessage } diff --git a/src/vs/workbench/contrib/void/browser/editCodeService.ts b/src/vs/workbench/contrib/void/browser/editCodeService.ts index d6c849df..240ce9a4 100644 --- a/src/vs/workbench/contrib/void/browser/editCodeService.ts +++ b/src/vs/workbench/contrib/void/browser/editCodeService.ts @@ -1594,10 +1594,10 @@ class EditCodeService extends Disposable implements IEditCodeService { for (const b of blocks) { const i = modelStr.indexOf(b.orig) if (i === -1) - throw new Error(this._errContentOfInvalidStr('Not found', replacements[i].block.orig)) + throw new Error(this._errContentOfInvalidStr('Not found', b.orig)) const j = modelStr.lastIndexOf(b.orig) if (i !== j) - throw new Error(this._errContentOfInvalidStr('Not unique', replacements[i].block.orig)) + throw new Error(this._errContentOfInvalidStr('Not unique', b.orig)) replacements.push({ origStart: i, @@ -1611,9 +1611,8 @@ class EditCodeService extends Disposable implements IEditCodeService { // ensure no overlap for (let i = 1; i < replacements.length; i++) { - if (replacements[i].origStart < replacements[i - 1].origEnd) { - // There's an overlap - throw new Error(this._errContentOfInvalidStr('Has overlap', replacements[i].block.orig)) + if (replacements[i].origStart <= replacements[i - 1].origEnd) { + throw new Error(this._errContentOfInvalidStr('Has overlap', replacements[i]?.block?.orig)) } } 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 3ebd78da..b85f8d76 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 @@ -1321,8 +1321,8 @@ const titleOfToolName = { 'search_for_files': { done: 'Searched', proposed: 'Search', running: loadingTitleWrapper('Searching') }, 'create_file_or_folder': { done: `Created`, proposed: `Create`, running: loadingTitleWrapper(`Creating`) }, 'delete_file_or_folder': { done: `Deleted`, proposed: `Delete`, running: loadingTitleWrapper(`Deleting`) }, - 'rewrite_file': { done: `Rewrote file`, proposed: 'Rewrite file', running: loadingTitleWrapper('Rewriting file') }, 'edit_file': { done: `Edited file`, proposed: 'Edit file', running: loadingTitleWrapper('Editing file') }, + 'rewrite_file': { done: `Wrote file`, proposed: 'Write file', running: loadingTitleWrapper('Writing file') }, 'run_command': { done: `Ran terminal`, proposed: 'Run terminal', running: loadingTitleWrapper('Running terminal') }, 'open_persistent_terminal': { done: `Opened terminal`, proposed: 'Open terminal', running: loadingTitleWrapper('Opening terminal') }, 'kill_persistent_terminal': { done: `Killed terminal`, proposed: 'Kill terminal', running: loadingTitleWrapper('Killing terminal') }, @@ -2065,12 +2065,12 @@ const toolNameToComponent: { [T in ToolName]: { resultWrapper: ResultWrapper, }, 'rewrite_file': { resultWrapper: (params) => { - return + return } }, 'edit_file': { resultWrapper: (params) => { - return + return } }, diff --git a/src/vs/workbench/contrib/void/browser/terminalToolService.ts b/src/vs/workbench/contrib/void/browser/terminalToolService.ts index 7abc98d6..96e9ec76 100644 --- a/src/vs/workbench/contrib/void/browser/terminalToolService.ts +++ b/src/vs/workbench/contrib/void/browser/terminalToolService.ts @@ -136,7 +136,7 @@ export class TerminalToolService extends Disposable implements ITerminalToolServ async killTerminal(terminalId: string) { const terminal = this.terminalInstanceOfId[terminalId] - if (!terminal) throw new Error(`Kill Terminal: Terminal with ID ${terminalId} did not exist.`); + if (!terminal) throw new Error(`Kill Terminal: Terminal with ID ${terminalId} does not exist.`); terminal.dispose(TerminalExitReason.Extension) delete this.terminalInstanceOfId[terminalId] return @@ -168,7 +168,7 @@ export class TerminalToolService extends Disposable implements ITerminalToolServ let terminalId: string if (isBG) { // BG process terminal = this.terminalInstanceOfId[bgTerminalId]; - if (!terminal) throw new Error(`Unexpected internal error: Terminal with ID ${bgTerminalId} did not exist.`); + if (!terminal) throw new Error(`Unexpected internal error: Terminal with ID ${bgTerminalId} does not exist.`); terminalId = bgTerminalId } else { diff --git a/src/vs/workbench/contrib/void/browser/toolsService.ts b/src/vs/workbench/contrib/void/browser/toolsService.ts index 6987e873..8c77a001 100644 --- a/src/vs/workbench/contrib/void/browser/toolsService.ts +++ b/src/vs/workbench/contrib/void/browser/toolsService.ts @@ -37,7 +37,7 @@ const isFalsy = (u: unknown) => { const validateStr = (argName: string, value: unknown) => { if (value === null) throw new Error(`Invalid LLM output: ${argName} was null.`) - if (typeof value !== 'string') throw new Error(`Invalid LLM output format: ${argName} must be a string, but it's a(n) ${typeof value}. Value: ${JSON.stringify(value)}.`) + if (typeof value !== 'string') throw new Error(`Invalid LLM output format: ${argName} must be a string, but its type is "${typeof value}". Full value: ${JSON.stringify(value)}.`) return value } @@ -46,7 +46,7 @@ const validateStr = (argName: string, value: unknown) => { // TODO!!!! check to make sure folder/file exists const validateURI = (uriStr: unknown) => { if (uriStr === null) throw new Error(`Invalid LLM output: uri was null.`) - if (typeof uriStr !== 'string') throw new Error(`Invalid LLM output format: Provided uri must be a string, but it's a(n) ${typeof uriStr}. Value: ${uriStr}.`) + if (typeof uriStr !== 'string') throw new Error(`Invalid LLM output format: Provided uri must be a string, but it's a(n) ${typeof uriStr}. Full value: ${JSON.stringify(uriStr)}.`) const uri = URI.file(uriStr) return uri } diff --git a/src/vs/workbench/contrib/void/common/prompt/prompts.ts b/src/vs/workbench/contrib/void/common/prompt/prompts.ts index f8c7fc11..3820c871 100644 --- a/src/vs/workbench/contrib/void/common/prompt/prompts.ts +++ b/src/vs/workbench/contrib/void/common/prompt/prompts.ts @@ -41,19 +41,17 @@ export const FINAL = `>>>>>>> UPDATED` const searchReplaceBlockTemplate = `\ -${tripleTick[0]} ${ORIGINAL} -// ... original code 1 goes here +// ... original code goes here ${DIVIDER} -// ... final code 1 goes here +// ... final code goes here ${FINAL} + ${ORIGINAL} -// ... original code 2 goes here +// ... original code goes here ${DIVIDER} -// ... final code 2 goes here -${FINAL} -... -${tripleTick[1]}` +// ... final code goes here +${FINAL}` @@ -63,7 +61,9 @@ You are a coding assistant that takes in a diff, and outputs SEARCH/REPLACE code The diff will be labeled \`DIFF\` and the original file will be labeled \`ORIGINAL_FILE\`. Format your SEARCH/REPLACE blocks as follows: +${tripleTick[0]} ${searchReplaceBlockTemplate} +${tripleTick[1]} 1. Your SEARCH/REPLACE block(s) must implement the diff EXACTLY. Do NOT leave anything out. @@ -106,18 +106,21 @@ ${tripleTick[1]}` const replaceTool_description = `\ -A string of SEARCH/REPLACE block(s) to apply to the given file. -You are encouraged to output multiple changes in this string when possible. For example: +A string of SEARCH/REPLACE block(s) which will be applied to the given file. +Your SEARCH/REPLACE blocks string must be formatted as follows: ${searchReplaceBlockTemplate} -Guidelines: -1. The ORIGINAL code in each SEARCH/REPLACE block must EXACTLY match lines in the original file. Do not add or remove any whitespace or comments from the original code. +## Guidelines: -2. Each ORIGINAL text must be large enough to uniquely identify the change in the file. However, bias towards writing as little as possible. +1. You are encouraged to output multiple changes whenever possible. -3. Each ORIGINAL text must be DISJOINT from all other ORIGINAL text. +2. The ORIGINAL code in each SEARCH/REPLACE block must EXACTLY match lines in the original file. Do not add or remove any whitespace or comments from the original code. -4. This field is a STRING (not an array). You should wrap the string in triple backticks.` +3. Each ORIGINAL text must be large enough to uniquely identify the change. However, bias towards writing as little as possible. + +4. Each ORIGINAL text must be DISJOINT from all other ORIGINAL text. + +5. This field is a STRING (not an array).` // ======================================================== tools ======================================================== @@ -300,7 +303,7 @@ export const voidTools = { description: `Edits a file, deleting all the old contents and replacing them with your new contents. Use this tool if you want to edit a file you just created.`, params: { ...uriParam('file'), - new_content: { description: `The new contents of the file.` } + new_content: { description: `The new contents of the file. Must be a string.` } }, }, @@ -403,7 +406,7 @@ ${toolCallXMLGuidelines}` // ======================================================== chat (normal, gather, agent) ======================================================== -export const chat_systemMessage = ({ workspaceFolders, openedURIs, activeURI, runningTerminalIds, directoryStr, chatMode: mode, includeXMLToolDefinitions }: { workspaceFolders: string[], directoryStr: string, openedURIs: string[], activeURI: string | undefined, runningTerminalIds: string[], chatMode: ChatMode, includeXMLToolDefinitions: boolean }) => { +export const chat_systemMessage = ({ workspaceFolders, openedURIs, activeURI, persistentTerminalIDs, directoryStr, chatMode: mode, includeXMLToolDefinitions }: { workspaceFolders: string[], directoryStr: string, openedURIs: string[], activeURI: string | undefined, persistentTerminalIDs: string[], chatMode: ChatMode, includeXMLToolDefinitions: boolean }) => { const header = (`You are an expert coding ${mode === 'agent' ? 'agent' : 'assistant'} whose job is \ ${mode === 'agent' ? `to help the user develop, run, and make changes to their codebase.` : mode === 'gather' ? `to search, understand, and reference files in the user's codebase.` @@ -425,9 +428,9 @@ ${workspaceFolders.join('\n') || 'NO WORKSPACE OPEN'} ${activeURI} - Open files: -${openedURIs.join('\n') || 'NO OPENED EDITORS'}${''/* separator */}${mode === 'agent' && runningTerminalIds.length !== 0 ? ` +${openedURIs.join('\n') || 'NO OPENED EDITORS'}${''/* separator */}${mode === 'agent' && persistentTerminalIDs.length !== 0 ? ` -- Existing terminal IDs: ${runningTerminalIds.join(', ')}` : ''} +- Persistent terminal IDs available for you to run commands in: ${persistentTerminalIDs.join(', ')}` : ''} `) @@ -510,7 +513,7 @@ ${details.map((d, i) => `${i + 1}. ${d}`).join('\n\n')}`) // // log all prompts // for (const chatMode of ['agent', 'gather', 'normal'] satisfies ChatMode[]) { // console.log(`========================================= SYSTEM MESSAGE FOR ${chatMode} ===================================\n`, -// chat_systemMessage({ chatMode, workspaceFolders: [], openedURIs: [], activeURI: 'pee', runningTerminalIds: [], directoryStr: 'lol', })) +// chat_systemMessage({ chatMode, workspaceFolders: [], openedURIs: [], activeURI: 'pee', persistentTerminalIDs: [], directoryStr: 'lol', })) // } 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 232bdfab..4a515e50 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 @@ -162,6 +162,10 @@ const _sendOpenAICompatibleFIM = async ({ messages: { prefix, suffix, stopTokens const toOpenAICompatibleTool = (toolInfo: InternalToolInfo) => { const { name, description, params } = toolInfo + + const paramsWithType: { [s: string]: { description: string; type: 'string' } } = {} + for (const key in params) { paramsWithType[key] = { ...params[key], type: 'string' } } + return { type: 'function', function: { @@ -358,12 +362,14 @@ const _openaiCompatibleList = async ({ onSuccess: onSuccess_, onError: onError_, // ------------ ANTHROPIC (HELPERS) ------------ const toAnthropicTool = (toolInfo: InternalToolInfo) => { const { name, description, params } = toolInfo + const paramsWithType: { [s: string]: { description: string; type: 'string' } } = {} + for (const key in params) { paramsWithType[key] = { ...params[key], type: 'string' } } return { name: name, description: description, input_schema: { type: 'object', - properties: params, + properties: paramsWithType, // required: Object.keys(params), }, } satisfies Anthropic.Messages.Tool