diff --git a/ChatView/ChatRootView.cpp b/ChatView/ChatRootView.cpp index 9f8cab4..ec6dcea 100644 --- a/ChatView/ChatRootView.cpp +++ b/ChatView/ChatRootView.cpp @@ -1298,7 +1298,7 @@ bool ChatRootView::isThinkingSupport() const auto providerName = Settings::generalSettings().caProvider(); auto provider = PluginLLMCore::ProvidersManager::instance().getProviderByName(providerName); - return provider && provider->supportThinking(); + return provider && provider->capabilities().testFlag(PluginLLMCore::ProviderCapability::Thinking); } QString ChatRootView::generateChatFileName(const QString &shortMessage, const QString &dir) const diff --git a/ChatView/ClientInterface.cpp b/ChatView/ClientInterface.cpp index 0acfa32..ef92fe5 100644 --- a/ChatView/ClientInterface.cpp +++ b/ChatView/ClientInterface.cpp @@ -227,7 +227,8 @@ void ClientInterface::sendMessage( apiMessage.isRedacted = msg.isRedacted; apiMessage.signature = msg.signature; - if (provider->supportImage() && !m_chatFilePath.isEmpty() && !msg.images.isEmpty()) { + if (provider->capabilities().testFlag(PluginLLMCore::ProviderCapability::Image) + && !m_chatFilePath.isEmpty() && !msg.images.isEmpty()) { auto apiImages = loadImagesFromStorage(msg.images); if (!apiImages.isEmpty()) { apiMessage.images = apiImages; @@ -237,7 +238,8 @@ void ClientInterface::sendMessage( messages.append(apiMessage); } - if (!imageFiles.isEmpty() && !provider->supportImage()) { + if (!imageFiles.isEmpty() + && !provider->capabilities().testFlag(PluginLLMCore::ProviderCapability::Image)) { LOG_MESSAGE(QString("Provider %1 doesn't support images, %2 ignored") .arg(provider->name(), QString::number(imageFiles.size()))); } @@ -330,7 +332,8 @@ void ClientInterface::sendMessage( provider->sendRequest(requestId, config.url, config.providerRequest); - if (provider->supportsTools() && provider->toolsManager()) { + if (provider->capabilities().testFlag(PluginLLMCore::ProviderCapability::Tools) + && provider->toolsManager()) { if (auto *todoTool = qobject_cast( provider->toolsManager()->tool("todo_tool"))) { todoTool->setCurrentSessionId(m_chatFilePath); @@ -343,7 +346,8 @@ void ClientInterface::clearMessages() const auto providerName = Settings::generalSettings().caProvider(); auto *provider = PluginLLMCore::ProvidersManager::instance().getProviderByName(providerName); - if (provider && !m_chatFilePath.isEmpty() && provider->supportsTools() + if (provider && !m_chatFilePath.isEmpty() + && provider->capabilities().testFlag(PluginLLMCore::ProviderCapability::Tools) && provider->toolsManager()) { if (auto *todoTool = qobject_cast( provider->toolsManager()->tool("todo_tool"))) { @@ -628,7 +632,9 @@ void ClientInterface::setChatFilePath(const QString &filePath) const auto providerName = Settings::generalSettings().caProvider(); auto *provider = PluginLLMCore::ProvidersManager::instance().getProviderByName(providerName); - if (provider && provider->supportsTools() && provider->toolsManager()) { + if (provider + && provider->capabilities().testFlag(PluginLLMCore::ProviderCapability::Tools) + && provider->toolsManager()) { if (auto *todoTool = qobject_cast( provider->toolsManager()->tool("todo_tool"))) { todoTool->clearSession(m_chatFilePath); diff --git a/pluginllmcore/Provider.hpp b/pluginllmcore/Provider.hpp index 2303754..9986324 100644 --- a/pluginllmcore/Provider.hpp +++ b/pluginllmcore/Provider.hpp @@ -19,6 +19,7 @@ #pragma once +#include #include #include #include @@ -38,6 +39,14 @@ class QJsonObject; namespace QodeAssist::PluginLLMCore { +enum class ProviderCapability { + Tools = 0x1, + Thinking = 0x2, + Image = 0x4, +}; +Q_DECLARE_FLAGS(ProviderCapabilities, ProviderCapability) +Q_DECLARE_OPERATORS_FOR_FLAGS(ProviderCapabilities) + class Provider : public QObject { Q_OBJECT @@ -68,9 +77,7 @@ public: virtual void sendRequest(const RequestID &requestId, const QUrl &url, const QJsonObject &payload) = 0; - virtual bool supportsTools() const { return false; }; - virtual bool supportThinking() const { return false; }; - virtual bool supportImage() const { return false; }; + virtual ProviderCapabilities capabilities() const { return {}; } virtual void cancelRequest(const RequestID &requestId) = 0; diff --git a/providers/ClaudeProvider.cpp b/providers/ClaudeProvider.cpp index c2a7dcf..2ff303a 100644 --- a/providers/ClaudeProvider.cpp +++ b/providers/ClaudeProvider.cpp @@ -249,19 +249,10 @@ void ClaudeProvider::sendRequest( .arg(requestId, clientId, url.toString())); } -bool ClaudeProvider::supportsTools() const +PluginLLMCore::ProviderCapabilities ClaudeProvider::capabilities() const { - return true; -} - -bool ClaudeProvider::supportThinking() const -{ - return true; -} - -bool ClaudeProvider::supportImage() const -{ - return true; + return PluginLLMCore::ProviderCapability::Tools | PluginLLMCore::ProviderCapability::Thinking + | PluginLLMCore::ProviderCapability::Image; } void ClaudeProvider::cancelRequest(const PluginLLMCore::RequestID &requestId) diff --git a/providers/ClaudeProvider.hpp b/providers/ClaudeProvider.hpp index a986386..f0d77b8 100644 --- a/providers/ClaudeProvider.hpp +++ b/providers/ClaudeProvider.hpp @@ -54,9 +54,7 @@ public: void sendRequest( const PluginLLMCore::RequestID &requestId, const QUrl &url, const QJsonObject &payload) override; - bool supportsTools() const override; - bool supportThinking() const override; - bool supportImage() const override; + PluginLLMCore::ProviderCapabilities capabilities() const override; void cancelRequest(const PluginLLMCore::RequestID &requestId) override; ::LLMCore::ToolsManager *toolsManager() const override; diff --git a/providers/GoogleAIProvider.cpp b/providers/GoogleAIProvider.cpp index 14acb6f..7315983 100644 --- a/providers/GoogleAIProvider.cpp +++ b/providers/GoogleAIProvider.cpp @@ -265,19 +265,10 @@ void GoogleAIProvider::sendRequest( .arg(requestId, clientId, url.toString())); } -bool GoogleAIProvider::supportsTools() const +PluginLLMCore::ProviderCapabilities GoogleAIProvider::capabilities() const { - return true; -} - -bool GoogleAIProvider::supportThinking() const -{ - return true; -} - -bool GoogleAIProvider::supportImage() const -{ - return true; + return PluginLLMCore::ProviderCapability::Tools | PluginLLMCore::ProviderCapability::Thinking + | PluginLLMCore::ProviderCapability::Image; } void GoogleAIProvider::cancelRequest(const PluginLLMCore::RequestID &requestId) diff --git a/providers/GoogleAIProvider.hpp b/providers/GoogleAIProvider.hpp index d3df995..86e1f0b 100644 --- a/providers/GoogleAIProvider.hpp +++ b/providers/GoogleAIProvider.hpp @@ -54,9 +54,7 @@ public: void sendRequest( const PluginLLMCore::RequestID &requestId, const QUrl &url, const QJsonObject &payload) override; - bool supportsTools() const override; - bool supportThinking() const override; - bool supportImage() const override; + PluginLLMCore::ProviderCapabilities capabilities() const override; void cancelRequest(const PluginLLMCore::RequestID &requestId) override; ::LLMCore::ToolsManager *toolsManager() const override; diff --git a/providers/LMStudioProvider.cpp b/providers/LMStudioProvider.cpp index a3c60f3..204a23c 100644 --- a/providers/LMStudioProvider.cpp +++ b/providers/LMStudioProvider.cpp @@ -177,14 +177,9 @@ void LMStudioProvider::sendRequest( .arg(requestId, clientId, url.toString())); } -bool LMStudioProvider::supportsTools() const +PluginLLMCore::ProviderCapabilities LMStudioProvider::capabilities() const { - return true; -} - -bool LMStudioProvider::supportImage() const -{ - return true; + return PluginLLMCore::ProviderCapability::Tools | PluginLLMCore::ProviderCapability::Image; } void LMStudioProvider::cancelRequest(const PluginLLMCore::RequestID &requestId) diff --git a/providers/LMStudioProvider.hpp b/providers/LMStudioProvider.hpp index bbb12e1..c4f12fa 100644 --- a/providers/LMStudioProvider.hpp +++ b/providers/LMStudioProvider.hpp @@ -53,8 +53,7 @@ public: void sendRequest( const PluginLLMCore::RequestID &requestId, const QUrl &url, const QJsonObject &payload) override; - bool supportsTools() const override; - bool supportImage() const override; + PluginLLMCore::ProviderCapabilities capabilities() const override; void cancelRequest(const PluginLLMCore::RequestID &requestId) override; ::LLMCore::ToolsManager *toolsManager() const override; diff --git a/providers/LlamaCppProvider.cpp b/providers/LlamaCppProvider.cpp index 578a4d0..4f6526e 100644 --- a/providers/LlamaCppProvider.cpp +++ b/providers/LlamaCppProvider.cpp @@ -237,14 +237,9 @@ void LlamaCppProvider::sendRequest( .arg(requestId, clientId, url.toString())); } -bool LlamaCppProvider::supportsTools() const +PluginLLMCore::ProviderCapabilities LlamaCppProvider::capabilities() const { - return true; -} - -bool LlamaCppProvider::supportImage() const -{ - return true; + return PluginLLMCore::ProviderCapability::Tools | PluginLLMCore::ProviderCapability::Image; } void LlamaCppProvider::cancelRequest(const PluginLLMCore::RequestID &requestId) diff --git a/providers/LlamaCppProvider.hpp b/providers/LlamaCppProvider.hpp index 166800b..9edfb63 100644 --- a/providers/LlamaCppProvider.hpp +++ b/providers/LlamaCppProvider.hpp @@ -54,8 +54,7 @@ public: void sendRequest( const PluginLLMCore::RequestID &requestId, const QUrl &url, const QJsonObject &payload) override; - bool supportsTools() const override; - bool supportImage() const override; + PluginLLMCore::ProviderCapabilities capabilities() const override; void cancelRequest(const PluginLLMCore::RequestID &requestId) override; ::LLMCore::ToolsManager *toolsManager() const override; diff --git a/providers/MistralAIProvider.cpp b/providers/MistralAIProvider.cpp index 3315ed4..b9a3b46 100644 --- a/providers/MistralAIProvider.cpp +++ b/providers/MistralAIProvider.cpp @@ -189,14 +189,9 @@ void MistralAIProvider::sendRequest( .arg(requestId, clientId, url.toString())); } -bool MistralAIProvider::supportsTools() const +PluginLLMCore::ProviderCapabilities MistralAIProvider::capabilities() const { - return true; -} - -bool MistralAIProvider::supportImage() const -{ - return true; + return PluginLLMCore::ProviderCapability::Tools | PluginLLMCore::ProviderCapability::Image; } void MistralAIProvider::cancelRequest(const PluginLLMCore::RequestID &requestId) diff --git a/providers/MistralAIProvider.hpp b/providers/MistralAIProvider.hpp index dd954e3..4fe781e 100644 --- a/providers/MistralAIProvider.hpp +++ b/providers/MistralAIProvider.hpp @@ -53,8 +53,7 @@ public: void sendRequest( const PluginLLMCore::RequestID &requestId, const QUrl &url, const QJsonObject &payload) override; - bool supportsTools() const override; - bool supportImage() const override; + PluginLLMCore::ProviderCapabilities capabilities() const override; void cancelRequest(const PluginLLMCore::RequestID &requestId) override; ::LLMCore::ToolsManager *toolsManager() const override; diff --git a/providers/OllamaProvider.cpp b/providers/OllamaProvider.cpp index 683b629..064e499 100644 --- a/providers/OllamaProvider.cpp +++ b/providers/OllamaProvider.cpp @@ -272,19 +272,10 @@ void OllamaProvider::sendRequest( .arg(requestId, clientId, url.toString())); } -bool OllamaProvider::supportsTools() const +PluginLLMCore::ProviderCapabilities OllamaProvider::capabilities() const { - return true; -} - -bool OllamaProvider::supportImage() const -{ - return true; -} - -bool OllamaProvider::supportThinking() const -{ - return true; + return PluginLLMCore::ProviderCapability::Tools | PluginLLMCore::ProviderCapability::Thinking + | PluginLLMCore::ProviderCapability::Image; } void OllamaProvider::cancelRequest(const PluginLLMCore::RequestID &requestId) diff --git a/providers/OllamaProvider.hpp b/providers/OllamaProvider.hpp index bcf9e22..e0027ab 100644 --- a/providers/OllamaProvider.hpp +++ b/providers/OllamaProvider.hpp @@ -54,9 +54,7 @@ public: void sendRequest( const PluginLLMCore::RequestID &requestId, const QUrl &url, const QJsonObject &payload) override; - bool supportsTools() const override; - bool supportImage() const override; - bool supportThinking() const override; + PluginLLMCore::ProviderCapabilities capabilities() const override; void cancelRequest(const PluginLLMCore::RequestID &requestId) override; ::LLMCore::ToolsManager *toolsManager() const override; diff --git a/providers/OpenAICompatProvider.cpp b/providers/OpenAICompatProvider.cpp index caa4a1c..1b247a3 100644 --- a/providers/OpenAICompatProvider.cpp +++ b/providers/OpenAICompatProvider.cpp @@ -224,14 +224,9 @@ void OpenAICompatProvider::sendRequest( .arg(requestId, clientId, url.toString())); } -bool OpenAICompatProvider::supportsTools() const +PluginLLMCore::ProviderCapabilities OpenAICompatProvider::capabilities() const { - return true; -} - -bool OpenAICompatProvider::supportImage() const -{ - return true; + return PluginLLMCore::ProviderCapability::Tools | PluginLLMCore::ProviderCapability::Image; } void OpenAICompatProvider::cancelRequest(const PluginLLMCore::RequestID &requestId) diff --git a/providers/OpenAICompatProvider.hpp b/providers/OpenAICompatProvider.hpp index 539fe96..10c0775 100644 --- a/providers/OpenAICompatProvider.hpp +++ b/providers/OpenAICompatProvider.hpp @@ -53,8 +53,7 @@ public: void sendRequest( const PluginLLMCore::RequestID &requestId, const QUrl &url, const QJsonObject &payload) override; - bool supportsTools() const override; - bool supportImage() const override; + PluginLLMCore::ProviderCapabilities capabilities() const override; void cancelRequest(const PluginLLMCore::RequestID &requestId) override; ::LLMCore::ToolsManager *toolsManager() const override; diff --git a/providers/OpenAIProvider.cpp b/providers/OpenAIProvider.cpp index d3fa411..8cb8cfe 100644 --- a/providers/OpenAIProvider.cpp +++ b/providers/OpenAIProvider.cpp @@ -254,14 +254,9 @@ void OpenAIProvider::sendRequest( .arg(requestId, clientId, url.toString())); } -bool OpenAIProvider::supportsTools() const +PluginLLMCore::ProviderCapabilities OpenAIProvider::capabilities() const { - return true; -} - -bool OpenAIProvider::supportImage() const -{ - return true; + return PluginLLMCore::ProviderCapability::Tools | PluginLLMCore::ProviderCapability::Image; } void OpenAIProvider::cancelRequest(const PluginLLMCore::RequestID &requestId) diff --git a/providers/OpenAIProvider.hpp b/providers/OpenAIProvider.hpp index 3dedee4..0d05b17 100644 --- a/providers/OpenAIProvider.hpp +++ b/providers/OpenAIProvider.hpp @@ -53,8 +53,7 @@ public: void sendRequest( const PluginLLMCore::RequestID &requestId, const QUrl &url, const QJsonObject &payload) override; - bool supportsTools() const override; - bool supportImage() const override; + PluginLLMCore::ProviderCapabilities capabilities() const override; void cancelRequest(const PluginLLMCore::RequestID &requestId) override; ::LLMCore::ToolsManager *toolsManager() const override; diff --git a/providers/OpenAIResponsesProvider.cpp b/providers/OpenAIResponsesProvider.cpp index acb5782..03fab1b 100644 --- a/providers/OpenAIResponsesProvider.cpp +++ b/providers/OpenAIResponsesProvider.cpp @@ -292,19 +292,10 @@ void OpenAIResponsesProvider::sendRequest( .arg(requestId, clientId, url.toString())); } -bool OpenAIResponsesProvider::supportsTools() const +PluginLLMCore::ProviderCapabilities OpenAIResponsesProvider::capabilities() const { - return true; -} - -bool OpenAIResponsesProvider::supportImage() const -{ - return true; -} - -bool OpenAIResponsesProvider::supportThinking() const -{ - return true; + return PluginLLMCore::ProviderCapability::Tools | PluginLLMCore::ProviderCapability::Thinking + | PluginLLMCore::ProviderCapability::Image; } void OpenAIResponsesProvider::cancelRequest(const PluginLLMCore::RequestID &requestId) diff --git a/providers/OpenAIResponsesProvider.hpp b/providers/OpenAIResponsesProvider.hpp index 1e27a94..4dfd124 100644 --- a/providers/OpenAIResponsesProvider.hpp +++ b/providers/OpenAIResponsesProvider.hpp @@ -53,9 +53,7 @@ public: void sendRequest( const PluginLLMCore::RequestID &requestId, const QUrl &url, const QJsonObject &payload) override; - bool supportsTools() const override; - bool supportImage() const override; - bool supportThinking() const override; + PluginLLMCore::ProviderCapabilities capabilities() const override; void cancelRequest(const PluginLLMCore::RequestID &requestId) override; ::LLMCore::ToolsManager *toolsManager() const override; diff --git a/test/DocumentContextReaderTest.cpp b/test/DocumentContextReaderTest.cpp index 76969d8..3ff5f12 100644 --- a/test/DocumentContextReaderTest.cpp +++ b/test/DocumentContextReaderTest.cpp @@ -369,7 +369,7 @@ TEST_F(DocumentContextReaderTest, testPrepareContext) EXPECT_EQ( reader.prepareContext(2, 3, *createSettingsForWholeFile()), - (ContextData{ + (QodeAssist::PluginLLMCore::ContextData{ .prefix = "Line 0\nLine 1\nLin", .suffix = "e 2\nLine 3\nLine 4", .fileContext = "\n Language: (MIME: text/python) filepath: /path/to/file()\n\n" @@ -377,7 +377,7 @@ TEST_F(DocumentContextReaderTest, testPrepareContext) EXPECT_EQ( reader.prepareContext(2, 3, *createSettingsForLines(1, 1)), - (ContextData{ + (QodeAssist::PluginLLMCore::ContextData{ .prefix = "Line 1\nLin", .suffix = "e 2\nLine 3", .fileContext = "\n Language: (MIME: text/python) filepath: /path/to/file()\n\n" @@ -385,7 +385,7 @@ TEST_F(DocumentContextReaderTest, testPrepareContext) EXPECT_EQ( reader.prepareContext(2, 3, *createSettingsForLines(2, 2)), - (ContextData{ + (QodeAssist::PluginLLMCore::ContextData{ .prefix = "Line 0\nLine 1\nLin", .suffix = "e 2\nLine 3\nLine 4", .fileContext = "\n Language: (MIME: text/python) filepath: /path/to/file()\n\n" diff --git a/test/TestUtils.hpp b/test/TestUtils.hpp index 533bb8f..00567b2 100644 --- a/test/TestUtils.hpp +++ b/test/TestUtils.hpp @@ -18,7 +18,7 @@ */ #include -#include +#include #include QT_BEGIN_NAMESPACE @@ -61,14 +61,14 @@ std::ostream &operator<<(std::ostream &out, const std::optional &value) namespace QodeAssist::LLMCore { -inline std::ostream &operator<<(std::ostream &out, const Message &value) +inline std::ostream &operator<<(std::ostream &out, const PluginLLMCore::Message &value) { out << "Message{" << "role=" << value.role << "content=" << value.content << "}"; return out; } -inline std::ostream &operator<<(std::ostream &out, const ContextData &value) +inline std::ostream &operator<<(std::ostream &out, const PluginLLMCore::ContextData &value) { out << "ContextData{" << "\n systemPrompt=" << value.systemPrompt << "\n prefix=" << value.prefix