Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP Brave search tool #2737

Draft
wants to merge 30 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
f4fb3df
Brave search tool calling.
manyoso Jul 25, 2024
a71db10
Change the name to announce the beta.
manyoso Jul 25, 2024
1c9911a
Fix problem with only displaying one source for tool call excerpts.
manyoso Jul 25, 2024
c78c95a
Add the extra snippets to the source excerpts.
manyoso Jul 25, 2024
dda59a9
Fix the way we're injecting the context back into the model for web s…
manyoso Jul 27, 2024
d2ee235
Change the suggestion mode to turn on for tool calls by default.
manyoso Jul 27, 2024
b0578e2
Change the name to inc the beta.
manyoso Jul 27, 2024
b9684ff
Inc again for new beta.
manyoso Jul 28, 2024
7c7558e
Stop hardcoding the tool call checking and rely upon the format advoc…
manyoso Jul 30, 2024
fffd9f3
Refactor to handle errors in tool calling better and add source comme…
manyoso Jul 30, 2024
dfe3e95
Refactor the brave search and introduce an abstraction for tool calls.
manyoso Jul 31, 2024
01f67c7
Begin converting the localdocs to a tool.
manyoso Aug 1, 2024
27b86da
Serialize the source excerpts from and to pure json
manyoso Aug 1, 2024
5fc2ff8
Use parameters which is in keeping with other standard practices.
manyoso Aug 1, 2024
244b826
Implement error handling for tool calls.
manyoso Aug 7, 2024
cedba6c
Tool model.
manyoso Aug 8, 2024
f93b764
Move the usearch submodule to third_party dir.
manyoso Aug 10, 2024
00ecbb7
Add jinja third party dependency.
manyoso Aug 10, 2024
c3cfaff
Refactor and make use of jinja templates.
manyoso Aug 9, 2024
587dd55
Get rid of the name change now that 3.2.0 has been released.
manyoso Aug 13, 2024
227dbfd
Use an enum for tool usage mode.
manyoso Aug 13, 2024
48117cd
Move the jinja processing to mysettings and validation.
manyoso Aug 13, 2024
a673087
Move to a brave search specific settings page.
manyoso Aug 13, 2024
f118720
Don't advertise brave.
manyoso Aug 14, 2024
75dbf9d
Handle the forced usage of tool calls outside of the recursive prompt…
manyoso Aug 14, 2024
991afc6
Abstract the built-in web search completely away from ChatLLM.
manyoso Aug 14, 2024
4cb9569
Breakout the ask before running which can be thought of as a security…
manyoso Aug 14, 2024
054ca43
Display the antenna by introducing notion of privacy scopes to tools.
manyoso Aug 14, 2024
3a56468
Implement all the settings for the web search.
manyoso Aug 14, 2024
4ae6acd
Force tool usage and refactor.
manyoso Aug 15, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Implement all the settings for the web search.
Signed-off-by: Adam Treat <[email protected]>
  • Loading branch information
manyoso committed Aug 14, 2024
commit 3a564688b1fa23ab4240737c7f1cda37ed4b462c
12 changes: 9 additions & 3 deletions gpt4all-chat/bravesearch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion gpt4all-chat/bravesearch.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ private Q_SLOTS:
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;
Expand Down
53 changes: 36 additions & 17 deletions gpt4all-chat/mysettings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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" };
Expand All @@ -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()
Expand Down Expand Up @@ -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()));
Expand Down Expand Up @@ -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)); }
Expand All @@ -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))); }
Expand Down Expand Up @@ -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});
Expand Down
17 changes: 15 additions & 2 deletions gpt4all-chat/mysettings.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#define MYSETTINGS_H

#include "modellist.h" // IWYU pragma: keep
#include "tool.h"

#include <QDateTime>
#include <QObject>
Expand Down Expand Up @@ -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:
Expand All @@ -81,6 +85,7 @@ class MySettings : public QObject
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);
Expand Down Expand Up @@ -188,7 +193,13 @@ class MySettings : public QObject
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);

Expand Down Expand Up @@ -251,6 +262,9 @@ class MySettings : public QObject
void deviceChanged();
void suggestionModeChanged();
void languageAndLocaleChanged();
void webSearchUsageModeChanged();
void webSearchRetrievalSizeChanged() const;
void webSearchAskBeforeRunningChanged() const;
void braveSearchAPIKeyChanged();

private:
Expand All @@ -274,7 +288,6 @@ class MySettings : public QObject
bool signal = false);
QString filePathForLocale(const QLocale &locale);
QString systemPromptInternal(const QString &proposedTemplate, QString &error);

};

#endif // MYSETTINGS_H
11 changes: 10 additions & 1 deletion gpt4all-chat/qml/ApplicationSettings.qml
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
10 changes: 6 additions & 4 deletions gpt4all-chat/qml/LocalDocsSettings.qml
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand All @@ -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
}
Expand Down
57 changes: 54 additions & 3 deletions gpt4all-chat/qml/WebSearchSettings.qml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import network

MySettingsTab {
onRestoreDefaultsClicked: {
MySettings.restoreLocalDocsDefaults();
MySettings.restoreWebSearchDefaults();
}

showRestoreDefaultsButton: true
Expand Down Expand Up @@ -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();
}
}
}
}
Expand All @@ -74,6 +84,7 @@ MySettingsTab {

MyTextField {
id: apiKeyField
enabled: usageModeBox.currentIndex !== 0
text: MySettings.braveSearchAPIKey
color: theme.textColor
font.pixelSize: theme.fontSizeLarge
Expand All @@ -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
Expand Down
6 changes: 3 additions & 3 deletions gpt4all-chat/tool.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down