diff --git a/routes/model_routes.py b/routes/model_routes.py index be17f14aa..49594505f 100644 --- a/routes/model_routes.py +++ b/routes/model_routes.py @@ -424,6 +424,31 @@ def _ping_endpoint(base_url: str, api_key: str = None, timeout: float = 1.5) -> return {"reachable": False, "status_code": None, "error": last_error} + +def _model_endpoint_error_message(base_url: str, ping: Dict[str, Any] = None) -> str: + """Return a provider-aware error message for failed endpoint probes.""" + ping = ping or {} + error = ping.get("error") + parsed = urlparse(base_url) + host = (parsed.hostname or "").lower() + is_ollama = parsed.port == 11434 or "ollama" in host or "ollama" in base_url.lower() + + if is_ollama: + parts = ["No Ollama models found for that endpoint."] + if error: + parts.append(f"Last probe error: {error}.") + parts.append("Check that Ollama is running and that the base URL is correct.") + parts.append("For native/local installs, use http://localhost:11434/v1.") + parts.append("For Docker, use http://host.docker.internal:11434/v1 when Ollama runs on the host.") + parts.append("Run `ollama list` to confirm at least one model is installed.") + return " ".join(parts) + + if error: + return f"No models found for that provider/key. Last probe error: {error}." + + return "No models found for that provider/key." + + def setup_model_routes(model_discovery): router = APIRouter(prefix="/api") @@ -999,7 +1024,7 @@ def setup_model_routes(model_discovery): if should_probe and not model_ids: ping = _ping_endpoint(base_url, api_key.strip() or None, timeout=_probe_timeout) if require_model_list and not model_ids: - raise HTTPException(400, "No models found for that provider/key") + raise HTTPException(400, _model_endpoint_error_message(base_url, ping)) ep_id = str(uuid.uuid4())[:8] db = SessionLocal() diff --git a/tests/test_model_routes.py b/tests/test_model_routes.py index f6b276d55..fd8de0b21 100644 --- a/tests/test_model_routes.py +++ b/tests/test_model_routes.py @@ -296,3 +296,23 @@ class TestSetupProbeSafety: monkeypatch.setattr(model_routes.httpx, "get", fake_get) assert _probe_endpoint("https://api.anthropic.com/v1") == ANTHROPIC_MODELS + +def test_ollama_endpoint_error_message_includes_troubleshooting(): + msg = model_routes._model_endpoint_error_message( + "http://localhost:11434/v1", + {"error": "Connection refused"}, + ) + + assert "No Ollama models found" in msg + assert "Connection refused" in msg + assert "http://localhost:11434/v1" in msg + assert "ollama list" in msg + + +def test_generic_endpoint_error_message_preserves_probe_error(): + msg = model_routes._model_endpoint_error_message( + "https://api.example.com/v1", + {"error": "HTTP 401"}, + ) + + assert msg == "No models found for that provider/key. Last probe error: HTTP 401."