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

This commit is contained in:
2026-10-18 12:58:38 +02:00
parent fc81be922f
commit 1fe8a3a959
54 changed files with 3022 additions and 2559 deletions
+26 -43
View File
@@ -6,23 +6,8 @@
namespace ZShell::llm {
namespace {
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
FileReadTool::FileReadTool(QObject* parent) : LlmTool(parent) {}
FileReadTool::FileReadTool(ToolRegistry* registry, QObject* parent)
: LlmTool(registry, parent) {}
QString FileReadTool::name() const {
return QStringLiteral("readfile");
@@ -34,8 +19,8 @@ QString FileReadTool::description() const {
"its content. At most a limited number of characters is returned "
"per call; use offset and limit to page through larger files. "
"Binary files are not supported. Full output of webfetch calls "
"is stored under /tmp/zshell-llm/webfetch/ and can be read this "
"way. This tool is read-only.");
"is saved in the sandbox directory and can be read this way. "
"This tool is read-only.");
}
QJsonObject FileReadTool::parameters() const {
@@ -72,19 +57,16 @@ QJsonObject FileReadTool::parameters() const {
}
void FileReadTool::execute(
const QString& toolCallId,
const QJsonObject& args,
int outputBudgetChars,
std::function<void(const QJsonObject&)> done) {
Q_UNUSED(toolCallId);
const ToolContext& context, const QJsonObject& args, ToolDone done) {
const QString path = args[QStringLiteral("path")].toString().trimmed();
if (path.isEmpty()) {
done(makeError(QStringLiteral("Missing required argument 'path'")));
done({false, QStringLiteral("Missing required argument 'path'")});
return;
}
const int offset = qMax(0, args[QStringLiteral("offset")].toInt(0));
int budget = inlineBudgetChars();
if (outputBudgetChars > 0) budget = qMin(budget, outputBudgetChars);
const int budget = context.outputBudgetChars > 0
? context.outputBudgetChars
: registry()->outputBudgetChars(1);
const int limit =
qBound(1, args[QStringLiteral("limit")].toInt(budget), budget);
@@ -92,33 +74,33 @@ void FileReadTool::execute(
if (!file.open(QIODevice::ReadOnly)) {
const QFileInfo info(path);
if (info.exists() && info.isDir()) {
done(makeError(QStringLiteral(
"Path is a directory, not a "
"file: %1")
.arg(path)));
done(
{false,
QStringLiteral("Path is a directory, not a file: %1")
.arg(path)});
} else {
done(makeError(QStringLiteral("Cannot open file: %1").arg(path)));
done({false, QStringLiteral("Cannot open file: %1").arg(path)});
}
return;
}
const qint64 fileSize = file.size();
if (fileSize == 0) {
file.close();
done(makeOutput(QString()));
done({true, QString()});
return;
}
if (offset >= fileSize) {
file.close();
done(makeError(QStringLiteral(
"Offset %1 is beyond the end of the "
"file (%2 bytes)")
.arg(offset)
.arg(fileSize)));
done(
{false,
QStringLiteral("Offset %1 is beyond the end of the file (%2 bytes)")
.arg(offset)
.arg(fileSize)});
return;
}
if (!file.seek(offset)) {
file.close();
done(makeError(QStringLiteral("Cannot seek in file: %1").arg(path)));
done({false, QStringLiteral("Cannot seek in file: %1").arg(path)});
return;
}
const qint64 wanted = qint64(limit) * 4 + 16;
@@ -126,13 +108,14 @@ void FileReadTool::execute(
file.close();
if (chunk.contains('\0')) {
done(makeError(
QStringLiteral("Binary files are not supported: %1").arg(path)));
done(
{false,
QStringLiteral("Binary files are not supported: %1").arg(path)});
return;
}
const QString content = QString::fromUtf8(chunk);
if (content.size() <= limit) {
done(makeOutput(content));
done({true, content});
return;
}
const QString head = content.left(limit);
@@ -147,7 +130,7 @@ void FileReadTool::execute(
.arg(nextOffset)
.arg(fileSize)
.arg(nextOffset);
done(makeOutput(output));
done({true, output});
}
} // namespace ZShell::llm