feat: Add DeepSeek provider

This commit is contained in:
Petr Mironychev
2026-05-29 12:41:18 +02:00
parent ea67ba0e2a
commit 033c0e8652
17 changed files with 212 additions and 10 deletions

View File

@@ -118,6 +118,7 @@ add_qtc_plugin(QodeAssist
providers/OpenAIResponsesProvider.hpp providers/OpenAIResponsesProvider.cpp providers/OpenAIResponsesProvider.hpp providers/OpenAIResponsesProvider.cpp
providers/QwenProvider.hpp providers/QwenProvider.cpp providers/QwenProvider.hpp providers/QwenProvider.cpp
providers/QwenResponsesProvider.hpp providers/QwenResponsesProvider.cpp providers/QwenResponsesProvider.hpp providers/QwenResponsesProvider.cpp
providers/DeepSeekProvider.hpp providers/DeepSeekProvider.cpp
QodeAssist.qrc QodeAssist.qrc
LSPCompletion.hpp LSPCompletion.hpp
LLMSuggestion.hpp LLMSuggestion.cpp LLMSuggestion.hpp LLMSuggestion.cpp

View File

@@ -6,7 +6,7 @@
[![License: GPL v3](https://img.shields.io/badge/License-GPLv3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0) [![License: GPL v3](https://img.shields.io/badge/License-GPLv3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0)
[![Discord](https://dcbadge.limes.pink/api/server/BGMkUsXUgf?style=flat)](https://discord.gg/BGMkUsXUgf) [![Discord](https://dcbadge.limes.pink/api/server/BGMkUsXUgf?style=flat)](https://discord.gg/BGMkUsXUgf)
![qodeassist-icon](https://github.com/user-attachments/assets/dc336712-83cb-440d-8761-8d0a31de898d) **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). ![qodeassist-icon](https://github.com/user-attachments/assets/dc336712-83cb-440d-8761-8d0a31de898d) **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, DeepSeek), 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** ⚠️ **Important Notice About Paid Providers**
> When using paid providers like Claude, OpenRouter or OpenAI-compatible services: > When using paid providers like Claude, OpenRouter or OpenAI-compatible services:
@@ -39,7 +39,8 @@ 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 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) - **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 - **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, Qwen (OpenAI + Responses), 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), DeepSeek, any OpenAI-compatible endpoint
- **Reasoning / Thinking** — streamed chain-of-thought is shown for reasoning models across Claude, Google, OpenAI Responses, and any OpenAI-compatible endpoint that returns `reasoning_content` (DeepSeek, Qwen QwQ/Qwen3-Thinking, LM Studio, OpenRouter, …)
- **Customizable** — per-project rules (`.qodeassist/rules/`), agent roles, reusable refactor templates, full prompt-template control - **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! **Join our [Discord Community](https://discord.gg/BGMkUsXUgf)** to get support and connect with other users!
@@ -170,6 +171,7 @@ The Quick Setup feature provides one-click configuration for popular cloud AI mo
- **Mistral AI** (Codestral 2501) - **Mistral AI** (Codestral 2501)
- **Google AI** (Gemini 2.5 Flash) - **Google AI** (Gemini 2.5 Flash)
- **Qwen** (Qwen3.6 Plus, Qwen3.7 Max) - **Qwen** (Qwen3.6 Plus, Qwen3.7 Max)
- **DeepSeek** (DeepSeek V4 Flash, DeepSeek V4 Pro)
3. **Configure API Key** - Click "Configure API Key" button and enter your API key in Provider Settings 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! All settings (provider, model, template, URL) are configured automatically. Just add your API key and you're ready to go!
@@ -191,6 +193,7 @@ For advanced users or local models, choose your preferred provider and follow th
- **[Mistral AI](docs/mistral-configuration.md)** / **Codestral** - **[Mistral AI](docs/mistral-configuration.md)** / **Codestral**
- **[Google AI](docs/google-ai-configuration.md)** — Gemini - **[Google AI](docs/google-ai-configuration.md)** — Gemini
- **Qwen (Alibaba)** — DashScope OpenAI-compatible Chat and Responses endpoints - **Qwen (Alibaba)** — DashScope OpenAI-compatible Chat and Responses endpoints
- **DeepSeek** — `deepseek-chat` and `deepseek-reasoner` (reasoning shown as thinking)
- **OpenAI-compatible** — OpenRouter and any custom endpoint - **OpenAI-compatible** — OpenRouter and any custom endpoint
### Recommended Models for Best Experience ### Recommended Models for Best Experience
@@ -255,7 +258,7 @@ Configure in: `Tools → Options → QodeAssist → Code Completion → General
- **[Chat Summarization](docs/chat-summarization.md)** - Compress long conversations into AI-generated summaries - **[Chat Summarization](docs/chat-summarization.md)** - Compress long conversations into AI-generated summaries
- **[File Context](docs/file-context.md)** - Attach or link files for better context - **[File Context](docs/file-context.md)** - Attach or link files for better context
- Automatic syncing with open editor files (optional) - Automatic syncing with open editor files (optional)
- Extended thinking mode (Claude, other providers in plan) - Enable deeper reasoning for complex tasks - Extended thinking / reasoning mode - shows streamed chain-of-thought for reasoning models (Claude, Google, OpenAI Responses, and OpenAI-compatible endpoints returning `reasoning_content` such as DeepSeek, Qwen, LM Studio, OpenRouter)
### Quick Refactoring ### Quick Refactoring
- Inline code refactoring directly in the editor with AI assistance - Inline code refactoring directly in the editor with AI assistance

View File

@@ -15,6 +15,7 @@ enum class ProviderID {
OpenRouter, OpenRouter,
GoogleAI, GoogleAI,
LlamaCpp, LlamaCpp,
Qwen Qwen,
DeepSeek
}; };
} }

View File

@@ -0,0 +1,110 @@
// Copyright (C) 2024-2026 Petr Mironychev
// SPDX-License-Identifier: GPL-3.0-or-later
#include "DeepSeekProvider.hpp"
#include <LLMQore/ToolsManager.hpp>
#include "logger/Logger.hpp"
#include "settings/ChatAssistantSettings.hpp"
#include "settings/CodeCompletionSettings.hpp"
#include "settings/GeneralSettings.hpp"
#include "settings/ProviderSettings.hpp"
#include "settings/QuickRefactorSettings.hpp"
#include "tools/ToolsRegistration.hpp"
#include <QJsonArray>
#include <QJsonDocument>
#include <QJsonObject>
namespace QodeAssist::Providers {
DeepSeekProvider::DeepSeekProvider(QObject *parent)
: PluginLLMCore::Provider(parent)
, m_client(new ::LLMQore::OpenAIClient(QString(), QString(), QString(), this))
{
Tools::registerQodeAssistTools(m_client->tools());
}
QString DeepSeekProvider::name() const
{
return "DeepSeek";
}
QString DeepSeekProvider::apiKey() const
{
return Settings::providerSettings().deepSeekApiKey();
}
QString DeepSeekProvider::url() const
{
return "https://api.deepseek.com";
}
QFuture<QList<QString>> DeepSeekProvider::getInstalledModels(const QString &url)
{
m_client->setUrl(url);
m_client->setApiKey(apiKey());
return m_client->listModels();
}
PluginLLMCore::ProviderID DeepSeekProvider::providerID() const
{
return PluginLLMCore::ProviderID::DeepSeek;
}
PluginLLMCore::ProviderCapabilities DeepSeekProvider::capabilities() const
{
return PluginLLMCore::ProviderCapability::Tools
| PluginLLMCore::ProviderCapability::Thinking
| PluginLLMCore::ProviderCapability::ModelListing;
}
void DeepSeekProvider::prepareRequest(
QJsonObject &request,
PluginLLMCore::PromptTemplate *prompt,
PluginLLMCore::ContextData context,
PluginLLMCore::RequestType type,
bool isToolsEnabled,
bool isThinkingEnabled)
{
if (!prompt->isSupportProvider(providerID())) {
LOG_MESSAGE(QString("Template %1 doesn't support %2 provider").arg(name(), prompt->name()));
}
prompt->prepareRequest(request, context);
auto applyModelParams = [&request](const auto &settings) {
request["max_tokens"] = settings.maxTokens();
request["temperature"] = settings.temperature();
if (settings.useTopP())
request["top_p"] = settings.topP();
if (settings.useFrequencyPenalty())
request["frequency_penalty"] = settings.frequencyPenalty();
if (settings.usePresencePenalty())
request["presence_penalty"] = settings.presencePenalty();
};
if (type == PluginLLMCore::RequestType::CodeCompletion) {
applyModelParams(Settings::codeCompletionSettings());
} else if (type == PluginLLMCore::RequestType::QuickRefactoring) {
applyModelParams(Settings::quickRefactorSettings());
} else {
applyModelParams(Settings::chatAssistantSettings());
}
if (isToolsEnabled) {
auto toolsDefinitions = m_client->tools()->getToolsDefinitions();
if (!toolsDefinitions.isEmpty()) {
request["tools"] = toolsDefinitions;
LOG_MESSAGE(QString("Added %1 tools to DeepSeek request").arg(toolsDefinitions.size()));
}
}
}
::LLMQore::BaseClient *DeepSeekProvider::client() const
{
return m_client;
}
} // namespace QodeAssist::Providers

View File

@@ -0,0 +1,37 @@
// Copyright (C) 2024-2026 Petr Mironychev
// SPDX-License-Identifier: GPL-3.0-or-later
#pragma once
#include <LLMQore/OpenAIClient.hpp>
#include <pluginllmcore/Provider.hpp>
namespace QodeAssist::Providers {
class DeepSeekProvider : public PluginLLMCore::Provider
{
Q_OBJECT
public:
explicit DeepSeekProvider(QObject *parent = nullptr);
QString name() const override;
QString url() const override;
void prepareRequest(
QJsonObject &request,
PluginLLMCore::PromptTemplate *prompt,
PluginLLMCore::ContextData context,
PluginLLMCore::RequestType type,
bool isToolsEnabled,
bool isThinkingEnabled) override;
QFuture<QList<QString>> getInstalledModels(const QString &url) override;
PluginLLMCore::ProviderID providerID() const override;
PluginLLMCore::ProviderCapabilities capabilities() const override;
::LLMQore::BaseClient *client() const override;
QString apiKey() const override;
private:
::LLMQore::OpenAIClient *m_client;
};
} // namespace QodeAssist::Providers

View File

@@ -57,7 +57,8 @@ PluginLLMCore::ProviderID LMStudioProvider::providerID() const
PluginLLMCore::ProviderCapabilities LMStudioProvider::capabilities() const PluginLLMCore::ProviderCapabilities LMStudioProvider::capabilities() const
{ {
return PluginLLMCore::ProviderCapability::Tools | PluginLLMCore::ProviderCapability::Image return PluginLLMCore::ProviderCapability::Tools | PluginLLMCore::ProviderCapability::Image
| PluginLLMCore::ProviderCapability::ModelListing; | PluginLLMCore::ProviderCapability::ModelListing
| PluginLLMCore::ProviderCapability::Thinking;
} }
void LMStudioProvider::prepareRequest( void LMStudioProvider::prepareRequest(

View File

@@ -55,7 +55,8 @@ PluginLLMCore::ProviderID MistralAIProvider::providerID() const
PluginLLMCore::ProviderCapabilities MistralAIProvider::capabilities() const PluginLLMCore::ProviderCapabilities MistralAIProvider::capabilities() const
{ {
return PluginLLMCore::ProviderCapability::Tools | PluginLLMCore::ProviderCapability::Image return PluginLLMCore::ProviderCapability::Tools | PluginLLMCore::ProviderCapability::Image
| PluginLLMCore::ProviderCapability::ModelListing; | PluginLLMCore::ProviderCapability::ModelListing
| PluginLLMCore::ProviderCapability::Thinking;
} }
void MistralAIProvider::prepareRequest( void MistralAIProvider::prepareRequest(

View File

@@ -113,7 +113,8 @@ PluginLLMCore::ProviderID OllamaCompatProvider::providerID() const
PluginLLMCore::ProviderCapabilities OllamaCompatProvider::capabilities() const PluginLLMCore::ProviderCapabilities OllamaCompatProvider::capabilities() const
{ {
return PluginLLMCore::ProviderCapability::Tools | PluginLLMCore::ProviderCapability::Image return PluginLLMCore::ProviderCapability::Tools | PluginLLMCore::ProviderCapability::Image
| PluginLLMCore::ProviderCapability::ModelListing; | PluginLLMCore::ProviderCapability::ModelListing
| PluginLLMCore::ProviderCapability::Thinking;
} }
::LLMQore::BaseClient *OllamaCompatProvider::client() const ::LLMQore::BaseClient *OllamaCompatProvider::client() const

View File

@@ -98,7 +98,8 @@ PluginLLMCore::ProviderID OpenAICompatProvider::providerID() const
PluginLLMCore::ProviderCapabilities OpenAICompatProvider::capabilities() const PluginLLMCore::ProviderCapabilities OpenAICompatProvider::capabilities() const
{ {
return PluginLLMCore::ProviderCapability::Tools | PluginLLMCore::ProviderCapability::Image; return PluginLLMCore::ProviderCapability::Tools | PluginLLMCore::ProviderCapability::Image
| PluginLLMCore::ProviderCapability::Thinking;
} }
::LLMQore::BaseClient *OpenAICompatProvider::client() const ::LLMQore::BaseClient *OpenAICompatProvider::client() const

View File

@@ -129,7 +129,8 @@ PluginLLMCore::ProviderID OpenAIProvider::providerID() const
PluginLLMCore::ProviderCapabilities OpenAIProvider::capabilities() const PluginLLMCore::ProviderCapabilities OpenAIProvider::capabilities() const
{ {
return PluginLLMCore::ProviderCapability::Tools | PluginLLMCore::ProviderCapability::Image return PluginLLMCore::ProviderCapability::Tools | PluginLLMCore::ProviderCapability::Image
| PluginLLMCore::ProviderCapability::ModelListing; | PluginLLMCore::ProviderCapability::ModelListing
| PluginLLMCore::ProviderCapability::Thinking;
} }
::LLMQore::BaseClient *OpenAIProvider::client() const ::LLMQore::BaseClient *OpenAIProvider::client() const

View File

@@ -5,6 +5,7 @@
#include "pluginllmcore/ProvidersManager.hpp" #include "pluginllmcore/ProvidersManager.hpp"
#include "providers/ClaudeProvider.hpp" #include "providers/ClaudeProvider.hpp"
#include "providers/DeepSeekProvider.hpp"
#include "providers/CodestralProvider.hpp" #include "providers/CodestralProvider.hpp"
#include "providers/GoogleAIProvider.hpp" #include "providers/GoogleAIProvider.hpp"
#include "providers/LMStudioProvider.hpp" #include "providers/LMStudioProvider.hpp"
@@ -40,6 +41,7 @@ inline void registerProviders()
providerManager.registerProvider<CodestralProvider>(); providerManager.registerProvider<CodestralProvider>();
providerManager.registerProvider<QwenProvider>(); providerManager.registerProvider<QwenProvider>();
providerManager.registerProvider<QwenResponsesProvider>(); providerManager.registerProvider<QwenResponsesProvider>();
providerManager.registerProvider<DeepSeekProvider>();
} }
} // namespace QodeAssist::Providers } // namespace QodeAssist::Providers

View File

@@ -121,6 +121,28 @@ QVector<AIConfiguration> ConfigurationManager::getPredefinedConfigurations(
qwenMax.type = type; qwenMax.type = type;
qwenMax.isPredefined = true; qwenMax.isPredefined = true;
AIConfiguration deepSeekFlash;
deepSeekFlash.id = "preset_deepseek_flash";
deepSeekFlash.name = "DeepSeek V4 Flash";
deepSeekFlash.provider = "DeepSeek";
deepSeekFlash.model = "deepseek-v4-flash";
deepSeekFlash.url = "https://api.deepseek.com";
deepSeekFlash.customEndpoint = "";
deepSeekFlash.templateName = "OpenAI Compatible";
deepSeekFlash.type = type;
deepSeekFlash.isPredefined = true;
AIConfiguration deepSeekPro;
deepSeekPro.id = "preset_deepseek_pro";
deepSeekPro.name = "DeepSeek V4 Pro";
deepSeekPro.provider = "DeepSeek";
deepSeekPro.model = "deepseek-v4-pro";
deepSeekPro.url = "https://api.deepseek.com";
deepSeekPro.customEndpoint = "";
deepSeekPro.templateName = "OpenAI Compatible";
deepSeekPro.type = type;
deepSeekPro.isPredefined = true;
AIConfiguration gpt; AIConfiguration gpt;
gpt.id = "preset_gpt"; gpt.id = "preset_gpt";
gpt.name = "gpt-5.5"; gpt.name = "gpt-5.5";
@@ -141,6 +163,8 @@ QVector<AIConfiguration> ConfigurationManager::getPredefinedConfigurations(
presets.append(geminiFlash); presets.append(geminiFlash);
presets.append(qwenPlus); presets.append(qwenPlus);
presets.append(qwenMax); presets.append(qwenMax);
presets.append(deepSeekFlash);
presets.append(deepSeekPro);
return presets; return presets;
} }

View File

@@ -132,6 +132,15 @@ ProviderSettings::ProviderSettings()
qwenApiKey.setDefaultValue(""); qwenApiKey.setDefaultValue("");
qwenApiKey.setAutoApply(true); qwenApiKey.setAutoApply(true);
// DeepSeek Settings
deepSeekApiKey.setSettingsKey(Constants::DEEPSEEK_API_KEY);
deepSeekApiKey.setLabelText(Tr::tr("DeepSeek API Key:"));
deepSeekApiKey.setDisplayStyle(Utils::StringAspect::LineEditDisplay);
deepSeekApiKey.setPlaceHolderText(Tr::tr("Enter your API key here"));
deepSeekApiKey.setHistoryCompleter(Constants::DEEPSEEK_API_KEY_HISTORY);
deepSeekApiKey.setDefaultValue("");
deepSeekApiKey.setAutoApply(true);
resetToDefaults.m_buttonText = Tr::tr("Reset Page to Defaults"); resetToDefaults.m_buttonText = Tr::tr("Reset Page to Defaults");
readSettings(); readSettings();
@@ -163,6 +172,8 @@ ProviderSettings::ProviderSettings()
Group{title(Tr::tr("llama.cpp Settings")), Column{llamaCppApiKey}}, Group{title(Tr::tr("llama.cpp Settings")), Column{llamaCppApiKey}},
Space{8}, Space{8},
Group{title(Tr::tr("Qwen (Alibaba) Settings")), Column{qwenApiKey}}, Group{title(Tr::tr("Qwen (Alibaba) Settings")), Column{qwenApiKey}},
Space{8},
Group{title(Tr::tr("DeepSeek Settings")), Column{deepSeekApiKey}},
Stretch{1}}; Stretch{1}};
}); });
} }
@@ -201,6 +212,9 @@ void ProviderSettings::setupConnections()
llamaCppApiKey.writeSettings(); llamaCppApiKey.writeSettings();
}); });
connect(&qwenApiKey, &ButtonAspect::changed, this, [this]() { qwenApiKey.writeSettings(); }); connect(&qwenApiKey, &ButtonAspect::changed, this, [this]() { qwenApiKey.writeSettings(); });
connect(&deepSeekApiKey, &ButtonAspect::changed, this, [this]() {
deepSeekApiKey.writeSettings();
});
} }
void ProviderSettings::resetSettingsToDefaults() void ProviderSettings::resetSettingsToDefaults()
@@ -224,6 +238,7 @@ void ProviderSettings::resetSettingsToDefaults()
resetAspect(ollamaBasicAuthApiKey); resetAspect(ollamaBasicAuthApiKey);
resetAspect(llamaCppApiKey); resetAspect(llamaCppApiKey);
resetAspect(qwenApiKey); resetAspect(qwenApiKey);
resetAspect(deepSeekApiKey);
writeSettings(); writeSettings();
} }
} }

View File

@@ -29,6 +29,7 @@ public:
Utils::StringAspect ollamaBasicAuthApiKey{this}; Utils::StringAspect ollamaBasicAuthApiKey{this};
Utils::StringAspect llamaCppApiKey{this}; Utils::StringAspect llamaCppApiKey{this};
Utils::StringAspect qwenApiKey{this}; Utils::StringAspect qwenApiKey{this};
Utils::StringAspect deepSeekApiKey{this};
private: private:
void setupConnections(); void setupConnections();

View File

@@ -165,6 +165,8 @@ const char LLAMA_CPP_API_KEY[] = "QodeAssist.llamaCppApiKey";
const char LLAMA_CPP_API_KEY_HISTORY[] = "QodeAssist.llamaCppApiKeyHistory"; const char LLAMA_CPP_API_KEY_HISTORY[] = "QodeAssist.llamaCppApiKeyHistory";
const char QWEN_API_KEY[] = "QodeAssist.qwenApiKey"; const char QWEN_API_KEY[] = "QodeAssist.qwenApiKey";
const char QWEN_API_KEY_HISTORY[] = "QodeAssist.qwenApiKeyHistory"; const char QWEN_API_KEY_HISTORY[] = "QodeAssist.qwenApiKeyHistory";
const char DEEPSEEK_API_KEY[] = "QodeAssist.deepSeekApiKey";
const char DEEPSEEK_API_KEY_HISTORY[] = "QodeAssist.deepSeekApiKeyHistory";
const char CLAUDE_ENABLE_PROMPT_CACHING[] = "QodeAssist.claudeEnablePromptCaching"; const char CLAUDE_ENABLE_PROMPT_CACHING[] = "QodeAssist.claudeEnablePromptCaching";
const char CLAUDE_USE_EXTENDED_CACHE_TTL[] = "QodeAssist.claudeUseExtendedCacheTTL"; const char CLAUDE_USE_EXTENDED_CACHE_TTL[] = "QodeAssist.claudeUseExtendedCacheTTL";

View File

@@ -82,6 +82,7 @@ public:
case PluginLLMCore::ProviderID::LMStudio: case PluginLLMCore::ProviderID::LMStudio:
case PluginLLMCore::ProviderID::LlamaCpp: case PluginLLMCore::ProviderID::LlamaCpp:
case PluginLLMCore::ProviderID::Qwen: case PluginLLMCore::ProviderID::Qwen:
case PluginLLMCore::ProviderID::DeepSeek:
return true; return true;
default: default:
return false; return false;