refactor: Remove validate request function

This commit is contained in:
Petr Mironychev
2026-04-01 01:24:46 +02:00
parent cd017ae1f2
commit 928519a636
24 changed files with 0 additions and 378 deletions

View File

@ -350,15 +350,6 @@ void LLMClientInterface::handleCompletion(const QJsonObject &request)
false,
false);
auto errors = config.provider->validateRequest(config.providerRequest, promptTemplate->type());
if (!errors.isEmpty()) {
QString error = QString("Request validation failed: %1").arg(errors.join("; "));
LOG_MESSAGE("Validate errors for request:");
LOG_MESSAGES(errors);
sendErrorResponse(request, error);
return;
}
connect(
provider->client(),
&::LLMCore::BaseClient::requestCompleted,

View File

@ -10,7 +10,6 @@ add_library(PluginLLMCore STATIC
PromptTemplate.hpp
PromptTemplateManager.hpp PromptTemplateManager.cpp
RequestConfig.hpp
ValidationUtils.hpp ValidationUtils.cpp
ProviderID.hpp
HttpClient.hpp HttpClient.cpp
DataBuffers.hpp

View File

@ -70,7 +70,6 @@ public:
bool isThinkingEnabled)
= 0;
virtual QFuture<QList<QString>> getInstalledModels(const QString &url) = 0;
virtual QList<QString> validateRequest(const QJsonObject &request, TemplateType type) = 0;
virtual QString apiKey() const = 0;
virtual void prepareNetworkRequest(QNetworkRequest &networkRequest) const = 0;
virtual ProviderID providerID() const = 0;

View File

@ -1,57 +0,0 @@
/*
* Copyright (C) 2024-2025 Petr Mironychev
*
* This file is part of QodeAssist.
*
* QodeAssist is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* QodeAssist is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with QodeAssist. If not, see <https://www.gnu.org/licenses/>.
*/
#include "ValidationUtils.hpp"
#include <QJsonArray>
namespace QodeAssist::PluginLLMCore {
QStringList ValidationUtils::validateRequestFields(
const QJsonObject &request, const QJsonObject &templateObj)
{
QStringList errors;
validateFields(request, templateObj, errors);
validateNestedObjects(request, templateObj, errors);
return errors;
}
void ValidationUtils::validateFields(
const QJsonObject &request, const QJsonObject &templateObj, QStringList &errors)
{
for (auto it = request.begin(); it != request.end(); ++it) {
if (!templateObj.contains(it.key())) {
errors << QString("unknown field '%1'").arg(it.key());
}
}
}
void ValidationUtils::validateNestedObjects(
const QJsonObject &request, const QJsonObject &templateObj, QStringList &errors)
{
for (auto it = request.begin(); it != request.end(); ++it) {
if (templateObj.contains(it.key()) && it.value().isObject()
&& templateObj[it.key()].isObject()) {
validateFields(it.value().toObject(), templateObj[it.key()].toObject(), errors);
validateNestedObjects(it.value().toObject(), templateObj[it.key()].toObject(), errors);
}
}
}
} // namespace QodeAssist::PluginLLMCore

View File

@ -1,41 +0,0 @@
/*
* Copyright (C) 2024-2025 Petr Mironychev
*
* This file is part of QodeAssist.
*
* QodeAssist is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* QodeAssist is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with QodeAssist. If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once
#include <QJsonObject>
#include <QStringList>
namespace QodeAssist::PluginLLMCore {
class ValidationUtils
{
public:
static QStringList validateRequestFields(
const QJsonObject &request, const QJsonObject &templateObj);
private:
static void validateFields(
const QJsonObject &request, const QJsonObject &templateObj, QStringList &errors);
static void validateNestedObjects(
const QJsonObject &request, const QJsonObject &templateObj, QStringList &errors);
};
} // namespace QodeAssist::PluginLLMCore

View File

@ -25,7 +25,6 @@
#include <LLMCore/ToolsManager.hpp>
#include "pluginllmcore/ValidationUtils.hpp"
#include "logger/Logger.hpp"
#include "settings/ChatAssistantSettings.hpp"
#include "settings/CodeCompletionSettings.hpp"
@ -136,26 +135,6 @@ QFuture<QList<QString>> ClaudeProvider::getInstalledModels(const QString &baseUr
return m_client->listModels();
}
QList<QString> ClaudeProvider::validateRequest(
const QJsonObject &request, PluginLLMCore::TemplateType type)
{
const auto templateReq = QJsonObject{
{"model", {}},
{"system", {}},
{"messages", QJsonArray{{QJsonObject{{"role", {}}, {"content", {}}}}}},
{"temperature", {}},
{"max_tokens", {}},
{"anthropic-version", {}},
{"top_p", {}},
{"top_k", {}},
{"stop", QJsonArray{}},
{"stream", {}},
{"tools", {}},
{"thinking", QJsonObject{{"type", {}}, {"budget_tokens", {}}}}};
return PluginLLMCore::ValidationUtils::validateRequestFields(request, templateReq);
}
QString ClaudeProvider::apiKey() const
{
return Settings::providerSettings().claudeApiKey();

View File

@ -43,7 +43,6 @@ public:
bool isToolsEnabled,
bool isThinkingEnabled) override;
QFuture<QList<QString>> getInstalledModels(const QString &url) override;
QList<QString> validateRequest(const QJsonObject &request, PluginLLMCore::TemplateType type) override;
QString apiKey() const override;
void prepareNetworkRequest(QNetworkRequest &networkRequest) const override;
PluginLLMCore::ProviderID providerID() const override;

View File

@ -27,7 +27,6 @@
#include <QJsonObject>
#include <QtCore/qurlquery.h>
#include "pluginllmcore/ValidationUtils.hpp"
#include "logger/Logger.hpp"
#include "settings/ChatAssistantSettings.hpp"
#include "settings/CodeCompletionSettings.hpp"
@ -149,28 +148,6 @@ QFuture<QList<QString>> GoogleAIProvider::getInstalledModels(const QString &base
return m_client->listModels();
}
QList<QString> GoogleAIProvider::validateRequest(
const QJsonObject &request, PluginLLMCore::TemplateType type)
{
QJsonObject templateReq;
templateReq = QJsonObject{
{"contents", QJsonArray{}},
{"system_instruction", QJsonArray{}},
{"generationConfig",
QJsonObject{
{"temperature", {}},
{"maxOutputTokens", {}},
{"topP", {}},
{"topK", {}},
{"thinkingConfig",
QJsonObject{{"thinkingBudget", {}}, {"includeThoughts", {}}}}}},
{"safetySettings", QJsonArray{}},
{"tools", QJsonArray{}}};
return PluginLLMCore::ValidationUtils::validateRequestFields(request, templateReq);
}
QString GoogleAIProvider::apiKey() const
{
return Settings::providerSettings().googleAiApiKey();

View File

@ -43,7 +43,6 @@ public:
bool isToolsEnabled,
bool isThinkingEnabled) override;
QFuture<QList<QString>> getInstalledModels(const QString &url) override;
QList<QString> validateRequest(const QJsonObject &request, PluginLLMCore::TemplateType type) override;
QString apiKey() const override;
void prepareNetworkRequest(QNetworkRequest &networkRequest) const override;
PluginLLMCore::ProviderID providerID() const override;

View File

@ -21,7 +21,6 @@
#include <LLMCore/ToolsManager.hpp>
#include "pluginllmcore/ValidationUtils.hpp"
#include "tools/ToolsRegistration.hpp"
#include "logger/Logger.hpp"
#include "settings/ChatAssistantSettings.hpp"
@ -70,25 +69,6 @@ QFuture<QList<QString>> LMStudioProvider::getInstalledModels(const QString &url)
return m_client->listModels();
}
QList<QString> LMStudioProvider::validateRequest(
const QJsonObject &request, PluginLLMCore::TemplateType type)
{
const auto templateReq = QJsonObject{
{"model", {}},
{"messages", QJsonArray{{QJsonObject{{"role", {}}, {"content", {}}}}}},
{"temperature", {}},
{"max_tokens", {}},
{"top_p", {}},
{"top_k", {}},
{"frequency_penalty", {}},
{"presence_penalty", {}},
{"stop", QJsonArray{}},
{"stream", {}},
{"tools", {}}};
return PluginLLMCore::ValidationUtils::validateRequestFields(request, templateReq);
}
QString LMStudioProvider::apiKey() const
{
return {};

View File

@ -42,7 +42,6 @@ public:
bool isToolsEnabled,
bool isThinkingEnabled) override;
QFuture<QList<QString>> getInstalledModels(const QString &url) override;
QList<QString> validateRequest(const QJsonObject &request, PluginLLMCore::TemplateType type) override;
QString apiKey() const override;
void prepareNetworkRequest(QNetworkRequest &networkRequest) const override;
PluginLLMCore::ProviderID providerID() const override;

View File

@ -20,7 +20,6 @@
#include "LlamaCppProvider.hpp"
#include <LLMCore/ToolsManager.hpp>
#include "pluginllmcore/ValidationUtils.hpp"
#include "logger/Logger.hpp"
#include "settings/ChatAssistantSettings.hpp"
#include "settings/CodeCompletionSettings.hpp"
@ -111,44 +110,6 @@ QFuture<QList<QString>> LlamaCppProvider::getInstalledModels(const QString &)
return QtFuture::makeReadyFuture(QList<QString>{});
}
QList<QString> LlamaCppProvider::validateRequest(
const QJsonObject &request, PluginLLMCore::TemplateType type)
{
if (type == PluginLLMCore::TemplateType::FIM) {
const auto infillReq = QJsonObject{
{"model", {}},
{"input_prefix", {}},
{"input_suffix", {}},
{"input_extra", {}},
{"prompt", {}},
{"temperature", {}},
{"top_p", {}},
{"top_k", {}},
{"max_tokens", {}},
{"frequency_penalty", {}},
{"presence_penalty", {}},
{"stop", QJsonArray{}},
{"stream", {}}};
return PluginLLMCore::ValidationUtils::validateRequestFields(request, infillReq);
} else {
const auto chatReq = QJsonObject{
{"model", {}},
{"messages", QJsonArray{{QJsonObject{{"role", {}}, {"content", {}}}}}},
{"temperature", {}},
{"max_tokens", {}},
{"top_p", {}},
{"top_k", {}},
{"frequency_penalty", {}},
{"presence_penalty", {}},
{"stop", QJsonArray{}},
{"stream", {}},
{"tools", {}}};
return PluginLLMCore::ValidationUtils::validateRequestFields(request, chatReq);
}
}
QString LlamaCppProvider::apiKey() const
{
return {};

View File

@ -43,7 +43,6 @@ public:
bool isToolsEnabled,
bool isThinkingEnabled) override;
QFuture<QList<QString>> getInstalledModels(const QString &url) override;
QList<QString> validateRequest(const QJsonObject &request, PluginLLMCore::TemplateType type) override;
QString apiKey() const override;
void prepareNetworkRequest(QNetworkRequest &networkRequest) const override;
PluginLLMCore::ProviderID providerID() const override;

View File

@ -20,7 +20,6 @@
#include "MistralAIProvider.hpp"
#include <LLMCore/ToolsManager.hpp>
#include "pluginllmcore/ValidationUtils.hpp"
#include "logger/Logger.hpp"
#include "settings/ChatAssistantSettings.hpp"
#include "settings/CodeCompletionSettings.hpp"
@ -69,34 +68,6 @@ QFuture<QList<QString>> MistralAIProvider::getInstalledModels(const QString &url
return m_client->listModels();
}
QList<QString> MistralAIProvider::validateRequest(
const QJsonObject &request, PluginLLMCore::TemplateType type)
{
const auto fimReq = QJsonObject{
{"model", {}},
{"max_tokens", {}},
{"stream", {}},
{"temperature", {}},
{"prompt", {}},
{"suffix", {}}};
const auto templateReq = QJsonObject{
{"model", {}},
{"messages", QJsonArray{{QJsonObject{{"role", {}}, {"content", {}}}}}},
{"temperature", {}},
{"max_tokens", {}},
{"top_p", {}},
{"top_k", {}},
{"frequency_penalty", {}},
{"presence_penalty", {}},
{"stop", QJsonArray{}},
{"stream", {}},
{"tools", {}}};
return PluginLLMCore::ValidationUtils::validateRequestFields(
request, type == PluginLLMCore::TemplateType::FIM ? fimReq : templateReq);
}
QString MistralAIProvider::apiKey() const
{
return Settings::providerSettings().mistralAiApiKey();

View File

@ -42,7 +42,6 @@ public:
bool isToolsEnabled,
bool isThinkingEnabled) override;
QFuture<QList<QString>> getInstalledModels(const QString &url) override;
QList<QString> validateRequest(const QJsonObject &request, PluginLLMCore::TemplateType type) override;
QString apiKey() const override;
void prepareNetworkRequest(QNetworkRequest &networkRequest) const override;
PluginLLMCore::ProviderID providerID() const override;

View File

@ -25,7 +25,6 @@
#include <QJsonDocument>
#include <QJsonObject>
#include "pluginllmcore/ValidationUtils.hpp"
#include "logger/Logger.hpp"
#include "settings/ChatAssistantSettings.hpp"
#include "settings/CodeCompletionSettings.hpp"
@ -140,46 +139,6 @@ QFuture<QList<QString>> OllamaProvider::getInstalledModels(const QString &baseUr
return m_client->listModels();
}
QList<QString> OllamaProvider::validateRequest(const QJsonObject &request, PluginLLMCore::TemplateType type)
{
const auto fimReq = QJsonObject{
{"keep_alive", {}},
{"model", {}},
{"stream", {}},
{"prompt", {}},
{"suffix", {}},
{"system", {}},
{"images", QJsonArray{}},
{"options",
QJsonObject{
{"temperature", {}},
{"stop", {}},
{"top_p", {}},
{"top_k", {}},
{"num_predict", {}},
{"frequency_penalty", {}},
{"presence_penalty", {}}}}};
const auto messageReq = QJsonObject{
{"keep_alive", {}},
{"model", {}},
{"stream", {}},
{"messages", QJsonArray{{QJsonObject{{"role", {}}, {"content", {}}, {"images", QJsonArray{}}}}}},
{"tools", QJsonArray{}},
{"options",
QJsonObject{
{"temperature", {}},
{"stop", {}},
{"top_p", {}},
{"top_k", {}},
{"num_predict", {}},
{"frequency_penalty", {}},
{"presence_penalty", {}}}}};
return PluginLLMCore::ValidationUtils::validateRequestFields(
request, type == PluginLLMCore::TemplateType::FIM ? fimReq : messageReq);
}
QString OllamaProvider::apiKey() const
{
return {};

View File

@ -43,7 +43,6 @@ public:
bool isToolsEnabled,
bool isThinkingEnabled) override;
QFuture<QList<QString>> getInstalledModels(const QString &url) override;
QList<QString> validateRequest(const QJsonObject &request, PluginLLMCore::TemplateType type) override;
QString apiKey() const override;
void prepareNetworkRequest(QNetworkRequest &networkRequest) const override;
PluginLLMCore::ProviderID providerID() const override;

View File

@ -20,7 +20,6 @@
#include "OpenAICompatProvider.hpp"
#include <LLMCore/ToolsManager.hpp>
#include "pluginllmcore/ValidationUtils.hpp"
#include "tools/ToolsRegistration.hpp"
#include "logger/Logger.hpp"
#include "settings/ChatAssistantSettings.hpp"
@ -113,25 +112,6 @@ QFuture<QList<QString>> OpenAICompatProvider::getInstalledModels(const QString &
return QtFuture::makeReadyFuture(QList<QString>{});
}
QList<QString> OpenAICompatProvider::validateRequest(
const QJsonObject &request, PluginLLMCore::TemplateType type)
{
const auto templateReq = QJsonObject{
{"model", {}},
{"messages", QJsonArray{{QJsonObject{{"role", {}}, {"content", {}}}}}},
{"temperature", {}},
{"max_tokens", {}},
{"top_p", {}},
{"top_k", {}},
{"frequency_penalty", {}},
{"presence_penalty", {}},
{"stop", QJsonArray{}},
{"stream", {}},
{"tools", {}}};
return PluginLLMCore::ValidationUtils::validateRequestFields(request, templateReq);
}
QString OpenAICompatProvider::apiKey() const
{
return Settings::providerSettings().openAiCompatApiKey();

View File

@ -42,7 +42,6 @@ public:
bool isToolsEnabled,
bool isThinkingEnabled) override;
QFuture<QList<QString>> getInstalledModels(const QString &url) override;
QList<QString> validateRequest(const QJsonObject &request, PluginLLMCore::TemplateType type) override;
QString apiKey() const override;
void prepareNetworkRequest(QNetworkRequest &networkRequest) const override;
PluginLLMCore::ProviderID providerID() const override;

View File

@ -21,7 +21,6 @@
#include <LLMCore/ToolsManager.hpp>
#include "tools/ToolsRegistration.hpp"
#include "pluginllmcore/ValidationUtils.hpp"
#include "logger/Logger.hpp"
#include "settings/ChatAssistantSettings.hpp"
#include "settings/CodeCompletionSettings.hpp"
@ -143,25 +142,6 @@ QFuture<QList<QString>> OpenAIProvider::getInstalledModels(const QString &baseUr
});
}
QList<QString> OpenAIProvider::validateRequest(const QJsonObject &request, PluginLLMCore::TemplateType type)
{
const auto templateReq = QJsonObject{
{"model", {}},
{"messages", QJsonArray{{QJsonObject{{"role", {}}, {"content", {}}}}}},
{"temperature", {}},
{"max_tokens", {}},
{"max_completion_tokens", {}}, // New parameter for newer models
{"top_p", {}},
{"top_k", {}},
{"frequency_penalty", {}},
{"presence_penalty", {}},
{"stop", QJsonArray{}},
{"stream", {}},
{"tools", {}}};
return PluginLLMCore::ValidationUtils::validateRequestFields(request, templateReq);
}
QString OpenAIProvider::apiKey() const
{
return Settings::providerSettings().openAiApiKey();

View File

@ -42,7 +42,6 @@ public:
bool isToolsEnabled,
bool isThinkingEnabled) override;
QFuture<QList<QString>> getInstalledModels(const QString &url) override;
QList<QString> validateRequest(const QJsonObject &request, PluginLLMCore::TemplateType type) override;
QString apiKey() const override;
void prepareNetworkRequest(QNetworkRequest &networkRequest) const override;
PluginLLMCore::ProviderID providerID() const override;

View File

@ -21,7 +21,6 @@
#include <LLMCore/ToolsManager.hpp>
#include "tools/ToolsRegistration.hpp"
#include "pluginllmcore/ValidationUtils.hpp"
#include "logger/Logger.hpp"
#include "settings/ChatAssistantSettings.hpp"
#include "settings/CodeCompletionSettings.hpp"
@ -163,46 +162,6 @@ QFuture<QList<QString>> OpenAIResponsesProvider::getInstalledModels(const QStrin
});
}
QList<QString> OpenAIResponsesProvider::validateRequest(
const QJsonObject &request, PluginLLMCore::TemplateType type)
{
Q_UNUSED(type);
QList<QString> errors;
if (!request.contains("input")) {
errors.append("Missing required field: input");
return errors;
}
const QJsonValue inputValue = request["input"];
if (!inputValue.isString() && !inputValue.isArray()) {
errors.append("Field 'input' must be either a string or an array");
}
if (request.contains("max_output_tokens") && !request["max_output_tokens"].isDouble()) {
errors.append("Field 'max_output_tokens' must be a number");
}
if (request.contains("top_p") && !request["top_p"].isDouble()) {
errors.append("Field 'top_p' must be a number");
}
if (request.contains("reasoning") && !request["reasoning"].isObject()) {
errors.append("Field 'reasoning' must be an object");
}
if (request.contains("stream") && !request["stream"].isBool()) {
errors.append("Field 'stream' must be a boolean");
}
if (request.contains("tools") && !request["tools"].isArray()) {
errors.append("Field 'tools' must be an array");
}
return errors;
}
QString OpenAIResponsesProvider::apiKey() const
{
return Settings::providerSettings().openAiApiKey();

View File

@ -42,7 +42,6 @@ public:
bool isToolsEnabled,
bool isThinkingEnabled) override;
QFuture<QList<QString>> getInstalledModels(const QString &url) override;
QList<QString> validateRequest(const QJsonObject &request, PluginLLMCore::TemplateType type) override;
QString apiKey() const override;
void prepareNetworkRequest(QNetworkRequest &networkRequest) const override;
PluginLLMCore::ProviderID providerID() const override;

View File

@ -83,12 +83,6 @@ public:
return QtFuture::makeReadyFuture(QList<QString>{});
}
QStringList validateRequest(
const QJsonObject &request, LLMCore::TemplateType templateType) override
{
return {};
}
QString apiKey() const override { return "mock_api_key"; }
void prepareNetworkRequest(QNetworkRequest &request) const override {}
LLMCore::ProviderID providerID() const override { return LLMCore::ProviderID::OpenAI; }