From 9e5014bfda9c8578bb7276fb29406fc818bb17fd Mon Sep 17 00:00:00 2001 From: byronwang2005 Date: Wed, 26 Nov 2025 11:53:14 +0800 Subject: [PATCH 1/3] Support DashScope --- .env.example | 3 + docs/CONFIGURATION_GUIDE.md | 14 +++- frontend/src/assets/png/index.ts | 1 + .../assets/png/model-providers/dashscope.png | Bin 0 -> 4399 bytes frontend/src/constants/icons.ts | 2 + python/configs/config.yaml | 4 + python/configs/providers/dashscope.yaml | 72 ++++++++++++++++++ python/valuecell/adapters/models/__init__.py | 2 + python/valuecell/adapters/models/factory.py | 64 ++++++++++++++++ python/valuecell/server/api/routers/models.py | 1 + 10 files changed, 162 insertions(+), 1 deletion(-) create mode 100644 frontend/src/assets/png/model-providers/dashscope.png create mode 100644 python/configs/providers/dashscope.yaml diff --git a/.env.example b/.env.example index d8a8c1d01..b0a47571b 100644 --- a/.env.example +++ b/.env.example @@ -60,5 +60,8 @@ OPENAI_API_KEY= OPENAI_COMPATIBLE_API_KEY= OPENAI_COMPATIBLE_BASE_URL= +# Get your API key from: https://bailian.console.aliyun.com/#/home +DASHSCOPE_API_KEY= + SEC_EMAIL=your.name@example.com diff --git a/docs/CONFIGURATION_GUIDE.md b/docs/CONFIGURATION_GUIDE.md index fdb0b6e51..2605a65d1 100644 --- a/docs/CONFIGURATION_GUIDE.md +++ b/docs/CONFIGURATION_GUIDE.md @@ -27,6 +27,7 @@ ValueCell supports multiple LLM providers. Choose at least one: | **SiliconFlow** | [siliconflow.cn](https://www.siliconflow.cn/) | | **Google** | [ai.google.dev](https://ai.google.dev/) | | **OpenAI** | [platform.openai.com](https://platform.openai.com/) | +| **DashScope** | [bailian.console.aliyun.com](https://bailian.console.aliyun.com/#/home) | ### Step 2: Configure .env File @@ -86,6 +87,7 @@ python/ │ ├── providers/ │ │ ├── openrouter.yaml # OpenRouter provider config │ │ ├── siliconflow.yaml # SiliconFlow provider config +│ │ ├── dashscope.yaml # DashScope (Alibaba Cloud) provider config │ │ └── other_provider.yaml │ ├── agents/ │ │ ├── super_agent.yaml # Super Agent configuration @@ -195,6 +197,9 @@ models: google: config_file: "providers/google.yaml" api_key_env: "GOOGLE_API_KEY" + dashscope: + config_file: "providers/dashscope.yaml" + api_key_env: "DASHSCOPE_API_KEY" # Agent registry agents: @@ -324,7 +329,10 @@ The selection logic is implemented in `python/valuecell/config/manager.py`: 1. OpenRouter 2. SiliconFlow 3. Google -4. Other configured providers +4. OpenAI +5. OpenAI-Compatible +6. Azure +7. Other configured providers (including DashScope, DeepSeek, etc.) Override this with an environment variable: @@ -417,6 +425,9 @@ GOOGLE_API_KEY=AIzaSyDxxxxxxxxxxxxx AZURE_OPENAI_API_KEY=xxxxxxxxxxxxx AZURE_OPENAI_ENDPOINT=https://xxxxx.openai.azure.com/ OPENAI_API_VERSION=2024-10-21 + +# DashScope (Alibaba Cloud Qwen3 models) +DASHSCOPE_API_KEY=sk-xxxxxxxxxxxxx ``` ### Model Configuration @@ -462,6 +473,7 @@ AGENT_DEBUG_MODE=true OPENROUTER_API_KEY=sk-or-v1-xxxxx # Primary: access to many models SILICONFLOW_API_KEY=sk-xxxxx # Fallback: cost-effective GOOGLE_API_KEY=AIzaSyD-xxxxx # Second fallback: specialized +DASHSCOPE_API_KEY=sk-xxxxx # DashScope: Qwen3 models (Chinese optimized) # config.yaml models: diff --git a/frontend/src/assets/png/index.ts b/frontend/src/assets/png/index.ts index 13fabba68..afa19c9d1 100644 --- a/frontend/src/assets/png/index.ts +++ b/frontend/src/assets/png/index.ts @@ -32,6 +32,7 @@ export { default as OkxPng } from "./exchanges/okx.png"; export { default as IconGroupPng } from "./icon-group.png"; export { default as MessageGroupPng } from "./message-group.png"; export { default as AzurePng } from "./model-providers/azure.png"; +export { default as DashScopePng } from "./model-providers/dashscope.png"; export { default as DeepSeekPng } from "./model-providers/deepseek.png"; export { default as GooglePng } from "./model-providers/google.png"; export { default as OpenAiPng } from "./model-providers/openai.png"; diff --git a/frontend/src/assets/png/model-providers/dashscope.png b/frontend/src/assets/png/model-providers/dashscope.png new file mode 100644 index 0000000000000000000000000000000000000000..7880368faa29fb4bb63ed9a85b292bafef908180 GIT binary patch literal 4399 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 literal 0 HcmV?d00001 diff --git a/frontend/src/constants/icons.ts b/frontend/src/constants/icons.ts index ddfa0a65b..d573e4914 100644 --- a/frontend/src/constants/icons.ts +++ b/frontend/src/constants/icons.ts @@ -3,6 +3,7 @@ import { BinancePng, BlockchainPng, CoinbasePng, + DashScopePng, DeepSeekPng, GatePng, GooglePng, @@ -23,6 +24,7 @@ export const MODEL_PROVIDER_ICONS = { deepseek: DeepSeekPng, google: GooglePng, azure: AzurePng, + dashscope: DashScopePng, }; export const EXCHANGE_ICONS = { diff --git a/python/configs/config.yaml b/python/configs/config.yaml index c034c1fe2..f081770bb 100644 --- a/python/configs/config.yaml +++ b/python/configs/config.yaml @@ -46,6 +46,10 @@ models: deepseek: config_file: "providers/deepseek.yaml" api_key_env: "DEEPSEEK_API_KEY" + + dashscope: + config_file: "providers/dashscope.yaml" + api_key_env: "DASHSCOPE_API_KEY" # Agent Configuration agents: diff --git a/python/configs/providers/dashscope.yaml b/python/configs/providers/dashscope.yaml new file mode 100644 index 000000000..3c8d5a454 --- /dev/null +++ b/python/configs/providers/dashscope.yaml @@ -0,0 +1,72 @@ +name: DashScope +provider_type: dashscope +enabled: true +connection: + base_url: https://dashscope.aliyuncs.com/compatible-mode/v1 + api_key_env: DASHSCOPE_API_KEY +default_model: qwen-max +defaults: + temperature: 0.7 + max_tokens: 4096 +models: +- id: qwen-max + name: Qwen3 Max + context_length: 128000 + max_output_tokens: 8192 + description: Qwen3 Max model with strongest performance + supported_inputs: + - text + supported_outputs: + - text +- id: qwen-plus + name: Qwen3 Plus + context_length: 128000 + max_output_tokens: 8192 + description: Qwen3 Plus model with balanced performance + supported_inputs: + - text + supported_outputs: + - text +- id: qwen-turbo + name: Qwen3 Turbo + context_length: 128000 + max_output_tokens: 8192 + description: Qwen3 Turbo model optimized for fast response + supported_inputs: + - text + supported_outputs: + - text +- id: qwen-7b-chat + name: Qwen3 7B Chat + context_length: 32000 + max_output_tokens: 4096 + description: Qwen3 7B chat model + supported_inputs: + - text + supported_outputs: + - text +- id: qwen-14b-chat + name: Qwen3 14B Chat + context_length: 32000 + max_output_tokens: 4096 + description: Qwen3 14B chat model + supported_inputs: + - text + supported_outputs: + - text +embedding: + default_model: text-embedding-v2 + defaults: + dimensions: 1536 + encoding_format: float + models: + - id: text-embedding-v2 + name: Text Embedding V2 + dimensions: 1536 + max_input: 2048 + description: DashScope text embedding v2 model + - id: text-embedding-v1 + name: Text Embedding V1 + dimensions: 1536 + max_input: 2048 + description: DashScope text embedding v1 model diff --git a/python/valuecell/adapters/models/__init__.py b/python/valuecell/adapters/models/__init__.py index 562247e80..eca956049 100644 --- a/python/valuecell/adapters/models/__init__.py +++ b/python/valuecell/adapters/models/__init__.py @@ -21,6 +21,7 @@ from valuecell.adapters.models.factory import ( AzureProvider, + DashScopeProvider, DeepSeekProvider, GoogleProvider, ModelFactory, @@ -47,6 +48,7 @@ "AzureProvider", "SiliconFlowProvider", "DeepSeekProvider", + "DashScopeProvider", # Convenience functions "create_model", "create_model_for_agent", diff --git a/python/valuecell/adapters/models/factory.py b/python/valuecell/adapters/models/factory.py index 11c88965a..685b29c2b 100644 --- a/python/valuecell/adapters/models/factory.py +++ b/python/valuecell/adapters/models/factory.py @@ -503,6 +503,69 @@ def create_model(self, model_id: Optional[str] = None, **kwargs): ) +class DashScopeProvider(ModelProvider): + """DashScope model provider + + DashScope (Alibaba Cloud) provides OpenAI-compatible API endpoints for Qwen3 models. + This provider uses the OpenAI-compatible interface to interact with DashScope's API. + """ + + def create_model(self, model_id: Optional[str] = None, **kwargs): + """Create DashScope model via agno (OpenAI-compatible)""" + try: + from agno.models.openai import OpenAILike + except ImportError: + raise ImportError( + "agno package not installed. Install with: pip install agno" + ) + + model_id = model_id or self.config.default_model + params = {**self.config.parameters, **kwargs} + + logger.info(f"Creating DashScope model: {model_id}") + + return OpenAILike( + id=model_id, + api_key=self.config.api_key, + base_url=self.config.base_url, + temperature=params.get("temperature"), + max_tokens=params.get("max_tokens"), + top_p=params.get("top_p"), + frequency_penalty=params.get("frequency_penalty"), + presence_penalty=params.get("presence_penalty"), + ) + + def create_embedder(self, model_id: Optional[str] = None, **kwargs): + """Create embedder via DashScope (OpenAI-compatible)""" + try: + from agno.knowledge.embedder.openai import OpenAIEmbedder + except ImportError: + raise ImportError("agno package not installed") + + # Use provided model_id or default embedding model + model_id = model_id or self.config.default_embedding_model + + if not model_id: + raise ValueError( + f"No embedding model specified for provider '{self.config.name}'" + ) + + # Merge parameters: provider embedding defaults < kwargs + params = {**self.config.embedding_parameters, **kwargs} + + logger.info(f"Creating DashScope embedder: {model_id}") + + return OpenAIEmbedder( + id=model_id, + api_key=self.config.api_key, + base_url=self.config.base_url, + dimensions=int(params.get("dimensions", 1536)) + if params.get("dimensions") + else None, + encoding_format=params.get("encoding_format", "float"), + ) + + class ModelFactory: """ Factory for creating model instances with provider abstraction @@ -523,6 +586,7 @@ class ModelFactory: "openai": OpenAIProvider, "openai-compatible": OpenAICompatibleProvider, "deepseek": DeepSeekProvider, + "dashscope": DashScopeProvider, } def __init__(self, config_manager: Optional[ConfigManager] = None): diff --git a/python/valuecell/server/api/routers/models.py b/python/valuecell/server/api/routers/models.py index c0ffe7a11..b55390c72 100644 --- a/python/valuecell/server/api/routers/models.py +++ b/python/valuecell/server/api/routers/models.py @@ -131,6 +131,7 @@ def _api_key_url_for(provider: str) -> str | None: "azure": "https://azure.microsoft.com/en-us/products/ai-foundry/models/openai/", "siliconflow": "https://cloud.siliconflow.cn/account/ak", "deepseek": "https://platform.deepseek.com/api_keys", + "dashscope": "https://bailian.console.aliyun.com/#/home", } return mapping.get(provider) From 4255d9a169a871caf810dc42f0062bf3bb52abd7 Mon Sep 17 00:00:00 2001 From: byronwang2005 Date: Wed, 26 Nov 2025 14:49:14 +0800 Subject: [PATCH 2/3] Add doc strings and format this yaml with blank lines for better readability --- python/configs/providers/dashscope.yaml | 133 ++++++++++++++---------- 1 file changed, 78 insertions(+), 55 deletions(-) diff --git a/python/configs/providers/dashscope.yaml b/python/configs/providers/dashscope.yaml index 3c8d5a454..a01666368 100644 --- a/python/configs/providers/dashscope.yaml +++ b/python/configs/providers/dashscope.yaml @@ -1,72 +1,95 @@ +# ============================================ +# DashScope Provider Configuration +# ============================================ +# DashScope (Alibaba Cloud Bailian) exposes an OpenAI-compatible API for Qwen3 models. +# Configure the API key via DASHSCOPE_API_KEY or override using env vars at runtime. + name: DashScope provider_type: dashscope enabled: true + +# Connection parameters for DashScope compatible-mode endpoint. connection: base_url: https://dashscope.aliyuncs.com/compatible-mode/v1 api_key_env: DASHSCOPE_API_KEY + +# Default chat model used when no model_id is specified. default_model: qwen-max + +# Global default inference parameters. defaults: temperature: 0.7 max_tokens: 4096 + +# Commonly used Qwen3 models available via DashScope. models: -- id: qwen-max - name: Qwen3 Max - context_length: 128000 - max_output_tokens: 8192 - description: Qwen3 Max model with strongest performance - supported_inputs: - - text - supported_outputs: - - text -- id: qwen-plus - name: Qwen3 Plus - context_length: 128000 - max_output_tokens: 8192 - description: Qwen3 Plus model with balanced performance - supported_inputs: - - text - supported_outputs: - - text -- id: qwen-turbo - name: Qwen3 Turbo - context_length: 128000 - max_output_tokens: 8192 - description: Qwen3 Turbo model optimized for fast response - supported_inputs: - - text - supported_outputs: - - text -- id: qwen-7b-chat - name: Qwen3 7B Chat - context_length: 32000 - max_output_tokens: 4096 - description: Qwen3 7B chat model - supported_inputs: - - text - supported_outputs: - - text -- id: qwen-14b-chat - name: Qwen3 14B Chat - context_length: 32000 - max_output_tokens: 4096 - description: Qwen3 14B chat model - supported_inputs: - - text - supported_outputs: - - text + - id: qwen-max + name: Qwen3 Max + context_length: 128000 + max_output_tokens: 8192 + description: Qwen3 Max model with strongest performance + supported_inputs: + - text + supported_outputs: + - text + + - id: qwen-plus + name: Qwen3 Plus + context_length: 128000 + max_output_tokens: 8192 + description: Qwen3 Plus model with balanced performance + supported_inputs: + - text + supported_outputs: + - text + + - id: qwen-turbo + name: Qwen3 Turbo + context_length: 128000 + max_output_tokens: 8192 + description: Qwen3 Turbo model optimized for fast response + supported_inputs: + - text + supported_outputs: + - text + + - id: qwen-7b-chat + name: Qwen3 7B Chat + context_length: 32000 + max_output_tokens: 4096 + description: Qwen3 7B chat model + supported_inputs: + - text + supported_outputs: + - text + + - id: qwen-14b-chat + name: Qwen3 14B Chat + context_length: 32000 + max_output_tokens: 4096 + description: Qwen3 14B chat model + supported_inputs: + - text + supported_outputs: + - text + +# Embedding configuration for DashScope text embedding models. embedding: default_model: text-embedding-v2 + defaults: dimensions: 1536 encoding_format: float + models: - - id: text-embedding-v2 - name: Text Embedding V2 - dimensions: 1536 - max_input: 2048 - description: DashScope text embedding v2 model - - id: text-embedding-v1 - name: Text Embedding V1 - dimensions: 1536 - max_input: 2048 - description: DashScope text embedding v1 model + - id: text-embedding-v2 + name: Text Embedding V2 + dimensions: 1536 + max_input: 2048 + description: DashScope text embedding v2 model + + - id: text-embedding-v1 + name: Text Embedding V1 + dimensions: 1536 + max_input: 2048 + description: DashScope text embedding v1 model From 279238460800cd00bde12e92f6a3b52be29a3dad Mon Sep 17 00:00:00 2001 From: byronwang2005 Date: Thu, 27 Nov 2025 15:30:36 +0800 Subject: [PATCH 3/3] Modify models --- python/configs/providers/dashscope.yaml | 76 +++++++++------------ python/valuecell/adapters/models/factory.py | 25 ++++--- 2 files changed, 45 insertions(+), 56 deletions(-) diff --git a/python/configs/providers/dashscope.yaml b/python/configs/providers/dashscope.yaml index a01666368..95d816ca1 100644 --- a/python/configs/providers/dashscope.yaml +++ b/python/configs/providers/dashscope.yaml @@ -14,60 +14,50 @@ connection: api_key_env: DASHSCOPE_API_KEY # Default chat model used when no model_id is specified. -default_model: qwen-max +default_model: qwen3-max # Global default inference parameters. defaults: temperature: 0.7 - max_tokens: 4096 + max_tokens: 16384 # Commonly used Qwen3 models available via DashScope. models: - - id: qwen-max + - id: qwen3-max name: Qwen3 Max - context_length: 128000 - max_output_tokens: 8192 + context_length: 256000 + max_output_tokens: 16384 description: Qwen3 Max model with strongest performance supported_inputs: - text supported_outputs: - text - - id: qwen-plus - name: Qwen3 Plus - context_length: 128000 - max_output_tokens: 8192 - description: Qwen3 Plus model with balanced performance + - id: qwen3-max-preview + name: Qwen3 Max Preview + context_length: 256000 + max_output_tokens: 16384 + description: Qwen3 Max preview model supported_inputs: - text supported_outputs: - text - - id: qwen-turbo - name: Qwen3 Turbo - context_length: 128000 - max_output_tokens: 8192 - description: Qwen3 Turbo model optimized for fast response - supported_inputs: - - text - supported_outputs: - - text - - - id: qwen-7b-chat - name: Qwen3 7B Chat - context_length: 32000 - max_output_tokens: 4096 - description: Qwen3 7B chat model + - id: qwen-plus + name: Qwen Plus + context_length: 256000 + max_output_tokens: 16384 + description: Qwen Plus model with balanced performance supported_inputs: - text supported_outputs: - text - - id: qwen-14b-chat - name: Qwen3 14B Chat - context_length: 32000 - max_output_tokens: 4096 - description: Qwen3 14B chat model + - id: qwen-flash + name: Qwen Flash + context_length: 256000 + max_output_tokens: 16384 + description: Qwen Flash model optimized for fast response supported_inputs: - text supported_outputs: @@ -75,21 +65,21 @@ models: # Embedding configuration for DashScope text embedding models. embedding: - default_model: text-embedding-v2 + default_model: text-embedding-v4 defaults: - dimensions: 1536 - encoding_format: float + dimensions: 2048 + encoding_format: "float" models: - - id: text-embedding-v2 - name: Text Embedding V2 - dimensions: 1536 - max_input: 2048 - description: DashScope text embedding v2 model + - id: text-embedding-v4 + name: Text Embedding V4 + dimensions: 2048 + max_input: 8192 + description: DashScope text embedding v4 model (latest) - - id: text-embedding-v1 - name: Text Embedding V1 - dimensions: 1536 - max_input: 2048 - description: DashScope text embedding v1 model + - id: text-embedding-v3 + name: Text Embedding V3 + dimensions: 1024 + max_input: 8192 + description: DashScope text embedding v3 model \ No newline at end of file diff --git a/python/valuecell/adapters/models/factory.py b/python/valuecell/adapters/models/factory.py index 685b29c2b..15835a8ed 100644 --- a/python/valuecell/adapters/models/factory.py +++ b/python/valuecell/adapters/models/factory.py @@ -504,16 +504,12 @@ def create_model(self, model_id: Optional[str] = None, **kwargs): class DashScopeProvider(ModelProvider): - """DashScope model provider - - DashScope (Alibaba Cloud) provides OpenAI-compatible API endpoints for Qwen3 models. - This provider uses the OpenAI-compatible interface to interact with DashScope's API. - """ + """DashScope model provider (native)""" def create_model(self, model_id: Optional[str] = None, **kwargs): - """Create DashScope model via agno (OpenAI-compatible)""" + """Create DashScope model via agno (native)""" try: - from agno.models.openai import OpenAILike + from agno.models.dashscope import DashScope except ImportError: raise ImportError( "agno package not installed. Install with: pip install agno" @@ -522,17 +518,20 @@ def create_model(self, model_id: Optional[str] = None, **kwargs): model_id = model_id or self.config.default_model params = {**self.config.parameters, **kwargs} - logger.info(f"Creating DashScope model: {model_id}") + # Prefer native endpoint; ignore compatible-mode base_url if present + base_url = self.config.base_url + if base_url and "compatible-mode" in base_url: + base_url = None - return OpenAILike( + logger.info(f"Creating DashScope (native) model: {model_id}") + + return DashScope( id=model_id, api_key=self.config.api_key, - base_url=self.config.base_url, + base_url=base_url, temperature=params.get("temperature"), max_tokens=params.get("max_tokens"), top_p=params.get("top_p"), - frequency_penalty=params.get("frequency_penalty"), - presence_penalty=params.get("presence_penalty"), ) def create_embedder(self, model_id: Optional[str] = None, **kwargs): @@ -559,7 +558,7 @@ def create_embedder(self, model_id: Optional[str] = None, **kwargs): id=model_id, api_key=self.config.api_key, base_url=self.config.base_url, - dimensions=int(params.get("dimensions", 1536)) + dimensions=int(params.get("dimensions", 2048)) if params.get("dimensions") else None, encoding_format=params.get("encoding_format", "float"),