Implement all the settings for the web search.

Signed-off-by: Adam Treat <treat.adam@gmail.com>
This commit is contained in:
Adam Treat 2024-08-14 16:19:28 -04:00
parent 054ca43d52
commit 3a564688b1
8 changed files with 134 additions and 34 deletions

View File

@ -17,11 +17,18 @@
using namespace Qt::Literals::StringLiterals; using namespace Qt::Literals::StringLiterals;
BraveSearch::BraveSearch()
: Tool(), m_error(ToolEnums::Error::NoError)
{
connect(MySettings::globalInstance(), &MySettings::webSearchUsageModeChanged,
this, &Tool::usageModeChanged);
}
QString BraveSearch::run(const QJsonObject &parameters, qint64 timeout) QString BraveSearch::run(const QJsonObject &parameters, qint64 timeout)
{ {
const QString apiKey = MySettings::globalInstance()->braveSearchAPIKey(); const QString apiKey = MySettings::globalInstance()->braveSearchAPIKey();
const QString query = parameters["query"].toString(); const QString query = parameters["query"].toString();
const int count = 2; // FIXME: This should be a setting const int count = MySettings::globalInstance()->webSearchRetrievalSize();
QThread workerThread; QThread workerThread;
BraveAPIWorker worker; BraveAPIWorker worker;
worker.moveToThread(&workerThread); worker.moveToThread(&workerThread);
@ -83,8 +90,7 @@ QJsonObject BraveSearch::exampleParams() const
ToolEnums::UsageMode BraveSearch::usageMode() const ToolEnums::UsageMode BraveSearch::usageMode() const
{ {
// FIXME: This needs to be a setting return MySettings::globalInstance()->webSearchUsageMode();
return ToolEnums::UsageMode::Enabled;
} }
void BraveAPIWorker::request(const QString &apiKey, const QString &query, int count) void BraveAPIWorker::request(const QString &apiKey, const QString &query, int count)

View File

@ -41,7 +41,7 @@ private:
class BraveSearch : public Tool { class BraveSearch : public Tool {
Q_OBJECT Q_OBJECT
public: public:
BraveSearch() : Tool(), m_error(ToolEnums::Error::NoError) {} BraveSearch();
virtual ~BraveSearch() {} virtual ~BraveSearch() {}
QString run(const QJsonObject &parameters, qint64 timeout = 2000) override; QString run(const QJsonObject &parameters, qint64 timeout = 2000) override;

View File

@ -26,6 +26,7 @@
#include <vector> #include <vector>
using namespace Qt::Literals::StringLiterals; using namespace Qt::Literals::StringLiterals;
using namespace ToolEnums;
// used only for settings serialization, do not translate // used only for settings serialization, do not translate
static const QStringList suggestionModeNames { "LocalDocsOnly", "On", "Off" }; static const QStringList suggestionModeNames { "LocalDocsOnly", "On", "Off" };
@ -47,22 +48,26 @@ static const QString languageAndLocale = "System Locale";
} // namespace defaults } // namespace defaults
static const QVariantMap basicDefaults { static const QVariantMap basicDefaults {
{ "chatTheme", QVariant::fromValue(ChatTheme::Light) }, { "chatTheme", QVariant::fromValue(ChatTheme::Light) },
{ "fontSize", QVariant::fromValue(FontSize::Small) }, { "fontSize", QVariant::fromValue(FontSize::Small) },
{ "lastVersionStarted", "" }, { "lastVersionStarted", "" },
{ "networkPort", 4891, }, { "networkPort", 4891, },
{ "saveChatsContext", false }, { "saveChatsContext", false },
{ "serverChat", false }, { "serverChat", false },
{ "userDefaultModel", "Application default" }, { "userDefaultModel", "Application default" },
{ "suggestionMode", QVariant::fromValue(SuggestionMode::SourceExcerptsOnly) }, { "suggestionMode", QVariant::fromValue(SuggestionMode::SourceExcerptsOnly) },
{ "localdocs/chunkSize", 512 }, { "localdocs/chunkSize", 512 },
{ "localdocs/retrievalSize", 3 }, { "localdocs/retrievalSize", 3 },
{ "localdocs/showReferences", true }, { "localdocs/showReferences", true },
{ "localdocs/fileExtensions", QStringList { "txt", "pdf", "md", "rst" } }, { "localdocs/fileExtensions", QStringList { "txt", "pdf", "md", "rst" } },
{ "localdocs/useRemoteEmbed", false }, { "localdocs/useRemoteEmbed", false },
{ "localdocs/nomicAPIKey", "" }, { "localdocs/nomicAPIKey", "" },
{ "localdocs/embedDevice", "Auto" }, { "localdocs/embedDevice", "Auto" },
{ "network/attribution", "" }, { "network/attribution", "" },
{ "websearch/usageMode", QVariant::fromValue(UsageMode::Disabled) },
{ "websearch/retrievalSize", 2 },
{ "websearch/askBeforeRunning", false },
{ "bravesearch/APIKey", "" },
}; };
static QString defaultLocalModelsPath() static QString defaultLocalModelsPath()
@ -230,6 +235,14 @@ void MySettings::restoreLocalDocsDefaults()
setLocalDocsEmbedDevice(basicDefaults.value("localdocs/embedDevice").toString()); setLocalDocsEmbedDevice(basicDefaults.value("localdocs/embedDevice").toString());
} }
void MySettings::restoreWebSearchDefaults()
{
setWebSearchUsageMode(basicDefaults.value("websearch/usageMode").value<UsageMode>());
setWebSearchRetrievalSize(basicDefaults.value("websearch/retrievalSize").toInt());
setWebSearchAskBeforeRunning(basicDefaults.value("websearch/askBeforeRunning").toBool());
setBraveSearchAPIKey(basicDefaults.value("bravesearch/APIKey").toString());
}
void MySettings::eraseModel(const ModelInfo &info) void MySettings::eraseModel(const ModelInfo &info)
{ {
m_settings.remove(u"model-%1"_s.arg(info.id())); m_settings.remove(u"model-%1"_s.arg(info.id()));
@ -467,6 +480,9 @@ QString MySettings::localDocsNomicAPIKey() const { return getBasicSetting
QString MySettings::localDocsEmbedDevice() const { return getBasicSetting("localdocs/embedDevice" ).toString(); } QString MySettings::localDocsEmbedDevice() const { return getBasicSetting("localdocs/embedDevice" ).toString(); }
QString MySettings::networkAttribution() const { return getBasicSetting("network/attribution" ).toString(); } QString MySettings::networkAttribution() const { return getBasicSetting("network/attribution" ).toString(); }
QString MySettings::braveSearchAPIKey() const { return getBasicSetting("bravesearch/APIKey" ).toString(); } QString MySettings::braveSearchAPIKey() const { return getBasicSetting("bravesearch/APIKey" ).toString(); }
int MySettings::webSearchRetrievalSize() const { return getBasicSetting("websearch/retrievalSize").toInt(); }
bool MySettings::webSearchAskBeforeRunning() const { return getBasicSetting("websearch/askBeforeRunning").toBool(); }
UsageMode MySettings::webSearchUsageMode() const { return getBasicSetting("websearch/usageMode").value<UsageMode>(); }
ChatTheme MySettings::chatTheme() const { return ChatTheme (getEnumSetting("chatTheme", chatThemeNames)); } ChatTheme MySettings::chatTheme() const { return ChatTheme (getEnumSetting("chatTheme", chatThemeNames)); }
FontSize MySettings::fontSize() const { return FontSize (getEnumSetting("fontSize", fontSizeNames)); } FontSize MySettings::fontSize() const { return FontSize (getEnumSetting("fontSize", fontSizeNames)); }
@ -486,6 +502,9 @@ void MySettings::setLocalDocsNomicAPIKey(const QString &value) { setBasic
void MySettings::setLocalDocsEmbedDevice(const QString &value) { setBasicSetting("localdocs/embedDevice", value, "localDocsEmbedDevice"); } void MySettings::setLocalDocsEmbedDevice(const QString &value) { setBasicSetting("localdocs/embedDevice", value, "localDocsEmbedDevice"); }
void MySettings::setNetworkAttribution(const QString &value) { setBasicSetting("network/attribution", value, "networkAttribution"); } void MySettings::setNetworkAttribution(const QString &value) { setBasicSetting("network/attribution", value, "networkAttribution"); }
void MySettings::setBraveSearchAPIKey(const QString &value) { setBasicSetting("bravesearch/APIKey", value, "braveSearchAPIKey"); } void MySettings::setBraveSearchAPIKey(const QString &value) { setBasicSetting("bravesearch/APIKey", value, "braveSearchAPIKey"); }
void MySettings::setWebSearchUsageMode(ToolEnums::UsageMode value) { setBasicSetting("websearch/usageMode", int(value), "webSearchUsageMode"); }
void MySettings::setWebSearchRetrievalSize(int value) { setBasicSetting("websearch/retrievalSize", value, "webSearchRetrievalSize"); }
void MySettings::setWebSearchAskBeforeRunning(bool value) { setBasicSetting("websearch/askBeforeRunning", value, "webSearchAskBeforeRunning"); }
void MySettings::setChatTheme(ChatTheme value) { setBasicSetting("chatTheme", chatThemeNames .value(int(value))); } void MySettings::setChatTheme(ChatTheme value) { setBasicSetting("chatTheme", chatThemeNames .value(int(value))); }
void MySettings::setFontSize(FontSize value) { setBasicSetting("fontSize", fontSizeNames .value(int(value))); } void MySettings::setFontSize(FontSize value) { setBasicSetting("fontSize", fontSizeNames .value(int(value))); }
@ -701,7 +720,7 @@ QString MySettings::systemPromptInternal(const QString &proposedTemplate, QStrin
int c = ToolModel::globalInstance()->count(); int c = ToolModel::globalInstance()->count();
for (int i = 0; i < c; ++i) { for (int i = 0; i < c; ++i) {
Tool *t = ToolModel::globalInstance()->get(i); Tool *t = ToolModel::globalInstance()->get(i);
if (t->usageMode() == ToolEnums::UsageMode::Enabled) if (t->usageMode() == UsageMode::Enabled)
toolList.push_back(t->jinjaValue()); toolList.push_back(t->jinjaValue());
} }
params.insert({"toolList", toolList}); params.insert({"toolList", toolList});

View File

@ -2,6 +2,7 @@
#define MYSETTINGS_H #define MYSETTINGS_H
#include "modellist.h" // IWYU pragma: keep #include "modellist.h" // IWYU pragma: keep
#include "tool.h"
#include <QDateTime> #include <QDateTime>
#include <QObject> #include <QObject>
@ -72,6 +73,9 @@ class MySettings : public QObject
Q_PROPERTY(int networkPort READ networkPort WRITE setNetworkPort NOTIFY networkPortChanged) Q_PROPERTY(int networkPort READ networkPort WRITE setNetworkPort NOTIFY networkPortChanged)
Q_PROPERTY(SuggestionMode suggestionMode READ suggestionMode WRITE setSuggestionMode NOTIFY suggestionModeChanged) Q_PROPERTY(SuggestionMode suggestionMode READ suggestionMode WRITE setSuggestionMode NOTIFY suggestionModeChanged)
Q_PROPERTY(QStringList uiLanguages MEMBER m_uiLanguages CONSTANT) Q_PROPERTY(QStringList uiLanguages MEMBER m_uiLanguages CONSTANT)
Q_PROPERTY(ToolEnums::UsageMode webSearchUsageMode READ webSearchUsageMode WRITE setWebSearchUsageMode NOTIFY webSearchUsageModeChanged)
Q_PROPERTY(int webSearchRetrievalSize READ webSearchRetrievalSize WRITE setWebSearchRetrievalSize NOTIFY webSearchRetrievalSizeChanged)
Q_PROPERTY(bool webSearchAskBeforeRunning READ webSearchAskBeforeRunning WRITE setWebSearchAskBeforeRunning NOTIFY webSearchAskBeforeRunningChanged)
Q_PROPERTY(QString braveSearchAPIKey READ braveSearchAPIKey WRITE setBraveSearchAPIKey NOTIFY braveSearchAPIKeyChanged) Q_PROPERTY(QString braveSearchAPIKey READ braveSearchAPIKey WRITE setBraveSearchAPIKey NOTIFY braveSearchAPIKeyChanged)
public: public:
@ -81,6 +85,7 @@ public:
Q_INVOKABLE void restoreModelDefaults(const ModelInfo &info); Q_INVOKABLE void restoreModelDefaults(const ModelInfo &info);
Q_INVOKABLE void restoreApplicationDefaults(); Q_INVOKABLE void restoreApplicationDefaults();
Q_INVOKABLE void restoreLocalDocsDefaults(); Q_INVOKABLE void restoreLocalDocsDefaults();
Q_INVOKABLE void restoreWebSearchDefaults();
// Model/Character settings // Model/Character settings
void eraseModel(const ModelInfo &info); void eraseModel(const ModelInfo &info);
@ -188,7 +193,13 @@ public:
QString localDocsEmbedDevice() const; QString localDocsEmbedDevice() const;
void setLocalDocsEmbedDevice(const QString &value); void setLocalDocsEmbedDevice(const QString &value);
// Tool settings // Web search settings
ToolEnums::UsageMode webSearchUsageMode() const;
void setWebSearchUsageMode(ToolEnums::UsageMode value);
int webSearchRetrievalSize() const;
void setWebSearchRetrievalSize(int value);
bool webSearchAskBeforeRunning() const;
void setWebSearchAskBeforeRunning(bool value);
QString braveSearchAPIKey() const; QString braveSearchAPIKey() const;
void setBraveSearchAPIKey(const QString &value); void setBraveSearchAPIKey(const QString &value);
@ -251,6 +262,9 @@ Q_SIGNALS:
void deviceChanged(); void deviceChanged();
void suggestionModeChanged(); void suggestionModeChanged();
void languageAndLocaleChanged(); void languageAndLocaleChanged();
void webSearchUsageModeChanged();
void webSearchRetrievalSizeChanged() const;
void webSearchAskBeforeRunningChanged() const;
void braveSearchAPIKeyChanged(); void braveSearchAPIKeyChanged();
private: private:
@ -274,7 +288,6 @@ private:
bool signal = false); bool signal = false);
QString filePathForLocale(const QLocale &locale); QString filePathForLocale(const QLocale &locale);
QString systemPromptInternal(const QString &proposedTemplate, QString &error); QString systemPromptInternal(const QString &proposedTemplate, QString &error);
}; };
#endif // MYSETTINGS_H #endif // MYSETTINGS_H

View File

@ -354,13 +354,22 @@ MySettingsTab {
ListElement { name: qsTr("Whenever possible") } ListElement { name: qsTr("Whenever possible") }
ListElement { name: qsTr("Never") } ListElement { name: qsTr("Never") }
} }
function updateModel() {
suggestionModeBox.currentIndex = MySettings.suggestionMode;
}
Accessible.name: suggestionModeLabel.text Accessible.name: suggestionModeLabel.text
Accessible.description: suggestionModeLabel.helpText Accessible.description: suggestionModeLabel.helpText
onActivated: { onActivated: {
MySettings.suggestionMode = suggestionModeBox.currentIndex; MySettings.suggestionMode = suggestionModeBox.currentIndex;
} }
Component.onCompleted: { Component.onCompleted: {
suggestionModeBox.currentIndex = MySettings.suggestionMode; suggestionModeBox.updateModel();
}
Connections {
target: MySettings
function onSuggestionModeChanged() {
suggestionModeBox.updateModel();
}
} }
} }
MySettingsLabel { MySettingsLabel {

View File

@ -255,13 +255,14 @@ MySettingsTab {
MySettingsLabel { MySettingsLabel {
id: chunkLabel id: chunkLabel
Layout.fillWidth: true Layout.fillWidth: true
text: qsTr("Document snippet size (characters)") text: qsTr("Document excerpt size (characters)")
helpText: qsTr("Number of characters per document snippet. Larger numbers increase likelihood of factual responses, but also result in slower generation.") helpText: qsTr("Number of characters per document excerpt. Larger numbers increase likelihood of factual responses, but also result in slower generation.")
} }
MyTextField { MyTextField {
id: chunkSizeTextField id: chunkSizeTextField
text: MySettings.localDocsChunkSize text: MySettings.localDocsChunkSize
font.pixelSize: theme.fontSizeLarge
validator: IntValidator { validator: IntValidator {
bottom: 1 bottom: 1
} }
@ -281,13 +282,14 @@ MySettingsTab {
Layout.topMargin: 15 Layout.topMargin: 15
MySettingsLabel { MySettingsLabel {
id: contextItemsPerPrompt id: contextItemsPerPrompt
text: qsTr("Max document snippets per prompt") text: qsTr("Max source excerpts per prompt")
helpText: qsTr("Max best N matches of retrieved document snippets to add to the context for prompt. Larger numbers increase likelihood of factual responses, but also result in slower generation.") helpText: qsTr("Max best N matches of retrieved source excerpts to add to the context for prompt. Larger numbers increase likelihood of factual responses, but also result in slower generation.")
} }
MyTextField { MyTextField {
text: MySettings.localDocsRetrievalSize text: MySettings.localDocsRetrievalSize
font.pixelSize: theme.fontSizeLarge
validator: IntValidator { validator: IntValidator {
bottom: 1 bottom: 1
} }

View File

@ -11,7 +11,7 @@ import network
MySettingsTab { MySettingsTab {
onRestoreDefaultsClicked: { onRestoreDefaultsClicked: {
MySettings.restoreLocalDocsDefaults(); MySettings.restoreWebSearchDefaults();
} }
showRestoreDefaultsButton: true showRestoreDefaultsButton: true
@ -52,14 +52,24 @@ MySettingsTab {
model: ListModel { model: ListModel {
ListElement { name: qsTr("Never") } ListElement { name: qsTr("Never") }
ListElement { name: qsTr("Model decides") } ListElement { name: qsTr("Model decides") }
ListElement { name: qsTr("Ask for confirmation before executing") } ListElement { name: qsTr("Force usage for every response where possible") }
ListElement { name: qsTr("Force usage for every response when possible") } }
function updateModel() {
usageModeBox.currentIndex = MySettings.webSearchUsageMode;
} }
Accessible.name: usageModeLabel.text Accessible.name: usageModeLabel.text
Accessible.description: usageModeLabel.helpText Accessible.description: usageModeLabel.helpText
onActivated: { onActivated: {
MySettings.webSearchUsageMode = usageModeBox.currentIndex;
} }
Component.onCompleted: { Component.onCompleted: {
usageModeBox.updateModel();
}
Connections {
target: MySettings
function onWebSearchUsageModeChanged() {
usageModeBox.updateModel();
}
} }
} }
} }
@ -74,6 +84,7 @@ MySettingsTab {
MyTextField { MyTextField {
id: apiKeyField id: apiKeyField
enabled: usageModeBox.currentIndex !== 0
text: MySettings.braveSearchAPIKey text: MySettings.braveSearchAPIKey
color: theme.textColor color: theme.textColor
font.pixelSize: theme.fontSizeLarge font.pixelSize: theme.fontSizeLarge
@ -89,6 +100,46 @@ MySettingsTab {
} }
} }
RowLayout {
MySettingsLabel {
id: contextItemsPerPrompt
text: qsTr("Max source excerpts per prompt")
helpText: qsTr("Max best N matches of retrieved source excerpts to add to the context for prompt. Larger numbers increase likelihood of factual responses, but also result in slower generation.")
}
MyTextField {
text: MySettings.webSearchRetrievalSize
font.pixelSize: theme.fontSizeLarge
validator: IntValidator {
bottom: 1
}
onEditingFinished: {
var val = parseInt(text)
if (!isNaN(val)) {
MySettings.webSearchRetrievalSize = val
focus = false
} else {
text = MySettings.webSearchRetrievalSize
}
}
}
}
RowLayout {
MySettingsLabel {
id: askBeforeRunningLabel
text: qsTr("Ask before running")
helpText: qsTr("The user is queried whether they want the tool to run in every instance")
}
MyCheckBox {
id: askBeforeRunningBox
checked: MySettings.webSearchAskBeforeRunning
onClicked: {
MySettings.webSearchAskBeforeRunning = !MySettings.webSearchAskBeforeRunning
}
}
}
Rectangle { Rectangle {
Layout.topMargin: 15 Layout.topMargin: 15
Layout.fillWidth: true Layout.fillWidth: true

View File

@ -17,9 +17,9 @@ namespace ToolEnums {
Q_ENUM_NS(Error) Q_ENUM_NS(Error)
enum class UsageMode { enum class UsageMode {
Disabled, // Completely disabled Disabled = 0, // Completely disabled
Enabled, // Enabled and the model decides whether to run Enabled = 1, // Enabled and the model decides whether to run
ForceUsage, // Attempt to force usage of the tool rather than let the LLM decide. NOTE: Not always possible. ForceUsage = 2, // Attempt to force usage of the tool rather than let the LLM decide. NOTE: Not always possible.
}; };
Q_ENUM_NS(UsageMode) Q_ENUM_NS(UsageMode)