#pragma once #include "segment.hpp" #include #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(qint64 toolsElapsedMs READ toolsElapsedMs NOTIFY elapsedMsChanged) Q_PROPERTY(bool streaming READ streaming NOTIFY streamingChanged) Q_PROPERTY( bool reasoningActive READ reasoningActive NOTIFY reasoningActiveChanged) Q_PROPERTY(bool hasRunningTool READ hasRunningTool NOTIFY toolStateChanged) Q_PROPERTY(qint64 timestamp READ timestamp CONSTANT) Q_PROPERTY( QList segments READ segments NOTIFY segmentsChanged) Q_PROPERTY(int toolCallCount READ toolCallCount NOTIFY segmentsChanged) public: explicit ChatGeneration(qint64 timestamp, QObject* parent = nullptr); [[nodiscard]] QString content() const; [[nodiscard]] QString reasoning() const; [[nodiscard]] bool reasoningActive() const; [[nodiscard]] qint64 reasoningElapsedMs() const; [[nodiscard]] qint64 contentElapsedMs() const; [[nodiscard]] qint64 toolsElapsedMs() const; [[nodiscard]] bool streaming() const { return m_streaming; } [[nodiscard]] qint64 timestamp() const { return m_timestamp; } [[nodiscard]] QList segments() const { return m_segments; } [[nodiscard]] int toolCallCount() const; [[nodiscard]] bool hasRunningTool() const; void setContent(const QString& value); void appendContent(const QString& piece); void appendReasoning(const QString& piece); void setStreaming(bool value); [[nodiscard]] LlmSegment* openContentSegment(); [[nodiscard]] LlmSegment* openReasoningSegment(); [[nodiscard]] LlmSegment* beginToolCall( const QString& name, const QString& toolCallId); void addSegment(LlmSegment* segment); void closeOpenSegments(); Q_SIGNALS: void contentChanged(); void reasoningChanged(); void reasoningActiveChanged(); void elapsedMsChanged(); void streamingChanged(); void toolStateChanged(); void segmentsChanged(); private: void updateReasoningActive(); QTimer m_timer; QList m_segments; bool m_reasoningActive = false; bool m_streaming = false; qint64 m_timestamp; }; } // namespace ZShell::llm