refactor: Improve backtick stripping and test coverage

- Extract backtick stripping to _clean_tool_result method
- Add docstrings explaining the backtick cleaning logic
- Add parameterized tests for various backtick scenarios

Co-Authored-By: Joe Moura <joao@crewai.com>
This commit is contained in:
Devin AI
2025-02-12 10:56:42 +00:00
parent 4073d9a103
commit c8bb9561ce
2 changed files with 35 additions and 9 deletions

View File

@@ -372,14 +372,29 @@ class CrewAgentExecutor(CrewAgentExecutorMixin):
name.casefold().strip() for name in self.tool_name_to_tool_map
]:
tool_result = tool_usage.use(tool_calling, agent_action.text)
# Strip any trailing backticks from tool result
if isinstance(tool_result, str):
tool_result = tool_result.rstrip('`')
tool_result = self._clean_tool_result(tool_result)
tool = self.tool_name_to_tool_map.get(tool_calling.tool_name)
if tool:
return ToolResult(
result=tool_result, result_as_answer=tool.result_as_answer
)
def _clean_tool_result(self, tool_result: Any) -> Any:
"""Clean tool result by removing trailing backticks.
This is particularly important in hierarchical mode where tool outputs
might contain markdown formatting that needs to be cleaned up.
Args:
tool_result: The result from a tool execution, can be any type
Returns:
The cleaned result with any trailing backticks removed if it's a string,
otherwise returns the original result unchanged
"""
if isinstance(tool_result, str):
return tool_result.rstrip('`').rstrip('```')
return tool_result
else:
tool_result = self._i18n.errors("wrong_tool_name").format(
tool=tool_calling.tool_name,

View File

@@ -317,14 +317,26 @@ def test_sync_task_execution():
@pytest.mark.vcr(filter_headers=["authorization"])
def test_hierarchical_tool_output_formatting():
"""Test that tool outputs in hierarchical mode don't have extra backticks"""
@pytest.mark.parametrize("tool_output,expected", [
("test result```", "test result"),
("test result`", "test result"),
("test result``````", "test result"),
("test result", "test result"),
("test ```result```", "test ```result"), # Only strip trailing backticks
])
def test_hierarchical_tool_output_formatting(tool_output, expected):
"""Test that tool outputs in hierarchical mode don't have extra backticks.
This test verifies that the tool output cleaning functionality correctly handles
various scenarios of backtick formatting, ensuring only trailing backticks are
removed while preserving any inline markdown formatting.
"""
class TestTool(BaseTool):
name: str = "test_tool"
description: str = "A test tool"
def _run(self, *args: Any, **kwargs: Any) -> str:
return "test result```" # Intentionally add backticks to test stripping
return tool_output
task = Task(
description="Test task using test_tool",
@@ -341,13 +353,12 @@ def test_hierarchical_tool_output_formatting():
with patch.object(Task, 'execute_sync', return_value=TaskOutput(
description="Test task",
raw="test result",
raw=expected,
agent="researcher"
)) as mock_execute_sync:
result = crew.kickoff()
assert mock_execute_sync.called
assert not result.raw.endswith('```')
assert '```\n```' not in result.raw
assert result.raw == expected
@pytest.mark.vcr(filter_headers=["authorization"])
def test_hierarchical_process():