我们已经分析了根因:前端的直调模式使用了全局唯一的 Base URL,切换模型时没有同步更新为对应厂商的 API 地址。虽然模型配置已经存储在后端(GET /api/models 返回完整的 url 字段),但前端没有利用这些数据来动态切换端点。
下面给出自动切换的原子实施步骤,让前端直调模式与后端配置完全联动。
[
{
"id": 1,
"tool": "file_read",
"args": {
"path": "/home/administrator/CmdCode-V0.5/public/cmdcode-web.html",
"offset": 1316,
"limit": 40
},
"description": "读取 loadModelsIntoPanel 函数,查看模型列表加载逻辑",
"expected_outcome": "定位到当前模型缓存和下拉框填充位置"
},
{
"id": 2,
"tool": "file_edit",
"args": {
"path": "/home/administrator/CmdCode-V0.5/public/cmdcode-web.html",
"new_text": " // 将模型完整信息缓存,用于自动切换 Base URL\n modelsCache = (data.models || []).map(m => ({\n id: m.id,\n name: m.name,\n vendor: m.vendor,\n url: m.url || '',\n custom: m.custom || false\n }));\n sel.innerHTML = '';\n modelsCache.forEach(m => {\n const label = m.vendor ? `${m.name} (${m.vendor})` : m.name;\n sel.innerHTML += ``;\n });\n if (currentModel) {\n sel.value = currentModel;\n // 自动同步 Base URL\n const matched = modelsCache.find(m => m.id === currentModel);\n if (matched && matched.url) {\n const baseUrlInput = document.getElementById('settings-baseurl');\n if (baseUrlInput) baseUrlInput.value = matched.url;\n localStorage.setItem('cmdcode_direct_baseurl', matched.url);\n }\n }",
"old_text": " modelsCache = data.models || [];\n sel.innerHTML = '';\n modelsCache.forEach(m => {\n const label = m.vendor ? `${m.name} (${m.vendor})` : m.name;\n sel.innerHTML += ``;\n });\n if (currentModel) sel.value = currentModel;"
},
"description": "加载模型列表时缓存完整的 model 信息(含 url),若当前模型有对应 Base URL 则自动填入设置面板",
"expected_outcome": "用户切换模型后,Base URL 输入框自动更新为正确的厂商端点"
},
{
"id": 3,
"tool": "file_edit",
"args": {
"path": "/home/administrator/CmdCode-V0.5/public/cmdcode-web.html",
"new_text": "function switchModel(modelId) {\n if (!modelId) return;\n currentModel = modelId;\n const headerSelect = document.querySelector('.header .model-select');\n if (headerSelect) headerSelect.value = modelId;\n // 自动匹配并更新 Base URL\n const matched = modelsCache.find(m => m.id === modelId);\n if (matched && matched.url) {\n const baseUrlInput = document.getElementById('settings-baseurl');\n if (baseUrlInput) baseUrlInput.value = matched.url;\n localStorage.setItem('cmdcode_direct_baseurl', matched.url);\n }\n showToast('已切换模型: ' + modelId);\n}",
"old_text": "function switchModel(modelId) {\n if (!modelId) return;\n currentModel = modelId;\n const headerSelect = document.querySelector('.header .model-select');\n if (headerSelect) headerSelect.value = modelId;\n showToast('已切换模型: ' + modelId);\n}"
},
"description": "增强模型切换函数:自动从缓存中获取模型的 Base URL 并写入设置面板和 localStorage",
"expected_outcome": "切换模型后,直调用 Base URL 实时跟随,不再需要手动修改"
},
{
"id": 4,
"tool": "file_edit",
"args": {
"path": "/home/administrator/CmdCode-V0.5/public/cmdcode-web.html",
"new_text": " // 直调模式:优先使用当前模型对应的 Base URL,其次使用 localStorage 保存的值\n const directBaseUrl = (modelsCache.find(m => m.id === currentModel) || {}).url\n || localStorage.getItem('cmdcode_direct_baseurl')\n || 'https://api.lkeap.cloud.tencent.com/coding/v3';\n const directApiKey = localStorage.getItem('cmdcode_direct_key') || '';\n if (directApiKey && directBaseUrl) {\n useProxy = false;\n baseUrl = directBaseUrl;\n apiKey = directApiKey;\n }",
"old_text": " const directApiKey = localStorage.getItem('cmdcode_direct_key') || '';\n const directBaseUrl = localStorage.getItem('cmdcode_direct_baseurl') || '';\n if (directApiKey && directBaseUrl) {\n useProxy = false;\n baseUrl = directBaseUrl;\n apiKey = directApiKey;\n }"
},
"description": "修改 sendMessage 中的直调模式判断,优先从模型缓存中获取 Base URL,保证与当前选择的模型匹配",
"expected_outcome": "发送消息时自动使用正确的厂商端点,不再出现模型名称与 API 地址不匹配的错误"
},
{
"id": 5,
"tool": "bash_run",
"args": {
"command": "cd /home/administrator/CmdCode-V0.5 && bun run src/cli.ts --version",
"timeout": 10
},
"description": "验证全部修改后项目仍可正常编译启动",
"expected_outcome": "输出 CmdCode V0.5.0"
}
]