From 76ed952aa28543aafed340a22f080132f36afc38 Mon Sep 17 00:00:00 2001 From: haddadrm <121486289+haddadrm@users.noreply.github.com> Date: Sun, 16 Feb 2025 15:21:28 +0400 Subject: [PATCH] fix: update LMStudio endpoint from /health to /v1/models - Replace health check endpoint with proper model listing endpoint - Remove workaround that returned 200 for unexpected GET /v1/health --- sample.config.toml | 2 +- src/lib/providers/lmstudio.ts | 46 +++++++++++++++++++++++++++++++---- 2 files changed, 42 insertions(+), 6 deletions(-) diff --git a/sample.config.toml b/sample.config.toml index 01419d3..671e85b 100644 --- a/sample.config.toml +++ b/sample.config.toml @@ -19,7 +19,7 @@ API_KEY = "" API_URL = "" # Ollama API URL - http://host.docker.internal:11434 [MODELS.LMSTUDIO] -API_URL = "" # LM STUDIO API URL - http://host.docker.internal:1234/v1 +API_URL = "" # LM STUDIO API URL - http://host.docker.internal:1234 [MODELS.CUSTOM_OPENAI] API_KEY = "" diff --git a/src/lib/providers/lmstudio.ts b/src/lib/providers/lmstudio.ts index 623a658..82389a8 100644 --- a/src/lib/providers/lmstudio.ts +++ b/src/lib/providers/lmstudio.ts @@ -4,6 +4,10 @@ import { getKeepAlive, getLMStudioApiEndpoint } from '../../config'; import logger from '../../utils/logger'; import axios from 'axios'; +const ensureV1Endpoint = (endpoint: string): string => { + return endpoint.endsWith('/v1') ? endpoint : `${endpoint}/v1`; +}; + interface LMStudioModel { id: string; // add other properties if LM Studio API provides them @@ -14,6 +18,22 @@ interface ChatModelConfig { model: ChatOpenAI; } +const checkLMStudioAvailability = async (endpoint: string): Promise => { + const v1Endpoint = ensureV1Endpoint(endpoint); + try { + await axios.get(`${v1Endpoint}/models`, { + timeout: 1000, // 1 second timeout + headers: { + 'Content-Type': 'application/json', + }, + }); + return true; + } catch (err) { + logger.debug(`LM Studio server not available at ${endpoint}`); + return false; + } +}; + export const loadLMStudioChatModels = async (): Promise> => { const lmStudioEndpoint = getLMStudioApiEndpoint(); @@ -22,8 +42,16 @@ export const loadLMStudioChatModels = async (): Promise(`${lmStudioEndpoint}/models`, { + const v1Endpoint = ensureV1Endpoint(lmStudioEndpoint); + const response = await axios.get<{ data: LMStudioModel[] }>(`${v1Endpoint}/models`, { + timeout: 5000, // 5 second timeout for model loading headers: { 'Content-Type': 'application/json', }, @@ -37,7 +65,7 @@ export const loadLMStudioChatModels = async (): Promise { if (!lmStudioEndpoint) return {}; + // Check if server is available before attempting to load models + const isAvailable = await checkLMStudioAvailability(lmStudioEndpoint); + if (!isAvailable) { + return {}; + } + try { - const response = await axios.get(`${lmStudioEndpoint}/models`, { + const v1Endpoint = ensureV1Endpoint(lmStudioEndpoint); + const response = await axios.get(`${v1Endpoint}/models`, { + timeout: 5000, // 5 second timeout for model loading headers: { 'Content-Type': 'application/json', }, @@ -73,7 +109,7 @@ export const loadLMStudioEmbeddingsModels = async () => { model: new OpenAIEmbeddings({ openAIApiKey: 'lm-studio', // Dummy key required by LangChain configuration: { - baseURL: lmStudioEndpoint, + baseURL: ensureV1Endpoint(lmStudioEndpoint), }, modelName: model.id, }), @@ -86,4 +122,4 @@ export const loadLMStudioEmbeddingsModels = async () => { logger.error(`Error loading LM Studio embeddings model: ${err}`); return {}; } -}; \ No newline at end of file +};