Skip to content

Commit 282e438

Browse files
fix(llm): expand docstring and add reasoning_effort/response_format fallback coverage tests
1 parent 5c61444 commit 282e438

2 files changed

Lines changed: 44 additions & 9 deletions

File tree

lib/crewai/src/crewai/llm.py

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2373,16 +2373,21 @@ def _get_custom_llm_provider(self) -> str | None:
23732373
return None
23742374

23752375
def _validate_call_params(self) -> None:
2376-
"""
2377-
Validate parameters before making a call. Currently this only checks if
2378-
a response_format is provided and whether the model supports it.
2379-
The custom_llm_provider is dynamically determined from the model:
2380-
- E.g., "openrouter/deepseek/deepseek-chat" yields "openrouter"
2381-
- "gemini/gemini-1.5-pro" yields "gemini"
2382-
- If no slash is present, "openai" is assumed.
2376+
"""Validate call parameters before executing a completion request.
2377+
2378+
Checks whether the requested ``response_format`` is supported by the
2379+
target model/provider via LiteLLM introspection. When introspection
2380+
raises an exception (e.g. an unmapped custom model ID or proxy
2381+
endpoint), the failure is logged at DEBUG level and validation is
2382+
skipped so the request can proceed — this mirrors the permissive
2383+
fallback used in :meth:`supports_function_calling`.
2384+
2385+
When no ``response_format`` is configured (including when only
2386+
``reasoning_effort`` or other parameters are set) this method returns
2387+
immediately without performing any checks.
23832388
23842389
Note: This validation only applies to the litellm fallback path.
2385-
Native providers have their own validation.
2390+
Native providers perform their own parameter validation.
23862391
"""
23872392
if self.response_format is None:
23882393
return

lib/crewai/tests/test_llm.py

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1169,6 +1169,7 @@ async def test_non_streaming_async_returns_tool_calls_when_text_also_present():
11691169
response = _build_response_with_text_and_tool_calls()
11701170

11711171
async def _ret(*args, **kwargs):
1172+
"""Return the pre-built mock response."""
11721173
return response
11731174

11741175
with patch("crewai.llm.litellm.acompletion", side_effect=_ret):
@@ -1184,6 +1185,35 @@ def test_validate_call_params_handles_introspection_error():
11841185
llm = LLM(model="custom/unsupported-model", is_litellm=True, response_format={"type": "json_object"})
11851186

11861187
with patch("crewai.llm.supports_response_schema", side_effect=Exception("Introspection error")):
1187-
# Should not raise exception
1188+
# Should not raise exception — permissive fallback applies
11881189
llm._validate_call_params()
11891190

1191+
1192+
def test_validate_call_params_raises_for_confirmed_unsupported_model():
1193+
"""Verify _validate_call_params still raises ValueError when introspection confirms no support.
1194+
1195+
This ensures the validation path is not silently skipped — only introspection
1196+
*errors* are swallowed; a clear ``False`` return still produces a ValueError.
1197+
"""
1198+
llm = LLM(model="my-provider/my-model", is_litellm=True, response_format={"type": "json_object"})
1199+
1200+
with patch("crewai.llm.supports_response_schema", return_value=False):
1201+
with pytest.raises(ValueError, match="does not support response_format"):
1202+
llm._validate_call_params()
1203+
1204+
1205+
def test_validate_call_params_skips_check_when_no_response_format():
1206+
"""Verify _validate_call_params is a no-op when response_format is not set.
1207+
1208+
This covers scenarios where only ``reasoning_effort`` or other parameters
1209+
are configured: the method must return immediately so those parameters are
1210+
forwarded to the provider without interference.
1211+
"""
1212+
llm = LLM(model="gpt-4o", is_litellm=True, reasoning_effort="medium")
1213+
1214+
# If supports_response_schema were called, patching it to raise would surface the bug
1215+
with patch("crewai.llm.supports_response_schema", side_effect=Exception("Should not be called")):
1216+
# No exception — response_format is None so introspection is never invoked
1217+
llm._validate_call_params()
1218+
1219+

0 commit comments

Comments
 (0)