151 lines
4.0 KiB
C++
151 lines
4.0 KiB
C++
#include "session.hpp"
|
|
|
|
#include <QDebug>
|
|
#include <QFile>
|
|
#include <QJsonArray>
|
|
#include <QJsonDocument>
|
|
#include <QJsonObject>
|
|
|
|
namespace ZShell {
|
|
|
|
ChatSession::ChatSession(const QString& id, QObject* parent)
|
|
: QObject(parent), m_id(id) {
|
|
}
|
|
|
|
void ChatSession::setTitle(const QString& value) {
|
|
if (m_title == value)
|
|
return;
|
|
m_title = value;
|
|
Q_EMIT titleChanged();
|
|
}
|
|
|
|
void ChatSession::setUpdatedAt(qint64 value) {
|
|
if (m_updatedAt == value)
|
|
return;
|
|
m_updatedAt = value;
|
|
Q_EMIT updatedAtChanged();
|
|
}
|
|
|
|
void ChatSession::setCount(int value) {
|
|
if (m_messageCount == value)
|
|
return;
|
|
m_messageCount = value;
|
|
Q_EMIT messageCountChanged();
|
|
}
|
|
|
|
void ChatSession::setMeta(
|
|
const QString& title,
|
|
qint64 createdAt,
|
|
qint64 updatedAt,
|
|
int messageCount) {
|
|
m_title = title;
|
|
m_createdAt = createdAt;
|
|
m_updatedAt = updatedAt;
|
|
m_messageCount = messageCount;
|
|
}
|
|
|
|
void ChatSession::ensureLoaded() {
|
|
if (m_loaded || m_path.isEmpty())
|
|
return;
|
|
m_loaded = true;
|
|
loadMessages();
|
|
}
|
|
|
|
void ChatSession::loadMessages() {
|
|
QFile file(m_path);
|
|
if (file.open(QIODevice::ReadOnly)) {
|
|
const QJsonDocument doc = QJsonDocument::fromJson(file.readAll());
|
|
file.close();
|
|
if (doc.isObject()) {
|
|
const QJsonObject obj = doc.object();
|
|
m_title = obj["title"].toString(m_title);
|
|
m_createdAt = obj["createdAt"].toVariant().toLongLong() || m_createdAt;
|
|
m_updatedAt = obj["updatedAt"].toVariant().toLongLong() || m_updatedAt;
|
|
for (const QJsonValue& value : obj["messages"].toArray()) {
|
|
const QJsonObject msg = value.toObject();
|
|
const QString content = msg["content"].toString();
|
|
const QString reasoning = msg["reasoning"].toString();
|
|
if (content.isEmpty() && reasoning.isEmpty())
|
|
continue;
|
|
auto* message = new ChatMessage(
|
|
msg["role"].toString() == "user" ? ChatMessage::Role::User
|
|
: ChatMessage::Role::Assistant,
|
|
content,
|
|
msg["timestamp"].toVariant().toLongLong(),
|
|
this);
|
|
message->setReasoning(reasoning);
|
|
message->setElapsedMs(
|
|
msg["reasoningElapsedMs"].toVariant().toLongLong(),
|
|
msg["contentElapsedMs"].toVariant().toLongLong());
|
|
m_messages.append(message);
|
|
}
|
|
}
|
|
} else {
|
|
qWarning() << "ChatSession: failed to load" << m_path << ":"
|
|
<< file.errorString();
|
|
}
|
|
setCount(int(m_messages.size()));
|
|
Q_EMIT titleChanged();
|
|
Q_EMIT messagesChanged();
|
|
}
|
|
|
|
ChatMessage* ChatSession::appendMessage(
|
|
ChatMessage::Role role, const QString& content, qint64 timestamp) {
|
|
ensureLoaded();
|
|
auto* message = new ChatMessage(role, content, timestamp, this);
|
|
m_messages.append(message);
|
|
setCount(int(m_messages.size()));
|
|
Q_EMIT messagesChanged();
|
|
return message;
|
|
}
|
|
|
|
void ChatSession::removeMessage(ChatMessage* message) {
|
|
if (!message || !m_messages.removeOne(message))
|
|
return;
|
|
delete message;
|
|
setCount(int(m_messages.size()));
|
|
Q_EMIT messagesChanged();
|
|
}
|
|
|
|
void ChatSession::clearMessages() {
|
|
ensureLoaded();
|
|
if (m_messages.isEmpty())
|
|
return;
|
|
qDeleteAll(m_messages);
|
|
m_messages.clear();
|
|
setCount(0);
|
|
Q_EMIT messagesChanged();
|
|
}
|
|
|
|
QJsonObject ChatSession::document() {
|
|
ensureLoaded();
|
|
QJsonArray arr;
|
|
for (const auto* message : m_messages) {
|
|
QJsonObject messageObj;
|
|
messageObj[QStringLiteral("role")] =
|
|
message->role() == ChatMessage::Role::User
|
|
? QStringLiteral("user")
|
|
: QStringLiteral("assistant");
|
|
messageObj[QStringLiteral("content")] = message->content();
|
|
if (!message->reasoning().isEmpty())
|
|
messageObj[QStringLiteral("reasoning")] = message->reasoning();
|
|
const qint64 reasoningMs = message->reasoningElapsedMs();
|
|
if (reasoningMs > 0)
|
|
messageObj[QStringLiteral("reasoningElapsedMs")] = reasoningMs;
|
|
const qint64 contentMs = message->contentElapsedMs();
|
|
if (contentMs > 0)
|
|
messageObj[QStringLiteral("contentElapsedMs")] = contentMs;
|
|
messageObj[QStringLiteral("timestamp")] = message->timestamp();
|
|
arr.append(messageObj);
|
|
}
|
|
QJsonObject doc;
|
|
doc[QStringLiteral("id")] = m_id;
|
|
doc[QStringLiteral("title")] = m_title;
|
|
doc[QStringLiteral("createdAt")] = m_createdAt;
|
|
doc[QStringLiteral("updatedAt")] = m_updatedAt;
|
|
doc[QStringLiteral("messages")] = arr;
|
|
return doc;
|
|
}
|
|
|
|
} // namespace ZShell
|