refactor: Remove duplicated signals

This commit is contained in:
Petr Mironychev
2026-04-01 01:07:37 +02:00
parent 666aa94e81
commit cd017ae1f2
28 changed files with 186 additions and 977 deletions

View File

@ -34,8 +34,8 @@ add_definitions(
-DQODEASSIST_QT_CREATOR_VERSION_PATCH=${QODEASSIST_QT_CREATOR_VERSION_PATCH}
)
add_subdirectory(pluginllmcore)
add_subdirectory(sources/external/llmcore)
add_subdirectory(pluginllmcore)
add_subdirectory(settings)
add_subdirectory(logger)
add_subdirectory(UIControls)
@ -62,8 +62,9 @@ add_qtc_plugin(QodeAssist
QtCreator::ExtensionSystem
QtCreator::Utils
QtCreator::CPlusPlus
QodeAssistChatViewplugin
LLMCore
PluginLLMCore
QodeAssistChatViewplugin
SOURCES
.github/workflows/build_cmake.yml
.github/workflows/README.md

View File

@ -18,6 +18,8 @@
*/
#include "ChatCompressor.hpp"
#include <LLMCore/BaseClient.hpp>
#include "ChatModel.hpp"
#include "GeneralSettings.hpp"
#include "PromptTemplateManager.hpp"
@ -76,7 +78,6 @@ void ChatCompressor::startCompression(const QString &chatFilePath, ChatModel *ch
m_chatModel = chatModel;
m_originalChatPath = chatFilePath;
m_accumulatedSummary.clear();
m_currentRequestId = QUuid::createUuid().toString(QUuid::WithoutBraces);
emit compressionStarted();
@ -98,8 +99,8 @@ void ChatCompressor::startCompression(const QString &chatFilePath, ChatModel *ch
buildRequestPayload(payload, promptTemplate);
m_currentRequestId = m_provider->sendRequest(requestUrl, payload);
LOG_MESSAGE(QString("Starting compression request: %1").arg(m_currentRequestId));
m_provider->sendRequest(m_currentRequestId, requestUrl, payload);
}
bool ChatCompressor::isCompressing() const
@ -266,23 +267,25 @@ bool ChatCompressor::createCompressedChatFile(
void ChatCompressor::connectProviderSignals()
{
auto *c = m_provider->client();
m_connections.append(connect(
m_provider,
&PluginLLMCore::Provider::partialResponseReceived,
c,
&::LLMCore::BaseClient::chunkReceived,
this,
&ChatCompressor::onPartialResponseReceived,
Qt::UniqueConnection));
m_connections.append(connect(
m_provider,
&PluginLLMCore::Provider::fullResponseReceived,
c,
&::LLMCore::BaseClient::requestCompleted,
this,
&ChatCompressor::onFullResponseReceived,
Qt::UniqueConnection));
m_connections.append(connect(
m_provider,
&PluginLLMCore::Provider::requestFailed,
c,
&::LLMCore::BaseClient::requestFailed,
this,
&ChatCompressor::onRequestFailed,
Qt::UniqueConnection));

View File

@ -19,6 +19,8 @@
#include "ClientInterface.hpp"
#include <LLMCore/BaseClient.hpp>
#include <projectexplorer/buildconfiguration.h>
#include <projectexplorer/target.h>
#include <texteditor/textdocument.h>
@ -274,64 +276,50 @@ void ClientInterface::sendMessage(
useTools,
useThinking);
QString requestId = QUuid::createUuid().toString();
connect(
provider->client(),
&::LLMCore::BaseClient::chunkReceived,
this,
&ClientInterface::handlePartialResponse,
Qt::UniqueConnection);
connect(
provider->client(),
&::LLMCore::BaseClient::requestCompleted,
this,
&ClientInterface::handleFullResponse,
Qt::UniqueConnection);
connect(
provider->client(),
&::LLMCore::BaseClient::requestFailed,
this,
&ClientInterface::handleRequestFailed,
Qt::UniqueConnection);
connect(
provider->client(),
&::LLMCore::BaseClient::toolStarted,
this,
&ClientInterface::handleToolExecutionStarted,
Qt::UniqueConnection);
connect(
provider->client(),
&::LLMCore::BaseClient::toolResultReady,
this,
&ClientInterface::handleToolExecutionCompleted,
Qt::UniqueConnection);
connect(
provider->client(),
&::LLMCore::BaseClient::thinkingBlockReceived,
this,
&ClientInterface::handleThinkingBlockReceived,
Qt::UniqueConnection);
auto requestId = provider->sendRequest(config.url, config.providerRequest);
QJsonObject request{{"id", requestId}};
m_activeRequests[requestId] = {request, provider};
emit requestStarted(requestId);
connect(
provider,
&PluginLLMCore::Provider::partialResponseReceived,
this,
&ClientInterface::handlePartialResponse,
Qt::UniqueConnection);
connect(
provider,
&PluginLLMCore::Provider::fullResponseReceived,
this,
&ClientInterface::handleFullResponse,
Qt::UniqueConnection);
connect(
provider,
&PluginLLMCore::Provider::requestFailed,
this,
&ClientInterface::handleRequestFailed,
Qt::UniqueConnection);
connect(
provider,
&PluginLLMCore::Provider::toolExecutionStarted,
this,
&ClientInterface::handleToolExecutionStarted,
Qt::UniqueConnection);
connect(
provider,
&PluginLLMCore::Provider::toolExecutionCompleted,
this,
&ClientInterface::handleToolExecutionCompleted,
Qt::UniqueConnection);
connect(
provider,
&PluginLLMCore::Provider::continuationStarted,
this,
&ClientInterface::handleCleanAccumulatedData,
Qt::UniqueConnection);
connect(
provider,
&PluginLLMCore::Provider::thinkingBlockReceived,
this,
&ClientInterface::handleThinkingBlockReceived,
Qt::UniqueConnection);
connect(
provider,
&PluginLLMCore::Provider::redactedThinkingBlockReceived,
this,
&ClientInterface::handleRedactedThinkingBlockReceived,
Qt::UniqueConnection);
provider->sendRequest(requestId, config.url, config.providerRequest);
if (provider->capabilities().testFlag(PluginLLMCore::ProviderCapability::Tools)
&& provider->toolsManager()) {
if (auto *todoTool = qobject_cast<QodeAssist::Tools::TodoTool *>(
@ -368,7 +356,7 @@ void ClientInterface::cancelRequest()
}
for (auto *provider : providers) {
disconnect(provider, nullptr, this, nullptr);
disconnect(provider->client(), nullptr, this, nullptr);
}
for (auto it = m_activeRequests.begin(); it != m_activeRequests.end(); ++it) {
@ -380,6 +368,7 @@ void ClientInterface::cancelRequest()
m_activeRequests.clear();
m_accumulatedResponses.clear();
m_awaitingContinuation.clear();
LOG_MESSAGE("All requests cancelled and state cleared");
}
@ -446,6 +435,12 @@ void ClientInterface::handlePartialResponse(const QString &requestId, const QStr
if (it == m_activeRequests.end())
return;
if (m_awaitingContinuation.remove(requestId)) {
m_accumulatedResponses[requestId].clear();
LOG_MESSAGE(
QString("Cleared accumulated responses for continuation request %1").arg(requestId));
}
m_accumulatedResponses[requestId] += partialText;
const RequestContext &ctx = it.value();
@ -476,12 +471,9 @@ void ClientInterface::handleFullResponse(const QString &requestId, const QString
+ ": " + finalText);
emit messageReceivedCompletely();
if (it != m_activeRequests.end()) {
m_activeRequests.erase(it);
}
if (m_accumulatedResponses.contains(requestId)) {
m_accumulatedResponses.remove(requestId);
}
m_activeRequests.erase(it);
m_accumulatedResponses.remove(requestId);
m_awaitingContinuation.remove(requestId);
}
void ClientInterface::handleRequestFailed(const QString &requestId, const QString &error)
@ -493,18 +485,9 @@ void ClientInterface::handleRequestFailed(const QString &requestId, const QStrin
LOG_MESSAGE(QString("Chat request %1 failed: %2").arg(requestId, error));
emit errorOccurred(error);
if (it != m_activeRequests.end()) {
m_activeRequests.erase(it);
}
if (m_accumulatedResponses.contains(requestId)) {
m_accumulatedResponses.remove(requestId);
}
}
void ClientInterface::handleCleanAccumulatedData(const QString &requestId)
{
m_accumulatedResponses[requestId].clear();
LOG_MESSAGE(QString("Cleared accumulated responses for continuation request %1").arg(requestId));
m_activeRequests.erase(it);
m_accumulatedResponses.remove(requestId);
m_awaitingContinuation.remove(requestId);
}
void ClientInterface::handleThinkingBlockReceived(
@ -515,19 +498,17 @@ void ClientInterface::handleThinkingBlockReceived(
return;
}
m_chatModel->addThinkingBlock(requestId, thinking, signature);
}
void ClientInterface::handleRedactedThinkingBlockReceived(
const QString &requestId, const QString &signature)
{
if (!m_activeRequests.contains(requestId)) {
if (m_awaitingContinuation.remove(requestId)) {
m_accumulatedResponses[requestId].clear();
LOG_MESSAGE(
QString("Ignoring redacted thinking block for non-chat request: %1").arg(requestId));
return;
QString("Cleared accumulated responses for continuation request %1").arg(requestId));
}
m_chatModel->addRedactedThinkingBlock(requestId, signature);
if (thinking.isEmpty()) {
m_chatModel->addRedactedThinkingBlock(requestId, signature);
} else {
m_chatModel->addThinkingBlock(requestId, thinking, signature);
}
}
void ClientInterface::handleToolExecutionStarted(
@ -539,6 +520,7 @@ void ClientInterface::handleToolExecutionStarted(
}
m_chatModel->addToolExecutionStatus(requestId, toolId, toolName);
m_awaitingContinuation.insert(requestId);
}
void ClientInterface::handleToolExecutionCompleted(

View File

@ -20,6 +20,7 @@
#pragma once
#include <QObject>
#include <QSet>
#include <QString>
#include <QVector>
@ -62,10 +63,8 @@ private slots:
void handlePartialResponse(const QString &requestId, const QString &partialText);
void handleFullResponse(const QString &requestId, const QString &fullText);
void handleRequestFailed(const QString &requestId, const QString &error);
void handleCleanAccumulatedData(const QString &requestId);
void handleThinkingBlockReceived(
const QString &requestId, const QString &thinking, const QString &signature);
void handleRedactedThinkingBlockReceived(const QString &requestId, const QString &signature);
void handleToolExecutionStarted(
const QString &requestId, const QString &toolId, const QString &toolName);
void handleToolExecutionCompleted(
@ -97,6 +96,7 @@ private:
QHash<QString, RequestContext> m_activeRequests;
QHash<QString, QString> m_accumulatedResponses;
QSet<QString> m_awaitingContinuation;
};
} // namespace QodeAssist::Chat

View File

@ -19,6 +19,7 @@
#include "LLMClientInterface.hpp"
#include <LLMCore/BaseClient.hpp>
#include <QJsonDocument>
#include <QNetworkAccessManager>
#include <QNetworkReply>
@ -122,8 +123,6 @@ void LLMClientInterface::sendData(const QByteArray &data)
} else if (method == "textDocument/didOpen") {
handleTextDocumentDidOpen(request);
} else if (method == "getCompletionsCycling") {
QString requestId = request["id"].toString();
m_performanceLogger.startTimeMeasurement(requestId);
handleCompletion(request);
} else if (method == "$/cancelRequest") {
handleCancelRequest();
@ -144,7 +143,7 @@ void LLMClientInterface::handleCancelRequest()
}
for (auto *provider : providers) {
disconnect(provider, nullptr, this, nullptr);
disconnect(provider->client(), nullptr, this, nullptr);
}
for (auto it = m_activeRequests.begin(); it != m_activeRequests.end(); ++it) {
@ -360,25 +359,22 @@ void LLMClientInterface::handleCompletion(const QJsonObject &request)
return;
}
QString requestId = request["id"].toString();
m_performanceLogger.startTimeMeasurement(requestId);
m_activeRequests[requestId] = {request, provider};
connect(
provider,
&PluginLLMCore::Provider::fullResponseReceived,
provider->client(),
&::LLMCore::BaseClient::requestCompleted,
this,
&LLMClientInterface::handleFullResponse,
Qt::UniqueConnection);
connect(
provider,
&PluginLLMCore::Provider::requestFailed,
provider->client(),
&::LLMCore::BaseClient::requestFailed,
this,
&LLMClientInterface::handleRequestFailed,
Qt::UniqueConnection);
provider->sendRequest(requestId, config.url, config.providerRequest);
auto requestId = provider->sendRequest(config.url, config.providerRequest);
m_activeRequests[requestId] = {request, provider};
m_performanceLogger.startTimeMeasurement(requestId);
}
PluginLLMCore::ContextData LLMClientInterface::prepareContext(

View File

@ -19,6 +19,7 @@
#include "QuickRefactorHandler.hpp"
#include <LLMCore/BaseClient.hpp>
#include <QJsonArray>
#include <QJsonDocument>
#include <QUuid>
@ -173,29 +174,27 @@ void QuickRefactorHandler::prepareAndSendRequest(
enableTools,
enableThinking);
QString requestId = QUuid::createUuid().toString();
m_lastRequestId = requestId;
QJsonObject request{{"id", requestId}};
m_isRefactoringInProgress = true;
m_activeRequests[requestId] = {request, provider};
connect(
provider,
&PluginLLMCore::Provider::fullResponseReceived,
provider->client(),
&::LLMCore::BaseClient::requestCompleted,
this,
&QuickRefactorHandler::handleFullResponse,
Qt::UniqueConnection);
connect(
provider,
&PluginLLMCore::Provider::requestFailed,
provider->client(),
&::LLMCore::BaseClient::requestFailed,
this,
&QuickRefactorHandler::handleRequestFailed,
Qt::UniqueConnection);
provider->sendRequest(requestId, config.url, config.providerRequest);
auto requestId = provider->sendRequest(config.url, config.providerRequest);
m_lastRequestId = requestId;
QJsonObject request{{"id", requestId}};
m_activeRequests[requestId] = {request, provider};
}
PluginLLMCore::ContextData QuickRefactorHandler::prepareContext(

View File

@ -28,6 +28,7 @@ target_link_libraries(PluginLLMCore
QtCreator::Core
QtCreator::Utils
QtCreator::ExtensionSystem
LLMCore
PRIVATE
QodeAssistLogger
)

View File

@ -1,9 +1,61 @@
/*
* Copyright (C) 2024-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/>.
*/
#include "Provider.hpp"
#include <LLMCore/BaseClient.hpp>
#include <LLMCore/ToolsManager.hpp>
#include <Logger.hpp>
namespace QodeAssist::PluginLLMCore {
Provider::Provider(QObject *parent)
: QObject(parent)
{}
RequestID Provider::sendRequest(const QUrl &url, const QJsonObject &payload)
{
auto *c = client();
QUrl baseUrl(url);
baseUrl.setPath("");
c->setUrl(baseUrl.toString());
c->setApiKey(apiKey());
auto requestId = c->sendMessage(payload);
LOG_MESSAGE(
QString("%1: Sending request %2 to %3").arg(name(), requestId, url.toString()));
return requestId;
}
void Provider::cancelRequest(const RequestID &requestId)
{
LOG_MESSAGE(QString("%1: Cancelling request %2").arg(name(), requestId));
client()->cancelRequest(requestId);
}
::LLMCore::ToolsManager *Provider::toolsManager() const
{
return client()->tools();
}
} // namespace QodeAssist::PluginLLMCore

View File

@ -21,10 +21,10 @@
#include <QFlags>
#include <QFuture>
#include <utils/environment.h>
#include <QNetworkRequest>
#include <QObject>
#include <QString>
#include <utils/environment.h>
#include "ContextData.hpp"
#include "IToolsManager.hpp"
@ -32,6 +32,7 @@
#include "RequestType.hpp"
namespace LLMCore {
class BaseClient;
class ToolsManager;
}
@ -73,34 +74,13 @@ public:
virtual QString apiKey() const = 0;
virtual void prepareNetworkRequest(QNetworkRequest &networkRequest) const = 0;
virtual ProviderID providerID() const = 0;
virtual void sendRequest(const RequestID &requestId, const QUrl &url, const QJsonObject &payload)
= 0;
virtual ProviderCapabilities capabilities() const { return {}; }
virtual void cancelRequest(const RequestID &requestId) = 0;
virtual ::LLMCore::ToolsManager *toolsManager() const { return nullptr; }
signals:
void partialResponseReceived(
const QodeAssist::PluginLLMCore::RequestID &requestId, const QString &partialText);
void fullResponseReceived(
const QodeAssist::PluginLLMCore::RequestID &requestId, const QString &fullText);
void requestFailed(const QodeAssist::PluginLLMCore::RequestID &requestId, const QString &error);
void toolExecutionStarted(
const QString &requestId, const QString &toolId, const QString &toolName);
void toolExecutionCompleted(
const QString &requestId,
const QString &toolId,
const QString &toolName,
const QString &result);
void continuationStarted(const QodeAssist::PluginLLMCore::RequestID &requestId);
void thinkingBlockReceived(
const QString &requestId, const QString &thinking, const QString &signature);
void redactedThinkingBlockReceived(const QString &requestId, const QString &signature);
virtual ::LLMCore::BaseClient *client() const = 0;
RequestID sendRequest(const QUrl &url, const QJsonObject &payload);
void cancelRequest(const RequestID &requestId);
::LLMCore::ToolsManager *toolsManager() const;
};
} // namespace QodeAssist::PluginLLMCore

View File

@ -176,74 +176,6 @@ PluginLLMCore::ProviderID ClaudeProvider::providerID() const
return PluginLLMCore::ProviderID::Claude;
}
void ClaudeProvider::sendRequest(
const PluginLLMCore::RequestID &requestId, const QUrl &url, const QJsonObject &payload)
{
QUrl baseUrl(url);
baseUrl.setPath("");
m_client->setUrl(baseUrl.toString());
m_client->setApiKey(apiKey());
::LLMCore::RequestCallbacks callbacks;
callbacks.onChunk = [this, requestId](const ::LLMCore::RequestID &, const QString &chunk) {
if (m_awaitingContinuation.remove(requestId)) {
emit continuationStarted(requestId);
}
emit partialResponseReceived(requestId, chunk);
};
callbacks.onCompleted
= [this, requestId](const ::LLMCore::RequestID &clientId, const QString &fullText) {
emit fullResponseReceived(requestId, fullText);
m_providerToClientIds.remove(requestId);
m_clientToProviderIds.remove(clientId);
m_awaitingContinuation.remove(requestId);
};
callbacks.onFailed
= [this, requestId](const ::LLMCore::RequestID &clientId, const QString &error) {
emit requestFailed(requestId, error);
m_providerToClientIds.remove(requestId);
m_clientToProviderIds.remove(clientId);
m_awaitingContinuation.remove(requestId);
};
callbacks.onThinkingBlock = [this, requestId](const ::LLMCore::RequestID &,
const QString &thinking,
const QString &signature) {
if (m_awaitingContinuation.remove(requestId)) {
emit continuationStarted(requestId);
}
if (thinking.isEmpty()) {
emit redactedThinkingBlockReceived(requestId, signature);
} else {
emit thinkingBlockReceived(requestId, thinking, signature);
}
};
callbacks.onToolStarted = [this, requestId](const ::LLMCore::RequestID &,
const QString &toolId,
const QString &toolName) {
emit toolExecutionStarted(requestId, toolId, toolName);
m_awaitingContinuation.insert(requestId);
};
callbacks.onToolResult = [this, requestId](const ::LLMCore::RequestID &,
const QString &toolId,
const QString &toolName,
const QString &result) {
emit toolExecutionCompleted(requestId, toolId, toolName, result);
};
auto clientId = m_client->sendMessage(payload, callbacks);
m_providerToClientIds[requestId] = clientId;
m_clientToProviderIds[clientId] = requestId;
LOG_MESSAGE(QString("ClaudeProvider: Sending request %1 (client: %2) to %3")
.arg(requestId, clientId, url.toString()));
}
PluginLLMCore::ProviderCapabilities ClaudeProvider::capabilities() const
{
return PluginLLMCore::ProviderCapability::Tools | PluginLLMCore::ProviderCapability::Thinking
@ -251,21 +183,9 @@ PluginLLMCore::ProviderCapabilities ClaudeProvider::capabilities() const
| PluginLLMCore::ProviderCapability::ModelListing;
}
void ClaudeProvider::cancelRequest(const PluginLLMCore::RequestID &requestId)
::LLMCore::BaseClient *ClaudeProvider::client() const
{
LOG_MESSAGE(QString("ClaudeProvider: Cancelling request %1").arg(requestId));
if (m_providerToClientIds.contains(requestId)) {
auto clientId = m_providerToClientIds.take(requestId);
m_clientToProviderIds.remove(clientId);
m_client->cancelRequest(clientId);
}
m_awaitingContinuation.remove(requestId);
}
::LLMCore::ToolsManager *ClaudeProvider::toolsManager() const
{
return m_client->tools();
return m_client;
}
} // namespace QodeAssist::Providers

View File

@ -19,8 +19,6 @@
#pragma once
#include <QSet>
#include <pluginllmcore/Provider.hpp>
#include <LLMCore/ClaudeClient.hpp>
@ -49,20 +47,12 @@ public:
QString apiKey() const override;
void prepareNetworkRequest(QNetworkRequest &networkRequest) const override;
PluginLLMCore::ProviderID providerID() const override;
void sendRequest(
const PluginLLMCore::RequestID &requestId, const QUrl &url, const QJsonObject &payload) override;
PluginLLMCore::ProviderCapabilities capabilities() const override;
void cancelRequest(const PluginLLMCore::RequestID &requestId) override;
::LLMCore::ToolsManager *toolsManager() const override;
::LLMCore::BaseClient *client() const override;
private:
::LLMCore::ClaudeClient *m_client;
QHash<PluginLLMCore::RequestID, ::LLMCore::RequestID> m_providerToClientIds;
QHash<::LLMCore::RequestID, PluginLLMCore::RequestID> m_clientToProviderIds;
QSet<PluginLLMCore::RequestID> m_awaitingContinuation;
};
} // namespace QodeAssist::Providers

View File

@ -192,74 +192,6 @@ PluginLLMCore::ProviderID GoogleAIProvider::providerID() const
return PluginLLMCore::ProviderID::GoogleAI;
}
void GoogleAIProvider::sendRequest(
const PluginLLMCore::RequestID &requestId, const QUrl &url, const QJsonObject &payload)
{
QUrl baseUrl(url);
baseUrl.setPath("");
m_client->setUrl(baseUrl.toString());
m_client->setApiKey(apiKey());
::LLMCore::RequestCallbacks callbacks;
callbacks.onChunk = [this, requestId](const ::LLMCore::RequestID &, const QString &chunk) {
if (m_awaitingContinuation.remove(requestId)) {
emit continuationStarted(requestId);
}
emit partialResponseReceived(requestId, chunk);
};
callbacks.onCompleted
= [this, requestId](const ::LLMCore::RequestID &clientId, const QString &fullText) {
emit fullResponseReceived(requestId, fullText);
m_providerToClientIds.remove(requestId);
m_clientToProviderIds.remove(clientId);
m_awaitingContinuation.remove(requestId);
};
callbacks.onFailed
= [this, requestId](const ::LLMCore::RequestID &clientId, const QString &error) {
emit requestFailed(requestId, error);
m_providerToClientIds.remove(requestId);
m_clientToProviderIds.remove(clientId);
m_awaitingContinuation.remove(requestId);
};
callbacks.onThinkingBlock = [this, requestId](const ::LLMCore::RequestID &,
const QString &thinking,
const QString &signature) {
if (m_awaitingContinuation.remove(requestId)) {
emit continuationStarted(requestId);
}
if (thinking.isEmpty()) {
emit redactedThinkingBlockReceived(requestId, signature);
} else {
emit thinkingBlockReceived(requestId, thinking, signature);
}
};
callbacks.onToolStarted = [this, requestId](const ::LLMCore::RequestID &,
const QString &toolId,
const QString &toolName) {
emit toolExecutionStarted(requestId, toolId, toolName);
m_awaitingContinuation.insert(requestId);
};
callbacks.onToolResult = [this, requestId](const ::LLMCore::RequestID &,
const QString &toolId,
const QString &toolName,
const QString &result) {
emit toolExecutionCompleted(requestId, toolId, toolName, result);
};
auto clientId = m_client->sendMessage(payload, callbacks);
m_providerToClientIds[requestId] = clientId;
m_clientToProviderIds[clientId] = requestId;
LOG_MESSAGE(QString("GoogleAIProvider: Sending request %1 (client: %2) to %3")
.arg(requestId, clientId, url.toString()));
}
PluginLLMCore::ProviderCapabilities GoogleAIProvider::capabilities() const
{
return PluginLLMCore::ProviderCapability::Tools | PluginLLMCore::ProviderCapability::Thinking
@ -267,21 +199,9 @@ PluginLLMCore::ProviderCapabilities GoogleAIProvider::capabilities() const
| PluginLLMCore::ProviderCapability::ModelListing;
}
void GoogleAIProvider::cancelRequest(const PluginLLMCore::RequestID &requestId)
::LLMCore::BaseClient *GoogleAIProvider::client() const
{
LOG_MESSAGE(QString("GoogleAIProvider: Cancelling request %1").arg(requestId));
if (m_providerToClientIds.contains(requestId)) {
auto clientId = m_providerToClientIds.take(requestId);
m_clientToProviderIds.remove(clientId);
m_client->cancelRequest(clientId);
}
m_awaitingContinuation.remove(requestId);
}
::LLMCore::ToolsManager *GoogleAIProvider::toolsManager() const
{
return m_client->tools();
return m_client;
}
} // namespace QodeAssist::Providers

View File

@ -19,8 +19,6 @@
#pragma once
#include <QSet>
#include <pluginllmcore/Provider.hpp>
#include <LLMCore/GoogleAIClient.hpp>
@ -49,20 +47,12 @@ public:
QString apiKey() const override;
void prepareNetworkRequest(QNetworkRequest &networkRequest) const override;
PluginLLMCore::ProviderID providerID() const override;
void sendRequest(
const PluginLLMCore::RequestID &requestId, const QUrl &url, const QJsonObject &payload) override;
PluginLLMCore::ProviderCapabilities capabilities() const override;
void cancelRequest(const PluginLLMCore::RequestID &requestId) override;
::LLMCore::ToolsManager *toolsManager() const override;
::LLMCore::BaseClient *client() const override;
private:
::LLMCore::GoogleAIClient *m_client;
QHash<PluginLLMCore::RequestID, ::LLMCore::RequestID> m_providerToClientIds;
QHash<::LLMCore::RequestID, PluginLLMCore::RequestID> m_clientToProviderIds;
QSet<PluginLLMCore::RequestID> m_awaitingContinuation;
};
} // namespace QodeAssist::Providers

View File

@ -104,92 +104,12 @@ PluginLLMCore::ProviderID LMStudioProvider::providerID() const
return PluginLLMCore::ProviderID::LMStudio;
}
void LMStudioProvider::sendRequest(
const PluginLLMCore::RequestID &requestId, const QUrl &url, const QJsonObject &payload)
{
QUrl baseUrl(url);
baseUrl.setPath("");
m_client->setUrl(baseUrl.toString());
m_client->setApiKey(apiKey());
::LLMCore::RequestCallbacks callbacks;
callbacks.onChunk = [this, requestId](const ::LLMCore::RequestID &, const QString &chunk) {
if (m_awaitingContinuation.remove(requestId)) {
emit continuationStarted(requestId);
}
emit partialResponseReceived(requestId, chunk);
};
callbacks.onCompleted
= [this, requestId](const ::LLMCore::RequestID &clientId, const QString &fullText) {
emit fullResponseReceived(requestId, fullText);
m_providerToClientIds.remove(requestId);
m_clientToProviderIds.remove(clientId);
m_awaitingContinuation.remove(requestId);
};
callbacks.onFailed
= [this, requestId](const ::LLMCore::RequestID &clientId, const QString &error) {
emit requestFailed(requestId, error);
m_providerToClientIds.remove(requestId);
m_clientToProviderIds.remove(clientId);
m_awaitingContinuation.remove(requestId);
};
callbacks.onThinkingBlock = [this, requestId](const ::LLMCore::RequestID &,
const QString &thinking,
const QString &signature) {
if (m_awaitingContinuation.remove(requestId)) {
emit continuationStarted(requestId);
}
if (thinking.isEmpty()) {
emit redactedThinkingBlockReceived(requestId, signature);
} else {
emit thinkingBlockReceived(requestId, thinking, signature);
}
};
callbacks.onToolStarted = [this, requestId](const ::LLMCore::RequestID &,
const QString &toolId,
const QString &toolName) {
emit toolExecutionStarted(requestId, toolId, toolName);
m_awaitingContinuation.insert(requestId);
};
callbacks.onToolResult = [this, requestId](const ::LLMCore::RequestID &,
const QString &toolId,
const QString &toolName,
const QString &result) {
emit toolExecutionCompleted(requestId, toolId, toolName, result);
};
auto clientId = m_client->sendMessage(payload, callbacks);
m_providerToClientIds[requestId] = clientId;
m_clientToProviderIds[clientId] = requestId;
LOG_MESSAGE(QString("LMStudioProvider: Sending request %1 (client: %2) to %3")
.arg(requestId, clientId, url.toString()));
}
PluginLLMCore::ProviderCapabilities LMStudioProvider::capabilities() const
{
return PluginLLMCore::ProviderCapability::Tools | PluginLLMCore::ProviderCapability::Image
| PluginLLMCore::ProviderCapability::ModelListing;
}
void LMStudioProvider::cancelRequest(const PluginLLMCore::RequestID &requestId)
{
LOG_MESSAGE(QString("LMStudioProvider: Cancelling request %1").arg(requestId));
if (m_providerToClientIds.contains(requestId)) {
auto clientId = m_providerToClientIds.take(requestId);
m_clientToProviderIds.remove(clientId);
m_client->cancelRequest(clientId);
}
m_awaitingContinuation.remove(requestId);
}
void LMStudioProvider::prepareRequest(
QJsonObject &request,
PluginLLMCore::PromptTemplate *prompt,
@ -235,9 +155,9 @@ void LMStudioProvider::prepareRequest(
}
}
::LLMCore::ToolsManager *LMStudioProvider::toolsManager() const
::LLMCore::BaseClient *LMStudioProvider::client() const
{
return m_client->tools();
return m_client;
}
} // namespace QodeAssist::Providers

View File

@ -19,8 +19,6 @@
#pragma once
#include <QSet>
#include <LLMCore/OpenAIClient.hpp>
#include <pluginllmcore/Provider.hpp>
@ -48,20 +46,12 @@ public:
QString apiKey() const override;
void prepareNetworkRequest(QNetworkRequest &networkRequest) const override;
PluginLLMCore::ProviderID providerID() const override;
void sendRequest(
const PluginLLMCore::RequestID &requestId, const QUrl &url, const QJsonObject &payload) override;
PluginLLMCore::ProviderCapabilities capabilities() const override;
void cancelRequest(const PluginLLMCore::RequestID &requestId) override;
::LLMCore::ToolsManager *toolsManager() const override;
::LLMCore::BaseClient *client() const override;
private:
::LLMCore::OpenAIClient *m_client;
QHash<PluginLLMCore::RequestID, ::LLMCore::RequestID> m_providerToClientIds;
QHash<::LLMCore::RequestID, PluginLLMCore::RequestID> m_clientToProviderIds;
QSet<PluginLLMCore::RequestID> m_awaitingContinuation;
};
} // namespace QodeAssist::Providers

View File

@ -164,94 +164,14 @@ PluginLLMCore::ProviderID LlamaCppProvider::providerID() const
return PluginLLMCore::ProviderID::LlamaCpp;
}
void LlamaCppProvider::sendRequest(
const PluginLLMCore::RequestID &requestId, const QUrl &url, const QJsonObject &payload)
{
QUrl baseUrl(url);
baseUrl.setPath("");
m_client->setUrl(baseUrl.toString());
m_client->setApiKey(apiKey());
::LLMCore::RequestCallbacks callbacks;
callbacks.onChunk = [this, requestId](const ::LLMCore::RequestID &, const QString &chunk) {
if (m_awaitingContinuation.remove(requestId)) {
emit continuationStarted(requestId);
}
emit partialResponseReceived(requestId, chunk);
};
callbacks.onCompleted
= [this, requestId](const ::LLMCore::RequestID &clientId, const QString &fullText) {
emit fullResponseReceived(requestId, fullText);
m_providerToClientIds.remove(requestId);
m_clientToProviderIds.remove(clientId);
m_awaitingContinuation.remove(requestId);
};
callbacks.onFailed
= [this, requestId](const ::LLMCore::RequestID &clientId, const QString &error) {
emit requestFailed(requestId, error);
m_providerToClientIds.remove(requestId);
m_clientToProviderIds.remove(clientId);
m_awaitingContinuation.remove(requestId);
};
callbacks.onThinkingBlock = [this, requestId](const ::LLMCore::RequestID &,
const QString &thinking,
const QString &signature) {
if (m_awaitingContinuation.remove(requestId)) {
emit continuationStarted(requestId);
}
if (thinking.isEmpty()) {
emit redactedThinkingBlockReceived(requestId, signature);
} else {
emit thinkingBlockReceived(requestId, thinking, signature);
}
};
callbacks.onToolStarted = [this, requestId](const ::LLMCore::RequestID &,
const QString &toolId,
const QString &toolName) {
emit toolExecutionStarted(requestId, toolId, toolName);
m_awaitingContinuation.insert(requestId);
};
callbacks.onToolResult = [this, requestId](const ::LLMCore::RequestID &,
const QString &toolId,
const QString &toolName,
const QString &result) {
emit toolExecutionCompleted(requestId, toolId, toolName, result);
};
auto clientId = m_client->sendMessage(payload, callbacks);
m_providerToClientIds[requestId] = clientId;
m_clientToProviderIds[clientId] = requestId;
LOG_MESSAGE(QString("LlamaCppProvider: Sending request %1 (client: %2) to %3")
.arg(requestId, clientId, url.toString()));
}
PluginLLMCore::ProviderCapabilities LlamaCppProvider::capabilities() const
{
return PluginLLMCore::ProviderCapability::Tools | PluginLLMCore::ProviderCapability::Image;
}
void LlamaCppProvider::cancelRequest(const PluginLLMCore::RequestID &requestId)
::LLMCore::BaseClient *LlamaCppProvider::client() const
{
LOG_MESSAGE(QString("LlamaCppProvider: Cancelling request %1").arg(requestId));
if (m_providerToClientIds.contains(requestId)) {
auto clientId = m_providerToClientIds.take(requestId);
m_clientToProviderIds.remove(clientId);
m_client->cancelRequest(clientId);
}
m_awaitingContinuation.remove(requestId);
}
::LLMCore::ToolsManager *LlamaCppProvider::toolsManager() const
{
return m_client->tools();
return m_client;
}
} // namespace QodeAssist::Providers

View File

@ -19,8 +19,6 @@
#pragma once
#include <QSet>
#include <pluginllmcore/Provider.hpp>
#include <LLMCore/LlamaCppClient.hpp>
@ -49,20 +47,12 @@ public:
QString apiKey() const override;
void prepareNetworkRequest(QNetworkRequest &networkRequest) const override;
PluginLLMCore::ProviderID providerID() const override;
void sendRequest(
const PluginLLMCore::RequestID &requestId, const QUrl &url, const QJsonObject &payload) override;
PluginLLMCore::ProviderCapabilities capabilities() const override;
void cancelRequest(const PluginLLMCore::RequestID &requestId) override;
::LLMCore::ToolsManager *toolsManager() const override;
::LLMCore::BaseClient *client() const override;
private:
::LLMCore::LlamaCppClient *m_client;
QHash<PluginLLMCore::RequestID, ::LLMCore::RequestID> m_providerToClientIds;
QHash<::LLMCore::RequestID, PluginLLMCore::RequestID> m_clientToProviderIds;
QSet<PluginLLMCore::RequestID> m_awaitingContinuation;
};
} // namespace QodeAssist::Providers

View File

@ -116,92 +116,12 @@ PluginLLMCore::ProviderID MistralAIProvider::providerID() const
return PluginLLMCore::ProviderID::MistralAI;
}
void MistralAIProvider::sendRequest(
const PluginLLMCore::RequestID &requestId, const QUrl &url, const QJsonObject &payload)
{
QUrl baseUrl(url);
baseUrl.setPath("");
m_client->setUrl(baseUrl.toString());
m_client->setApiKey(apiKey());
::LLMCore::RequestCallbacks callbacks;
callbacks.onChunk = [this, requestId](const ::LLMCore::RequestID &, const QString &chunk) {
if (m_awaitingContinuation.remove(requestId)) {
emit continuationStarted(requestId);
}
emit partialResponseReceived(requestId, chunk);
};
callbacks.onCompleted
= [this, requestId](const ::LLMCore::RequestID &clientId, const QString &fullText) {
emit fullResponseReceived(requestId, fullText);
m_providerToClientIds.remove(requestId);
m_clientToProviderIds.remove(clientId);
m_awaitingContinuation.remove(requestId);
};
callbacks.onFailed
= [this, requestId](const ::LLMCore::RequestID &clientId, const QString &error) {
emit requestFailed(requestId, error);
m_providerToClientIds.remove(requestId);
m_clientToProviderIds.remove(clientId);
m_awaitingContinuation.remove(requestId);
};
callbacks.onThinkingBlock = [this, requestId](const ::LLMCore::RequestID &,
const QString &thinking,
const QString &signature) {
if (m_awaitingContinuation.remove(requestId)) {
emit continuationStarted(requestId);
}
if (thinking.isEmpty()) {
emit redactedThinkingBlockReceived(requestId, signature);
} else {
emit thinkingBlockReceived(requestId, thinking, signature);
}
};
callbacks.onToolStarted = [this, requestId](const ::LLMCore::RequestID &,
const QString &toolId,
const QString &toolName) {
emit toolExecutionStarted(requestId, toolId, toolName);
m_awaitingContinuation.insert(requestId);
};
callbacks.onToolResult = [this, requestId](const ::LLMCore::RequestID &,
const QString &toolId,
const QString &toolName,
const QString &result) {
emit toolExecutionCompleted(requestId, toolId, toolName, result);
};
auto clientId = m_client->sendMessage(payload, callbacks);
m_providerToClientIds[requestId] = clientId;
m_clientToProviderIds[clientId] = requestId;
LOG_MESSAGE(QString("MistralAIProvider: Sending request %1 (client: %2) to %3")
.arg(requestId, clientId, url.toString()));
}
PluginLLMCore::ProviderCapabilities MistralAIProvider::capabilities() const
{
return PluginLLMCore::ProviderCapability::Tools | PluginLLMCore::ProviderCapability::Image
| PluginLLMCore::ProviderCapability::ModelListing;
}
void MistralAIProvider::cancelRequest(const PluginLLMCore::RequestID &requestId)
{
LOG_MESSAGE(QString("MistralAIProvider: Cancelling request %1").arg(requestId));
if (m_providerToClientIds.contains(requestId)) {
auto clientId = m_providerToClientIds.take(requestId);
m_clientToProviderIds.remove(clientId);
m_client->cancelRequest(clientId);
}
m_awaitingContinuation.remove(requestId);
}
void MistralAIProvider::prepareRequest(
QJsonObject &request,
PluginLLMCore::PromptTemplate *prompt,
@ -247,9 +167,9 @@ void MistralAIProvider::prepareRequest(
}
}
::LLMCore::ToolsManager *MistralAIProvider::toolsManager() const
::LLMCore::BaseClient *MistralAIProvider::client() const
{
return m_client->tools();
return m_client;
}
} // namespace QodeAssist::Providers

View File

@ -19,8 +19,6 @@
#pragma once
#include <QSet>
#include <LLMCore/OpenAIClient.hpp>
#include <pluginllmcore/Provider.hpp>
@ -48,20 +46,12 @@ public:
QString apiKey() const override;
void prepareNetworkRequest(QNetworkRequest &networkRequest) const override;
PluginLLMCore::ProviderID providerID() const override;
void sendRequest(
const PluginLLMCore::RequestID &requestId, const QUrl &url, const QJsonObject &payload) override;
PluginLLMCore::ProviderCapabilities capabilities() const override;
void cancelRequest(const PluginLLMCore::RequestID &requestId) override;
::LLMCore::ToolsManager *toolsManager() const override;
::LLMCore::BaseClient *client() const override;
private:
::LLMCore::OpenAIClient *m_client;
QHash<PluginLLMCore::RequestID, ::LLMCore::RequestID> m_providerToClientIds;
QHash<::LLMCore::RequestID, PluginLLMCore::RequestID> m_clientToProviderIds;
QSet<PluginLLMCore::RequestID> m_awaitingContinuation;
};
} // namespace QodeAssist::Providers

View File

@ -199,74 +199,6 @@ PluginLLMCore::ProviderID OllamaProvider::providerID() const
return PluginLLMCore::ProviderID::Ollama;
}
void OllamaProvider::sendRequest(
const PluginLLMCore::RequestID &requestId, const QUrl &url, const QJsonObject &payload)
{
QUrl baseUrl(url);
baseUrl.setPath("");
m_client->setUrl(baseUrl.toString());
m_client->setApiKey(apiKey());
::LLMCore::RequestCallbacks callbacks;
callbacks.onChunk = [this, requestId](const ::LLMCore::RequestID &, const QString &chunk) {
if (m_awaitingContinuation.remove(requestId)) {
emit continuationStarted(requestId);
}
emit partialResponseReceived(requestId, chunk);
};
callbacks.onCompleted
= [this, requestId](const ::LLMCore::RequestID &clientId, const QString &fullText) {
emit fullResponseReceived(requestId, fullText);
m_providerToClientIds.remove(requestId);
m_clientToProviderIds.remove(clientId);
m_awaitingContinuation.remove(requestId);
};
callbacks.onFailed
= [this, requestId](const ::LLMCore::RequestID &clientId, const QString &error) {
emit requestFailed(requestId, error);
m_providerToClientIds.remove(requestId);
m_clientToProviderIds.remove(clientId);
m_awaitingContinuation.remove(requestId);
};
callbacks.onThinkingBlock = [this, requestId](const ::LLMCore::RequestID &,
const QString &thinking,
const QString &signature) {
if (m_awaitingContinuation.remove(requestId)) {
emit continuationStarted(requestId);
}
if (thinking.isEmpty()) {
emit redactedThinkingBlockReceived(requestId, signature);
} else {
emit thinkingBlockReceived(requestId, thinking, signature);
}
};
callbacks.onToolStarted = [this, requestId](const ::LLMCore::RequestID &,
const QString &toolId,
const QString &toolName) {
emit toolExecutionStarted(requestId, toolId, toolName);
m_awaitingContinuation.insert(requestId);
};
callbacks.onToolResult = [this, requestId](const ::LLMCore::RequestID &,
const QString &toolId,
const QString &toolName,
const QString &result) {
emit toolExecutionCompleted(requestId, toolId, toolName, result);
};
auto clientId = m_client->sendMessage(payload, callbacks);
m_providerToClientIds[requestId] = clientId;
m_clientToProviderIds[clientId] = requestId;
LOG_MESSAGE(QString("OllamaProvider: Sending request %1 (client: %2) to %3")
.arg(requestId, clientId, url.toString()));
}
PluginLLMCore::ProviderCapabilities OllamaProvider::capabilities() const
{
return PluginLLMCore::ProviderCapability::Tools | PluginLLMCore::ProviderCapability::Thinking
@ -274,21 +206,9 @@ PluginLLMCore::ProviderCapabilities OllamaProvider::capabilities() const
| PluginLLMCore::ProviderCapability::ModelListing;
}
void OllamaProvider::cancelRequest(const PluginLLMCore::RequestID &requestId)
::LLMCore::BaseClient *OllamaProvider::client() const
{
LOG_MESSAGE(QString("OllamaProvider: Cancelling request %1").arg(requestId));
if (m_providerToClientIds.contains(requestId)) {
auto clientId = m_providerToClientIds.take(requestId);
m_clientToProviderIds.remove(clientId);
m_client->cancelRequest(clientId);
}
m_awaitingContinuation.remove(requestId);
}
::LLMCore::ToolsManager *OllamaProvider::toolsManager() const
{
return m_client->tools();
return m_client;
}
} // namespace QodeAssist::Providers

View File

@ -19,8 +19,6 @@
#pragma once
#include <QSet>
#include <pluginllmcore/Provider.hpp>
#include <LLMCore/OllamaClient.hpp>
@ -49,20 +47,12 @@ public:
QString apiKey() const override;
void prepareNetworkRequest(QNetworkRequest &networkRequest) const override;
PluginLLMCore::ProviderID providerID() const override;
void sendRequest(
const PluginLLMCore::RequestID &requestId, const QUrl &url, const QJsonObject &payload) override;
PluginLLMCore::ProviderCapabilities capabilities() const override;
void cancelRequest(const PluginLLMCore::RequestID &requestId) override;
::LLMCore::ToolsManager *toolsManager() const override;
::LLMCore::BaseClient *client() const override;
private:
::LLMCore::OllamaClient *m_client;
QHash<PluginLLMCore::RequestID, ::LLMCore::RequestID> m_providerToClientIds;
QHash<::LLMCore::RequestID, PluginLLMCore::RequestID> m_clientToProviderIds;
QSet<PluginLLMCore::RequestID> m_awaitingContinuation;
};
} // namespace QodeAssist::Providers

View File

@ -151,94 +151,14 @@ PluginLLMCore::ProviderID OpenAICompatProvider::providerID() const
return PluginLLMCore::ProviderID::OpenAICompatible;
}
void OpenAICompatProvider::sendRequest(
const PluginLLMCore::RequestID &requestId, const QUrl &url, const QJsonObject &payload)
{
QUrl baseUrl(url);
baseUrl.setPath("");
m_client->setUrl(baseUrl.toString());
m_client->setApiKey(apiKey());
::LLMCore::RequestCallbacks callbacks;
callbacks.onChunk = [this, requestId](const ::LLMCore::RequestID &, const QString &chunk) {
if (m_awaitingContinuation.remove(requestId)) {
emit continuationStarted(requestId);
}
emit partialResponseReceived(requestId, chunk);
};
callbacks.onCompleted
= [this, requestId](const ::LLMCore::RequestID &clientId, const QString &fullText) {
emit fullResponseReceived(requestId, fullText);
m_providerToClientIds.remove(requestId);
m_clientToProviderIds.remove(clientId);
m_awaitingContinuation.remove(requestId);
};
callbacks.onFailed
= [this, requestId](const ::LLMCore::RequestID &clientId, const QString &error) {
emit requestFailed(requestId, error);
m_providerToClientIds.remove(requestId);
m_clientToProviderIds.remove(clientId);
m_awaitingContinuation.remove(requestId);
};
callbacks.onThinkingBlock = [this, requestId](const ::LLMCore::RequestID &,
const QString &thinking,
const QString &signature) {
if (m_awaitingContinuation.remove(requestId)) {
emit continuationStarted(requestId);
}
if (thinking.isEmpty()) {
emit redactedThinkingBlockReceived(requestId, signature);
} else {
emit thinkingBlockReceived(requestId, thinking, signature);
}
};
callbacks.onToolStarted = [this, requestId](const ::LLMCore::RequestID &,
const QString &toolId,
const QString &toolName) {
emit toolExecutionStarted(requestId, toolId, toolName);
m_awaitingContinuation.insert(requestId);
};
callbacks.onToolResult = [this, requestId](const ::LLMCore::RequestID &,
const QString &toolId,
const QString &toolName,
const QString &result) {
emit toolExecutionCompleted(requestId, toolId, toolName, result);
};
auto clientId = m_client->sendMessage(payload, callbacks);
m_providerToClientIds[requestId] = clientId;
m_clientToProviderIds[clientId] = requestId;
LOG_MESSAGE(QString("OpenAICompatProvider: Sending request %1 (client: %2) to %3")
.arg(requestId, clientId, url.toString()));
}
PluginLLMCore::ProviderCapabilities OpenAICompatProvider::capabilities() const
{
return PluginLLMCore::ProviderCapability::Tools | PluginLLMCore::ProviderCapability::Image;
}
void OpenAICompatProvider::cancelRequest(const PluginLLMCore::RequestID &requestId)
::LLMCore::BaseClient *OpenAICompatProvider::client() const
{
LOG_MESSAGE(QString("OpenAICompatProvider: Cancelling request %1").arg(requestId));
if (m_providerToClientIds.contains(requestId)) {
auto clientId = m_providerToClientIds.take(requestId);
m_clientToProviderIds.remove(clientId);
m_client->cancelRequest(clientId);
}
m_awaitingContinuation.remove(requestId);
}
::LLMCore::ToolsManager *OpenAICompatProvider::toolsManager() const
{
return m_client->tools();
return m_client;
}
} // namespace QodeAssist::Providers

View File

@ -19,8 +19,6 @@
#pragma once
#include <QSet>
#include <LLMCore/OpenAIClient.hpp>
#include <pluginllmcore/Provider.hpp>
@ -48,20 +46,12 @@ public:
QString apiKey() const override;
void prepareNetworkRequest(QNetworkRequest &networkRequest) const override;
PluginLLMCore::ProviderID providerID() const override;
void sendRequest(
const PluginLLMCore::RequestID &requestId, const QUrl &url, const QJsonObject &payload) override;
PluginLLMCore::ProviderCapabilities capabilities() const override;
void cancelRequest(const PluginLLMCore::RequestID &requestId) override;
::LLMCore::ToolsManager *toolsManager() const override;
::LLMCore::BaseClient *client() const override;
private:
::LLMCore::OpenAIClient *m_client;
QHash<PluginLLMCore::RequestID, ::LLMCore::RequestID> m_providerToClientIds;
QHash<::LLMCore::RequestID, PluginLLMCore::RequestID> m_clientToProviderIds;
QSet<PluginLLMCore::RequestID> m_awaitingContinuation;
};
} // namespace QodeAssist::Providers

View File

@ -181,95 +181,15 @@ PluginLLMCore::ProviderID OpenAIProvider::providerID() const
return PluginLLMCore::ProviderID::OpenAI;
}
void OpenAIProvider::sendRequest(
const PluginLLMCore::RequestID &requestId, const QUrl &url, const QJsonObject &payload)
{
QUrl baseUrl(url);
baseUrl.setPath("");
m_client->setUrl(baseUrl.toString());
m_client->setApiKey(apiKey());
::LLMCore::RequestCallbacks callbacks;
callbacks.onChunk = [this, requestId](const ::LLMCore::RequestID &, const QString &chunk) {
if (m_awaitingContinuation.remove(requestId)) {
emit continuationStarted(requestId);
}
emit partialResponseReceived(requestId, chunk);
};
callbacks.onCompleted
= [this, requestId](const ::LLMCore::RequestID &clientId, const QString &fullText) {
emit fullResponseReceived(requestId, fullText);
m_providerToClientIds.remove(requestId);
m_clientToProviderIds.remove(clientId);
m_awaitingContinuation.remove(requestId);
};
callbacks.onFailed
= [this, requestId](const ::LLMCore::RequestID &clientId, const QString &error) {
emit requestFailed(requestId, error);
m_providerToClientIds.remove(requestId);
m_clientToProviderIds.remove(clientId);
m_awaitingContinuation.remove(requestId);
};
callbacks.onThinkingBlock = [this, requestId](const ::LLMCore::RequestID &,
const QString &thinking,
const QString &signature) {
if (m_awaitingContinuation.remove(requestId)) {
emit continuationStarted(requestId);
}
if (thinking.isEmpty()) {
emit redactedThinkingBlockReceived(requestId, signature);
} else {
emit thinkingBlockReceived(requestId, thinking, signature);
}
};
callbacks.onToolStarted = [this, requestId](const ::LLMCore::RequestID &,
const QString &toolId,
const QString &toolName) {
emit toolExecutionStarted(requestId, toolId, toolName);
m_awaitingContinuation.insert(requestId);
};
callbacks.onToolResult = [this, requestId](const ::LLMCore::RequestID &,
const QString &toolId,
const QString &toolName,
const QString &result) {
emit toolExecutionCompleted(requestId, toolId, toolName, result);
};
auto clientId = m_client->sendMessage(payload, callbacks);
m_providerToClientIds[requestId] = clientId;
m_clientToProviderIds[clientId] = requestId;
LOG_MESSAGE(QString("OpenAIProvider: Sending request %1 (client: %2) to %3")
.arg(requestId, clientId, url.toString()));
}
PluginLLMCore::ProviderCapabilities OpenAIProvider::capabilities() const
{
return PluginLLMCore::ProviderCapability::Tools | PluginLLMCore::ProviderCapability::Image
| PluginLLMCore::ProviderCapability::ModelListing;
}
void OpenAIProvider::cancelRequest(const PluginLLMCore::RequestID &requestId)
::LLMCore::BaseClient *OpenAIProvider::client() const
{
LOG_MESSAGE(QString("OpenAIProvider: Cancelling request %1").arg(requestId));
if (m_providerToClientIds.contains(requestId)) {
auto clientId = m_providerToClientIds.take(requestId);
m_clientToProviderIds.remove(clientId);
m_client->cancelRequest(clientId);
}
m_awaitingContinuation.remove(requestId);
}
::LLMCore::ToolsManager *OpenAIProvider::toolsManager() const
{
return m_client->tools();
return m_client;
}
} // namespace QodeAssist::Providers

View File

@ -19,8 +19,6 @@
#pragma once
#include <QSet>
#include <LLMCore/OpenAIClient.hpp>
#include <pluginllmcore/Provider.hpp>
@ -48,20 +46,12 @@ public:
QString apiKey() const override;
void prepareNetworkRequest(QNetworkRequest &networkRequest) const override;
PluginLLMCore::ProviderID providerID() const override;
void sendRequest(
const PluginLLMCore::RequestID &requestId, const QUrl &url, const QJsonObject &payload) override;
PluginLLMCore::ProviderCapabilities capabilities() const override;
void cancelRequest(const PluginLLMCore::RequestID &requestId) override;
::LLMCore::ToolsManager *toolsManager() const override;
::LLMCore::BaseClient *client() const override;
private:
::LLMCore::OpenAIClient *m_client;
QHash<PluginLLMCore::RequestID, ::LLMCore::RequestID> m_providerToClientIds;
QHash<::LLMCore::RequestID, PluginLLMCore::RequestID> m_clientToProviderIds;
QSet<PluginLLMCore::RequestID> m_awaitingContinuation;
};
} // namespace QodeAssist::Providers

View File

@ -222,71 +222,6 @@ PluginLLMCore::ProviderID OpenAIResponsesProvider::providerID() const
return PluginLLMCore::ProviderID::OpenAIResponses;
}
void OpenAIResponsesProvider::sendRequest(
const PluginLLMCore::RequestID &requestId, const QUrl &url, const QJsonObject &payload)
{
QUrl baseUrl(url);
baseUrl.setPath("");
m_client->setUrl(baseUrl.toString());
m_client->setApiKey(apiKey());
::LLMCore::RequestCallbacks callbacks;
callbacks.onChunk = [this, requestId](const ::LLMCore::RequestID &, const QString &chunk) {
if (m_awaitingContinuation.remove(requestId))
emit continuationStarted(requestId);
emit partialResponseReceived(requestId, chunk);
};
callbacks.onCompleted
= [this, requestId](const ::LLMCore::RequestID &clientId, const QString &fullText) {
emit fullResponseReceived(requestId, fullText);
m_providerToClientIds.remove(requestId);
m_clientToProviderIds.remove(clientId);
m_awaitingContinuation.remove(requestId);
};
callbacks.onFailed
= [this, requestId](const ::LLMCore::RequestID &clientId, const QString &error) {
emit requestFailed(requestId, error);
m_providerToClientIds.remove(requestId);
m_clientToProviderIds.remove(clientId);
m_awaitingContinuation.remove(requestId);
};
callbacks.onThinkingBlock = [this, requestId](const ::LLMCore::RequestID &,
const QString &thinking,
const QString &signature) {
if (m_awaitingContinuation.remove(requestId))
emit continuationStarted(requestId);
if (thinking.isEmpty())
emit redactedThinkingBlockReceived(requestId, signature);
else
emit thinkingBlockReceived(requestId, thinking, signature);
};
callbacks.onToolStarted = [this, requestId](const ::LLMCore::RequestID &,
const QString &toolId,
const QString &toolName) {
emit toolExecutionStarted(requestId, toolId, toolName);
m_awaitingContinuation.insert(requestId);
};
callbacks.onToolResult = [this, requestId](const ::LLMCore::RequestID &,
const QString &toolId,
const QString &toolName,
const QString &result) {
emit toolExecutionCompleted(requestId, toolId, toolName, result);
};
auto clientId = m_client->sendMessage(payload, callbacks);
m_providerToClientIds[requestId] = clientId;
m_clientToProviderIds[clientId] = requestId;
LOG_MESSAGE(QString("OpenAIResponsesProvider: Sending request %1 (client: %2) to %3")
.arg(requestId, clientId, url.toString()));
}
PluginLLMCore::ProviderCapabilities OpenAIResponsesProvider::capabilities() const
{
return PluginLLMCore::ProviderCapability::Tools | PluginLLMCore::ProviderCapability::Thinking
@ -294,21 +229,9 @@ PluginLLMCore::ProviderCapabilities OpenAIResponsesProvider::capabilities() cons
| PluginLLMCore::ProviderCapability::ModelListing;
}
void OpenAIResponsesProvider::cancelRequest(const PluginLLMCore::RequestID &requestId)
::LLMCore::BaseClient *OpenAIResponsesProvider::client() const
{
LOG_MESSAGE(QString("OpenAIResponsesProvider: Cancelling request %1").arg(requestId));
if (m_providerToClientIds.contains(requestId)) {
auto clientId = m_providerToClientIds.take(requestId);
m_clientToProviderIds.remove(clientId);
m_client->cancelRequest(clientId);
}
m_awaitingContinuation.remove(requestId);
}
::LLMCore::ToolsManager *OpenAIResponsesProvider::toolsManager() const
{
return m_client->tools();
return m_client;
}
} // namespace QodeAssist::Providers

View File

@ -19,8 +19,6 @@
#pragma once
#include <QSet>
#include <LLMCore/OpenAIResponsesClient.hpp>
#include <pluginllmcore/Provider.hpp>
@ -48,20 +46,12 @@ public:
QString apiKey() const override;
void prepareNetworkRequest(QNetworkRequest &networkRequest) const override;
PluginLLMCore::ProviderID providerID() const override;
void sendRequest(
const PluginLLMCore::RequestID &requestId, const QUrl &url, const QJsonObject &payload) override;
PluginLLMCore::ProviderCapabilities capabilities() const override;
void cancelRequest(const PluginLLMCore::RequestID &requestId) override;
::LLMCore::ToolsManager *toolsManager() const override;
::LLMCore::BaseClient *client() const override;
private:
::LLMCore::OpenAIResponsesClient *m_client;
QHash<PluginLLMCore::RequestID, ::LLMCore::RequestID> m_providerToClientIds;
QHash<::LLMCore::RequestID, PluginLLMCore::RequestID> m_clientToProviderIds;
QSet<PluginLLMCore::RequestID> m_awaitingContinuation;
};
} // namespace QodeAssist::Providers

View File

@ -17,6 +17,8 @@ target_link_libraries(QodeAssistTest PRIVATE
GTest::Main
QtCreator::LanguageClient
Context
PluginLLMCore
LLMCore
)
target_compile_definitions(QodeAssistTest PRIVATE CMAKE_CURRENT_SOURCE_DIR="${CMAKE_CURRENT_SOURCE_DIR}")