refactor: Decoupling chat architecture (#367)

* refactor: Migrate tests to Qt Creator plugin framework and update llmqore transports

* refactor: Move conversation history into IDE-free session library

* refactor: Extract turn context assembly behind injected ports

* build: Add RunQodeAssistTests target for the plugin test suite

* refactor: Route the chat through a Session and ChatBackend seam
This commit is contained in:
Petr Mironychev
2026-07-19 22:45:04 +02:00
committed by GitHub
parent bd809edb8a
commit af85efb554
83 changed files with 5421 additions and 4620 deletions

View File

@@ -12,28 +12,30 @@
#include <QJsonObject>
#include <QtConcurrent>
#include "session/HistoryProjection.hpp"
#include "session/HistorySerializer.hpp"
namespace QodeAssist::Tools {
namespace {
QString roleName(int role)
QString roleName(Session::RowKind kind)
{
switch (role) {
case 0:
switch (kind) {
case Session::RowKind::System:
return QStringLiteral("system");
case 1:
case Session::RowKind::User:
return QStringLiteral("user");
case 2:
case Session::RowKind::Assistant:
return QStringLiteral("assistant");
case 3:
case Session::RowKind::Tool:
return QStringLiteral("tool");
case 4:
case Session::RowKind::FileEdit:
return QStringLiteral("file_edit");
case 5:
case Session::RowKind::Thinking:
return QStringLiteral("thinking");
default:
return QStringLiteral("unknown");
}
return QStringLiteral("unknown");
}
QJsonObject readJsonObject(const QString &path)
@@ -144,8 +146,15 @@ QFuture<LLMQore::ToolResult> ReadOriginalHistoryTool::executeAsync(const QJsonOb
"history.");
}
const QJsonObject root = readJsonObject(rootPath);
const QJsonArray messages = root.value("messages").toArray();
const auto history = Session::HistorySerializer::fromJson(readJsonObject(rootPath));
if (!history) {
return LLMQore::ToolResult::text(
QString("Cannot read the pre-compression history at %1: unsupported chat file "
"format.")
.arg(rootPath));
}
const QList<Session::MessageRow> messages = Session::projectToRows(*history);
const QString query = input.value("query").toString().trimmed();
const QString roleFilter = input.value("role").toString().trimmed().toLower();
@@ -155,9 +164,9 @@ QFuture<LLMQore::ToolResult> ReadOriginalHistoryTool::executeAsync(const QJsonOb
QStringList matched;
int matchCount = 0;
for (int i = 0; i < messages.size(); ++i) {
const QJsonObject msg = messages.at(i).toObject();
const QString role = roleName(msg.value("role").toInt());
const QString content = msg.value("content").toString();
const Session::MessageRow &msg = messages.at(i);
const QString role = roleName(msg.kind);
const QString content = msg.content;
if (!roleFilter.isEmpty() && role != roleFilter)
continue;