fix: truncate context logic
C++ / fmt (pull_request) Successful in 4s
C++ / build (pull_request) Failing after 2m6s
C++ / clang-tidy (pull_request) Failing after 2m5s
JS/TS / fmt (pull_request) Failing after 3m8s
Python / static (pull_request) Successful in 24s
Python / verify (pull_request) Successful in 1m21s
JS/TS / lint (pull_request) Successful in 5m10s
Rust / fmt (pull_request) Successful in 30s
Rust / build (pull_request) Successful in 56s
Rust / clippy (pull_request) Successful in 46s

This commit is contained in:
2026-09-04 02:20:37 +02:00
parent 34dde4bbfb
commit cd3da1941b
15 changed files with 238 additions and 126 deletions
+14 -12
View File
@@ -53,9 +53,9 @@ QJsonObject FileReadTool::parameters() const {
QJsonObject limit;
limit[QStringLiteral("type")] = QStringLiteral("integer");
limit[QStringLiteral("minimum")] = 1;
limit[QStringLiteral("description")] =
QStringLiteral("Maximum number of characters to return. Defaults "
"to a value that fits the model's context window.");
limit[QStringLiteral("description")] = QStringLiteral(
"Maximum number of characters to return. Defaults "
"to a value that fits the model's context window.");
QJsonObject properties;
properties[QStringLiteral("path")] = path;
@@ -74,6 +74,7 @@ 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 QString path = args[QStringLiteral("path")].toString().trimmed();
@@ -82,7 +83,8 @@ void FileReadTool::execute(
return;
}
const int offset = qMax(0, args[QStringLiteral("offset")].toInt(0));
const int budget = inlineBudgetChars();
int budget = inlineBudgetChars();
if (outputBudgetChars > 0) budget = qMin(budget, outputBudgetChars);
const int limit =
qBound(1, args[QStringLiteral("limit")].toInt(budget), budget);
@@ -90,8 +92,9 @@ 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")
done(makeError(QStringLiteral(
"Path is a directory, not a "
"file: %1")
.arg(path)));
} else {
done(makeError(QStringLiteral("Cannot open file: %1").arg(path)));
@@ -106,8 +109,9 @@ void FileReadTool::execute(
}
if (offset >= fileSize) {
file.close();
done(makeError(QStringLiteral("Offset %1 is beyond the end of the "
"file (%2 bytes)")
done(makeError(QStringLiteral(
"Offset %1 is beyond the end of the "
"file (%2 bytes)")
.arg(offset)
.arg(fileSize)));
return;
@@ -117,15 +121,13 @@ void FileReadTool::execute(
done(makeError(QStringLiteral("Cannot seek in file: %1").arg(path)));
return;
}
// UTF-8 uses at most 4 bytes per character, so this many bytes always
// cover `limit` characters.
const qint64 wanted = qint64(limit) * 4 + 16;
const QByteArray chunk = file.read(qMin(wanted, fileSize - offset));
file.close();
if (chunk.contains('\0')) {
done(makeError(QStringLiteral("Binary files are not supported: %1")
.arg(path)));
done(makeError(
QStringLiteral("Binary files are not supported: %1").arg(path)));
return;
}
const QString content = QString::fromUtf8(chunk);