fim better abstraction

This commit is contained in:
Andrew Pareles 2025-02-05 00:36:44 -08:00
parent 31ed11393f
commit da4c9c8c40
10 changed files with 38 additions and 35 deletions

View file

@ -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<OnFinalMessage>[0]
export type EventLLMMessageOnErrorParams = Parameters<OnError>[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

View file

@ -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

View file

@ -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 = ''

View file

@ -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

View file

@ -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;

View file

@ -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<OllamaModelResponse> = async ({ onSuccess: onSuccess_, onError: onError_, settingsOfProvider }) => {
@ -38,7 +38,7 @@ export const ollamaList: _InternalModelListFnType<OllamaModelResponse> = 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

View file

@ -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<Model> = 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 = ''

View file

@ -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)
)

View file

@ -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,

View file

@ -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,