From e65ac23e6611340d7d0a90a547fcaaaf53fc04ed Mon Sep 17 00:00:00 2001 From: Petr Mironychev <9195189+Palm1r@users.noreply.github.com> Date: Thu, 11 Jun 2026 14:18:44 +0200 Subject: [PATCH] refactor: Move QuickRefactor to Session way --- LLMClientInterface.cpp | 14 ++++- QuickRefactorHandler.cpp | 98 +++++++++++++------------------- QuickRefactorHandler.hpp | 10 +--- bench/main.cpp | 11 ++-- sources/Session/PluginBlocks.hpp | 18 ++++++ sources/Session/Session.cpp | 17 ++---- sources/Session/Session.hpp | 2 - 7 files changed, 83 insertions(+), 87 deletions(-) diff --git a/LLMClientInterface.cpp b/LLMClientInterface.cpp index a1ac8af..b0b0100 100644 --- a/LLMClientInterface.cpp +++ b/LLMClientInterface.cpp @@ -18,9 +18,16 @@ #include #include #include +#include #include +#include #include "sources/common/ContextData.hpp" +#include + +#include +#include + #include "CodeHandler.hpp" #include "context/DocumentContextReader.hpp" #include "context/Utils.hpp" @@ -271,7 +278,7 @@ void LLMClientInterface::handleCompletion(const QJsonObject &request) editorContext.append(m_contextManager->openedFilesContext({filePath})); if (!editorContext.isEmpty()) - context.systemPrompt = editorContext; + session->systemPrompt()->setLayer(QStringLiteral("completion.context"), editorContext); connect(session, &Session::finished, this, [this, session](const LLMQore::RequestID &, const QString &) { onCompletionFinished(requestIdForSession(session)); @@ -284,7 +291,10 @@ void LLMClientInterface::handleCompletion(const QJsonObject &request) client->setTransferTimeout( static_cast(m_generalSettings.requestTimeout() * 1000)); - const LLMQore::RequestID requestId = session->sendCompletion(std::move(context)); + std::vector> blocks; + blocks.push_back(std::make_unique( + context.prefix.value_or(QString()), context.suffix.value_or(QString()))); + const LLMQore::RequestID requestId = session->send(std::move(blocks), /*toolsOverride=*/false); if (requestId.isEmpty()) { QString error = QString("Failed to start completion request for agent '%1': %2") .arg(agentName, session->lastError().message); diff --git a/QuickRefactorHandler.cpp b/QuickRefactorHandler.cpp index 3e8cd5f..6962cf1 100644 --- a/QuickRefactorHandler.cpp +++ b/QuickRefactorHandler.cpp @@ -30,6 +30,7 @@ #include #include +#include #include #include #include @@ -184,14 +185,13 @@ void QuickRefactorHandler::prepareAndSendRequest( m_isRefactoringInProgress = true; connect( - client, &::LLMQore::BaseClient::requestCompleted, - this, &QuickRefactorHandler::handleFullResponse, Qt::UniqueConnection); + session, &Session::finished, this, + [this](const LLMQore::RequestID &id, const QString &) { onRefactorFinished(id); }); connect( - client, &::LLMQore::BaseClient::requestFinalized, - this, &QuickRefactorHandler::handleRequestFinalized, Qt::UniqueConnection); - connect( - client, &::LLMQore::BaseClient::requestFailed, - this, &QuickRefactorHandler::handleRequestFailed, Qt::UniqueConnection); + session, &Session::failed, this, + [this](const LLMQore::RequestID &id, const QodeAssist::ErrorInfo &error) { + onRefactorFailed(id, error); + }); std::vector> blocks; const QString userMessage = instructions.isEmpty() @@ -371,32 +371,6 @@ QString QuickRefactorHandler::buildSystemPrompt( return systemPrompt; } -void QuickRefactorHandler::handleLLMResponse( - const QString &response, const QJsonObject &request, bool isComplete) -{ - if (request["id"].toString() != m_lastRequestId) { - return; - } - - if (isComplete) { - m_isRefactoringInProgress = false; - QString cleanedResponse = ResponseCleaner::clean(response); - - RefactorResult result; - result.newText = cleanedResponse; - result.insertRange = m_currentRange; - result.success = true; - result.editor = m_currentEditor; - - LOG_MESSAGE("Refactoring completed successfully. New code to insert: "); - LOG_MESSAGE("---------- BEGIN REFACTORED CODE ----------"); - LOG_MESSAGE(cleanedResponse); - LOG_MESSAGE("----------- END REFACTORED CODE -----------"); - - emit refactoringCompleted(result); - } -} - void QuickRefactorHandler::cancelRequest() { if (!m_isRefactoringInProgress) @@ -410,12 +384,8 @@ void QuickRefactorHandler::cancelRequest() if (it != m_activeRequests.end()) { Session *session = it.value().session; m_activeRequests.erase(it); - if (session) { - if (auto *client = session->client()) - disconnect(client, nullptr, this, nullptr); - if (m_sessionManager) - m_sessionManager->removeSession(session); - } + if (session && m_sessionManager) + m_sessionManager->removeSession(session); } RefactorResult result; @@ -424,7 +394,7 @@ void QuickRefactorHandler::cancelRequest() emit refactoringCompleted(result); } -void QuickRefactorHandler::handleFullResponse(const QString &requestId, const QString &fullText) +void QuickRefactorHandler::onRefactorFinished(const QString &requestId) { if (requestId != m_lastRequestId) return; @@ -434,30 +404,36 @@ void QuickRefactorHandler::handleFullResponse(const QString &requestId, const QS if (it != m_activeRequests.end()) m_activeRequests.erase(it); - QJsonObject request{{"id", requestId}}; - handleLLMResponse(fullText, request, true); + QString fullText; + if (session) { + if (auto *history = session->history(); history && !history->isEmpty()) + fullText = history->messages().back().text(); + } + + m_isRefactoringInProgress = false; + m_lastRequestId.clear(); + + const QString cleanedResponse = ResponseCleaner::clean(fullText); + + RefactorResult result; + result.newText = cleanedResponse; + result.insertRange = m_currentRange; + result.success = true; + result.editor = m_currentEditor; + + LOG_MESSAGE("Refactoring completed successfully. New code to insert: "); + LOG_MESSAGE("---------- BEGIN REFACTORED CODE ----------"); + LOG_MESSAGE(cleanedResponse); + LOG_MESSAGE("----------- END REFACTORED CODE -----------"); + + emit refactoringCompleted(result); if (session && m_sessionManager) m_sessionManager->removeSession(session); } -void QuickRefactorHandler::handleRequestFinalized( - const ::LLMQore::RequestID &requestId, const ::LLMQore::CompletionInfo &info) -{ - if (requestId != m_lastRequestId || !info.usage) - return; - - const auto &u = *info.usage; - LOG_MESSAGE( - QString("Quick refactor usage [%1]: prompt=%2 completion=%3 cached=%4 reasoning=%5") - .arg(requestId) - .arg(u.promptTokens) - .arg(u.completionTokens) - .arg(u.cachedPromptTokens) - .arg(u.reasoningTokens)); -} - -void QuickRefactorHandler::handleRequestFailed(const QString &requestId, const QString &error) +void QuickRefactorHandler::onRefactorFailed( + const QString &requestId, const QodeAssist::ErrorInfo &error) { if (requestId != m_lastRequestId) return; @@ -468,9 +444,11 @@ void QuickRefactorHandler::handleRequestFailed(const QString &requestId, const Q m_activeRequests.erase(it); m_isRefactoringInProgress = false; + m_lastRequestId.clear(); + RefactorResult result; result.success = false; - result.errorMessage = error; + result.errorMessage = error.message; result.editor = m_currentEditor; emit refactoringCompleted(result); diff --git a/QuickRefactorHandler.hpp b/QuickRefactorHandler.hpp index 2ca22eb..ad7a119 100644 --- a/QuickRefactorHandler.hpp +++ b/QuickRefactorHandler.hpp @@ -12,6 +12,7 @@ #include #include +#include #include #include @@ -49,19 +50,14 @@ public: signals: void refactoringCompleted(const QodeAssist::RefactorResult &result); -private slots: - void handleFullResponse(const QString &requestId, const QString &fullText); - void handleRequestFinalized( - const ::LLMQore::RequestID &requestId, const ::LLMQore::CompletionInfo &info); - void handleRequestFailed(const QString &requestId, const QString &error); - private: void prepareAndSendRequest( TextEditor::TextEditorWidget *editor, const QString &instructions, const Utils::Text::Range &range); - void handleLLMResponse(const QString &response, const QJsonObject &request, bool isComplete); + void onRefactorFinished(const QString &requestId); + void onRefactorFailed(const QString &requestId, const QodeAssist::ErrorInfo &error); QString buildSystemPrompt( TextEditor::TextEditorWidget *editor, const Utils::Text::Range &range); QString pickRefactorAgent(const QString &filePath) const; diff --git a/bench/main.cpp b/bench/main.cpp index da962a1..dc968ea 100644 --- a/bench/main.cpp +++ b/bench/main.cpp @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -532,11 +533,11 @@ int main(int argc, char *argv[]) auto dispatch = [&] { if (fimMode) { - Templates::ContextData ctx; - ctx.prefix = turns.value(0); - if (parser.isSet(suffixOpt)) - ctx.suffix = parser.value(suffixOpt); - if (session->sendCompletion(std::move(ctx)).isEmpty()) { + const QString prefix = turns.value(0); + const QString suffix = parser.isSet(suffixOpt) ? parser.value(suffixOpt) : QString(); + std::vector> blocks; + blocks.push_back(std::make_unique(prefix, suffix)); + if (session->send(std::move(blocks), /*toolsOverride=*/false).isEmpty()) { err() << "Failed to dispatch FIM request: " << session->lastError().message << "\n"; exitCode = 1; QCoreApplication::quit(); diff --git a/sources/Session/PluginBlocks.hpp b/sources/Session/PluginBlocks.hpp index ad03950..7b3cbfc 100644 --- a/sources/Session/PluginBlocks.hpp +++ b/sources/Session/PluginBlocks.hpp @@ -31,6 +31,24 @@ private: QString m_mediaType; }; +class CompletionContent : public LLMQore::ContentBlock +{ +public: + CompletionContent(QString prefix, QString suffix) + : m_prefix(std::move(prefix)) + , m_suffix(std::move(suffix)) + {} + + QString type() const override { return QStringLiteral("completion"); } + + QString prefix() const { return m_prefix; } + QString suffix() const { return m_suffix; } + +private: + QString m_prefix; + QString m_suffix; +}; + class StoredAttachmentContent : public LLMQore::ContentBlock { public: diff --git a/sources/Session/Session.cpp b/sources/Session/Session.cpp index aaac52c..0297f71 100644 --- a/sources/Session/Session.cpp +++ b/sources/Session/Session.cpp @@ -134,17 +134,6 @@ LLMQore::RequestID Session::sendText(const QString &text) return send(std::move(blocks)); } -LLMQore::RequestID Session::sendCompletion(Templates::ContextData ctx) -{ - if (!isValid()) { - m_lastError = makeError(ErrorCategory::Config, invalidReason()); - return {}; - } - if (isInFlight()) - cancel(); - return dispatchContext(std::move(ctx), /*tools=*/false); -} - LLMQore::RequestID Session::send( std::vector> userBlocks, std::optional toolsOverride) @@ -290,6 +279,12 @@ Templates::ContextData Session::buildLegacyContext( if (m.role() == Message::Role::System) continue; + if (auto *cc = m.lastBlockOfType()) { + ctx.prefix = cc->prefix(); + ctx.suffix = cc->suffix(); + continue; + } + QVector blockEntries; for (const auto &blockPtr : m.blocks()) { diff --git a/sources/Session/Session.hpp b/sources/Session/Session.hpp index 9500d2b..b87d867 100644 --- a/sources/Session/Session.hpp +++ b/sources/Session/Session.hpp @@ -66,8 +66,6 @@ public: LLMQore::RequestID sendText(const QString &text); - LLMQore::RequestID sendCompletion(Templates::ContextData ctx); - void cancel(); signals: