diff --git a/routes/model_routes.py b/routes/model_routes.py index 0adaa2b06..2a363388c 100644 --- a/routes/model_routes.py +++ b/routes/model_routes.py @@ -731,12 +731,19 @@ def _is_loading_model_response(resp: Any) -> bool: def _openai_model_ids(data: Any) -> List[str]: - """Extract OpenAI-style model IDs (``{"data": [{"id": ...}]}``). + """Extract OpenAI-style model IDs. - Tolerates a non-dict body and non-string IDs from non-compliant upstreams, - returning only non-empty string IDs. + Accepts both standard ``{"data": [{"id": ...}]}`` responses and bare + ``[{"id": ...}]`` lists returned by some OpenAI-compatible providers. + Tolerates non-dict/non-list bodies and non-string IDs, returning only + non-empty string IDs. """ - items = data.get("data") if isinstance(data, dict) else None + if isinstance(data, list): + items = data + elif isinstance(data, dict): + items = data.get("data") + else: + items = None return [m["id"] for m in (items or []) if isinstance(m, dict) and isinstance(m.get("id"), str) and m["id"]] diff --git a/routes/webhook_routes.py b/routes/webhook_routes.py index c9cf856ca..8d3a704c6 100644 --- a/routes/webhook_routes.py +++ b/routes/webhook_routes.py @@ -345,8 +345,9 @@ def setup_webhook_routes( resp = await client.get(models_url, headers=hdrs) resp.raise_for_status() data = resp.json() - ids = [m.get("id") for m in (data.get("data") or []) if m.get("id")] - if not ids: + items = data if isinstance(data, list) else (data.get("data") or []) + ids = [m.get("id") for m in items if isinstance(m, dict) and m.get("id")] + if not ids and isinstance(data, dict): ids = [ m.get("name") or m.get("model") for m in (data.get("models") or []) diff --git a/src/ai_interaction.py b/src/ai_interaction.py index 6655beaf4..ca6e24436 100644 --- a/src/ai_interaction.py +++ b/src/ai_interaction.py @@ -134,7 +134,8 @@ def _resolve_model(spec: str, owner: Optional[str] = None) -> Tuple[str, str, Di r = httpx.get(models_url, headers=headers, timeout=5) r.raise_for_status() data = r.json() - model_ids = [m.get("id") for m in (data.get("data") or []) if m.get("id")] + items = data if isinstance(data, list) else (data.get("data") or []) + model_ids = [m.get("id") for m in items if isinstance(m, dict) and m.get("id")] if not model_ids: model_ids = [ m.get("name") or m.get("model") @@ -453,8 +454,6 @@ async def do_manage_memory(content: str, session_id: Optional[str] = None, owner return {"error": f"Unknown action '{action}'. Use: list, add, edit, delete, search"} - - # --------------------------------------------------------------------------- # RAG management tool # --------------------------------------------------------------------------- @@ -942,7 +941,9 @@ async def do_generate_image(content: str, session_id: Optional[str] = None, owne try: _r = _req.get(_ibase + "/models", timeout=3) _r.raise_for_status() - _mids = [m.get("id") for m in (_r.json().get("data") or []) if m.get("id")] + _data = _r.json() + _ditems = _data if isinstance(_data, list) else (_data.get("data") or []) + _mids = [m.get("id") for m in _ditems if isinstance(m, dict) and m.get("id")] if _mids: model_spec = _mids[0] break diff --git a/src/llm_core.py b/src/llm_core.py index 02aebffd9..7af9c2725 100644 --- a/src/llm_core.py +++ b/src/llm_core.py @@ -1468,8 +1468,10 @@ def list_model_ids( r = httpx_get_kimi_aware(models_url, h, timeout=timeout) r.raise_for_status() data = r.json() - model_ids = [m.get("id") for m in (data.get("data") or []) if m.get("id")] - if not model_ids: + # Some OpenAI-compatible APIs (e.g. Together) return a bare list here. + items = data if isinstance(data, list) else (data.get("data") or []) + model_ids = [m.get("id") for m in items if isinstance(m, dict) and m.get("id")] + if not model_ids and isinstance(data, dict): model_ids = [ m.get("name") or m.get("model") for m in (data.get("models") or []) diff --git a/src/model_discovery.py b/src/model_discovery.py index e740d6f44..4d67502c5 100644 --- a/src/model_discovery.py +++ b/src/model_discovery.py @@ -187,8 +187,10 @@ class ModelDiscovery: r = httpx.get(f"{base}/models", timeout=3) if not r.is_success: return None - data = r.json() or {} - ids = [m.get("id") for m in (data.get("data") or []) if m.get("id")] + data = r.json() + # Some OpenAI-compatible servers return a bare list, not {"data": [...]}. + items = data if isinstance(data, list) else ((data or {}).get("data") or []) + ids = [m.get("id") for m in items if isinstance(m, dict) and m.get("id")] if ids: return { "host": host,