mirror of
https://github.com/Palm1r/QodeAssist.git
synced 2026-06-13 17:59:15 -04:00
refactor: Move QuickRefactor to Session way
This commit is contained in:
@@ -18,9 +18,16 @@
|
|||||||
#include <AgentFactory.hpp>
|
#include <AgentFactory.hpp>
|
||||||
#include <AgentRouter.hpp>
|
#include <AgentRouter.hpp>
|
||||||
#include <ConversationHistory.hpp>
|
#include <ConversationHistory.hpp>
|
||||||
|
#include <PluginBlocks.hpp>
|
||||||
#include <Session.hpp>
|
#include <Session.hpp>
|
||||||
|
#include <SystemPromptBuilder.hpp>
|
||||||
#include "sources/common/ContextData.hpp"
|
#include "sources/common/ContextData.hpp"
|
||||||
|
|
||||||
|
#include <LLMQore/ContentBlocks.hpp>
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "CodeHandler.hpp"
|
#include "CodeHandler.hpp"
|
||||||
#include "context/DocumentContextReader.hpp"
|
#include "context/DocumentContextReader.hpp"
|
||||||
#include "context/Utils.hpp"
|
#include "context/Utils.hpp"
|
||||||
@@ -271,7 +278,7 @@ void LLMClientInterface::handleCompletion(const QJsonObject &request)
|
|||||||
editorContext.append(m_contextManager->openedFilesContext({filePath}));
|
editorContext.append(m_contextManager->openedFilesContext({filePath}));
|
||||||
|
|
||||||
if (!editorContext.isEmpty())
|
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 &) {
|
connect(session, &Session::finished, this, [this, session](const LLMQore::RequestID &, const QString &) {
|
||||||
onCompletionFinished(requestIdForSession(session));
|
onCompletionFinished(requestIdForSession(session));
|
||||||
@@ -284,7 +291,10 @@ void LLMClientInterface::handleCompletion(const QJsonObject &request)
|
|||||||
client->setTransferTimeout(
|
client->setTransferTimeout(
|
||||||
static_cast<int>(m_generalSettings.requestTimeout() * 1000));
|
static_cast<int>(m_generalSettings.requestTimeout() * 1000));
|
||||||
|
|
||||||
const LLMQore::RequestID requestId = session->sendCompletion(std::move(context));
|
std::vector<std::unique_ptr<LLMQore::ContentBlock>> blocks;
|
||||||
|
blocks.push_back(std::make_unique<CompletionContent>(
|
||||||
|
context.prefix.value_or(QString()), context.suffix.value_or(QString())));
|
||||||
|
const LLMQore::RequestID requestId = session->send(std::move(blocks), /*toolsOverride=*/false);
|
||||||
if (requestId.isEmpty()) {
|
if (requestId.isEmpty()) {
|
||||||
QString error = QString("Failed to start completion request for agent '%1': %2")
|
QString error = QString("Failed to start completion request for agent '%1': %2")
|
||||||
.arg(agentName, session->lastError().message);
|
.arg(agentName, session->lastError().message);
|
||||||
|
|||||||
@@ -30,6 +30,7 @@
|
|||||||
|
|
||||||
#include <AgentFactory.hpp>
|
#include <AgentFactory.hpp>
|
||||||
#include <AgentRouter.hpp>
|
#include <AgentRouter.hpp>
|
||||||
|
#include <ConversationHistory.hpp>
|
||||||
#include <Session.hpp>
|
#include <Session.hpp>
|
||||||
#include <SessionManager.hpp>
|
#include <SessionManager.hpp>
|
||||||
#include <SystemPromptBuilder.hpp>
|
#include <SystemPromptBuilder.hpp>
|
||||||
@@ -184,14 +185,13 @@ void QuickRefactorHandler::prepareAndSendRequest(
|
|||||||
m_isRefactoringInProgress = true;
|
m_isRefactoringInProgress = true;
|
||||||
|
|
||||||
connect(
|
connect(
|
||||||
client, &::LLMQore::BaseClient::requestCompleted,
|
session, &Session::finished, this,
|
||||||
this, &QuickRefactorHandler::handleFullResponse, Qt::UniqueConnection);
|
[this](const LLMQore::RequestID &id, const QString &) { onRefactorFinished(id); });
|
||||||
connect(
|
connect(
|
||||||
client, &::LLMQore::BaseClient::requestFinalized,
|
session, &Session::failed, this,
|
||||||
this, &QuickRefactorHandler::handleRequestFinalized, Qt::UniqueConnection);
|
[this](const LLMQore::RequestID &id, const QodeAssist::ErrorInfo &error) {
|
||||||
connect(
|
onRefactorFailed(id, error);
|
||||||
client, &::LLMQore::BaseClient::requestFailed,
|
});
|
||||||
this, &QuickRefactorHandler::handleRequestFailed, Qt::UniqueConnection);
|
|
||||||
|
|
||||||
std::vector<std::unique_ptr<LLMQore::ContentBlock>> blocks;
|
std::vector<std::unique_ptr<LLMQore::ContentBlock>> blocks;
|
||||||
const QString userMessage = instructions.isEmpty()
|
const QString userMessage = instructions.isEmpty()
|
||||||
@@ -371,32 +371,6 @@ QString QuickRefactorHandler::buildSystemPrompt(
|
|||||||
return systemPrompt;
|
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()
|
void QuickRefactorHandler::cancelRequest()
|
||||||
{
|
{
|
||||||
if (!m_isRefactoringInProgress)
|
if (!m_isRefactoringInProgress)
|
||||||
@@ -410,12 +384,8 @@ void QuickRefactorHandler::cancelRequest()
|
|||||||
if (it != m_activeRequests.end()) {
|
if (it != m_activeRequests.end()) {
|
||||||
Session *session = it.value().session;
|
Session *session = it.value().session;
|
||||||
m_activeRequests.erase(it);
|
m_activeRequests.erase(it);
|
||||||
if (session) {
|
if (session && m_sessionManager)
|
||||||
if (auto *client = session->client())
|
m_sessionManager->removeSession(session);
|
||||||
disconnect(client, nullptr, this, nullptr);
|
|
||||||
if (m_sessionManager)
|
|
||||||
m_sessionManager->removeSession(session);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RefactorResult result;
|
RefactorResult result;
|
||||||
@@ -424,7 +394,7 @@ void QuickRefactorHandler::cancelRequest()
|
|||||||
emit refactoringCompleted(result);
|
emit refactoringCompleted(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QuickRefactorHandler::handleFullResponse(const QString &requestId, const QString &fullText)
|
void QuickRefactorHandler::onRefactorFinished(const QString &requestId)
|
||||||
{
|
{
|
||||||
if (requestId != m_lastRequestId)
|
if (requestId != m_lastRequestId)
|
||||||
return;
|
return;
|
||||||
@@ -434,30 +404,36 @@ void QuickRefactorHandler::handleFullResponse(const QString &requestId, const QS
|
|||||||
if (it != m_activeRequests.end())
|
if (it != m_activeRequests.end())
|
||||||
m_activeRequests.erase(it);
|
m_activeRequests.erase(it);
|
||||||
|
|
||||||
QJsonObject request{{"id", requestId}};
|
QString fullText;
|
||||||
handleLLMResponse(fullText, request, true);
|
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)
|
if (session && m_sessionManager)
|
||||||
m_sessionManager->removeSession(session);
|
m_sessionManager->removeSession(session);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QuickRefactorHandler::handleRequestFinalized(
|
void QuickRefactorHandler::onRefactorFailed(
|
||||||
const ::LLMQore::RequestID &requestId, const ::LLMQore::CompletionInfo &info)
|
const QString &requestId, const QodeAssist::ErrorInfo &error)
|
||||||
{
|
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
if (requestId != m_lastRequestId)
|
if (requestId != m_lastRequestId)
|
||||||
return;
|
return;
|
||||||
@@ -468,9 +444,11 @@ void QuickRefactorHandler::handleRequestFailed(const QString &requestId, const Q
|
|||||||
m_activeRequests.erase(it);
|
m_activeRequests.erase(it);
|
||||||
|
|
||||||
m_isRefactoringInProgress = false;
|
m_isRefactoringInProgress = false;
|
||||||
|
m_lastRequestId.clear();
|
||||||
|
|
||||||
RefactorResult result;
|
RefactorResult result;
|
||||||
result.success = false;
|
result.success = false;
|
||||||
result.errorMessage = error;
|
result.errorMessage = error.message;
|
||||||
result.editor = m_currentEditor;
|
result.editor = m_currentEditor;
|
||||||
emit refactoringCompleted(result);
|
emit refactoringCompleted(result);
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
#include <texteditor/texteditor.h>
|
#include <texteditor/texteditor.h>
|
||||||
#include <utils/textutils.h>
|
#include <utils/textutils.h>
|
||||||
|
|
||||||
|
#include <ErrorInfo.hpp>
|
||||||
#include <context/ContextManager.hpp>
|
#include <context/ContextManager.hpp>
|
||||||
#include <context/IDocumentReader.hpp>
|
#include <context/IDocumentReader.hpp>
|
||||||
|
|
||||||
@@ -49,19 +50,14 @@ public:
|
|||||||
signals:
|
signals:
|
||||||
void refactoringCompleted(const QodeAssist::RefactorResult &result);
|
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:
|
private:
|
||||||
void prepareAndSendRequest(
|
void prepareAndSendRequest(
|
||||||
TextEditor::TextEditorWidget *editor,
|
TextEditor::TextEditorWidget *editor,
|
||||||
const QString &instructions,
|
const QString &instructions,
|
||||||
const Utils::Text::Range &range);
|
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(
|
QString buildSystemPrompt(
|
||||||
TextEditor::TextEditorWidget *editor, const Utils::Text::Range &range);
|
TextEditor::TextEditorWidget *editor, const Utils::Text::Range &range);
|
||||||
QString pickRefactorAgent(const QString &filePath) const;
|
QString pickRefactorAgent(const QString &filePath) const;
|
||||||
|
|||||||
@@ -31,6 +31,7 @@
|
|||||||
#include <AgentFactory.hpp>
|
#include <AgentFactory.hpp>
|
||||||
#include <ContextData.hpp>
|
#include <ContextData.hpp>
|
||||||
#include <ContextRenderer.hpp>
|
#include <ContextRenderer.hpp>
|
||||||
|
#include <PluginBlocks.hpp>
|
||||||
#include <GenericProvider.hpp>
|
#include <GenericProvider.hpp>
|
||||||
#include <Provider.hpp>
|
#include <Provider.hpp>
|
||||||
#include <ProviderInstance.hpp>
|
#include <ProviderInstance.hpp>
|
||||||
@@ -532,11 +533,11 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
auto dispatch = [&] {
|
auto dispatch = [&] {
|
||||||
if (fimMode) {
|
if (fimMode) {
|
||||||
Templates::ContextData ctx;
|
const QString prefix = turns.value(0);
|
||||||
ctx.prefix = turns.value(0);
|
const QString suffix = parser.isSet(suffixOpt) ? parser.value(suffixOpt) : QString();
|
||||||
if (parser.isSet(suffixOpt))
|
std::vector<std::unique_ptr<LLMQore::ContentBlock>> blocks;
|
||||||
ctx.suffix = parser.value(suffixOpt);
|
blocks.push_back(std::make_unique<QodeAssist::CompletionContent>(prefix, suffix));
|
||||||
if (session->sendCompletion(std::move(ctx)).isEmpty()) {
|
if (session->send(std::move(blocks), /*toolsOverride=*/false).isEmpty()) {
|
||||||
err() << "Failed to dispatch FIM request: " << session->lastError().message << "\n";
|
err() << "Failed to dispatch FIM request: " << session->lastError().message << "\n";
|
||||||
exitCode = 1;
|
exitCode = 1;
|
||||||
QCoreApplication::quit();
|
QCoreApplication::quit();
|
||||||
|
|||||||
@@ -31,6 +31,24 @@ private:
|
|||||||
QString m_mediaType;
|
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
|
class StoredAttachmentContent : public LLMQore::ContentBlock
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -134,17 +134,6 @@ LLMQore::RequestID Session::sendText(const QString &text)
|
|||||||
return send(std::move(blocks));
|
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(
|
LLMQore::RequestID Session::send(
|
||||||
std::vector<std::unique_ptr<LLMQore::ContentBlock>> userBlocks,
|
std::vector<std::unique_ptr<LLMQore::ContentBlock>> userBlocks,
|
||||||
std::optional<bool> toolsOverride)
|
std::optional<bool> toolsOverride)
|
||||||
@@ -290,6 +279,12 @@ Templates::ContextData Session::buildLegacyContext(
|
|||||||
if (m.role() == Message::Role::System)
|
if (m.role() == Message::Role::System)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (auto *cc = m.lastBlockOfType<CompletionContent>()) {
|
||||||
|
ctx.prefix = cc->prefix();
|
||||||
|
ctx.suffix = cc->suffix();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
QVector<ContentBlockEntry> blockEntries;
|
QVector<ContentBlockEntry> blockEntries;
|
||||||
|
|
||||||
for (const auto &blockPtr : m.blocks()) {
|
for (const auto &blockPtr : m.blocks()) {
|
||||||
|
|||||||
@@ -66,8 +66,6 @@ public:
|
|||||||
|
|
||||||
LLMQore::RequestID sendText(const QString &text);
|
LLMQore::RequestID sendText(const QString &text);
|
||||||
|
|
||||||
LLMQore::RequestID sendCompletion(Templates::ContextData ctx);
|
|
||||||
|
|
||||||
void cancel();
|
void cancel();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|||||||
Reference in New Issue
Block a user