diff --git a/CMakeLists.txt b/CMakeLists.txt index a989304..3eebde3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,7 +10,7 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) find_package(QtCreator REQUIRED COMPONENTS Core) -find_package(Qt6 COMPONENTS Core Gui Widgets Network REQUIRED) +find_package(Qt6 COMPONENTS Core Gui Quick Widgets Network REQUIRED) add_subdirectory(llmcore) add_subdirectory(settings) @@ -22,11 +22,16 @@ add_qtc_plugin(QodeAssist QtCreator::Core QtCreator::LanguageClient QtCreator::TextEditor + QtCreator::ProjectExplorer DEPENDS + Qt::Core + Qt::Gui + Qt::Quick Qt::Widgets + Qt::Network QtCreator::ExtensionSystem QtCreator::Utils - QtCreator::ProjectExplorer + QodeAssistChatViewplugin SOURCES .github/workflows/build_cmake.yml .github/workflows/README.md @@ -55,6 +60,7 @@ add_qtc_plugin(QodeAssist core/ChangesManager.h core/ChangesManager.cpp chat/ChatOutputPane.h chat/ChatOutputPane.cpp chat/NavigationPanel.hpp chat/NavigationPanel.cpp + ConfigurationManager.hpp ConfigurationManager.cpp ) -target_link_libraries(QodeAssist PRIVATE QodeAssistChatViewplugin) +target_link_libraries(QodeAssist PRIVATE ) diff --git a/ConfigurationManager.cpp b/ConfigurationManager.cpp new file mode 100644 index 0000000..e3cdb6e --- /dev/null +++ b/ConfigurationManager.cpp @@ -0,0 +1,167 @@ +/* + * Copyright (C) 2024 Petr Mironychev + * + * This file is part of QodeAssist. + * + * QodeAssist is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * QodeAssist is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with QodeAssist. If not, see . + */ + +#include "ConfigurationManager.hpp" + +#include +#include + +#include "QodeAssisttr.h" + +namespace QodeAssist { + +ConfigurationManager &ConfigurationManager::instance() +{ + static ConfigurationManager instance; + return instance; +} + +void ConfigurationManager::init() +{ + setupConnections(); +} + +LLMCore::Provider *ConfigurationManager::getCurrentProvider() +{ + auto providerName = Settings::generalSettings().ccProvider(); + return LLMCore::ProvidersManager::instance().getProviderByName(providerName); +} + +LLMCore::PromptTemplate *ConfigurationManager::getCurrentTemplate() +{ + auto templateName = Settings::generalSettings().ccTemplate(); + return LLMCore::PromptTemplateManager::instance().getFimTemplateByName(templateName); +} + +ConfigurationManager::ConfigurationManager(QObject *parent) + : QObject(parent) + , m_generalSettings(Settings::generalSettings()) + , m_providersManager(LLMCore::ProvidersManager::instance()) + , m_templateManger(LLMCore::PromptTemplateManager::instance()) +{} + +void ConfigurationManager::setupConnections() +{ + using Config = ConfigurationManager; + using Button = ButtonAspect; + + connect(&m_generalSettings.ccSelectProvider, &Button::clicked, this, &Config::selectProvider); + connect(&m_generalSettings.caSelectProvider, &Button::clicked, this, &Config::selectProvider); + connect(&m_generalSettings.ccSelectModel, &Button::clicked, this, &Config::selectModel); + connect(&m_generalSettings.caSelectModel, &Button::clicked, this, &Config::selectModel); + connect(&m_generalSettings.ccSelectTemplate, &Button::clicked, this, &Config::selectTemplate); + connect(&m_generalSettings.caSelectTemplate, &Button::clicked, this, &Config::selectTemplate); + connect(&m_generalSettings.ccSetUrl, &Button::clicked, this, &Config::selectUrl); + connect(&m_generalSettings.caSetUrl, &Button::clicked, this, &Config::selectUrl); +} + +void ConfigurationManager::selectProvider() +{ + const auto providersList = m_providersManager.providersNames(); + + auto *settingsButton = qobject_cast(sender()); + if (!settingsButton) + return; + + auto &targetSettings = (settingsButton == &m_generalSettings.ccSelectProvider) + ? m_generalSettings.ccProvider + : m_generalSettings.caProvider; + + QTimer::singleShot(0, this, [this, providersList, &targetSettings] { + m_generalSettings.showSelectionDialog(providersList, + targetSettings, + Tr::tr("Select LLM Provider"), + Tr::tr("Providers:")); + }); +} + +void ConfigurationManager::selectModel() +{ + const QString providerName = m_generalSettings.ccProvider(); + + auto *settingsButton = qobject_cast(sender()); + if (!settingsButton) + return; + + const auto providerUrl = (settingsButton == &m_generalSettings.ccSelectModel) + ? m_generalSettings.ccUrl() + : m_generalSettings.caUrl(); + const auto modelList = m_providersManager.getProviderByName(providerName) + ->getInstalledModels(providerUrl); + + auto &targetSettings = (settingsButton == &m_generalSettings.ccSelectModel) + ? m_generalSettings.ccModel + : m_generalSettings.caModel; + + QTimer::singleShot(0, &m_generalSettings, [this, modelList, &targetSettings]() { + m_generalSettings.showSelectionDialog(modelList, + targetSettings, + Tr::tr("Select LLM Model"), + Tr::tr("Models:")); + }); +} + +void ConfigurationManager::selectTemplate() +{ + auto *settingsButton = qobject_cast(sender()); + if (!settingsButton) + return; + + const auto templateList = (settingsButton == &m_generalSettings.ccSelectTemplate) + ? m_templateManger.fimTemplatesNames() + : m_templateManger.chatTemplatesNames(); + + auto &targetSettings = (settingsButton == &m_generalSettings.ccSelectTemplate) + ? m_generalSettings.ccTemplate + : m_generalSettings.caTemplate; + + QTimer::singleShot(0, &m_generalSettings, [this, templateList, &targetSettings]() { + m_generalSettings.showSelectionDialog(templateList, + targetSettings, + Tr::tr("Select Template"), + Tr::tr("Templates:")); + }); +} + +void ConfigurationManager::selectUrl() +{ + QStringList urls; + for (const auto &name : m_providersManager.providersNames()) { + const auto url = m_providersManager.getProviderByName(name)->url(); + if (!urls.contains(url)) + urls.append(url); + } + + auto *settingsButton = qobject_cast(sender()); + if (!settingsButton) + return; + + auto &targetSettings = (settingsButton == &m_generalSettings.ccSetUrl) + ? m_generalSettings.ccUrl + : m_generalSettings.caUrl; + + QTimer::singleShot(0, &m_generalSettings, [this, urls, &targetSettings]() { + m_generalSettings.showSelectionDialog(urls, + targetSettings, + Tr::tr("Select URL"), + Tr::tr("URLs:")); + }); +} + +} // namespace QodeAssist diff --git a/ConfigurationManager.hpp b/ConfigurationManager.hpp new file mode 100644 index 0000000..ffe033c --- /dev/null +++ b/ConfigurationManager.hpp @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2024 Petr Mironychev + * + * This file is part of QodeAssist. + * + * QodeAssist is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * QodeAssist is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with QodeAssist. If not, see . + */ + +#pragma once + +#include + +#include "llmcore/PromptTemplateManager.hpp" +#include "llmcore/ProvidersManager.hpp" +#include "settings/GeneralSettings.hpp" + +namespace QodeAssist { + +class ConfigurationManager : public QObject +{ + Q_OBJECT + +public: + static ConfigurationManager &instance(); + + void init(); + + LLMCore::Provider *getCurrentProvider(); + LLMCore::PromptTemplate *getCurrentTemplate(); + +public slots: + void selectProvider(); + void selectModel(); + void selectTemplate(); + void selectUrl(); + +private: + explicit ConfigurationManager(QObject *parent = nullptr); + ~ConfigurationManager() = default; + ConfigurationManager(const ConfigurationManager &) = delete; + ConfigurationManager &operator=(const ConfigurationManager &) = delete; + + Settings::GeneralSettings &m_generalSettings; + LLMCore::ProvidersManager &m_providersManager; + LLMCore::PromptTemplateManager &m_templateManger; + + void setupConnections(); +}; + +} // namespace QodeAssist diff --git a/LLMClientInterface.cpp b/LLMClientInterface.cpp index 0360725..70e93ab 100644 --- a/LLMClientInterface.cpp +++ b/LLMClientInterface.cpp @@ -146,28 +146,28 @@ void LLMClientInterface::handleExit(const QJsonObject &request) void LLMClientInterface::handleCompletion(const QJsonObject &request) { - auto updatedContext = prepareContext(request); + // auto updatedContext = prepareContext(request); - LLMCore::LLMConfig config; - config.requestType = LLMCore::RequestType::Fim; - config.provider = LLMCore::ProvidersManager::instance().getCurrentFimProvider(); - config.promptTemplate = LLMCore::PromptTemplateManager::instance().getCurrentFimTemplate(); - config.url = QUrl(QString("%1%2").arg(Settings::generalSettings().url(), - Settings::generalSettings().endPoint())); + // LLMCore::LLMConfig config; + // config.requestType = LLMCore::RequestType::Fim; + // config.provider = LLMCore::ProvidersManager::instance().getCurrentFimProvider(); + // config.promptTemplate = LLMCore::PromptTemplateManager::instance().getCurrentFimTemplate(); + // config.url = QUrl(QString("%1%2").arg(Settings::generalSettings().url(), + // Settings::generalSettings().endPoint())); - config.providerRequest = {{"model", Settings::generalSettings().modelName.value()}, - {"stream", true}, - {"stop", - QJsonArray::fromStringList(config.promptTemplate->stopWords())}}; - config.multiLineCompletion = Settings::generalSettings().multiLineCompletion(); + // config.providerRequest = {{"model", Settings::generalSettings().modelName.value()}, + // {"stream", true}, + // {"stop", + // QJsonArray::fromStringList(config.promptTemplate->stopWords())}}; + // config.multiLineCompletion = Settings::generalSettings().multiLineCompletion(); - if (Settings::contextSettings().useSystemPrompt()) - config.providerRequest["system"] = Settings::contextSettings().systemPrompt(); + // if (Settings::contextSettings().useSystemPrompt()) + // config.providerRequest["system"] = Settings::contextSettings().systemPrompt(); - config.promptTemplate->prepareRequest(config.providerRequest, updatedContext); - config.provider->prepareRequest(config.providerRequest, LLMCore::RequestType::Fim); + // config.promptTemplate->prepareRequest(config.providerRequest, updatedContext); + // config.provider->prepareRequest(config.providerRequest, LLMCore::RequestType::Fim); - m_requestHandler.sendLLMRequest(config, request); + // m_requestHandler.sendLLMRequest(config, request); } LLMCore::ContextData LLMClientInterface::prepareContext(const QJsonObject &request, diff --git a/QodeAssistClient.cpp b/QodeAssistClient.cpp index f85056f..89549c0 100644 --- a/QodeAssistClient.cpp +++ b/QodeAssistClient.cpp @@ -65,52 +65,52 @@ QodeAssistClient::~QodeAssistClient() void QodeAssistClient::openDocument(TextEditor::TextDocument *document) { - auto project = ProjectManager::projectForFile(document->filePath()); - if (!isEnabled(project)) - return; + // auto project = ProjectManager::projectForFile(document->filePath()); + // if (!isEnabled(project)) + // return; - Client::openDocument(document); - connect(document, - &TextDocument::contentsChangedWithPosition, - this, - [this, document](int position, int charsRemoved, int charsAdded) { - Q_UNUSED(charsRemoved) - if (!Settings::generalSettings().enableAutoComplete()) - return; + // Client::openDocument(document); + // connect(document, + // &TextDocument::contentsChangedWithPosition, + // this, + // [this, document](int position, int charsRemoved, int charsAdded) { + // Q_UNUSED(charsRemoved) + // if (!Settings::generalSettings().enableAutoComplete()) + // return; - auto project = ProjectManager::projectForFile(document->filePath()); - if (!isEnabled(project)) - return; + // auto project = ProjectManager::projectForFile(document->filePath()); + // if (!isEnabled(project)) + // return; - auto textEditor = BaseTextEditor::currentTextEditor(); - if (!textEditor || textEditor->document() != document) - return; + // auto textEditor = BaseTextEditor::currentTextEditor(); + // if (!textEditor || textEditor->document() != document) + // return; - if (Settings::contextSettings().useProjectChangesCache()) - ChangesManager::instance().addChange(document, - position, - charsRemoved, - charsAdded); + // if (Settings::contextSettings().useProjectChangesCache()) + // ChangesManager::instance().addChange(document, + // position, + // charsRemoved, + // charsAdded); - TextEditorWidget *widget = textEditor->editorWidget(); - if (widget->isReadOnly() || widget->multiTextCursor().hasMultipleCursors()) - return; - const int cursorPosition = widget->textCursor().position(); - if (cursorPosition < position || cursorPosition > position + charsAdded) - return; + // TextEditorWidget *widget = textEditor->editorWidget(); + // if (widget->isReadOnly() || widget->multiTextCursor().hasMultipleCursors()) + // return; + // const int cursorPosition = widget->textCursor().position(); + // if (cursorPosition < position || cursorPosition > position + charsAdded) + // return; - m_recentCharCount += charsAdded; + // m_recentCharCount += charsAdded; - if (m_typingTimer.elapsed() - > Settings::generalSettings().autoCompletionTypingInterval()) { - m_recentCharCount = charsAdded; - m_typingTimer.restart(); - } + // if (m_typingTimer.elapsed() + // > Settings::generalSettings().autoCompletionTypingInterval()) { + // m_recentCharCount = charsAdded; + // m_typingTimer.restart(); + // } - if (m_recentCharCount > Settings::generalSettings().autoCompletionCharThreshold()) { - scheduleRequest(widget); - } - }); + // if (m_recentCharCount > Settings::generalSettings().autoCompletionCharThreshold()) { + // scheduleRequest(widget); + // } + // }); } bool QodeAssistClient::canOpenProject(ProjectExplorer::Project *project) @@ -144,31 +144,31 @@ void QodeAssistClient::requestCompletions(TextEditor::TextEditorWidget *editor) void QodeAssistClient::scheduleRequest(TextEditor::TextEditorWidget *editor) { - cancelRunningRequest(editor); + // cancelRunningRequest(editor); - auto it = m_scheduledRequests.find(editor); - if (it == m_scheduledRequests.end()) { - auto timer = new QTimer(this); - timer->setSingleShot(true); - connect(timer, &QTimer::timeout, this, [this, editor]() { - if (editor - && editor->textCursor().position() - == m_scheduledRequests[editor]->property("cursorPosition").toInt() - && m_recentCharCount > Settings::generalSettings().autoCompletionCharThreshold()) - requestCompletions(editor); - }); - connect(editor, &TextEditorWidget::destroyed, this, [this, editor]() { - delete m_scheduledRequests.take(editor); - cancelRunningRequest(editor); - }); - connect(editor, &TextEditorWidget::cursorPositionChanged, this, [this, editor] { - cancelRunningRequest(editor); - }); - it = m_scheduledRequests.insert(editor, timer); - } + // auto it = m_scheduledRequests.find(editor); + // if (it == m_scheduledRequests.end()) { + // auto timer = new QTimer(this); + // timer->setSingleShot(true); + // connect(timer, &QTimer::timeout, this, [this, editor]() { + // if (editor + // && editor->textCursor().position() + // == m_scheduledRequests[editor]->property("cursorPosition").toInt() + // && m_recentCharCount > Settings::generalSettings().autoCompletionCharThreshold()) + // requestCompletions(editor); + // }); + // connect(editor, &TextEditorWidget::destroyed, this, [this, editor]() { + // delete m_scheduledRequests.take(editor); + // cancelRunningRequest(editor); + // }); + // connect(editor, &TextEditorWidget::cursorPositionChanged, this, [this, editor] { + // cancelRunningRequest(editor); + // }); + // it = m_scheduledRequests.insert(editor, timer); + // } - it.value()->setProperty("cursorPosition", editor->textCursor().position()); - it.value()->start(Settings::generalSettings().startSuggestionTimer()); + // it.value()->setProperty("cursorPosition", editor->textCursor().position()); + // it.value()->start(Settings::generalSettings().startSuggestionTimer()); } void QodeAssistClient::handleCompletions(const GetCompletionRequest::Response &response, TextEditor::TextEditorWidget *editor) diff --git a/chatview/ChatModel.cpp b/chatview/ChatModel.cpp index c5cf9f7..0656075 100644 --- a/chatview/ChatModel.cpp +++ b/chatview/ChatModel.cpp @@ -30,12 +30,12 @@ ChatModel::ChatModel(QObject *parent) : QAbstractListModel(parent) , m_totalTokens(0) { - auto &settings = Settings::generalSettings(); + // auto &settings = Settings::generalSettings(); - connect(&settings.chatTokensThreshold, - &Utils::BaseAspect::changed, - this, - &ChatModel::tokensThresholdChanged); + // connect(&settings.chatTokensThreshold, + // &Utils::BaseAspect::changed, + // this, + // &ChatModel::tokensThresholdChanged); } int ChatModel::rowCount(const QModelIndex &parent) const @@ -183,8 +183,9 @@ int ChatModel::totalTokens() const int ChatModel::tokensThreshold() const { - auto &settings = Settings::generalSettings(); - return settings.chatTokensThreshold(); + // auto &settings = Settings::generalSettings(); + // return settings.chatTokensThreshold(); + return 0; } QString ChatModel::lastMessageId() const diff --git a/chatview/ChatRootView.cpp b/chatview/ChatRootView.cpp index 6450c51..180c4ea 100644 --- a/chatview/ChatRootView.cpp +++ b/chatview/ChatRootView.cpp @@ -31,12 +31,12 @@ ChatRootView::ChatRootView(QQuickItem *parent) , m_chatModel(new ChatModel(this)) , m_clientInterface(new ClientInterface(m_chatModel, this)) { - auto &settings = Settings::generalSettings(); + // auto &settings = Settings::generalSettings(); - connect(&settings.chatModelName, - &Utils::BaseAspect::changed, - this, - &ChatRootView::currentTemplateChanged); + // connect(&settings.chatModelName, + // &Utils::BaseAspect::changed, + // this, + // &ChatRootView::currentTemplateChanged); generateColors(); } @@ -111,7 +111,7 @@ QColor ChatRootView::generateColor(const QColor &baseColor, QString ChatRootView::currentTemplate() const { auto &settings = Settings::generalSettings(); - return settings.chatModelName(); + return settings.caModel(); } QColor ChatRootView::primaryColor() const diff --git a/chatview/ClientInterface.cpp b/chatview/ClientInterface.cpp index 2d1c1b6..b99c7b8 100644 --- a/chatview/ClientInterface.cpp +++ b/chatview/ClientInterface.cpp @@ -56,46 +56,46 @@ ClientInterface::~ClientInterface() = default; void ClientInterface::sendMessage(const QString &message) { - cancelRequest(); + // cancelRequest(); - LOG_MESSAGE("Sending message: " + message); - LOG_MESSAGE("chatProvider " + Settings::generalSettings().chatLlmProviders.stringValue()); - LOG_MESSAGE("chatTemplate " + Settings::generalSettings().chatPrompts.stringValue()); + // LOG_MESSAGE("Sending message: " + message); + // LOG_MESSAGE("chatProvider " + Settings::generalSettings().chatLlmProviders.stringValue()); + // LOG_MESSAGE("chatTemplate " + Settings::generalSettings().chatPrompts.stringValue()); - auto chatTemplate = LLMCore::PromptTemplateManager::instance().getCurrentChatTemplate(); - auto chatProvider = LLMCore::ProvidersManager::instance().getCurrentChatProvider(); + // auto chatTemplate = LLMCore::PromptTemplateManager::instance().getCurrentChatTemplate(); + // auto chatProvider = LLMCore::ProvidersManager::instance().getCurrentChatProvider(); - LLMCore::ContextData context; - context.prefix = message; - context.suffix = ""; - if (Settings::contextSettings().useChatSystemPrompt()) - context.systemPrompt = Settings::contextSettings().chatSystemPrompt(); + // LLMCore::ContextData context; + // context.prefix = message; + // context.suffix = ""; + // if (Settings::contextSettings().useChatSystemPrompt()) + // context.systemPrompt = Settings::contextSettings().chatSystemPrompt(); - QJsonObject providerRequest; - providerRequest["model"] = Settings::generalSettings().chatModelName(); - providerRequest["stream"] = true; - providerRequest["messages"] = m_chatModel->prepareMessagesForRequest(context); + // QJsonObject providerRequest; + // providerRequest["model"] = Settings::generalSettings().chatModelName(); + // providerRequest["stream"] = true; + // providerRequest["messages"] = m_chatModel->prepareMessagesForRequest(context); - if (!chatTemplate || !chatProvider) { - LOG_MESSAGE("Check settings, provider or template are not set"); - } - chatTemplate->prepareRequest(providerRequest, context); - chatProvider->prepareRequest(providerRequest, LLMCore::RequestType::Chat); + // if (!chatTemplate || !chatProvider) { + // LOG_MESSAGE("Check settings, provider or template are not set"); + // } + // chatTemplate->prepareRequest(providerRequest, context); + // chatProvider->prepareRequest(providerRequest, LLMCore::RequestType::Chat); - LLMCore::LLMConfig config; - config.requestType = LLMCore::RequestType::Chat; - config.provider = chatProvider; - config.promptTemplate = chatTemplate; - config.url = QString("%1%2").arg(Settings::generalSettings().chatUrl(), - Settings::generalSettings().chatEndPoint()); - config.providerRequest = providerRequest; - config.multiLineCompletion = Settings::generalSettings().multiLineCompletion(); + // LLMCore::LLMConfig config; + // config.requestType = LLMCore::RequestType::Chat; + // config.provider = chatProvider; + // config.promptTemplate = chatTemplate; + // config.url = QString("%1%2").arg(Settings::generalSettings().chatUrl(), + // Settings::generalSettings().chatEndPoint()); + // config.providerRequest = providerRequest; + // config.multiLineCompletion = Settings::generalSettings().multiLineCompletion(); - QJsonObject request; - request["id"] = QUuid::createUuid().toString(); + // QJsonObject request; + // request["id"] = QUuid::createUuid().toString(); - m_chatModel->addMessage(message, ChatModel::ChatRole::User, ""); - m_requestHandler->sendLLMRequest(config, request); + // m_chatModel->addMessage(message, ChatModel::ChatRole::User, ""); + // m_requestHandler->sendLLMRequest(config, request); } void ClientInterface::clearMessages() diff --git a/llmcore/PromptTemplateManager.cpp b/llmcore/PromptTemplateManager.cpp index 2eafc18..c0b08fc 100644 --- a/llmcore/PromptTemplateManager.cpp +++ b/llmcore/PromptTemplateManager.cpp @@ -19,8 +19,6 @@ #include "PromptTemplateManager.hpp" -#include "Logger.hpp" - namespace QodeAssist::LLMCore { PromptTemplateManager &PromptTemplateManager::instance() @@ -29,48 +27,6 @@ PromptTemplateManager &PromptTemplateManager::instance() return instance; } -void PromptTemplateManager::setCurrentFimTemplate(const QString &name) -{ - LOG_MESSAGE("Setting current FIM provider to: " + name); - if (!m_fimTemplates.contains(name) || m_fimTemplates[name] == nullptr) { - LOG_MESSAGE("Error to set current FIM template" + name); - return; - } - - m_currentFimTemplate = m_fimTemplates[name]; -} - -PromptTemplate *PromptTemplateManager::getCurrentFimTemplate() -{ - if (m_currentFimTemplate == nullptr) { - LOG_MESSAGE("Current fim provider is null, return first"); - return m_fimTemplates.first(); - } - - return m_currentFimTemplate; -} - -void PromptTemplateManager::setCurrentChatTemplate(const QString &name) -{ - LOG_MESSAGE("Setting current chat provider to: " + name); - if (!m_chatTemplates.contains(name) || m_chatTemplates[name] == nullptr) { - LOG_MESSAGE("Error to set current chat template" + name); - return; - } - - m_currentChatTemplate = m_chatTemplates[name]; -} - -PromptTemplate *PromptTemplateManager::getCurrentChatTemplate() -{ - if (m_currentChatTemplate == nullptr) { - LOG_MESSAGE("Current chat provider is null, return first"); - return m_chatTemplates.first(); - } - - return m_currentChatTemplate; -} - QStringList PromptTemplateManager::fimTemplatesNames() const { return m_fimTemplates.keys(); @@ -87,4 +43,14 @@ PromptTemplateManager::~PromptTemplateManager() qDeleteAll(m_chatTemplates); } +PromptTemplate *PromptTemplateManager::getFimTemplateByName(const QString &templateName) +{ + return m_fimTemplates[templateName]; +} + +PromptTemplate *PromptTemplateManager::getChatTemplateByName(const QString &templateName) +{ + return m_chatTemplates[templateName]; +} + } // namespace QodeAssist::LLMCore diff --git a/llmcore/PromptTemplateManager.hpp b/llmcore/PromptTemplateManager.hpp index 5c2c3bf..4774a22 100644 --- a/llmcore/PromptTemplateManager.hpp +++ b/llmcore/PromptTemplateManager.hpp @@ -46,11 +46,8 @@ public: } } - void setCurrentFimTemplate(const QString &name); - PromptTemplate *getCurrentFimTemplate(); - - void setCurrentChatTemplate(const QString &name); - PromptTemplate *getCurrentChatTemplate(); + PromptTemplate *getFimTemplateByName(const QString &templateName); + PromptTemplate *getChatTemplateByName(const QString &templateName); QStringList fimTemplatesNames() const; QStringList chatTemplatesNames() const; @@ -62,8 +59,6 @@ private: QMap m_fimTemplates; QMap m_chatTemplates; - PromptTemplate *m_currentFimTemplate; - PromptTemplate *m_currentChatTemplate; }; } // namespace QodeAssist::LLMCore diff --git a/llmcore/Provider.hpp b/llmcore/Provider.hpp index e66f941..55f6da3 100644 --- a/llmcore/Provider.hpp +++ b/llmcore/Provider.hpp @@ -40,7 +40,7 @@ public: virtual void prepareRequest(QJsonObject &request, RequestType type) = 0; virtual bool handleResponse(QNetworkReply *reply, QString &accumulatedResponse) = 0; - virtual QList getInstalledModels(const Utils::Environment &env, const QString &url) = 0; + virtual QList getInstalledModels(const QString &url) = 0; }; } // namespace QodeAssist::LLMCore diff --git a/llmcore/ProvidersManager.cpp b/llmcore/ProvidersManager.cpp index fdde562..19a1d43 100644 --- a/llmcore/ProvidersManager.cpp +++ b/llmcore/ProvidersManager.cpp @@ -18,8 +18,6 @@ */ #include "ProvidersManager.hpp" -#include "Logger.hpp" -#include namespace QodeAssist::LLMCore { @@ -29,50 +27,6 @@ ProvidersManager &ProvidersManager::instance() return instance; } -Provider *ProvidersManager::setCurrentFimProvider(const QString &name) -{ - LOG_MESSAGE("Setting current FIM provider to: " + name); - if (!m_providers.contains(name)) { - LOG_MESSAGE("Can't find provider with name: " + name); - return nullptr; - } - - m_currentFimProvider = m_providers[name]; - return m_currentFimProvider; -} - -Provider *ProvidersManager::setCurrentChatProvider(const QString &name) -{ - LOG_MESSAGE("Setting current chat provider to: " + name); - if (!m_providers.contains(name)) { - LOG_MESSAGE("Can't find chat provider with name: " + name); - return nullptr; - } - - m_currentChatProvider = m_providers[name]; - return m_currentChatProvider; -} - -Provider *ProvidersManager::getCurrentFimProvider() -{ - if (m_currentFimProvider == nullptr) { - LOG_MESSAGE("Current fim provider is null, return first"); - return m_providers.first(); - } - - return m_currentFimProvider; -} - -Provider *ProvidersManager::getCurrentChatProvider() -{ - if (m_currentChatProvider == nullptr) { - LOG_MESSAGE("Current chat provider is null, return first"); - return m_providers.first(); - } - - return m_currentChatProvider; -} - QStringList ProvidersManager::providersNames() const { return m_providers.keys(); @@ -83,4 +37,9 @@ ProvidersManager::~ProvidersManager() qDeleteAll(m_providers); } +Provider *ProvidersManager::getProviderByName(const QString &providerName) +{ + return m_providers[providerName]; +} + } // namespace QodeAssist::LLMCore diff --git a/llmcore/ProvidersManager.hpp b/llmcore/ProvidersManager.hpp index 03eabd2..82a0c8e 100644 --- a/llmcore/ProvidersManager.hpp +++ b/llmcore/ProvidersManager.hpp @@ -21,6 +21,7 @@ #include +#include #include "Provider.hpp" namespace QodeAssist::LLMCore { @@ -40,11 +41,7 @@ public: m_providers[name] = provider; } - Provider *setCurrentFimProvider(const QString &name); - Provider *setCurrentChatProvider(const QString &name); - - Provider *getCurrentFimProvider(); - Provider *getCurrentChatProvider(); + Provider *getProviderByName(const QString &providerName); QStringList providersNames() const; @@ -54,8 +51,6 @@ private: ProvidersManager &operator=(const ProvidersManager &) = delete; QMap m_providers; - Provider *m_currentFimProvider = nullptr; - Provider *m_currentChatProvider = nullptr; }; } // namespace QodeAssist::LLMCore diff --git a/providers/LMStudioProvider.cpp b/providers/LMStudioProvider.cpp index edcd832..06bc67e 100644 --- a/providers/LMStudioProvider.cpp +++ b/providers/LMStudioProvider.cpp @@ -127,8 +127,7 @@ bool LMStudioProvider::handleResponse(QNetworkReply *reply, QString &accumulated return isComplete; } -QList LMStudioProvider::getInstalledModels(const Utils::Environment &env, - const QString &url) +QList LMStudioProvider::getInstalledModels(const QString &url) { QList models; QNetworkAccessManager manager; diff --git a/providers/LMStudioProvider.hpp b/providers/LMStudioProvider.hpp index 42964ab..a92a01f 100644 --- a/providers/LMStudioProvider.hpp +++ b/providers/LMStudioProvider.hpp @@ -34,7 +34,7 @@ public: QString chatEndpoint() const override; void prepareRequest(QJsonObject &request, LLMCore::RequestType type) override; bool handleResponse(QNetworkReply *reply, QString &accumulatedResponse) override; - QList getInstalledModels(const Utils::Environment &env, const QString &url) override; + QList getInstalledModels(const QString &url) override; }; } // namespace QodeAssist::Providers diff --git a/providers/OllamaProvider.cpp b/providers/OllamaProvider.cpp index dd92033..223b568 100644 --- a/providers/OllamaProvider.cpp +++ b/providers/OllamaProvider.cpp @@ -25,7 +25,6 @@ #include #include -#include "llmcore/PromptTemplateManager.hpp" #include "logger/Logger.hpp" #include "settings/PresetPromptsSettings.hpp" @@ -124,7 +123,7 @@ bool OllamaProvider::handleResponse(QNetworkReply *reply, QString &accumulatedRe return isComplete; } -QList OllamaProvider::getInstalledModels(const Utils::Environment &env, const QString &url) +QList OllamaProvider::getInstalledModels(const QString &url) { QList models; QNetworkAccessManager manager; diff --git a/providers/OllamaProvider.hpp b/providers/OllamaProvider.hpp index 145d475..cd00e18 100644 --- a/providers/OllamaProvider.hpp +++ b/providers/OllamaProvider.hpp @@ -34,7 +34,7 @@ public: QString chatEndpoint() const override; void prepareRequest(QJsonObject &request, LLMCore::RequestType type) override; bool handleResponse(QNetworkReply *reply, QString &accumulatedResponse) override; - QList getInstalledModels(const Utils::Environment &env, const QString &url) override; + QList getInstalledModels(const QString &url) override; }; } // namespace QodeAssist::Providers diff --git a/providers/OpenAICompatProvider.cpp b/providers/OpenAICompatProvider.cpp index d277015..8f7b7e9 100644 --- a/providers/OpenAICompatProvider.cpp +++ b/providers/OpenAICompatProvider.cpp @@ -129,8 +129,7 @@ bool OpenAICompatProvider::handleResponse(QNetworkReply *reply, QString &accumul return isComplete; } -QList OpenAICompatProvider::getInstalledModels(const Utils::Environment &env, - const QString &url) +QList OpenAICompatProvider::getInstalledModels(const QString &url) { return QStringList(); } diff --git a/providers/OpenAICompatProvider.hpp b/providers/OpenAICompatProvider.hpp index bd23c73..ebe1c0a 100644 --- a/providers/OpenAICompatProvider.hpp +++ b/providers/OpenAICompatProvider.hpp @@ -34,7 +34,7 @@ public: QString chatEndpoint() const override; void prepareRequest(QJsonObject &request, LLMCore::RequestType type) override; bool handleResponse(QNetworkReply *reply, QString &accumulatedResponse) override; - QList getInstalledModels(const Utils::Environment &env, const QString &url) override; + QList getInstalledModels(const QString &url) override; }; } // namespace QodeAssist::Providers diff --git a/qodeassist.cpp b/qodeassist.cpp index 5007dd7..a8b2b2a 100644 --- a/qodeassist.cpp +++ b/qodeassist.cpp @@ -39,6 +39,7 @@ #include #include +#include "ConfigurationManager.hpp" #include "QodeAssistClient.hpp" #include "chat/ChatOutputPane.h" #include "chat/NavigationPanel.hpp" @@ -125,6 +126,8 @@ public: m_chatOutputPane = new Chat::ChatOutputPane(this); m_navigationPanel = new Chat::NavigationPanel(); + + ConfigurationManager::instance().init(); } void extensionsInitialized() final diff --git a/settings/CMakeLists.txt b/settings/CMakeLists.txt index 882cc76..f2062ec 100644 --- a/settings/CMakeLists.txt +++ b/settings/CMakeLists.txt @@ -16,7 +16,5 @@ target_link_libraries(QodeAssistSettings QtCreator::Core QtCreator::Utils QodeAssistLogger - PRIVATE - LLMCore ) target_include_directories(QodeAssistSettings PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) diff --git a/settings/GeneralSettings.cpp b/settings/GeneralSettings.cpp index 1c64d87..bfab84f 100644 --- a/settings/GeneralSettings.cpp +++ b/settings/GeneralSettings.cpp @@ -27,9 +27,6 @@ #include #include "Logger.hpp" -#include "PromptTemplateManager.hpp" -#include "Provider.hpp" -#include "ProvidersManager.hpp" #include "SettingsConstants.hpp" #include "SettingsTr.hpp" #include "SettingsUtils.hpp" @@ -46,117 +43,59 @@ GeneralSettings::GeneralSettings() { setAutoApply(false); - setDisplayName(Tr::tr("General")); + setDisplayName(TrConstants::GENERAL); enableQodeAssist.setSettingsKey(Constants::ENABLE_QODE_ASSIST); - enableQodeAssist.setLabelText(Tr::tr("Enable Qode Assist")); + enableQodeAssist.setLabelText(TrConstants::ENABLE_QODE_ASSIST); enableQodeAssist.setDefaultValue(true); - enableAutoComplete.setSettingsKey(Constants::ENABLE_AUTO_COMPLETE); - enableAutoComplete.setLabelText(Tr::tr("Enable Auto Complete")); - enableAutoComplete.setDefaultValue(true); - enableLogging.setSettingsKey(Constants::ENABLE_LOGGING); - enableLogging.setLabelText(Tr::tr("Enable Logging")); + enableLogging.setLabelText(TrConstants::ENABLE_LOG); enableLogging.setDefaultValue(false); - multiLineCompletion.setSettingsKey(Constants::MULTILINE_COMPLETION); - multiLineCompletion.setDefaultValue(false); - multiLineCompletion.setLabelText(Tr::tr("Enable Multiline Completion(experimental)")); + resetToDefaults.m_buttonText = TrConstants::RESET_TO_DEFAULTS; - startSuggestionTimer.setSettingsKey(Constants::START_SUGGESTION_TIMER); - startSuggestionTimer.setLabelText(Tr::tr("with delay(ms)")); - startSuggestionTimer.setRange(10, 10000); - startSuggestionTimer.setDefaultValue(500); + initStringAspect(ccProvider, Constants::CC_PROVIDER, TrConstants::PROVIDER, "Ollama"); + ccProvider.setReadOnly(true); + ccSelectProvider.m_buttonText = TrConstants::SELECT; - autoCompletionCharThreshold.setSettingsKey(Constants::AUTO_COMPLETION_CHAR_THRESHOLD); - autoCompletionCharThreshold.setLabelText(Tr::tr("AI suggestion triggers after typing")); - autoCompletionCharThreshold.setToolTip( - Tr::tr("The number of characters that need to be typed within the typing interval " - "before an AI suggestion request is sent.")); - autoCompletionCharThreshold.setRange(0, 10); - autoCompletionCharThreshold.setDefaultValue(0); + initStringAspect(ccModel, Constants::CC_MODEL, TrConstants::MODEL, "codellama:7b-code"); + ccSelectModel.m_buttonText = TrConstants::SELECT; - autoCompletionTypingInterval.setSettingsKey(Constants::AUTO_COMPLETION_TYPING_INTERVAL); - autoCompletionTypingInterval.setLabelText(Tr::tr("character(s) within(ms)")); - autoCompletionTypingInterval.setToolTip( - Tr::tr("The time window (in milliseconds) during which the character threshold " - "must be met to trigger an AI suggestion request.")); - autoCompletionTypingInterval.setRange(500, 5000); - autoCompletionTypingInterval.setDefaultValue(2000); + initStringAspect(ccTemplate, Constants::CC_TEMPLATE, TrConstants::TEMPLATE, "CodeLlama FIM"); + ccTemplate.setReadOnly(true); + ccSelectTemplate.m_buttonText = TrConstants::SELECT; - llmProviders.setSettingsKey(Constants::LLM_PROVIDERS); - llmProviders.setDisplayName(Tr::tr("AI Suggest Provider:")); - llmProviders.setDisplayStyle(Utils::SelectionAspect::DisplayStyle::ComboBox); + initStringAspect(ccUrl, Constants::CC_URL, TrConstants::URL, "http://localhost:11434"); + ccSetUrl.m_buttonText = TrConstants::SELECT; - url.setSettingsKey(Constants::URL); - url.setLabelText(Tr::tr("URL:")); - url.setDisplayStyle(Utils::StringAspect::LineEditDisplay); + ccStatus.setDisplayStyle(Utils::StringAspect::LabelDisplay); + ccStatus.setLabelText(TrConstants::STATUS); + ccStatus.setDefaultValue(""); + ccTest.m_buttonText = TrConstants::TEST; - endPoint.setSettingsKey(Constants::END_POINT); - endPoint.setLabelText(Tr::tr("FIM Endpoint:")); - endPoint.setDisplayStyle(Utils::StringAspect::LineEditDisplay); + initStringAspect(caProvider, Constants::CA_PROVIDER, TrConstants::PROVIDER, "Ollama"); + caProvider.setReadOnly(true); + caSelectProvider.m_buttonText = TrConstants::SELECT; - modelName.setSettingsKey(Constants::MODEL_NAME); - modelName.setLabelText(Tr::tr("Model name:")); - modelName.setDisplayStyle(Utils::StringAspect::LineEditDisplay); + initStringAspect(caModel, Constants::CA_MODEL, TrConstants::MODEL, "codellama:7b-instruct"); + caSelectModel.m_buttonText = TrConstants::SELECT; - selectModels.m_buttonText = Tr::tr("Select Fill-In-the-Middle Model"); + initStringAspect(caTemplate, Constants::CA_TEMPLATE, TrConstants::TEMPLATE, "CodeLlama Chat"); + caTemplate.setReadOnly(true); - fimPrompts.setDisplayName(Tr::tr("Fill-In-the-Middle Prompt")); - fimPrompts.setSettingsKey(Constants::FIM_PROMPTS); - fimPrompts.setDisplayStyle(Utils::SelectionAspect::DisplayStyle::ComboBox); - resetToDefaults.m_buttonText = Tr::tr("Reset Page to Defaults"); + caSelectTemplate.m_buttonText = TrConstants::SELECT; - chatLlmProviders.setSettingsKey(Constants::CHAT_LLM_PROVIDERS); - chatLlmProviders.setDisplayName(Tr::tr("AI Chat Provider:")); - chatLlmProviders.setDisplayStyle(Utils::SelectionAspect::DisplayStyle::ComboBox); + initStringAspect(caUrl, Constants::CA_URL, TrConstants::URL, "http://localhost:11434"); + caSetUrl.m_buttonText = TrConstants::SELECT; - chatUrl.setSettingsKey(Constants::CHAT_URL); - chatUrl.setLabelText(Tr::tr("URL:")); - chatUrl.setDisplayStyle(Utils::StringAspect::LineEditDisplay); - - chatEndPoint.setSettingsKey(Constants::CHAT_END_POINT); - chatEndPoint.setLabelText(Tr::tr("Chat Endpoint:")); - chatEndPoint.setDisplayStyle(Utils::StringAspect::LineEditDisplay); - - chatModelName.setSettingsKey(Constants::CHAT_MODEL_NAME); - chatModelName.setLabelText(Tr::tr("Model name:")); - chatModelName.setDisplayStyle(Utils::StringAspect::LineEditDisplay); - - chatSelectModels.m_buttonText = Tr::tr("Select Chat Model"); - - chatPrompts.setDisplayName(Tr::tr("Chat Prompt")); - chatPrompts.setSettingsKey(Constants::CHAT_PROMPTS); - chatPrompts.setDisplayStyle(Utils::SelectionAspect::DisplayStyle::ComboBox); - - chatTokensThreshold.setSettingsKey(Constants::CHAT_TOKENS_THRESHOLD); - chatTokensThreshold.setLabelText(Tr::tr("Chat History Token Limit")); - chatTokensThreshold.setToolTip(Tr::tr("Maximum number of tokens in chat history. When " - "exceeded, oldest messages will be removed.")); - chatTokensThreshold.setRange(1000, 16000); - chatTokensThreshold.setDefaultValue(8000); - - loadProviders(); - loadPrompts(); - - llmProviders.setDefaultValue(llmProviders.indexForDisplay("Ollama")); - chatLlmProviders.setDefaultValue(chatLlmProviders.indexForDisplay("Ollama")); - fimPrompts.setDefaultValue(fimPrompts.indexForDisplay("CodeLlama FIM")); - chatPrompts.setDefaultValue(chatPrompts.indexForDisplay("CodeLlama Chat")); - - auto fimProviderName = llmProviders.displayForIndex(llmProviders.value()); - setCurrentFimProvider(fimProviderName); - auto chatProviderName = chatLlmProviders.displayForIndex(chatLlmProviders.value()); - setCurrentChatProvider(chatProviderName); + caStatus.setDisplayStyle(Utils::StringAspect::LabelDisplay); + caStatus.setLabelText(TrConstants::STATUS); + caStatus.setDefaultValue(""); + caTest.m_buttonText = TrConstants::TEST; readSettings(); - auto nameFimPromts = fimPrompts.displayForIndex(fimPrompts.value()); - LLMCore::PromptTemplateManager::instance().setCurrentFimTemplate(nameFimPromts); - auto nameChatPromts = chatPrompts.displayForIndex(chatPrompts.value()); - LLMCore::PromptTemplateManager::instance().setCurrentChatTemplate(nameChatPromts); - Logger::instance().setLoggingEnabled(enableLogging()); setupConnections(); @@ -164,226 +103,88 @@ GeneralSettings::GeneralSettings() setLayouter([this]() { using namespace Layouting; - auto rootLayout - = Column{Row{enableQodeAssist, Stretch{1}, resetToDefaults}, - Row{enableLogging, Stretch{1}}, - Space{8}, - Group{title(Tr::tr("AI Suggestions")), - Column{enableAutoComplete, - multiLineCompletion, - Row{autoCompletionCharThreshold, - autoCompletionTypingInterval, - startSuggestionTimer, - Stretch{1}}, - Row{llmProviders, Stretch{1}}, - Row{url, endPoint, fimUrlIndicator}, - Row{selectModels, modelName, fimModelIndicator}, - Row{fimPrompts, Stretch{1}}}}, - Space{16}, - Group{title(Tr::tr("AI Chat")), - Column{Row{chatLlmProviders, Stretch{1}}, - Row{chatUrl, chatEndPoint, chatUrlIndicator}, - Row{chatSelectModels, chatModelName, chatModelIndicator}, - Row{chatPrompts, Stretch{1}}, - Row{chatTokensThreshold, Stretch{1}}}}, - Stretch{1}}; + auto ccGrid = Grid{}; + ccGrid.addRow({ccProvider, ccSelectProvider}); + ccGrid.addRow({ccModel, ccSelectModel}); + ccGrid.addRow({ccTemplate, ccSelectTemplate}); + ccGrid.addRow({ccUrl, ccSetUrl}); + ccGrid.addRow({ccStatus, ccTest}); + + auto caGrid = Grid{}; + caGrid.addRow({caProvider, caSelectProvider}); + caGrid.addRow({caModel, caSelectModel}); + caGrid.addRow({caTemplate, caSelectTemplate}); + caGrid.addRow({caUrl, caSetUrl}); + caGrid.addRow({caStatus, caTest}); + + auto ccGroup = Group{title(TrConstants::CODE_COMPLETION), ccGrid}; + auto caGroup = Group{title(TrConstants::CHAT_ASSISTANT), caGrid}; + + auto rootLayout = Column{Row{enableQodeAssist, Stretch{1}, resetToDefaults}, + Row{enableLogging, Stretch{1}}, + Space{8}, + ccGroup, + Space{8}, + caGroup, + Stretch{1}}; + return rootLayout; }); - - updateStatusIndicators(); } -void GeneralSettings::setupConnections() +void GeneralSettings::showSelectionDialog(const QStringList &data, + Utils::StringAspect &aspect, + const QString &title, + const QString &text) { - connect(&llmProviders, &Utils::SelectionAspect::volatileValueChanged, this, [this]() { - auto providerName = llmProviders.displayForIndex(llmProviders.volatileValue()); - setCurrentFimProvider(providerName); - modelName.setVolatileValue(""); - }); - connect(&chatLlmProviders, &Utils::SelectionAspect::volatileValueChanged, this, [this]() { - auto providerName = chatLlmProviders.displayForIndex(chatLlmProviders.volatileValue()); - setCurrentChatProvider(providerName); - chatModelName.setVolatileValue(""); - }); + if (data.isEmpty()) + return; - connect(&fimPrompts, &Utils::SelectionAspect::volatileValueChanged, this, [this]() { - int index = fimPrompts.volatileValue(); - LLMCore::PromptTemplateManager::instance().setCurrentFimTemplate( - fimPrompts.displayForIndex(index)); - }); - connect(&chatPrompts, &Utils::SelectionAspect::volatileValueChanged, this, [this]() { - int index = chatPrompts.volatileValue(); - LLMCore::PromptTemplateManager::instance().setCurrentChatTemplate( - chatPrompts.displayForIndex(index)); - }); + bool ok; + QInputDialog dialog(Core::ICore::dialogParent()); + dialog.setWindowTitle(title); + dialog.setLabelText(text); + dialog.setComboBoxItems(data); + dialog.setComboBoxEditable(false); + dialog.setFixedSize(400, 150); - connect(&selectModels, &ButtonAspect::clicked, this, [this]() { - auto *provider = LLMCore::ProvidersManager::instance().getCurrentFimProvider(); - showModelSelectionDialog(&modelName, provider); - }); - connect(&chatSelectModels, &ButtonAspect::clicked, this, [this]() { - auto *provider = LLMCore::ProvidersManager::instance().getCurrentChatProvider(); - showModelSelectionDialog(&chatModelName, provider); - }); - - connect(&enableLogging, &Utils::BoolAspect::volatileValueChanged, this, [this]() { - Logger::instance().setLoggingEnabled(enableLogging.volatileValue()); - }); - connect(&resetToDefaults, &ButtonAspect::clicked, this, &GeneralSettings::resetPageToDefaults); - - connect(&url, - &Utils::StringAspect::volatileValueChanged, - this, - &GeneralSettings::updateStatusIndicators); - connect(&modelName, - &Utils::StringAspect::volatileValueChanged, - this, - &GeneralSettings::updateStatusIndicators); - connect(&chatUrl, - &Utils::StringAspect::volatileValueChanged, - this, - &GeneralSettings::updateStatusIndicators); - connect(&chatModelName, - &Utils::StringAspect::volatileValueChanged, - this, - &GeneralSettings::updateStatusIndicators); -} - -void GeneralSettings::showModelSelectionDialog(Utils::StringAspect *modelNameObj, - LLMCore::Provider *provider) -{ - Utils::Environment env = Utils::Environment::systemEnvironment(); - QString providerUrl = (modelNameObj == &modelName) ? url() : chatUrl(); - - if (provider) { - QStringList models = provider->getInstalledModels(env, providerUrl); - bool ok; - QString selectedModel = QInputDialog::getItem(Core::ICore::dialogParent(), - Tr::tr("Select LLM Model"), - Tr::tr("Choose a model:"), - models, - 0, - false, - &ok); - - if (ok && !selectedModel.isEmpty()) { - modelNameObj->setVolatileValue(selectedModel); + if (dialog.exec() == QDialog::Accepted) { + QString result = dialog.textValue(); + if (!result.isEmpty()) { + aspect.setValue(result); writeSettings(); } } } +void GeneralSettings::setupConnections() +{ + connect(&enableLogging, &Utils::BoolAspect::volatileValueChanged, this, [this]() { + Logger::instance().setLoggingEnabled(enableLogging.volatileValue()); + }); + connect(&resetToDefaults, &ButtonAspect::clicked, this, &GeneralSettings::resetPageToDefaults); +} + void GeneralSettings::resetPageToDefaults() { QMessageBox::StandardButton reply; - reply = QMessageBox::question( - Core::ICore::dialogParent(), - Tr::tr("Reset Settings"), - Tr::tr("Are you sure you want to reset all settings to default values?"), - QMessageBox::Yes | QMessageBox::No); + reply = QMessageBox::question(Core::ICore::dialogParent(), + TrConstants::RESET_SETTINGS, + TrConstants::CONFIRMATION, + QMessageBox::Yes | QMessageBox::No); if (reply == QMessageBox::Yes) { resetAspect(enableQodeAssist); - resetAspect(enableAutoComplete); resetAspect(enableLogging); - resetAspect(startSuggestionTimer); - resetAspect(autoCompletionTypingInterval); - resetAspect(autoCompletionCharThreshold); - resetAspect(llmProviders); - resetAspect(chatLlmProviders); - resetAspect(fimPrompts); - resetAspect(chatPrompts); - resetAspect(chatTokensThreshold); - } - - modelName.setVolatileValue(""); - chatModelName.setVolatileValue(""); - - updateStatusIndicators(); -} - -void GeneralSettings::updateStatusIndicators() -{ - bool fimUrlValid = !url.volatileValue().isEmpty() && !endPoint.volatileValue().isEmpty(); - bool fimModelValid = !modelName.volatileValue().isEmpty(); - bool chatUrlValid = !chatUrl.volatileValue().isEmpty() - && !chatEndPoint.volatileValue().isEmpty(); - bool chatModelValid = !chatModelName.volatileValue().isEmpty(); - - bool fimPingSuccessful = false; - if (fimUrlValid) { - QUrl pingUrl(url.volatileValue()); - fimPingSuccessful = Settings::pingUrl(pingUrl); - } - bool chatPingSuccessful = false; - if (chatUrlValid) { - QUrl pingUrl(chatUrl.volatileValue()); - chatPingSuccessful = Settings::pingUrl(pingUrl); - } - - setIndicatorStatus(fimModelIndicator, - fimModelValid ? tr("Model is properly configured") - : tr("No model selected or model name is invalid"), - fimModelValid); - setIndicatorStatus(fimUrlIndicator, - fimPingSuccessful ? tr("Server is reachable") - : tr("Server is not reachable or URL is invalid"), - fimPingSuccessful); - - setIndicatorStatus(chatModelIndicator, - chatModelValid ? tr("Model is properly configured") - : tr("No model selected or model name is invalid"), - chatModelValid); - setIndicatorStatus(chatUrlIndicator, - chatPingSuccessful ? tr("Server is reachable") - : tr("Server is not reachable or URL is invalid"), - chatPingSuccessful); -} - -void GeneralSettings::setIndicatorStatus(Utils::StringAspect &indicator, - const QString &tooltip, - bool isValid) -{ - const Utils::Icon &icon = isValid ? Utils::Icons::OK : Utils::Icons::WARNING; - indicator.setLabelPixmap(icon.pixmap()); - indicator.setToolTip(tooltip); -} - -void GeneralSettings::setCurrentFimProvider(const QString &name) -{ - const auto provider = LLMCore::ProvidersManager::instance().setCurrentFimProvider(name); - if (!provider) - return; - - url.setValue(provider->url()); - endPoint.setValue(provider->completionEndpoint()); -} - -void GeneralSettings::setCurrentChatProvider(const QString &name) -{ - const auto provider = LLMCore::ProvidersManager::instance().setCurrentChatProvider(name); - if (!provider) - return; - - chatUrl.setValue(provider->url()); - chatEndPoint.setValue(provider->chatEndpoint()); -} - -void GeneralSettings::loadProviders() -{ - for (const auto &name : LLMCore::ProvidersManager::instance().providersNames()) { - llmProviders.addOption(name); - chatLlmProviders.addOption(name); - } -} - -void GeneralSettings::loadPrompts() -{ - for (const auto &name : LLMCore::PromptTemplateManager::instance().fimTemplatesNames()) { - fimPrompts.addOption(name); - } - for (const auto &name : LLMCore::PromptTemplateManager::instance().chatTemplatesNames()) { - chatPrompts.addOption(name); + resetAspect(ccProvider); + resetAspect(ccModel); + resetAspect(ccTemplate); + resetAspect(ccUrl); + resetAspect(caProvider); + resetAspect(caModel); + resetAspect(caTemplate); + resetAspect(caUrl); + writeSettings(); } } @@ -393,7 +194,7 @@ public: GeneralSettingsPage() { setId(Constants::QODE_ASSIST_GENERAL_SETTINGS_PAGE_ID); - setDisplayName(Tr::tr("General")); + setDisplayName(TrConstants::GENERAL); setCategory(Constants::QODE_ASSIST_GENERAL_OPTIONS_CATEGORY); setSettingsProvider([] { return &generalSettings(); }); } diff --git a/settings/GeneralSettings.hpp b/settings/GeneralSettings.hpp index 6584659..9b0fc4f 100644 --- a/settings/GeneralSettings.hpp +++ b/settings/GeneralSettings.hpp @@ -34,50 +34,49 @@ public: GeneralSettings(); Utils::BoolAspect enableQodeAssist{this}; - Utils::BoolAspect enableAutoComplete{this}; - Utils::BoolAspect multiLineCompletion{this}; Utils::BoolAspect enableLogging{this}; - Utils::IntegerAspect startSuggestionTimer{this}; - Utils::IntegerAspect autoCompletionCharThreshold{this}; - Utils::IntegerAspect autoCompletionTypingInterval{this}; - - Utils::SelectionAspect llmProviders{this}; - Utils::StringAspect url{this}; - Utils::StringAspect endPoint{this}; - - Utils::StringAspect modelName{this}; - ButtonAspect selectModels{this}; - Utils::SelectionAspect fimPrompts{this}; ButtonAspect resetToDefaults{this}; - Utils::SelectionAspect chatLlmProviders{this}; - Utils::StringAspect chatUrl{this}; - Utils::StringAspect chatEndPoint{this}; + // code completion setttings + Utils::StringAspect ccProvider{this}; + ButtonAspect ccSelectProvider{this}; - Utils::StringAspect chatModelName{this}; - ButtonAspect chatSelectModels{this}; - Utils::SelectionAspect chatPrompts{this}; + Utils::StringAspect ccModel{this}; + ButtonAspect ccSelectModel{this}; - Utils::StringAspect fimModelIndicator{this}; - Utils::StringAspect fimUrlIndicator{this}; - Utils::StringAspect chatModelIndicator{this}; - Utils::StringAspect chatUrlIndicator{this}; + Utils::StringAspect ccTemplate{this}; + ButtonAspect ccSelectTemplate{this}; - Utils::IntegerAspect chatTokensThreshold{this}; + Utils::StringAspect ccUrl{this}; + ButtonAspect ccSetUrl{this}; + + Utils::StringAspect ccStatus{this}; + ButtonAspect ccTest{this}; + + // chat assistant settings + Utils::StringAspect caProvider{this}; + ButtonAspect caSelectProvider{this}; + + Utils::StringAspect caModel{this}; + ButtonAspect caSelectModel{this}; + + Utils::StringAspect caTemplate{this}; + ButtonAspect caSelectTemplate{this}; + + Utils::StringAspect caUrl{this}; + ButtonAspect caSetUrl{this}; + + Utils::StringAspect caStatus{this}; + ButtonAspect caTest{this}; + + void showSelectionDialog(const QStringList &data, + Utils::StringAspect &aspect, + const QString &title = {}, + const QString &text = {}); private: void setupConnections(); - void showModelSelectionDialog(Utils::StringAspect *modelNameObj, LLMCore::Provider *provider); void resetPageToDefaults(); - - void updateStatusIndicators(); - void setIndicatorStatus(Utils::StringAspect &indicator, const QString &tooltip, bool isValid); - - void setCurrentFimProvider(const QString &name); - void setCurrentChatProvider(const QString &name); - - void loadProviders(); - void loadPrompts(); }; GeneralSettings &generalSettings(); diff --git a/settings/PresetPromptsSettings.cpp b/settings/PresetPromptsSettings.cpp index 861dd1a..6c2a1b6 100644 --- a/settings/PresetPromptsSettings.cpp +++ b/settings/PresetPromptsSettings.cpp @@ -24,7 +24,6 @@ #include #include -#include "RequestType.hpp" #include "SettingsConstants.hpp" #include "SettingsTr.hpp" #include "SettingsUtils.hpp" @@ -193,9 +192,8 @@ PresetPromptsSettings::PresetPromptsSettings() PresetPromptsSettings::PromptSettings PresetPromptsSettings::getSettings(int type) const { - auto reqtype = static_cast(type); PromptSettings settings; - if (reqtype == LLMCore::RequestType::Fim) { + if (type == 0) { settings.temperature = fimTemperature(); settings.maxTokens = fimMaxTokens(); settings.useTopP = fimUseTopP(); @@ -208,7 +206,7 @@ PresetPromptsSettings::PromptSettings PresetPromptsSettings::getSettings(int typ settings.frequencyPenalty = fimFrequencyPenalty(); settings.ollamaLivetime = fimOllamaLivetime(); settings.apiKey = fimApiKey(); - } else if (reqtype == LLMCore::RequestType::Chat) { + } else if (type = 1) { settings.temperature = chatTemperature(); settings.maxTokens = chatMaxTokens(); settings.useTopP = chatUseTopP(); diff --git a/settings/SettingsConstants.hpp b/settings/SettingsConstants.hpp index 0f7d573..1c66d3e 100644 --- a/settings/SettingsConstants.hpp +++ b/settings/SettingsConstants.hpp @@ -24,6 +24,17 @@ namespace QodeAssist::Constants { const char ACTION_ID[] = "QodeAssist.Action"; const char MENU_ID[] = "QodeAssist.Menu"; +// new settings +const char CC_PROVIDER[] = "QodeAssist.ccProvider"; +const char CC_MODEL[] = "QodeAssist.ccModel"; +const char CC_TEMPLATE[] = "QodeAssist.ccTemplate"; +const char CC_URL[] = "QodeAssist.ccUrl"; + +const char CA_PROVIDER[] = "QodeAssist.caProvider"; +const char CA_MODEL[] = "QodeAssist.caModel"; +const char CA_TEMPLATE[] = "QodeAssist.caTemplate"; +const char CA_URL[] = "QodeAssist.caUrl"; + // settings const char ENABLE_QODE_ASSIST[] = "QodeAssist.enableQodeAssist"; const char ENABLE_AUTO_COMPLETE[] = "QodeAssist.enableAutoComplete"; diff --git a/settings/SettingsTr.hpp b/settings/SettingsTr.hpp index ec2b40f..a47b279 100644 --- a/settings/SettingsTr.hpp +++ b/settings/SettingsTr.hpp @@ -23,6 +23,27 @@ namespace QodeAssist::Settings { +namespace TrConstants { +inline const char *ENABLE_QODE_ASSIST = QT_TRANSLATE_NOOP("QtC::QodeAssist", "Enable Qode Assist"); +inline const char *GENERAL = QT_TRANSLATE_NOOP("QtC::QodeAssist", "General"); +inline const char *RESET_TO_DEFAULTS = QT_TRANSLATE_NOOP("QtC::QodeAssist", + "Reset Page to Defaults"); +inline const char *SELECT = QT_TRANSLATE_NOOP("QtC::QodeAssist", "Select..."); +inline const char *PROVIDER = QT_TRANSLATE_NOOP("QtC::QodeAssist", "Provider:"); +inline const char *MODEL = QT_TRANSLATE_NOOP("QtC::QodeAssist", "Model:"); +inline const char *TEMPLATE = QT_TRANSLATE_NOOP("QtC::QodeAssist", "Template:"); +inline const char *URL = QT_TRANSLATE_NOOP("QtC::QodeAssist", "URL:"); +inline const char *STATUS = QT_TRANSLATE_NOOP("QtC::QodeAssist", "Status:"); +inline const char *TEST = QT_TRANSLATE_NOOP("QtC::QodeAssist", "Test"); +inline const char *ENABLE_LOG = QT_TRANSLATE_NOOP("QtC::QodeAssist", "Enable Logging"); +inline const char *CODE_COMPLETION = QT_TRANSLATE_NOOP("QtC::QodeAssist", "Code Completion"); +inline const char *CHAT_ASSISTANT = QT_TRANSLATE_NOOP("QtC::QodeAssist", "Chat Assistant"); +inline const char *RESET_SETTINGS = QT_TRANSLATE_NOOP("QtC::QodeAssist", "Reset Settings"); +inline const char *CONFIRMATION + = QT_TRANSLATE_NOOP("QtC::QodeAssist", + "Are you sure you want to reset all settings to default values?"); +} // namespace TrConstants + struct Tr { Q_DECLARE_TR_FUNCTIONS(QtC::QodeAssist) diff --git a/settings/SettingsUtils.hpp b/settings/SettingsUtils.hpp index 2761ec2..bca8115 100644 --- a/settings/SettingsUtils.hpp +++ b/settings/SettingsUtils.hpp @@ -67,4 +67,15 @@ void resetAspect(AspectType &aspect) aspect.setVolatileValue(aspect.defaultValue()); } +inline void initStringAspect(Utils::StringAspect &aspect, + const Utils::Key &settingsKey, + const QString &labelText, + const QString &defaultValue) +{ + aspect.setSettingsKey(settingsKey); + aspect.setLabelText(labelText); + aspect.setDisplayStyle(Utils::StringAspect::LineEditDisplay); + aspect.setDefaultValue(defaultValue); +} + } // namespace QodeAssist::Settings