Skip to content

Fix #5878: Preserve reasoning_content from DeepSeek thinking mode in conversation history#5880

Open
devin-ai-integration[bot] wants to merge 3 commits into
mainfrom
devin/1779340749-fix-reasoning-content-5878
Open

Fix #5878: Preserve reasoning_content from DeepSeek thinking mode in conversation history#5880
devin-ai-integration[bot] wants to merge 3 commits into
mainfrom
devin/1779340749-fix-reasoning-content-5878

Conversation

@devin-ai-integration
Copy link
Copy Markdown
Contributor

@devin-ai-integration devin-ai-integration Bot commented May 21, 2026

Summary

Fixes #5878. DeepSeek V4 models return reasoning_content alongside content in thinking mode. The DeepSeek API requires this reasoning_content to be passed back in subsequent API calls for multi-turn conversations. Previously, CrewAI discarded reasoning_content from LLM responses, causing DeepSeek API errors in multi-turn conversations.

This PR:

  1. Extracts reasoning_content from the litellm response in LLM._handle_non_streaming_response() and stores it on the LLM instance
  2. Resets reasoning_content at the start of each LLM.call() to avoid stale values
  3. Propagates reasoning_content into assistant messages via format_message_for_llm(), _append_message(), and _append_message_to_state()
  4. Adds reasoning_content as an optional field on LLMMessage TypedDict

Files changed:

  • lib/crewai/src/crewai/llm.py — extract + store reasoning_content
  • lib/crewai/src/crewai/utilities/types.py — add field to LLMMessage
  • lib/crewai/src/crewai/utilities/agent_utils.py — format_message_for_llm now accepts reasoning_content
  • lib/crewai/src/crewai/agents/crew_agent_executor.py — propagate in all sync/async loops
  • lib/crewai/src/crewai/experimental/agent_executor.py — propagate in native tools path
  • lib/crewai/tests/llms/litellm/test_reasoning_content.py — 13 new tests

Review & Testing Checklist for Human

  • Verify that reasoning_content is correctly extracted from a real DeepSeek API response (the mock tests verify the extraction logic, but a manual test with deepseek/deepseek-reasoner would confirm end-to-end)
  • Check that normal models (GPT-4o, Claude, etc.) are unaffected — reasoning_content should be None and assistant messages should not contain the field
  • Confirm the reasoning_content field in LLMMessage TypedDict doesn't break any downstream serialization or message processing

Notes

  • The fix uses a dual extraction approach (getattr + .get()) to handle both attribute-style and dict-style access patterns from litellm's Message object
  • reasoning_content is only added to assistant messages (not user/system) per the DeepSeek API specification
  • The CrewAgentExecutor is deprecated but still receives the fix for backward compatibility; the experimental AgentExecutor is also updated
  • Supersedes Fix #5878: Preserve reasoning_content from DeepSeek thinking mode in conversation history #5879 which had merge conflicts due to the monorepo restructuring

Link to Devin session: https://app.devin.ai/sessions/584ca5a82022414490972068929d4d53

Summary by CodeRabbit

  • New Features

    • Capture and preserve AI model "reasoning" content in assistant messages so conversation history reflects model explanations.
    • Ensure reasoning content is included only for assistant outputs and is reset between model calls.
  • Tests

    • Added tests covering extraction, storage, formatting rules, and propagation of reasoning content through agent execution.

Review Change Stack

Extract reasoning_content from litellm response and store it on the
LLM instance so that executors can propagate it into conversation
history as required by the DeepSeek API.

Changes:
- LLM._handle_non_streaming_response: extract reasoning_content from
  the response message and store it as self.reasoning_content
- LLM.call: reset reasoning_content at the start of each call
- format_message_for_llm: accept optional reasoning_content param;
  include it in assistant messages only
- LLMMessage TypedDict: add reasoning_content field
- CrewAgentExecutor: pass reasoning_content through _append_message
  for both sync and async loops (ReAct + native tools)
- AgentExecutor (experimental): same propagation in
  _append_message_to_state for native tools path

Tests: 13 new tests covering LLM extraction, format_message_for_llm,
and executor integration.

Co-Authored-By: João <joao@crewai.com>
@devin-ai-integration
Copy link
Copy Markdown
Contributor Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment and CI monitoring

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 21, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: a636db4b-8be0-4780-b30a-3bbf96471aad

📥 Commits

Reviewing files that changed from the base of the PR and between d93040e and ce4399e.

📒 Files selected for processing (3)
  • lib/crewai/src/crewai/agents/crew_agent_executor.py
  • lib/crewai/src/crewai/experimental/agent_executor.py
  • lib/crewai/src/crewai/llm.py

📝 Walkthrough

Walkthrough

This PR adds end-to-end support for capturing and propagating LLM reasoning_content (from DeepSeek thinking mode) through agent execution flows. The LLM layer extracts reasoning from responses, executors retrieve it via a new helper, and message formatting conditionally includes it in assistant messages.

Changes

Reasoning Content Propagation

Layer / File(s) Summary
Type contracts and messaging infrastructure
lib/crewai/src/crewai/utilities/types.py, lib/crewai/src/crewai/utilities/agent_utils.py
LLMMessage TypedDict adds optional reasoning_content: NotRequired[str | None] field; format_message_for_llm() signature extends to accept optional reasoning_content parameter and includes it in returned message dict when role is "assistant".
LLM response handling
lib/crewai/src/crewai/llm.py
LLM.call() initializes self.reasoning_content = None at invocation start; _handle_non_streaming_response() extracts reasoning_content from response messages (via attribute or dict-style access) and stores it in self.reasoning_content.
CrewAgentExecutor reasoning propagation
lib/crewai/src/crewai/agents/crew_agent_executor.py
New _get_llm_reasoning_content() helper reads reasoning_content from the configured LLM; _append_message() signature extended with optional reasoning_content parameter forwarded to format_message_for_llm(); applied across synchronous and asynchronous execution loops in ReAct and native tool-calling paths.
Experimental AgentExecutor reasoning propagation
lib/crewai/src/crewai/experimental/agent_executor.py
New _get_llm_reasoning_content() helper; _append_message_to_state() signature extended with optional reasoning_content parameter; applied in native tool-calling response paths for BaseModel, string, and unexpected outputs.
Test coverage
lib/crewai/tests/llms/litellm/test_reasoning_content.py
New test module with three test classes: TestLLMReasoningContent verifies extraction and reset behavior; TestFormatMessageReasoningContent validates conditional inclusion based on role; TestCrewExecutorReasoningContent ensures propagation through executor invoke loops with reasoning preserved for DeepSeek-style models and omitted for normal models.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested labels

enhancement

Suggested reviewers

  • greysonlalonde

Poem

🐰 I tunneled through code to catch the thought,
Collected DeepSeek whispers that models brought.
Now messages carry the mind's quiet art,
From LLM to history, reasoning plays its part.
Hooray — the crew keeps every thinking heart.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 65.63% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the issue being fixed (#5878) and describes the main change: preserving reasoning_content from DeepSeek thinking mode in conversation history.
Linked Issues check ✅ Passed The PR successfully implements all coding requirements from #5878: extracts and stores reasoning_content from LLM responses, resets it between calls, propagates it through message history for assistant messages, updates LLMMessage TypedDict, and handles multi-turn conversations.
Out of Scope Changes check ✅ Passed All changes are directly aligned with the linked issue #5878 requirements. Modifications to LLM extraction, message formatting, and executor propagation are all in-scope, plus comprehensive test coverage.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch devin/1779340749-fix-reasoning-content-5878

Comment @coderabbitai help to get the list of available commands and usage tips.

@ZangXincz
Copy link
Copy Markdown

Could you provide an example of a working Python code?

from typing import Any
from unittest.mock import MagicMock, patch

import pytest
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
lib/crewai/src/crewai/agents/crew_agent_executor.py (1)

531-557: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Preserve reasoning_content for native tool-call turns too.

reasoning_content is only propagated for terminal assistant responses in these branches. When the model returns tool calls, the assistant tool-call message path still omits reasoning_content, so that turn’s reasoning is lost before the next request.

Suggested fix
@@
-    def _append_assistant_tool_calls_message(
-        self,
-        parsed_calls: list[tuple[str, str, str | dict[str, Any]]],
-    ) -> None:
+    def _append_assistant_tool_calls_message(
+        self,
+        parsed_calls: list[tuple[str, str, str | dict[str, Any]]],
+        reasoning_content: str | None = None,
+    ) -> None:
@@
         assistant_message: LLMMessage = {
             "role": "assistant",
             "content": None,
@@
         }
+        if reasoning_content is not None:
+            assistant_message["reasoning_content"] = reasoning_content
         self.messages.append(assistant_message)
@@
-                self._append_assistant_tool_calls_message(
+                self._append_assistant_tool_calls_message(
                     [
                         (call_id, func_name, func_args)
                         for call_id, func_name, func_args, _ in execution_plan
-                    ]
+                    ],
+                    reasoning_content=self._get_llm_reasoning_content(),
                 )
@@
-        self._append_assistant_tool_calls_message([(call_id, func_name, func_args)])
+        self._append_assistant_tool_calls_message(
+            [(call_id, func_name, func_args)],
+            reasoning_content=self._get_llm_reasoning_content(),
+        )

Also applies to: 1348-1375

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/crewai/src/crewai/agents/crew_agent_executor.py` around lines 531 - 557,
The code currently only attaches reasoning_content for terminal assistant
responses; update the branches that create assistant/tool-call turns so they
also capture reasoning = self._get_llm_reasoning_content() and pass
reasoning_content=reasoning into _append_message (and keep calling
_invoke_step_callback(formatted_answer) and _show_logs as before) for all paths
that construct formatted_answer (including the BaseModel branch and native
tool-call branches), ensuring the same pattern is applied where assistant/tool
messages are emitted (see functions/methods: _get_llm_reasoning_content,
_invoke_step_callback, _append_message, _show_logs and classes/values:
AgentFinish, BaseModel; also apply the same change to the other occurrence
around the 1348-1375 region).
lib/crewai/tests/llms/litellm/test_reasoning_content.py (1)

1-268: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Formatting check is failing in CI.

uv run ruff format --check lib/ is currently failing for this PR. Please run formatter and commit the resulting changes so lint passes.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/crewai/tests/llms/litellm/test_reasoning_content.py` around lines 1 -
268, Formatting check failing in CI because the file
lib/crewai/tests/llms/litellm/test_reasoning_content.py (and possibly other
files under lib/) is not formatted; run the project's formatter and commit the
results: execute the formatter command used by CI (e.g., `uv run ruff format
--check lib/` to verify, then `uv run ruff format lib/` or the repo's preferred
formatting command), stage and commit the updated files (including
test_reasoning_content.py) so the lint/format check passes; no code logic
changes required—only apply and commit the formatter's edits.
🧹 Nitpick comments (1)
lib/crewai/tests/llms/litellm/test_reasoning_content.py (1)

236-243: ⚡ Quick win

Make invoke-loop assertions order-independent.

Both tests currently assert on assistant_msgs[0], which can become flaky if assistant message ordering changes while behavior remains correct. Assert with any(...) / all(...) over assistant messages instead.

Proposed diff
@@
-        assert len(assistant_msgs) >= 1
-        assert (
-            assistant_msgs[0].get("reasoning_content")
-            == "Let me reason step by step..."
-        )
+        assert assistant_msgs
+        assert any(
+            m.get("reasoning_content") == "Let me reason step by step..."
+            for m in assistant_msgs
+        )
@@
-        assert len(assistant_msgs) >= 1
-        assert "reasoning_content" not in assistant_msgs[0]
+        assert assistant_msgs
+        assert all("reasoning_content" not in m for m in assistant_msgs)

Also applies to: 263-267

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/crewai/tests/llms/litellm/test_reasoning_content.py` around lines 236 -
243, The assertions that check assistant_msgs[0].get("reasoning_content") are
order-dependent and flaky; update the tests to assert order-independently by
replacing checks on assistant_msgs[0] with a membership-style assertion using
any(...) (e.g., assert any(m.get("reasoning_content") == "Let me reason step by
step..." for m in assistant_msgs)) and do the same for the other occurrence (the
block around lines 263-267) so both tests verify that at least one assistant
message contains the expected reasoning_content instead of assuming it is the
first message.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@lib/crewai/src/crewai/agents/crew_agent_executor.py`:
- Around line 1492-1509: The file fails the project's formatter; run the
configured formatter (ruff format / black as configured) or apply the project's
formatting rules to this function (_append_message) and nearby calls to
format_message_for_llm so the file matches ruff/black expectations; specifically
reformat the signature, docstring and the self.messages.append(...) call to
match the repo's style, then re-run ruff format --check to verify the CI issue
is resolved.

In `@lib/crewai/src/crewai/experimental/agent_executor.py`:
- Around line 1333-1344: Final-answer branch only sets reasoning_content;
tool-call branches skip it causing loss of reasoning. Update the branches that
handle LLM tool calls so that when creating and appending the assistant
tool-call message and when setting state for tool-invocation you also call
_get_llm_reasoning_content() and pass that reasoning_content into
_append_message_to_state (and any AgentAction/assistant tool-call constructors)
just like the AgentFinish path does; look for usages in methods around
_get_llm_reasoning_content, _append_message_to_state, AgentFinish and
AgentAction/assistant tool-call creation and ensure every path that adds an
assistant/tool message forwards the reasoning_content parameter.
- Around line 2824-2841: The file fails ruff formatting; run the project
formatter on the affected function _append_message_to_state (and surrounding
block) so it matches the repository's style (e.g., run ruff format or the
configured formatter/formatter config) and ensure the call to
format_message_for_llm stays properly indented and wrapped to satisfy ruff/black
rules; after formatting, re-run ruff format --check to confirm the file
(including _append_message_to_state and its use of format_message_for_llm) no
longer reports changes.

In `@lib/crewai/src/crewai/llm.py`:
- Around line 1236-1243: The async code path doesn't reset or extract
reasoning_content like the sync path does, causing stale values; update acall()
and _ahandle_non_streaming_response() to mirror the sync logic used in call() by
resetting self.reasoning_content before the call and extracting
reasoning_content from response_message (using getattr(response_message,
"reasoning_content", None) or response_message.get("reasoning_content") if it
has get) after receiving the non-streaming response so async flows receive the
same reasoning_content handling as sync flows.

In `@lib/crewai/src/crewai/utilities/types.py`:
- Line 30: The file contains a ruff formatting violation around the type
declaration reasoning_content: NotRequired[str | None]; run the ruff formatter
(uv run ruff format) to reformat the code and commit the resulting changes so CI
passes, ensuring the declaration for reasoning_content and surrounding
imports/whitespace follow the project's ruff style rules.

---

Outside diff comments:
In `@lib/crewai/src/crewai/agents/crew_agent_executor.py`:
- Around line 531-557: The code currently only attaches reasoning_content for
terminal assistant responses; update the branches that create
assistant/tool-call turns so they also capture reasoning =
self._get_llm_reasoning_content() and pass reasoning_content=reasoning into
_append_message (and keep calling _invoke_step_callback(formatted_answer) and
_show_logs as before) for all paths that construct formatted_answer (including
the BaseModel branch and native tool-call branches), ensuring the same pattern
is applied where assistant/tool messages are emitted (see functions/methods:
_get_llm_reasoning_content, _invoke_step_callback, _append_message, _show_logs
and classes/values: AgentFinish, BaseModel; also apply the same change to the
other occurrence around the 1348-1375 region).

In `@lib/crewai/tests/llms/litellm/test_reasoning_content.py`:
- Around line 1-268: Formatting check failing in CI because the file
lib/crewai/tests/llms/litellm/test_reasoning_content.py (and possibly other
files under lib/) is not formatted; run the project's formatter and commit the
results: execute the formatter command used by CI (e.g., `uv run ruff format
--check lib/` to verify, then `uv run ruff format lib/` or the repo's preferred
formatting command), stage and commit the updated files (including
test_reasoning_content.py) so the lint/format check passes; no code logic
changes required—only apply and commit the formatter's edits.

---

Nitpick comments:
In `@lib/crewai/tests/llms/litellm/test_reasoning_content.py`:
- Around line 236-243: The assertions that check
assistant_msgs[0].get("reasoning_content") are order-dependent and flaky; update
the tests to assert order-independently by replacing checks on assistant_msgs[0]
with a membership-style assertion using any(...) (e.g., assert
any(m.get("reasoning_content") == "Let me reason step by step..." for m in
assistant_msgs)) and do the same for the other occurrence (the block around
lines 263-267) so both tests verify that at least one assistant message contains
the expected reasoning_content instead of assuming it is the first message.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: d71c2bc0-5ede-4e8d-b62d-1cdcc3a1feb8

📥 Commits

Reviewing files that changed from the base of the PR and between 418afd2 and d93040e.

📒 Files selected for processing (6)
  • lib/crewai/src/crewai/agents/crew_agent_executor.py
  • lib/crewai/src/crewai/experimental/agent_executor.py
  • lib/crewai/src/crewai/llm.py
  • lib/crewai/src/crewai/utilities/agent_utils.py
  • lib/crewai/src/crewai/utilities/types.py
  • lib/crewai/tests/llms/litellm/test_reasoning_content.py

Comment thread lib/crewai/src/crewai/agents/crew_agent_executor.py
Comment on lines +1333 to +1344
reasoning = self._get_llm_reasoning_content()

if isinstance(answer, BaseModel):
self.state.current_answer = AgentFinish(
thought="",
output=answer,
text=answer.model_dump_json(),
)
self._invoke_step_callback(self.state.current_answer)
self._append_message_to_state(answer.model_dump_json())
self._append_message_to_state(
answer.model_dump_json(), reasoning_content=reasoning
)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Tool-call responses still lose reasoning_content in native flow.

This propagation only covers final-answer branches. If the LLM returns tool calls, routing exits before using reasoning_content, and the assistant tool-call message later added to state does not include it.

Suggested fix
@@
-            # Check if the response is a list of tool calls
+            reasoning = self._get_llm_reasoning_content()
+
+            # Check if the response is a list of tool calls
             if isinstance(answer, list) and answer and self._is_tool_call_list(answer):
                 # Store tool calls for sequential processing
                 self.state.pending_tool_calls = list(answer)
                 return "native_tool_calls"
-
-            reasoning = self._get_llm_reasoning_content()
@@
         if tool_calls_to_report:
             assistant_message: LLMMessage = {
                 "role": "assistant",
                 "content": None,
                 "tool_calls": tool_calls_to_report,
             }
+            reasoning = self._get_llm_reasoning_content()
+            if reasoning is not None:
+                assistant_message["reasoning_content"] = reasoning
             if all(type(tc).__qualname__ == "Part" for tc in pending_tool_calls):
                 assistant_message["raw_tool_call_parts"] = list(pending_tool_calls)
             self.state.messages.append(assistant_message)

Also applies to: 1355-1367

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/crewai/src/crewai/experimental/agent_executor.py` around lines 1333 -
1344, Final-answer branch only sets reasoning_content; tool-call branches skip
it causing loss of reasoning. Update the branches that handle LLM tool calls so
that when creating and appending the assistant tool-call message and when
setting state for tool-invocation you also call _get_llm_reasoning_content() and
pass that reasoning_content into _append_message_to_state (and any
AgentAction/assistant tool-call constructors) just like the AgentFinish path
does; look for usages in methods around _get_llm_reasoning_content,
_append_message_to_state, AgentFinish and AgentAction/assistant tool-call
creation and ensure every path that adds an assistant/tool message forwards the
reasoning_content parameter.

Comment thread lib/crewai/src/crewai/experimental/agent_executor.py
Comment on lines +1236 to +1243
# Store reasoning_content for models that return it (e.g. DeepSeek thinking mode)
self.reasoning_content = getattr(
response_message, "reasoning_content", None
) or (
response_message.get("reasoning_content")
if hasattr(response_message, "get")
else None
)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Async path is missing reasoning_content reset/extraction parity.

Line 1754 resets state only in call(), and Lines 1236-1243 extract only in sync non-streaming. acall() / _ahandle_non_streaming_response() currently don’t mirror this, so async flows can miss new reasoning_content or carry stale values across turns.

Suggested parity patch
@@
     async def _ahandle_non_streaming_response(
@@
         response_message = cast(Choices, cast(ModelResponse, response).choices)[
             0
         ].message
         text_response = response_message.content or ""
+
+        # Store reasoning_content for models that return it (e.g. DeepSeek thinking mode)
+        self.reasoning_content = getattr(
+            response_message, "reasoning_content", None
+        ) or (
+            response_message.get("reasoning_content")
+            if hasattr(response_message, "get")
+            else None
+        )
@@
     async def acall(
@@
-        with llm_call_context() as call_id:
+        self.reasoning_content: str | None = None
+        with llm_call_context() as call_id:

Also applies to: 1754-1754

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/crewai/src/crewai/llm.py` around lines 1236 - 1243, The async code path
doesn't reset or extract reasoning_content like the sync path does, causing
stale values; update acall() and _ahandle_non_streaming_response() to mirror the
sync logic used in call() by resetting self.reasoning_content before the call
and extracting reasoning_content from response_message (using
getattr(response_message, "reasoning_content", None) or
response_message.get("reasoning_content") if it has get) after receiving the
non-streaming response so async flows receive the same reasoning_content
handling as sync flows.

name: NotRequired[str]
tool_calls: NotRequired[list[dict[str, Any]]]
raw_tool_call_parts: NotRequired[list[Any]]
reasoning_content: NotRequired[str | None]
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Fix ruff formatting before merge (CI is failing).

Pipeline is failing on uv run ruff format --check lib/. Please run formatter and commit the result to unblock merge.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/crewai/src/crewai/utilities/types.py` at line 30, The file contains a
ruff formatting violation around the type declaration reasoning_content:
NotRequired[str | None]; run the ruff formatter (uv run ruff format) to reformat
the code and commit the resulting changes so CI passes, ensuring the declaration
for reasoning_content and surrounding imports/whitespace follow the project's
ruff style rules.

Co-Authored-By: João <joao@crewai.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEATURE]The latest version of DeepSeek is incompatible with reasoning_content.

1 participant