mirror of
https://github.com/Palm1r/QodeAssist.git
synced 2026-05-30 02:49:12 -04:00
feat: Add Qwen provider
This commit is contained in:
@@ -116,6 +116,8 @@ add_qtc_plugin(QodeAssist
|
||||
providers/LlamaCppProvider.hpp providers/LlamaCppProvider.cpp
|
||||
providers/CodestralProvider.hpp providers/CodestralProvider.cpp
|
||||
providers/OpenAIResponsesProvider.hpp providers/OpenAIResponsesProvider.cpp
|
||||
providers/QwenProvider.hpp providers/QwenProvider.cpp
|
||||
providers/QwenResponsesProvider.hpp providers/QwenResponsesProvider.cpp
|
||||
QodeAssist.qrc
|
||||
LSPCompletion.hpp
|
||||
LLMSuggestion.hpp LLMSuggestion.cpp
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
[](https://www.gnu.org/licenses/gpl-3.0)
|
||||
[](https://discord.gg/BGMkUsXUgf)
|
||||
|
||||
 **QodeAssist** brings a full AI coding workflow to Qt Creator for C++ and QML — smart code completion, multi-panel chat, inline quick refactoring, and project-aware tool calling. It works with local runtimes (Ollama, llama.cpp, LM Studio) and cloud providers (Claude, OpenAI, Google AI, Mistral), can run as an **MCP server** so other clients reuse its project context, and can also act as an **MCP client** to consume tools from external MCP servers (authenticated MCP servers are not supported yet).
|
||||
 **QodeAssist** brings a full AI coding workflow to Qt Creator for C++ and QML — smart code completion, multi-panel chat, inline quick refactoring, and project-aware tool calling. It works with local runtimes (Ollama, llama.cpp, LM Studio) and cloud providers (Claude, OpenAI, Google AI, Mistral, Qwen), can run as an **MCP server** so other clients reuse its project context, and can also act as an **MCP client** to consume tools from external MCP servers (authenticated MCP servers are not supported yet).
|
||||
|
||||
⚠️ **Important Notice About Paid Providers**
|
||||
> When using paid providers like Claude, OpenRouter or OpenAI-compatible services:
|
||||
@@ -39,7 +39,7 @@ QodeAssist enhances Qt Creator with AI-powered coding assistance:
|
||||
- **MCP Server** — expose QodeAssist's project-aware tools to external MCP clients (Claude Code, VS Code, Claude Desktop via bridge)
|
||||
- **MCP Client Hub** — connect QodeAssist to external MCP servers and use their tools in Chat and Quick Refactor (authenticated MCP servers are not supported yet)
|
||||
- **File Context** — attach, link, or auto-sync open editor files for richer prompts
|
||||
- **Many Providers** — Ollama, llama.cpp, LM Studio (Chat + Responses), Claude, OpenAI (Chat + Responses), Google AI, Mistral, Codestral, OpenRouter, any OpenAI-compatible endpoint
|
||||
- **Many Providers** — Ollama, llama.cpp, LM Studio (Chat + Responses), Claude, OpenAI (Chat + Responses), Google AI, Mistral, Codestral, OpenRouter, Qwen (OpenAI + Responses), any OpenAI-compatible endpoint
|
||||
- **Customizable** — per-project rules (`.qodeassist/rules/`), agent roles, reusable refactor templates, full prompt-template control
|
||||
|
||||
**Join our [Discord Community](https://discord.gg/BGMkUsXUgf)** to get support and connect with other users!
|
||||
@@ -169,6 +169,7 @@ The Quick Setup feature provides one-click configuration for popular cloud AI mo
|
||||
- **OpenAI** (gpt-5.2-codex)
|
||||
- **Mistral AI** (Codestral 2501)
|
||||
- **Google AI** (Gemini 2.5 Flash)
|
||||
- **Qwen** (Qwen3.6 Plus, Qwen3.7 Max)
|
||||
3. **Configure API Key** - Click "Configure API Key" button and enter your API key in Provider Settings
|
||||
|
||||
All settings (provider, model, template, URL) are configured automatically. Just add your API key and you're ready to go!
|
||||
@@ -189,6 +190,7 @@ For advanced users or local models, choose your preferred provider and follow th
|
||||
- **[OpenAI](docs/openai-configuration.md)** — Chat Completions and Responses API
|
||||
- **[Mistral AI](docs/mistral-configuration.md)** / **Codestral**
|
||||
- **[Google AI](docs/google-ai-configuration.md)** — Gemini
|
||||
- **Qwen (Alibaba)** — DashScope OpenAI-compatible Chat and Responses endpoints
|
||||
- **OpenAI-compatible** — OpenRouter and any custom endpoint
|
||||
|
||||
### Recommended Models for Best Experience
|
||||
|
||||
@@ -14,6 +14,7 @@ enum class ProviderID {
|
||||
MistralAI,
|
||||
OpenRouter,
|
||||
GoogleAI,
|
||||
LlamaCpp
|
||||
LlamaCpp,
|
||||
Qwen
|
||||
};
|
||||
}
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
#include "providers/OpenAIProvider.hpp"
|
||||
#include "providers/OpenAIResponsesProvider.hpp"
|
||||
#include "providers/OpenRouterAIProvider.hpp"
|
||||
#include "providers/QwenProvider.hpp"
|
||||
#include "providers/QwenResponsesProvider.hpp"
|
||||
|
||||
namespace QodeAssist::Providers {
|
||||
|
||||
@@ -36,6 +38,8 @@ inline void registerProviders()
|
||||
providerManager.registerProvider<GoogleAIProvider>();
|
||||
providerManager.registerProvider<LlamaCppProvider>();
|
||||
providerManager.registerProvider<CodestralProvider>();
|
||||
providerManager.registerProvider<QwenProvider>();
|
||||
providerManager.registerProvider<QwenResponsesProvider>();
|
||||
}
|
||||
|
||||
} // namespace QodeAssist::Providers
|
||||
|
||||
34
providers/QwenProvider.cpp
Normal file
34
providers/QwenProvider.cpp
Normal file
@@ -0,0 +1,34 @@
|
||||
// Copyright (C) 2024-2026 Petr Mironychev
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#include "QwenProvider.hpp"
|
||||
|
||||
#include "settings/ProviderSettings.hpp"
|
||||
|
||||
namespace QodeAssist::Providers {
|
||||
|
||||
QwenProvider::QwenProvider(QObject *parent)
|
||||
: OpenAICompatProvider(parent)
|
||||
{}
|
||||
|
||||
QString QwenProvider::name() const
|
||||
{
|
||||
return "Qwen (OpenAI)";
|
||||
}
|
||||
|
||||
QString QwenProvider::apiKey() const
|
||||
{
|
||||
return Settings::providerSettings().qwenApiKey();
|
||||
}
|
||||
|
||||
QString QwenProvider::url() const
|
||||
{
|
||||
return "https://dashscope-intl.aliyuncs.com/compatible-mode/v1";
|
||||
}
|
||||
|
||||
PluginLLMCore::ProviderID QwenProvider::providerID() const
|
||||
{
|
||||
return PluginLLMCore::ProviderID::Qwen;
|
||||
}
|
||||
|
||||
} // namespace QodeAssist::Providers
|
||||
21
providers/QwenProvider.hpp
Normal file
21
providers/QwenProvider.hpp
Normal file
@@ -0,0 +1,21 @@
|
||||
// Copyright (C) 2024-2026 Petr Mironychev
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "providers/OpenAICompatProvider.hpp"
|
||||
|
||||
namespace QodeAssist::Providers {
|
||||
|
||||
class QwenProvider : public OpenAICompatProvider
|
||||
{
|
||||
public:
|
||||
explicit QwenProvider(QObject *parent = nullptr);
|
||||
|
||||
QString name() const override;
|
||||
QString url() const override;
|
||||
QString apiKey() const override;
|
||||
PluginLLMCore::ProviderID providerID() const override;
|
||||
};
|
||||
|
||||
} // namespace QodeAssist::Providers
|
||||
40
providers/QwenResponsesProvider.cpp
Normal file
40
providers/QwenResponsesProvider.cpp
Normal file
@@ -0,0 +1,40 @@
|
||||
// Copyright (C) 2024-2026 Petr Mironychev
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#include "QwenResponsesProvider.hpp"
|
||||
|
||||
#include "settings/ProviderSettings.hpp"
|
||||
|
||||
namespace QodeAssist::Providers {
|
||||
|
||||
QwenResponsesProvider::QwenResponsesProvider(QObject *parent)
|
||||
: OpenAIResponsesProvider(parent)
|
||||
{}
|
||||
|
||||
QString QwenResponsesProvider::name() const
|
||||
{
|
||||
return "Qwen (OpenAI Response)";
|
||||
}
|
||||
|
||||
QString QwenResponsesProvider::apiKey() const
|
||||
{
|
||||
return Settings::providerSettings().qwenApiKey();
|
||||
}
|
||||
|
||||
QString QwenResponsesProvider::url() const
|
||||
{
|
||||
return "https://dashscope-intl.aliyuncs.com/compatible-mode/v1";
|
||||
}
|
||||
|
||||
QFuture<QList<QString>> QwenResponsesProvider::getInstalledModels(const QString &)
|
||||
{
|
||||
return QtFuture::makeReadyFuture(QList<QString>{});
|
||||
}
|
||||
|
||||
PluginLLMCore::ProviderCapabilities QwenResponsesProvider::capabilities() const
|
||||
{
|
||||
return PluginLLMCore::ProviderCapability::Tools | PluginLLMCore::ProviderCapability::Thinking
|
||||
| PluginLLMCore::ProviderCapability::Image;
|
||||
}
|
||||
|
||||
} // namespace QodeAssist::Providers
|
||||
23
providers/QwenResponsesProvider.hpp
Normal file
23
providers/QwenResponsesProvider.hpp
Normal file
@@ -0,0 +1,23 @@
|
||||
// Copyright (C) 2024-2026 Petr Mironychev
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "providers/OpenAIResponsesProvider.hpp"
|
||||
|
||||
namespace QodeAssist::Providers {
|
||||
|
||||
class QwenResponsesProvider : public OpenAIResponsesProvider
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit QwenResponsesProvider(QObject *parent = nullptr);
|
||||
|
||||
QString name() const override;
|
||||
QString url() const override;
|
||||
QString apiKey() const override;
|
||||
QFuture<QList<QString>> getInstalledModels(const QString &url) override;
|
||||
PluginLLMCore::ProviderCapabilities capabilities() const override;
|
||||
};
|
||||
|
||||
} // namespace QodeAssist::Providers
|
||||
@@ -99,6 +99,28 @@ QVector<AIConfiguration> ConfigurationManager::getPredefinedConfigurations(
|
||||
geminiFlash.type = type;
|
||||
geminiFlash.isPredefined = true;
|
||||
|
||||
AIConfiguration qwenPlus;
|
||||
qwenPlus.id = "preset_qwen_plus";
|
||||
qwenPlus.name = "Qwen3.6 Plus";
|
||||
qwenPlus.provider = "Qwen (OpenAI Response)";
|
||||
qwenPlus.model = "qwen3.6-plus";
|
||||
qwenPlus.url = "https://dashscope-intl.aliyuncs.com/compatible-mode/v1";
|
||||
qwenPlus.customEndpoint = "";
|
||||
qwenPlus.templateName = "OpenAI Responses";
|
||||
qwenPlus.type = type;
|
||||
qwenPlus.isPredefined = true;
|
||||
|
||||
AIConfiguration qwenMax;
|
||||
qwenMax.id = "preset_qwen_max";
|
||||
qwenMax.name = "Qwen3.7 Max";
|
||||
qwenMax.provider = "Qwen (OpenAI Response)";
|
||||
qwenMax.model = "qwen3.7-max";
|
||||
qwenMax.url = "https://dashscope-intl.aliyuncs.com/compatible-mode/v1";
|
||||
qwenMax.customEndpoint = "";
|
||||
qwenMax.templateName = "OpenAI Responses";
|
||||
qwenMax.type = type;
|
||||
qwenMax.isPredefined = true;
|
||||
|
||||
AIConfiguration gpt;
|
||||
gpt.id = "preset_gpt";
|
||||
gpt.name = "gpt-5.5";
|
||||
@@ -117,6 +139,8 @@ QVector<AIConfiguration> ConfigurationManager::getPredefinedConfigurations(
|
||||
presets.append(codestral);
|
||||
presets.append(mistral);
|
||||
presets.append(geminiFlash);
|
||||
presets.append(qwenPlus);
|
||||
presets.append(qwenMax);
|
||||
|
||||
return presets;
|
||||
}
|
||||
|
||||
@@ -123,6 +123,15 @@ ProviderSettings::ProviderSettings()
|
||||
llamaCppApiKey.setDefaultValue("");
|
||||
llamaCppApiKey.setAutoApply(true);
|
||||
|
||||
// Qwen (Alibaba) Settings
|
||||
qwenApiKey.setSettingsKey(Constants::QWEN_API_KEY);
|
||||
qwenApiKey.setLabelText(Tr::tr("Qwen API Key:"));
|
||||
qwenApiKey.setDisplayStyle(Utils::StringAspect::LineEditDisplay);
|
||||
qwenApiKey.setPlaceHolderText(Tr::tr("Enter your API key here"));
|
||||
qwenApiKey.setHistoryCompleter(Constants::QWEN_API_KEY_HISTORY);
|
||||
qwenApiKey.setDefaultValue("");
|
||||
qwenApiKey.setAutoApply(true);
|
||||
|
||||
resetToDefaults.m_buttonText = Tr::tr("Reset Page to Defaults");
|
||||
|
||||
readSettings();
|
||||
@@ -152,6 +161,8 @@ ProviderSettings::ProviderSettings()
|
||||
Group{title(Tr::tr("Ollama Settings")), Column{ollamaBasicAuthApiKey}},
|
||||
Space{8},
|
||||
Group{title(Tr::tr("llama.cpp Settings")), Column{llamaCppApiKey}},
|
||||
Space{8},
|
||||
Group{title(Tr::tr("Qwen (Alibaba) Settings")), Column{qwenApiKey}},
|
||||
Stretch{1}};
|
||||
});
|
||||
}
|
||||
@@ -189,6 +200,7 @@ void ProviderSettings::setupConnections()
|
||||
connect(&llamaCppApiKey, &ButtonAspect::changed, this, [this]() {
|
||||
llamaCppApiKey.writeSettings();
|
||||
});
|
||||
connect(&qwenApiKey, &ButtonAspect::changed, this, [this]() { qwenApiKey.writeSettings(); });
|
||||
}
|
||||
|
||||
void ProviderSettings::resetSettingsToDefaults()
|
||||
@@ -211,6 +223,7 @@ void ProviderSettings::resetSettingsToDefaults()
|
||||
resetAspect(googleAiApiKey);
|
||||
resetAspect(ollamaBasicAuthApiKey);
|
||||
resetAspect(llamaCppApiKey);
|
||||
resetAspect(qwenApiKey);
|
||||
writeSettings();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ public:
|
||||
Utils::StringAspect googleAiApiKey{this};
|
||||
Utils::StringAspect ollamaBasicAuthApiKey{this};
|
||||
Utils::StringAspect llamaCppApiKey{this};
|
||||
Utils::StringAspect qwenApiKey{this};
|
||||
|
||||
private:
|
||||
void setupConnections();
|
||||
|
||||
@@ -163,6 +163,8 @@ const char OLLAMA_BASIC_AUTH_API_KEY[] = "QodeAssist.ollamaBasicAuthApiKey";
|
||||
const char OLLAMA_BASIC_AUTH_API_KEY_HISTORY[] = "QodeAssist.ollamaBasicAuthApiKeyHistory";
|
||||
const char LLAMA_CPP_API_KEY[] = "QodeAssist.llamaCppApiKey";
|
||||
const char LLAMA_CPP_API_KEY_HISTORY[] = "QodeAssist.llamaCppApiKeyHistory";
|
||||
const char QWEN_API_KEY[] = "QodeAssist.qwenApiKey";
|
||||
const char QWEN_API_KEY_HISTORY[] = "QodeAssist.qwenApiKeyHistory";
|
||||
|
||||
const char CLAUDE_ENABLE_PROMPT_CACHING[] = "QodeAssist.claudeEnablePromptCaching";
|
||||
const char CLAUDE_USE_EXTENDED_CACHE_TTL[] = "QodeAssist.claudeUseExtendedCacheTTL";
|
||||
|
||||
@@ -81,6 +81,7 @@ public:
|
||||
case PluginLLMCore::ProviderID::OpenRouter:
|
||||
case PluginLLMCore::ProviderID::LMStudio:
|
||||
case PluginLLMCore::ProviderID::LlamaCpp:
|
||||
case PluginLLMCore::ProviderID::Qwen:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
|
||||
Reference in New Issue
Block a user