Repository navigation
feat: set default API URLs for various model credentials #7889
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7,6 +7,7 @@ | |
| @Date :5/13/24 7:47 AM | ||
| """ | ||
|
|
||
| import copy | ||
| import os | ||
|
|
||
| from common.utils.common import get_file_content | ||
|
|
@@ -146,6 +147,15 @@ class VolcanicEngineModelProvider(IModelProvider): | |
| def get_model_info_manage(self): | ||
| return model_info_manage | ||
|
|
||
| def get_model_credential(self, model_type, model_name): | ||
| model_credential = super().get_model_credential(model_type, model_name) | ||
| # 火山引擎 Ark 统一走 v3 地址;LLM 复用 OpenAI 凭证类,需为实例单独设置, | ||
| # 避免覆写共享凭证类的 default_value 影响到其它 provider。 | ||
| if model_type == "LLM" and hasattr(model_credential, "api_base"): | ||
| model_credential.api_base = copy.copy(model_credential.api_base) | ||
| model_credential.api_base.default_value = "https://ark.cn-beijing.volces.com/api/v3" | ||
| return model_credential | ||
|
|
||
| def get_model_provide_info(self): | ||
| return ModelProvideInfo( | ||
| provider="model_volcanic_engine_provider", | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. SummaryThe change is small and the intent is reasonable (give Volcanic Ark LLMs the v3 base URL without poisoning a shared credential class), but the implementation relies on a fragile monkey-patch of a credential-field object. Below are the concerns, ordered by severity. 1.
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,144 @@ | ||
| from django.test import SimpleTestCase | ||
|
|
||
| from models_provider.constants.model_provider_constants import ModelProvideConstants | ||
|
|
||
|
|
||
| class ProviderDefaultUrlTests(SimpleTestCase): | ||
| """供应商创建模型表单中的 API 地址应展示官方默认值。""" | ||
|
|
||
| def _url_default(self, provider_key, model_type, model_name, field): | ||
| provider = ModelProvideConstants[provider_key] | ||
| form_list = provider.get_model_credential(model_type, model_name).to_form_list() | ||
| fields = {item["field"]: item for item in form_list} | ||
| return fields[field].get("default_value") | ||
|
|
||
| def test_providers_expose_default_url(self): | ||
| cases = ( | ||
| # OpenAI | ||
| ("model_openai_provider", "LLM", "gpt-4o", "api_base", "https://api.openai.com/v1"), | ||
| ("model_openai_provider", "STT", "whisper-1", "api_base", "https://api.openai.com/v1"), | ||
| ("model_openai_provider", "TTS", "tts-1", "api_base", "https://api.openai.com/v1"), | ||
| ("model_openai_provider", "EMBEDDING", "text-embedding-3-small", "api_base", "https://api.openai.com/v1"), | ||
| ("model_openai_provider", "IMAGE", "gpt-4o", "api_base", "https://api.openai.com/v1"), | ||
| ("model_openai_provider", "TTI", "dall-e-3", "api_base", "https://api.openai.com/v1"), | ||
| # Anthropic | ||
| ( | ||
| "model_anthropic_provider", | ||
| "LLM", | ||
| "claude-3-5-sonnet-20241022", | ||
| "api_base", | ||
| "https://api.anthropic.com/v1", | ||
| ), | ||
| ( | ||
| "model_anthropic_provider", | ||
| "IMAGE", | ||
| "claude-3-5-sonnet-20241022", | ||
| "api_base", | ||
| "https://api.anthropic.com/v1", | ||
| ), | ||
| # Kimi | ||
| ("model_kimi_provider", "LLM", "moonshot-v1-128k", "api_base", "https://api.moonshot.cn/v1"), | ||
| # SiliconCloud | ||
| ( | ||
| "model_siliconCloud_provider", | ||
| "LLM", | ||
| "deepseek-ai/DeepSeek-R1-Distill-Llama-8B", | ||
| "api_base", | ||
| "https://api.siliconflow.cn/v1", | ||
| ), | ||
| ( | ||
| "model_siliconCloud_provider", | ||
| "STT", | ||
| "FunAudioLLM/SenseVoiceSmall", | ||
| "api_base", | ||
| "https://api.siliconflow.cn/v1", | ||
| ), | ||
| ( | ||
| "model_siliconCloud_provider", | ||
| "EMBEDDING", | ||
| "BAAI/bge-large-zh-v1.5", | ||
| "api_base", | ||
| "https://api.siliconflow.cn/v1", | ||
| ), | ||
| ( | ||
| "model_siliconCloud_provider", | ||
| "TTI", | ||
| "stabilityai/stable-diffusion-xl-base-1.0", | ||
| "api_base", | ||
| "https://api.siliconflow.cn/v1", | ||
| ), | ||
| ( | ||
| "model_siliconCloud_provider", | ||
| "RERANKER", | ||
| "BAAI/bge-reranker-v2-m3", | ||
| "api_base", | ||
| "https://api.siliconflow.cn/v1", | ||
| ), | ||
| ( | ||
| "model_siliconCloud_provider", | ||
| "TTS", | ||
| "FunAudioLLM/CosyVoice2-0.5B", | ||
| "api_base", | ||
| "https://api.siliconflow.cn/v1", | ||
| ), | ||
| ( | ||
| "model_siliconCloud_provider", | ||
| "IMAGE", | ||
| "Qwen/Qwen3-VL-32B-Instruct", | ||
| "api_base", | ||
| "https://api.siliconflow.cn/v1", | ||
| ), | ||
| # Aliyun BaiLian | ||
| ( | ||
| "aliyun_bai_lian_model_provider", | ||
| "LLM", | ||
| "qwen3.7-plus", | ||
| "api_base", | ||
| "https://dashscope.aliyuncs.com/compatible-mode/v1", | ||
| ), | ||
| ("aliyun_bai_lian_model_provider", "STT", "default", "api_url", "https://dashscope.aliyuncs.com/api/v1"), | ||
| ( | ||
| "aliyun_bai_lian_model_provider", | ||
| "STT", | ||
| "qwen-omni-turbo", | ||
| "api_url", | ||
| "https://dashscope.aliyuncs.com/api/v1", | ||
| ), | ||
| ( | ||
| "aliyun_bai_lian_model_provider", | ||
| "STT", | ||
| "qwen-audio-asr", | ||
| "api_url", | ||
| "https://dashscope.aliyuncs.com/api/v1", | ||
| ), | ||
| # Volcanic engine | ||
| ( | ||
| "model_volcanic_engine_provider", | ||
| "LLM", | ||
| "ep-xxxxxxxxxx-yyyy", | ||
| "api_base", | ||
| "https://ark.cn-beijing.volces.com/api/v3", | ||
| ), | ||
| ( | ||
| "model_volcanic_engine_provider", | ||
| "IMAGE", | ||
| "ep-xxxxxxxxxx-yyyy", | ||
| "api_base", | ||
| "https://ark.cn-beijing.volces.com/api/v3", | ||
| ), | ||
| ( | ||
| "model_volcanic_engine_provider", | ||
| "EMBEDDING", | ||
| "ep-xxxxxxxxxx-yyyy", | ||
| "api_base", | ||
| "https://ark.cn-beijing.volces.com/api/v3", | ||
| ), | ||
| # Xunfei | ||
| ("model_xf_provider", "LLM", "general", "spark_api_url", "wss://spark-api.xf-yun.com/v3.5/chat"), | ||
| # Qianfan reranker | ||
| ("model_qianfan_provider", "RERANKER", "bce-reranker-base", "api_url", "https://qianfan.baidubce.com/v2"), | ||
| ) | ||
|
|
||
| for provider_key, model_type, model_name, field, expected in cases: | ||
| with self.subTest(provider=provider_key, model_type=model_type, model_name=model_name, field=field): | ||
| self.assertEqual(expected, self._url_default(provider_key, model_type, model_name, field)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Review of Code Changes
The provided diff adds a
default_valueto an API URL field in what appears to be a credential form for Aliyun BaiLian models within a Dify-like framework. Here are the findings:1. Potential Issues & Irregularities
"https://dashscope.aliyuncs.com/api/v1"assumes all users will access the public internet endpoint. This ignores:https://dashscope-intl.aliyuncs.com/...)./api/v1is hardcoded. If Alibaba changes the API version, this code becomes stale. While unlikely to break immediately, it is generally better to let the SDK/client library handle base URLs internally rather than exposing and hardcoding them in UI forms unless strictly necessary for multi-tenant proxy setups.relation_show_field_dict: The field is shown for types["qwen", "omni"]. Ensure that for these types, the backend logic expects this exact URL format. If some types don't require custom URLs (and rely on SDK defaults), showing this field with a hardcoded default could mislead users into thinking it's mandatory configuration when it's not.2. Optimization Suggestions
default_value, consider makingrequired=Falseand letting the backend fall back to the standard SDK behavior if no URL is provided.SelectField) instead of a free-text input for the API URL, such as "Public Internet," "International," "Custom."3. Recommendation
If this change is to simplify setup for most users (who use the public dashscope), it is functionally acceptable but architecturally slightly risky. A better approach would be:
required=False.default_valueunless strictly required to populate existing user settings (migration scenario).If you must keep the default, consider adding a comment explaining why this specific URL/path is chosen, especially regarding versioning (
v1).