chore: restructure llm plugin to be more coherent & fix various bugs in llm ui
C++ / fmt (pull_request) Failing after 6s
C++ / build (pull_request) Failing after 10s
C++ / clang-tidy (pull_request) Failing after 9s
JS/TS / fmt (pull_request) Successful in 10s
JS/TS / lint (pull_request) Successful in 8s
Python / static (pull_request) Successful in 30s
Rust / build (pull_request) Successful in 49s
Python / verify (pull_request) Successful in 1m35s
Rust / fmt (pull_request) Successful in 36s
Rust / clippy (pull_request) Successful in 54s
C++ / fmt (pull_request) Failing after 6s
C++ / build (pull_request) Failing after 10s
C++ / clang-tidy (pull_request) Failing after 9s
JS/TS / fmt (pull_request) Successful in 10s
JS/TS / lint (pull_request) Successful in 8s
Python / static (pull_request) Successful in 30s
Rust / build (pull_request) Successful in 49s
Python / verify (pull_request) Successful in 1m35s
Rust / fmt (pull_request) Successful in 36s
Rust / clippy (pull_request) Successful in 54s
This commit is contained in:
@@ -10,30 +10,16 @@
|
||||
|
||||
namespace ZShell::llm {
|
||||
|
||||
const QString WebFetchTool::StoragePath =
|
||||
QStringLiteral("/tmp/zshell-llm/webfetch");
|
||||
|
||||
namespace {
|
||||
|
||||
const char* kUserAgent =
|
||||
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 "
|
||||
"(KHTML, like Gecko) Chrome/143.0.0.0 Safari/537.36";
|
||||
|
||||
QJsonObject makeOutput(const QString& text) {
|
||||
QJsonObject obj;
|
||||
obj[QStringLiteral("output")] = text;
|
||||
return obj;
|
||||
}
|
||||
|
||||
QJsonObject makeError(const QString& message) {
|
||||
QJsonObject obj;
|
||||
obj[QStringLiteral("error")] = message;
|
||||
return obj;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
WebFetchTool::WebFetchTool(QObject* parent) : LlmTool(parent) {}
|
||||
WebFetchTool::WebFetchTool(ToolRegistry* registry, QObject* parent)
|
||||
: LlmTool(registry, parent) {}
|
||||
|
||||
WebFetchTool::~WebFetchTool() {
|
||||
for (auto* job : m_jobs) {
|
||||
@@ -52,9 +38,9 @@ QString WebFetchTool::description() const {
|
||||
"Fetch content from an HTTP or HTTPS URL and return it as plain "
|
||||
"text or raw HTML. HTML pages are reduced to their visible text "
|
||||
"by default. Only a limited amount of content is returned inline; "
|
||||
"the full output of every call is saved under "
|
||||
"/tmp/zshell-llm/webfetch/, where it can be paged through with "
|
||||
"the readfile tool. This tool is read-only.");
|
||||
"the full output of every call is saved in the sandbox directory "
|
||||
"of the conversation, where it can be paged through with the "
|
||||
"readfile tool. This tool is read-only.");
|
||||
}
|
||||
|
||||
QJsonObject WebFetchTool::parameters() const {
|
||||
@@ -94,7 +80,7 @@ QJsonObject WebFetchTool::parameters() const {
|
||||
return schema;
|
||||
}
|
||||
|
||||
void WebFetchTool::completeJob(Job* job, QJsonObject result) {
|
||||
void WebFetchTool::completeJob(Job* job, ToolResult result) {
|
||||
QMetaObject::invokeMethod(
|
||||
this,
|
||||
[this, job, result = std::move(result)]() mutable {
|
||||
@@ -110,19 +96,23 @@ void WebFetchTool::completeJob(Job* job, QJsonObject result) {
|
||||
}
|
||||
|
||||
void WebFetchTool::execute(
|
||||
const QString& toolCallId,
|
||||
const QJsonObject& args,
|
||||
int outputBudgetChars,
|
||||
std::function<void(const QJsonObject&)> done) {
|
||||
const ToolContext& context, const QJsonObject& args, ToolDone done) {
|
||||
auto* job = new Job;
|
||||
job->done = std::move(done);
|
||||
job->toolCallId = toolCallId;
|
||||
job->budgetChars = outputBudgetChars;
|
||||
job->toolCallId = context.toolCallId;
|
||||
job->budgetChars = context.outputBudgetChars > 0
|
||||
? context.outputBudgetChars
|
||||
: registry()->outputBudgetChars(1);
|
||||
job->storagePath =
|
||||
context.workspace.isEmpty()
|
||||
? QDir(QDir::tempPath())
|
||||
.filePath(QStringLiteral("zshell-llm/webfetch"))
|
||||
: context.workspace + QStringLiteral("/webfetch");
|
||||
m_jobs.append(job);
|
||||
|
||||
auto fail = [this, job](const QString& message) {
|
||||
job->timer->stop();
|
||||
completeJob(job, makeError(message));
|
||||
completeJob(job, {false, message});
|
||||
};
|
||||
|
||||
const QString urlText = args[QStringLiteral("url")].toString().trimmed();
|
||||
@@ -194,23 +184,27 @@ void WebFetchTool::execute(
|
||||
if (job->tooLarge) {
|
||||
completeJob(
|
||||
job,
|
||||
makeError(QStringLiteral(
|
||||
"Response too large (exceeds the 5 MB "
|
||||
"limit")));
|
||||
ToolResult{
|
||||
false,
|
||||
QStringLiteral(
|
||||
"Response too large (exceeds the 5 MB "
|
||||
"limit")});
|
||||
return;
|
||||
}
|
||||
if (error != QNetworkReply::NoError) {
|
||||
completeJob(
|
||||
job,
|
||||
makeError(
|
||||
QStringLiteral("Request failed: %1").arg(errorString)));
|
||||
ToolResult{
|
||||
false,
|
||||
QStringLiteral("Request failed: %1").arg(errorString)});
|
||||
return;
|
||||
}
|
||||
if (status < 200 || status >= 300) {
|
||||
completeJob(
|
||||
job,
|
||||
makeError(
|
||||
QStringLiteral("Server returned status %1").arg(status)));
|
||||
ToolResult{
|
||||
false,
|
||||
QStringLiteral("Server returned status %1").arg(status)});
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -220,9 +214,10 @@ void WebFetchTool::execute(
|
||||
if (mime.startsWith(QLatin1String("image/"))) {
|
||||
completeJob(
|
||||
job,
|
||||
makeError(
|
||||
ToolResult{
|
||||
false,
|
||||
QStringLiteral("Unsupported fetched image content type: %1")
|
||||
.arg(mime)));
|
||||
.arg(mime)});
|
||||
return;
|
||||
}
|
||||
const bool textual =
|
||||
@@ -236,9 +231,10 @@ void WebFetchTool::execute(
|
||||
if (!textual) {
|
||||
completeJob(
|
||||
job,
|
||||
makeError(
|
||||
ToolResult{
|
||||
false,
|
||||
QStringLiteral("Unsupported fetched file content type: %1")
|
||||
.arg(mime)));
|
||||
.arg(mime)});
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -249,9 +245,8 @@ void WebFetchTool::execute(
|
||||
|
||||
const QString savedPath = saveToFile(*job, content, mime);
|
||||
|
||||
const int budget = job->budgetChars;
|
||||
QString output = content;
|
||||
int budget = inlineBudgetChars();
|
||||
if (job->budgetChars > 0) budget = qMin(budget, job->budgetChars);
|
||||
if (content.size() > budget) {
|
||||
output = content.left(budget);
|
||||
const QString note =
|
||||
@@ -269,13 +264,13 @@ void WebFetchTool::execute(
|
||||
". The remaining content is not "
|
||||
"available.");
|
||||
}
|
||||
completeJob(job, makeOutput(output));
|
||||
completeJob(job, ToolResult{true, output});
|
||||
});
|
||||
}
|
||||
|
||||
QString WebFetchTool::saveToFile(
|
||||
const Job& job, const QString& content, const QString& mime) const {
|
||||
QDir dir(StoragePath);
|
||||
QDir dir(job.storagePath);
|
||||
if (!dir.exists() && !dir.mkpath(QStringLiteral("."))) return QString();
|
||||
|
||||
QString fileName;
|
||||
|
||||
Reference in New Issue
Block a user