2023-04-30 20:28:07 -04:00
|
|
|
#ifndef CHAT_H
|
|
|
|
#define CHAT_H
|
|
|
|
|
2023-05-01 09:10:05 -04:00
|
|
|
#include "chatllm.h"
|
2023-04-30 20:28:07 -04:00
|
|
|
#include "chatmodel.h"
|
2024-06-06 11:59:28 -04:00
|
|
|
#include "database.h" // IWYU pragma: keep
|
2024-06-04 14:47:11 -04:00
|
|
|
#include "localdocsmodel.h" // IWYU pragma: keep
|
|
|
|
#include "modellist.h"
|
|
|
|
|
|
|
|
#include <QList>
|
|
|
|
#include <QObject>
|
|
|
|
#include <QQmlEngine>
|
|
|
|
#include <QString>
|
|
|
|
#include <QtGlobal>
|
|
|
|
|
|
|
|
class QDataStream;
|
2023-04-30 20:28:07 -04:00
|
|
|
|
|
|
|
class Chat : public QObject
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
Q_PROPERTY(QString id READ id NOTIFY idChanged)
|
2023-05-01 20:27:07 -04:00
|
|
|
Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
|
2023-04-30 20:28:07 -04:00
|
|
|
Q_PROPERTY(ChatModel *chatModel READ chatModel NOTIFY chatModelChanged)
|
2023-05-01 09:10:05 -04:00
|
|
|
Q_PROPERTY(bool isModelLoaded READ isModelLoaded NOTIFY isModelLoadedChanged)
|
2024-05-15 14:07:03 -04:00
|
|
|
Q_PROPERTY(bool isCurrentlyLoading READ isCurrentlyLoading NOTIFY isCurrentlyLoadingChanged)
|
2024-02-07 09:37:59 -05:00
|
|
|
Q_PROPERTY(float modelLoadingPercentage READ modelLoadingPercentage NOTIFY modelLoadingPercentageChanged)
|
2023-05-01 09:10:05 -04:00
|
|
|
Q_PROPERTY(QString response READ response NOTIFY responseChanged)
|
2023-06-22 15:44:49 -04:00
|
|
|
Q_PROPERTY(ModelInfo modelInfo READ modelInfo WRITE setModelInfo NOTIFY modelInfoChanged)
|
2023-05-01 09:10:05 -04:00
|
|
|
Q_PROPERTY(bool responseInProgress READ responseInProgress NOTIFY responseInProgressChanged)
|
|
|
|
Q_PROPERTY(bool isRecalc READ isRecalc NOTIFY recalcChanged)
|
2023-05-11 16:46:25 -04:00
|
|
|
Q_PROPERTY(bool isServer READ isServer NOTIFY isServerChanged)
|
2023-10-29 18:34:42 -04:00
|
|
|
Q_PROPERTY(ResponseState responseState READ responseState NOTIFY responseStateChanged)
|
2023-05-23 14:51:14 -04:00
|
|
|
Q_PROPERTY(QList<QString> collectionList READ collectionList NOTIFY collectionListChanged)
|
2023-06-04 14:55:05 -04:00
|
|
|
Q_PROPERTY(QString modelLoadingError READ modelLoadingError NOTIFY modelLoadingErrorChanged)
|
2023-06-19 14:34:53 -04:00
|
|
|
Q_PROPERTY(QString tokenSpeed READ tokenSpeed NOTIFY tokenSpeedChanged);
|
2024-06-26 15:26:27 -04:00
|
|
|
Q_PROPERTY(QString deviceBackend READ deviceBackend NOTIFY loadedModelInfoChanged)
|
|
|
|
Q_PROPERTY(QString device READ device NOTIFY loadedModelInfoChanged)
|
|
|
|
Q_PROPERTY(QString fallbackReason READ fallbackReason NOTIFY loadedModelInfoChanged)
|
2023-10-24 12:13:32 -04:00
|
|
|
Q_PROPERTY(LocalDocsCollectionsModel *collectionModel READ collectionModel NOTIFY collectionModelChanged)
|
2024-05-15 14:07:03 -04:00
|
|
|
// 0=no, 1=waiting, 2=working
|
|
|
|
Q_PROPERTY(int trySwitchContextInProgress READ trySwitchContextInProgress NOTIFY trySwitchContextInProgressChanged)
|
2023-04-30 20:28:07 -04:00
|
|
|
QML_ELEMENT
|
|
|
|
QML_UNCREATABLE("Only creatable from c++!")
|
|
|
|
|
|
|
|
public:
|
2023-05-20 20:04:36 -04:00
|
|
|
enum ResponseState {
|
|
|
|
ResponseStopped,
|
|
|
|
LocalDocsRetrieval,
|
|
|
|
LocalDocsProcessing,
|
|
|
|
PromptProcessing,
|
|
|
|
ResponseGeneration
|
|
|
|
};
|
|
|
|
Q_ENUM(ResponseState)
|
|
|
|
|
2023-05-01 09:10:05 -04:00
|
|
|
explicit Chat(QObject *parent = nullptr);
|
2023-05-11 16:46:25 -04:00
|
|
|
explicit Chat(bool isServer, QObject *parent = nullptr);
|
2023-05-12 14:06:03 -04:00
|
|
|
virtual ~Chat();
|
2024-03-06 16:42:59 -05:00
|
|
|
void destroy() { m_llmodel->destroy(); }
|
2023-05-12 14:06:03 -04:00
|
|
|
void connectLLM();
|
2023-04-30 20:28:07 -04:00
|
|
|
|
|
|
|
QString id() const { return m_id; }
|
2023-05-01 20:27:07 -04:00
|
|
|
QString name() const { return m_userName.isEmpty() ? m_name : m_userName; }
|
|
|
|
void setName(const QString &name)
|
|
|
|
{
|
|
|
|
m_userName = name;
|
|
|
|
emit nameChanged();
|
|
|
|
}
|
2023-04-30 20:28:07 -04:00
|
|
|
ChatModel *chatModel() { return m_chatModel; }
|
|
|
|
|
2023-10-11 10:23:33 -04:00
|
|
|
bool isNewChat() const { return m_name == tr("New Chat") && !m_chatModel->count(); }
|
|
|
|
|
2023-05-01 09:10:05 -04:00
|
|
|
Q_INVOKABLE void reset();
|
2023-07-01 11:34:21 -04:00
|
|
|
Q_INVOKABLE void processSystemPrompt();
|
2024-05-15 14:07:03 -04:00
|
|
|
bool isModelLoaded() const { return m_modelLoadingPercentage == 1.0f; }
|
|
|
|
bool isCurrentlyLoading() const { return m_modelLoadingPercentage > 0.0f && m_modelLoadingPercentage < 1.0f; }
|
|
|
|
float modelLoadingPercentage() const { return m_modelLoadingPercentage; }
|
2023-07-01 11:34:21 -04:00
|
|
|
Q_INVOKABLE void prompt(const QString &prompt);
|
2023-05-01 09:10:05 -04:00
|
|
|
Q_INVOKABLE void regenerateResponse();
|
|
|
|
Q_INVOKABLE void stopGenerating();
|
2023-05-01 12:30:54 -04:00
|
|
|
Q_INVOKABLE void newPromptResponsePair(const QString &prompt);
|
2023-05-01 09:10:05 -04:00
|
|
|
|
2023-06-19 18:23:54 -04:00
|
|
|
QList<ResultInfo> databaseResults() const { return m_databaseResults; }
|
2023-06-01 14:13:12 -04:00
|
|
|
|
2023-05-01 09:10:05 -04:00
|
|
|
QString response() const;
|
|
|
|
bool responseInProgress() const { return m_responseInProgress; }
|
2023-10-29 18:34:42 -04:00
|
|
|
ResponseState responseState() const;
|
2023-06-22 15:44:49 -04:00
|
|
|
ModelInfo modelInfo() const;
|
|
|
|
void setModelInfo(const ModelInfo &modelInfo);
|
2023-05-01 09:10:05 -04:00
|
|
|
bool isRecalc() const;
|
2023-04-30 21:05:54 -04:00
|
|
|
|
2024-02-07 09:37:59 -05:00
|
|
|
Q_INVOKABLE void unloadModel();
|
|
|
|
Q_INVOKABLE void reloadModel();
|
|
|
|
Q_INVOKABLE void forceUnloadModel();
|
|
|
|
Q_INVOKABLE void forceReloadModel();
|
|
|
|
Q_INVOKABLE void trySwitchContextOfLoadedModel();
|
2023-05-13 19:05:35 -04:00
|
|
|
void unloadAndDeleteLater();
|
2024-03-06 12:59:34 -05:00
|
|
|
void markForDeletion();
|
2023-05-04 15:31:41 -04:00
|
|
|
|
2024-06-24 18:49:23 -04:00
|
|
|
QDateTime creationDate() const { return QDateTime::fromSecsSinceEpoch(m_creationDate); }
|
2023-05-08 05:52:57 -04:00
|
|
|
bool serialize(QDataStream &stream, int version) const;
|
|
|
|
bool deserialize(QDataStream &stream, int version);
|
2023-05-11 16:46:25 -04:00
|
|
|
bool isServer() const { return m_isServer; }
|
|
|
|
|
2023-05-23 14:51:14 -04:00
|
|
|
QList<QString> collectionList() const;
|
2023-10-24 12:13:32 -04:00
|
|
|
LocalDocsCollectionsModel *collectionModel() const { return m_collectionModel; }
|
2023-05-23 14:51:14 -04:00
|
|
|
|
|
|
|
Q_INVOKABLE bool hasCollection(const QString &collection) const;
|
|
|
|
Q_INVOKABLE void addCollection(const QString &collection);
|
|
|
|
Q_INVOKABLE void removeCollection(const QString &collection);
|
2023-06-01 17:23:27 -04:00
|
|
|
void resetResponseState();
|
2023-05-23 14:51:14 -04:00
|
|
|
|
2023-06-04 14:55:05 -04:00
|
|
|
QString modelLoadingError() const { return m_modelLoadingError; }
|
|
|
|
|
2023-06-19 14:34:53 -04:00
|
|
|
QString tokenSpeed() const { return m_tokenSpeed; }
|
2024-06-26 15:26:27 -04:00
|
|
|
QString deviceBackend() const;
|
|
|
|
QString device() const;
|
|
|
|
// not loaded -> QString(), no fallback -> QString("")
|
|
|
|
QString fallbackReason() const;
|
2023-06-19 14:34:53 -04:00
|
|
|
|
2024-05-15 14:07:03 -04:00
|
|
|
int trySwitchContextInProgress() const { return m_trySwitchContextInProgress; }
|
|
|
|
|
2023-05-11 16:46:25 -04:00
|
|
|
public Q_SLOTS:
|
|
|
|
void serverNewPromptResponsePair(const QString &prompt);
|
2023-05-01 20:27:07 -04:00
|
|
|
|
2023-04-30 20:28:07 -04:00
|
|
|
Q_SIGNALS:
|
2023-06-19 19:51:28 -04:00
|
|
|
void idChanged(const QString &id);
|
2023-04-30 20:28:07 -04:00
|
|
|
void nameChanged();
|
|
|
|
void chatModelChanged();
|
2023-05-01 09:10:05 -04:00
|
|
|
void isModelLoadedChanged();
|
2024-05-15 14:07:03 -04:00
|
|
|
void isCurrentlyLoadingChanged();
|
2024-02-07 09:37:59 -05:00
|
|
|
void modelLoadingPercentageChanged();
|
2024-03-06 17:14:54 -05:00
|
|
|
void modelLoadingWarning(const QString &warning);
|
2023-05-01 09:10:05 -04:00
|
|
|
void responseChanged();
|
|
|
|
void responseInProgressChanged();
|
2023-05-20 20:04:36 -04:00
|
|
|
void responseStateChanged();
|
2023-07-01 11:34:21 -04:00
|
|
|
void promptRequested(const QList<QString> &collectionList, const QString &prompt);
|
2023-05-01 09:10:05 -04:00
|
|
|
void regenerateResponseRequested();
|
|
|
|
void resetResponseRequested();
|
|
|
|
void resetContextRequested();
|
2023-07-01 11:34:21 -04:00
|
|
|
void processSystemPromptRequested();
|
2023-06-22 15:44:49 -04:00
|
|
|
void modelChangeRequested(const ModelInfo &modelInfo);
|
|
|
|
void modelInfoChanged();
|
2023-05-01 09:10:05 -04:00
|
|
|
void recalcChanged();
|
2023-05-04 15:31:41 -04:00
|
|
|
void loadDefaultModelRequested();
|
2023-06-22 15:44:49 -04:00
|
|
|
void loadModelRequested(const ModelInfo &modelInfo);
|
2023-05-02 11:19:17 -04:00
|
|
|
void generateNameRequested();
|
2023-06-04 14:55:05 -04:00
|
|
|
void modelLoadingErrorChanged();
|
2023-05-11 16:46:25 -04:00
|
|
|
void isServerChanged();
|
2023-06-19 19:51:28 -04:00
|
|
|
void collectionListChanged(const QList<QString> &collectionList);
|
2023-06-19 14:34:53 -04:00
|
|
|
void tokenSpeedChanged();
|
2023-09-14 08:25:37 -04:00
|
|
|
void deviceChanged();
|
2023-09-29 14:25:37 -04:00
|
|
|
void fallbackReasonChanged();
|
2023-10-24 12:13:32 -04:00
|
|
|
void collectionModelChanged();
|
2024-05-15 14:07:03 -04:00
|
|
|
void trySwitchContextInProgressChanged();
|
2024-06-26 15:26:27 -04:00
|
|
|
void loadedModelInfoChanged();
|
2023-05-01 09:10:05 -04:00
|
|
|
|
|
|
|
private Q_SLOTS:
|
2023-06-20 16:14:30 -04:00
|
|
|
void handleResponseChanged(const QString &response);
|
2024-02-07 09:37:59 -05:00
|
|
|
void handleModelLoadingPercentageChanged(float);
|
2023-05-20 20:04:36 -04:00
|
|
|
void promptProcessing();
|
2024-04-25 13:16:52 -04:00
|
|
|
void responseStopped(qint64 promptResponseMs);
|
2023-06-20 16:14:30 -04:00
|
|
|
void generatedNameChanged(const QString &name);
|
2023-05-02 20:31:17 -04:00
|
|
|
void handleRecalculating();
|
2023-06-04 14:55:05 -04:00
|
|
|
void handleModelLoadingError(const QString &error);
|
2023-06-19 14:34:53 -04:00
|
|
|
void handleTokenSpeedChanged(const QString &tokenSpeed);
|
2023-06-19 18:23:54 -04:00
|
|
|
void handleDatabaseResultsChanged(const QList<ResultInfo> &results);
|
2023-06-22 15:44:49 -04:00
|
|
|
void handleModelInfoChanged(const ModelInfo &modelInfo);
|
2024-05-15 14:07:03 -04:00
|
|
|
void handleTrySwitchContextOfLoadedModelCompleted(int value);
|
2023-04-30 20:28:07 -04:00
|
|
|
|
|
|
|
private:
|
|
|
|
QString m_id;
|
|
|
|
QString m_name;
|
2023-06-20 16:14:30 -04:00
|
|
|
QString m_generatedName;
|
2023-05-01 20:27:07 -04:00
|
|
|
QString m_userName;
|
2023-06-22 15:44:49 -04:00
|
|
|
ModelInfo m_modelInfo;
|
2023-06-04 14:55:05 -04:00
|
|
|
QString m_modelLoadingError;
|
2023-06-19 14:34:53 -04:00
|
|
|
QString m_tokenSpeed;
|
2023-09-14 08:25:37 -04:00
|
|
|
QString m_device;
|
2023-09-29 14:25:37 -04:00
|
|
|
QString m_fallbackReason;
|
2023-06-20 16:14:30 -04:00
|
|
|
QString m_response;
|
2023-05-23 14:51:14 -04:00
|
|
|
QList<QString> m_collections;
|
2023-04-30 20:28:07 -04:00
|
|
|
ChatModel *m_chatModel;
|
2023-12-09 12:55:46 -05:00
|
|
|
bool m_responseInProgress = false;
|
2023-05-20 20:04:36 -04:00
|
|
|
ResponseState m_responseState;
|
2023-05-04 15:31:41 -04:00
|
|
|
qint64 m_creationDate;
|
|
|
|
ChatLLM *m_llmodel;
|
2023-06-19 18:23:54 -04:00
|
|
|
QList<ResultInfo> m_databaseResults;
|
2023-12-09 12:55:46 -05:00
|
|
|
bool m_isServer = false;
|
|
|
|
bool m_shouldDeleteLater = false;
|
2024-02-07 09:37:59 -05:00
|
|
|
float m_modelLoadingPercentage = 0.0f;
|
2023-10-24 12:13:32 -04:00
|
|
|
LocalDocsCollectionsModel *m_collectionModel;
|
2024-04-25 13:16:52 -04:00
|
|
|
bool m_firstResponse = true;
|
2024-05-15 14:07:03 -04:00
|
|
|
int m_trySwitchContextInProgress = 0;
|
|
|
|
bool m_isCurrentlyLoading = false;
|
2023-04-30 20:28:07 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
#endif // CHAT_H
|