LM studio refreshing

This commit is contained in:
Andrew Pareles 2025-04-18 03:48:42 -07:00
parent 6d28b0627f
commit f77907fe0d
7 changed files with 51 additions and 49 deletions

View file

@ -8,7 +8,7 @@ import { ILLMMessageService } from './sendLLMMessageService.js';
import { Emitter, Event } from '../../../../base/common/event.js';
import { Disposable, IDisposable } from '../../../../base/common/lifecycle.js';
import { RefreshableProviderName, refreshableProviderNames, SettingsOfProvider } from './voidSettingsTypes.js';
import { LMStudioModelResponse, OllamaModelResponse, VLLMModelResponse } from './sendLLMMessageTypes.js';
import { OllamaModelResponse, OpenaiCompatibleModelResponse } from './sendLLMMessageTypes.js';
import { registerSingleton, InstantiationType } from '../../../../platform/instantiation/common/extensions.js';
import { createDecorator } from '../../../../platform/instantiation/common/instantiation.js';
@ -162,19 +162,18 @@ export class RefreshModelService extends Disposable implements IRefreshModelServ
}
}
const listFn = providerName === 'ollama' ? this.llmMessageService.ollamaList
: providerName === 'vLLM' ? this.llmMessageService.vLLMList
: () => { }
: this.llmMessageService.openAICompatibleList
listFn({
providerName,
onSuccess: ({ models }) => {
// set the models to the detected models
this.voidSettingsService.setAutodetectedModels(
providerName,
models.map(model => {
if (providerName === 'ollama') return (model as OllamaModelResponse).name;
else if (providerName === 'vLLM') return (model as VLLMModelResponse).id;
else if (providerName === 'lmStudio') return (model as LMStudioModelResponse).id;
else if (providerName === 'vLLM') return (model as OpenaiCompatibleModelResponse).id;
else if (providerName === 'lmStudio') return (model as OpenaiCompatibleModelResponse).id;
else throw new Error('refreshMode fn: unknown provider', providerName);
}),
{ enableProviderOnSuccess: options.enableProviderOnSuccess, hideRefresh: options.doNotFire }

View file

@ -3,7 +3,7 @@
* Licensed under the Apache License, Version 2.0. See LICENSE.txt for more information.
*--------------------------------------------------------------------------------------*/
import { EventLLMMessageOnTextParams, EventLLMMessageOnErrorParams, EventLLMMessageOnFinalMessageParams, ServiceSendLLMMessageParams, MainSendLLMMessageParams, MainLLMMessageAbortParams, ServiceModelListParams, EventModelListOnSuccessParams, EventModelListOnErrorParams, MainModelListParams, OllamaModelResponse, VLLMModelResponse, } from './sendLLMMessageTypes.js';
import { EventLLMMessageOnTextParams, EventLLMMessageOnErrorParams, EventLLMMessageOnFinalMessageParams, ServiceSendLLMMessageParams, MainSendLLMMessageParams, MainLLMMessageAbortParams, ServiceModelListParams, EventModelListOnSuccessParams, EventModelListOnErrorParams, MainModelListParams, OllamaModelResponse, OpenaiCompatibleModelResponse, } from './sendLLMMessageTypes.js';
import { createDecorator } from '../../../../platform/instantiation/common/instantiation.js';
import { registerSingleton, InstantiationType } from '../../../../platform/instantiation/common/extensions.js';
@ -22,7 +22,7 @@ export interface ILLMMessageService {
sendLLMMessage: (params: ServiceSendLLMMessageParams) => string | null;
abort: (requestId: string) => void;
ollamaList: (params: ServiceModelListParams<OllamaModelResponse>) => void;
vLLMList: (params: ServiceModelListParams<VLLMModelResponse>) => void;
openAICompatibleList: (params: ServiceModelListParams<OpenaiCompatibleModelResponse>) => void;
}
@ -46,12 +46,12 @@ export class LLMMessageService extends Disposable implements ILLMMessageService
success: {} as { [eventId: string]: ((params: EventModelListOnSuccessParams<OllamaModelResponse>) => void) },
error: {} as { [eventId: string]: ((params: EventModelListOnErrorParams<OllamaModelResponse>) => void) },
},
vLLM: {
success: {} as { [eventId: string]: ((params: EventModelListOnSuccessParams<VLLMModelResponse>) => void) },
error: {} as { [eventId: string]: ((params: EventModelListOnErrorParams<VLLMModelResponse>) => void) },
openAICompat: {
success: {} as { [eventId: string]: ((params: EventModelListOnSuccessParams<OpenaiCompatibleModelResponse>) => void) },
error: {} as { [eventId: string]: ((params: EventModelListOnErrorParams<OpenaiCompatibleModelResponse>) => void) },
}
} satisfies {
[providerName: string]: {
[providerName in 'ollama' | 'openAICompat']: {
success: { [eventId: string]: ((params: EventModelListOnSuccessParams<any>) => void) },
error: { [eventId: string]: ((params: EventModelListOnErrorParams<any>) => void) },
}
@ -76,8 +76,8 @@ export class LLMMessageService extends Disposable implements ILLMMessageService
// ollama .list()
this._register((this.channel.listen('onSuccess_list_ollama') satisfies Event<EventModelListOnSuccessParams<OllamaModelResponse>>)(e => { this.listHooks.ollama.success[e.requestId]?.(e) }))
this._register((this.channel.listen('onError_list_ollama') satisfies Event<EventModelListOnErrorParams<OllamaModelResponse>>)(e => { this.listHooks.ollama.error[e.requestId]?.(e) }))
this._register((this.channel.listen('onSuccess_list_vLLM') satisfies Event<EventModelListOnSuccessParams<VLLMModelResponse>>)(e => { this.listHooks.vLLM.success[e.requestId]?.(e) }))
this._register((this.channel.listen('onError_list_vLLM') satisfies Event<EventModelListOnErrorParams<VLLMModelResponse>>)(e => { this.listHooks.vLLM.error[e.requestId]?.(e) }))
this._register((this.channel.listen('onSuccess_list_openAICompatible') satisfies Event<EventModelListOnSuccessParams<OpenaiCompatibleModelResponse>>)(e => { this.listHooks.openAICompat.success[e.requestId]?.(e) }))
this._register((this.channel.listen('onError_list_openAICompatible') satisfies Event<EventModelListOnErrorParams<OpenaiCompatibleModelResponse>>)(e => { this.listHooks.openAICompat.error[e.requestId]?.(e) }))
}
@ -143,22 +143,21 @@ export class LLMMessageService extends Disposable implements ILLMMessageService
}
vLLMList = (params: ServiceModelListParams<VLLMModelResponse>) => {
openAICompatibleList = (params: ServiceModelListParams<OpenaiCompatibleModelResponse>) => {
const { onSuccess, onError, ...proxyParams } = params
const { settingsOfProvider } = this.voidSettingsService.state
// add state for request id
const requestId_ = generateUuid();
this.listHooks.vLLM.success[requestId_] = onSuccess
this.listHooks.vLLM.error[requestId_] = onError
this.listHooks.openAICompat.success[requestId_] = onSuccess
this.listHooks.openAICompat.error[requestId_] = onError
this.channel.call('vLLMList', {
this.channel.call('openAICompatibleList', {
...proxyParams,
settingsOfProvider,
providerName: 'vLLM',
requestId: requestId_,
} satisfies MainModelListParams<VLLMModelResponse>)
} satisfies MainModelListParams<OpenaiCompatibleModelResponse>)
}
_clearChannelHooks(requestId: string) {
@ -169,8 +168,8 @@ export class LLMMessageService extends Disposable implements ILLMMessageService
delete this.listHooks.ollama.success[requestId]
delete this.listHooks.ollama.error[requestId]
delete this.listHooks.vLLM.success[requestId]
delete this.listHooks.vLLM.error[requestId]
delete this.listHooks.openAICompat.success[requestId]
delete this.listHooks.openAICompat.error[requestId]
}
}

View file

@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------*/
import { ToolName, ToolParamName } from './prompt/prompts.js'
import { ChatMode, ModelSelection, ModelSelectionOptions, ProviderName, SettingsOfProvider } from './voidSettingsTypes.js'
import { ChatMode, ModelSelection, ModelSelectionOptions, ProviderName, RefreshableProviderName, SettingsOfProvider } from './voidSettingsTypes.js'
export const errorDetails = (fullError: Error | null): string | null => {
@ -162,16 +162,13 @@ export type OllamaModelResponse = {
size_vram: number;
}
type OpenaiCompatibleModelResponse = {
export type OpenaiCompatibleModelResponse = {
id: string;
created: number;
object: 'model';
owned_by: string;
}
export type VLLMModelResponse = OpenaiCompatibleModelResponse
export type LMStudioModelResponse = OpenaiCompatibleModelResponse
// params to the true list fn
@ -184,12 +181,13 @@ export type ModelListParams<ModelResponse> = {
// params to the service
export type ServiceModelListParams<modelResponse> = {
providerName: RefreshableProviderName;
onSuccess: (param: { models: modelResponse[] }) => void;
onError: (param: { error: any }) => void;
}
type BlockedMainModelListParams = 'onSuccess' | 'onError'
export type MainModelListParams<modelResponse> = Omit<ModelListParams<modelResponse>, BlockedMainModelListParams> & { requestId: string }
export type MainModelListParams<modelResponse> = Omit<ModelListParams<modelResponse>, BlockedMainModelListParams> & { providerName: RefreshableProviderName, requestId: string }
export type EventModelListOnSuccessParams<modelResponse> = Parameters<ModelListParams<modelResponse>['onSuccess']>[0] & { requestId: string }
export type EventModelListOnErrorParams<modelResponse> = Parameters<ModelListParams<modelResponse>['onError']>[0] & { requestId: string }

View file

@ -42,10 +42,15 @@ class VoidModelService extends Disposable implements IVoidModelService {
}
initializeModel = async (uri: URI) => {
if (uri.fsPath in this._modelRefOfURI) return;
const editorModelRef = await this._textModelService.createModelReference(uri);
// Keep a strong reference to prevent disposal
this._modelRefOfURI[uri.fsPath] = editorModelRef;
try {
if (uri.fsPath in this._modelRefOfURI) return;
const editorModelRef = await this._textModelService.createModelReference(uri);
// Keep a strong reference to prevent disposal
this._modelRefOfURI[uri.fsPath] = editorModelRef;
}
catch (e) {
console.log('InitializeModel error:', e)
}
};
getModelFromFsPath = (fsPath: string): VoidModelType => {

View file

@ -150,7 +150,8 @@ export const displayInfoOfSettingName = (providerName: ProviderName, settingName
providerName === 'xAI' ? 'xai-key...' :
providerName === 'mistral' ? 'api-key...' :
providerName === 'googleVertex' ? 'AIzaSy...' :
'',
providerName === 'microsoftAzure' ? 'key-...' :
'',
isPasswordField: true,
}

View file

@ -684,7 +684,7 @@ export const sendLLMMessageToProviderImplementation = {
lmStudio: {
sendChat: (params) => _sendOpenAICompatibleChat(params),
sendFIM: null, // lmStudio has no suffix parameter in /completions
list: null,
list: (params) => _openaiCompatibleList(params),
},
liteLLM: {
sendChat: (params) => _sendOpenAICompatibleChat(params),

View file

@ -8,7 +8,7 @@
import { IServerChannel } from '../../../../base/parts/ipc/common/ipc.js';
import { Emitter, Event } from '../../../../base/common/event.js';
import { EventLLMMessageOnTextParams, EventLLMMessageOnErrorParams, EventLLMMessageOnFinalMessageParams, MainSendLLMMessageParams, AbortRef, SendLLMMessageParams, MainLLMMessageAbortParams, ModelListParams, EventModelListOnSuccessParams, EventModelListOnErrorParams, OllamaModelResponse, VLLMModelResponse, MainModelListParams, } from '../common/sendLLMMessageTypes.js';
import { EventLLMMessageOnTextParams, EventLLMMessageOnErrorParams, EventLLMMessageOnFinalMessageParams, MainSendLLMMessageParams, AbortRef, SendLLMMessageParams, MainLLMMessageAbortParams, ModelListParams, EventModelListOnSuccessParams, EventModelListOnErrorParams, OllamaModelResponse, OpenaiCompatibleModelResponse, MainModelListParams, } from '../common/sendLLMMessageTypes.js';
import { sendLLMMessage } from './llmMessage/sendLLMMessage.js'
import { IMetricsService } from '../common/metricsService.js';
import { sendLLMMessageToProviderImplementation } from './llmMessage/sendLLMMessage.impl.js';
@ -34,12 +34,12 @@ export class LLMMessageChannel implements IServerChannel {
success: new Emitter<EventModelListOnSuccessParams<OllamaModelResponse>>(),
error: new Emitter<EventModelListOnErrorParams<OllamaModelResponse>>(),
},
vLLM: {
success: new Emitter<EventModelListOnSuccessParams<VLLMModelResponse>>(),
error: new Emitter<EventModelListOnErrorParams<VLLMModelResponse>>(),
}
openaiCompat: {
success: new Emitter<EventModelListOnSuccessParams<OpenaiCompatibleModelResponse>>(),
error: new Emitter<EventModelListOnErrorParams<OpenaiCompatibleModelResponse>>(),
},
} satisfies {
[providerName: string]: {
[providerName in 'ollama' | 'openaiCompat']: {
success: Emitter<EventModelListOnSuccessParams<any>>,
error: Emitter<EventModelListOnErrorParams<any>>,
}
@ -59,8 +59,8 @@ export class LLMMessageChannel implements IServerChannel {
// list
else if (event === 'onSuccess_list_ollama') return this.listEmitters.ollama.success.event;
else if (event === 'onError_list_ollama') return this.listEmitters.ollama.error.event;
else if (event === 'onSuccess_list_vLLM') return this.listEmitters.vLLM.success.event;
else if (event === 'onError_list_vLLM') return this.listEmitters.vLLM.error.event;
else if (event === 'onSuccess_list_openAICompatible') return this.listEmitters.openaiCompat.success.event;
else if (event === 'onError_list_openAICompatible') return this.listEmitters.openaiCompat.error.event;
else throw new Error(`Event not found: ${event}`);
}
@ -77,8 +77,8 @@ export class LLMMessageChannel implements IServerChannel {
else if (command === 'ollamaList') {
this._callOllamaList(params)
}
else if (command === 'vLLMList') {
this._callVLLMList(params)
else if (command === 'openAICompatibleList') {
this._callOpenAICompatibleList(params)
}
else {
throw new Error(`Void sendLLM: command "${command}" not recognized.`)
@ -131,15 +131,15 @@ export class LLMMessageChannel implements IServerChannel {
sendLLMMessageToProviderImplementation.ollama.list(mainThreadParams)
}
_callVLLMList = (params: MainModelListParams<VLLMModelResponse>) => {
const { requestId } = params
const emitters = this.listEmitters.vLLM
const mainThreadParams: ModelListParams<VLLMModelResponse> = {
_callOpenAICompatibleList = (params: MainModelListParams<OpenaiCompatibleModelResponse>) => {
const { requestId, providerName } = params
const emitters = this.listEmitters.openaiCompat
const mainThreadParams: ModelListParams<OpenaiCompatibleModelResponse> = {
...params,
onSuccess: (p) => { emitters.success.fire({ requestId, ...p }); },
onError: (p) => { emitters.error.fire({ requestId, ...p }); },
}
sendLLMMessageToProviderImplementation.vLLM.list(mainThreadParams)
sendLLMMessageToProviderImplementation[providerName].list(mainThreadParams)
}