mirror of
https://github.com/Palm1r/QodeAssist.git
synced 2026-05-30 10:59:30 -04:00
fix: Add handling final argument for OpenAI responses tool calling
This commit is contained in:
@@ -77,10 +77,20 @@ QFuture<LLMQore::ToolResult> CreateNewFileTool::executeAsync(const QJsonObject &
|
||||
if (!isInProject) {
|
||||
const auto &settings = Settings::toolsSettings();
|
||||
if (!settings.allowAccessOutsideProject()) {
|
||||
const QString projectRoot = Context::ProjectUtils::getProjectRoot();
|
||||
const QString hint = projectRoot.isEmpty()
|
||||
? QStringLiteral(
|
||||
"No project is currently open. Open a project in Qt Creator or "
|
||||
"enable 'Allow file access outside project' in QodeAssist settings.")
|
||||
: QString(
|
||||
"Retry with a path under the active project root: '%1'. The build "
|
||||
"directory is for compiler output only and cannot accept new source "
|
||||
"files. If you really need to write outside the project, enable "
|
||||
"'Allow file access outside project' in QodeAssist settings.")
|
||||
.arg(projectRoot);
|
||||
throw LLMQore::ToolRuntimeError(
|
||||
QString("Error: File path '%1' is not within the current project. "
|
||||
"Enable 'Allow file access outside project' in settings to create files outside project scope.")
|
||||
.arg(absolutePath));
|
||||
QString("Error: File path '%1' is not within the current project. %2")
|
||||
.arg(absolutePath, hint));
|
||||
}
|
||||
LOG_MESSAGE(QString("Creating file outside project scope: %1").arg(absolutePath));
|
||||
}
|
||||
|
||||
@@ -143,10 +143,20 @@ QFuture<LLMQore::ToolResult> EditFileTool::executeAsync(const QJsonObject &input
|
||||
if (!isInProject) {
|
||||
const auto &settings = Settings::toolsSettings();
|
||||
if (!settings.allowAccessOutsideProject()) {
|
||||
const QString projectRoot = Context::ProjectUtils::getProjectRoot();
|
||||
const QString hint = projectRoot.isEmpty()
|
||||
? QStringLiteral(
|
||||
"No project is currently open. Open a project in Qt Creator or "
|
||||
"enable 'Allow file access outside project' in QodeAssist settings.")
|
||||
: QString(
|
||||
"Retry with a path under the active project root: '%1'. The build "
|
||||
"directory is for compiler output only — source files must live under "
|
||||
"the project root. If you really need to edit outside the project, "
|
||||
"enable 'Allow file access outside project' in QodeAssist settings.")
|
||||
.arg(projectRoot);
|
||||
throw LLMQore::ToolRuntimeError(
|
||||
QString("File path '%1' is not within the current project. "
|
||||
"Enable 'Allow file access outside project' in settings to edit files outside the project.")
|
||||
.arg(filePath));
|
||||
QString("File path '%1' is not within the current project. %2")
|
||||
.arg(filePath, hint));
|
||||
}
|
||||
LOG_MESSAGE(QString("Editing file outside project scope: %1").arg(filePath));
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <QProcess>
|
||||
#include <QPromise>
|
||||
#include <QRegularExpression>
|
||||
#include <QRegularExpression>
|
||||
#include <QSharedPointer>
|
||||
#include <QTimer>
|
||||
|
||||
@@ -45,18 +46,26 @@ QJsonObject ExecuteTerminalCommandTool::parametersSchema() const
|
||||
QJsonObject definition;
|
||||
definition["type"] = "object";
|
||||
|
||||
const QString commandDesc = getCommandDescription();
|
||||
const QStringList allowed = getAllowedCommands();
|
||||
const QString allowedList = allowed.isEmpty() ? "none" : allowed.join(", ");
|
||||
|
||||
QJsonObject properties;
|
||||
properties["command"] = QJsonObject{
|
||||
{"type", "string"},
|
||||
{"description", commandDesc}};
|
||||
{"description",
|
||||
QString("Name of the executable to run, WITHOUT any arguments or flags. "
|
||||
"Must be exactly one of the allowed commands: %1. "
|
||||
"Put every flag and argument in the separate `args` field. "
|
||||
"Correct: command=\"ls\", args=\"-R\". "
|
||||
"Incorrect: command=\"ls -R\" (the whole line in one field will be rejected).")
|
||||
.arg(allowedList)}};
|
||||
|
||||
properties["args"] = QJsonObject{
|
||||
{"type", "string"},
|
||||
{"description",
|
||||
"Optional arguments for the command. Arguments with spaces should be properly quoted. "
|
||||
"Example: '--file \"path with spaces.txt\" --verbose'"}};
|
||||
"Optional arguments and flags for the command, as a single string. Do NOT repeat the "
|
||||
"command name here. Arguments with spaces should be quoted. "
|
||||
"Example: args=\"--file \\\"path with spaces.txt\\\" --verbose\"."}};
|
||||
|
||||
definition["properties"] = properties;
|
||||
definition["required"] = QJsonArray{"command"};
|
||||
@@ -68,14 +77,25 @@ QFuture<LLMQore::ToolResult> ExecuteTerminalCommandTool::executeAsync(const QJso
|
||||
{
|
||||
using LLMQore::ToolResult;
|
||||
|
||||
const QString command = input.value("command").toString().trimmed();
|
||||
const QString args = input.value("args").toString().trimmed();
|
||||
QString command = input.value("command").toString().trimmed();
|
||||
QString args = input.value("args").toString().trimmed();
|
||||
|
||||
if (command.isEmpty()) {
|
||||
LOG_MESSAGE("ExecuteTerminalCommandTool: Command is empty");
|
||||
return QtFuture::makeReadyFuture(ToolResult::error("Error: Command parameter is required."));
|
||||
}
|
||||
|
||||
// Tolerate models that pack the whole command line into `command`. As long as `args` is
|
||||
// empty we can safely split on the first whitespace — the allowlist check still validates
|
||||
// the actual executable name.
|
||||
if (args.isEmpty()) {
|
||||
const int firstSpace = command.indexOf(QRegularExpression("\\s"));
|
||||
if (firstSpace > 0) {
|
||||
args = command.mid(firstSpace + 1).trimmed();
|
||||
command = command.left(firstSpace);
|
||||
}
|
||||
}
|
||||
|
||||
if (command.length() > MAX_COMMAND_LENGTH) {
|
||||
LOG_MESSAGE(QString("ExecuteTerminalCommandTool: Command too long (%1 chars)")
|
||||
.arg(command.length()));
|
||||
|
||||
Reference in New Issue
Block a user