From e1025df21e85ad494adfa97b2a0992ad9d5f68a7 Mon Sep 17 00:00:00 2001
From: Petr Mironychev <9195189+Palm1r@users.noreply.github.com>
Date: Thu, 23 Oct 2025 16:32:40 +0200
Subject: [PATCH] feat: Add tool for creating file
---
CMakeLists.txt | 1 +
tools/CreateNewFileTool.cpp | 125 ++++++++++++++++++++++++++++++++++++
tools/CreateNewFileTool.hpp | 42 ++++++++++++
tools/ToolsFactory.cpp | 2 +
4 files changed, 170 insertions(+)
create mode 100644 tools/CreateNewFileTool.cpp
create mode 100644 tools/CreateNewFileTool.hpp
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 8b092b4..af5863c 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -125,6 +125,7 @@ add_qtc_plugin(QodeAssist
tools/EditProjectFileTool.hpp tools/EditProjectFileTool.cpp
tools/FindSymbolTool.hpp tools/FindSymbolTool.cpp
tools/FindFileTool.hpp tools/FindFileTool.cpp
+ tools/CreateNewFileTool.hpp tools/CreateNewFileTool.cpp
providers/ClaudeMessage.hpp providers/ClaudeMessage.cpp
providers/OpenAIMessage.hpp providers/OpenAIMessage.cpp
providers/OllamaMessage.hpp providers/OllamaMessage.cpp
diff --git a/tools/CreateNewFileTool.cpp b/tools/CreateNewFileTool.cpp
new file mode 100644
index 0000000..7d4ab96
--- /dev/null
+++ b/tools/CreateNewFileTool.cpp
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2025 Petr Mironychev
+ *
+ * This file is part of QodeAssist.
+ *
+ * QodeAssist is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * QodeAssist is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with QodeAssist. If not, see .
+ */
+
+#include "CreateNewFileTool.hpp"
+#include "ToolExceptions.hpp"
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+namespace QodeAssist::Tools {
+
+CreateNewFileTool::CreateNewFileTool(QObject *parent)
+ : BaseTool(parent)
+{}
+
+QString CreateNewFileTool::name() const
+{
+ return "create_new_file";
+}
+
+QString CreateNewFileTool::stringName() const
+{
+ return {"Creating new file"};
+}
+
+QString CreateNewFileTool::description() const
+{
+ return "Create a new empty file at the specified path. "
+ "The directory path must exist. Provide absolute file path. After crate files add file "
+ "to project file (CMakeLists.txt or .cmake or .pri)";
+}
+
+QJsonObject CreateNewFileTool::getDefinition(LLMCore::ToolSchemaFormat format) const
+{
+ QJsonObject properties;
+
+ QJsonObject filepathProperty;
+ filepathProperty["type"] = "string";
+ filepathProperty["description"] = "The absolute path where the new file should be created";
+ properties["filepath"] = filepathProperty;
+
+ QJsonObject definition;
+ definition["type"] = "object";
+ definition["properties"] = properties;
+ QJsonArray required;
+ required.append("filepath");
+ definition["required"] = required;
+
+ switch (format) {
+ case LLMCore::ToolSchemaFormat::OpenAI:
+ return customizeForOpenAI(definition);
+ case LLMCore::ToolSchemaFormat::Claude:
+ return customizeForClaude(definition);
+ case LLMCore::ToolSchemaFormat::Ollama:
+ return customizeForOllama(definition);
+ case LLMCore::ToolSchemaFormat::Google:
+ return customizeForGoogle(definition);
+ }
+
+ return definition;
+}
+
+LLMCore::ToolPermissions CreateNewFileTool::requiredPermissions() const
+{
+ return LLMCore::ToolPermission::FileSystemWrite;
+}
+
+QFuture CreateNewFileTool::executeAsync(const QJsonObject &input)
+{
+ return QtConcurrent::run([this, input]() -> QString {
+ QString filePath = input["filepath"].toString();
+
+ if (filePath.isEmpty()) {
+ throw ToolInvalidArgument("Error: 'filepath' parameter is required");
+ }
+
+ QFileInfo fileInfo(filePath);
+
+ if (fileInfo.exists()) {
+ throw ToolRuntimeError(
+ QString("Error: File already exists at path '%1'").arg(filePath));
+ }
+
+ QDir dir = fileInfo.absoluteDir();
+ if (!dir.exists()) {
+ throw ToolRuntimeError(QString("Error: Directory does not exist: '%1'")
+ .arg(dir.absolutePath()));
+ }
+
+ QFile file(filePath);
+ if (!file.open(QIODevice::WriteOnly)) {
+ throw ToolRuntimeError(
+ QString("Error: Could not create file '%1': %2").arg(filePath, file.errorString()));
+ }
+
+ file.close();
+
+ LOG_MESSAGE(QString("Successfully created new file: %1").arg(filePath));
+
+ return QString("Successfully created new file: %1").arg(filePath);
+ });
+}
+
+} // namespace QodeAssist::Tools
+
diff --git a/tools/CreateNewFileTool.hpp b/tools/CreateNewFileTool.hpp
new file mode 100644
index 0000000..1c16325
--- /dev/null
+++ b/tools/CreateNewFileTool.hpp
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2025 Petr Mironychev
+ *
+ * This file is part of QodeAssist.
+ *
+ * QodeAssist is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * QodeAssist is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with QodeAssist. If not, see .
+ */
+
+#pragma once
+
+#include
+
+namespace QodeAssist::Tools {
+
+class CreateNewFileTool : public LLMCore::BaseTool
+{
+ Q_OBJECT
+public:
+ explicit CreateNewFileTool(QObject *parent = nullptr);
+
+ QString name() const override;
+ QString stringName() const override;
+ QString description() const override;
+ QJsonObject getDefinition(LLMCore::ToolSchemaFormat format) const override;
+ LLMCore::ToolPermissions requiredPermissions() const override;
+
+ QFuture executeAsync(const QJsonObject &input = QJsonObject()) override;
+};
+
+} // namespace QodeAssist::Tools
+
diff --git a/tools/ToolsFactory.cpp b/tools/ToolsFactory.cpp
index 5cb5d6f..7db04ef 100644
--- a/tools/ToolsFactory.cpp
+++ b/tools/ToolsFactory.cpp
@@ -24,6 +24,7 @@
#include
#include
+#include "CreateNewFileTool.hpp"
#include "EditProjectFileTool.hpp"
#include "FindFileTool.hpp"
#include "FindSymbolTool.hpp"
@@ -51,6 +52,7 @@ void ToolsFactory::registerTools()
registerTool(new EditProjectFileTool(this));
registerTool(new FindSymbolTool(this));
registerTool(new FindFileTool(this));
+ registerTool(new CreateNewFileTool(this));
LOG_MESSAGE(QString("Registered %1 tools").arg(m_tools.size()));
}