diff --git a/llmcore/BaseTool.hpp b/llmcore/BaseTool.hpp index 8ba5539..ddb5684 100644 --- a/llmcore/BaseTool.hpp +++ b/llmcore/BaseTool.hpp @@ -36,6 +36,14 @@ enum ToolPermission { NetworkAccess = 1 << 2 }; Q_DECLARE_FLAGS(ToolPermissions, ToolPermission) +Q_DECLARE_OPERATORS_FOR_FLAGS(ToolPermissions) + +enum class RunToolsFilter { + ALL, // Run all tools (no filtering) + OnlyRead, // Run only read tools (FileSystemRead + None) + OnlyWrite, // Run only write tools (FileSystemWrite) + OnlyNetworking // Run only network tools (NetworkAccess) +}; class BaseTool : public QObject { diff --git a/providers/ClaudeProvider.cpp b/providers/ClaudeProvider.cpp index e548e60..dcfa6df 100644 --- a/providers/ClaudeProvider.cpp +++ b/providers/ClaudeProvider.cpp @@ -128,8 +128,13 @@ void ClaudeProvider::prepareRequest( } if (isToolsEnabled) { + LLMCore::RunToolsFilter filter = LLMCore::RunToolsFilter::ALL; + if (type == LLMCore::RequestType::QuickRefactoring) { + filter = LLMCore::RunToolsFilter::OnlyRead; + } + auto toolsDefinitions = m_toolsManager->getToolsDefinitions( - LLMCore::ToolSchemaFormat::Claude); + LLMCore::ToolSchemaFormat::Claude, filter); if (!toolsDefinitions.isEmpty()) { request["tools"] = toolsDefinitions; LOG_MESSAGE(QString("Added %1 tools to Claude request").arg(toolsDefinitions.size())); diff --git a/providers/GoogleAIProvider.cpp b/providers/GoogleAIProvider.cpp index 6ba4448..9ddae6e 100644 --- a/providers/GoogleAIProvider.cpp +++ b/providers/GoogleAIProvider.cpp @@ -142,8 +142,13 @@ void GoogleAIProvider::prepareRequest( } if (isToolsEnabled) { + LLMCore::RunToolsFilter filter = LLMCore::RunToolsFilter::ALL; + if (type == LLMCore::RequestType::QuickRefactoring) { + filter = LLMCore::RunToolsFilter::OnlyRead; + } + auto toolsDefinitions = m_toolsManager->getToolsDefinitions( - LLMCore::ToolSchemaFormat::Google); + LLMCore::ToolSchemaFormat::Google, filter); if (!toolsDefinitions.isEmpty()) { request["tools"] = toolsDefinitions; LOG_MESSAGE(QString("Added %1 tools to Google AI request").arg(toolsDefinitions.size())); diff --git a/providers/LMStudioProvider.cpp b/providers/LMStudioProvider.cpp index 2ab2dee..7c84b28 100644 --- a/providers/LMStudioProvider.cpp +++ b/providers/LMStudioProvider.cpp @@ -256,8 +256,13 @@ void LMStudioProvider::prepareRequest( } if (isToolsEnabled) { + LLMCore::RunToolsFilter filter = LLMCore::RunToolsFilter::ALL; + if (type == LLMCore::RequestType::QuickRefactoring) { + filter = LLMCore::RunToolsFilter::OnlyRead; + } + auto toolsDefinitions = m_toolsManager->getToolsDefinitions( - LLMCore::ToolSchemaFormat::OpenAI); + LLMCore::ToolSchemaFormat::OpenAI, filter); if (!toolsDefinitions.isEmpty()) { request["tools"] = toolsDefinitions; LOG_MESSAGE(QString("Added %1 tools to LMStudio request").arg(toolsDefinitions.size())); diff --git a/providers/LlamaCppProvider.cpp b/providers/LlamaCppProvider.cpp index db16651..f974a4f 100644 --- a/providers/LlamaCppProvider.cpp +++ b/providers/LlamaCppProvider.cpp @@ -107,8 +107,13 @@ void LlamaCppProvider::prepareRequest( } if (isToolsEnabled) { + LLMCore::RunToolsFilter filter = LLMCore::RunToolsFilter::ALL; + if (type == LLMCore::RequestType::QuickRefactoring) { + filter = LLMCore::RunToolsFilter::OnlyRead; + } + auto toolsDefinitions = m_toolsManager->getToolsDefinitions( - LLMCore::ToolSchemaFormat::OpenAI); + LLMCore::ToolSchemaFormat::OpenAI, filter); if (!toolsDefinitions.isEmpty()) { request["tools"] = toolsDefinitions; LOG_MESSAGE(QString("Added %1 tools to llama.cpp request").arg(toolsDefinitions.size())); diff --git a/providers/MistralAIProvider.cpp b/providers/MistralAIProvider.cpp index e774cfa..177500f 100644 --- a/providers/MistralAIProvider.cpp +++ b/providers/MistralAIProvider.cpp @@ -277,8 +277,13 @@ void MistralAIProvider::prepareRequest( } if (isToolsEnabled) { + LLMCore::RunToolsFilter filter = LLMCore::RunToolsFilter::ALL; + if (type == LLMCore::RequestType::QuickRefactoring) { + filter = LLMCore::RunToolsFilter::OnlyRead; + } + auto toolsDefinitions = m_toolsManager->getToolsDefinitions( - LLMCore::ToolSchemaFormat::OpenAI); + LLMCore::ToolSchemaFormat::OpenAI, filter); if (!toolsDefinitions.isEmpty()) { request["tools"] = toolsDefinitions; LOG_MESSAGE(QString("Added %1 tools to Mistral request").arg(toolsDefinitions.size())); diff --git a/providers/OllamaProvider.cpp b/providers/OllamaProvider.cpp index 7b5ba27..52ac5e5 100644 --- a/providers/OllamaProvider.cpp +++ b/providers/OllamaProvider.cpp @@ -113,8 +113,13 @@ void OllamaProvider::prepareRequest( } if (isToolsEnabled) { + LLMCore::RunToolsFilter filter = LLMCore::RunToolsFilter::ALL; + if (type == LLMCore::RequestType::QuickRefactoring) { + filter = LLMCore::RunToolsFilter::OnlyRead; + } + auto toolsDefinitions = m_toolsManager->toolsFactory()->getToolsDefinitions( - LLMCore::ToolSchemaFormat::Ollama); + LLMCore::ToolSchemaFormat::Ollama, filter); if (!toolsDefinitions.isEmpty()) { request["tools"] = toolsDefinitions; LOG_MESSAGE( diff --git a/providers/OpenAICompatProvider.cpp b/providers/OpenAICompatProvider.cpp index 85026ce..4b33867 100644 --- a/providers/OpenAICompatProvider.cpp +++ b/providers/OpenAICompatProvider.cpp @@ -107,8 +107,13 @@ void OpenAICompatProvider::prepareRequest( } if (isToolsEnabled) { + LLMCore::RunToolsFilter filter = LLMCore::RunToolsFilter::ALL; + if (type == LLMCore::RequestType::QuickRefactoring) { + filter = LLMCore::RunToolsFilter::OnlyRead; + } + auto toolsDefinitions = m_toolsManager->getToolsDefinitions( - LLMCore::ToolSchemaFormat::OpenAI); + LLMCore::ToolSchemaFormat::OpenAI, filter); if (!toolsDefinitions.isEmpty()) { request["tools"] = toolsDefinitions; LOG_MESSAGE( diff --git a/providers/OpenAIProvider.cpp b/providers/OpenAIProvider.cpp index 92ff574..142ffaa 100644 --- a/providers/OpenAIProvider.cpp +++ b/providers/OpenAIProvider.cpp @@ -127,8 +127,13 @@ void OpenAIProvider::prepareRequest( } if (isToolsEnabled) { + LLMCore::RunToolsFilter filter = LLMCore::RunToolsFilter::ALL; + if (type == LLMCore::RequestType::QuickRefactoring) { + filter = LLMCore::RunToolsFilter::OnlyRead; + } + auto toolsDefinitions = m_toolsManager->getToolsDefinitions( - LLMCore::ToolSchemaFormat::OpenAI); + LLMCore::ToolSchemaFormat::OpenAI, filter); if (!toolsDefinitions.isEmpty()) { request["tools"] = toolsDefinitions; LOG_MESSAGE(QString("Added %1 tools to OpenAI request").arg(toolsDefinitions.size())); diff --git a/tools/ToolsFactory.cpp b/tools/ToolsFactory.cpp index a31c064..b8c7159 100644 --- a/tools/ToolsFactory.cpp +++ b/tools/ToolsFactory.cpp @@ -81,7 +81,8 @@ LLMCore::BaseTool *ToolsFactory::getToolByName(const QString &name) const return m_tools.value(name, nullptr); } -QJsonArray ToolsFactory::getToolsDefinitions(LLMCore::ToolSchemaFormat format) const +QJsonArray ToolsFactory::getToolsDefinitions( + LLMCore::ToolSchemaFormat format, LLMCore::RunToolsFilter filter) const { QJsonArray toolsArray; const auto &settings = Settings::toolsSettings(); @@ -100,6 +101,42 @@ QJsonArray ToolsFactory::getToolsDefinitions(LLMCore::ToolSchemaFormat format) c } const auto requiredPerms = it.value()->requiredPermissions(); + + if (filter != LLMCore::RunToolsFilter::ALL) { + bool matchesFilter = false; + + switch (filter) { + case LLMCore::RunToolsFilter::OnlyRead: + if (requiredPerms == LLMCore::ToolPermission::None + || requiredPerms.testFlag(LLMCore::ToolPermission::FileSystemRead)) { + matchesFilter = true; + } + break; + + case LLMCore::RunToolsFilter::OnlyWrite: + if (requiredPerms.testFlag(LLMCore::ToolPermission::FileSystemWrite)) { + matchesFilter = true; + } + break; + + case LLMCore::RunToolsFilter::OnlyNetworking: + if (requiredPerms.testFlag(LLMCore::ToolPermission::NetworkAccess)) { + matchesFilter = true; + } + break; + + case LLMCore::RunToolsFilter::ALL: + matchesFilter = true; + break; + } + + if (!matchesFilter) { + LOG_MESSAGE(QString("Tool '%1' skipped by tools filter") + .arg(it.value()->name())); + continue; + } + } + bool hasPermission = true; if (requiredPerms.testFlag(LLMCore::ToolPermission::FileSystemRead)) { diff --git a/tools/ToolsFactory.hpp b/tools/ToolsFactory.hpp index b7998c3..abb0e1a 100644 --- a/tools/ToolsFactory.hpp +++ b/tools/ToolsFactory.hpp @@ -34,7 +34,9 @@ public: QList getAvailableTools() const; LLMCore::BaseTool *getToolByName(const QString &name) const; - QJsonArray getToolsDefinitions(LLMCore::ToolSchemaFormat format) const; + QJsonArray getToolsDefinitions( + LLMCore::ToolSchemaFormat format, + LLMCore::RunToolsFilter filter = LLMCore::RunToolsFilter::ALL) const; QString getStringName(const QString &name) const; private: diff --git a/tools/ToolsManager.cpp b/tools/ToolsManager.cpp index b5c6fc9..4c74169 100644 --- a/tools/ToolsManager.cpp +++ b/tools/ToolsManager.cpp @@ -127,13 +127,14 @@ void ToolsManager::executeNextTool(const QString &requestId) LOG_MESSAGE(QString("ToolsManager: Started async execution of %1").arg(tool.name)); } -QJsonArray ToolsManager::getToolsDefinitions(LLMCore::ToolSchemaFormat format) const +QJsonArray ToolsManager::getToolsDefinitions( + LLMCore::ToolSchemaFormat format, LLMCore::RunToolsFilter filter) const { if (!m_toolsFactory) { return QJsonArray(); } - return m_toolsFactory->getToolsDefinitions(format); + return m_toolsFactory->getToolsDefinitions(format, filter); } void ToolsManager::cleanupRequest(const QString &requestId) diff --git a/tools/ToolsManager.hpp b/tools/ToolsManager.hpp index c94c425..242b7e0 100644 --- a/tools/ToolsManager.hpp +++ b/tools/ToolsManager.hpp @@ -59,7 +59,9 @@ public: const QString &toolName, const QJsonObject &input); - QJsonArray getToolsDefinitions(LLMCore::ToolSchemaFormat format) const; + QJsonArray getToolsDefinitions( + LLMCore::ToolSchemaFormat format, + LLMCore::RunToolsFilter filter = LLMCore::RunToolsFilter::ALL) const; void cleanupRequest(const QString &requestId); ToolsFactory *toolsFactory() const;