Display the antenna by introducing notion of privacy scopes to tools.

Signed-off-by: Adam Treat <treat.adam@gmail.com>
This commit is contained in:
Adam Treat 2024-08-14 12:01:48 -04:00
parent 4cb95694ff
commit 054ca43d52
7 changed files with 47 additions and 2 deletions

View File

@ -51,6 +51,7 @@ public:
QString name() const override { return tr("Web Search"); }
QString description() const override { return tr("Search the web"); }
QString function() const override { return "web_search"; }
ToolEnums::PrivacyScope privacyScope() const override { return ToolEnums::PrivacyScope::None; }
QJsonObject paramSchema() const override;
QJsonObject exampleParams() const override;
bool isBuiltin() const override { return true; }

View File

@ -37,6 +37,7 @@ public:
QString name() const override { return tr("LocalDocs Search"); }
QString description() const override { return tr("Search the local docs"); }
QString function() const override { return "localdocs_search"; }
ToolEnums::PrivacyScope privacyScope() const override { return ToolEnums::PrivacyScope::Local; }
QJsonObject paramSchema() const override;
bool isBuiltin() const override { return true; }
ToolEnums::UsageMode usageMode() const override { return ToolEnums::UsageMode::ForceUsage; }

View File

@ -7,6 +7,7 @@
#include "modellist.h"
#include "mysettings.h"
#include "network.h"
#include "toolmodel.h"
#include "../gpt4all-backend/llmodel.h"
@ -67,6 +68,8 @@ int main(int argc, char *argv[])
qmlRegisterSingletonInstance("download", 1, 0, "Download", Download::globalInstance());
qmlRegisterSingletonInstance("network", 1, 0, "Network", Network::globalInstance());
qmlRegisterSingletonInstance("localdocs", 1, 0, "LocalDocs", LocalDocs::globalInstance());
qmlRegisterSingletonInstance("toollist", 1, 0, "ToolList", ToolModel::globalInstance());
qmlRegisterUncreatableMetaObject(ToolEnums::staticMetaObject, "toolenums", 1, 0, "ToolEnums", "Error: only enums");
qmlRegisterUncreatableMetaObject(MySettingsEnums::staticMetaObject, "mysettingsenums", 1, 0, "MySettingsEnums", "Error: only enums");
const QUrl url(u"qrc:/gpt4all/main.qml"_qs);

View File

@ -12,6 +12,8 @@ import network
import gpt4all
import localdocs
import mysettings
import toollist
import toolenums
Window {
id: window
@ -413,7 +415,11 @@ Window {
ColorOverlay {
id: antennaColored
visible: ModelList.selectableModels.count !== 0 && (currentChat.isServer || currentChat.modelInfo.isOnline || MySettings.networkIsActive)
visible: ModelList.selectableModels.count !== 0
&& (MySettings.networkIsActive
|| currentChat.modelInfo.isOnline
|| currentChat.isServer
|| ToolList.privacyScope === ToolEnums.PrivacyScope.None)
anchors.fill: antennaImage
source: antennaImage
color: theme.styledTextColor
@ -422,8 +428,10 @@ Window {
return qsTr("The datalake is enabled")
else if (currentChat.modelInfo.isOnline)
return qsTr("Using a network model")
else if (currentChat.modelInfo.isOnline)
else if (currentChat.isServer)
return qsTr("Server mode is enabled")
else if (ToolList.privacyScope === ToolEnums.PrivacyScope.None)
return qsTr("One or more enabled tools is not private")
return ""
}
ToolTip.visible: maAntenna.containsMouse

View File

@ -22,6 +22,14 @@ namespace ToolEnums {
ForceUsage, // Attempt to force usage of the tool rather than let the LLM decide. NOTE: Not always possible.
};
Q_ENUM_NS(UsageMode)
// Ordered in increasing levels of privacy
enum class PrivacyScope {
None = 0, // Tool call data does not have any privacy scope
LocalOrg = 1, // Tool call data does not leave the local organization
Local = 2 // Tool call data does not leave the machine
};
Q_ENUM_NS(PrivacyScope)
}
class Tool : public QObject {
@ -29,6 +37,7 @@ class Tool : public QObject {
Q_PROPERTY(QString name READ name CONSTANT)
Q_PROPERTY(QString description READ description CONSTANT)
Q_PROPERTY(QString function READ function CONSTANT)
Q_PROPERTY(ToolEnums::PrivacyScope privacyScope READ privacyScope CONSTANT)
Q_PROPERTY(QJsonObject paramSchema READ paramSchema CONSTANT)
Q_PROPERTY(QJsonObject exampleParams READ exampleParams CONSTANT)
Q_PROPERTY(QUrl url READ url CONSTANT)
@ -54,6 +63,9 @@ public:
// [Required] Must be unique. Name of the function to invoke. Must be a-z, A-Z, 0-9, or contain underscores and dashes, with a maximum length of 64.
virtual QString function() const = 0;
// [Required] The privacy scope
virtual ToolEnums::PrivacyScope privacyScope() const = 0;
// [Optional] Json schema describing the tool's parameters. An empty object specifies no parameters.
// https://json-schema.org/understanding-json-schema/
// https://platform.openai.com/docs/api-reference/runs/createRun#runs-createrun-tools

View File

@ -22,10 +22,12 @@ ToolModel::ToolModel()
Tool* localDocsSearch = new LocalDocsSearch;
m_tools.append(localDocsSearch);
m_toolMap.insert(localDocsSearch->function(), localDocsSearch);
connect(localDocsSearch, &Tool::usageModeChanged, this, &ToolModel::privacyScopeChanged);
Tool *braveSearch = new BraveSearch;
m_tools.append(braveSearch);
m_toolMap.insert(braveSearch->function(), braveSearch);
connect(braveSearch, &Tool::usageModeChanged, this, &ToolModel::privacyScopeChanged);
}
bool ToolModel::eventFilter(QObject *obj, QEvent *ev)
@ -34,3 +36,12 @@ bool ToolModel::eventFilter(QObject *obj, QEvent *ev)
emit dataChanged(index(0, 0), index(m_tools.size() - 1, 0));
return false;
}
ToolEnums::PrivacyScope ToolModel::privacyScope() const
{
ToolEnums::PrivacyScope scope = ToolEnums::PrivacyScope::Local; // highest scope
for (const Tool *t : m_tools)
if (t->usageMode() != ToolEnums::UsageMode::Disabled)
scope = std::min(scope, t->privacyScope());
return scope;
}

View File

@ -9,6 +9,7 @@ class ToolModel : public QAbstractListModel
{
Q_OBJECT
Q_PROPERTY(int count READ count NOTIFY countChanged)
Q_PROPERTY(ToolEnums::PrivacyScope privacyScope READ privacyScope NOTIFY privacyScopeChanged)
public:
static ToolModel *globalInstance();
@ -17,6 +18,7 @@ public:
NameRole = Qt::UserRole + 1,
DescriptionRole,
FunctionRole,
PrivacyScopeRole,
ParametersRole,
UrlRole,
ApiKeyRole,
@ -46,6 +48,8 @@ public:
return item->description();
case FunctionRole:
return item->function();
case PrivacyScopeRole:
return QVariant::fromValue(item->privacyScope());
case ParametersRole:
return item->paramSchema();
case UrlRole:
@ -69,6 +73,7 @@ public:
roles[NameRole] = "name";
roles[DescriptionRole] = "description";
roles[FunctionRole] = "function";
roles[PrivacyScopeRole] = "privacyScope";
roles[ParametersRole] = "parameters";
roles[UrlRole] = "url";
roles[ApiKeyRole] = "apiKey";
@ -94,8 +99,12 @@ public:
int count() const { return m_tools.size(); }
// Returns the least private scope of all enabled tools
ToolEnums::PrivacyScope privacyScope() const;
Q_SIGNALS:
void countChanged();
void privacyScopeChanged();
void valueChanged(int index, const QString &value);
protected: