diff --git a/backend/api/server.py b/backend/api/server.py index 8f3d3f4..9ec147d 100644 --- a/backend/api/server.py +++ b/backend/api/server.py @@ -65,6 +65,11 @@ VALIDATED_CHAT_MODEL_PROVIDERS = { 'zhipuai', } +UNSUPPORTED_CHAT_MODEL_PREFIXES: tuple[tuple[str, str], ...] = ( + # /models 会返回这批 ppio 模型,但 /chat/completions 实测不支持。 + ('ppio', 'pa/claude-'), +) + # WebUI 的快速入口只展示可以通过对话输入框安全执行的 slash command。 # 这些命令仍然保留在终端 `/` 列表里,但不适合作为 WebUI 快捷项。 WEBUI_HIDDEN_SLASH_COMMANDS = { @@ -1547,6 +1552,8 @@ def _normalize_model_list(payload: Any) -> list[dict[str, str]]: ) if provider and provider not in VALIDATED_CHAT_MODEL_PROVIDERS: continue + if _is_known_unsupported_chat_model(provider, model_id): + continue normalized = _normalize_model_id(model_id, provider=provider) if normalized is not None: entry = {'id': normalized} @@ -1579,6 +1586,15 @@ def _normalize_model_id(model: str, *, provider: str | None = None) -> str | Non return value +def _is_known_unsupported_chat_model(provider: str | None, model_id: str) -> bool: + provider_key = (provider or '').strip().lower() + model_key = model_id.strip().lower() + return any( + provider_key == blocked_provider and model_key.startswith(blocked_prefix) + for blocked_provider, blocked_prefix in UNSUPPORTED_CHAT_MODEL_PREFIXES + ) + + def _is_llm_model(model_id: str, model_type: str | None) -> bool: lower = model_id.strip().lower() blocked_fragments = ( diff --git a/tests/test_model_list.py b/tests/test_model_list.py index fe6677c..24c27c1 100644 --- a/tests/test_model_list.py +++ b/tests/test_model_list.py @@ -56,6 +56,18 @@ class ModelListTests(unittest.TestCase): 'owned_by': 'siliconflow', 'model_type': 'llm', }, + { + 'id': 'pa/claude-opus-4-7', + 'object': 'model', + 'owned_by': 'ppio', + 'model_type': 'llm', + }, + { + 'id': 'gemini-2.0-flash-20250609', + 'object': 'model', + 'owned_by': 'ppio', + 'model_type': 'llm', + }, ] } @@ -65,6 +77,7 @@ class ModelListTests(unittest.TestCase): [model['id'] for model in models], [ 'azure_openai/gpt-5', + 'ppio/gemini-2.0-flash-20250609', 'siliconflow/Pro/deepseek-ai/DeepSeek-V3', 'xiaomi/DeepSeek-R1-0528', ],