mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-25 01:02:15 +00:00
fix(health_check): skip max_tokens for image_generation mode
`_update_litellm_params_for_health_check` injected `max_tokens` for every deployment. OpenAI `/v1/images/generations` strictly rejects unknown fields, so health checks for dall-e-* and gpt-image-1 always failed with `400 "Unknown parameter: 'max_tokens'"` even though the actual image endpoint calls succeed. Skip the `max_tokens` injection when `model_info.mode == "image_generation"`. `messages` still gets injected (downstream `_filter_model_params` already strips it for non-chat handlers).
This commit is contained in:
parent
0992bf2271
commit
83b5252d69
2 changed files with 66 additions and 3 deletions
|
|
@ -362,14 +362,21 @@ def _update_litellm_params_for_health_check(
|
|||
Update the litellm params for health check.
|
||||
|
||||
- gets a short `messages` param for health check
|
||||
- adds a bounded `max_tokens`, except when
|
||||
`model_info.mode == "image_generation"` — OpenAI
|
||||
`/v1/images/generations` rejects unknown fields with
|
||||
400 "Unknown parameter: 'max_tokens'".
|
||||
- updates the `model` param with the `health_check_model` if it exists Doc: https://docs.litellm.ai/docs/proxy/health#wildcard-routes
|
||||
- updates the `voice` param with the `health_check_voice` for `audio_speech` mode if it exists Doc: https://docs.litellm.ai/docs/proxy/health#text-to-speech-models
|
||||
- for Bedrock models with region routing (bedrock/region/model), strips the litellm routing prefix but preserves the model ID
|
||||
"""
|
||||
litellm_params["messages"] = _get_random_llm_message()
|
||||
_resolved_max_tokens = _resolve_health_check_max_tokens(model_info, litellm_params)
|
||||
if _resolved_max_tokens is not None:
|
||||
litellm_params["max_tokens"] = _resolved_max_tokens
|
||||
if model_info.get("mode", None) != "image_generation":
|
||||
_resolved_max_tokens = _resolve_health_check_max_tokens(
|
||||
model_info, litellm_params
|
||||
)
|
||||
if _resolved_max_tokens is not None:
|
||||
litellm_params["max_tokens"] = _resolved_max_tokens
|
||||
|
||||
_health_check_model = model_info.get("health_check_model", None)
|
||||
if _health_check_model is not None:
|
||||
|
|
|
|||
|
|
@ -225,3 +225,59 @@ def test_wildcard_ignores_reasoning_split_model_info(monkeypatch):
|
|||
litellm_params = {"model": "openai/*"}
|
||||
|
||||
assert _resolve_health_check_max_tokens(model_info, litellm_params) is None
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# image_generation must not receive max_tokens.
|
||||
#
|
||||
# _update_litellm_params_for_health_check injected `max_tokens` for every
|
||||
# deployment. For `mode: image_generation` that leaked into OpenAI
|
||||
# `/v1/images/generations`, which strictly rejects unknown fields with
|
||||
# `400 "Unknown parameter: 'max_tokens'"`, marking dall-e-* and
|
||||
# gpt-image-1 as permanently unhealthy even though their actual image
|
||||
# calls succeed. `messages` still gets injected (downstream
|
||||
# `_filter_model_params` already strips it for non-chat handlers).
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
def test_image_generation_mode_skips_max_tokens():
|
||||
"""image_generation must not receive max_tokens."""
|
||||
model_info = {"mode": "image_generation"}
|
||||
litellm_params = {"model": "openai/dall-e-3", "api_key": "sk-test"}
|
||||
|
||||
updated = _update_litellm_params_for_health_check(model_info, litellm_params)
|
||||
|
||||
assert "max_tokens" not in updated
|
||||
# connection-level params must still pass through unchanged
|
||||
assert updated["api_key"] == "sk-test"
|
||||
|
||||
|
||||
def test_image_generation_ignores_explicit_health_check_max_tokens():
|
||||
"""Even an explicit `health_check_max_tokens` override must not be
|
||||
forwarded to image endpoints — the field is invalid there."""
|
||||
model_info = {"mode": "image_generation", "health_check_max_tokens": 50}
|
||||
litellm_params = {"model": "openai/dall-e-3"}
|
||||
|
||||
updated = _update_litellm_params_for_health_check(model_info, litellm_params)
|
||||
|
||||
assert "max_tokens" not in updated
|
||||
|
||||
|
||||
def test_chat_mode_still_injects_max_tokens():
|
||||
"""Regression guard: the chat-style probe payload is unchanged."""
|
||||
model_info = {"mode": "chat"}
|
||||
litellm_params = {"model": "gpt-4"}
|
||||
|
||||
updated = _update_litellm_params_for_health_check(model_info, litellm_params)
|
||||
|
||||
assert updated["max_tokens"] == 5
|
||||
|
||||
|
||||
def test_no_mode_still_injects_max_tokens():
|
||||
"""Regression guard: model_info without `mode` keeps the legacy path."""
|
||||
model_info: dict = {}
|
||||
litellm_params = {"model": "gpt-4"}
|
||||
|
||||
updated = _update_litellm_params_for_health_check(model_info, litellm_params)
|
||||
|
||||
assert updated["max_tokens"] == 5
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue