fix: Remove extra backticks from hierarchical tool outputs

Issue #2105 - Tool outputs in hierarchical mode were getting extra backticks
appended. This fix:
- Strips trailing backticks from tool results
- Adds test to verify tool output formatting in hierarchical mode

Co-Authored-By: Joe Moura <joao@crewai.com>
This commit is contained in:
Devin AI
2025-02-12 10:53:11 +00:00
parent 47818f4f41
commit c830ffab7a
2 changed files with 38 additions and 0 deletions

View File

@@ -372,6 +372,9 @@ class CrewAgentExecutor(CrewAgentExecutorMixin):
name.casefold().strip() for name in self.tool_name_to_tool_map name.casefold().strip() for name in self.tool_name_to_tool_map
]: ]:
tool_result = tool_usage.use(tool_calling, agent_action.text) 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 = self.tool_name_to_tool_map.get(tool_calling.tool_name) tool = self.tool_name_to_tool_map.get(tool_calling.tool_name)
if tool: if tool:
return ToolResult( return ToolResult(

View File

@@ -3,6 +3,7 @@
import hashlib import hashlib
import json import json
from concurrent.futures import Future from concurrent.futures import Future
from typing import Any
from unittest import mock from unittest import mock
from unittest.mock import MagicMock, patch from unittest.mock import MagicMock, patch
@@ -14,6 +15,7 @@ from crewai.agent import Agent
from crewai.agents.cache import CacheHandler from crewai.agents.cache import CacheHandler
from crewai.crew import Crew from crewai.crew import Crew
from crewai.crews.crew_output import CrewOutput from crewai.crews.crew_output import CrewOutput
from crewai.tools.base_tool import BaseTool
from crewai.knowledge.source.string_knowledge_source import StringKnowledgeSource from crewai.knowledge.source.string_knowledge_source import StringKnowledgeSource
from crewai.memory.contextual.contextual_memory import ContextualMemory from crewai.memory.contextual.contextual_memory import ContextualMemory
from crewai.process import Process from crewai.process import Process
@@ -315,6 +317,39 @@ def test_sync_task_execution():
assert mock_execute_sync.call_count == len(tasks) assert mock_execute_sync.call_count == len(tasks)
@pytest.mark.vcr(filter_headers=["authorization"])
def test_hierarchical_tool_output_formatting():
"""Test that tool outputs in hierarchical mode don't have extra backticks"""
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
task = Task(
description="Test task using test_tool",
expected_output="Test output",
)
crew = Crew(
agents=[researcher],
process=Process.hierarchical,
manager_llm="gpt-4o",
tasks=[task],
tools=[TestTool()],
)
with patch.object(Task, 'execute_sync', return_value=TaskOutput(
description="Test task",
raw="test result",
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
@pytest.mark.vcr(filter_headers=["authorization"]) @pytest.mark.vcr(filter_headers=["authorization"])
def test_hierarchical_process(): def test_hierarchical_process():
task = Task( task = Task(