#pragma once #include "attachment.hpp" #include "generation.hpp" #include #include #include #include namespace ZShell::llm { class ChatSession; class ChatMessage : public QObject { Q_OBJECT QML_ELEMENT QML_UNCREATABLE("Chat messages are created by ChatMessageModel") Q_PROPERTY(Role role READ role CONSTANT) Q_PROPERTY(qint64 timestamp READ timestamp CONSTANT) Q_PROPERTY(QString content READ content NOTIFY contentChanged) Q_PROPERTY( int generationCount READ generationCount NOTIFY generationsChanged) Q_PROPERTY( QList generations READ generations NOTIFY generationsChanged) Q_PROPERTY( ZShell::llm::ChatGeneration* activeGeneration READ activeGeneration NOTIFY activeGenerationChanged) Q_PROPERTY( int activeGenerationIndex READ activeGenerationIndex NOTIFY activeGenerationChanged) Q_PROPERTY( QList attachments READ attachments NOTIFY attachmentsChanged) public: enum class Role : int { User = 0, Assistant }; Q_ENUM(Role) ChatMessage( ChatSession* session, Role role, qint64 timestamp, QObject* parent = nullptr); [[nodiscard]] ChatSession* session() const { return m_session; } [[nodiscard]] Role role() const { return m_role; } [[nodiscard]] qint64 timestamp() const { return m_timestamp; } [[nodiscard]] QString content() const; [[nodiscard]] int generationCount() const { return static_cast(m_generations.size()); } [[nodiscard]] QList generations() const { return m_generations; } [[nodiscard]] ChatGeneration* activeGeneration() const { return generation(m_active); } [[nodiscard]] int activeGenerationIndex() const { return m_active; } [[nodiscard]] QList attachments() const { return m_attachments; } [[nodiscard]] ChatGeneration* generation(int index) const { if (index < 0 || index >= m_generations.size()) return nullptr; return m_generations.at(index); } Q_INVOKABLE void setActiveGeneration(int index); void setAttachments(QList attachments); Q_INVOKABLE void edit(const QString& newContent); Q_INVOKABLE void retry(); Q_INVOKABLE void generate(); ChatGeneration* addGeneration(qint64 timestamp); ChatGeneration* appendGeneration(qint64 timestamp); void removeGeneration(ChatGeneration* generation); void setContent(const QString& value); Q_SIGNALS: void contentChanged(); void generationsChanged(); void activeGenerationChanged(); void attachmentsChanged(); private: void setActiveInternal(int index); ChatSession* m_session; Role m_role; qint64 m_timestamp; QString m_content; QList m_generations; QList m_attachments; int m_active = -1; }; } // namespace ZShell::llm