Skip to content

Commit 573fc42

Browse files
Diwak4rclaude
andcommitted
fix(agents): exclude sanitized cache-read tool name from tool cache
The exclusion guard compared the raw default name "Hit Cache" against the sanitized runtime name "hit_cache", so it was always true and the cache tool's own output was written into the cache. Compare with sanitize_tool_name(CacheTools().name) instead. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 0e5d0ec commit 573fc42

2 files changed

Lines changed: 28 additions & 1 deletion

File tree

lib/crewai/src/crewai/agents/tools_handler.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
from crewai.agents.cache.cache_handler import CacheHandler
1111
from crewai.tools.cache_tools.cache_tools import CacheTools
1212
from crewai.tools.tool_calling import InstructorToolCalling, ToolCalling
13+
from crewai.utilities.string_utils import sanitize_tool_name
1314

1415

1516
class ToolsHandler(BaseModel):
@@ -37,7 +38,9 @@ def on_tool_use(
3738
should_cache: Whether to cache the tool output.
3839
"""
3940
self.last_used_tool = calling
40-
if self.cache and should_cache and calling.tool_name != CacheTools().name:
41+
if self.cache and should_cache and calling.tool_name != sanitize_tool_name(
42+
CacheTools().name
43+
):
4144
input_str = ""
4245
if calling.arguments:
4346
if isinstance(calling.arguments, dict):

lib/crewai/tests/tools/test_tool_usage.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,10 @@
2424
register_after_tool_call_hook,
2525
)
2626
from crewai.tools import BaseTool
27+
from crewai.tools.cache_tools.cache_tools import CacheTools
2728
from crewai.tools.tool_calling import ToolCalling
2829
from crewai.tools.tool_usage import ToolUsage
30+
from crewai.utilities.string_utils import sanitize_tool_name
2931
from crewai.utilities.tool_utils import execute_tool_and_check_finality
3032
from pydantic import BaseModel, Field
3133
import pytest
@@ -903,3 +905,25 @@ def on_finished(source, event):
903905
assert len(finished_events) == 0, (
904906
"ToolUsageFinishedEvent should NOT be emitted after ToolUsageErrorEvent"
905907
)
908+
909+
910+
def test_cache_tool_result_is_not_cached():
911+
"""The cache-read tool ('hit_cache') must not be added to the tool cache.
912+
913+
Regression test: the exclusion guard compared the raw default name
914+
'Hit Cache' against the sanitized runtime name 'hit_cache', so the guard
915+
was always True and the cache tool's own output got cached anyway.
916+
"""
917+
cache = CacheHandler()
918+
tools_handler = ToolsHandler(cache=cache)
919+
920+
tools_handler.on_tool_use(
921+
calling=ToolCalling(
922+
tool_name=sanitize_tool_name(CacheTools().name),
923+
arguments={},
924+
),
925+
output="cached value",
926+
)
927+
928+
cached = cache.read(tool=sanitize_tool_name(CacheTools().name), input="")
929+
assert cached is None, "Cache read tool result must not be cached"

0 commit comments

Comments
 (0)