diff --git a/QodeAssistUtils.hpp b/QodeAssistUtils.hpp index 4ad1267..63ab992 100644 --- a/QodeAssistUtils.hpp +++ b/QodeAssistUtils.hpp @@ -19,7 +19,12 @@ #pragma once +#include +#include +#include #include +#include +#include #include #include @@ -65,4 +70,36 @@ inline void logMessages(const QStringList &messages, bool silent = true) } } +inline bool pingUrl(const QUrl &url, int timeout = 5000) +{ + if (!url.isValid()) { + return false; + } + + QNetworkAccessManager manager; + QNetworkRequest request(url); + request.setAttribute(QNetworkRequest::RedirectPolicyAttribute, true); + + QScopedPointer reply(manager.get(request)); + + QTimer timer; + timer.setSingleShot(true); + + QEventLoop loop; + QObject::connect(reply.data(), &QNetworkReply::finished, &loop, &QEventLoop::quit); + QObject::connect(&timer, &QTimer::timeout, &loop, &QEventLoop::quit); + + timer.start(timeout); + loop.exec(); + + if (timer.isActive()) { + timer.stop(); + return (reply->error() == QNetworkReply::NoError); + } else { + QObject::disconnect(reply.data(), &QNetworkReply::finished, &loop, &QEventLoop::quit); + reply->abort(); + return false; + } +} + } // namespace QodeAssist diff --git a/settings/ContextSettings.cpp b/settings/ContextSettings.cpp index 5ff5d46..c76e902 100644 --- a/settings/ContextSettings.cpp +++ b/settings/ContextSettings.cpp @@ -61,7 +61,7 @@ ContextSettings::ContextSettings() useFilePathInContext.setLabelText(Tr::tr("Use File Path in Context")); useSpecificInstructions.setSettingsKey(Constants::USE_SPECIFIC_INSTRUCTIONS); - useSpecificInstructions.setDefaultValue(false); + useSpecificInstructions.setDefaultValue(true); useSpecificInstructions.setLabelText(Tr::tr("Use Specific Instructions")); specificInstractions.setSettingsKey(Constants::SPECIFIC_INSTRUCTIONS); @@ -134,10 +134,6 @@ void ContextSettings::resetPageToDefaults() resetAspect(useSpecificInstructions); resetAspect(specificInstractions); } - - QMessageBox::information(Core::ICore::dialogParent(), - Tr::tr("Settings Reset"), - Tr::tr("All settings have been reset to their default values.")); } class ContextSettingsPage : public Core::IOptionsPage diff --git a/settings/CustomPromptSettings.cpp b/settings/CustomPromptSettings.cpp index ee5ad78..4361efc 100644 --- a/settings/CustomPromptSettings.cpp +++ b/settings/CustomPromptSettings.cpp @@ -122,10 +122,6 @@ void CustomPromptSettings::resetSettingsToDefaults() if (reply == QMessageBox::Yes) { resetAspect(customJsonTemplate); } - - QMessageBox::information(Core::ICore::dialogParent(), - Tr::tr("Settings Reset"), - Tr::tr("All settings have been reset to their default values.")); } void CustomPromptSettings::saveCustomTemplate() diff --git a/settings/GeneralSettings.cpp b/settings/GeneralSettings.cpp index 7933965..25af1ec 100644 --- a/settings/GeneralSettings.cpp +++ b/settings/GeneralSettings.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include "LLMProvidersManager.hpp" #include "PromptTemplateManager.hpp" @@ -144,15 +145,17 @@ GeneralSettings::GeneralSettings() Space{8}, enableLogging, Space{8}, - llmProviders, - Row{url, endPoint}, + Row{llmProviders, Stretch{1}}, + Row{url, endPoint, urlIndicator}, Space{8}, - Row{selectModels, modelName}, + Row{selectModels, modelName, modelIndicator}, Space{8}, fimPrompts, Stretch{1}}; return rootLayout; }); + + updateStatusIndicators(); } void GeneralSettings::setupConnections() @@ -173,6 +176,15 @@ void GeneralSettings::setupConnections() 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); } void GeneralSettings::updateProviderSettings() @@ -182,6 +194,7 @@ void GeneralSettings::updateProviderSettings() if (provider) { url.setVolatileValue(provider->url()); endPoint.setVolatileValue(provider->completionEndpoint()); + modelName.setVolatileValue(""); } } @@ -233,10 +246,38 @@ void GeneralSettings::resetPageToDefaults() fimPrompts.setStringValue("StarCoder2"); llmProviders.setStringValue("Ollama"); + updateStatusIndicators(); +} - QMessageBox::information(Core::ICore::dialogParent(), - Tr::tr("Settings Reset"), - Tr::tr("All settings have been reset to their default values.")); +void GeneralSettings::updateStatusIndicators() +{ + bool urlValid = !url.volatileValue().isEmpty() && !endPoint.volatileValue().isEmpty(); + bool modelValid = !modelName.volatileValue().isEmpty(); + + bool pingSuccessful = false; + if (urlValid) { + QUrl pingUrl(url.volatileValue()); + pingSuccessful = QodeAssist::pingUrl(pingUrl); + } + + setIndicatorStatus(modelIndicator, + modelValid ? tr("Model is properly configured") + : tr("No model selected or model name is invalid"), + modelValid); + + setIndicatorStatus(urlIndicator, + pingSuccessful ? tr("Server is reachable") + : tr("Server is not reachable or URL is invalid"), + pingSuccessful); +} + +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); } class GeneralSettingsPage : public Core::IOptionsPage diff --git a/settings/GeneralSettings.hpp b/settings/GeneralSettings.hpp index d82da9c..709954e 100644 --- a/settings/GeneralSettings.hpp +++ b/settings/GeneralSettings.hpp @@ -47,11 +47,17 @@ class GeneralSettings : public Utils::AspectContainer Utils::SelectionAspect fimPrompts{this}; ButtonAspect resetToDefaults{this}; + Utils::StringAspect modelIndicator{this}; + Utils::StringAspect urlIndicator{this}; + private: void setupConnections(); void updateProviderSettings(); void showModelSelectionDialog(); void resetPageToDefaults(); + + void updateStatusIndicators(); + void setIndicatorStatus(Utils::StringAspect &indicator, const QString &tooltip, bool isValid); }; GeneralSettings &generalSettings(); diff --git a/settings/PresetPromptsSettings.cpp b/settings/PresetPromptsSettings.cpp index 89c8de5..897f555 100644 --- a/settings/PresetPromptsSettings.cpp +++ b/settings/PresetPromptsSettings.cpp @@ -45,6 +45,7 @@ PresetPromptsSettings::PresetPromptsSettings() temperature.setLabelText(Tr::tr("Temperature:")); temperature.setDefaultValue(0.2); temperature.setRange(0.0, 10.0); + temperature.setSingleStep(0.1); ollamaLivetime.setSettingsKey(Constants::OLLAMA_LIVETIME); ollamaLivetime.setLabelText( @@ -62,15 +63,16 @@ PresetPromptsSettings::PresetPromptsSettings() useTopP.setDefaultValue(false); topP.setSettingsKey(Constants::TOP_P); - topP.setLabelText(Tr::tr("top_p")); + topP.setLabelText(Tr::tr("use top_p")); topP.setDefaultValue(0.9); topP.setRange(0.0, 1.0); + topP.setSingleStep(0.1); useTopK.setSettingsKey(Constants::USE_TOP_K); useTopK.setDefaultValue(false); topK.setSettingsKey(Constants::TOP_K); - topK.setLabelText(Tr::tr("top_k")); + topK.setLabelText(Tr::tr("use top_k")); topK.setDefaultValue(50); topK.setRange(1, 1000); @@ -78,17 +80,19 @@ PresetPromptsSettings::PresetPromptsSettings() usePresencePenalty.setDefaultValue(false); presencePenalty.setSettingsKey(Constants::PRESENCE_PENALTY); - presencePenalty.setLabelText(Tr::tr("presence_penalty")); + presencePenalty.setLabelText(Tr::tr("use presence_penalty")); presencePenalty.setDefaultValue(0.0); presencePenalty.setRange(-2.0, 2.0); + presencePenalty.setSingleStep(0.1); useFrequencyPenalty.setSettingsKey(Constants::USE_FREQUENCY_PENALTY); useFrequencyPenalty.setDefaultValue(false); frequencyPenalty.setSettingsKey(Constants::FREQUENCY_PENALTY); - frequencyPenalty.setLabelText(Tr::tr("frequency_penalty")); + frequencyPenalty.setLabelText(Tr::tr("use frequency_penalty")); frequencyPenalty.setDefaultValue(0.0); frequencyPenalty.setRange(-2.0, 2.0); + frequencyPenalty.setSingleStep(0.1); apiKey.setSettingsKey(Constants::API_KEY); apiKey.setLabelText(Tr::tr("API Key:")); @@ -99,17 +103,12 @@ PresetPromptsSettings::PresetPromptsSettings() readSettings(); - topK.setEnabled(useTopK()); - topP.setEnabled(useTopP()); - presencePenalty.setEnabled(usePresencePenalty()); - frequencyPenalty.setEnabled(useFrequencyPenalty()); - setupConnections(); setLayouter([this]() { using namespace Layouting; return Column{Row{temperature, Stretch{1}, resetToDefaults}, - maxTokens, + Row{maxTokens, Stretch{1}}, Row{useTopP, topP, Stretch{1}}, Row{useTopK, topK, Stretch{1}}, Row{usePresencePenalty, presencePenalty, Stretch{1}}, @@ -121,19 +120,6 @@ PresetPromptsSettings::PresetPromptsSettings() void PresetPromptsSettings::setupConnections() { - connect(&useTopP, &Utils::BoolAspect::volatileValueChanged, this, [this]() { - topP.setEnabled(useTopP.volatileValue()); - }); - connect(&useTopK, &Utils::BoolAspect::volatileValueChanged, this, [this]() { - topK.setEnabled(useTopK.volatileValue()); - }); - connect(&usePresencePenalty, &Utils::BoolAspect::volatileValueChanged, this, [this]() { - presencePenalty.setEnabled(usePresencePenalty.volatileValue()); - }); - connect(&useFrequencyPenalty, &Utils::BoolAspect::volatileValueChanged, this, [this]() { - frequencyPenalty.setEnabled(useFrequencyPenalty.volatileValue()); - }); - connect(&resetToDefaults, &ButtonAspect::clicked, this, @@ -162,10 +148,6 @@ void PresetPromptsSettings::resetSettingsToDefaults() resetAspect(useFrequencyPenalty); resetAspect(frequencyPenalty); } - - QMessageBox::information(Core::ICore::dialogParent(), - Tr::tr("Settings Reset"), - Tr::tr("All settings have been reset to their default values.")); } class PresetPromptsSettingsPage : public Core::IOptionsPage