mirror of
https://github.com/nomic-ai/gpt4all
synced 2024-11-18 03:25:46 +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::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
|
||||
// to respond to
|
||||
@ -115,3 +117,14 @@ bool Chat::isRecalc() const
|
||||
{
|
||||
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_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(bool isModelLoaded READ isModelLoaded NOTIFY isModelLoadedChanged)
|
||||
Q_PROPERTY(QString response READ response NOTIFY responseChanged)
|
||||
@ -26,7 +26,12 @@ public:
|
||||
explicit Chat(QObject *parent = nullptr);
|
||||
|
||||
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; }
|
||||
|
||||
Q_INVOKABLE void reset();
|
||||
@ -46,6 +51,9 @@ public:
|
||||
void setModelName(const QString &modelName);
|
||||
bool isRecalc() const;
|
||||
|
||||
void unload();
|
||||
void reload();
|
||||
|
||||
Q_SIGNALS:
|
||||
void idChanged();
|
||||
void nameChanged();
|
||||
@ -63,6 +71,8 @@ Q_SIGNALS:
|
||||
void threadCountChanged();
|
||||
void setThreadCountRequested(int32_t threadCount);
|
||||
void recalcChanged();
|
||||
void unloadRequested();
|
||||
void reloadRequested();
|
||||
|
||||
private Q_SLOTS:
|
||||
void responseStarted();
|
||||
@ -72,6 +82,7 @@ private:
|
||||
ChatLLM *m_llmodel;
|
||||
QString m_id;
|
||||
QString m_name;
|
||||
QString m_userName;
|
||||
ChatModel *m_chatModel;
|
||||
bool m_responseInProgress;
|
||||
int32_t m_desiredThreadCount;
|
||||
|
@ -14,8 +14,6 @@ public:
|
||||
explicit ChatListModel(QObject *parent = nullptr)
|
||||
: QAbstractListModel(parent)
|
||||
{
|
||||
if (m_chats.isEmpty())
|
||||
addChat();
|
||||
}
|
||||
|
||||
enum Roles {
|
||||
@ -56,8 +54,8 @@ public:
|
||||
Q_INVOKABLE Chat* addChat()
|
||||
{
|
||||
Chat *newChat = new Chat(this);
|
||||
beginInsertRows(QModelIndex(), m_chats.size(), m_chats.size());
|
||||
m_chats.append(newChat);
|
||||
beginInsertRows(QModelIndex(), 0, 0);
|
||||
m_chats.prepend(newChat);
|
||||
endInsertRows();
|
||||
emit countChanged();
|
||||
setCurrentChat(newChat);
|
||||
@ -97,12 +95,15 @@ public:
|
||||
}
|
||||
|
||||
if (m_currentChat) {
|
||||
Q_ASSERT(m_currentChat);
|
||||
if (m_currentChat->isModelLoaded())
|
||||
m_currentChat->unload();
|
||||
emit disconnect(m_currentChat);
|
||||
}
|
||||
|
||||
emit connectChat(chat);
|
||||
m_currentChat = chat;
|
||||
if (!m_currentChat->isModelLoaded())
|
||||
m_currentChat->reload();
|
||||
emit currentChatChanged();
|
||||
}
|
||||
|
||||
|
12
chatllm.cpp
12
chatllm.cpp
@ -288,3 +288,15 @@ bool ChatLLM::prompt(const QString &prompt, const QString &prompt_template, int3
|
||||
emit responseStopped();
|
||||
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);
|
||||
bool loadModel();
|
||||
void modelNameChangeRequested(const QString &modelName);
|
||||
void unload();
|
||||
void reload();
|
||||
|
||||
Q_SIGNALS:
|
||||
void isModelLoadedChanged();
|
||||
|
20
llm.cpp
20
llm.cpp
@ -21,12 +21,16 @@ LLM::LLM()
|
||||
: QObject{nullptr}
|
||||
, m_chatListModel(new ChatListModel(this))
|
||||
{
|
||||
// Should be in the same thread
|
||||
connect(Download::globalInstance(), &Download::modelListChanged,
|
||||
this, &LLM::modelListChanged, Qt::QueuedConnection);
|
||||
this, &LLM::modelListChanged, Qt::DirectConnection);
|
||||
connect(m_chatListModel, &ChatListModel::connectChat,
|
||||
this, &LLM::connectChat, Qt::QueuedConnection);
|
||||
this, &LLM::connectChat, Qt::DirectConnection);
|
||||
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
|
||||
@ -117,12 +121,10 @@ bool LLM::isRecalc() const
|
||||
|
||||
void LLM::connectChat(Chat *chat)
|
||||
{
|
||||
connect(chat, &Chat::modelNameChanged,
|
||||
this, &LLM::modelListChanged, Qt::QueuedConnection);
|
||||
connect(chat, &Chat::recalcChanged,
|
||||
this, &LLM::recalcChanged, Qt::QueuedConnection);
|
||||
connect(chat, &Chat::responseChanged,
|
||||
this, &LLM::responseChanged, Qt::QueuedConnection);
|
||||
// Should be in the same thread
|
||||
connect(chat, &Chat::modelNameChanged, this, &LLM::modelListChanged, Qt::DirectConnection);
|
||||
connect(chat, &Chat::recalcChanged, this, &LLM::recalcChanged, Qt::DirectConnection);
|
||||
connect(chat, &Chat::responseChanged, this, &LLM::responseChanged, Qt::DirectConnection);
|
||||
}
|
||||
|
||||
void LLM::disconnectChat(Chat *chat)
|
||||
|
4
llm.h
4
llm.h
@ -29,8 +29,8 @@ Q_SIGNALS:
|
||||
void chatListModelChanged();
|
||||
|
||||
private Q_SLOTS:
|
||||
void connectChat(Chat *chat);
|
||||
void disconnectChat(Chat *chat);
|
||||
void connectChat(Chat*);
|
||||
void disconnectChat(Chat*);
|
||||
|
||||
private:
|
||||
ChatListModel *m_chatListModel;
|
||||
|
@ -58,33 +58,94 @@ Drawer {
|
||||
}
|
||||
}
|
||||
|
||||
ListView {
|
||||
id: conversationList
|
||||
ScrollView {
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: -10
|
||||
anchors.topMargin: 10
|
||||
anchors.top: newChat.bottom
|
||||
anchors.bottom: checkForUpdatesButton.top
|
||||
anchors.bottomMargin: 10
|
||||
ScrollBar.vertical.policy: ScrollBar.AlwaysOn
|
||||
|
||||
ListView {
|
||||
id: conversationList
|
||||
anchors.fill: parent
|
||||
anchors.rightMargin: 10
|
||||
|
||||
model: LLM.chatListModel
|
||||
|
||||
delegate: Label {
|
||||
id: chatLabel
|
||||
delegate: Rectangle {
|
||||
id: chatRectangle
|
||||
anchors.left: parent.left
|
||||
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
|
||||
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
|
||||
text: name
|
||||
background: Rectangle {
|
||||
color: index % 2 === 0 ? theme.backgroundLight : theme.backgroundLighter
|
||||
}
|
||||
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.name: qsTr("List of chats")
|
||||
Accessible.description: qsTr("List of chats in the drawer dialog")
|
||||
}
|
||||
}
|
||||
|
||||
/*Label {
|
||||
id: discordLink
|
||||
|
Loading…
Reference in New Issue
Block a user