From a06320d1c4dbb15e55fb8c2792cdd68c19aa0132 Mon Sep 17 00:00:00 2001 From: Petr Mironychev <9195189+Palm1r@users.noreply.github.com> Date: Fri, 15 May 2026 21:55:07 +0200 Subject: [PATCH] fix: LM Studio url and endpoints --- CMakeLists.txt | 6 +----- providers/LMStudioProvider.cpp | 12 ++++++++++-- providers/LMStudioProvider.hpp | 3 +++ providers/LMStudioResponsesProvider.cpp | 11 ++++------- providers/ProviderUrlUtils.hpp | 23 +++++++++++++++++++++++ 5 files changed, 41 insertions(+), 14 deletions(-) create mode 100644 providers/ProviderUrlUtils.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 43fc317..cacd66b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,10 +1,5 @@ cmake_minimum_required(VERSION 3.16) -# list(APPEND CMAKE_PREFIX_PATH "/Users/palm1r/Qt/Qt Creator 20.0.0-beta1.app/Contents/Resources") -list(APPEND CMAKE_PREFIX_PATH "/Users/palm1r/Qt/Qt Creator 20.0.0-beta1.sdk/lib/cmake/QtCreator") -# list(APPEND CMAKE_PREFIX_PATH "/Users/palm1r/Qt/Qt Creator 20.0.0-beta1.sdk") -# list(APPEND CMAKE_PREFIX_PATH "/Users/palm1r/Qt/Qt Creator 20.0.0-beta1.app/Contents/Resources") - project(QodeAssist) set(CMAKE_AUTOMOC ON) @@ -98,6 +93,7 @@ add_qtc_plugin(QodeAssist templates/Qwen3CoderFIM.hpp templates/OpenAIResponses.hpp providers/Providers.hpp + providers/ProviderUrlUtils.hpp providers/OllamaProvider.hpp providers/OllamaProvider.cpp providers/OllamaCompatProvider.hpp providers/OllamaCompatProvider.cpp providers/ClaudeProvider.hpp providers/ClaudeProvider.cpp diff --git a/providers/LMStudioProvider.cpp b/providers/LMStudioProvider.cpp index c70a3f7..77e36d7 100644 --- a/providers/LMStudioProvider.cpp +++ b/providers/LMStudioProvider.cpp @@ -5,6 +5,7 @@ #include +#include "providers/ProviderUrlUtils.hpp" #include "tools/ToolsRegistration.hpp" #include "logger/Logger.hpp" #include "settings/ChatAssistantSettings.hpp" @@ -38,12 +39,12 @@ QString LMStudioProvider::apiKey() const QString LMStudioProvider::url() const { - return "http://localhost:1234/v1"; + return "http://localhost:1234"; } QFuture> LMStudioProvider::getInstalledModels(const QString &url) { - m_client->setUrl(url); + m_client->setUrl(ensureOpenAIV1Base(url)); m_client->setApiKey(apiKey()); return m_client->listModels(); } @@ -104,6 +105,13 @@ void LMStudioProvider::prepareRequest( } } +PluginLLMCore::RequestID LMStudioProvider::sendRequest( + const QUrl &url, const QJsonObject &payload, const QString &endpoint) +{ + return PluginLLMCore::Provider::sendRequest( + QUrl(ensureOpenAIV1Base(url.toString())), payload, endpoint); +} + ::LLMQore::BaseClient *LMStudioProvider::client() const { return m_client; diff --git a/providers/LMStudioProvider.hpp b/providers/LMStudioProvider.hpp index 5ec9c02..5015a86 100644 --- a/providers/LMStudioProvider.hpp +++ b/providers/LMStudioProvider.hpp @@ -30,6 +30,9 @@ public: ::LLMQore::BaseClient *client() const override; QString apiKey() const override; + PluginLLMCore::RequestID sendRequest( + const QUrl &url, const QJsonObject &payload, const QString &endpoint) override; + private: ::LLMQore::OpenAIClient *m_client; }; diff --git a/providers/LMStudioResponsesProvider.cpp b/providers/LMStudioResponsesProvider.cpp index 16ea792..5560689 100644 --- a/providers/LMStudioResponsesProvider.cpp +++ b/providers/LMStudioResponsesProvider.cpp @@ -6,6 +6,7 @@ #include #include "logger/Logger.hpp" +#include "providers/ProviderUrlUtils.hpp" #include "settings/ChatAssistantSettings.hpp" #include "settings/CodeCompletionSettings.hpp" #include "settings/GeneralSettings.hpp" @@ -112,10 +113,7 @@ void LMStudioResponsesProvider::prepareRequest( QFuture> LMStudioResponsesProvider::getInstalledModels(const QString &baseUrl) { - QString url = baseUrl; - if (!url.endsWith(QStringLiteral("/v1"))) - url += QStringLiteral("/v1"); - m_client->setUrl(url); + m_client->setUrl(ensureOpenAIV1Base(baseUrl)); m_client->setApiKey(apiKey()); return m_client->listModels(); } @@ -123,9 +121,8 @@ QFuture> LMStudioResponsesProvider::getInstalledModels(const QStr PluginLLMCore::RequestID LMStudioResponsesProvider::sendRequest( const QUrl &url, const QJsonObject &payload, const QString &endpoint) { - const QString effectiveEndpoint - = endpoint.isEmpty() ? QStringLiteral("/v1/responses") : endpoint; - return PluginLLMCore::Provider::sendRequest(url, payload, effectiveEndpoint); + return PluginLLMCore::Provider::sendRequest( + QUrl(ensureOpenAIV1Base(url.toString())), payload, endpoint); } PluginLLMCore::ProviderID LMStudioResponsesProvider::providerID() const diff --git a/providers/ProviderUrlUtils.hpp b/providers/ProviderUrlUtils.hpp new file mode 100644 index 0000000..c16a5a3 --- /dev/null +++ b/providers/ProviderUrlUtils.hpp @@ -0,0 +1,23 @@ +// Copyright (C) 2024-2026 Petr Mironychev +// SPDX-License-Identifier: GPL-3.0-or-later + +#pragma once + +#include + +namespace QodeAssist::Providers { + +// LM Studio presents its OpenAI-compatible API as /v1/..., while the +// OpenAI-style clients expect the base URL to already include /v1. Accept the +// configured URL either with or without the /v1 suffix and return it normalized. +inline QString ensureOpenAIV1Base(const QString &url) +{ + QString base = url.trimmed(); + while (base.endsWith(QLatin1Char('/'))) + base.chop(1); + if (!base.endsWith(QStringLiteral("/v1"))) + base += QStringLiteral("/v1"); + return base; +} + +} // namespace QodeAssist::Providers