Skip to content

Commit 3165e1d

Browse files
authored
modellist: fix models.json cache location (#3052)
Signed-off-by: Jared Van Bortel <[email protected]>
1 parent 0d9b4f0 commit 3165e1d

File tree

2 files changed

+50
-27
lines changed

2 files changed

+50
-27
lines changed

gpt4all-chat/CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@ All notable changes to this project will be documented in this file.
44

55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
66

7+
## [Unreleased]
8+
9+
### Fixed
10+
- Fix models.json cache location ([#3052](https://github.com/nomic-ai/gpt4all/pull/3052))
11+
712
## [3.4.0] - 2024-10-08
813

914
### Added
@@ -147,6 +152,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
147152
- Fix several Vulkan resource management issues ([#2694](https://github.com/nomic-ai/gpt4all/pull/2694))
148153
- Fix crash/hang when some models stop generating, by showing special tokens ([#2701](https://github.com/nomic-ai/gpt4all/pull/2701))
149154

155+
[Unreleased]: https://github.com/nomic-ai/gpt4all/compare/v3.4.0...HEAD
150156
[3.4.0]: https://github.com/nomic-ai/gpt4all/compare/v3.3.0...v3.4.0
151157
[3.3.1]: https://github.com/nomic-ai/gpt4all/compare/v3.3.0...v3.3.1
152158
[3.3.0]: https://github.com/nomic-ai/gpt4all/compare/v3.2.1...v3.3.0

gpt4all-chat/src/modellist.cpp

Lines changed: 44 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include <QSettings>
2828
#include <QSslConfiguration>
2929
#include <QSslSocket>
30+
#include <QStandardPaths>
3031
#include <QStringList>
3132
#include <QTextStream>
3233
#include <QTimer>
@@ -36,13 +37,16 @@
3637
#include <algorithm>
3738
#include <cstddef>
3839
#include <iterator>
40+
#include <optional>
3941
#include <string>
4042
#include <utility>
4143

4244
using namespace Qt::Literals::StringLiterals;
4345

4446
//#define USE_LOCAL_MODELSJSON
4547

48+
#define MODELS_JSON_VERSION "3"
49+
4650
static const QStringList FILENAME_BLACKLIST { u"gpt4all-nomic-embed-text-v1.rmodel"_s };
4751

4852
QString ModelInfo::id() const
@@ -1331,15 +1335,32 @@ void ModelList::updateModelsFromDirectory()
13311335
}
13321336
}
13331337

1334-
#define MODELS_VERSION 3
1338+
static QString modelsJsonFilename()
1339+
{
1340+
return QStringLiteral("models" MODELS_JSON_VERSION ".json");
1341+
}
1342+
1343+
static std::optional<QFile> modelsJsonCacheFile()
1344+
{
1345+
constexpr auto loc = QStandardPaths::CacheLocation;
1346+
QString modelsJsonFname = modelsJsonFilename();
1347+
if (auto path = QStandardPaths::locate(loc, modelsJsonFname); !path.isEmpty())
1348+
return std::make_optional<QFile>(path);
1349+
if (auto path = QStandardPaths::writableLocation(loc); !path.isEmpty())
1350+
return std::make_optional<QFile>(path);
1351+
return std::nullopt;
1352+
}
13351353

13361354
void ModelList::updateModelsFromJson()
13371355
{
1356+
QString modelsJsonFname = modelsJsonFilename();
1357+
13381358
#if defined(USE_LOCAL_MODELSJSON)
1339-
QUrl jsonUrl("file://" + QDir::homePath() + u"/dev/large_language_models/gpt4all/gpt4all-chat/metadata/models%1.json"_s.arg(MODELS_VERSION));
1359+
QUrl jsonUrl(u"file://%1/dev/large_language_models/gpt4all/gpt4all-chat/metadata/%2"_s.arg(QDir::homePath(), modelsJsonFname));
13401360
#else
1341-
QUrl jsonUrl(u"http://gpt4all.io/models/models%1.json"_s.arg(MODELS_VERSION));
1361+
QUrl jsonUrl(u"http://gpt4all.io/models/%1"_s.arg(modelsJsonFname));
13421362
#endif
1363+
13431364
QNetworkRequest request(jsonUrl);
13441365
QSslConfiguration conf = request.sslConfiguration();
13451366
conf.setPeerVerifyMode(QSslSocket::VerifyNone);
@@ -1358,18 +1379,15 @@ void ModelList::updateModelsFromJson()
13581379
qWarning() << "WARNING: Could not download models.json synchronously";
13591380
updateModelsFromJsonAsync();
13601381

1361-
QSettings settings;
1362-
QFileInfo info(settings.fileName());
1363-
QString dirPath = info.canonicalPath();
1364-
const QString modelsConfig = dirPath + "/models.json";
1365-
QFile file(modelsConfig);
1366-
if (!file.open(QIODeviceBase::ReadOnly)) {
1367-
qWarning() << "ERROR: Couldn't read models config file: " << modelsConfig;
1368-
} else {
1369-
QByteArray jsonData = file.readAll();
1370-
file.close();
1382+
auto cacheFile = modelsJsonCacheFile();
1383+
if (!cacheFile) {
1384+
// no known location
1385+
} else if (cacheFile->open(QIODeviceBase::ReadOnly)) {
1386+
QByteArray jsonData = cacheFile->readAll();
1387+
cacheFile->close();
13711388
parseModelsJsonFile(jsonData, false);
1372-
}
1389+
} else if (cacheFile->exists())
1390+
qWarning() << "ERROR: Couldn't read models.json cache file: " << cacheFile->fileName();
13731391
}
13741392
delete jsonReply;
13751393
}
@@ -1378,12 +1396,14 @@ void ModelList::updateModelsFromJsonAsync()
13781396
{
13791397
m_asyncModelRequestOngoing = true;
13801398
emit asyncModelRequestOngoingChanged();
1399+
QString modelsJsonFname = modelsJsonFilename();
13811400

13821401
#if defined(USE_LOCAL_MODELSJSON)
1383-
QUrl jsonUrl("file://" + QDir::homePath() + u"/dev/large_language_models/gpt4all/gpt4all-chat/metadata/models%1.json"_s.arg(MODELS_VERSION));
1402+
QUrl jsonUrl(u"file://%1/dev/large_language_models/gpt4all/gpt4all-chat/metadata/%2"_s.arg(QDir::homePath(), modelsJsonFname));
13841403
#else
1385-
QUrl jsonUrl(u"http://gpt4all.io/models/models%1.json"_s.arg(MODELS_VERSION));
1404+
QUrl jsonUrl(u"http://gpt4all.io/models/%1"_s.arg(modelsJsonFname));
13861405
#endif
1406+
13871407
QNetworkRequest request(jsonUrl);
13881408
QSslConfiguration conf = request.sslConfiguration();
13891409
conf.setPeerVerifyMode(QSslSocket::VerifyNone);
@@ -1446,17 +1466,14 @@ void ModelList::parseModelsJsonFile(const QByteArray &jsonData, bool save)
14461466
}
14471467

14481468
if (save) {
1449-
QSettings settings;
1450-
QFileInfo info(settings.fileName());
1451-
QString dirPath = info.canonicalPath();
1452-
const QString modelsConfig = dirPath + "/models.json";
1453-
QFile file(modelsConfig);
1454-
if (!file.open(QIODeviceBase::WriteOnly)) {
1455-
qWarning() << "ERROR: Couldn't write models config file: " << modelsConfig;
1456-
} else {
1457-
file.write(jsonData);
1458-
file.close();
1459-
}
1469+
auto cacheFile = modelsJsonCacheFile();
1470+
if (!cacheFile) {
1471+
// no known location
1472+
} else if (QFileInfo(*cacheFile).dir().mkpath(u"."_s) && cacheFile->open(QIODeviceBase::WriteOnly)) {
1473+
cacheFile->write(jsonData);
1474+
cacheFile->close();
1475+
} else
1476+
qWarning() << "ERROR: Couldn't write models config file: " << cacheFile->fileName();
14601477
}
14611478

14621479
QJsonArray jsonArray = document.array();

0 commit comments

Comments
 (0)