mirror of
https://github.com/voideditor/void
synced 2026-05-24 09:58:23 +00:00
tool improvements
This commit is contained in:
parent
7244d433dd
commit
af41d6a439
6 changed files with 41 additions and 33 deletions
|
|
@ -326,19 +326,21 @@ class ChatThreadService extends Disposable implements IChatThreadService {
|
|||
this._setStreamState(threadId, { messageSoFar: fullText })
|
||||
},
|
||||
onFinalMessage: async ({ fullText, tools }) => {
|
||||
if (tools.length === 0) {
|
||||
this._addMessageToThread(threadId, { role: 'assistant', content: fullText, displayContent: fullText, tool_calls: tools })
|
||||
|
||||
if ((tools?.length ?? 0) === 0) {
|
||||
this._finishStreamingTextMessage(threadId, fullText)
|
||||
}
|
||||
else {
|
||||
for (const tool of tools) {
|
||||
for (const tool of tools ?? []) {
|
||||
if (!(tool.name in this._toolsService.toolFns)) {
|
||||
this._addMessageToThread(threadId, { role: 'tool', name: tool.name, params: tool.args, id: tool.id, content: `Error: This tool was not recognized, so it was not called.`, displayContent: `Error: tool not recognized.`, })
|
||||
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.`, })
|
||||
}
|
||||
else {
|
||||
const toolName = tool.name as ToolName
|
||||
const toolResult = await this._toolsService.toolFns[toolName](tool.args)
|
||||
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.args, id: tool.id, content: string, displayContent: string, })
|
||||
this._addMessageToThread(threadId, { role: 'tool', name: tool.name, params: tool.params, id: tool.id, content: string, displayContent: string, })
|
||||
shouldContinue = true
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ export const errorDetails = (fullError: Error | null): string | null => {
|
|||
}
|
||||
|
||||
export type OnText = (p: { newText: string, fullText: string }) => void
|
||||
export type OnFinalMessage = (p: { fullText: string, tools: { name: string, args: string, id: string, }[] }) => void // id is tool_use_id
|
||||
export type OnFinalMessage = (p: { fullText: string, tools?: { name: string, params: string, id: string, }[] }) => void // id is tool_use_id
|
||||
export type OnError = (p: { message: string, fullError: Error | null }) => void
|
||||
export type AbortRef = { current: (() => void) | null }
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ export type DeveloperInfoAtModel = {
|
|||
// UNUSED (coming soon):
|
||||
recognizedModelName: RecognizedModelName, // used to show user if model was auto-recognized
|
||||
supportsTools: boolean, // we will just do a string of tool use if it doesn't support
|
||||
supportsSystemMessage: 'developer' | 'system' | false, // if null, we will just do a string of system message
|
||||
supportsSystemMessageRole: 'developer' | 'system' | false, // if null, we will just do a string of system message. this is independent from separateSystemMessage, which takes priority and is passed directly in each provider's implementation.
|
||||
supportsAutocompleteFIM: boolean, // we will just do a description of FIM if it doens't support <|fim_hole|>
|
||||
supportsStreaming: boolean, // (o1 does NOT) we will just dump the final result if doesn't support it
|
||||
maxTokens: number, // required
|
||||
|
|
@ -98,7 +98,7 @@ export function recognizedModelOfModelName(modelName: string): RecognizedModelNa
|
|||
const developerInfoAtProvider: { [providerName in ProviderName]: DeveloperInfoAtProvider } = {
|
||||
'anthropic': {
|
||||
overrideSettingsForAllModels: {
|
||||
supportsSystemMessage: 'system',
|
||||
supportsSystemMessageRole: 'system',
|
||||
supportsTools: true,
|
||||
supportsAutocompleteFIM: false,
|
||||
supportsStreaming: true,
|
||||
|
|
@ -106,7 +106,7 @@ const developerInfoAtProvider: { [providerName in ProviderName]: DeveloperInfoAt
|
|||
},
|
||||
'deepseek': {
|
||||
overrideSettingsForAllModels: {
|
||||
supportsSystemMessage: false,
|
||||
supportsSystemMessageRole: false,
|
||||
supportsTools: false,
|
||||
supportsAutocompleteFIM: false,
|
||||
supportsStreaming: true,
|
||||
|
|
@ -137,15 +137,15 @@ export const developerInfoOfProviderName = (providerName: ProviderName): Partial
|
|||
// providerName is optional, but gives some extra fallbacks if provided
|
||||
const developerInfoOfRecognizedModelName: { [recognizedModel in RecognizedModelName]: Omit<DeveloperInfoAtModel, 'recognizedModelName'> } = {
|
||||
'OpenAI 4o': {
|
||||
supportsSystemMessage: false,
|
||||
supportsTools: false,
|
||||
supportsSystemMessageRole: 'system',
|
||||
supportsTools: true,
|
||||
supportsAutocompleteFIM: false,
|
||||
supportsStreaming: false,
|
||||
supportsStreaming: true,
|
||||
maxTokens: 4096,
|
||||
},
|
||||
|
||||
'Anthropic Claude': {
|
||||
supportsSystemMessage: false,
|
||||
supportsSystemMessageRole: 'system',
|
||||
supportsTools: false,
|
||||
supportsAutocompleteFIM: false,
|
||||
supportsStreaming: false,
|
||||
|
|
@ -153,7 +153,7 @@ const developerInfoOfRecognizedModelName: { [recognizedModel in RecognizedModelN
|
|||
},
|
||||
|
||||
'Llama 3.x': {
|
||||
supportsSystemMessage: false,
|
||||
supportsSystemMessageRole: false,
|
||||
supportsTools: false,
|
||||
supportsAutocompleteFIM: false,
|
||||
supportsStreaming: false,
|
||||
|
|
@ -161,7 +161,7 @@ const developerInfoOfRecognizedModelName: { [recognizedModel in RecognizedModelN
|
|||
},
|
||||
|
||||
'Deepseek Chat': {
|
||||
supportsSystemMessage: false,
|
||||
supportsSystemMessageRole: false,
|
||||
supportsTools: false,
|
||||
supportsAutocompleteFIM: false,
|
||||
supportsStreaming: false,
|
||||
|
|
@ -169,7 +169,7 @@ const developerInfoOfRecognizedModelName: { [recognizedModel in RecognizedModelN
|
|||
},
|
||||
|
||||
'Alibaba Qwen2.5 Coder Instruct': {
|
||||
supportsSystemMessage: false,
|
||||
supportsSystemMessageRole: false,
|
||||
supportsTools: false,
|
||||
supportsAutocompleteFIM: false,
|
||||
supportsStreaming: false,
|
||||
|
|
@ -177,7 +177,7 @@ const developerInfoOfRecognizedModelName: { [recognizedModel in RecognizedModelN
|
|||
},
|
||||
|
||||
'Mistral Codestral': {
|
||||
supportsSystemMessage: false,
|
||||
supportsSystemMessageRole: false,
|
||||
supportsTools: false,
|
||||
supportsAutocompleteFIM: false,
|
||||
supportsStreaming: false,
|
||||
|
|
@ -185,7 +185,7 @@ const developerInfoOfRecognizedModelName: { [recognizedModel in RecognizedModelN
|
|||
},
|
||||
|
||||
'OpenAI o1, o3': {
|
||||
supportsSystemMessage: false,
|
||||
supportsSystemMessageRole: false,
|
||||
supportsTools: false,
|
||||
supportsAutocompleteFIM: false,
|
||||
supportsStreaming: false,
|
||||
|
|
@ -193,7 +193,7 @@ const developerInfoOfRecognizedModelName: { [recognizedModel in RecognizedModelN
|
|||
},
|
||||
|
||||
'Deepseek R1': {
|
||||
supportsSystemMessage: false,
|
||||
supportsSystemMessageRole: false,
|
||||
supportsTools: false,
|
||||
supportsAutocompleteFIM: false,
|
||||
supportsStreaming: false,
|
||||
|
|
@ -201,7 +201,7 @@ const developerInfoOfRecognizedModelName: { [recognizedModel in RecognizedModelN
|
|||
},
|
||||
|
||||
'<GENERAL>': {
|
||||
supportsSystemMessage: false,
|
||||
supportsSystemMessageRole: false,
|
||||
supportsTools: false,
|
||||
supportsAutocompleteFIM: false,
|
||||
supportsStreaming: false,
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
import Anthropic from '@anthropic-ai/sdk';
|
||||
import { _InternalSendLLMChatMessageFnType } from '../../common/llmMessageTypes.js';
|
||||
import { anthropicMaxPossibleTokens } from '../../common/voidSettingsTypes.js';
|
||||
import { anthropicMaxPossibleTokens, developerInfoOfModelName, developerInfoOfProviderName } from '../../common/voidSettingsTypes.js';
|
||||
import { InternalToolInfo } from '../../common/toolsService.js';
|
||||
import { addSystemMessageAndToolSupport } from './processMessages.js';
|
||||
|
||||
|
|
@ -39,11 +39,14 @@ export const sendAnthropicChat: _InternalSendLLMChatMessageFnType = ({ messages:
|
|||
return
|
||||
}
|
||||
|
||||
const { messages, separateSystemMessageStr, devInfo } = addSystemMessageAndToolSupport(modelName, providerName, messages_, aiInstructions, { separateSystemMessage: true })
|
||||
const { messages, separateSystemMessageStr } = addSystemMessageAndToolSupport(modelName, providerName, messages_, aiInstructions, { separateSystemMessage: true })
|
||||
|
||||
const { overrideSettingsForAllModels } = developerInfoOfProviderName(providerName)
|
||||
const { supportsTools } = developerInfoOfModelName(modelName, overrideSettingsForAllModels)
|
||||
|
||||
const anthropic = new Anthropic({ apiKey: thisConfig.apiKey, dangerouslyAllowBrowser: true });
|
||||
|
||||
const tools = devInfo?.supportsTools && (tools_?.length ?? 0) !== 0 ? tools_?.map(tool => toAnthropicTool(tool)) : undefined
|
||||
const tools = (supportsTools && ((tools_?.length ?? 0) !== 0)) ? tools_?.map(tool => toAnthropicTool(tool)) : undefined
|
||||
|
||||
const stream = anthropic.messages.stream({
|
||||
system: separateSystemMessageStr,
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import { _InternalModelListFnType, _InternalSendLLMFIMMessageFnType, _InternalSe
|
|||
import { Model } from 'openai/resources/models.js';
|
||||
import { InternalToolInfo } from '../../common/toolsService.js';
|
||||
import { addSystemMessageAndToolSupport } from './processMessages.js';
|
||||
import { developerInfoOfModelName, developerInfoOfProviderName } from '../../common/voidSettingsTypes.js';
|
||||
// import { parseMaxTokensStr } from './util.js';
|
||||
|
||||
|
||||
|
|
@ -147,12 +148,14 @@ export const sendOpenAIFIM: _InternalSendLLMFIMMessageFnType = ({ messages, onTe
|
|||
export const sendOpenAIChat: _InternalSendLLMChatMessageFnType = ({ messages: messages_, onText, onFinalMessage, onError, settingsOfProvider, modelName, _setAborter, providerName, aiInstructions, tools: tools_ }) => {
|
||||
|
||||
let fullText = ''
|
||||
const toolCallOfIndex: { [index: string]: { name: string, args: string, id: string } } = {}
|
||||
const toolCallOfIndex: { [index: string]: { name: string, params: string, id: string } } = {}
|
||||
|
||||
const { messages, devInfo } = addSystemMessageAndToolSupport(modelName, providerName, messages_, aiInstructions, { separateSystemMessage: false })
|
||||
const { overrideSettingsForAllModels } = developerInfoOfProviderName(providerName)
|
||||
const { supportsTools } = developerInfoOfModelName(modelName, overrideSettingsForAllModels)
|
||||
|
||||
const tools = devInfo?.supportsTools && (tools_?.length ?? 0) !== 0 ? tools_?.map(tool => toOpenAITool(tool)) : undefined
|
||||
const { messages } = addSystemMessageAndToolSupport(modelName, providerName, messages_, aiInstructions, { separateSystemMessage: false })
|
||||
|
||||
const tools = (supportsTools && ((tools_?.length ?? 0) !== 0)) ? tools_?.map(tool => toOpenAITool(tool)) : undefined
|
||||
|
||||
const openai: OpenAI = newOpenAI({ providerName, settingsOfProvider })
|
||||
const options: OpenAI.Chat.Completions.ChatCompletionCreateParamsStreaming = {
|
||||
|
|
@ -175,9 +178,9 @@ export const sendOpenAIChat: _InternalSendLLMChatMessageFnType = ({ messages: me
|
|||
// tool call
|
||||
for (const tool of chunk.choices[0]?.delta?.tool_calls ?? []) {
|
||||
const index = tool.index
|
||||
if (!toolCallOfIndex[index]) toolCallOfIndex[index] = { name: '', args: '', id: '' }
|
||||
if (!toolCallOfIndex[index]) toolCallOfIndex[index] = { name: '', params: '', id: '' }
|
||||
toolCallOfIndex[index].name += tool.function?.name ?? ''
|
||||
toolCallOfIndex[index].args += tool.function?.arguments ?? '';
|
||||
toolCallOfIndex[index].params += tool.function?.arguments ?? '';
|
||||
toolCallOfIndex[index].id = tool.id ?? ''
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
|
||||
|
||||
import { LLMChatMessage } from '../../common/llmMessageTypes.js';
|
||||
import { DeveloperInfoAtModel, developerInfoOfModelName, developerInfoOfProviderName, ProviderName } from '../../common/voidSettingsTypes.js';
|
||||
import { developerInfoOfModelName, developerInfoOfProviderName, ProviderName } from '../../common/voidSettingsTypes.js';
|
||||
import { deepClone } from '../../../../../base/common/objects.js';
|
||||
|
||||
|
||||
|
|
@ -9,13 +9,12 @@ import { deepClone } from '../../../../../base/common/objects.js';
|
|||
|
||||
// no matter whether the model supports a system message or not (or what format it supports), add it in some way
|
||||
// also take into account tools if the model doesn't support tool use
|
||||
export const addSystemMessageAndToolSupport = (modelName: string, providerName: ProviderName, messages_: LLMChatMessage[], aiInstructions: string, { separateSystemMessage }: { separateSystemMessage: boolean }): { separateSystemMessageStr?: string, messages: any[], devInfo: DeveloperInfoAtModel } => {
|
||||
export const addSystemMessageAndToolSupport = (modelName: string, providerName: ProviderName, messages_: LLMChatMessage[], aiInstructions: string, { separateSystemMessage }: { separateSystemMessage: boolean }): { separateSystemMessageStr?: string, messages: any[] } => {
|
||||
|
||||
const messages = deepClone(messages_).map(m => ({ ...m, content: m.content.trim(), }))
|
||||
|
||||
const { overrideSettingsForAllModels } = developerInfoOfProviderName(providerName)
|
||||
const devInfo = developerInfoOfModelName(modelName, overrideSettingsForAllModels)
|
||||
const { supportsSystemMessage, supportsTools } = devInfo
|
||||
const { supportsSystemMessageRole: supportsSystemMessage, supportsTools } = developerInfoOfModelName(modelName, overrideSettingsForAllModels)
|
||||
|
||||
// 1. SYSTEM MESSAGE
|
||||
// find system messages and concatenate them
|
||||
|
|
@ -236,12 +235,13 @@ export const addSystemMessageAndToolSupport = (modelName: string, providerName:
|
|||
// TODO!!!
|
||||
|
||||
|
||||
console.log('SYSMG', separateSystemMessage)
|
||||
console.log('FINAL MESSAGES', finalMessages)
|
||||
|
||||
|
||||
return {
|
||||
separateSystemMessageStr,
|
||||
messages: finalMessages,
|
||||
devInfo,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue