fix(crewai): guard native tool output formatting

This commit is contained in:
Vinicius Brasil
2026-06-18 22:24:51 -07:00
parent 3e74832ec9
commit 754d1a93f3
3 changed files with 23 additions and 6 deletions

View File

@@ -57,6 +57,7 @@ from crewai.utilities.agent_utils import (
convert_tools_to_openai_schema,
enforce_rpm_limit,
format_message_for_llm,
format_native_tool_output_for_agent,
get_llm_response,
handle_agent_action_core,
handle_context_length,
@@ -931,7 +932,7 @@ class CrewAgentExecutor(BaseAgentExecutor):
)
if cached_result is not None:
raw_tool_result = cached_result
result = output_tool.format_output_for_agent(cached_result)
result = format_native_tool_output_for_agent(output_tool, cached_result)
from_cache = True
agent_key = getattr(self.agent, "key", "unknown") if self.agent else "unknown"
@@ -1003,7 +1004,7 @@ class CrewAgentExecutor(BaseAgentExecutor):
tool=func_name, input=input_str, output=raw_result
)
result = output_tool.format_output_for_agent(raw_result)
result = format_native_tool_output_for_agent(output_tool, raw_result)
except Exception as e:
result = f"Error executing tool: {e}"
raw_tool_result = result

View File

@@ -80,6 +80,7 @@ from crewai.utilities.agent_utils import (
enforce_rpm_limit,
extract_tool_call_info,
format_message_for_llm,
format_native_tool_output_for_agent,
get_llm_response,
handle_agent_action_core,
handle_context_length,
@@ -1930,7 +1931,7 @@ class AgentExecutor(Flow[AgentExecutorState], BaseAgentExecutor):
)
if cached_result is not None:
raw_tool_result = cached_result
result = output_tool.format_output_for_agent(cached_result)
result = format_native_tool_output_for_agent(output_tool, cached_result)
from_cache = True
# Emit tool usage started event
@@ -1994,7 +1995,9 @@ class AgentExecutor(Flow[AgentExecutorState], BaseAgentExecutor):
tool=func_name, input=input_str, output=raw_result
)
result = output_tool.format_output_for_agent(raw_result)
result = format_native_tool_output_for_agent(
output_tool, raw_result
)
except Exception as e:
result = f"Error executing tool: {e}"
raw_tool_result = result

View File

@@ -1383,6 +1383,19 @@ class NativeToolCallResult:
tool_message: LLMMessage = field(default_factory=dict) # type: ignore[assignment]
def format_native_tool_output_for_agent(tool: Any, raw_result: Any) -> str:
"""Format native tool output when a tool explicitly defines a formatter."""
formatter = inspect.getattr_static(tool, "format_output_for_agent", None)
if formatter is None:
return str(raw_result)
runtime_formatter = getattr(tool, "format_output_for_agent", None)
if not callable(runtime_formatter):
return str(raw_result)
return str(runtime_formatter(raw_result))
def execute_single_native_tool_call(
tool_call: Any,
*,
@@ -1473,7 +1486,7 @@ def execute_single_native_tool_call(
cached_result = tools_handler.cache.read(tool=func_name, input=input_str)
if cached_result is not None:
raw_tool_result = cached_result
result = output_tool.format_output_for_agent(cached_result)
result = format_native_tool_output_for_agent(output_tool, cached_result)
from_cache = True
started_at = datetime.now()
@@ -1531,7 +1544,7 @@ def execute_single_native_tool_call(
tool=func_name, input=input_str, output=raw_result
)
result = output_tool.format_output_for_agent(raw_result)
result = format_native_tool_output_for_agent(output_tool, raw_result)
except Exception as e:
result = f"Error executing tool: {e}"
raw_tool_result = result