Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions lib/crewai/src/crewai/llm.py
Original file line number Diff line number Diff line change
Expand Up @@ -706,6 +706,7 @@ def _prepare_completion_params(
"stream": self.stream,
"tools": tools,
"reasoning_effort": self.reasoning_effort,
"thinking": self.thinking,
**self.additional_params,
}

Expand Down
25 changes: 25 additions & 0 deletions lib/crewai/tests/test_llm.py
Original file line number Diff line number Diff line change
Expand Up @@ -1196,3 +1196,28 @@ async def _ret(*args, **kwargs):
assert isinstance(result, list)
assert len(result) == 1
assert result[0].function.name == "search"


def test_thinking_param_included_in_completion_params():
"""Verify that the `thinking` field is forwarded to litellm completion params.

Regression test for: https://github.com/crewAIInc/crewAI/issues/5537
The `thinking` field was defined on LLM but never added to the params dict
built by _prepare_completion_params, causing it to be silently dropped for
OpenRouter (and other non-Anthropic) providers.
"""
thinking_config = {"type": "enabled", "budget_tokens": 5000}
llm = LLM(
model="openrouter/anthropic/claude-sonnet-4-5",
thinking=thinking_config,
is_litellm=True,
)

params = llm._prepare_completion_params(
messages=[{"role": "user", "content": "Hello"}]
)

assert params.get("thinking") == thinking_config, (
"The 'thinking' field must be forwarded to the LiteLLM completion params "
"so that OpenRouter and other compatible providers can enable extended thinking."
)