mirror of
https://github.com/nomic-ai/gpt4all.git
synced 2025-08-14 06:05:34 +00:00
Abstract the built-in web search completely away from ChatLLM.
Signed-off-by: Adam Treat <treat.adam@gmail.com>
This commit is contained in:
parent
75dbf9de7d
commit
991afc6ef2
@ -1,4 +1,5 @@
|
|||||||
#include "bravesearch.h"
|
#include "bravesearch.h"
|
||||||
|
#include "mysettings.h"
|
||||||
|
|
||||||
#include <QCoreApplication>
|
#include <QCoreApplication>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
@ -18,9 +19,9 @@ using namespace Qt::Literals::StringLiterals;
|
|||||||
|
|
||||||
QString BraveSearch::run(const QJsonObject ¶meters, qint64 timeout)
|
QString BraveSearch::run(const QJsonObject ¶meters, qint64 timeout)
|
||||||
{
|
{
|
||||||
const QString apiKey = parameters["apiKey"].toString();
|
const QString apiKey = MySettings::globalInstance()->braveSearchAPIKey();
|
||||||
const QString query = parameters["query"].toString();
|
const QString query = parameters["query"].toString();
|
||||||
const int count = parameters["count"].toInt();
|
const int count = 2; // FIXME: This should be a setting
|
||||||
QThread workerThread;
|
QThread workerThread;
|
||||||
BraveAPIWorker worker;
|
BraveAPIWorker worker;
|
||||||
worker.moveToThread(&workerThread);
|
worker.moveToThread(&workerThread);
|
||||||
|
@ -34,7 +34,7 @@ private Q_SLOTS:
|
|||||||
private:
|
private:
|
||||||
QNetworkAccessManager *m_networkManager;
|
QNetworkAccessManager *m_networkManager;
|
||||||
QString m_response;
|
QString m_response;
|
||||||
ToolEnums::Error m_error;
|
ToolEnums::Error m_error = ToolEnums::Error::NoError;
|
||||||
QString m_errorString;
|
QString m_errorString;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
#include "chatllm.h"
|
#include "chatllm.h"
|
||||||
|
|
||||||
#include "bravesearch.h"
|
|
||||||
#include "chat.h"
|
#include "chat.h"
|
||||||
#include "chatapi.h"
|
#include "chatapi.h"
|
||||||
#include "localdocssearch.h"
|
#include "localdocssearch.h"
|
||||||
@ -893,36 +892,31 @@ bool ChatLLM::promptRecursive(const QList<QString> &toolContexts, const QString
|
|||||||
const QString tool = toolCallDoc["name"].toString();
|
const QString tool = toolCallDoc["name"].toString();
|
||||||
const QJsonObject args = toolCallDoc["parameters"].toObject();
|
const QJsonObject args = toolCallDoc["parameters"].toObject();
|
||||||
|
|
||||||
// FIXME: In the future this will try to match the tool call to a list of tools that are supported
|
Tool *toolInstance = ToolModel::globalInstance()->get(tool);
|
||||||
// according to MySettings, but for now only brave search is supported
|
if (!toolInstance) {
|
||||||
if (tool != "web_search" || !args.contains("query")) {
|
qWarning() << "ERROR: Could not find the tool for " << toolCall;
|
||||||
// FIXME: Need to surface errors to the UI
|
|
||||||
qWarning() << "ERROR: Could not find the tool and correct parameters for " << toolCall;
|
|
||||||
return handleFailedToolCall(trimmed, totalTime);
|
return handleFailedToolCall(trimmed, totalTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
const QString query = args["query"].toString();
|
// Inform the chat that we're executing a tool call
|
||||||
|
emit toolCalled(toolInstance->name().toLower());
|
||||||
|
|
||||||
emit toolCalled(tr("searching web..."));
|
const QString response = toolInstance->run(args, 2000 /*msecs to timeout*/);
|
||||||
const QString apiKey = MySettings::globalInstance()->braveSearchAPIKey();
|
if (toolInstance->error() != ToolEnums::Error::NoError) {
|
||||||
Q_ASSERT(apiKey != "");
|
qWarning() << "ERROR: Tool call produced error:" << toolInstance->errorString();
|
||||||
BraveSearch brave;
|
return handleFailedToolCall(trimmed, totalTime);
|
||||||
|
}
|
||||||
|
|
||||||
QJsonObject parameters;
|
// If the tool supports excerpts then try to parse them here
|
||||||
parameters.insert("apiKey", apiKey);
|
if (toolInstance->excerpts()) {
|
||||||
parameters.insert("query", query);
|
QString parseError;
|
||||||
parameters.insert("count", 2);
|
QList<SourceExcerpt> sourceExcerpts = SourceExcerpt::fromJson(response, parseError);
|
||||||
|
if (!parseError.isEmpty()) {
|
||||||
// FIXME: Need to surface errors to the UI
|
qWarning() << "ERROR: Could not parse source excerpts for response:" << parseError;
|
||||||
const QString braveResponse = brave.run(parameters, 2000 /*msecs to timeout*/);
|
} else if (!sourceExcerpts.isEmpty()) {
|
||||||
|
producedSourceExcerpts = true;
|
||||||
QString parseError;
|
emit sourceExcerptsChanged(sourceExcerpts);
|
||||||
QList<SourceExcerpt> sourceExcerpts = SourceExcerpt::fromJson(braveResponse, parseError);
|
}
|
||||||
if (!parseError.isEmpty()) {
|
|
||||||
qWarning() << "ERROR: Could not parse source excerpts for brave response:" << parseError;
|
|
||||||
} else if (!sourceExcerpts.isEmpty()) {
|
|
||||||
producedSourceExcerpts = true;
|
|
||||||
emit sourceExcerptsChanged(sourceExcerpts);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_promptResponseTokens = 0;
|
m_promptResponseTokens = 0;
|
||||||
@ -931,7 +925,7 @@ bool ChatLLM::promptRecursive(const QList<QString> &toolContexts, const QString
|
|||||||
|
|
||||||
// This is a recursive call but isRecursiveCall is checked above to arrest infinite recursive
|
// This is a recursive call but isRecursiveCall is checked above to arrest infinite recursive
|
||||||
// tool calls
|
// tool calls
|
||||||
return promptRecursive(QList<QString>()/*collectionList*/, braveResponse, toolTemplate,
|
return promptRecursive(QList<QString>()/*tool context*/, response, toolTemplate,
|
||||||
n_predict, top_k, top_p, min_p, temp, n_batch, repeat_penalty, repeat_penalty_tokens, totalTime,
|
n_predict, top_k, top_p, min_p, temp, n_batch, repeat_penalty, repeat_penalty_tokens, totalTime,
|
||||||
producedSourceExcerpts, true /*isRecursiveCall*/);
|
producedSourceExcerpts, true /*isRecursiveCall*/);
|
||||||
} else {
|
} else {
|
||||||
@ -946,6 +940,7 @@ bool ChatLLM::promptRecursive(const QList<QString> &toolContexts, const QString
|
|||||||
|
|
||||||
bool ChatLLM::handleFailedToolCall(const std::string &response, qint64 elapsed)
|
bool ChatLLM::handleFailedToolCall(const std::string &response, qint64 elapsed)
|
||||||
{
|
{
|
||||||
|
// FIXME: Need to surface errors to the UI
|
||||||
// Restore the strings that we excluded previously when detecting the tool call
|
// Restore the strings that we excluded previously when detecting the tool call
|
||||||
m_response = "<tool_call>" + response + "</tool_call>";
|
m_response = "<tool_call>" + response + "</tool_call>";
|
||||||
emit responseChanged(QString::fromStdString(m_response));
|
emit responseChanged(QString::fromStdString(m_response));
|
||||||
|
@ -881,8 +881,8 @@ Rectangle {
|
|||||||
case Chat.PromptProcessing: return qsTr("processing ...")
|
case Chat.PromptProcessing: return qsTr("processing ...")
|
||||||
case Chat.ResponseGeneration: return qsTr("generating response ...");
|
case Chat.ResponseGeneration: return qsTr("generating response ...");
|
||||||
case Chat.GeneratingQuestions: return qsTr("generating questions ...");
|
case Chat.GeneratingQuestions: return qsTr("generating questions ...");
|
||||||
case Chat.ToolCalled: return currentChat.toolDescription;
|
case Chat.ToolCalled: return qsTr("executing %1 ...").arg(currentChat.toolDescription);
|
||||||
case Chat.ToolProcessing: return qsTr("processing web results ..."); // FIXME should not be hardcoded!
|
case Chat.ToolProcessing: return qsTr("processing %1 results ...").arg(currentChat.toolDescription);
|
||||||
default: return ""; // handle unexpected values
|
default: return ""; // handle unexpected values
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user