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

View File

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

View File

@ -26,6 +26,7 @@
#include <vector>
using namespace Qt::Literals::StringLiterals;
using namespace ToolEnums;
// used only for settings serialization, do not translate
static const QStringList suggestionModeNames { "LocalDocsOnly", "On", "Off" };
@ -47,22 +48,26 @@ static const QString languageAndLocale = "System Locale";
} // namespace defaults
static const QVariantMap basicDefaults {
{ "chatTheme", QVariant::fromValue(ChatTheme::Light) },
{ "fontSize", QVariant::fromValue(FontSize::Small) },
{ "lastVersionStarted", "" },
{ "networkPort", 4891, },
{ "saveChatsContext", false },
{ "serverChat", false },
{ "userDefaultModel", "Application default" },
{ "suggestionMode", QVariant::fromValue(SuggestionMode::SourceExcerptsOnly) },
{ "localdocs/chunkSize", 512 },
{ "localdocs/retrievalSize", 3 },
{ "localdocs/showReferences", true },
{ "localdocs/fileExtensions", QStringList { "txt", "pdf", "md", "rst" } },
{ "localdocs/useRemoteEmbed", false },
{ "localdocs/nomicAPIKey", "" },
{ "localdocs/embedDevice", "Auto" },
{ "network/attribution", "" },
{ "chatTheme", QVariant::fromValue(ChatTheme::Light) },
{ "fontSize", QVariant::fromValue(FontSize::Small) },
{ "lastVersionStarted", "" },
{ "networkPort", 4891, },
{ "saveChatsContext", false },
{ "serverChat", false },
{ "userDefaultModel", "Application default" },
{ "suggestionMode", QVariant::fromValue(SuggestionMode::SourceExcerptsOnly) },
{ "localdocs/chunkSize", 512 },
{ "localdocs/retrievalSize", 3 },
{ "localdocs/showReferences", true },
{ "localdocs/fileExtensions", QStringList { "txt", "pdf", "md", "rst" } },
{ "localdocs/useRemoteEmbed", false },
{ "localdocs/nomicAPIKey", "" },
{ "localdocs/embedDevice", "Auto" },
{ "network/attribution", "" },
{ "websearch/usageMode", QVariant::fromValue(UsageMode::Disabled) },
{ "websearch/retrievalSize", 2 },
{ "websearch/askBeforeRunning", false },
{ "bravesearch/APIKey", "" },
};
static QString defaultLocalModelsPath()
@ -230,6 +235,14 @@ void MySettings::restoreLocalDocsDefaults()
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)
{
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::networkAttribution() const { return getBasicSetting("network/attribution" ).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)); }
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::setNetworkAttribution(const QString &value) { setBasicSetting("network/attribution", value, "networkAttribution"); }
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::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();
for (int i = 0; i < c; ++i) {
Tool *t = ToolModel::globalInstance()->get(i);
if (t->usageMode() == ToolEnums::UsageMode::Enabled)
if (t->usageMode() == UsageMode::Enabled)
toolList.push_back(t->jinjaValue());
}
params.insert({"toolList", toolList});

View File

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

View File

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

View File

@ -255,13 +255,14 @@ MySettingsTab {
MySettingsLabel {
id: chunkLabel
Layout.fillWidth: true
text: qsTr("Document snippet size (characters)")
helpText: qsTr("Number of characters per document snippet. Larger numbers increase likelihood of factual responses, but also result in slower generation.")
text: qsTr("Document excerpt size (characters)")
helpText: qsTr("Number of characters per document excerpt. Larger numbers increase likelihood of factual responses, but also result in slower generation.")
}
MyTextField {
id: chunkSizeTextField
text: MySettings.localDocsChunkSize
font.pixelSize: theme.fontSizeLarge
validator: IntValidator {
bottom: 1
}
@ -281,13 +282,14 @@ MySettingsTab {
Layout.topMargin: 15
MySettingsLabel {
id: contextItemsPerPrompt
text: qsTr("Max document snippets 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.")
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.localDocsRetrievalSize
font.pixelSize: theme.fontSizeLarge
validator: IntValidator {
bottom: 1
}

View File

@ -11,7 +11,7 @@ import network
MySettingsTab {
onRestoreDefaultsClicked: {
MySettings.restoreLocalDocsDefaults();
MySettings.restoreWebSearchDefaults();
}
showRestoreDefaultsButton: true
@ -52,14 +52,24 @@ MySettingsTab {
model: ListModel {
ListElement { name: qsTr("Never") }
ListElement { name: qsTr("Model decides") }
ListElement { name: qsTr("Ask for confirmation before executing") }
ListElement { name: qsTr("Force usage for every response when possible") }
ListElement { name: qsTr("Force usage for every response where possible") }
}
function updateModel() {
usageModeBox.currentIndex = MySettings.webSearchUsageMode;
}
Accessible.name: usageModeLabel.text
Accessible.description: usageModeLabel.helpText
onActivated: {
MySettings.webSearchUsageMode = usageModeBox.currentIndex;
}
Component.onCompleted: {
usageModeBox.updateModel();
}
Connections {
target: MySettings
function onWebSearchUsageModeChanged() {
usageModeBox.updateModel();
}
}
}
}
@ -74,6 +84,7 @@ MySettingsTab {
MyTextField {
id: apiKeyField
enabled: usageModeBox.currentIndex !== 0
text: MySettings.braveSearchAPIKey
color: theme.textColor
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 {
Layout.topMargin: 15
Layout.fillWidth: true

View File

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