mirror of
https://github.com/nomic-ai/gpt4all.git
synced 2025-06-23 14:07:58 +00:00
Hot swapping of conversations. Destroys context for now.
This commit is contained in:
parent
a48226613c
commit
412cad99f2
13
chat.cpp
13
chat.cpp
@ -21,6 +21,8 @@ Chat::Chat(QObject *parent)
|
|||||||
|
|
||||||
connect(this, &Chat::promptRequested, m_llmodel, &ChatLLM::prompt, Qt::QueuedConnection);
|
connect(this, &Chat::promptRequested, m_llmodel, &ChatLLM::prompt, Qt::QueuedConnection);
|
||||||
connect(this, &Chat::modelNameChangeRequested, m_llmodel, &ChatLLM::modelNameChangeRequested, Qt::QueuedConnection);
|
connect(this, &Chat::modelNameChangeRequested, m_llmodel, &ChatLLM::modelNameChangeRequested, Qt::QueuedConnection);
|
||||||
|
connect(this, &Chat::unloadRequested, m_llmodel, &ChatLLM::unload, Qt::QueuedConnection);
|
||||||
|
connect(this, &Chat::reloadRequested, m_llmodel, &ChatLLM::reload, Qt::QueuedConnection);
|
||||||
|
|
||||||
// The following are blocking operations and will block the gui thread, therefore must be fast
|
// The following are blocking operations and will block the gui thread, therefore must be fast
|
||||||
// to respond to
|
// to respond to
|
||||||
@ -115,3 +117,14 @@ bool Chat::isRecalc() const
|
|||||||
{
|
{
|
||||||
return m_llmodel->isRecalc();
|
return m_llmodel->isRecalc();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Chat::unload()
|
||||||
|
{
|
||||||
|
stopGenerating();
|
||||||
|
emit unloadRequested();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Chat::reload()
|
||||||
|
{
|
||||||
|
emit reloadRequested();
|
||||||
|
}
|
||||||
|
15
chat.h
15
chat.h
@ -11,7 +11,7 @@ class Chat : public QObject
|
|||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_PROPERTY(QString id READ id NOTIFY idChanged)
|
Q_PROPERTY(QString id READ id NOTIFY idChanged)
|
||||||
Q_PROPERTY(QString name READ name NOTIFY nameChanged)
|
Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
|
||||||
Q_PROPERTY(ChatModel *chatModel READ chatModel NOTIFY chatModelChanged)
|
Q_PROPERTY(ChatModel *chatModel READ chatModel NOTIFY chatModelChanged)
|
||||||
Q_PROPERTY(bool isModelLoaded READ isModelLoaded NOTIFY isModelLoadedChanged)
|
Q_PROPERTY(bool isModelLoaded READ isModelLoaded NOTIFY isModelLoadedChanged)
|
||||||
Q_PROPERTY(QString response READ response NOTIFY responseChanged)
|
Q_PROPERTY(QString response READ response NOTIFY responseChanged)
|
||||||
@ -26,7 +26,12 @@ public:
|
|||||||
explicit Chat(QObject *parent = nullptr);
|
explicit Chat(QObject *parent = nullptr);
|
||||||
|
|
||||||
QString id() const { return m_id; }
|
QString id() const { return m_id; }
|
||||||
QString name() const { return m_name; }
|
QString name() const { return m_userName.isEmpty() ? m_name : m_userName; }
|
||||||
|
void setName(const QString &name)
|
||||||
|
{
|
||||||
|
m_userName = name;
|
||||||
|
emit nameChanged();
|
||||||
|
}
|
||||||
ChatModel *chatModel() { return m_chatModel; }
|
ChatModel *chatModel() { return m_chatModel; }
|
||||||
|
|
||||||
Q_INVOKABLE void reset();
|
Q_INVOKABLE void reset();
|
||||||
@ -46,6 +51,9 @@ public:
|
|||||||
void setModelName(const QString &modelName);
|
void setModelName(const QString &modelName);
|
||||||
bool isRecalc() const;
|
bool isRecalc() const;
|
||||||
|
|
||||||
|
void unload();
|
||||||
|
void reload();
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void idChanged();
|
void idChanged();
|
||||||
void nameChanged();
|
void nameChanged();
|
||||||
@ -63,6 +71,8 @@ Q_SIGNALS:
|
|||||||
void threadCountChanged();
|
void threadCountChanged();
|
||||||
void setThreadCountRequested(int32_t threadCount);
|
void setThreadCountRequested(int32_t threadCount);
|
||||||
void recalcChanged();
|
void recalcChanged();
|
||||||
|
void unloadRequested();
|
||||||
|
void reloadRequested();
|
||||||
|
|
||||||
private Q_SLOTS:
|
private Q_SLOTS:
|
||||||
void responseStarted();
|
void responseStarted();
|
||||||
@ -72,6 +82,7 @@ private:
|
|||||||
ChatLLM *m_llmodel;
|
ChatLLM *m_llmodel;
|
||||||
QString m_id;
|
QString m_id;
|
||||||
QString m_name;
|
QString m_name;
|
||||||
|
QString m_userName;
|
||||||
ChatModel *m_chatModel;
|
ChatModel *m_chatModel;
|
||||||
bool m_responseInProgress;
|
bool m_responseInProgress;
|
||||||
int32_t m_desiredThreadCount;
|
int32_t m_desiredThreadCount;
|
||||||
|
@ -14,8 +14,6 @@ public:
|
|||||||
explicit ChatListModel(QObject *parent = nullptr)
|
explicit ChatListModel(QObject *parent = nullptr)
|
||||||
: QAbstractListModel(parent)
|
: QAbstractListModel(parent)
|
||||||
{
|
{
|
||||||
if (m_chats.isEmpty())
|
|
||||||
addChat();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
enum Roles {
|
enum Roles {
|
||||||
@ -56,8 +54,8 @@ public:
|
|||||||
Q_INVOKABLE Chat* addChat()
|
Q_INVOKABLE Chat* addChat()
|
||||||
{
|
{
|
||||||
Chat *newChat = new Chat(this);
|
Chat *newChat = new Chat(this);
|
||||||
beginInsertRows(QModelIndex(), m_chats.size(), m_chats.size());
|
beginInsertRows(QModelIndex(), 0, 0);
|
||||||
m_chats.append(newChat);
|
m_chats.prepend(newChat);
|
||||||
endInsertRows();
|
endInsertRows();
|
||||||
emit countChanged();
|
emit countChanged();
|
||||||
setCurrentChat(newChat);
|
setCurrentChat(newChat);
|
||||||
@ -97,12 +95,15 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (m_currentChat) {
|
if (m_currentChat) {
|
||||||
Q_ASSERT(m_currentChat);
|
if (m_currentChat->isModelLoaded())
|
||||||
|
m_currentChat->unload();
|
||||||
emit disconnect(m_currentChat);
|
emit disconnect(m_currentChat);
|
||||||
}
|
}
|
||||||
|
|
||||||
emit connectChat(chat);
|
emit connectChat(chat);
|
||||||
m_currentChat = chat;
|
m_currentChat = chat;
|
||||||
|
if (!m_currentChat->isModelLoaded())
|
||||||
|
m_currentChat->reload();
|
||||||
emit currentChatChanged();
|
emit currentChatChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -117,8 +118,8 @@ public:
|
|||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void countChanged();
|
void countChanged();
|
||||||
void connectChat(Chat *);
|
void connectChat(Chat*);
|
||||||
void disconnectChat(Chat *);
|
void disconnectChat(Chat*);
|
||||||
void currentChatChanged();
|
void currentChatChanged();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
12
chatllm.cpp
12
chatllm.cpp
@ -288,3 +288,15 @@ bool ChatLLM::prompt(const QString &prompt, const QString &prompt_template, int3
|
|||||||
emit responseStopped();
|
emit responseStopped();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ChatLLM::unload()
|
||||||
|
{
|
||||||
|
delete m_llmodel;
|
||||||
|
m_llmodel = nullptr;
|
||||||
|
emit isModelLoadedChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChatLLM::reload()
|
||||||
|
{
|
||||||
|
loadModel();
|
||||||
|
}
|
||||||
|
@ -39,6 +39,8 @@ public Q_SLOTS:
|
|||||||
float temp, int32_t n_batch, float repeat_penalty, int32_t repeat_penalty_tokens);
|
float temp, int32_t n_batch, float repeat_penalty, int32_t repeat_penalty_tokens);
|
||||||
bool loadModel();
|
bool loadModel();
|
||||||
void modelNameChangeRequested(const QString &modelName);
|
void modelNameChangeRequested(const QString &modelName);
|
||||||
|
void unload();
|
||||||
|
void reload();
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void isModelLoadedChanged();
|
void isModelLoadedChanged();
|
||||||
|
20
llm.cpp
20
llm.cpp
@ -21,12 +21,16 @@ LLM::LLM()
|
|||||||
: QObject{nullptr}
|
: QObject{nullptr}
|
||||||
, m_chatListModel(new ChatListModel(this))
|
, m_chatListModel(new ChatListModel(this))
|
||||||
{
|
{
|
||||||
|
// Should be in the same thread
|
||||||
connect(Download::globalInstance(), &Download::modelListChanged,
|
connect(Download::globalInstance(), &Download::modelListChanged,
|
||||||
this, &LLM::modelListChanged, Qt::QueuedConnection);
|
this, &LLM::modelListChanged, Qt::DirectConnection);
|
||||||
connect(m_chatListModel, &ChatListModel::connectChat,
|
connect(m_chatListModel, &ChatListModel::connectChat,
|
||||||
this, &LLM::connectChat, Qt::QueuedConnection);
|
this, &LLM::connectChat, Qt::DirectConnection);
|
||||||
connect(m_chatListModel, &ChatListModel::disconnectChat,
|
connect(m_chatListModel, &ChatListModel::disconnectChat,
|
||||||
this, &LLM::disconnectChat, Qt::QueuedConnection);
|
this, &LLM::disconnectChat, Qt::DirectConnection);
|
||||||
|
|
||||||
|
if (!m_chatListModel->count())
|
||||||
|
m_chatListModel->addChat();
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<QString> LLM::modelList() const
|
QList<QString> LLM::modelList() const
|
||||||
@ -117,12 +121,10 @@ bool LLM::isRecalc() const
|
|||||||
|
|
||||||
void LLM::connectChat(Chat *chat)
|
void LLM::connectChat(Chat *chat)
|
||||||
{
|
{
|
||||||
connect(chat, &Chat::modelNameChanged,
|
// Should be in the same thread
|
||||||
this, &LLM::modelListChanged, Qt::QueuedConnection);
|
connect(chat, &Chat::modelNameChanged, this, &LLM::modelListChanged, Qt::DirectConnection);
|
||||||
connect(chat, &Chat::recalcChanged,
|
connect(chat, &Chat::recalcChanged, this, &LLM::recalcChanged, Qt::DirectConnection);
|
||||||
this, &LLM::recalcChanged, Qt::QueuedConnection);
|
connect(chat, &Chat::responseChanged, this, &LLM::responseChanged, Qt::DirectConnection);
|
||||||
connect(chat, &Chat::responseChanged,
|
|
||||||
this, &LLM::responseChanged, Qt::QueuedConnection);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void LLM::disconnectChat(Chat *chat)
|
void LLM::disconnectChat(Chat *chat)
|
||||||
|
4
llm.h
4
llm.h
@ -29,8 +29,8 @@ Q_SIGNALS:
|
|||||||
void chatListModelChanged();
|
void chatListModelChanged();
|
||||||
|
|
||||||
private Q_SLOTS:
|
private Q_SLOTS:
|
||||||
void connectChat(Chat *chat);
|
void connectChat(Chat*);
|
||||||
void disconnectChat(Chat *chat);
|
void disconnectChat(Chat*);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ChatListModel *m_chatListModel;
|
ChatListModel *m_chatListModel;
|
||||||
|
@ -58,33 +58,94 @@ Drawer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ListView {
|
ScrollView {
|
||||||
id: conversationList
|
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
|
anchors.rightMargin: -10
|
||||||
anchors.topMargin: 10
|
anchors.topMargin: 10
|
||||||
anchors.top: newChat.bottom
|
anchors.top: newChat.bottom
|
||||||
anchors.bottom: checkForUpdatesButton.top
|
anchors.bottom: checkForUpdatesButton.top
|
||||||
|
anchors.bottomMargin: 10
|
||||||
|
ScrollBar.vertical.policy: ScrollBar.AlwaysOn
|
||||||
|
|
||||||
|
ListView {
|
||||||
|
id: conversationList
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.rightMargin: 10
|
||||||
|
|
||||||
model: LLM.chatListModel
|
model: LLM.chatListModel
|
||||||
|
|
||||||
delegate: Label {
|
delegate: Rectangle {
|
||||||
id: chatLabel
|
id: chatRectangle
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
|
height: chatName.height
|
||||||
|
opacity: 0.9
|
||||||
|
property bool isCurrent: LLM.chatListModel.currentChat === LLM.chatListModel.get(index)
|
||||||
|
color: index % 2 === 0 ? theme.backgroundLight : theme.backgroundLighter
|
||||||
|
border.width: isCurrent
|
||||||
|
border.color: theme.backgroundLightest
|
||||||
|
TextArea {
|
||||||
|
id: chatName
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: editButton.left
|
||||||
color: theme.textColor
|
color: theme.textColor
|
||||||
padding: 15
|
padding: 15
|
||||||
|
focus: false
|
||||||
|
readOnly: true
|
||||||
|
wrapMode: Text.NoWrap
|
||||||
|
hoverEnabled: false // Disable hover events on the TextArea
|
||||||
|
selectByMouse: false // Disable text selection in the TextArea
|
||||||
font.pixelSize: theme.fontSizeLarger
|
font.pixelSize: theme.fontSizeLarger
|
||||||
text: name
|
text: name
|
||||||
background: Rectangle {
|
|
||||||
color: index % 2 === 0 ? theme.backgroundLight : theme.backgroundLighter
|
|
||||||
}
|
|
||||||
horizontalAlignment: TextInput.AlignLeft
|
horizontalAlignment: TextInput.AlignLeft
|
||||||
|
background: Rectangle {
|
||||||
|
color: "transparent"
|
||||||
|
}
|
||||||
|
Keys.onReturnPressed: (event)=> {
|
||||||
|
changeName();
|
||||||
|
}
|
||||||
|
onEditingFinished: {
|
||||||
|
changeName();
|
||||||
|
}
|
||||||
|
function changeName() {
|
||||||
|
LLM.chatListModel.get(index).name = chatName.text
|
||||||
|
chatName.focus = false
|
||||||
|
chatName.readOnly = true
|
||||||
|
}
|
||||||
|
TapHandler {
|
||||||
|
onTapped: {
|
||||||
|
if (isCurrent)
|
||||||
|
return;
|
||||||
|
LLM.chatListModel.currentChat = LLM.chatListModel.get(index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Button {
|
||||||
|
id: editButton
|
||||||
|
anchors.verticalCenter: chatName.verticalCenter
|
||||||
|
anchors.right: chatRectangle.right
|
||||||
|
anchors.rightMargin: 10
|
||||||
|
width: 30
|
||||||
|
height: 30
|
||||||
|
visible: isCurrent
|
||||||
|
background: Image {
|
||||||
|
width: 30
|
||||||
|
height: 30
|
||||||
|
source: "qrc:/gpt4all/icons/edit.svg"
|
||||||
|
}
|
||||||
|
onClicked: {
|
||||||
|
chatName.focus = true
|
||||||
|
chatName.readOnly = false
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Accessible.role: Accessible.List
|
Accessible.role: Accessible.List
|
||||||
Accessible.name: qsTr("List of chats")
|
Accessible.name: qsTr("List of chats")
|
||||||
Accessible.description: qsTr("List of chats in the drawer dialog")
|
Accessible.description: qsTr("List of chats in the drawer dialog")
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*Label {
|
/*Label {
|
||||||
id: discordLink
|
id: discordLink
|
||||||
|
Loading…
Reference in New Issue
Block a user