#pragma once #include #include #include #include #include "chatstore.hpp" class QQmlEngine; class QJSEngine; namespace ZShell::llm { class LlmClient; // QML-facing facade. Persistence lives in ChatStore, network streaming in // LlmClient; this class only wires them together and exposes the // application-wide state. class Chat : public QObject { Q_OBJECT QML_ELEMENT QML_SINGLETON Q_PROPERTY(bool busy READ busy NOTIFY busyChanged) Q_PROPERTY(QString endpoint READ endpoint NOTIFY endpointChanged) Q_PROPERTY(QString model READ model NOTIFY modelChanged) Q_PROPERTY( QStringList availableModels READ availableModels NOTIFY availableModelsChanged) Q_PROPERTY(int contextSize READ contextSize NOTIFY contextSizeChanged) Q_PROPERTY( bool toolsEnabled READ toolsEnabled WRITE setToolsEnabled NOTIFY toolsEnabledChanged) Q_PROPERTY(QString lastError READ lastError NOTIFY lastErrorChanged) Q_PROPERTY(ZShell::llm::ChatStore* chats READ chats CONSTANT) Q_PROPERTY( QString streamingChatId READ streamingChatId NOTIFY streamingChatIdChanged) public: explicit Chat(QObject* parent = nullptr); [[nodiscard]] bool busy() const; [[nodiscard]] QString endpoint() const; [[nodiscard]] QString model() const; [[nodiscard]] QStringList availableModels() const; [[nodiscard]] int contextSize() const; [[nodiscard]] bool toolsEnabled() const; void setToolsEnabled(bool value); [[nodiscard]] QString lastError() const { return m_lastError; } [[nodiscard]] ChatStore* chats() const { return m_store; } [[nodiscard]] QString streamingChatId() const; Q_INVOKABLE void stop(); Q_INVOKABLE void dismissError(); Q_INVOKABLE void refreshModels(); Q_INVOKABLE void selectModel(const QString& id); static Chat* create(QQmlEngine*, QJSEngine*); Q_SIGNALS: void busyChanged(); void endpointChanged(); void modelChanged(); void availableModelsChanged(); void contextSizeChanged(); void toolsEnabledChanged(); void errorOccurred(const QString& message); void lastErrorChanged(); void streamingChatIdChanged(); private: ChatStore* m_store = nullptr; LlmClient* m_client = nullptr; QString m_lastError; static Chat* s_instance; }; } // namespace ZShell::llm