2023-04-08 23:28:39 -04:00
|
|
|
#include "llm.h"
|
2023-04-18 21:10:06 -04:00
|
|
|
#include "download.h"
|
2023-04-26 22:05:56 -04:00
|
|
|
#include "network.h"
|
2023-04-08 23:28:39 -04:00
|
|
|
|
|
|
|
#include <QCoreApplication>
|
|
|
|
#include <QDir>
|
|
|
|
#include <QFile>
|
2023-04-10 23:34:34 -04:00
|
|
|
#include <QProcess>
|
2023-04-08 23:28:39 -04:00
|
|
|
#include <QResource>
|
2023-04-27 13:52:24 -04:00
|
|
|
#include <QSettings>
|
2023-04-10 16:33:14 -04:00
|
|
|
#include <fstream>
|
2023-04-08 23:28:39 -04:00
|
|
|
|
|
|
|
class MyLLM: public LLM { };
|
|
|
|
Q_GLOBAL_STATIC(MyLLM, llmInstance)
|
|
|
|
LLM *LLM::globalInstance()
|
|
|
|
{
|
|
|
|
return llmInstance();
|
|
|
|
}
|
|
|
|
|
2023-05-01 09:10:05 -04:00
|
|
|
LLM::LLM()
|
2023-04-08 23:28:39 -04:00
|
|
|
: QObject{nullptr}
|
2023-05-01 17:13:20 -04:00
|
|
|
, m_chatListModel(new ChatListModel(this))
|
2023-04-18 11:42:16 -04:00
|
|
|
{
|
2023-05-01 20:27:07 -04:00
|
|
|
// Should be in the same thread
|
2023-05-01 09:10:05 -04:00
|
|
|
connect(Download::globalInstance(), &Download::modelListChanged,
|
2023-05-01 20:27:07 -04:00
|
|
|
this, &LLM::modelListChanged, Qt::DirectConnection);
|
2023-05-01 17:13:20 -04:00
|
|
|
connect(m_chatListModel, &ChatListModel::connectChat,
|
2023-05-01 20:27:07 -04:00
|
|
|
this, &LLM::connectChat, Qt::DirectConnection);
|
2023-05-01 17:13:20 -04:00
|
|
|
connect(m_chatListModel, &ChatListModel::disconnectChat,
|
2023-05-01 20:27:07 -04:00
|
|
|
this, &LLM::disconnectChat, Qt::DirectConnection);
|
|
|
|
|
|
|
|
if (!m_chatListModel->count())
|
|
|
|
m_chatListModel->addChat();
|
2023-04-18 11:42:16 -04:00
|
|
|
}
|
|
|
|
|
2023-05-01 09:10:05 -04:00
|
|
|
QList<QString> LLM::modelList() const
|
2023-04-18 11:42:16 -04:00
|
|
|
{
|
2023-05-01 17:13:20 -04:00
|
|
|
Q_ASSERT(m_chatListModel->currentChat());
|
|
|
|
const Chat *currentChat = m_chatListModel->currentChat();
|
2023-04-23 11:28:17 -04:00
|
|
|
// Build a model list from exepath and from the localpath
|
|
|
|
QList<QString> list;
|
|
|
|
|
|
|
|
QString exePath = QCoreApplication::applicationDirPath() + QDir::separator();
|
|
|
|
QString localPath = Download::globalInstance()->downloadLocalModelsPath();
|
|
|
|
|
|
|
|
{
|
|
|
|
QDir dir(exePath);
|
|
|
|
dir.setNameFilters(QStringList() << "ggml-*.bin");
|
|
|
|
QStringList fileNames = dir.entryList();
|
|
|
|
for (QString f : fileNames) {
|
|
|
|
QString filePath = exePath + f;
|
|
|
|
QFileInfo info(filePath);
|
|
|
|
QString name = info.completeBaseName().remove(0, 5);
|
|
|
|
if (info.exists()) {
|
2023-05-01 17:13:20 -04:00
|
|
|
if (name == currentChat->modelName())
|
2023-04-23 11:28:17 -04:00
|
|
|
list.prepend(name);
|
|
|
|
else
|
|
|
|
list.append(name);
|
|
|
|
}
|
|
|
|
}
|
2023-04-18 11:42:16 -04:00
|
|
|
}
|
|
|
|
|
2023-04-23 11:28:17 -04:00
|
|
|
if (localPath != exePath) {
|
|
|
|
QDir dir(localPath);
|
|
|
|
dir.setNameFilters(QStringList() << "ggml-*.bin");
|
|
|
|
QStringList fileNames = dir.entryList();
|
|
|
|
for (QString f : fileNames) {
|
|
|
|
QString filePath = localPath + f;
|
|
|
|
QFileInfo info(filePath);
|
|
|
|
QString name = info.completeBaseName().remove(0, 5);
|
|
|
|
if (info.exists() && !list.contains(name)) { // don't allow duplicates
|
2023-05-01 17:13:20 -04:00
|
|
|
if (name == currentChat->modelName())
|
2023-04-23 11:28:17 -04:00
|
|
|
list.prepend(name);
|
|
|
|
else
|
|
|
|
list.append(name);
|
|
|
|
}
|
2023-04-18 11:42:16 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-04-23 11:28:17 -04:00
|
|
|
if (list.isEmpty()) {
|
|
|
|
if (exePath != localPath) {
|
|
|
|
qWarning() << "ERROR: Could not find any applicable models in"
|
|
|
|
<< exePath << "nor" << localPath;
|
|
|
|
} else {
|
|
|
|
qWarning() << "ERROR: Could not find any applicable models in"
|
|
|
|
<< exePath;
|
|
|
|
}
|
|
|
|
return QList<QString>();
|
|
|
|
}
|
|
|
|
|
2023-04-18 11:42:16 -04:00
|
|
|
return list;
|
|
|
|
}
|
|
|
|
|
2023-04-10 23:34:34 -04:00
|
|
|
bool LLM::checkForUpdates() const
|
|
|
|
{
|
2023-04-27 07:41:23 -04:00
|
|
|
Network::globalInstance()->sendCheckForUpdates();
|
|
|
|
|
2023-04-10 23:34:34 -04:00
|
|
|
#if defined(Q_OS_LINUX)
|
2023-04-11 12:16:04 -04:00
|
|
|
QString tool("maintenancetool");
|
2023-04-10 23:34:34 -04:00
|
|
|
#elif defined(Q_OS_WINDOWS)
|
2023-04-11 12:16:04 -04:00
|
|
|
QString tool("maintenancetool.exe");
|
2023-04-10 23:34:34 -04:00
|
|
|
#elif defined(Q_OS_DARWIN)
|
2023-04-12 17:57:02 -04:00
|
|
|
QString tool("../../../maintenancetool.app/Contents/MacOS/maintenancetool");
|
2023-04-10 23:34:34 -04:00
|
|
|
#endif
|
|
|
|
|
|
|
|
QString fileName = QCoreApplication::applicationDirPath()
|
2023-04-29 21:02:54 -04:00
|
|
|
+ "/../" + tool;
|
2023-04-10 23:34:34 -04:00
|
|
|
if (!QFileInfo::exists(fileName)) {
|
|
|
|
qDebug() << "Couldn't find tool at" << fileName << "so cannot check for updates!";
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return QProcess::startDetached(fileName);
|
|
|
|
}
|
2023-05-01 12:41:03 -04:00
|
|
|
|
|
|
|
bool LLM::isRecalc() const
|
|
|
|
{
|
2023-05-01 17:13:20 -04:00
|
|
|
Q_ASSERT(m_chatListModel->currentChat());
|
|
|
|
return m_chatListModel->currentChat()->isRecalc();
|
2023-05-01 14:24:16 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
void LLM::connectChat(Chat *chat)
|
|
|
|
{
|
2023-05-01 20:27:07 -04:00
|
|
|
// 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);
|
2023-05-01 12:41:03 -04:00
|
|
|
}
|
|
|
|
|
2023-05-01 14:24:16 -04:00
|
|
|
void LLM::disconnectChat(Chat *chat)
|
|
|
|
{
|
2023-05-02 07:48:40 -04:00
|
|
|
chat->disconnect(this);
|
2023-05-01 14:24:16 -04:00
|
|
|
}
|