#pragma once #include #include #include #include namespace ZShell::llm { class ChatGeneration : public QObject { Q_OBJECT QML_ELEMENT QML_UNCREATABLE("Chat generations are managed by ChatMessage") Q_PROPERTY(QString content READ content WRITE setContent NOTIFY contentChanged) Q_PROPERTY(QString reasoning READ reasoning NOTIFY reasoningChanged) Q_PROPERTY(qint64 reasoningElapsedMs READ reasoningElapsedMs NOTIFY elapsedMsChanged) Q_PROPERTY(qint64 contentElapsedMs READ contentElapsedMs NOTIFY elapsedMsChanged) Q_PROPERTY(bool streaming READ streaming NOTIFY streamingChanged) Q_PROPERTY(bool reasoningActive READ reasoningActive NOTIFY reasoningActiveChanged) Q_PROPERTY(qint64 timestamp READ timestamp CONSTANT) public: explicit ChatGeneration(qint64 timestamp, QObject* parent = nullptr); [[nodiscard]] QString content() const { return m_content; } [[nodiscard]] QString reasoning() const { return m_reasoning; } [[nodiscard]] bool reasoningActive() const { return m_reasoningActive; } [[nodiscard]] qint64 reasoningElapsedMs() const; [[nodiscard]] qint64 contentElapsedMs() const; [[nodiscard]] bool streaming() const { return m_streaming; } [[nodiscard]] qint64 timestamp() const { return m_timestamp; } void setContent(const QString& value); void setReasoning(const QString& value); void appendContent(const QString& piece); void appendReasoning(const QString& piece); void setElapsedMs(qint64 reasoningMs, qint64 contentMs); void setStreaming(bool value); Q_SIGNALS: void contentChanged(); void reasoningChanged(); void reasoningActiveChanged(); void elapsedMsChanged(); void streamingChanged(); private: void updateReasoningActive(); [[nodiscard]] bool reasoningInFlight() const { return m_reasoningStartedAt > 0 && m_reasoningEndedAt <= 0; } [[nodiscard]] bool contentInFlight() const { return m_contentStartedAt > 0 && m_contentEndedAt <= 0; } QTimer m_timer; QString m_content; QString m_reasoning; bool m_reasoningActive = false; bool m_streaming = false; qint64 m_timestamp; qint64 m_reasoningStartedAt = 0; qint64 m_reasoningEndedAt = 0; qint64 m_contentStartedAt = 0; qint64 m_contentEndedAt = 0; }; } // namespace ZShell::llm