refactor: Replace plugin tools manager to client api tools manager

This commit is contained in:
Petr Mironychev
2026-03-30 06:53:29 +02:00
parent f58fad9578
commit e55e96714b
42 changed files with 381 additions and 343 deletions

View File

@ -35,7 +35,7 @@ add_definitions(
)
add_subdirectory(pluginllmcore)
# add_subdirectory(sources/external/llmcore)
add_subdirectory(sources/external/llmcore)
add_subdirectory(settings)
add_subdirectory(logger)
add_subdirectory(UIControls)
@ -63,6 +63,7 @@ add_qtc_plugin(QodeAssist
QtCreator::Utils
QtCreator::CPlusPlus
QodeAssistChatViewplugin
LLMCore
SOURCES
.github/workflows/build_cmake.yml
.github/workflows/README.md
@ -142,10 +143,8 @@ add_qtc_plugin(QodeAssist
widgets/DiffStatistics.hpp
QuickRefactorHandler.hpp QuickRefactorHandler.cpp
tools/ToolsFactory.hpp tools/ToolsFactory.cpp
tools/ToolHandler.hpp tools/ToolHandler.cpp
tools/ToolsRegistration.hpp tools/ToolsRegistration.cpp
tools/ListProjectFilesTool.hpp tools/ListProjectFilesTool.cpp
tools/ToolsManager.hpp tools/ToolsManager.cpp
tools/GetIssuesListTool.hpp tools/GetIssuesListTool.cpp
tools/CreateNewFileTool.hpp tools/CreateNewFileTool.cpp
tools/EditFileTool.hpp tools/EditFileTool.cpp

View File

@ -85,6 +85,7 @@ target_link_libraries(QodeAssistChatView
Context
QodeAssistUIControlsplugin
QodeAssistLogger
LLMCore
)
target_include_directories(QodeAssistChatView

View File

@ -40,6 +40,10 @@
#include <texteditor/textdocument.h>
#include <texteditor/texteditor.h>
#include <LLMCore/ToolsManager.hpp>
#include "tools/TodoTool.hpp"
#include "ChatAssistantSettings.hpp"
#include "ChatSerializer.hpp"
#include "GeneralSettings.hpp"
@ -327,7 +331,10 @@ void ClientInterface::sendMessage(
provider->sendRequest(requestId, config.url, config.providerRequest);
if (provider->supportsTools() && provider->toolsManager()) {
provider->toolsManager()->setCurrentSessionId(m_chatFilePath);
if (auto *todoTool = qobject_cast<QodeAssist::Tools::TodoTool *>(
provider->toolsManager()->tool("todo_tool"))) {
todoTool->setCurrentSessionId(m_chatFilePath);
}
}
}
@ -338,7 +345,10 @@ void ClientInterface::clearMessages()
if (provider && !m_chatFilePath.isEmpty() && provider->supportsTools()
&& provider->toolsManager()) {
provider->toolsManager()->clearTodoSession(m_chatFilePath);
if (auto *todoTool = qobject_cast<QodeAssist::Tools::TodoTool *>(
provider->toolsManager()->tool("todo_tool"))) {
todoTool->clearSession(m_chatFilePath);
}
}
m_chatModel->clear();
@ -619,7 +629,10 @@ void ClientInterface::setChatFilePath(const QString &filePath)
auto *provider = PluginLLMCore::ProvidersManager::instance().getProviderByName(providerName);
if (provider && provider->supportsTools() && provider->toolsManager()) {
provider->toolsManager()->clearTodoSession(m_chatFilePath);
if (auto *todoTool = qobject_cast<QodeAssist::Tools::TodoTool *>(
provider->toolsManager()->tool("todo_tool"))) {
todoTool->clearSession(m_chatFilePath);
}
}
}

View File

@ -34,6 +34,10 @@
#include "PromptTemplate.hpp"
#include "RequestType.hpp"
namespace LLMCore {
class ToolsManager;
}
class QNetworkReply;
class QJsonObject;
@ -75,7 +79,7 @@ public:
virtual void cancelRequest(const RequestID &requestId);
virtual IToolsManager *toolsManager() const { return nullptr; }
virtual ::LLMCore::ToolsManager *toolsManager() const { return nullptr; }
HttpClient *httpClient() const;

View File

@ -24,6 +24,8 @@
#include <QJsonObject>
#include <QUrlQuery>
#include <LLMCore/ToolsManager.hpp>
#include "pluginllmcore/ValidationUtils.hpp"
#include "logger/Logger.hpp"
#include "settings/ChatAssistantSettings.hpp"
@ -31,16 +33,19 @@
#include "settings/QuickRefactorSettings.hpp"
#include "settings/GeneralSettings.hpp"
#include "settings/ProviderSettings.hpp"
#include "tools/ToolsRegistration.hpp"
namespace QodeAssist::Providers {
ClaudeProvider::ClaudeProvider(QObject *parent)
: PluginLLMCore::Provider(parent)
, m_toolsManager(new Tools::ToolsManager(this))
, m_client(new ::LLMCore::ClaudeClient(url(), apiKey(), QString(), this))
{
Tools::registerQodeAssistTools(m_client->tools());
connect(
m_toolsManager,
&Tools::ToolsManager::toolExecutionComplete,
m_client->tools(),
&::LLMCore::ToolsManager::toolExecutionComplete,
this,
&ClaudeProvider::onToolExecutionComplete);
}
@ -131,8 +136,8 @@ void ClaudeProvider::prepareRequest(
filter = PluginLLMCore::RunToolsFilter::OnlyRead;
}
auto toolsDefinitions = m_toolsManager->getToolsDefinitions(
PluginLLMCore::ToolSchemaFormat::Claude, filter);
auto toolsDefinitions = m_client->tools()->getToolsDefinitions();
if (!toolsDefinitions.isEmpty()) {
request["tools"] = toolsDefinitions;
LOG_MESSAGE(QString("Added %1 tools to Claude request").arg(toolsDefinitions.size()));
@ -252,9 +257,9 @@ void ClaudeProvider::cancelRequest(const PluginLLMCore::RequestID &requestId)
cleanupRequest(requestId);
}
PluginLLMCore::IToolsManager *ClaudeProvider::toolsManager() const
::LLMCore::ToolsManager *ClaudeProvider::toolsManager() const
{
return m_toolsManager;
return m_client->tools();
}
void ClaudeProvider::onDataReceived(
@ -318,7 +323,7 @@ void ClaudeProvider::onToolExecutionComplete(
auto toolContent = message->getCurrentToolUseContent();
for (auto tool : toolContent) {
if (tool->id() == it.key()) {
auto toolStringName = m_toolsManager->toolsFactory()->getStringName(tool->name());
auto toolStringName = m_client->tools()->displayName(tool->name());
emit toolExecutionCompleted(
requestId, tool->id(), toolStringName, toolResults[tool->id()]);
break;
@ -434,7 +439,7 @@ void ClaudeProvider::processStreamEvent(const QString &requestId, const QJsonObj
if (!signature.isEmpty()) {
auto allBlocks = message->getCurrentBlocks();
if (index < allBlocks.size()) {
if (auto thinkingContent = qobject_cast<PluginLLMCore::ThinkingContent *>(allBlocks[index])) {
if (auto thinkingContent = dynamic_cast<::LLMCore::ThinkingContent *>(allBlocks[index])) {
thinkingContent->setSignature(signature);
LOG_MESSAGE(
QString("Updated thinking block signature from content_block_stop, "
@ -448,7 +453,7 @@ void ClaudeProvider::processStreamEvent(const QString &requestId, const QJsonObj
if (!signature.isEmpty()) {
auto allBlocks = message->getCurrentBlocks();
if (index < allBlocks.size()) {
if (auto redactedContent = qobject_cast<PluginLLMCore::RedactedThinkingContent *>(allBlocks[index])) {
if (auto redactedContent = dynamic_cast<::LLMCore::RedactedThinkingContent *>(allBlocks[index])) {
redactedContent->setSignature(signature);
LOG_MESSAGE(
QString("Updated redacted_thinking block signature from content_block_stop, "
@ -518,10 +523,10 @@ void ClaudeProvider::handleMessageComplete(const QString &requestId)
}
for (auto toolContent : toolUseContent) {
auto toolStringName = m_toolsManager->toolsFactory()->getStringName(toolContent->name());
auto toolStringName = m_client->tools()->displayName(toolContent->name());
emit toolExecutionStarted(requestId, toolContent->id(), toolStringName);
m_toolsManager->executeToolCall(
m_client->tools()->executeToolCall(
requestId, toolContent->id(), toolContent->name(), toolContent->input());
}
@ -542,7 +547,7 @@ void ClaudeProvider::cleanupRequest(const PluginLLMCore::RequestID &requestId)
m_dataBuffers.remove(requestId);
m_requestUrls.remove(requestId);
m_originalRequests.remove(requestId);
m_toolsManager->cleanupRequest(requestId);
m_client->tools()->cleanupRequest(requestId);
}
} // namespace QodeAssist::Providers

View File

@ -22,7 +22,7 @@
#include <pluginllmcore/Provider.hpp>
#include "ClaudeMessage.hpp"
#include "tools/ToolsManager.hpp"
#include <LLMCore/ClaudeClient.hpp>
namespace QodeAssist::Providers {
@ -58,7 +58,7 @@ public:
bool supportImage() const override;
void cancelRequest(const PluginLLMCore::RequestID &requestId) override;
PluginLLMCore::IToolsManager *toolsManager() const override;
::LLMCore::ToolsManager *toolsManager() const override;
public slots:
void onDataReceived(
@ -79,7 +79,7 @@ private:
QHash<QodeAssist::PluginLLMCore::RequestID, ClaudeMessage *> m_messages;
QHash<QodeAssist::PluginLLMCore::RequestID, QUrl> m_requestUrls;
QHash<QodeAssist::PluginLLMCore::RequestID, QJsonObject> m_originalRequests;
Tools::ToolsManager *m_toolsManager;
::LLMCore::ClaudeClient *m_client;
};
} // namespace QodeAssist::Providers

View File

@ -19,7 +19,10 @@
#include "GoogleAIProvider.hpp"
#include <LLMCore/ToolsManager.hpp>
#include <QJsonArray>
#include "tools/ToolsRegistration.hpp"
#include <QJsonDocument>
#include <QJsonObject>
#include <QtCore/qurlquery.h>
@ -36,11 +39,13 @@ namespace QodeAssist::Providers {
GoogleAIProvider::GoogleAIProvider(QObject *parent)
: PluginLLMCore::Provider(parent)
, m_toolsManager(new Tools::ToolsManager(this))
, m_client(new ::LLMCore::GoogleAIClient(url(), apiKey(), QString(), this))
{
Tools::registerQodeAssistTools(m_client->tools());
connect(
m_toolsManager,
&Tools::ToolsManager::toolExecutionComplete,
m_client->tools(),
&::LLMCore::ToolsManager::toolExecutionComplete,
this,
&GoogleAIProvider::onToolExecutionComplete);
}
@ -145,8 +150,7 @@ void GoogleAIProvider::prepareRequest(
filter = PluginLLMCore::RunToolsFilter::OnlyRead;
}
auto toolsDefinitions = m_toolsManager->getToolsDefinitions(
PluginLLMCore::ToolSchemaFormat::Google, filter);
auto toolsDefinitions = m_client->tools()->getToolsDefinitions();
if (!toolsDefinitions.isEmpty()) {
request["tools"] = toolsDefinitions;
LOG_MESSAGE(QString("Added %1 tools to Google AI request").arg(toolsDefinitions.size()));
@ -365,7 +369,7 @@ void GoogleAIProvider::onToolExecutionComplete(
auto toolContent = message->getCurrentToolUseContent();
for (auto tool : toolContent) {
if (tool->id() == it.key()) {
auto toolStringName = m_toolsManager->toolsFactory()->getStringName(tool->name());
auto toolStringName = m_client->tools()->displayName(tool->name());
emit toolExecutionCompleted(
requestId, tool->id(), toolStringName, toolResults[tool->id()]);
break;
@ -544,9 +548,9 @@ void GoogleAIProvider::handleMessageComplete(const QString &requestId)
}
for (auto toolContent : toolUseContent) {
auto toolStringName = m_toolsManager->toolsFactory()->getStringName(toolContent->name());
auto toolStringName = m_client->tools()->displayName(toolContent->name());
emit toolExecutionStarted(requestId, toolContent->id(), toolStringName);
m_toolsManager->executeToolCall(
m_client->tools()->executeToolCall(
requestId, toolContent->id(), toolContent->name(), toolContent->input());
}
@ -569,7 +573,12 @@ void GoogleAIProvider::cleanupRequest(const PluginLLMCore::RequestID &requestId)
m_originalRequests.remove(requestId);
m_emittedThinkingBlocksCount.remove(requestId);
m_failedRequests.remove(requestId);
m_toolsManager->cleanupRequest(requestId);
m_client->tools()->cleanupRequest(requestId);
}
::LLMCore::ToolsManager *GoogleAIProvider::toolsManager() const
{
return m_client->tools();
}
} // namespace QodeAssist::Providers

View File

@ -21,7 +21,7 @@
#include "GoogleMessage.hpp"
#include "pluginllmcore/Provider.hpp"
#include "tools/ToolsManager.hpp"
#include <LLMCore/GoogleAIClient.hpp>
namespace QodeAssist::Providers {
@ -57,6 +57,8 @@ public:
bool supportImage() const override;
void cancelRequest(const PluginLLMCore::RequestID &requestId) override;
::LLMCore::ToolsManager *toolsManager() const override;
public slots:
void onDataReceived(
const QodeAssist::PluginLLMCore::RequestID &requestId, const QByteArray &data) override;
@ -79,7 +81,7 @@ private:
QHash<PluginLLMCore::RequestID, QJsonObject> m_originalRequests;
QHash<PluginLLMCore::RequestID, int> m_emittedThinkingBlocksCount;
QSet<PluginLLMCore::RequestID> m_failedRequests;
Tools::ToolsManager *m_toolsManager;
::LLMCore::GoogleAIClient *m_client;
};
} // namespace QodeAssist::Providers

View File

@ -19,7 +19,10 @@
#include "LMStudioProvider.hpp"
#include <LLMCore/ToolsManager.hpp>
#include "pluginllmcore/ValidationUtils.hpp"
#include "tools/ToolsRegistration.hpp"
#include "logger/Logger.hpp"
#include "settings/ChatAssistantSettings.hpp"
#include "settings/CodeCompletionSettings.hpp"
@ -35,11 +38,13 @@ namespace QodeAssist::Providers {
LMStudioProvider::LMStudioProvider(QObject *parent)
: PluginLLMCore::Provider(parent)
, m_toolsManager(new Tools::ToolsManager(this))
, m_client(new ::LLMCore::OpenAIClient(url(), apiKey(), QString(), this))
{
Tools::registerQodeAssistTools(m_client->tools());
connect(
m_toolsManager,
&Tools::ToolsManager::toolExecutionComplete,
m_client->tools(),
&::LLMCore::ToolsManager::toolExecutionComplete,
this,
&LMStudioProvider::onToolExecutionComplete);
}
@ -250,8 +255,7 @@ void LMStudioProvider::prepareRequest(
filter = PluginLLMCore::RunToolsFilter::OnlyRead;
}
auto toolsDefinitions = m_toolsManager->getToolsDefinitions(
PluginLLMCore::ToolSchemaFormat::OpenAI, filter);
auto toolsDefinitions = m_client->tools()->getToolsDefinitions();
if (!toolsDefinitions.isEmpty()) {
request["tools"] = toolsDefinitions;
LOG_MESSAGE(QString("Added %1 tools to LMStudio request").arg(toolsDefinitions.size()));
@ -275,7 +279,7 @@ void LMStudioProvider::onToolExecutionComplete(
auto toolContent = message->getCurrentToolUseContent();
for (auto tool : toolContent) {
if (tool->id() == it.key()) {
auto toolStringName = m_toolsManager->toolsFactory()->getStringName(tool->name());
auto toolStringName = m_client->tools()->displayName(tool->name());
emit toolExecutionCompleted(
requestId, tool->id(), toolStringName, toolResults[tool->id()]);
break;
@ -392,9 +396,9 @@ void LMStudioProvider::handleMessageComplete(const QString &requestId)
}
for (auto toolContent : toolUseContent) {
auto toolStringName = m_toolsManager->toolsFactory()->getStringName(toolContent->name());
auto toolStringName = m_client->tools()->displayName(toolContent->name());
emit toolExecutionStarted(requestId, toolContent->id(), toolStringName);
m_toolsManager->executeToolCall(
m_client->tools()->executeToolCall(
requestId, toolContent->id(), toolContent->name(), toolContent->input());
}
@ -415,7 +419,12 @@ void LMStudioProvider::cleanupRequest(const PluginLLMCore::RequestID &requestId)
m_dataBuffers.remove(requestId);
m_requestUrls.remove(requestId);
m_originalRequests.remove(requestId);
m_toolsManager->cleanupRequest(requestId);
m_client->tools()->cleanupRequest(requestId);
}
::LLMCore::ToolsManager *LMStudioProvider::toolsManager() const
{
return m_client->tools();
}
} // namespace QodeAssist::Providers

View File

@ -20,7 +20,7 @@
#pragma once
#include "OpenAIMessage.hpp"
#include "tools/ToolsManager.hpp"
#include <LLMCore/OpenAIClient.hpp>
#include <pluginllmcore/Provider.hpp>
namespace QodeAssist::Providers {
@ -56,6 +56,8 @@ public:
bool supportImage() const override;
void cancelRequest(const PluginLLMCore::RequestID &requestId) override;
::LLMCore::ToolsManager *toolsManager() const override;
public slots:
void onDataReceived(
const QodeAssist::PluginLLMCore::RequestID &requestId, const QByteArray &data) override;
@ -75,7 +77,7 @@ private:
QHash<PluginLLMCore::RequestID, OpenAIMessage *> m_messages;
QHash<PluginLLMCore::RequestID, QUrl> m_requestUrls;
QHash<PluginLLMCore::RequestID, QJsonObject> m_originalRequests;
Tools::ToolsManager *m_toolsManager;
::LLMCore::OpenAIClient *m_client;
};
} // namespace QodeAssist::Providers

View File

@ -19,12 +19,14 @@
#include "LlamaCppProvider.hpp"
#include <LLMCore/ToolsManager.hpp>
#include "pluginllmcore/ValidationUtils.hpp"
#include "logger/Logger.hpp"
#include "settings/ChatAssistantSettings.hpp"
#include "settings/CodeCompletionSettings.hpp"
#include "settings/QuickRefactorSettings.hpp"
#include "settings/GeneralSettings.hpp"
#include "tools/ToolsRegistration.hpp"
#include <QJsonArray>
#include <QJsonDocument>
@ -34,11 +36,13 @@ namespace QodeAssist::Providers {
LlamaCppProvider::LlamaCppProvider(QObject *parent)
: PluginLLMCore::Provider(parent)
, m_toolsManager(new Tools::ToolsManager(this))
, m_client(new ::LLMCore::LlamaCppClient(url(), apiKey(), QString(), this))
{
Tools::registerQodeAssistTools(m_client->tools());
connect(
m_toolsManager,
&Tools::ToolsManager::toolExecutionComplete,
m_client->tools(),
&::LLMCore::ToolsManager::toolExecutionComplete,
this,
&LlamaCppProvider::onToolExecutionComplete);
}
@ -110,8 +114,7 @@ void LlamaCppProvider::prepareRequest(
filter = PluginLLMCore::RunToolsFilter::OnlyRead;
}
auto toolsDefinitions = m_toolsManager->getToolsDefinitions(
PluginLLMCore::ToolSchemaFormat::OpenAI, filter);
auto toolsDefinitions = m_client->tools()->getToolsDefinitions();
if (!toolsDefinitions.isEmpty()) {
request["tools"] = toolsDefinitions;
LOG_MESSAGE(QString("Added %1 tools to llama.cpp request").arg(toolsDefinitions.size()));
@ -290,7 +293,7 @@ void LlamaCppProvider::onToolExecutionComplete(
auto toolContent = message->getCurrentToolUseContent();
for (auto tool : toolContent) {
if (tool->id() == it.key()) {
auto toolStringName = m_toolsManager->toolsFactory()->getStringName(tool->name());
auto toolStringName = m_client->tools()->displayName(tool->name());
emit toolExecutionCompleted(
requestId, tool->id(), toolStringName, toolResults[tool->id()]);
break;
@ -407,9 +410,9 @@ void LlamaCppProvider::handleMessageComplete(const QString &requestId)
}
for (auto toolContent : toolUseContent) {
auto toolStringName = m_toolsManager->toolsFactory()->getStringName(toolContent->name());
auto toolStringName = m_client->tools()->displayName(toolContent->name());
emit toolExecutionStarted(requestId, toolContent->id(), toolStringName);
m_toolsManager->executeToolCall(
m_client->tools()->executeToolCall(
requestId, toolContent->id(), toolContent->name(), toolContent->input());
}
@ -430,7 +433,12 @@ void LlamaCppProvider::cleanupRequest(const PluginLLMCore::RequestID &requestId)
m_dataBuffers.remove(requestId);
m_requestUrls.remove(requestId);
m_originalRequests.remove(requestId);
m_toolsManager->cleanupRequest(requestId);
m_client->tools()->cleanupRequest(requestId);
}
::LLMCore::ToolsManager *LlamaCppProvider::toolsManager() const
{
return m_client->tools();
}
} // namespace QodeAssist::Providers

View File

@ -20,7 +20,7 @@
#pragma once
#include "OpenAIMessage.hpp"
#include "tools/ToolsManager.hpp"
#include <LLMCore/LlamaCppClient.hpp>
#include <pluginllmcore/Provider.hpp>
namespace QodeAssist::Providers {
@ -56,6 +56,8 @@ public:
bool supportImage() const override;
void cancelRequest(const PluginLLMCore::RequestID &requestId) override;
::LLMCore::ToolsManager *toolsManager() const override;
public slots:
void onDataReceived(
const QodeAssist::PluginLLMCore::RequestID &requestId, const QByteArray &data) override;
@ -75,7 +77,7 @@ private:
QHash<PluginLLMCore::RequestID, OpenAIMessage *> m_messages;
QHash<PluginLLMCore::RequestID, QUrl> m_requestUrls;
QHash<PluginLLMCore::RequestID, QJsonObject> m_originalRequests;
Tools::ToolsManager *m_toolsManager;
::LLMCore::LlamaCppClient *m_client;
};
} // namespace QodeAssist::Providers

View File

@ -19,6 +19,7 @@
#include "MistralAIProvider.hpp"
#include <LLMCore/ToolsManager.hpp>
#include "pluginllmcore/ValidationUtils.hpp"
#include "logger/Logger.hpp"
#include "settings/ChatAssistantSettings.hpp"
@ -26,6 +27,7 @@
#include "settings/QuickRefactorSettings.hpp"
#include "settings/GeneralSettings.hpp"
#include "settings/ProviderSettings.hpp"
#include "tools/ToolsRegistration.hpp"
#include <QJsonArray>
#include <QJsonDocument>
@ -35,11 +37,13 @@ namespace QodeAssist::Providers {
MistralAIProvider::MistralAIProvider(QObject *parent)
: PluginLLMCore::Provider(parent)
, m_toolsManager(new Tools::ToolsManager(this))
, m_client(new ::LLMCore::OpenAIClient(url(), apiKey(), QString(), this))
{
Tools::registerQodeAssistTools(m_client->tools());
connect(
m_toolsManager,
&Tools::ToolsManager::toolExecutionComplete,
m_client->tools(),
&::LLMCore::ToolsManager::toolExecutionComplete,
this,
&MistralAIProvider::onToolExecutionComplete);
}
@ -271,8 +275,7 @@ void MistralAIProvider::prepareRequest(
filter = PluginLLMCore::RunToolsFilter::OnlyRead;
}
auto toolsDefinitions = m_toolsManager->getToolsDefinitions(
PluginLLMCore::ToolSchemaFormat::OpenAI, filter);
auto toolsDefinitions = m_client->tools()->getToolsDefinitions();
if (!toolsDefinitions.isEmpty()) {
request["tools"] = toolsDefinitions;
LOG_MESSAGE(QString("Added %1 tools to Mistral request").arg(toolsDefinitions.size()));
@ -296,7 +299,7 @@ void MistralAIProvider::onToolExecutionComplete(
auto toolContent = message->getCurrentToolUseContent();
for (auto tool : toolContent) {
if (tool->id() == it.key()) {
auto toolStringName = m_toolsManager->toolsFactory()->getStringName(tool->name());
auto toolStringName = m_client->tools()->displayName(tool->name());
emit toolExecutionCompleted(
requestId, tool->id(), toolStringName, toolResults[tool->id()]);
break;
@ -413,9 +416,9 @@ void MistralAIProvider::handleMessageComplete(const QString &requestId)
}
for (auto toolContent : toolUseContent) {
auto toolStringName = m_toolsManager->toolsFactory()->getStringName(toolContent->name());
auto toolStringName = m_client->tools()->displayName(toolContent->name());
emit toolExecutionStarted(requestId, toolContent->id(), toolStringName);
m_toolsManager->executeToolCall(
m_client->tools()->executeToolCall(
requestId, toolContent->id(), toolContent->name(), toolContent->input());
}
@ -436,7 +439,12 @@ void MistralAIProvider::cleanupRequest(const PluginLLMCore::RequestID &requestId
m_dataBuffers.remove(requestId);
m_requestUrls.remove(requestId);
m_originalRequests.remove(requestId);
m_toolsManager->cleanupRequest(requestId);
m_client->tools()->cleanupRequest(requestId);
}
::LLMCore::ToolsManager *MistralAIProvider::toolsManager() const
{
return m_client->tools();
}
} // namespace QodeAssist::Providers

View File

@ -20,7 +20,7 @@
#pragma once
#include "OpenAIMessage.hpp"
#include "tools/ToolsManager.hpp"
#include <LLMCore/OpenAIClient.hpp>
#include <pluginllmcore/Provider.hpp>
namespace QodeAssist::Providers {
@ -56,6 +56,8 @@ public:
bool supportImage() const override;
void cancelRequest(const PluginLLMCore::RequestID &requestId) override;
::LLMCore::ToolsManager *toolsManager() const override;
public slots:
void onDataReceived(
const QodeAssist::PluginLLMCore::RequestID &requestId, const QByteArray &data) override;
@ -75,7 +77,7 @@ private:
QHash<PluginLLMCore::RequestID, OpenAIMessage *> m_messages;
QHash<PluginLLMCore::RequestID, QUrl> m_requestUrls;
QHash<PluginLLMCore::RequestID, QJsonObject> m_originalRequests;
Tools::ToolsManager *m_toolsManager;
::LLMCore::OpenAIClient *m_client;
};
} // namespace QodeAssist::Providers

View File

@ -19,7 +19,10 @@
#include "OllamaProvider.hpp"
#include <LLMCore/ToolsManager.hpp>
#include <QJsonArray>
#include "tools/ToolsRegistration.hpp"
#include <QJsonDocument>
#include <QJsonObject>
@ -35,11 +38,13 @@ namespace QodeAssist::Providers {
OllamaProvider::OllamaProvider(QObject *parent)
: PluginLLMCore::Provider(parent)
, m_toolsManager(new Tools::ToolsManager(this))
, m_client(new ::LLMCore::OllamaClient(url(), apiKey(), QString(), this))
{
Tools::registerQodeAssistTools(m_client->tools());
connect(
m_toolsManager,
&Tools::ToolsManager::toolExecutionComplete,
m_client->tools(),
&::LLMCore::ToolsManager::toolExecutionComplete,
this,
&OllamaProvider::onToolExecutionComplete);
}
@ -135,8 +140,7 @@ void OllamaProvider::prepareRequest(
filter = PluginLLMCore::RunToolsFilter::OnlyRead;
}
auto toolsDefinitions = m_toolsManager->toolsFactory()->getToolsDefinitions(
PluginLLMCore::ToolSchemaFormat::Ollama, filter);
auto toolsDefinitions = m_client->tools()->getToolsDefinitions();
if (!toolsDefinitions.isEmpty()) {
request["tools"] = toolsDefinitions;
LOG_MESSAGE(
@ -358,7 +362,7 @@ void OllamaProvider::onToolExecutionComplete(
auto toolContent = message->getCurrentToolUseContent();
for (auto tool : toolContent) {
if (tool->id() == it.key()) {
auto toolStringName = m_toolsManager->toolsFactory()->getStringName(tool->name());
auto toolStringName = m_client->tools()->displayName(tool->name());
emit toolExecutionCompleted(requestId, tool->id(), toolStringName, it.value());
break;
}
@ -534,7 +538,7 @@ void OllamaProvider::handleMessageComplete(const QString &requestId)
}
for (auto toolContent : toolUseContent) {
auto toolStringName = m_toolsManager->toolsFactory()->getStringName(toolContent->name());
auto toolStringName = m_client->tools()->displayName(toolContent->name());
emit toolExecutionStarted(requestId, toolContent->id(), toolStringName);
LOG_MESSAGE(
@ -545,7 +549,7 @@ void OllamaProvider::handleMessageComplete(const QString &requestId)
QString::fromUtf8(
QJsonDocument(toolContent->input()).toJson(QJsonDocument::Compact))));
m_toolsManager->executeToolCall(
m_client->tools()->executeToolCall(
requestId, toolContent->id(), toolContent->name(), toolContent->input());
}
@ -568,7 +572,7 @@ void OllamaProvider::cleanupRequest(const PluginLLMCore::RequestID &requestId)
m_originalRequests.remove(requestId);
m_thinkingEmitted.remove(requestId);
m_thinkingStarted.remove(requestId);
m_toolsManager->cleanupRequest(requestId);
m_client->tools()->cleanupRequest(requestId);
}
void OllamaProvider::emitThinkingBlocks(const QString &requestId, OllamaMessage *message)
@ -594,4 +598,9 @@ void OllamaProvider::emitThinkingBlocks(const QString &requestId, OllamaMessage
m_thinkingEmitted.insert(requestId);
}
::LLMCore::ToolsManager *OllamaProvider::toolsManager() const
{
return m_client->tools();
}
} // namespace QodeAssist::Providers

View File

@ -22,7 +22,7 @@
#include <pluginllmcore/Provider.hpp>
#include "OllamaMessage.hpp"
#include "tools/ToolsManager.hpp"
#include <LLMCore/OllamaClient.hpp>
namespace QodeAssist::Providers {
@ -58,6 +58,8 @@ public:
bool supportThinking() const override;
void cancelRequest(const PluginLLMCore::RequestID &requestId) override;
::LLMCore::ToolsManager *toolsManager() const override;
public slots:
void onDataReceived(
const QodeAssist::PluginLLMCore::RequestID &requestId, const QByteArray &data) override;
@ -80,7 +82,7 @@ private:
QHash<QodeAssist::PluginLLMCore::RequestID, QJsonObject> m_originalRequests;
QSet<QString> m_thinkingEmitted;
QSet<QString> m_thinkingStarted;
Tools::ToolsManager *m_toolsManager;
::LLMCore::OllamaClient *m_client;
};
} // namespace QodeAssist::Providers

View File

@ -18,8 +18,10 @@
*/
#include "OpenAICompatProvider.hpp"
#include <LLMCore/ToolsManager.hpp>
#include "pluginllmcore/ValidationUtils.hpp"
#include "tools/ToolsRegistration.hpp"
#include "logger/Logger.hpp"
#include "settings/ChatAssistantSettings.hpp"
#include "settings/CodeCompletionSettings.hpp"
@ -36,11 +38,13 @@ namespace QodeAssist::Providers {
OpenAICompatProvider::OpenAICompatProvider(QObject *parent)
: PluginLLMCore::Provider(parent)
, m_toolsManager(new Tools::ToolsManager(this))
, m_client(new ::LLMCore::OpenAIClient(url(), apiKey(), QString(), this))
{
Tools::registerQodeAssistTools(m_client->tools());
connect(
m_toolsManager,
&Tools::ToolsManager::toolExecutionComplete,
m_client->tools(),
&::LLMCore::ToolsManager::toolExecutionComplete,
this,
&OpenAICompatProvider::onToolExecutionComplete);
}
@ -112,8 +116,7 @@ void OpenAICompatProvider::prepareRequest(
filter = PluginLLMCore::RunToolsFilter::OnlyRead;
}
auto toolsDefinitions = m_toolsManager->getToolsDefinitions(
PluginLLMCore::ToolSchemaFormat::OpenAI, filter);
auto toolsDefinitions = m_client->tools()->getToolsDefinitions();
if (!toolsDefinitions.isEmpty()) {
request["tools"] = toolsDefinitions;
LOG_MESSAGE(
@ -266,7 +269,7 @@ void OpenAICompatProvider::onToolExecutionComplete(
auto toolContent = message->getCurrentToolUseContent();
for (auto tool : toolContent) {
if (tool->id() == it.key()) {
auto toolStringName = m_toolsManager->toolsFactory()->getStringName(tool->name());
auto toolStringName = m_client->tools()->displayName(tool->name());
emit toolExecutionCompleted(
requestId, tool->id(), toolStringName, toolResults[tool->id()]);
break;
@ -383,9 +386,9 @@ void OpenAICompatProvider::handleMessageComplete(const QString &requestId)
}
for (auto toolContent : toolUseContent) {
auto toolStringName = m_toolsManager->toolsFactory()->getStringName(toolContent->name());
auto toolStringName = m_client->tools()->displayName(toolContent->name());
emit toolExecutionStarted(requestId, toolContent->id(), toolStringName);
m_toolsManager->executeToolCall(
m_client->tools()->executeToolCall(
requestId, toolContent->id(), toolContent->name(), toolContent->input());
}
@ -406,7 +409,12 @@ void OpenAICompatProvider::cleanupRequest(const PluginLLMCore::RequestID &reques
m_dataBuffers.remove(requestId);
m_requestUrls.remove(requestId);
m_originalRequests.remove(requestId);
m_toolsManager->cleanupRequest(requestId);
m_client->tools()->cleanupRequest(requestId);
}
::LLMCore::ToolsManager *OpenAICompatProvider::toolsManager() const
{
return m_client->tools();
}
} // namespace QodeAssist::Providers

View File

@ -20,7 +20,7 @@
#pragma once
#include "OpenAIMessage.hpp"
#include "tools/ToolsManager.hpp"
#include <LLMCore/OpenAIClient.hpp>
#include <pluginllmcore/Provider.hpp>
namespace QodeAssist::Providers {
@ -56,6 +56,8 @@ public:
bool supportImage() const override;
void cancelRequest(const PluginLLMCore::RequestID &requestId) override;
::LLMCore::ToolsManager *toolsManager() const override;
public slots:
void onDataReceived(
const QodeAssist::PluginLLMCore::RequestID &requestId, const QByteArray &data) override;
@ -75,7 +77,7 @@ private:
QHash<PluginLLMCore::RequestID, OpenAIMessage *> m_messages;
QHash<PluginLLMCore::RequestID, QUrl> m_requestUrls;
QHash<PluginLLMCore::RequestID, QJsonObject> m_originalRequests;
Tools::ToolsManager *m_toolsManager;
::LLMCore::OpenAIClient *m_client;
};
} // namespace QodeAssist::Providers

View File

@ -19,6 +19,8 @@
#include "OpenAIProvider.hpp"
#include <LLMCore/ToolsManager.hpp>
#include "tools/ToolsRegistration.hpp"
#include "pluginllmcore/ValidationUtils.hpp"
#include "logger/Logger.hpp"
#include "settings/ChatAssistantSettings.hpp"
@ -35,11 +37,13 @@ namespace QodeAssist::Providers {
OpenAIProvider::OpenAIProvider(QObject *parent)
: PluginLLMCore::Provider(parent)
, m_toolsManager(new Tools::ToolsManager(this))
, m_client(new ::LLMCore::OpenAIClient(url(), apiKey(), QString(), this))
{
Tools::registerQodeAssistTools(m_client->tools());
connect(
m_toolsManager,
&Tools::ToolsManager::toolExecutionComplete,
m_client->tools(),
&::LLMCore::ToolsManager::toolExecutionComplete,
this,
&OpenAIProvider::onToolExecutionComplete);
}
@ -130,8 +134,7 @@ void OpenAIProvider::prepareRequest(
filter = PluginLLMCore::RunToolsFilter::OnlyRead;
}
auto toolsDefinitions = m_toolsManager->getToolsDefinitions(
PluginLLMCore::ToolSchemaFormat::OpenAI, filter);
auto toolsDefinitions = m_client->tools()->getToolsDefinitions();
if (!toolsDefinitions.isEmpty()) {
request["tools"] = toolsDefinitions;
LOG_MESSAGE(QString("Added %1 tools to OpenAI request").arg(toolsDefinitions.size()));
@ -310,7 +313,7 @@ void OpenAIProvider::onToolExecutionComplete(
auto toolContent = message->getCurrentToolUseContent();
for (auto tool : toolContent) {
if (tool->id() == it.key()) {
auto toolStringName = m_toolsManager->toolsFactory()->getStringName(tool->name());
auto toolStringName = m_client->tools()->displayName(tool->name());
emit toolExecutionCompleted(
requestId, tool->id(), toolStringName, toolResults[tool->id()]);
break;
@ -427,9 +430,9 @@ void OpenAIProvider::handleMessageComplete(const QString &requestId)
}
for (auto toolContent : toolUseContent) {
auto toolStringName = m_toolsManager->toolsFactory()->getStringName(toolContent->name());
auto toolStringName = m_client->tools()->displayName(toolContent->name());
emit toolExecutionStarted(requestId, toolContent->id(), toolStringName);
m_toolsManager->executeToolCall(
m_client->tools()->executeToolCall(
requestId, toolContent->id(), toolContent->name(), toolContent->input());
}
@ -450,7 +453,12 @@ void OpenAIProvider::cleanupRequest(const PluginLLMCore::RequestID &requestId)
m_dataBuffers.remove(requestId);
m_requestUrls.remove(requestId);
m_originalRequests.remove(requestId);
m_toolsManager->cleanupRequest(requestId);
m_client->tools()->cleanupRequest(requestId);
}
::LLMCore::ToolsManager *OpenAIProvider::toolsManager() const
{
return m_client->tools();
}
} // namespace QodeAssist::Providers

View File

@ -20,7 +20,7 @@
#pragma once
#include "OpenAIMessage.hpp"
#include "tools/ToolsManager.hpp"
#include <LLMCore/OpenAIClient.hpp>
#include <pluginllmcore/Provider.hpp>
namespace QodeAssist::Providers {
@ -56,6 +56,8 @@ public:
bool supportImage() const override;
void cancelRequest(const PluginLLMCore::RequestID &requestId) override;
::LLMCore::ToolsManager *toolsManager() const override;
public slots:
void onDataReceived(
const QodeAssist::PluginLLMCore::RequestID &requestId, const QByteArray &data) override;
@ -75,7 +77,7 @@ private:
QHash<PluginLLMCore::RequestID, OpenAIMessage *> m_messages;
QHash<PluginLLMCore::RequestID, QUrl> m_requestUrls;
QHash<PluginLLMCore::RequestID, QJsonObject> m_originalRequests;
Tools::ToolsManager *m_toolsManager;
::LLMCore::OpenAIClient *m_client;
};
} // namespace QodeAssist::Providers

View File

@ -18,7 +18,9 @@
*/
#include "OpenAIResponsesProvider.hpp"
#include <LLMCore/ToolsManager.hpp>
#include "OpenAIResponses/ResponseObject.hpp"
#include "tools/ToolsRegistration.hpp"
#include "pluginllmcore/ValidationUtils.hpp"
#include "logger/Logger.hpp"
@ -36,11 +38,13 @@ namespace QodeAssist::Providers {
OpenAIResponsesProvider::OpenAIResponsesProvider(QObject *parent)
: PluginLLMCore::Provider(parent)
, m_toolsManager(new Tools::ToolsManager(this))
, m_client(new ::LLMCore::OpenAIResponsesClient(url(), apiKey(), QString(), this))
{
Tools::registerQodeAssistTools(m_client->tools());
connect(
m_toolsManager,
&Tools::ToolsManager::toolExecutionComplete,
m_client->tools(),
&::LLMCore::ToolsManager::toolExecutionComplete,
this,
&OpenAIResponsesProvider::onToolExecutionComplete);
}
@ -133,7 +137,7 @@ void OpenAIResponsesProvider::prepareRequest(
: PluginLLMCore::RunToolsFilter::ALL;
const auto toolsDefinitions
= m_toolsManager->getToolsDefinitions(PluginLLMCore::ToolSchemaFormat::OpenAI, filter);
= m_client->tools()->getToolsDefinitions();
if (!toolsDefinitions.isEmpty()) {
QJsonArray responsesTools;
@ -579,10 +583,10 @@ void OpenAIResponsesProvider::handleMessageComplete(const QString &requestId)
}
for (const auto *toolContent : toolUseContent) {
const auto toolStringName = m_toolsManager->toolsFactory()->getStringName(
const auto toolStringName = m_client->tools()->displayName(
toolContent->name());
emit toolExecutionStarted(requestId, toolContent->id(), toolStringName);
m_toolsManager->executeToolCall(
m_client->tools()->executeToolCall(
requestId, toolContent->id(), toolContent->name(), toolContent->input());
}
}
@ -604,7 +608,7 @@ void OpenAIResponsesProvider::onToolExecutionComplete(
for (auto it = toolResults.constBegin(); it != toolResults.constEnd(); ++it) {
for (const auto *tool : toolContent) {
if (tool->id() == it.key()) {
const auto toolStringName = m_toolsManager->toolsFactory()->getStringName(
const auto toolStringName = m_client->tools()->displayName(
tool->name());
emit toolExecutionCompleted(
requestId, tool->id(), toolStringName, toolResults[tool->id()]);
@ -645,7 +649,12 @@ void OpenAIResponsesProvider::cleanupRequest(const PluginLLMCore::RequestID &req
m_originalRequests.remove(requestId);
m_itemIdToCallId.remove(requestId);
m_emittedThinkingBlocksCount.remove(requestId);
m_toolsManager->cleanupRequest(requestId);
m_client->tools()->cleanupRequest(requestId);
}
::LLMCore::ToolsManager *OpenAIResponsesProvider::toolsManager() const
{
return m_client->tools();
}
} // namespace QodeAssist::Providers

View File

@ -20,7 +20,7 @@
#pragma once
#include "OpenAIResponsesMessage.hpp"
#include "tools/ToolsManager.hpp"
#include <LLMCore/OpenAIResponsesClient.hpp>
#include <pluginllmcore/Provider.hpp>
namespace QodeAssist::Providers {
@ -57,6 +57,8 @@ public:
bool supportThinking() const override;
void cancelRequest(const PluginLLMCore::RequestID &requestId) override;
::LLMCore::ToolsManager *toolsManager() const override;
public slots:
void onDataReceived(
const QodeAssist::PluginLLMCore::RequestID &requestId, const QByteArray &data) override;
@ -79,7 +81,7 @@ private:
QHash<PluginLLMCore::RequestID, QJsonObject> m_originalRequests;
QHash<PluginLLMCore::RequestID, QHash<QString, QString>> m_itemIdToCallId;
QHash<PluginLLMCore::RequestID, int> m_emittedThinkingBlocksCount;
Tools::ToolsManager *m_toolsManager;
::LLMCore::OpenAIResponsesClient *m_client;
};
} // namespace QodeAssist::Providers

View File

@ -59,12 +59,12 @@ BuildProjectTool::~BuildProjectTool()
m_activeBuilds.clear();
}
QString BuildProjectTool::name() const
QString BuildProjectTool::id() const
{
return "build_project";
}
QString BuildProjectTool::stringName() const
QString BuildProjectTool::displayName() const
{
return "Building and running project";
}
@ -80,7 +80,7 @@ QString BuildProjectTool::description() const
"Note: This operation may take some time depending on project size.";
}
QJsonObject BuildProjectTool::getDefinition(PluginLLMCore::ToolSchemaFormat format) const
QJsonObject BuildProjectTool::parametersSchema() const
{
QJsonObject definition;
definition["type"] = "object";
@ -96,26 +96,9 @@ QJsonObject BuildProjectTool::getDefinition(PluginLLMCore::ToolSchemaFormat form
definition["properties"] = properties;
definition["required"] = QJsonArray();
switch (format) {
case PluginLLMCore::ToolSchemaFormat::OpenAI:
return customizeForOpenAI(definition);
case PluginLLMCore::ToolSchemaFormat::Claude:
return customizeForClaude(definition);
case PluginLLMCore::ToolSchemaFormat::Ollama:
return customizeForOllama(definition);
case PluginLLMCore::ToolSchemaFormat::Google:
return customizeForGoogle(definition);
}
return definition;
}
PluginLLMCore::ToolPermissions BuildProjectTool::requiredPermissions() const
{
return PluginLLMCore::ToolPermission::FileSystemRead
| PluginLLMCore::ToolPermission::FileSystemWrite;
}
QFuture<QString> BuildProjectTool::executeAsync(const QJsonObject &input)
{
auto *project = ProjectExplorer::ProjectManager::startupProject();

View File

@ -19,7 +19,7 @@
#pragma once
#include <pluginllmcore/BaseTool.hpp>
#include <LLMCore/BaseTool.hpp>
#include <QHash>
#include <QObject>
#include <QPointer>
@ -42,18 +42,17 @@ struct BuildInfo
QMetaObject::Connection buildFinishedConnection;
};
class BuildProjectTool : public PluginLLMCore::BaseTool
class BuildProjectTool : public ::LLMCore::BaseTool
{
Q_OBJECT
public:
explicit BuildProjectTool(QObject *parent = nullptr);
~BuildProjectTool() override;
QString name() const override;
QString stringName() const override;
QString id() const override;
QString displayName() const override;
QString description() const override;
QJsonObject getDefinition(PluginLLMCore::ToolSchemaFormat format) const override;
PluginLLMCore::ToolPermissions requiredPermissions() const override;
QJsonObject parametersSchema() const override;
QFuture<QString> executeAsync(const QJsonObject &input = QJsonObject()) override;

View File

@ -36,12 +36,12 @@ CreateNewFileTool::CreateNewFileTool(QObject *parent)
: BaseTool(parent)
{}
QString CreateNewFileTool::name() const
QString CreateNewFileTool::id() const
{
return "create_new_file";
}
QString CreateNewFileTool::stringName() const
QString CreateNewFileTool::displayName() const
{
return {"Creating new file"};
}
@ -54,7 +54,7 @@ QString CreateNewFileTool::description() const
"to the project file";
}
QJsonObject CreateNewFileTool::getDefinition(PluginLLMCore::ToolSchemaFormat format) const
QJsonObject CreateNewFileTool::parametersSchema() const
{
QJsonObject properties;
@ -70,25 +70,9 @@ QJsonObject CreateNewFileTool::getDefinition(PluginLLMCore::ToolSchemaFormat for
required.append("filepath");
definition["required"] = required;
switch (format) {
case PluginLLMCore::ToolSchemaFormat::OpenAI:
return customizeForOpenAI(definition);
case PluginLLMCore::ToolSchemaFormat::Claude:
return customizeForClaude(definition);
case PluginLLMCore::ToolSchemaFormat::Ollama:
return customizeForOllama(definition);
case PluginLLMCore::ToolSchemaFormat::Google:
return customizeForGoogle(definition);
}
return definition;
}
PluginLLMCore::ToolPermissions CreateNewFileTool::requiredPermissions() const
{
return PluginLLMCore::ToolPermission::FileSystemWrite;
}
QFuture<QString> CreateNewFileTool::executeAsync(const QJsonObject &input)
{
return QtConcurrent::run([this, input]() -> QString {

View File

@ -19,21 +19,20 @@
#pragma once
#include <pluginllmcore/BaseTool.hpp>
#include <LLMCore/BaseTool.hpp>
namespace QodeAssist::Tools {
class CreateNewFileTool : public PluginLLMCore::BaseTool
class CreateNewFileTool : public ::LLMCore::BaseTool
{
Q_OBJECT
public:
explicit CreateNewFileTool(QObject *parent = nullptr);
QString name() const override;
QString stringName() const override;
QString id() const override;
QString displayName() const override;
QString description() const override;
QJsonObject getDefinition(PluginLLMCore::ToolSchemaFormat format) const override;
PluginLLMCore::ToolPermissions requiredPermissions() const override;
QJsonObject parametersSchema() const override;
QFuture<QString> executeAsync(const QJsonObject &input = QJsonObject()) override;
};

View File

@ -39,12 +39,12 @@ EditFileTool::EditFileTool(QObject *parent)
: BaseTool(parent)
{}
QString EditFileTool::name() const
QString EditFileTool::id() const
{
return "edit_file";
}
QString EditFileTool::stringName() const
QString EditFileTool::displayName() const
{
return {"Editing file"};
}
@ -71,7 +71,7 @@ QString EditFileTool::description() const
"disabled auto-apply. DO NOT retry the same edit - wait for user action.";
}
QJsonObject EditFileTool::getDefinition(PluginLLMCore::ToolSchemaFormat format) const
QJsonObject EditFileTool::parametersSchema() const
{
QJsonObject properties;
@ -104,25 +104,9 @@ QJsonObject EditFileTool::getDefinition(PluginLLMCore::ToolSchemaFormat format)
required.append("new_content");
definition["required"] = required;
switch (format) {
case PluginLLMCore::ToolSchemaFormat::OpenAI:
return customizeForOpenAI(definition);
case PluginLLMCore::ToolSchemaFormat::Claude:
return customizeForClaude(definition);
case PluginLLMCore::ToolSchemaFormat::Ollama:
return customizeForOllama(definition);
case PluginLLMCore::ToolSchemaFormat::Google:
return customizeForGoogle(definition);
}
return definition;
}
PluginLLMCore::ToolPermissions EditFileTool::requiredPermissions() const
{
return PluginLLMCore::ToolPermission::FileSystemWrite;
}
QFuture<QString> EditFileTool::executeAsync(const QJsonObject &input)
{
return QtConcurrent::run([this, input]() -> QString {

View File

@ -19,21 +19,20 @@
#pragma once
#include <pluginllmcore/BaseTool.hpp>
#include <LLMCore/BaseTool.hpp>
namespace QodeAssist::Tools {
class EditFileTool : public PluginLLMCore::BaseTool
class EditFileTool : public ::LLMCore::BaseTool
{
Q_OBJECT
public:
explicit EditFileTool(QObject *parent = nullptr);
QString name() const override;
QString stringName() const override;
QString id() const override;
QString displayName() const override;
QString description() const override;
QJsonObject getDefinition(PluginLLMCore::ToolSchemaFormat format) const override;
PluginLLMCore::ToolPermissions requiredPermissions() const override;
QJsonObject parametersSchema() const override;
QFuture<QString> executeAsync(const QJsonObject &input = QJsonObject()) override;
};

View File

@ -41,12 +41,12 @@ ExecuteTerminalCommandTool::ExecuteTerminalCommandTool(QObject *parent)
{
}
QString ExecuteTerminalCommandTool::name() const
QString ExecuteTerminalCommandTool::id() const
{
return "execute_terminal_command";
}
QString ExecuteTerminalCommandTool::stringName() const
QString ExecuteTerminalCommandTool::displayName() const
{
return "Executing terminal command";
}
@ -56,7 +56,7 @@ QString ExecuteTerminalCommandTool::description() const
return getCommandDescription();
}
QJsonObject ExecuteTerminalCommandTool::getDefinition(PluginLLMCore::ToolSchemaFormat format) const
QJsonObject ExecuteTerminalCommandTool::parametersSchema() const
{
QJsonObject definition;
definition["type"] = "object";
@ -77,27 +77,9 @@ QJsonObject ExecuteTerminalCommandTool::getDefinition(PluginLLMCore::ToolSchemaF
definition["properties"] = properties;
definition["required"] = QJsonArray{"command"};
switch (format) {
case PluginLLMCore::ToolSchemaFormat::OpenAI:
return customizeForOpenAI(definition);
case PluginLLMCore::ToolSchemaFormat::Claude:
return customizeForClaude(definition);
case PluginLLMCore::ToolSchemaFormat::Ollama:
return customizeForOllama(definition);
case PluginLLMCore::ToolSchemaFormat::Google:
return customizeForGoogle(definition);
}
return definition;
}
PluginLLMCore::ToolPermissions ExecuteTerminalCommandTool::requiredPermissions() const
{
return PluginLLMCore::ToolPermission::FileSystemRead
| PluginLLMCore::ToolPermission::FileSystemWrite
| PluginLLMCore::ToolPermission::NetworkAccess;
}
QFuture<QString> ExecuteTerminalCommandTool::executeAsync(const QJsonObject &input)
{
const QString command = input.value("command").toString().trimmed();

View File

@ -19,22 +19,21 @@
#pragma once
#include <pluginllmcore/BaseTool.hpp>
#include <LLMCore/BaseTool.hpp>
#include <QObject>
namespace QodeAssist::Tools {
class ExecuteTerminalCommandTool : public PluginLLMCore::BaseTool
class ExecuteTerminalCommandTool : public ::LLMCore::BaseTool
{
Q_OBJECT
public:
explicit ExecuteTerminalCommandTool(QObject *parent = nullptr);
QString name() const override;
QString stringName() const override;
QString id() const override;
QString displayName() const override;
QString description() const override;
QJsonObject getDefinition(PluginLLMCore::ToolSchemaFormat format) const override;
PluginLLMCore::ToolPermissions requiredPermissions() const override;
QJsonObject parametersSchema() const override;
QFuture<QString> executeAsync(const QJsonObject &input = QJsonObject()) override;

View File

@ -32,12 +32,12 @@ FindAndReadFileTool::FindAndReadFileTool(QObject *parent)
, m_ignoreManager(new Context::IgnoreManager(this))
{}
QString FindAndReadFileTool::name() const
QString FindAndReadFileTool::id() const
{
return "find_and_read_file";
}
QString FindAndReadFileTool::stringName() const
QString FindAndReadFileTool::displayName() const
{
return "Finding and reading file";
}
@ -48,7 +48,7 @@ QString FindAndReadFileTool::description() const
"Returns the best matching file and its content.";
}
QJsonObject FindAndReadFileTool::getDefinition(PluginLLMCore::ToolSchemaFormat format) const
QJsonObject FindAndReadFileTool::parametersSchema() const
{
QJsonObject properties;
@ -68,24 +68,9 @@ QJsonObject FindAndReadFileTool::getDefinition(PluginLLMCore::ToolSchemaFormat f
definition["properties"] = properties;
definition["required"] = QJsonArray{"query"};
switch (format) {
case PluginLLMCore::ToolSchemaFormat::OpenAI:
return customizeForOpenAI(definition);
case PluginLLMCore::ToolSchemaFormat::Claude:
return customizeForClaude(definition);
case PluginLLMCore::ToolSchemaFormat::Ollama:
return customizeForOllama(definition);
case PluginLLMCore::ToolSchemaFormat::Google:
return customizeForGoogle(definition);
}
return definition;
}
PluginLLMCore::ToolPermissions FindAndReadFileTool::requiredPermissions() const
{
return PluginLLMCore::ToolPermission::FileSystemRead;
}
QFuture<QString> FindAndReadFileTool::executeAsync(const QJsonObject &input)
{
return QtConcurrent::run([this, input]() -> QString {

View File

@ -22,25 +22,24 @@
#include "FileSearchUtils.hpp"
#include <context/IgnoreManager.hpp>
#include <pluginllmcore/BaseTool.hpp>
#include <LLMCore/BaseTool.hpp>
#include <QFuture>
#include <QJsonObject>
#include <QObject>
namespace QodeAssist::Tools {
class FindAndReadFileTool : public PluginLLMCore::BaseTool
class FindAndReadFileTool : public ::LLMCore::BaseTool
{
Q_OBJECT
public:
explicit FindAndReadFileTool(QObject *parent = nullptr);
QString name() const override;
QString stringName() const override;
QString id() const override;
QString displayName() const override;
QString description() const override;
QJsonObject getDefinition(PluginLLMCore::ToolSchemaFormat format) const override;
PluginLLMCore::ToolPermissions requiredPermissions() const override;
QJsonObject parametersSchema() const override;
QFuture<QString> executeAsync(const QJsonObject &input) override;
private:

View File

@ -121,12 +121,12 @@ GetIssuesListTool::GetIssuesListTool(QObject *parent)
IssuesTracker::instance();
}
QString GetIssuesListTool::name() const
QString GetIssuesListTool::id() const
{
return "get_issues_list";
}
QString GetIssuesListTool::stringName() const
QString GetIssuesListTool::displayName() const
{
return "Getting issues list from Qt Creator";
}
@ -138,7 +138,7 @@ QString GetIssuesListTool::description() const
"Optional severity filter: 'error', 'warning', or 'all' (default).";
}
QJsonObject GetIssuesListTool::getDefinition(PluginLLMCore::ToolSchemaFormat format) const
QJsonObject GetIssuesListTool::parametersSchema() const
{
QJsonObject definition;
definition["type"] = "object";
@ -152,25 +152,9 @@ QJsonObject GetIssuesListTool::getDefinition(PluginLLMCore::ToolSchemaFormat for
definition["properties"] = properties;
definition["required"] = QJsonArray();
switch (format) {
case PluginLLMCore::ToolSchemaFormat::OpenAI:
return customizeForOpenAI(definition);
case PluginLLMCore::ToolSchemaFormat::Claude:
return customizeForClaude(definition);
case PluginLLMCore::ToolSchemaFormat::Ollama:
return customizeForOllama(definition);
case PluginLLMCore::ToolSchemaFormat::Google:
return customizeForGoogle(definition);
}
return definition;
}
PluginLLMCore::ToolPermissions GetIssuesListTool::requiredPermissions() const
{
return PluginLLMCore::ToolPermission::FileSystemRead;
}
QFuture<QString> GetIssuesListTool::executeAsync(const QJsonObject &input)
{
return QtConcurrent::run([input]() -> QString {

View File

@ -19,7 +19,7 @@
#pragma once
#include <pluginllmcore/BaseTool.hpp>
#include <LLMCore/BaseTool.hpp>
#include <projectexplorer/task.h>
#include <QList>
#include <QMutex>
@ -46,17 +46,16 @@ private:
mutable QMutex m_mutex;
};
class GetIssuesListTool : public PluginLLMCore::BaseTool
class GetIssuesListTool : public ::LLMCore::BaseTool
{
Q_OBJECT
public:
explicit GetIssuesListTool(QObject *parent = nullptr);
QString name() const override;
QString stringName() const override;
QString id() const override;
QString displayName() const override;
QString description() const override;
QJsonObject getDefinition(PluginLLMCore::ToolSchemaFormat format) const override;
PluginLLMCore::ToolPermissions requiredPermissions() const override;
QJsonObject parametersSchema() const override;
QFuture<QString> executeAsync(const QJsonObject &input = QJsonObject()) override;
};

View File

@ -37,12 +37,12 @@ ListProjectFilesTool::ListProjectFilesTool(QObject *parent)
{}
QString ListProjectFilesTool::name() const
QString ListProjectFilesTool::id() const
{
return "list_project_files";
}
QString ListProjectFilesTool::stringName() const
QString ListProjectFilesTool::displayName() const
{
return {"Reading project files list"};
}
@ -53,32 +53,16 @@ QString ListProjectFilesTool::description() const
"Useful for understanding project structure. No parameters required.";
}
QJsonObject ListProjectFilesTool::getDefinition(PluginLLMCore::ToolSchemaFormat format) const
QJsonObject ListProjectFilesTool::parametersSchema() const
{
QJsonObject definition;
definition["type"] = "object";
definition["properties"] = QJsonObject();
definition["required"] = QJsonArray();
switch (format) {
case PluginLLMCore::ToolSchemaFormat::OpenAI:
return customizeForOpenAI(definition);
case PluginLLMCore::ToolSchemaFormat::Claude:
return customizeForClaude(definition);
case PluginLLMCore::ToolSchemaFormat::Ollama:
return customizeForOllama(definition);
case PluginLLMCore::ToolSchemaFormat::Google:
return customizeForGoogle(definition);
}
return definition;
}
PluginLLMCore::ToolPermissions ListProjectFilesTool::requiredPermissions() const
{
return PluginLLMCore::ToolPermission::FileSystemRead;
}
QFuture<QString> ListProjectFilesTool::executeAsync(const QJsonObject &input)
{
Q_UNUSED(input)

View File

@ -19,23 +19,22 @@
#pragma once
#include <pluginllmcore/BaseTool.hpp>
#include <LLMCore/BaseTool.hpp>
#include <context/IgnoreManager.hpp>
namespace QodeAssist::Tools {
class ListProjectFilesTool : public PluginLLMCore::BaseTool
class ListProjectFilesTool : public ::LLMCore::BaseTool
{
Q_OBJECT
public:
explicit ListProjectFilesTool(QObject *parent = nullptr);
QString name() const override;
QString stringName() const override;
QString id() const override;
QString displayName() const override;
QString description() const override;
QJsonObject getDefinition(PluginLLMCore::ToolSchemaFormat format) const override;
PluginLLMCore::ToolPermissions requiredPermissions() const override;
QJsonObject parametersSchema() const override;
QFuture<QString> executeAsync(const QJsonObject &input = QJsonObject()) override;

View File

@ -43,12 +43,12 @@ ProjectSearchTool::ProjectSearchTool(QObject *parent)
, m_ignoreManager(new Context::IgnoreManager(this))
{}
QString ProjectSearchTool::name() const
QString ProjectSearchTool::id() const
{
return "search_project";
}
QString ProjectSearchTool::stringName() const
QString ProjectSearchTool::displayName() const
{
return "Searching in project";
}
@ -60,7 +60,7 @@ QString ProjectSearchTool::description() const
"Symbol mode: finds C++ definitions (classes, functions, etc).";
}
QJsonObject ProjectSearchTool::getDefinition(PluginLLMCore::ToolSchemaFormat format) const
QJsonObject ProjectSearchTool::parametersSchema() const
{
QJsonObject properties;
@ -94,24 +94,9 @@ QJsonObject ProjectSearchTool::getDefinition(PluginLLMCore::ToolSchemaFormat for
definition["properties"] = properties;
definition["required"] = QJsonArray{"query", "search_type"};
switch (format) {
case PluginLLMCore::ToolSchemaFormat::OpenAI:
return customizeForOpenAI(definition);
case PluginLLMCore::ToolSchemaFormat::Claude:
return customizeForClaude(definition);
case PluginLLMCore::ToolSchemaFormat::Ollama:
return customizeForOllama(definition);
case PluginLLMCore::ToolSchemaFormat::Google:
return customizeForGoogle(definition);
}
return definition;
}
PluginLLMCore::ToolPermissions ProjectSearchTool::requiredPermissions() const
{
return PluginLLMCore::ToolPermission::FileSystemRead;
}
QFuture<QString> ProjectSearchTool::executeAsync(const QJsonObject &input)
{
return QtConcurrent::run([this, input]() -> QString {

View File

@ -20,25 +20,24 @@
#pragma once
#include <context/IgnoreManager.hpp>
#include <pluginllmcore/BaseTool.hpp>
#include <LLMCore/BaseTool.hpp>
#include <QFuture>
#include <QJsonObject>
#include <QObject>
namespace QodeAssist::Tools {
class ProjectSearchTool : public PluginLLMCore::BaseTool
class ProjectSearchTool : public ::LLMCore::BaseTool
{
Q_OBJECT
public:
explicit ProjectSearchTool(QObject *parent = nullptr);
QString name() const override;
QString stringName() const override;
QString id() const override;
QString displayName() const override;
QString description() const override;
QJsonObject getDefinition(PluginLLMCore::ToolSchemaFormat format) const override;
PluginLLMCore::ToolPermissions requiredPermissions() const override;
QJsonObject parametersSchema() const override;
QFuture<QString> executeAsync(const QJsonObject &input) override;
private:

View File

@ -31,12 +31,12 @@ TodoTool::TodoTool(QObject *parent)
: BaseTool(parent)
{}
QString TodoTool::name() const
QString TodoTool::id() const
{
return "todo_tool";
}
QString TodoTool::stringName() const
QString TodoTool::displayName() const
{
return "Managing TODO list for task tracking";
}
@ -53,7 +53,7 @@ QString TodoTool::description() const
"The list persists throughout the conversation.";
}
QJsonObject TodoTool::getDefinition(PluginLLMCore::ToolSchemaFormat format) const
QJsonObject TodoTool::parametersSchema() const
{
QJsonObject definition;
definition["type"] = "object";
@ -97,32 +97,15 @@ QJsonObject TodoTool::getDefinition(PluginLLMCore::ToolSchemaFormat format) cons
required.append("operation");
definition["required"] = required;
switch (format) {
case PluginLLMCore::ToolSchemaFormat::OpenAI:
return customizeForOpenAI(definition);
case PluginLLMCore::ToolSchemaFormat::Claude:
return customizeForClaude(definition);
case PluginLLMCore::ToolSchemaFormat::Ollama:
return customizeForOllama(definition);
case PluginLLMCore::ToolSchemaFormat::Google:
return customizeForGoogle(definition);
}
return definition;
}
PluginLLMCore::ToolPermissions TodoTool::requiredPermissions() const
{
return PluginLLMCore::ToolPermission::None;
}
QFuture<QString> TodoTool::executeAsync(const QJsonObject &input)
{
return QtConcurrent::run([this, input]() -> QString {
QString sessionId = input.value("session_id").toString();
if (sessionId.isEmpty()) {
sessionId = "current";
}
QMutexLocker sessionLocker(&m_mutex);
QString sessionId = m_currentSessionId.isEmpty() ? "current" : m_currentSessionId;
sessionLocker.unlock();
const QString operation = input.value("operation").toString();
@ -194,6 +177,12 @@ QFuture<QString> TodoTool::executeAsync(const QJsonObject &input)
});
}
void TodoTool::setCurrentSessionId(const QString &sessionId)
{
QMutexLocker locker(&m_mutex);
m_currentSessionId = sessionId;
}
void TodoTool::clearSession(const QString &sessionId)
{
QMutexLocker locker(&m_mutex);

View File

@ -19,7 +19,7 @@
#pragma once
#include <pluginllmcore/BaseTool.hpp>
#include <LLMCore/BaseTool.hpp>
#include <QHash>
#include <QMutex>
@ -34,21 +34,21 @@ struct TodoItem
bool completed;
};
class TodoTool : public PluginLLMCore::BaseTool
class TodoTool : public ::LLMCore::BaseTool
{
Q_OBJECT
public:
explicit TodoTool(QObject *parent = nullptr);
QString name() const override;
QString stringName() const override;
QString id() const override;
QString displayName() const override;
QString description() const override;
QJsonObject getDefinition(PluginLLMCore::ToolSchemaFormat format) const override;
PluginLLMCore::ToolPermissions requiredPermissions() const override;
QJsonObject parametersSchema() const override;
QFuture<QString> executeAsync(const QJsonObject &input = QJsonObject()) override;
void setCurrentSessionId(const QString &sessionId);
void clearSession(const QString &sessionId);
private:
@ -59,6 +59,7 @@ private:
QString listRemainingTodosLocked(const QString &sessionId) const;
mutable QMutex m_mutex;
QString m_currentSessionId;
QHash<QString, QHash<int, TodoItem>> m_sessionTodos;
QHash<QString, int> m_sessionNextId;
};

View File

@ -0,0 +1,49 @@
/*
* Copyright (C) 2026 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 <https://www.gnu.org/licenses/>.
*/
#include "ToolsRegistration.hpp"
#include <LLMCore/ToolsManager.hpp>
#include "BuildProjectTool.hpp"
#include "CreateNewFileTool.hpp"
#include "EditFileTool.hpp"
#include "ExecuteTerminalCommandTool.hpp"
#include "FindAndReadFileTool.hpp"
#include "GetIssuesListTool.hpp"
#include "ListProjectFilesTool.hpp"
#include "ProjectSearchTool.hpp"
#include "TodoTool.hpp"
namespace QodeAssist::Tools {
void registerQodeAssistTools(::LLMCore::ToolsManager *manager)
{
manager->addTool(new ListProjectFilesTool(manager));
manager->addTool(new GetIssuesListTool(manager));
manager->addTool(new CreateNewFileTool(manager));
manager->addTool(new EditFileTool(manager));
manager->addTool(new BuildProjectTool(manager));
manager->addTool(new ExecuteTerminalCommandTool(manager));
manager->addTool(new ProjectSearchTool(manager));
manager->addTool(new FindAndReadFileTool(manager));
manager->addTool(new TodoTool(manager));
}
} // namespace QodeAssist::Tools

View File

@ -0,0 +1,30 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
#pragma once
namespace LLMCore {
class ToolsManager;
}
namespace QodeAssist::Tools {
void registerQodeAssistTools(::LLMCore::ToolsManager *manager);
} // namespace QodeAssist::Tools