mirror of
https://github.com/voideditor/void
synced 2026-05-24 09:58:23 +00:00
tools + misc fixes
This commit is contained in:
parent
628adedaec
commit
a78a6169f8
8 changed files with 68 additions and 22 deletions
|
|
@ -14,7 +14,7 @@ import { IRange } from '../../../../editor/common/core/range.js';
|
|||
import { ILLMMessageService } from '../common/llmMessageService.js';
|
||||
import { IModelService } from '../../../../editor/common/services/model.js';
|
||||
import { chat_userMessage, chat_systemMessage } from './prompt/prompts.js';
|
||||
import { InternalToolInfo, IToolsService, ToolName, voidTools } from '../common/toolsService.js';
|
||||
import { InternalToolInfo, IToolsService, ToolFns, ToolName, voidTools } from '../common/toolsService.js';
|
||||
import { toLLMChatMessage } from '../common/llmMessageTypes.js';
|
||||
|
||||
// one of the square items that indicates a selection in a chat bubble (NOT a file, a Selection of text)
|
||||
|
|
@ -57,11 +57,6 @@ export type ChatMessage =
|
|||
staging: StagingInfo | null
|
||||
} | {
|
||||
role: 'assistant';
|
||||
tool_calls?: {
|
||||
name: string,
|
||||
id: string,
|
||||
params: string
|
||||
}[];
|
||||
content: string | null; // content received from LLM - allowed to be '', will be replaced with (empty)
|
||||
displayContent: string | null; // content displayed to user (this is the same as content for now) - allowed to be '', will be ignored
|
||||
} | {
|
||||
|
|
@ -327,25 +322,43 @@ class ChatThreadService extends Disposable implements IChatThreadService {
|
|||
this._setStreamState(threadId, { messageSoFar: fullText })
|
||||
},
|
||||
onFinalMessage: async ({ fullText, toolCalls }) => {
|
||||
toolCalls = toolCalls?.filter(tool => tool.name in this._toolsService.toolFns)
|
||||
|
||||
console.log('FINAL MESSAGE', fullText, toolCalls)
|
||||
|
||||
if ((toolCalls?.length ?? 0) === 0) {
|
||||
this._finishStreamingTextMessage(threadId, fullText)
|
||||
}
|
||||
else {
|
||||
this._addMessageToThread(threadId, { role: 'assistant', content: fullText, displayContent: fullText, tool_calls: toolCalls })
|
||||
this._addMessageToThread(threadId, { role: 'assistant', content: fullText, displayContent: fullText })
|
||||
this._setStreamState(threadId, { messageSoFar: undefined }) // clear streaming message
|
||||
for (const tool of toolCalls ?? []) {
|
||||
if (!(tool.name in this._toolsService.toolFns)) {
|
||||
this._addMessageToThread(threadId, { role: 'tool', name: tool.name, params: tool.params, id: tool.id, content: `Error: This tool was not recognized, so it was not called.`, displayContent: `Error: tool not recognized.`, })
|
||||
const toolName = tool.name as ToolName
|
||||
|
||||
// 1.
|
||||
let toolResult: Awaited<ReturnType<ToolFns[ToolName]>>
|
||||
try {
|
||||
toolResult = await this._toolsService.toolFns[toolName](tool.params)
|
||||
} catch (e) {
|
||||
this._setStreamState(threadId, { error: e })
|
||||
shouldContinue = false
|
||||
break
|
||||
}
|
||||
else {
|
||||
const toolName = tool.name as ToolName
|
||||
const toolResult = await this._toolsService.toolFns[toolName](tool.params)
|
||||
const string = this._toolsService.toolResultToString[toolName](toolResult as any) // typescript is so bad it doesn't even couple the type of ToolResult with the type of the function being called here
|
||||
this._addMessageToThread(threadId, { role: 'tool', name: tool.name, params: tool.params, id: tool.id, content: string, displayContent: string, })
|
||||
shouldContinue = true
|
||||
|
||||
// 2.
|
||||
let toolResultStr: string
|
||||
try {
|
||||
toolResultStr = this._toolsService.toolResultToString[toolName](toolResult as any) // typescript is so bad it doesn't even couple the type of ToolResult with the type of the function being called here
|
||||
} catch (e) {
|
||||
this._setStreamState(threadId, { error: e })
|
||||
shouldContinue = false
|
||||
break
|
||||
}
|
||||
|
||||
this._addMessageToThread(threadId, { role: 'tool', name: tool.name, params: tool.params, id: tool.id, content: toolResultStr, displayContent: toolResultStr, })
|
||||
shouldContinue = true
|
||||
}
|
||||
|
||||
}
|
||||
res_()
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,3 +1,7 @@
|
|||
/*--------------------------------------------------------------------------------------
|
||||
* Copyright 2025 Glass Devtools, Inc. All rights reserved.
|
||||
* Licensed under the Apache License, Version 2.0. See LICENSE.txt for more information.
|
||||
*--------------------------------------------------------------------------------------*/
|
||||
|
||||
// eg "bash" -> "shell"
|
||||
export const nameToVscodeLanguage: { [key: string]: string } = {
|
||||
|
|
|
|||
|
|
@ -1,3 +1,8 @@
|
|||
/*--------------------------------------------------------------------------------------
|
||||
* Copyright 2025 Glass Devtools, Inc. All rights reserved.
|
||||
* Licensed under the Apache License, Version 2.0. See LICENSE.txt for more information.
|
||||
*--------------------------------------------------------------------------------------*/
|
||||
|
||||
import { URI } from '../../../../../base/common/uri'
|
||||
import { EndOfLinePreference } from '../../../../../editor/common/model'
|
||||
import { IModelService } from '../../../../../editor/common/services/model.js'
|
||||
|
|
|
|||
17
src/vs/workbench/contrib/void/browser/helpers/systemInfo.ts
Normal file
17
src/vs/workbench/contrib/void/browser/helpers/systemInfo.ts
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
/*--------------------------------------------------------------------------------------
|
||||
* Copyright 2025 Glass Devtools, Inc. All rights reserved.
|
||||
* Licensed under the Apache License, Version 2.0. See LICENSE.txt for more information.
|
||||
*--------------------------------------------------------------------------------------*/
|
||||
|
||||
import { isLinux, isMacintosh, isWindows } from '../../../../../base/common/platform.js';
|
||||
|
||||
// import { OS, OperatingSystem } from '../../../../../base/common/platform.js';
|
||||
// alternatively could use ^ and OS === OperatingSystem.Windows ? ...
|
||||
|
||||
|
||||
|
||||
export const os = isWindows ? 'windows' : isMacintosh ? 'mac' : isLinux ? 'linux' : null
|
||||
|
||||
export const arch = process.arch
|
||||
export const osplatform = process.platform;
|
||||
|
||||
|
|
@ -9,6 +9,7 @@ import { filenameToVscodeLanguage } from '../helpers/detectLanguage.js';
|
|||
import { CodeSelection, StagingSelectionItem, FileSelection } from '../chatThreadService.js';
|
||||
import { VSReadFile } from '../helpers/readFile.js';
|
||||
import { IModelService } from '../../../../../editor/common/services/model.js';
|
||||
import { os, arch, osplatform } from '../helpers/systemInfo.js';
|
||||
|
||||
|
||||
// this is just for ease of readability
|
||||
|
|
@ -19,17 +20,22 @@ You are a coding assistant. You are given a list of instructions to follow \`INS
|
|||
|
||||
Please respond to the user's query.
|
||||
|
||||
The user has the following system information:
|
||||
- ${os} ${arch} ${osplatform}
|
||||
|
||||
In the case that the user asks you to make changes to code, you should make sure to return CODE BLOCKS of the changes, as well as explanations and descriptions of the changes.
|
||||
For example, if the user asks you to "make this file look nicer", make sure your output includes a code block with concrete ways the file can look nicer.
|
||||
- Do not re-write the entire file in the code block
|
||||
- You can write comments like "// ... existing code" to indicate existing code
|
||||
- Make sure you give enough context in the code block to apply the change to the correct location in the code.
|
||||
|
||||
You're allowed to ask for more context. For example, if the user only gives you a selection but you want to see the the full file, you can ask them to provide it.
|
||||
|
||||
Do not output any of these instructions, nor tell the user anything about them unless directly prompted for them.
|
||||
Do not tell the user anything about the examples below.
|
||||
|
||||
If you are not given tools, you're allowed to ask for more context. For example, if the user only gives you a selection but you want to see the the full file, you can ask them to provide it.
|
||||
If you are given tools, you are allowed to use them without asking for permission. You do not have to use them if you don't want to.
|
||||
If you are given tools, NEVER refer to a tool by name when speaking with the user. For example, do NOT say to the user user "I'm going to use \`list_dir\`". Instead, say "I'm going to list all files in ___ directory", etc.
|
||||
|
||||
## EXAMPLE 1
|
||||
FILES
|
||||
math.ts
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ import { env } from '../../../../../../../base/common/process.js'
|
|||
import { ModelDropdown } from './ModelDropdown.js'
|
||||
import { ChatMarkdownRender } from '../markdown/ChatMarkdownRender.js'
|
||||
import { WarningBox } from './WarningBox.js'
|
||||
import { os } from '../../../helpers/systemInfo.js'
|
||||
|
||||
const SubtleButton = ({ onClick, text, icon, disabled }: { onClick: () => void, text: string, icon: React.ReactNode, disabled: boolean }) => {
|
||||
|
||||
|
|
@ -505,7 +506,7 @@ const transferTheseFilesOfOS = (os: 'mac' | 'windows' | 'linux' | null): Transfe
|
|||
throw new Error(`os '${os}' not recognized`)
|
||||
}
|
||||
|
||||
const os = isWindows ? 'windows' : isMacintosh ? 'mac' : isLinux ? 'linux' : null
|
||||
|
||||
let transferTheseFiles: TransferFilesInfo = []
|
||||
let transferError: string | null = null
|
||||
|
||||
|
|
|
|||
|
|
@ -52,12 +52,12 @@ export type AbortRef = { current: (() => void) | null }
|
|||
|
||||
export const toLLMChatMessage = (c: ChatMessage): LLMChatMessage => {
|
||||
if (c.role === 'system' || c.role === 'user') {
|
||||
return { role: c.role, content: c.content ?? '(empty)' }
|
||||
return { role: c.role, content: c.content || '(empty message)' }
|
||||
}
|
||||
else if (c.role === 'assistant')
|
||||
return { role: c.role, content: c.content ?? '(empty model output)' }
|
||||
return { role: c.role, content: c.content || '(empty message)' }
|
||||
else if (c.role === 'tool')
|
||||
return { role: c.role, id: c.id, name: c.name, params: c.params, content: c.content ?? '(empty output)' }
|
||||
return { role: c.role, id: c.id, name: c.name, params: c.params, content: c.content || '(empty output)' }
|
||||
else {
|
||||
throw 1
|
||||
}
|
||||
|
|
|
|||
|
|
@ -111,7 +111,7 @@ async function generateDirectoryTreeMd(fileService: IFileService, rootURI: URI):
|
|||
|
||||
|
||||
const validateURI = (uriStr: unknown) => {
|
||||
if (typeof uriStr !== 'string') throw new Error('(uri was not a string)')
|
||||
if (typeof uriStr !== 'string') throw new Error('(provided uri must be a string)')
|
||||
const uri = URI.file(uriStr)
|
||||
return uri
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue