feat: add Kimi (moonshot) and full provider support in model configs

- backend: expand valid_providers from 4 to full frontend provider list
  (module-level VALID_PROVIDERS constant, used by create + update)
- backend: test endpoint gains generic OpenAI-compatible branch
  (moonshot/qwen/zhipu/siliconflow etc. via AsyncOpenAI direct call)
- frontend: Kimi preset models add kimi-k2-0905/0711/turbo + kimi-latest
  alongside legacy moonshot-v1 series

Verified: moonshot config create 201 (was 400), test endpoint reaches
api.moonshot.cn and returns provider auth error with dummy key.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-07-26 18:33:51 +08:00
parent 495eafcd78
commit 769dcc828e
2 changed files with 40 additions and 5 deletions

View File

@@ -29,10 +29,28 @@ router = APIRouter(
)
# 与前端 ModelConfigs.vue 的提供商列表保持一致。
# anthropic/google/cohere 为原生 API;其余均走 OpenAI 兼容端点。
VALID_PROVIDERS = [
'openai', 'deepseek', 'anthropic', 'local',
'qwen', 'zhipu', 'baidu', 'moonshot', 'bytedance', 'minimax',
'siliconflow', 'xunfei', 'hunyuan', 'yi', 'baichuan', 'openrouter',
'cohere', 'xai', 'together', 'fireworks', 'perplexity', 'deepinfra',
'groq', 'google', 'mistral',
]
# 可用 OpenAI 兼容协议直连测试的 provider(anthropic/google/cohere 协议不同,暂除外)
OPENAI_COMPATIBLE_PROVIDERS = {
'local', 'qwen', 'zhipu', 'baidu', 'moonshot', 'bytedance', 'minimax',
'siliconflow', 'xunfei', 'hunyuan', 'yi', 'baichuan', 'openrouter',
'xai', 'together', 'fireworks', 'perplexity', 'deepinfra', 'groq', 'mistral',
}
class ModelConfigCreate(BaseModel):
"""模型配置创建模型"""
name: str
provider: str # openai/deepseek/anthropic/local
provider: str # 见 VALID_PROVIDERS
model_name: str
api_key: str
base_url: Optional[str] = None
@@ -103,8 +121,7 @@ async def create_model_config(
注意:API密钥会加密存储
"""
# 验证提供商
valid_providers = ['openai', 'deepseek', 'anthropic', 'local']
if config_data.provider not in valid_providers:
if config_data.provider not in VALID_PROVIDERS:
raise ValidationError(f"不支持的提供商: {config_data.provider}")
# 检查名称是否重复
@@ -189,8 +206,7 @@ async def update_model_config(
config.name = config_data.name
if config_data.provider is not None:
valid_providers = ['openai', 'deepseek', 'anthropic', 'local']
if config_data.provider not in valid_providers:
if config_data.provider not in VALID_PROVIDERS:
raise ValidationError(f"不支持的提供商: {config_data.provider}")
config.provider = config_data.provider
@@ -277,6 +293,21 @@ async def test_model_config(
api_key=decrypted_api_key,
base_url=config.base_url
)
elif config.provider in OPENAI_COMPATIBLE_PROVIDERS:
# OpenAI 兼容协议通用测试(moonshot/qwen/zhipu/siliconflow 等)
if not config.base_url:
return {
"status": "error",
"message": f"提供商 {config.provider} 需要填写 API 地址(base_url)"
}
from openai import AsyncOpenAI
client = AsyncOpenAI(api_key=decrypted_api_key, base_url=config.base_url)
await client.chat.completions.create(
model=config.model_name,
messages=[{"role": "user", "content": "test"}],
max_tokens=5,
timeout=30,
)
else:
return {
"status": "warning",

View File

@@ -376,6 +376,10 @@ function createModelGroups(): ProviderGroup[] {
{
provider: 'moonshot', label: '月之暗面 Kimi', defaultBaseUrl: 'https://api.moonshot.cn/v1',
models: [
{ name: 'kimi-k2-0905-preview', desc: 'K2 增强版', price: '¥4/16', checked: false },
{ name: 'kimi-k2-0711-preview', desc: 'K2 旗舰', price: '¥4/16', checked: false },
{ name: 'kimi-k2-turbo-preview', desc: 'K2 高速版', price: '¥8/32', checked: false },
{ name: 'kimi-latest', desc: '自动指向最新', price: '¥4/16', checked: false },
{ name: 'moonshot-v1-8k', desc: '标准长度', price: '¥0.15/0.15', checked: false },
{ name: 'moonshot-v1-32k', desc: '中长文本', price: '¥0.3/0.3', checked: false },
{ name: 'moonshot-v1-128k', desc: '超长文本', price: '¥0.6/0.6', checked: false },