diff --git a/gpt4all-chat/bravesearch.cpp b/gpt4all-chat/bravesearch.cpp index 197ed383af5c..0a0ef8f9f138 100644 --- a/gpt4all-chat/bravesearch.cpp +++ b/gpt4all-chat/bravesearch.cpp @@ -1,4 +1,5 @@ #include "bravesearch.h" +#include "mysettings.h" #include #include @@ -18,9 +19,9 @@ using namespace Qt::Literals::StringLiterals; 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 int count = parameters["count"].toInt(); + const int count = 2; // FIXME: This should be a setting QThread workerThread; BraveAPIWorker worker; worker.moveToThread(&workerThread); diff --git a/gpt4all-chat/bravesearch.h b/gpt4all-chat/bravesearch.h index 872e230a95e3..0cf1118b1496 100644 --- a/gpt4all-chat/bravesearch.h +++ b/gpt4all-chat/bravesearch.h @@ -34,7 +34,7 @@ private Q_SLOTS: private: QNetworkAccessManager *m_networkManager; QString m_response; - ToolEnums::Error m_error; + ToolEnums::Error m_error = ToolEnums::Error::NoError; QString m_errorString; }; diff --git a/gpt4all-chat/chatllm.cpp b/gpt4all-chat/chatllm.cpp index 7450ab1fc402..d86de0d01c6a 100644 --- a/gpt4all-chat/chatllm.cpp +++ b/gpt4all-chat/chatllm.cpp @@ -1,6 +1,5 @@ #include "chatllm.h" -#include "bravesearch.h" #include "chat.h" #include "chatapi.h" #include "localdocssearch.h" @@ -893,36 +892,31 @@ bool ChatLLM::promptRecursive(const QList &toolContexts, const QString const QString tool = toolCallDoc["name"].toString(); 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 - // according to MySettings, but for now only brave search is supported - if (tool != "web_search" || !args.contains("query")) { - // FIXME: Need to surface errors to the UI - qWarning() << "ERROR: Could not find the tool and correct parameters for " << toolCall; + Tool *toolInstance = ToolModel::globalInstance()->get(tool); + if (!toolInstance) { + qWarning() << "ERROR: Could not find the tool for " << toolCall; 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 apiKey = MySettings::globalInstance()->braveSearchAPIKey(); - Q_ASSERT(apiKey != ""); - BraveSearch brave; - - QJsonObject parameters; - parameters.insert("apiKey", apiKey); - parameters.insert("query", query); - parameters.insert("count", 2); - - // FIXME: Need to surface errors to the UI - const QString braveResponse = brave.run(parameters, 2000 /*msecs to timeout*/); + const QString response = toolInstance->run(args, 2000 /*msecs to timeout*/); + if (toolInstance->error() != ToolEnums::Error::NoError) { + qWarning() << "ERROR: Tool call produced error:" << toolInstance->errorString(); + return handleFailedToolCall(trimmed, totalTime); + } - QString parseError; - QList 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); + // If the tool supports excerpts then try to parse them here + if (toolInstance->excerpts()) { + QString parseError; + QList sourceExcerpts = SourceExcerpt::fromJson(response, parseError); + if (!parseError.isEmpty()) { + qWarning() << "ERROR: Could not parse source excerpts for response:" << parseError; + } else if (!sourceExcerpts.isEmpty()) { + producedSourceExcerpts = true; + emit sourceExcerptsChanged(sourceExcerpts); + } } m_promptResponseTokens = 0; @@ -931,7 +925,7 @@ bool ChatLLM::promptRecursive(const QList &toolContexts, const QString // This is a recursive call but isRecursiveCall is checked above to arrest infinite recursive // tool calls - return promptRecursive(QList()/*collectionList*/, braveResponse, toolTemplate, + return promptRecursive(QList()/*tool context*/, response, toolTemplate, n_predict, top_k, top_p, min_p, temp, n_batch, repeat_penalty, repeat_penalty_tokens, totalTime, producedSourceExcerpts, true /*isRecursiveCall*/); } else { @@ -946,6 +940,7 @@ bool ChatLLM::promptRecursive(const QList &toolContexts, const QString 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 m_response = "" + response + ""; emit responseChanged(QString::fromStdString(m_response)); diff --git a/gpt4all-chat/qml/ChatView.qml b/gpt4all-chat/qml/ChatView.qml index 1417f42b0971..58926b7e398e 100644 --- a/gpt4all-chat/qml/ChatView.qml +++ b/gpt4all-chat/qml/ChatView.qml @@ -881,8 +881,8 @@ Rectangle { case Chat.PromptProcessing: return qsTr("processing ...") case Chat.ResponseGeneration: return qsTr("generating response ..."); case Chat.GeneratingQuestions: return qsTr("generating questions ..."); - case Chat.ToolCalled: return currentChat.toolDescription; - case Chat.ToolProcessing: return qsTr("processing web results ..."); // FIXME should not be hardcoded! + case Chat.ToolCalled: return qsTr("executing %1 ...").arg(currentChat.toolDescription); + case Chat.ToolProcessing: return qsTr("processing %1 results ...").arg(currentChat.toolDescription); default: return ""; // handle unexpected values } }