📄 models.ts • 6021 bytes
/**
* CmdCode V0.5 - 模型提供商注册表
*
* 内置免费/低成本大模型API列表,启动时交互式选择
* 支持用户自定义接入任意 OpenAI 兼容 API
*/
export interface ModelProvider {
id: string // 模型ID(用于API调用)
name: string // 显示名称
vendor: string // 厂商
url: string // API Base URL
free: boolean // 是否免费
description: string // 简短描述
apiKeyHint: string // API Key获取提示
}
/** 内置模型提供商列表 */
export const BUILTIN_PROVIDERS: ModelProvider[] = [
// ═══════════════════════════════════════
// 付费模型(按量计费 / 赠送额度)
// ═══════════════════════════════════════
{
id: 'deepseek-v4-flash',
name: 'DeepSeek V4 Flash',
vendor: 'DeepSeek',
url: 'https://api.deepseek.com/v1',
free: false,
description: 'DeepSeek V4 Flash,快速响应,新用户赠送额度',
apiKeyHint: 'platform.deepseek.com/api_keys → API Key',
},
{
id: 'deepseek-v4-pro',
name: 'DeepSeek V4 Pro',
vendor: 'DeepSeek',
url: 'https://api.deepseek.com/v1',
free: false,
description: 'DeepSeek V4 Pro,深度推理,适合复杂任务',
apiKeyHint: 'platform.deepseek.com/api_keys → API Key',
},
{
id: 'minimax-m2.7-m1',
name: 'MiniMax-M2.7 (m1)',
vendor: 'MiniMax',
url: 'https://api.minimaxi.com/v1',
free: false,
description: 'MiniMax M2.7 (m1) 119元套餐',
apiKeyHint: 'platform.minimaxi.com → API Key',
},
{
id: 'minimax-m2.7-m2',
name: 'MiniMax-M2.7 (m2)',
vendor: 'MiniMax',
url: 'https://api.minimaxi.com/v1',
free: false,
description: 'MiniMax M2.7 (m2) 119元套餐',
apiKeyHint: 'platform.minimaxi.com → API Key',
},
{
id: 'minimax-m2.7-m3',
name: 'MiniMax-M2.7 (m3)',
vendor: 'MiniMax',
url: 'https://api.minimaxi.com/v1',
free: false,
description: 'MiniMax M2.7 (m3) 199极速套餐',
apiKeyHint: 'platform.minimaxi.com → API Key',
},
{
id: 'glm-5.1',
name: 'GLM-5.1 (火山引擎)',
vendor: '字节跳动',
url: 'https://ark.cn-beijing.volces.com/api/coding/v3',
free: false,
description: '火山引擎 Ark GLM-5.1 编码模型',
apiKeyHint: 'console.volcengine.com/ark → API Key',
},
{
id: 'glm-5',
name: 'GLM-5 (腾讯云)',
vendor: '腾讯云',
url: 'https://api.lkeap.cloud.tencent.com/coding/v3',
free: false,
description: '腾讯云 GLM-5 编码模型',
apiKeyHint: 'console.cloud.tencent.com/lkeap → API Key',
},
// ═══════════════════════════════════════
// 小米 MiMo(Token Plan 计费,双认证头 api-key + Bearer)
// ═══════════════════════════════════════
{
id: 'mimo-v2.5-pro',
name: 'MiMo V2.5 Pro',
vendor: '小米',
url: 'https://api.xiaomimimo.com/v1',
free: false,
description: '小米MiMo V2.5 Pro,深度推理,1M上下文,128K输出',
apiKeyHint: 'platform.xiaomimimo.com → API Key',
},
{
id: 'mimo-v2.5',
name: 'MiMo V2.5',
vendor: '小米',
url: 'https://api.xiaomimimo.com/v1',
free: false,
description: '小米MiMo V2.5,1M上下文,128K输出',
apiKeyHint: 'platform.xiaomimimo.com → API Key',
},
]
/** 自定义模型配置(用户手动输入) */
export interface CustomModelConfig {
id: string
name: string
vendor: string
url: string
apiKey: string
}
/** 连接测试结果 */
export interface ConnectionTestResult {
success: boolean
latencyMs: number
error?: string
}
/**
* 测试API连通性(5秒超时,不会卡死)
*/
export async function testConnection(
url: string,
apiKey: string,
model: string,
): Promise<ConnectionTestResult> {
const start = Date.now()
try {
const controller = new AbortController()
const timer = setTimeout(() => controller.abort(), 5_000)
// 尝试调用 models 端点或发送最小请求
const testUrl = url.replace(/\/+$/, '') + '/chat/completions'
const response = await fetch(testUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${apiKey}`,
},
body: JSON.stringify({
model,
messages: [{ role: 'user', content: 'hi' }],
max_tokens: 1,
stream: false,
}),
signal: controller.signal,
})
clearTimeout(timer)
const latencyMs = Date.now() - start
// 200/401/403/429 都说明网络通了,只是认证/限流问题
if (response.ok || response.status === 429 || response.status === 401 || response.status === 403) {
// 尝试读取错误信息
if (!response.ok) {
let errMsg = `HTTP ${response.status}`
try {
const body = await response.json()
if (body.error?.message) errMsg = body.error.message
} catch { /* P5: 响应体解析失败 */ }
if (response.status === 401) {
return { success: false, latencyMs, error: `API Key 无效: ${errMsg}` }
}
if (response.status === 429) {
return { success: true, latencyMs } // 429说明Key有效,只是限流
}
return { success: false, latencyMs, error: errMsg }
}
return { success: true, latencyMs }
}
return { success: false, latencyMs, error: `HTTP ${response.status}` }
} catch (e: any) {
const latencyMs = Date.now() - start
if (e.name === 'AbortError') {
return { success: false, latencyMs, error: '连接超时(5秒),请检查网络或API地址' }
}
return { success: false, latencyMs, error: e.message || '网络连接失败' }
}
}