chat: implement display of model loading warnings (#2034)

Signed-off-by: Jared Van Bortel <jared@nomic.ai>
This commit is contained in:
Jared Van Bortel 2024-03-06 17:14:54 -05:00 committed by GitHub
parent a0bd96f75d
commit 44717682a7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 33 additions and 10 deletions

View File

@ -46,6 +46,7 @@ void Chat::connectLLM()
connect(m_llmodel, &ChatLLM::promptProcessing, this, &Chat::promptProcessing, Qt::QueuedConnection); connect(m_llmodel, &ChatLLM::promptProcessing, this, &Chat::promptProcessing, Qt::QueuedConnection);
connect(m_llmodel, &ChatLLM::responseStopped, this, &Chat::responseStopped, Qt::QueuedConnection); connect(m_llmodel, &ChatLLM::responseStopped, this, &Chat::responseStopped, Qt::QueuedConnection);
connect(m_llmodel, &ChatLLM::modelLoadingError, this, &Chat::handleModelLoadingError, Qt::QueuedConnection); connect(m_llmodel, &ChatLLM::modelLoadingError, this, &Chat::handleModelLoadingError, Qt::QueuedConnection);
connect(m_llmodel, &ChatLLM::modelLoadingWarning, this, &Chat::modelLoadingWarning, Qt::QueuedConnection);
connect(m_llmodel, &ChatLLM::recalcChanged, this, &Chat::handleRecalculating, Qt::QueuedConnection); connect(m_llmodel, &ChatLLM::recalcChanged, this, &Chat::handleRecalculating, Qt::QueuedConnection);
connect(m_llmodel, &ChatLLM::generatedNameChanged, this, &Chat::generatedNameChanged, Qt::QueuedConnection); connect(m_llmodel, &ChatLLM::generatedNameChanged, this, &Chat::generatedNameChanged, Qt::QueuedConnection);
connect(m_llmodel, &ChatLLM::reportSpeed, this, &Chat::handleTokenSpeedChanged, Qt::QueuedConnection); connect(m_llmodel, &ChatLLM::reportSpeed, this, &Chat::handleTokenSpeedChanged, Qt::QueuedConnection);
@ -333,7 +334,8 @@ void Chat::handleRecalculating()
void Chat::handleModelLoadingError(const QString &error) void Chat::handleModelLoadingError(const QString &error)
{ {
qWarning() << "ERROR:" << qPrintable(error) << "id" << id(); auto stream = qWarning().noquote() << "ERROR:" << error << "id";
stream.quote() << id();
m_modelLoadingError = error; m_modelLoadingError = error;
emit modelLoadingErrorChanged(); emit modelLoadingErrorChanged();
} }

View File

@ -113,6 +113,7 @@ Q_SIGNALS:
void chatModelChanged(); void chatModelChanged();
void isModelLoadedChanged(); void isModelLoadedChanged();
void modelLoadingPercentageChanged(); void modelLoadingPercentageChanged();
void modelLoadingWarning(const QString &warning);
void responseChanged(); void responseChanged();
void responseInProgressChanged(); void responseInProgressChanged();
void responseStateChanged(); void responseStateChanged();

View File

@ -142,7 +142,7 @@ void ChatGPT::prompt(const std::string &prompt,
QJsonDocument doc(root); QJsonDocument doc(root);
#if defined(DEBUG) #if defined(DEBUG)
qDebug() << "ChatGPT::prompt begin network request" << qPrintable(doc.toJson()); qDebug().noquote() << "ChatGPT::prompt begin network request" << doc.toJson();
#endif #endif
m_responseCallback = responseCallback; m_responseCallback = responseCallback;
@ -231,7 +231,7 @@ void ChatGPTWorker::handleReadyRead()
int code = response.toInt(&ok); int code = response.toInt(&ok);
if (!ok || code != 200) { if (!ok || code != 200) {
m_chat->callResponse(-1, QString("\nERROR: 2 ChatGPT responded with error code \"%1-%2\" %3\n") m_chat->callResponse(-1, QString("\nERROR: 2 ChatGPT responded with error code \"%1-%2\" %3\n")
.arg(code).arg(reply->errorString()).arg(qPrintable(reply->readAll())).toStdString()); .arg(code).arg(reply->errorString()).arg(reply->readAll()).toStdString());
emit finished(); emit finished();
return; return;
} }
@ -246,7 +246,7 @@ void ChatGPTWorker::handleReadyRead()
if (jsonData == "[DONE]") if (jsonData == "[DONE]")
continue; continue;
#if defined(DEBUG) #if defined(DEBUG)
qDebug() << "line" << qPrintable(jsonData); qDebug().noquote() << "line" << jsonData;
#endif #endif
QJsonParseError err; QJsonParseError err;
const QJsonDocument document = QJsonDocument::fromJson(jsonData.toUtf8(), &err); const QJsonDocument document = QJsonDocument::fromJson(jsonData.toUtf8(), &err);

View File

@ -308,7 +308,14 @@ bool ChatLLM::loadModel(const ModelInfo &modelInfo)
if (m_llModelInfo.model) { if (m_llModelInfo.model) {
if (m_llModelInfo.model->isModelBlacklisted(filePath.toStdString())) { if (m_llModelInfo.model->isModelBlacklisted(filePath.toStdString())) {
// TODO(cebtenzzre): warn that this model is out-of-date static QSet<QString> warned;
auto fname = modelInfo.filename();
if (!warned.contains(fname)) {
emit modelLoadingWarning(QString(
"%1 is known to be broken. Please get a replacement via the download dialog."
).arg(fname));
warned.insert(fname); // don't warn again until restart
}
} }
m_llModelInfo.model->setProgressCallback([this](float progress) -> bool { m_llModelInfo.model->setProgressCallback([this](float progress) -> bool {
@ -996,7 +1003,7 @@ void ChatLLM::restoreState()
m_llModelInfo.model->restoreState(static_cast<const uint8_t*>(reinterpret_cast<void*>(m_state.data()))); m_llModelInfo.model->restoreState(static_cast<const uint8_t*>(reinterpret_cast<void*>(m_state.data())));
m_processedSystemPrompt = true; m_processedSystemPrompt = true;
} else { } else {
qWarning() << "restoring state from text because" << m_llModelInfo.model->stateSize() << "!=" << m_state.size() << "\n"; qWarning() << "restoring state from text because" << m_llModelInfo.model->stateSize() << "!=" << m_state.size();
m_restoreStateFromText = true; m_restoreStateFromText = true;
} }

View File

@ -120,6 +120,7 @@ Q_SIGNALS:
void recalcChanged(); void recalcChanged();
void modelLoadingPercentageChanged(float); void modelLoadingPercentageChanged(float);
void modelLoadingError(const QString &error); void modelLoadingError(const QString &error);
void modelLoadingWarning(const QString &warning);
void responseChanged(const QString &response); void responseChanged(const QString &response);
void promptProcessing(); void promptProcessing();
void responseStopped(); void responseStopped();

View File

@ -93,6 +93,9 @@ Window {
if (currentChat.modelLoadingError !== "") if (currentChat.modelLoadingError !== "")
modelLoadingErrorPopup.open() modelLoadingErrorPopup.open()
} }
function onModelLoadingWarning(warning) {
modelLoadingWarningPopup.open_(warning)
}
} }
property bool hasShownModelDownload: false property bool hasShownModelDownload: false
@ -213,6 +216,15 @@ Window {
+ "<li>Check out our <a href=\"https://discord.gg/4M2QFmTt2k\">discord channel</a> for help") + "<li>Check out our <a href=\"https://discord.gg/4M2QFmTt2k\">discord channel</a> for help")
} }
PopupDialog {
id: modelLoadingWarningPopup
property string message
anchors.centerIn: parent
shouldTimeOut: false
text: qsTr("<h3>Warning</h3><p>%1</p>").arg(message)
function open_(msg) { message = msg; open(); }
}
Rectangle { Rectangle {
id: accentRibbon id: accentRibbon
anchors.left: parent.left anchors.left: parent.left

View File

@ -1311,7 +1311,7 @@ void ModelList::parseModelsJsonFile(const QByteArray &jsonData, bool save)
if (!file.open(QIODeviceBase::WriteOnly)) { if (!file.open(QIODeviceBase::WriteOnly)) {
qWarning() << "ERROR: Couldn't write models config file: " << modelsConfig; qWarning() << "ERROR: Couldn't write models config file: " << modelsConfig;
} else { } else {
file.write(jsonData.constData()); file.write(jsonData);
file.close(); file.close();
} }
} }
@ -1328,7 +1328,7 @@ void ModelList::parseModelsJsonFile(const QByteArray &jsonData, bool save)
QString requiresVersion = obj["requires"].toString(); QString requiresVersion = obj["requires"].toString();
QString versionRemoved = obj["removedIn"].toString(); QString versionRemoved = obj["removedIn"].toString();
QString url = obj["url"].toString(); QString url = obj["url"].toString();
QByteArray modelHash = obj["md5sum"].toString().toLatin1().constData(); QByteArray modelHash = obj["md5sum"].toString().toLatin1();
bool isDefault = obj.contains("isDefault") && obj["isDefault"] == QString("true"); bool isDefault = obj.contains("isDefault") && obj["isDefault"] == QString("true");
bool disableGUI = obj.contains("disableGUI") && obj["disableGUI"] == QString("true"); bool disableGUI = obj.contains("disableGUI") && obj["disableGUI"] == QString("true");
QString description = obj["description"].toString(); QString description = obj["description"].toString();

View File

@ -462,9 +462,9 @@ void Network::handleIpifyFinished()
qWarning() << "ERROR: ipify invalid response."; qWarning() << "ERROR: ipify invalid response.";
if (code != 200) if (code != 200)
qWarning() << "ERROR: ipify response != 200 code:" << code; qWarning() << "ERROR: ipify response != 200 code:" << code;
m_ipify = qPrintable(reply->readAll()); m_ipify = reply->readAll();
#if defined(DEBUG) #if defined(DEBUG)
printf("ipify finished %s\n", m_ipify.toLatin1().constData()); printf("ipify finished %s\n", qPrintable(m_ipify));
fflush(stdout); fflush(stdout);
#endif #endif
reply->deleteLater(); reply->deleteLater();