lewtun HF Staff OpenAI Codex commited on
Commit
dc0275b
·
2 Parent(s): 21cdbc7a999dba

Deploy 2026-06-05

Browse files

Co-authored-by: OpenAI Codex <codex@openai.com>

backend/models.py CHANGED
@@ -148,7 +148,7 @@ class HealthResponse(BaseModel):
148
  class LLMHealthResponse(BaseModel):
149
  """LLM provider health check response."""
150
 
151
- status: str # "ok" | "error"
152
  model: str
153
  error: str | None = None
154
  error_type: str | None = (
 
148
  class LLMHealthResponse(BaseModel):
149
  """LLM provider health check response."""
150
 
151
+ status: str # "ok" | "error" | "skipped"
152
  model: str
153
  error: str | None = None
154
  error_type: str | None = (
backend/routes/agent.py CHANGED
@@ -51,6 +51,7 @@ from session_manager import (
51
 
52
  from agent.core.hf_access import get_jobs_access
53
  from agent.core.hf_tokens import resolve_hf_request_token
 
54
  from agent.core.llm_params import _resolve_llm_params
55
  from agent.core.model_ids import (
56
  CLAUDE_OPUS_48_MODEL_ID,
@@ -59,6 +60,7 @@ from agent.core.model_ids import (
59
  GPT_55_MODEL_ID,
60
  KIMI_K26_MODEL_ID,
61
  MINIMAX_M27_MODEL_ID,
 
62
  )
63
 
64
  logger = logging.getLogger(__name__)
@@ -144,6 +146,11 @@ def _user_hf_token(user: dict[str, Any] | None) -> str | None:
144
  return user.get(INTERNAL_HF_TOKEN_KEY)
145
 
146
 
 
 
 
 
 
147
  def _reject_oversize_dataset_upload(request: Request) -> None:
148
  raw_content_length = request.headers.get("content-length")
149
  if raw_content_length is None:
@@ -241,18 +248,28 @@ async def health_check() -> HealthResponse:
241
 
242
 
243
  @router.get("/health/llm", response_model=LLMHealthResponse)
244
- async def llm_health_check() -> LLMHealthResponse:
245
  """Check if the LLM provider is reachable and the API key is valid.
246
 
247
- Makes a minimal 1-token completion call. Catches common errors:
 
 
248
  - 401 → invalid API key
249
  - 402/insufficient_quota → out of credits
250
  - 429 → rate limited
251
  - timeout / network → provider unreachable
252
  """
253
  model = session_manager.config.model_name
 
 
 
 
254
  try:
255
- llm_params = _resolve_llm_params(model, reasoning_effort="high")
 
 
 
 
256
  await acompletion(
257
  messages=[{"role": "user", "content": "hi"}],
258
  max_tokens=1,
 
51
 
52
  from agent.core.hf_access import get_jobs_access
53
  from agent.core.hf_tokens import resolve_hf_request_token
54
+ from agent.core.local_models import local_model_provider
55
  from agent.core.llm_params import _resolve_llm_params
56
  from agent.core.model_ids import (
57
  CLAUDE_OPUS_48_MODEL_ID,
 
60
  GPT_55_MODEL_ID,
61
  KIMI_K26_MODEL_ID,
62
  MINIMAX_M27_MODEL_ID,
63
+ strip_huggingface_model_prefix,
64
  )
65
 
66
  logger = logging.getLogger(__name__)
 
146
  return user.get(INTERNAL_HF_TOKEN_KEY)
147
 
148
 
149
+ def _model_requires_hf_router_token(model_id: str | None) -> bool:
150
+ normalized = strip_huggingface_model_prefix(model_id) or model_id or ""
151
+ return local_model_provider(normalized) is None
152
+
153
+
154
  def _reject_oversize_dataset_upload(request: Request) -> None:
155
  raw_content_length = request.headers.get("content-length")
156
  if raw_content_length is None:
 
248
 
249
 
250
  @router.get("/health/llm", response_model=LLMHealthResponse)
251
+ async def llm_health_check(request: Request) -> LLMHealthResponse:
252
  """Check if the LLM provider is reachable and the API key is valid.
253
 
254
+ Makes a minimal 1-token completion call when a token is available. For
255
+ token-less HF Router requests, returns ``status="skipped"`` instead of
256
+ making an unauthenticated probe. Catches common errors:
257
  - 401 → invalid API key
258
  - 402/insufficient_quota → out of credits
259
  - 429 → rate limited
260
  - timeout / network → provider unreachable
261
  """
262
  model = session_manager.config.model_name
263
+ hf_token = resolve_hf_request_token(request)
264
+ if _model_requires_hf_router_token(model) and not hf_token:
265
+ return LLMHealthResponse(status="skipped", model=model)
266
+
267
  try:
268
+ llm_params = _resolve_llm_params(
269
+ model,
270
+ hf_token,
271
+ reasoning_effort="high",
272
+ )
273
  await acompletion(
274
  messages=[{"role": "user", "content": "hi"}],
275
  max_tokens=1,
tests/unit/test_agent_model_gating.py CHANGED
@@ -32,6 +32,75 @@ def test_default_model_for_user_is_plan_aware():
32
  assert agent._default_model_for_user({}) == agent.DEFAULT_FREE_MODEL_ID
33
 
34
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
35
  @pytest.mark.asyncio
36
  async def test_empty_session_model_uses_plan_default():
37
  assert (
 
32
  assert agent._default_model_for_user({}) == agent.DEFAULT_FREE_MODEL_ID
33
 
34
 
35
+ @pytest.mark.asyncio
36
+ async def test_llm_health_uses_request_hf_token(monkeypatch):
37
+ class Request:
38
+ headers = {"Authorization": "Bearer user-token"}
39
+ cookies = {}
40
+
41
+ resolved = []
42
+ completions = []
43
+
44
+ def fake_resolve_llm_params(
45
+ model_name,
46
+ session_hf_token=None,
47
+ reasoning_effort=None,
48
+ strict=False,
49
+ ):
50
+ resolved.append((model_name, session_hf_token, reasoning_effort, strict))
51
+ return {
52
+ "model": f"openai/{model_name}",
53
+ "api_base": "https://router.huggingface.co/v1",
54
+ "api_key": session_hf_token,
55
+ }
56
+
57
+ async def fake_acompletion(**kwargs):
58
+ completions.append(kwargs)
59
+
60
+ monkeypatch.setattr(
61
+ agent.session_manager,
62
+ "config",
63
+ SimpleNamespace(model_name=agent.DEFAULT_FREE_MODEL_ID),
64
+ )
65
+ monkeypatch.setattr(agent, "_resolve_llm_params", fake_resolve_llm_params)
66
+ monkeypatch.setattr(agent, "acompletion", fake_acompletion)
67
+
68
+ response = await agent.llm_health_check(Request())
69
+
70
+ assert response.status == "ok"
71
+ assert resolved == [(agent.DEFAULT_FREE_MODEL_ID, "user-token", "high", False)]
72
+ assert completions[0]["api_key"] == "user-token"
73
+
74
+
75
+ @pytest.mark.asyncio
76
+ async def test_llm_health_skips_router_probe_without_token(monkeypatch):
77
+ class Request:
78
+ headers = {}
79
+ cookies = {}
80
+
81
+ def fail_resolve_llm_params(*args, **kwargs):
82
+ raise AssertionError(
83
+ "health check should not resolve router params without token"
84
+ )
85
+
86
+ async def fail_acompletion(**kwargs):
87
+ raise AssertionError("health check should not call LiteLLM without token")
88
+
89
+ monkeypatch.delenv("HF_TOKEN", raising=False)
90
+ monkeypatch.setattr(
91
+ agent.session_manager,
92
+ "config",
93
+ SimpleNamespace(model_name=agent.DEFAULT_FREE_MODEL_ID),
94
+ )
95
+ monkeypatch.setattr(agent, "_resolve_llm_params", fail_resolve_llm_params)
96
+ monkeypatch.setattr(agent, "acompletion", fail_acompletion)
97
+
98
+ response = await agent.llm_health_check(Request())
99
+
100
+ assert response.status == "skipped"
101
+ assert response.model == agent.DEFAULT_FREE_MODEL_ID
102
+
103
+
104
  @pytest.mark.asyncio
105
  async def test_empty_session_model_uses_plan_default():
106
  assert (