[GH-ISSUE #3306] [BUG]: in Chat mode but still Custom refusal message #2127

Closed
opened 2026-02-22 18:28:14 -05:00 by yindo · 6 comments
Owner

Originally created by @ImOP12138 on GitHub (Feb 21, 2025).
Original GitHub issue: https://github.com/Mintplex-Labs/anything-llm/issues/3306

How are you running AnythingLLM?

AnythingLLM desktop app

What happened?

My workspace is in chat mode and when it doesn't pin any docs,it will it will reply "Custom refusal message" for me.
I'm not in query mode.
I chat with LLM by calling the API,which is supported by ollama

Image

Image

Image

my code about chatting request is as follows:

void QT_checkFiles::on_sendButton_clicked()
{
    qDebug() << "connecting...";
    QString input = ui.inputEdit->toPlainText().trimmed();
    if (input.isEmpty()) {
        qDebug() << "Input is empty. Aborting request.";
        return;
    }
    qDebug() << "User input:" << input;

    // 添加用户消息到历史
    addMessageToHistory("user", input);
    displayMessage("You", input);
    ui.inputEdit->clear();

    QJsonArray messagesArray;
    for (const auto& msg : chatHistory) {
        messagesArray.append(msg);
    }

    // 设置目标 URL
    QUrl url("http://localhost:3001/api/v1/workspace/test/chat");
    QNetworkRequest request(url);

    // 设置请求头
    request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
    request.setRawHeader("accept", "application/json");
    request.setRawHeader("Authorization", "Bearer API_KEYS");

    // 构造 JSON 数据
    QJsonObject json;
    json["message"] = input;
    QJsonDocument doc(json);
    QByteArray data = doc.toJson();

    // 发送 POST 请求
    QNetworkReply* reply = networkManager->post(request, data);

    // 连接信号槽,处理异步响应
    connect(reply, &QNetworkReply::finished, this, [this, reply]() {
        if (reply->error() == QNetworkReply::NoError) {
            QByteArray responseData = reply->readAll();
            qDebug() << "Raw response data from server:" << responseData;

            int statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
            qDebug() << "HTTP status code:" << statusCode;

            QJsonParseError parseError;
            QJsonDocument response = QJsonDocument::fromJson(responseData, &parseError);
            if (response.isNull()) {
                qDebug() << "Failed to parse JSON response. Parse error:" << parseError.errorString();
                QMessageBox::critical(this, "Error", "Failed to parse JSON response.");
                reply->deleteLater();
                return;
            }

            QJsonObject responseObj = response.object();

            // 检查是否有错误信息
            if (responseObj.contains("error") && !responseObj["error"].isNull()) {
                QString errorMessage = responseObj["error"].toObject()["message"].toString();
                qDebug() << "API returned an error:" << errorMessage;
                QMessageBox::critical(this, "API Error", errorMessage);
                reply->deleteLater();
                return;
            }

            // 检查 textResponse 字段
            if (responseObj.contains("textResponse")) {
                QString textResponse = responseObj["textResponse"].toString();
                qDebug() << "Server text response:" << textResponse;

                // 如果 textResponse 是拒绝消息,显示给用户
                if (!textResponse.isEmpty()) {
                    displayMessage("AI", textResponse);
                    addMessageToHistory("assistant", textResponse);
                }
            }
            else {
                qDebug() << "Unexpected response format. Missing 'textResponse' field.";
                QMessageBox::critical(this, "Error", "Unexpected response format from server.");
            }
        }
        else {
            QByteArray errorResponse = reply->readAll();
            qDebug() << "Network error:" << reply->errorString();
            qDebug() << "Error response from server:" << errorResponse;
            QMessageBox::critical(this, "Network Error", reply->errorString());
        }

        reply->deleteLater();
        });
}

void QT_checkFiles::addMessageToHistory(const QString& role, const QString& content)
{
    QJsonObject message;
    message["role"] = role;
    message["content"] = content;
    chatHistory.append(message);
    qDebug() << "Added message to history:" << message;
}

void QT_checkFiles::displayMessage(const QString& sender, const QString& message)
{
    ui.chatBrowser->append(QString("<b>%1:</b> %2").arg(sender, message));
    qDebug() << "Displayed message:" << sender << ":" << message;
}

Are there known steps to reproduce?

just new a blank workspace in chat mode and chat with the LLM by calling the API without pinning any docs.
I'm sure I'm not in query mode.

Originally created by @ImOP12138 on GitHub (Feb 21, 2025). Original GitHub issue: https://github.com/Mintplex-Labs/anything-llm/issues/3306 ### How are you running AnythingLLM? AnythingLLM desktop app ### What happened? My workspace is in _**chat**_ mode and when it **_doesn't pin any docs_**,it will it will reply "Custom refusal message" for me. I'm not in query mode. I chat with LLM by calling the API,which is supported by ollama ![Image](https://github.com/user-attachments/assets/f63c74de-49da-4759-bd8f-8e791f7b927b) ![Image](https://github.com/user-attachments/assets/72712d61-5840-4cf8-9ea2-dee534ed8b6e) ![Image](https://github.com/user-attachments/assets/dea89003-062a-4c8b-91aa-8af85175a328) my code about chatting request is as follows: ``` void QT_checkFiles::on_sendButton_clicked() { qDebug() << "connecting..."; QString input = ui.inputEdit->toPlainText().trimmed(); if (input.isEmpty()) { qDebug() << "Input is empty. Aborting request."; return; } qDebug() << "User input:" << input; // 添加用户消息到历史 addMessageToHistory("user", input); displayMessage("You", input); ui.inputEdit->clear(); QJsonArray messagesArray; for (const auto& msg : chatHistory) { messagesArray.append(msg); } // 设置目标 URL QUrl url("http://localhost:3001/api/v1/workspace/test/chat"); QNetworkRequest request(url); // 设置请求头 request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); request.setRawHeader("accept", "application/json"); request.setRawHeader("Authorization", "Bearer API_KEYS"); // 构造 JSON 数据 QJsonObject json; json["message"] = input; QJsonDocument doc(json); QByteArray data = doc.toJson(); // 发送 POST 请求 QNetworkReply* reply = networkManager->post(request, data); // 连接信号槽,处理异步响应 connect(reply, &QNetworkReply::finished, this, [this, reply]() { if (reply->error() == QNetworkReply::NoError) { QByteArray responseData = reply->readAll(); qDebug() << "Raw response data from server:" << responseData; int statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); qDebug() << "HTTP status code:" << statusCode; QJsonParseError parseError; QJsonDocument response = QJsonDocument::fromJson(responseData, &parseError); if (response.isNull()) { qDebug() << "Failed to parse JSON response. Parse error:" << parseError.errorString(); QMessageBox::critical(this, "Error", "Failed to parse JSON response."); reply->deleteLater(); return; } QJsonObject responseObj = response.object(); // 检查是否有错误信息 if (responseObj.contains("error") && !responseObj["error"].isNull()) { QString errorMessage = responseObj["error"].toObject()["message"].toString(); qDebug() << "API returned an error:" << errorMessage; QMessageBox::critical(this, "API Error", errorMessage); reply->deleteLater(); return; } // 检查 textResponse 字段 if (responseObj.contains("textResponse")) { QString textResponse = responseObj["textResponse"].toString(); qDebug() << "Server text response:" << textResponse; // 如果 textResponse 是拒绝消息,显示给用户 if (!textResponse.isEmpty()) { displayMessage("AI", textResponse); addMessageToHistory("assistant", textResponse); } } else { qDebug() << "Unexpected response format. Missing 'textResponse' field."; QMessageBox::critical(this, "Error", "Unexpected response format from server."); } } else { QByteArray errorResponse = reply->readAll(); qDebug() << "Network error:" << reply->errorString(); qDebug() << "Error response from server:" << errorResponse; QMessageBox::critical(this, "Network Error", reply->errorString()); } reply->deleteLater(); }); } void QT_checkFiles::addMessageToHistory(const QString& role, const QString& content) { QJsonObject message; message["role"] = role; message["content"] = content; chatHistory.append(message); qDebug() << "Added message to history:" << message; } void QT_checkFiles::displayMessage(const QString& sender, const QString& message) { ui.chatBrowser->append(QString("<b>%1:</b> %2").arg(sender, message)); qDebug() << "Displayed message:" << sender << ":" << message; } ``` ### Are there known steps to reproduce? just new a blank workspace in chat mode and chat with the LLM by calling the API without pinning any docs. I'm sure I'm not in query mode.
yindo added the possible bug label 2026-02-22 18:28:14 -05:00
yindo closed this issue 2026-02-22 18:28:15 -05:00
Author
Owner

@timothycarambat commented on GitHub (Feb 21, 2025):

I dont see mode defined in your body. That parameter is the control for the UI, not your code.
https://github.com/Mintplex-Labs/anything-llm/blob/27b661c9bb88b09104d3b8e16bef5fe198e6abc7/server/endpoints/api/workspace/index.js#L645

Define chat in your API request and it should work as expected. The default fallback is query - that is confusing and should be fixed.

@timothycarambat commented on GitHub (Feb 21, 2025): I dont see `mode` defined in your body. That parameter is the control for the UI, not your code. https://github.com/Mintplex-Labs/anything-llm/blob/27b661c9bb88b09104d3b8e16bef5fe198e6abc7/server/endpoints/api/workspace/index.js#L645 Define `chat` in your API request and it should work as expected. The default fallback is `query` - that is confusing and should be fixed.
Author
Owner

@ImOP12138 commented on GitHub (Feb 21, 2025):

there are my new workspace code

void QT_checkFiles::on_newWkSpaceButton_clicked()
{
    // 构造 JSON 数据
    QJsonObject jsonData;
    jsonData["name"] = "test";
    jsonData["similarityThreshold"] = 0.7;
    jsonData["openAiTemp"] = 0.7;
    jsonData["openAiHistory"] = 20;
    jsonData["openAiPrompt"] = "Custom prompt for responses";
    jsonData["queryRefusalResponse"] = "Custom refusal message";
    jsonData["chatMode"] = "chat";
    jsonData["topN"] = 4;

    // 将 JSON 对象转换为 JSON 文档
    QJsonDocument jsonDoc(jsonData);
    QByteArray jsonDataBytes = jsonDoc.toJson();



    QUrl url("http://localhost:3001/api/v1/workspace/new");
    QNetworkRequest request(url);

    // 设置请求头
    request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
    request.setRawHeader("accept", "application/json");
    request.setRawHeader("Authorization", "Bearer MJ0TZ5V-STHMNNR-JKMC6P3-SBPG3WW");

    // 发送 POST 请求
    QNetworkReply* reply = networkManager->post(request, jsonDataBytes);

    // 处理响应
    QObject::connect(reply, &QNetworkReply::finished, [=]() {
        if (reply->error() == QNetworkReply::NoError) {
            // 读取响应数据
            QByteArray responseData = reply->readAll();
            qDebug() << "Response:" << QString::fromUtf8(responseData);
        }
        else {
            // 输出错误信息
            qDebug() << "Error:" << reply->errorString();
        }

        // 清理资源
        reply->deleteLater();
        //networkManager->deleteLater();
        });
}
@ImOP12138 commented on GitHub (Feb 21, 2025): there are my new workspace code ``` void QT_checkFiles::on_newWkSpaceButton_clicked() { // 构造 JSON 数据 QJsonObject jsonData; jsonData["name"] = "test"; jsonData["similarityThreshold"] = 0.7; jsonData["openAiTemp"] = 0.7; jsonData["openAiHistory"] = 20; jsonData["openAiPrompt"] = "Custom prompt for responses"; jsonData["queryRefusalResponse"] = "Custom refusal message"; jsonData["chatMode"] = "chat"; jsonData["topN"] = 4; // 将 JSON 对象转换为 JSON 文档 QJsonDocument jsonDoc(jsonData); QByteArray jsonDataBytes = jsonDoc.toJson(); QUrl url("http://localhost:3001/api/v1/workspace/new"); QNetworkRequest request(url); // 设置请求头 request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); request.setRawHeader("accept", "application/json"); request.setRawHeader("Authorization", "Bearer MJ0TZ5V-STHMNNR-JKMC6P3-SBPG3WW"); // 发送 POST 请求 QNetworkReply* reply = networkManager->post(request, jsonDataBytes); // 处理响应 QObject::connect(reply, &QNetworkReply::finished, [=]() { if (reply->error() == QNetworkReply::NoError) { // 读取响应数据 QByteArray responseData = reply->readAll(); qDebug() << "Response:" << QString::fromUtf8(responseData); } else { // 输出错误信息 qDebug() << "Error:" << reply->errorString(); } // 清理资源 reply->deleteLater(); //networkManager->deleteLater(); }); } ```
Author
Owner

@timothycarambat commented on GitHub (Feb 21, 2025):

Creation of workspace is fine. Your chat code is wrong

 QUrl url("http://localhost:3001/api/v1/workspace/test/chat");

When using that URL the POST BODY must have mode: "chat" in the body.

@timothycarambat commented on GitHub (Feb 21, 2025): Creation of workspace is fine. Your chat code is wrong ``` QUrl url("http://localhost:3001/api/v1/workspace/test/chat"); ``` When using that URL the **POST BODY** must have `mode: "chat"` in the body.
Author
Owner

@ImOP12138 commented on GitHub (Feb 21, 2025):

Ah, that was indeed a point I overlooked. Thank you for your answer. You've been a great help!

@ImOP12138 commented on GitHub (Feb 21, 2025): Ah, that was indeed a point I overlooked. Thank you for your answer. You've been a great help!
Author
Owner

@timothycarambat commented on GitHub (Feb 21, 2025):

It is something we should fix, it is non-obvious and your assumption that was the issue is fully reasonable - so we should address this.

@timothycarambat commented on GitHub (Feb 21, 2025): It is something we should fix, it is non-obvious and your assumption that was the issue is fully reasonable - so we should address this.
Author
Owner

@ImOP12138 commented on GitHub (Feb 21, 2025):

Thank you for your dedication.

@ImOP12138 commented on GitHub (Feb 21, 2025): Thank you for your dedication.
yindo changed title from [BUG]: in Chat mode but still Custom refusal message to [GH-ISSUE #3306] [BUG]: in Chat mode but still Custom refusal message 2026-06-05 14:44:42 -04:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: Mintplex-Labs/anything-llm#2127