From da4c9c8c40dbff2ab84caf37c563cc7632d81b38 Mon Sep 17 00:00:00 2001 From: Andrew Pareles Date: Wed, 5 Feb 2025 00:36:44 -0800 Subject: [PATCH] fim better abstraction --- .../platform/void/common/llmMessageTypes.ts | 22 +++++++++---------- .../electron-main/llmMessage/anthropic.ts | 4 ++-- .../void/electron-main/llmMessage/gemini.ts | 4 ++-- .../void/electron-main/llmMessage/groq.ts | 4 ++-- .../void/electron-main/llmMessage/mistral.ts | 4 ++-- .../void/electron-main/llmMessage/ollama.ts | 6 ++--- .../void/electron-main/llmMessage/openai.ts | 7 ++++-- .../llmMessage/sendLLMMessage.ts | 14 ++++++------ .../void/browser/autocompleteService.ts | 2 +- .../void/browser/inlineDiffsService.ts | 6 ++--- 10 files changed, 38 insertions(+), 35 deletions(-) diff --git a/src/vs/platform/void/common/llmMessageTypes.ts b/src/vs/platform/void/common/llmMessageTypes.ts index 94096b7c..cbc6856e 100644 --- a/src/vs/platform/void/common/llmMessageTypes.ts +++ b/src/vs/platform/void/common/llmMessageTypes.ts @@ -24,28 +24,28 @@ export type OnFinalMessage = (p: { fullText: string }) => void export type OnError = (p: { message: string, fullError: Error | null }) => void export type AbortRef = { current: (() => void) | null } -export type LLMMessage = { +export type LLMChatMessage = { role: 'system' | 'user' | 'assistant'; content: string; } -export type _InternalLLMMessage = { +export type _InternalLLMChatMessage = { role: 'user' | 'assistant'; content: string; } -type _InternalOllamaFIMMessages = { +type _InternalSendFIMMessage = { prefix: string; suffix: string; stopTokens: string[]; } type SendLLMType = { - type: 'sendLLMMessage'; - messages: LLMMessage[]; + type: 'sendChatMessage'; + messages: LLMChatMessage[]; } | { - type: 'ollamaFIM'; - messages: _InternalOllamaFIMMessages; + type: 'sendFIMMessage'; + messages: _InternalSendFIMMessage; } // service types @@ -85,7 +85,7 @@ export type EventLLMMessageOnFinalMessageParams = Parameters[0] export type EventLLMMessageOnErrorParams = Parameters[0] & { requestId: string } -export type _InternalSendLLMMessageFnType = ( +export type _InternalSendLLMChatMessageFnType = ( params: { onText: OnText; onFinalMessage: OnFinalMessage; @@ -95,11 +95,11 @@ export type _InternalSendLLMMessageFnType = ( modelName: string; _setAborter: (aborter: () => void) => void; - messages: _InternalLLMMessage[]; + messages: _InternalLLMChatMessage[]; } ) => void -export type _InternalOllamaFIMMessageFnType = ( +export type _InternalSendLLMFIMMessageFnType = ( params: { onText: OnText; onFinalMessage: OnFinalMessage; @@ -109,7 +109,7 @@ export type _InternalOllamaFIMMessageFnType = ( modelName: string; _setAborter: (aborter: () => void) => void; - messages: _InternalOllamaFIMMessages; + messages: _InternalSendFIMMessage; } ) => void diff --git a/src/vs/platform/void/electron-main/llmMessage/anthropic.ts b/src/vs/platform/void/electron-main/llmMessage/anthropic.ts index 59d4c04a..4a672ea6 100644 --- a/src/vs/platform/void/electron-main/llmMessage/anthropic.ts +++ b/src/vs/platform/void/electron-main/llmMessage/anthropic.ts @@ -4,10 +4,10 @@ *--------------------------------------------------------------------------------------*/ import Anthropic from '@anthropic-ai/sdk'; -import { _InternalSendLLMMessageFnType } from '../../common/llmMessageTypes.js'; +import { _InternalSendLLMChatMessageFnType } from '../../common/llmMessageTypes.js'; import { anthropicMaxPossibleTokens } from '../../common/voidSettingsTypes.js'; -export const sendAnthropicMsg: _InternalSendLLMMessageFnType = ({ messages, onText, onFinalMessage, onError, settingsOfProvider, modelName, _setAborter }) => { +export const sendAnthropicMsg: _InternalSendLLMChatMessageFnType = ({ messages, onText, onFinalMessage, onError, settingsOfProvider, modelName, _setAborter }) => { const thisConfig = settingsOfProvider.anthropic diff --git a/src/vs/platform/void/electron-main/llmMessage/gemini.ts b/src/vs/platform/void/electron-main/llmMessage/gemini.ts index 936a68f0..e3f0a294 100644 --- a/src/vs/platform/void/electron-main/llmMessage/gemini.ts +++ b/src/vs/platform/void/electron-main/llmMessage/gemini.ts @@ -4,10 +4,10 @@ *--------------------------------------------------------------------------------------*/ import { Content, GoogleGenerativeAI } from '@google/generative-ai'; -import { _InternalSendLLMMessageFnType } from '../../common/llmMessageTypes.js'; +import { _InternalSendLLMChatMessageFnType } from '../../common/llmMessageTypes.js'; // Gemini -export const sendGeminiMsg: _InternalSendLLMMessageFnType = async ({ messages, onText, onFinalMessage, onError, settingsOfProvider, modelName, _setAborter }) => { +export const sendGeminiMsg: _InternalSendLLMChatMessageFnType = async ({ messages, onText, onFinalMessage, onError, settingsOfProvider, modelName, _setAborter }) => { let fullText = '' diff --git a/src/vs/platform/void/electron-main/llmMessage/groq.ts b/src/vs/platform/void/electron-main/llmMessage/groq.ts index 70a4250b..01817cc5 100644 --- a/src/vs/platform/void/electron-main/llmMessage/groq.ts +++ b/src/vs/platform/void/electron-main/llmMessage/groq.ts @@ -4,10 +4,10 @@ *--------------------------------------------------------------------------------------*/ import Groq from 'groq-sdk'; -import { _InternalSendLLMMessageFnType } from '../../common/llmMessageTypes.js'; +import { _InternalSendLLMChatMessageFnType } from '../../common/llmMessageTypes.js'; // Groq -export const sendGroqMsg: _InternalSendLLMMessageFnType = async ({ messages, onText, onFinalMessage, onError, settingsOfProvider, modelName, _setAborter }) => { +export const sendGroqMsg: _InternalSendLLMChatMessageFnType = async ({ messages, onText, onFinalMessage, onError, settingsOfProvider, modelName, _setAborter }) => { let fullText = ''; const thisConfig = settingsOfProvider.groq diff --git a/src/vs/platform/void/electron-main/llmMessage/mistral.ts b/src/vs/platform/void/electron-main/llmMessage/mistral.ts index 74f9233e..d0fd11f3 100644 --- a/src/vs/platform/void/electron-main/llmMessage/mistral.ts +++ b/src/vs/platform/void/electron-main/llmMessage/mistral.ts @@ -4,10 +4,10 @@ *--------------------------------------------------------------------------------------*/ import { Mistral } from '@mistralai/mistralai'; -import { _InternalSendLLMMessageFnType } from '../../common/llmMessageTypes.js'; +import { _InternalSendLLMChatMessageFnType } from '../../common/llmMessageTypes.js'; // Mistral -export const sendMistralMsg: _InternalSendLLMMessageFnType = async ({ messages, onText, onFinalMessage, onError, settingsOfProvider, modelName, _setAborter }) => { +export const sendMistralMsg: _InternalSendLLMChatMessageFnType = async ({ messages, onText, onFinalMessage, onError, settingsOfProvider, modelName, _setAborter }) => { let fullText = ''; const thisConfig = settingsOfProvider.mistral; diff --git a/src/vs/platform/void/electron-main/llmMessage/ollama.ts b/src/vs/platform/void/electron-main/llmMessage/ollama.ts index a41eedb4..981fa7a5 100644 --- a/src/vs/platform/void/electron-main/llmMessage/ollama.ts +++ b/src/vs/platform/void/electron-main/llmMessage/ollama.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------*/ import { Ollama } from 'ollama'; -import { _InternalModelListFnType, _InternalOllamaFIMMessageFnType, _InternalSendLLMMessageFnType, OllamaModelResponse } from '../../common/llmMessageTypes.js'; +import { _InternalModelListFnType, _InternalSendLLMFIMMessageFnType, _InternalSendLLMChatMessageFnType, OllamaModelResponse } from '../../common/llmMessageTypes.js'; import { defaultProviderSettings } from '../../common/voidSettingsTypes.js'; export const ollamaList: _InternalModelListFnType = async ({ onSuccess: onSuccess_, onError: onError_, settingsOfProvider }) => { @@ -38,7 +38,7 @@ export const ollamaList: _InternalModelListFnType = async ( } -export const sendOllamaFIM: _InternalOllamaFIMMessageFnType = ({ messages, onText, onFinalMessage, onError, settingsOfProvider, modelName, _setAborter }) => { +export const sendOllamaFIM: _InternalSendLLMFIMMessageFnType = ({ messages, onText, onFinalMessage, onError, settingsOfProvider, modelName, _setAborter }) => { const thisConfig = settingsOfProvider.ollama // if endpoint is empty, normally ollama will send to 11434, but we want it to fail - the user should type it in @@ -78,7 +78,7 @@ export const sendOllamaFIM: _InternalOllamaFIMMessageFnType = ({ messages, onTex // Ollama -export const sendOllamaMsg: _InternalSendLLMMessageFnType = ({ messages, onText, onFinalMessage, onError, settingsOfProvider, modelName, _setAborter }) => { +export const sendOllamaMsg: _InternalSendLLMChatMessageFnType = ({ messages, onText, onFinalMessage, onError, settingsOfProvider, modelName, _setAborter }) => { const thisConfig = settingsOfProvider.ollama // if endpoint is empty, normally ollama will send to 11434, but we want it to fail - the user should type it in diff --git a/src/vs/platform/void/electron-main/llmMessage/openai.ts b/src/vs/platform/void/electron-main/llmMessage/openai.ts index 5695cd06..6ee5b5eb 100644 --- a/src/vs/platform/void/electron-main/llmMessage/openai.ts +++ b/src/vs/platform/void/electron-main/llmMessage/openai.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------*/ import OpenAI from 'openai'; -import { _InternalModelListFnType, _InternalSendLLMMessageFnType } from '../../common/llmMessageTypes.js'; +import { _InternalModelListFnType, _InternalSendLLMFIMMessageFnType, _InternalSendLLMChatMessageFnType } from '../../common/llmMessageTypes.js'; import { Model } from 'openai/resources/models.js'; // import { parseMaxTokensStr } from './util.js'; @@ -43,9 +43,12 @@ export const openaiCompatibleList: _InternalModelListFnType = async ({ on +// export const sendOpenAIFimMsg: _InternalSendLLMFIMMessageFnType + + // OpenAI, OpenRouter, OpenAICompatible -export const sendOpenAIMsg: _InternalSendLLMMessageFnType = ({ messages, onText, onFinalMessage, onError, settingsOfProvider, modelName, _setAborter, providerName }) => { +export const sendOpenAIMsg: _InternalSendLLMChatMessageFnType = ({ messages, onText, onFinalMessage, onError, settingsOfProvider, modelName, _setAborter, providerName }) => { let fullText = '' diff --git a/src/vs/platform/void/electron-main/llmMessage/sendLLMMessage.ts b/src/vs/platform/void/electron-main/llmMessage/sendLLMMessage.ts index 6ca51139..0cbdad44 100644 --- a/src/vs/platform/void/electron-main/llmMessage/sendLLMMessage.ts +++ b/src/vs/platform/void/electron-main/llmMessage/sendLLMMessage.ts @@ -3,7 +3,7 @@ * Licensed under the Apache License, Version 2.0. See LICENSE.txt for more information. *--------------------------------------------------------------------------------------*/ -import { SendLLMMessageParams, OnText, OnFinalMessage, OnError, LLMMessage, _InternalLLMMessage } from '../../common/llmMessageTypes.js'; +import { SendLLMMessageParams, OnText, OnFinalMessage, OnError, LLMChatMessage, _InternalLLMChatMessage } from '../../common/llmMessageTypes.js'; import { IMetricsService } from '../../common/metricsService.js'; import { sendAnthropicMsg } from './anthropic.js'; @@ -14,7 +14,7 @@ import { sendGroqMsg } from './groq.js'; import { sendMistralMsg } from './mistral.js'; -const cleanMessages = (messages: LLMMessage[]): _InternalLLMMessage[] => { +const cleanChatMessages = (messages: LLMChatMessage[]): _InternalLLMChatMessage[] => { // trim message content (Anthropic and other providers give an error if there is trailing whitespace) messages = messages.map(m => ({ ...m, content: m.content.trim() })) @@ -26,7 +26,7 @@ const cleanMessages = (messages: LLMMessage[]): _InternalLLMMessage[] => { // remove all system messages const noSystemMessages = messages - .filter(msg => msg.role !== 'system') as _InternalLLMMessage[] + .filter(msg => msg.role !== 'system') as _InternalLLMChatMessage[] // add system mesasges to first message (should be a user message) if (systemMessage && (noSystemMessages.length !== 0)) { @@ -66,20 +66,20 @@ export const sendLLMMessage = ({ ) => { // messages.unshift({ role: 'system', content: aiInstructions }) - const messagesArr = type === 'sendLLMMessage' ? cleanMessages(messages_) : [] + const messagesArr = type === 'sendChatMessage' ? cleanChatMessages(messages_) : [] // only captures number of messages and message "shape", no actual code, instructions, prompts, etc const captureLLMEvent = (eventId: string, extras?: object) => { metricsService.capture(eventId, { providerName, modelName, - ...type === 'sendLLMMessage' ? { + ...type === 'sendChatMessage' ? { numMessages: messagesArr?.length, messagesShape: messagesArr?.map(msg => ({ role: msg.role, length: msg.content.length })), origNumMessages: messages_?.length, origMessagesShape: messages_?.map(msg => ({ role: msg.role, length: msg.content.length })), - } : type === 'ollamaFIM' ? { + } : type === 'sendFIMMessage' ? { } : {}, @@ -138,7 +138,7 @@ export const sendLLMMessage = ({ break; case 'ollama': if ( // TODO @andrew in future we want to use our own templates instead of using ollamaFIM - type === 'ollamaFIM' + type === 'sendFIMMessage' && settingsOfProvider['ollama']._enabled && settingsOfProvider['ollama'].models.some(m => !m.isHidden) ) diff --git a/src/vs/workbench/contrib/void/browser/autocompleteService.ts b/src/vs/workbench/contrib/void/browser/autocompleteService.ts index 6eab4c3f..64d181f0 100644 --- a/src/vs/workbench/contrib/void/browser/autocompleteService.ts +++ b/src/vs/workbench/contrib/void/browser/autocompleteService.ts @@ -791,7 +791,7 @@ export class AutocompleteService extends Disposable implements IAutocompleteServ newAutocompletion.llmPromise = new Promise((resolve, reject) => { const requestId = this._llmMessageService.sendLLMMessage({ - type: 'ollamaFIM', + type: 'sendFIMMessage', messages: { prefix: llmPrefix, suffix: llmSuffix, diff --git a/src/vs/workbench/contrib/void/browser/inlineDiffsService.ts b/src/vs/workbench/contrib/void/browser/inlineDiffsService.ts index 618db611..09da6af3 100644 --- a/src/vs/workbench/contrib/void/browser/inlineDiffsService.ts +++ b/src/vs/workbench/contrib/void/browser/inlineDiffsService.ts @@ -30,7 +30,7 @@ import { ILLMMessageService } from '../../../../platform/void/common/llmMessageS import { mountCtrlK } from '../browser/react/out/quick-edit-tsx/index.js' import { QuickEditPropsType } from './quickEditActions.js'; -import { errorDetails, LLMMessage } from '../../../../platform/void/common/llmMessageTypes.js'; +import { errorDetails, LLMChatMessage } from '../../../../platform/void/common/llmMessageTypes.js'; import { IModelContentChangedEvent } from '../../../../editor/common/textModelEvents.js'; import { extractCodeFromFIM, extractCodeFromRegular } from './helpers/extractCodeFromResult.js'; import { IMetricsService } from '../../../../platform/void/common/metricsService.js'; @@ -1287,7 +1287,7 @@ class InlineDiffsService extends Disposable implements IInlineDiffsService { } // now handle messages - let messages: LLMMessage[] + let messages: LLMChatMessage[] if (featureName === 'Ctrl+L') { const userContent = fastApply_userMessage({ originalCode, applyStr: opts.applyStr, uri }) @@ -1367,7 +1367,7 @@ class InlineDiffsService extends Disposable implements IInlineDiffsService { let prevIgnoredSuffix = '' streamRequestIdRef.current = this._llmMessageService.sendLLMMessage({ - type: 'sendLLMMessage', + type: 'sendChatMessage', useProviderFor: opts.featureName === 'Ctrl+L' ? 'FastApply' : 'Ctrl+K', logging: { loggingName: `startApplying - ${featureName}` }, messages,