From 637a4d9d4cc62493df760818dd295a8fb1ebadfb Mon Sep 17 00:00:00 2001 From: Petr Mironychev <9195189+Palm1r@users.noreply.github.com> Date: Sat, 17 May 2025 09:21:06 +0200 Subject: [PATCH] feat: Add custom providers endpoint (#188) --- LLMClientInterface.cpp | 26 ++++++++++++--- LLMClientInterface.hpp | 1 + settings/GeneralSettings.cpp | 60 +++++++++++++++++++++++++++++++++- settings/GeneralSettings.hpp | 9 +++++ settings/SettingsConstants.hpp | 9 +++++ settings/SettingsTr.hpp | 1 + 6 files changed, 101 insertions(+), 5 deletions(-) diff --git a/LLMClientInterface.cpp b/LLMClientInterface.cpp index 0186405..a6749ac 100644 --- a/LLMClientInterface.cpp +++ b/LLMClientInterface.cpp @@ -218,10 +218,8 @@ void LLMClientInterface::handleCompletion(const QJsonObject &request) : QString{"generateContent?"}; config.url = QUrl(QString("%1/models/%2:%3").arg(url, modelName, stream)); } else { - config.url = QUrl(QString("%1%2").arg( - url, - promptTemplate->type() == LLMCore::TemplateType::FIM ? provider->completionEndpoint() - : provider->chatEndpoint())); + config.url = QUrl( + QString("%1%2").arg(url, endpoint(provider, promptTemplate->type(), isPreset1Active))); config.providerRequest = {{"model", modelName}, {"stream", m_completeSettings.stream()}}; } config.apiKey = provider->apiKey(); @@ -300,6 +298,26 @@ LLMCore::ContextData LLMClientInterface::prepareContext( return reader.prepareContext(lineNumber, cursorPosition, m_completeSettings); } +QString LLMClientInterface::endpoint( + LLMCore::Provider *provider, LLMCore::TemplateType type, bool isLanguageSpecify) +{ + QString endpoint; + auto endpointMode = isLanguageSpecify ? m_generalSettings.ccPreset1EndpointMode.stringValue() + : m_generalSettings.ccEndpointMode.stringValue(); + if (endpointMode == "Auto") { + endpoint = type == LLMCore::TemplateType::FIM ? provider->completionEndpoint() + : provider->chatEndpoint(); + } else if (endpointMode == "Custom") { + endpoint = isLanguageSpecify ? m_generalSettings.ccPreset1CustomEndpoint() + : m_generalSettings.ccCustomEndpoint(); + } else if (endpointMode == "FIM") { + endpoint = provider->completionEndpoint(); + } else if (endpointMode == "Chat") { + endpoint = provider->chatEndpoint(); + } + return endpoint; +} + Context::ContextManager *LLMClientInterface::contextManager() const { return m_contextManager; diff --git a/LLMClientInterface.hpp b/LLMClientInterface.hpp index ce4c89e..f010f65 100644 --- a/LLMClientInterface.hpp +++ b/LLMClientInterface.hpp @@ -77,6 +77,7 @@ private: LLMCore::ContextData prepareContext( const QJsonObject &request, const Context::DocumentInfo &documentInfo); + QString endpoint(LLMCore::Provider *provider, LLMCore::TemplateType type, bool isLanguageSpecify); const Settings::CodeCompletionSettings &m_completeSettings; const Settings::GeneralSettings &m_generalSettings; diff --git a/settings/GeneralSettings.cpp b/settings/GeneralSettings.cpp index 2dfca51..14303b5 100644 --- a/settings/GeneralSettings.cpp +++ b/settings/GeneralSettings.cpp @@ -99,9 +99,20 @@ GeneralSettings::GeneralSettings() ccSelectTemplate.m_buttonText = TrConstants::SELECT; initStringAspect(ccUrl, Constants::CC_URL, TrConstants::URL, "http://localhost:11434"); - ccUrl.setHistoryCompleter(Constants::CC_URL_HISTORY); + ccUrl.setHistoryCompleter(Constants::CC_CUSTOM_ENDPOINT_HISTORY); ccSetUrl.m_buttonText = TrConstants::SELECT; + ccEndpointMode.setSettingsKey(Constants::CC_ENDPOINT_MODE); + ccEndpointMode.setDisplayStyle(Utils::SelectionAspect::DisplayStyle::ComboBox); + ccEndpointMode.addOption("Auto"); + ccEndpointMode.addOption("Custom"); + ccEndpointMode.addOption("FIM"); + ccEndpointMode.addOption("Chat"); + ccEndpointMode.setDefaultValue("Auto"); + + initStringAspect(ccCustomEndpoint, Constants::CC_CUSTOM_ENDPOINT, TrConstants::ENDPOINT_MODE, ""); + ccCustomEndpoint.setHistoryCompleter(Constants::CC_CUSTOM_ENDPOINT_HISTORY); + ccStatus.setDisplayStyle(Utils::StringAspect::LabelDisplay); ccStatus.setLabelText(TrConstants::STATUS); ccStatus.setDefaultValue(""); @@ -134,6 +145,21 @@ GeneralSettings::GeneralSettings() ccPreset1Url.setHistoryCompleter(Constants::CC_PRESET1_URL_HISTORY); ccPreset1SetUrl.m_buttonText = TrConstants::SELECT; + ccPreset1EndpointMode.setSettingsKey(Constants::CC_PRESET1_ENDPOINT_MODE); + ccPreset1EndpointMode.setDisplayStyle(Utils::SelectionAspect::DisplayStyle::ComboBox); + ccPreset1EndpointMode.addOption("Auto"); + ccPreset1EndpointMode.addOption("Custom"); + ccPreset1EndpointMode.addOption("FIM"); + ccPreset1EndpointMode.addOption("Chat"); + ccPreset1EndpointMode.setDefaultValue("Auto"); + + initStringAspect( + ccPreset1CustomEndpoint, + Constants::CC_PRESET1_CUSTOM_ENDPOINT, + TrConstants::ENDPOINT_MODE, + ""); + ccPreset1CustomEndpoint.setHistoryCompleter(Constants::CC_PRESET1_CUSTOM_ENDPOINT_HISTORY); + initStringAspect( ccPreset1Model, Constants::CC_PRESET1_MODEL, TrConstants::MODEL, "qwen2.5-coder:7b"); ccPreset1Model.setHistoryCompleter(Constants::CC_PRESET1_MODEL_HISTORY); @@ -162,6 +188,17 @@ GeneralSettings::GeneralSettings() caUrl.setHistoryCompleter(Constants::CA_URL_HISTORY); caSetUrl.m_buttonText = TrConstants::SELECT; + caEndpointMode.setSettingsKey(Constants::CA_ENDPOINT_MODE); + caEndpointMode.setDisplayStyle(Utils::SelectionAspect::DisplayStyle::ComboBox); + caEndpointMode.addOption("Auto"); + caEndpointMode.addOption("Custom"); + caEndpointMode.addOption("FIM"); + caEndpointMode.addOption("Chat"); + caEndpointMode.setDefaultValue("Auto"); + + initStringAspect(caCustomEndpoint, Constants::CA_CUSTOM_ENDPOINT, TrConstants::ENDPOINT_MODE, ""); + caCustomEndpoint.setHistoryCompleter(Constants::CA_CUSTOM_ENDPOINT_HISTORY); + caStatus.setDisplayStyle(Utils::StringAspect::LabelDisplay); caStatus.setLabelText(TrConstants::STATUS); caStatus.setDefaultValue(""); @@ -179,6 +216,9 @@ GeneralSettings::GeneralSettings() setupConnections(); updatePreset1Visiblity(specifyPreset1.value()); + ccCustomEndpoint.setEnabled(ccEndpointMode.stringValue() == "Custom"); + ccPreset1CustomEndpoint.setEnabled(ccPreset1EndpointMode.stringValue() == "Custom"); + caCustomEndpoint.setEnabled(caEndpointMode.stringValue() == "Custom"); setLayouter([this]() { using namespace Layouting; @@ -186,18 +226,21 @@ GeneralSettings::GeneralSettings() auto ccGrid = Grid{}; ccGrid.addRow({ccProvider, ccSelectProvider}); ccGrid.addRow({ccUrl, ccSetUrl}); + ccGrid.addRow({ccCustomEndpoint, ccEndpointMode}); ccGrid.addRow({ccModel, ccSelectModel}); ccGrid.addRow({ccTemplate, ccSelectTemplate}); auto ccPreset1Grid = Grid{}; ccPreset1Grid.addRow({ccPreset1Provider, ccPreset1SelectProvider}); ccPreset1Grid.addRow({ccPreset1Url, ccPreset1SetUrl}); + ccPreset1Grid.addRow({ccPreset1CustomEndpoint, ccPreset1EndpointMode}); ccPreset1Grid.addRow({ccPreset1Model, ccPreset1SelectModel}); ccPreset1Grid.addRow({ccPreset1Template, ccPreset1SelectTemplate}); auto caGrid = Grid{}; caGrid.addRow({caProvider, caSelectProvider}); caGrid.addRow({caUrl, caSetUrl}); + caGrid.addRow({caCustomEndpoint, caEndpointMode}); caGrid.addRow({caModel, caSelectModel}); caGrid.addRow({caTemplate, caSelectTemplate}); @@ -389,6 +432,8 @@ void GeneralSettings::updatePreset1Visiblity(bool state) ccPreset1SelectModel.updateVisibility(specifyPreset1.volatileValue()); ccPreset1Template.setVisible(specifyPreset1.volatileValue()); ccPreset1SelectTemplate.updateVisibility(specifyPreset1.volatileValue()); + ccPreset1EndpointMode.setVisible(specifyPreset1.volatileValue()); + ccPreset1CustomEndpoint.setVisible(specifyPreset1.volatileValue()); } void GeneralSettings::setupConnections() @@ -404,6 +449,19 @@ void GeneralSettings::setupConnections() connect(&specifyPreset1, &Utils::BoolAspect::volatileValueChanged, this, [this]() { updatePreset1Visiblity(specifyPreset1.volatileValue()); }); + connect(&ccEndpointMode, &Utils::BaseAspect::volatileValueChanged, this, [this]() { + ccCustomEndpoint.setEnabled( + ccEndpointMode.volatileValue() == ccEndpointMode.indexForDisplay("Custom")); + }); + connect(&ccPreset1EndpointMode, &Utils::BaseAspect::volatileValueChanged, this, [this]() { + ccPreset1CustomEndpoint.setEnabled( + ccPreset1EndpointMode.volatileValue() + == ccPreset1EndpointMode.indexForDisplay("Custom")); + }); + connect(&caEndpointMode, &Utils::BaseAspect::volatileValueChanged, this, [this]() { + caCustomEndpoint.setEnabled( + caEndpointMode.volatileValue() == caEndpointMode.indexForDisplay("Custom")); + }); } void GeneralSettings::resetPageToDefaults() diff --git a/settings/GeneralSettings.hpp b/settings/GeneralSettings.hpp index 9d4bd16..f1d80a9 100644 --- a/settings/GeneralSettings.hpp +++ b/settings/GeneralSettings.hpp @@ -54,6 +54,9 @@ public: Utils::StringAspect ccUrl{this}; ButtonAspect ccSetUrl{this}; + Utils::SelectionAspect ccEndpointMode{this}; + Utils::StringAspect ccCustomEndpoint{this}; + Utils::StringAspect ccStatus{this}; ButtonAspect ccTest{this}; @@ -70,6 +73,9 @@ public: Utils::StringAspect ccPreset1Url{this}; ButtonAspect ccPreset1SetUrl{this}; + Utils::SelectionAspect ccPreset1EndpointMode{this}; + Utils::StringAspect ccPreset1CustomEndpoint{this}; + Utils::StringAspect ccPreset1Model{this}; ButtonAspect ccPreset1SelectModel{this}; @@ -89,6 +95,9 @@ public: Utils::StringAspect caUrl{this}; ButtonAspect caSetUrl{this}; + Utils::SelectionAspect caEndpointMode{this}; + Utils::StringAspect caCustomEndpoint{this}; + Utils::StringAspect caStatus{this}; ButtonAspect caTest{this}; diff --git a/settings/SettingsConstants.hpp b/settings/SettingsConstants.hpp index 3e3936b..19ecb3e 100644 --- a/settings/SettingsConstants.hpp +++ b/settings/SettingsConstants.hpp @@ -35,6 +35,9 @@ const char CC_MODEL_HISTORY[] = "QodeAssist.ccModelHistory"; const char CC_TEMPLATE[] = "QodeAssist.ccTemplate"; const char CC_URL[] = "QodeAssist.ccUrl"; const char CC_URL_HISTORY[] = "QodeAssist.ccUrlHistory"; +const char CC_ENDPOINT_MODE[] = "QodeAssist.ccEndpointMode"; +const char CC_CUSTOM_ENDPOINT[] = "QodeAssist.ccCustomEndpoint"; +const char CC_CUSTOM_ENDPOINT_HISTORY[] = "QodeAssist.ccCustomEndpointHistory"; const char CA_PROVIDER[] = "QodeAssist.caProvider"; const char CA_MODEL[] = "QodeAssist.caModel"; @@ -42,6 +45,9 @@ const char CA_MODEL_HISTORY[] = "QodeAssist.caModelHistory"; const char CA_TEMPLATE[] = "QodeAssist.caTemplate"; const char CA_URL[] = "QodeAssist.caUrl"; const char CA_URL_HISTORY[] = "QodeAssist.caUrlHistory"; +const char CA_ENDPOINT_MODE[] = "QodeAssist.caEndpointMode"; +const char CA_CUSTOM_ENDPOINT[] = "QodeAssist.caCustomEndpoint"; +const char CA_CUSTOM_ENDPOINT_HISTORY[] = "QodeAssist.caCustomEndpointHistory"; const char CC_SPECIFY_PRESET1[] = "QodeAssist.ccSpecifyPreset1"; const char CC_PRESET1_LANGUAGE[] = "QodeAssist.ccPreset1Language"; @@ -51,6 +57,9 @@ const char CC_PRESET1_MODEL_HISTORY[] = "QodeAssist.ccPreset1ModelHistory"; const char CC_PRESET1_TEMPLATE[] = "QodeAssist.ccPreset1Template"; const char CC_PRESET1_URL[] = "QodeAssist.ccPreset1Url"; const char CC_PRESET1_URL_HISTORY[] = "QodeAssist.ccPreset1UrlHistory"; +const char CC_PRESET1_ENDPOINT_MODE[] = "QodeAssist.caPreset1EndpointMode"; +const char CC_PRESET1_CUSTOM_ENDPOINT[] = "QodeAssist.caPreset1CustomEndpointHistory"; +const char CC_PRESET1_CUSTOM_ENDPOINT_HISTORY[] = "QodeAssist.caPreset1CustomEndpointHistory"; // settings const char ENABLE_QODE_ASSIST[] = "QodeAssist.enableQodeAssist"; diff --git a/settings/SettingsTr.hpp b/settings/SettingsTr.hpp index 729d291..affc9e3 100644 --- a/settings/SettingsTr.hpp +++ b/settings/SettingsTr.hpp @@ -44,6 +44,7 @@ inline const char *ENABLE_CHECK_UPDATE_ON_START inline const char *ENABLE_CHAT = QT_TRANSLATE_NOOP( "QtC::QodeAssist", "Enable Chat(If you have performance issues try disabling this, need restart QtC)"); +inline const char *ENDPOINT_MODE = QT_TRANSLATE_NOOP("QtC::QodeAssist", "Endpoint Mode:"); inline const char *CODE_COMPLETION = QT_TRANSLATE_NOOP("QtC::QodeAssist", "Code Completion"); inline const char *CHAT_ASSISTANT = QT_TRANSLATE_NOOP("QtC::QodeAssist", "Chat Assistant");