diff --git a/CMakeLists.txt b/CMakeLists.txt index bf8f712..2c38b1e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -75,7 +75,7 @@ add_qtc_plugin(QodeAssist templates/StarCoder2Fim.hpp # templates/DeepSeekCoderFim.hpp # templates/CustomFimTemplate.hpp - templates/Qwen.hpp + templates/Qwen25CoderFIM.hpp templates/OpenAICompatible.hpp templates/Llama3.hpp templates/ChatML.hpp @@ -84,6 +84,7 @@ add_qtc_plugin(QodeAssist templates/CodeLlamaQMLFim.hpp templates/GoogleAI.hpp templates/LlamaCppFim.hpp + templates/Qwen3CoderFIM.hpp providers/Providers.hpp providers/OllamaProvider.hpp providers/OllamaProvider.cpp providers/ClaudeProvider.hpp providers/ClaudeProvider.cpp diff --git a/llmcore/PromptTemplate.hpp b/llmcore/PromptTemplate.hpp index 25fd572..07eee24 100644 --- a/llmcore/PromptTemplate.hpp +++ b/llmcore/PromptTemplate.hpp @@ -28,7 +28,7 @@ namespace QodeAssist::LLMCore { -enum class TemplateType { Chat, FIM }; +enum class TemplateType { Chat, FIM, FIMOnChat }; class PromptTemplate { diff --git a/llmcore/PromptTemplateManager.cpp b/llmcore/PromptTemplateManager.cpp index 69f288f..804b52c 100644 --- a/llmcore/PromptTemplateManager.cpp +++ b/llmcore/PromptTemplateManager.cpp @@ -19,6 +19,8 @@ #include "PromptTemplateManager.hpp" +#include + namespace QodeAssist::LLMCore { PromptTemplateManager &PromptTemplateManager::instance() @@ -70,15 +72,27 @@ PromptTemplateManager::~PromptTemplateManager() PromptTemplate *PromptTemplateManager::getFimTemplateByName(const QString &templateName) { - if (!m_fimTemplates.contains(templateName)) + if (!m_fimTemplates.contains(templateName)) { + QMessageBox::warning( + nullptr, + QObject::tr("Template Not Found"), + QObject::tr("Template '%1' was not found or has been updated. Please re-set new one.") + .arg(templateName)); return m_fimTemplates.first(); + } return m_fimTemplates[templateName]; } PromptTemplate *PromptTemplateManager::getChatTemplateByName(const QString &templateName) { - if (!m_chatTemplates.contains(templateName)) + if (!m_chatTemplates.contains(templateName)) { + QMessageBox::warning( + nullptr, + QObject::tr("Template Not Found"), + QObject::tr("Template '%1' was not found or has been updated. Please re-set new one.") + .arg(templateName)); return m_chatTemplates.first(); + } return m_chatTemplates[templateName]; } diff --git a/templates/Qwen.hpp b/templates/Qwen25CoderFIM.hpp similarity index 94% rename from templates/Qwen.hpp rename to templates/Qwen25CoderFIM.hpp index de5372c..cad83da 100644 --- a/templates/Qwen.hpp +++ b/templates/Qwen25CoderFIM.hpp @@ -24,10 +24,10 @@ namespace QodeAssist::Templates { -class QwenFim : public LLMCore::PromptTemplate +class Qwen25CoderFIM : public LLMCore::PromptTemplate { public: - QString name() const override { return "Qwen FIM"; } + QString name() const override { return "Qwen2.5 Coder FIM"; } LLMCore::TemplateType type() const override { return LLMCore::TemplateType::FIM; } QStringList stopWords() const override { return QStringList() << "<|endoftext|>" << "<|EOT|>"; } void prepareRequest(QJsonObject &request, const LLMCore::ContextData &context) const override diff --git a/templates/Qwen3CoderFIM.hpp b/templates/Qwen3CoderFIM.hpp new file mode 100644 index 0000000..94af77e --- /dev/null +++ b/templates/Qwen3CoderFIM.hpp @@ -0,0 +1,80 @@ +/* + * 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 . + */ + +#pragma once + +#include + +#include "llmcore/PromptTemplate.hpp" + +namespace QodeAssist::Templates { + +class Qwen3CoderFIM : public LLMCore::PromptTemplate +{ +public: + QString name() const override { return "Qwen3 Coder FIM"; } + LLMCore::TemplateType type() const override { return LLMCore::TemplateType::FIMOnChat; } + QStringList stopWords() const override { return QStringList() << "<|im_end|>"; } + void prepareRequest(QJsonObject &request, const LLMCore::ContextData &context) const override + { + QJsonArray messages; + + messages.append( + QJsonObject{{"role", "system"}, {"content", context.systemPrompt.value_or("")}}); + + messages.append( + QJsonObject{ + {"role", "user"}, + {"content", + QString("<|fim_prefix|>%1<|fim_suffix|>%2<|fim_middle|>") + .arg(context.prefix.value_or(""), context.suffix.value_or(""))}}); + request["messages"] = messages; + } + QString description() const override + { + return "Template for supporting Qwen3 Coder FIM format via chat template:\n\n" + "{\n" + " \"messages\": [\n" + " {\n" + " \"role\": \"system\",\n" + " \"content\": \"You are a code completion assistant.\"\n" + " },\n" + " {\n" + " \"role\": \"user\",\n" + " \"content\": \"<|fim_prefix|>code<|fim_suffix|>code<|fim_middle|>\"\n" + " }\n" + " ]\n" + "}\n\n"; + } + bool isSupportProvider(LLMCore::ProviderID id) const override + { + switch (id) { + case LLMCore::ProviderID::Ollama: + case LLMCore::ProviderID::LMStudio: + case LLMCore::ProviderID::OpenRouter: + case LLMCore::ProviderID::OpenAICompatible: + case LLMCore::ProviderID::LlamaCpp: + return true; + default: + return false; + } + } +}; + +} // namespace QodeAssist::Templates diff --git a/templates/Templates.hpp b/templates/Templates.hpp index 74369df..628b01f 100644 --- a/templates/Templates.hpp +++ b/templates/Templates.hpp @@ -35,7 +35,8 @@ #include "templates/Llama2.hpp" #include "templates/Llama3.hpp" #include "templates/LlamaCppFim.hpp" -#include "templates/Qwen.hpp" +#include "templates/Qwen25CoderFIM.hpp" +#include "templates/Qwen3CoderFIM.hpp" #include "templates/StarCoder2Fim.hpp" namespace QodeAssist::Templates { @@ -57,7 +58,8 @@ inline void registerTemplates() templateManager.registerTemplate(); // templateManager.registerTemplate(); // templateManager.registerTemplate(); - templateManager.registerTemplate(); + templateManager.registerTemplate(); + templateManager.registerTemplate(); templateManager.registerTemplate(); templateManager.registerTemplate(); templateManager.registerTemplate();