Lorenze/imp/native tool calling - #4258
Merged
Merged
Conversation
Added a check to ensure that if the task is None, the method returns early without attempting to access task properties. This change improves the robustness of the AgentExecutor by preventing potential errors when the task is not set.
…nt parameters Updated the Agent class to simplify the initialization of the AgentExecutor by removing unnecessary task and crew parameters in standalone mode. This change enhances code clarity and maintains backward compatibility by ensuring that the executor is correctly configured without redundant assignments.
Updated the Agent class to introduce a new private method that consolidates the common setup logic for both synchronous and asynchronous kickoff executions. This change improves code clarity and maintainability by reducing redundancy in the kickoff process, while ensuring that the agent can still execute effectively within both standalone and flow contexts.
…ecouple-executor-from-crew
Updated the test for the Agent class to ensure that the kickoff method correctly preserves parameters. The test now verifies the configuration of the agent after kickoff, enhancing clarity and maintainability. Additionally, the test for asynchronous kickoff within a flow context has been updated to reflect the Agent class instead of LiteAgent.
…dation Refactored the test for task guardrail process output to enhance the validation of the output against the OpenAPI schema. The changes include a more structured request body and updated response handling to ensure compliance with the guardrail requirements. This update aims to improve the clarity and reliability of the test cases, ensuring that task outputs are correctly validated and feedback is appropriately provided.
Refactored the Agent class to simplify the execution method by removing the event loop check and clarifying the behavior when called from synchronous and asynchronous contexts. The changes ensure that the method operates seamlessly within flow methods, improving clarity in the documentation. Additionally, updated the AgentExecutor to set the response model to None, enhancing flexibility. New test cassettes were added to validate the functionality of agents within flow contexts, ensuring robust testing for both synchronous and asynchronous operations.
…ecouple-executor-from-crew
- Introduced conditional execution for start methods in the Flow class. - Unconditional start methods are prioritized during kickoff, while conditional starts are executed only if no unconditional starts are present. - Improved handling of cyclic flows by allowing re-execution of conditional start methods triggered by routers. - Added checks to continue execution chains for completed conditional starts. These changes improve the flexibility and control of flow execution, ensuring that the correct methods are triggered based on the defined conditions.
…ecouple-executor-from-crew
…ative-tool-calling
- Updated the Agent class to automatically detect the event loop and return a coroutine when called within a Flow, simplifying async handling for users. - Modified Flow class to execute listeners sequentially, preventing race conditions on shared state during listener execution. - Improved handling of coroutine results from synchronous methods, ensuring proper execution flow and state management. These changes enhance the overall execution logic and user experience when working with agents and flows in CrewAI.
- Updated the Flow class to track fired OR listeners, ensuring that multi-source OR listeners only trigger once during execution. This prevents redundant executions and improves flow efficiency. - Cleared fired OR listeners during cyclic flow resets to allow re-execution in new cycles. - Modified the Agent class imports to include Coroutine from collections.abc, enhancing type handling for asynchronous operations. These changes improve the control and performance of flow execution in CrewAI, ensuring more predictable behavior in complex scenarios.
…ecouple-executor-from-crew
…ative-tool-calling
- Added a new function to replace invalid characters in function names with underscores, ensuring compatibility with LLM providers. - Updated the function to sanitize tool names before validation. - Modified the function to use sanitized names for tool registration. These changes improve the robustness of tool name handling, preventing potential issues with invalid characters in function names.
- Added functionality to check if a tool has reached its maximum usage count before execution in both crew_agent_executor.py and agent_executor.py. - Enhanced error handling to return a message when a tool's usage limit is reached. - Updated tool usage logic in tool_usage.py to increment usage counts and print current usage status. - Introduced tests to validate max usage count behavior for native tool calling, ensuring proper enforcement and tracking. This update improves tool management by preventing overuse and providing clear feedback when limits are reached.
Align test expectations with unified sanitize_tool_name behavior that lowercases and splits camelCase for LLM provider compatibility.
Unify tool name sanitization to ensure consistency between tool names shown to LLMs and tool name matching/lookup logic.
…c/crewAI into lorenze/imp/native-tool-calling
- Update extract_tool_call_info to return sanitized tool names - Fix delegation tool name matching to use sanitized names - Add sanitization in crew_agent_executor tool call extraction - Add sanitization in experimental agent_executor - Add sanitization in LLM.call function lookup - Update streaming utility to use sanitized names - Update base_agent_executor_mixin delegation check
…crewAIInc/crewAI into lorenze/imp/native-tool-calling
- Introduced a new YAML cassette for tracking token usage in Gemini API responses. - Updated the test for Gemini to validate token usage metrics and response content. - Ensured proper integration with the Gemini model and API key handling.
greysonlalonde
approved these changes
Jan 23, 2026
joaomdmoura
added a commit
that referenced
this pull request
Jul 26, 2026
* fix(openai): make tool calling work on the Responses API path
An agent with tools on api="responses" never produced an answer. It returned the
raw tool-call list instead:
[{'id': 'call_...', 'name': 'multiply', 'arguments': '{"a":17,"b":23}'}]
Three defects in the chain, all on the Responses side only:
1. `is_tool_call_list()` knew the OpenAI-nested, Anthropic, Bedrock and Gemini
shapes but not the Responses one ({"id", "name", "arguments"} -- no nested
"function", no "input"). The list wasn't recognized as tool calls, so the
executor handed it back verbatim as the final answer.
2. `extract_tool_call_info()` read "arguments" only from a nested "function"
object, falling back to "input". For the Responses shape both missed and the
arguments silently became {}, so the tool would have run with no input.
3. With those fixed the tool ran, then the follow-up request 400'd:
Invalid type for 'input[1].content': expected one of an array of objects
or string, but got null instead.
Tool calling is expressed differently by the two APIs. Chat Completions uses an
assistant message carrying `tool_calls` with content: None, then role: "tool"
results. The Responses API uses flat function_call / function_call_output items
keyed by call_id. Those messages were passed through untranslated.
`_to_responses_input()` now converts them. Messages without tool calls pass
through unchanged, so nothing else moves.
Verified end to end against the live API:
api="responses" + tools -> 391 (was raw tool-call JSON)
chained multi-step tool calls -> 400 (17*23, then +9)
completions path (control) -> 391 (unchanged)
The generated `input` payload was also posted to /v1/responses directly and
accepted, and the pre-fix chat-shaped payload confirmed as a 400.
This is why api="responses" never worked for agents: the provider side has had a
full Responses implementation since #4258/c4c9208, but the executor never learned
the shape it emits. Fixing it also unblocks routing gpt-5.4+ tool calls to the
Responses API instead of dropping reasoning_effort.
Tests: 12 cases covering recognition, extraction (including that the Chat
Completions and Bedrock shapes are unaffected), translation of assistant/tool
messages, parallel calls, assistant text alongside tool calls, non-string tool
output, and the full prepared `input` list.
* fix(openai): prefer Responses "call_id" over the item's own "id"
Per CodeRabbit review. A raw Responses function_call item carries both keys with
different values, confirmed against the live API:
keys ['arguments', 'call_id', 'id', 'name', 'status', 'type']
id fc_0adeb715c5d740c7006a65ccb72b948199872ad8b5a5c53108
call_id call_dEoHFrYnOgWYvk17FymdcDZ5
function_call_output must reference call_id. Reading the item's own "id" would
produce a tool result the model can't correlate back to its invocation.
Our own _extract_function_calls_from_response already maps item.call_id into "id",
so the normal path was correct and the existing tests passed. But
extract_tool_call_info is a shared helper reached from every provider's tool loop,
and a raw Responses item is a plausible thing to hand it -- silently picking the
wrong identifier is a bad trap to leave in place for one line of guard.
Tests: raw item extraction asserting call_id is chosen over id, and a round-trip
check that the id extracted from a call is the one sent back with its result.
997 passed across tests/llms, test_agent_utils and tests/agents (1 pre-existing
unrelated failure from a local OLLAMA_API_KEY env leak). Real two-agent chained-tool
run still returns the correct answer.
---------
Co-authored-by: João Moura <joaomdmoura@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.