116 lines
3.5 KiB
C++
116 lines
3.5 KiB
C++
#pragma once
|
|
|
|
#include "messagemodel.hpp"
|
|
#include "message.hpp"
|
|
|
|
#include <QDateTime>
|
|
#include <QObject>
|
|
#include <QString>
|
|
#include <QtQml>
|
|
|
|
namespace ZShell::llm {
|
|
|
|
class LlmClient;
|
|
|
|
class ChatSession : public QObject {
|
|
Q_OBJECT
|
|
QML_ELEMENT
|
|
QML_UNCREATABLE("Chat sessions are managed by Chat.chats")
|
|
|
|
Q_PROPERTY(QString id READ id CONSTANT)
|
|
Q_PROPERTY(QString title READ title WRITE setTitle NOTIFY titleChanged)
|
|
Q_PROPERTY(QString icon READ icon NOTIFY iconChanged)
|
|
Q_PROPERTY(QDateTime createdAt READ createdAt CONSTANT)
|
|
Q_PROPERTY(QDateTime updatedAt READ updatedAt NOTIFY updatedAtChanged)
|
|
Q_PROPERTY(bool pinned READ pinned NOTIFY pinnedChanged)
|
|
Q_PROPERTY(bool loaded READ isLoaded NOTIFY loaded)
|
|
Q_PROPERTY(int messageCount READ messageCount NOTIFY messageCountChanged)
|
|
Q_PROPERTY(
|
|
ZShell::llm::ChatMessageModel* messagesModel READ messagesModel CONSTANT)
|
|
|
|
public:
|
|
explicit ChatSession(const QString& id, QObject* parent = nullptr);
|
|
|
|
[[nodiscard]] QString id() const { return m_id; }
|
|
[[nodiscard]] QString title() const { return m_title; }
|
|
[[nodiscard]] QString icon() const { return m_icon; }
|
|
[[nodiscard]] QDateTime createdAt() const {
|
|
return QDateTime::fromMSecsSinceEpoch(m_createdAt);
|
|
}
|
|
[[nodiscard]] QDateTime updatedAt() const {
|
|
return QDateTime::fromMSecsSinceEpoch(m_updatedAt);
|
|
}
|
|
[[nodiscard]] qint64 createdAtMs() const { return m_createdAt; }
|
|
[[nodiscard]] qint64 updatedAtMs() const { return m_updatedAt; }
|
|
[[nodiscard]] bool pinned() const { return m_pinned; }
|
|
[[nodiscard]] int messageCount() const { return m_messageCount; }
|
|
// The messages model; the first access starts the (async) load
|
|
// from the store.
|
|
[[nodiscard]] ChatMessageModel* messagesModel();
|
|
void ensureLoaded();
|
|
// True once the async load from the store has finished.
|
|
[[nodiscard]] bool isLoaded() const { return m_loaded; }
|
|
// The model without triggering a load (ChatStore use during the
|
|
// load itself).
|
|
[[nodiscard]] ChatMessageModel* model() const { return m_model; }
|
|
void markLoaded();
|
|
[[nodiscard]] bool takeClearPending();
|
|
|
|
[[nodiscard]] LlmClient* client() const;
|
|
[[nodiscard]] int lastTokenCount() const { return m_lastTokenCount; }
|
|
void setLastTokenCount(int value);
|
|
|
|
void setTitle(const QString& value);
|
|
void setIcon(const QString& value);
|
|
void setUpdatedAt(qint64 value);
|
|
void setPinned(bool value);
|
|
|
|
void setMeta(
|
|
const QString& title,
|
|
qint64 createdAt,
|
|
qint64 updatedAt,
|
|
int messageCount);
|
|
|
|
// Replaces the model's rows with `messages` (most recent first).
|
|
void adoptMessages(QList<ChatMessage*> messages);
|
|
void persist();
|
|
void removeMessage(ChatMessage* message);
|
|
void clearMessages();
|
|
|
|
Q_INVOKABLE void sendMessage(const QString& text);
|
|
Q_INVOKABLE void retry(ZShell::llm::ChatMessage* target);
|
|
Q_INVOKABLE void continueFrom(ZShell::llm::ChatMessage* message);
|
|
Q_INVOKABLE void clear();
|
|
|
|
Q_SIGNALS:
|
|
void titleChanged();
|
|
void iconChanged();
|
|
void updatedAtChanged();
|
|
void pinnedChanged();
|
|
void messageCountChanged();
|
|
// The messages finished loading from the store.
|
|
void loaded();
|
|
|
|
private:
|
|
void onModelRowsChanged();
|
|
ChatMessage* appendNewest(
|
|
ChatMessage::Role role, const QString& content, qint64 timestamp);
|
|
void startGeneration(ChatMessage* target);
|
|
void setCount(int value);
|
|
|
|
QString m_id;
|
|
QString m_title;
|
|
QString m_icon;
|
|
qint64 m_createdAt = 0;
|
|
qint64 m_updatedAt = 0;
|
|
bool m_pinned = false;
|
|
int m_messageCount = 0;
|
|
ChatMessageModel* m_model = nullptr;
|
|
bool m_loadRequested = false;
|
|
bool m_loaded = false;
|
|
bool m_clearPending = false;
|
|
int m_lastTokenCount = 0;
|
|
};
|
|
|
|
} // namespace ZShell::llm
|