fix(backend): 修复 DeepSeek 模型列表为空 & whisper 下载不走代理 (#417)

问题1 — DeepSeek 模型下拉为空:
provider 的 /models 调用失败时,get_model_list 吞掉异常返回 [],
get_all_models_by_id 再对 [] 取 .data 触发 AttributeError 又被吞,
最终接口返回 {"code":0,"msg":"success","data":[]},把失败伪装成空成功,
用户看不到任何原因。
- 捕获并回传真实错误,不再二次吞
- 新增 model_fallback.normalize_models 兼容 SyncPage/list/dict,绝不再 .data 崩
- 内置供应商提供已知模型兜底清单(DeepSeek→deepseek-chat/deepseek-reasoner,
  Qwen→qwen-plus 等),动态拿不到时回退,保证下拉非空;动态可用时仍以动态为准

问题2 — whisper 模型下载不走代理(Docker 里代理没生效):
snapshot_download 既不读 UI 配的代理,HF_ENDPOINT 又固定 hf-mirror.com。
- ProxyConfigManager.apply_to_env() 把生效代理 export 到 HTTP(S)_PROXY/ALL_PROXY,
  huggingface_hub 即可复用;在每次下载前与启动时应用(覆盖转写按需下载)
- 网络类下载报错翻译成可操作提示(配代理 / 改 HF_ENDPOINT / 检查容器外网)
- .env.example 补充 HF_ENDPOINT 与代理覆盖说明

新增 tests/test_model_fallback.py、tests/test_proxy_apply_env.py(14 用例)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
huangjianwu
2026-06-29 13:54:44 +08:00
co-authored by Claude Opus 4.8
parent 6a43043874
commit bebf2e8c61
9 changed files with 373 additions and 18 deletions
@@ -58,3 +58,22 @@ class ProxyConfigManager:
if val:
return val
return None
def apply_to_env(self) -> Optional[str]:
"""把当前生效的代理 URL 写进进程环境变量,返回生效的 url(无则 None)。
为什么需要(issue #417):huggingface_hub / requests 这类库**只认**环境变量
HTTP_PROXY / HTTPS_PROXY / ALL_PROXY,不读我们 UI 配置文件。whisper 模型用
snapshot_download 从 HuggingFace 拉取,如果用户只在设置页填了代理,下载根本
不走代理 —— 就是用户说的「Docker 容器里代理没生效」。在下载前/启动时调用本
方法,把 UI 配的代理 export 到环境变量,HF 下载就能复用同一个代理。
大小写别名都写,覆盖不同库的读取习惯。
"""
url = self.get_proxy_url()
if not url:
return None
for key in ("HTTP_PROXY", "HTTPS_PROXY", "ALL_PROXY",
"http_proxy", "https_proxy", "all_proxy"):
os.environ[key] = url
return url