Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 10 additions & 4 deletions src/strands/handlers/callback_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,15 @@
class PrintingCallbackHandler:
"""Handler for streaming text output and tool invocations to stdout."""

def __init__(self) -> None:
"""Initialize handler."""
def __init__(self, verbose_tool_use: bool = True) -> None:
"""Initialize handler.

Args:
verbose_tool_use: Print out verbose information about tool calls.
"""
self.tool_count = 0
self.previous_tool_use = None
self._verbose_tool_use = verbose_tool_use

def __call__(self, **kwargs: Any) -> None:
"""Stream text output and tool invocations to stdout.
Expand All @@ -34,11 +39,12 @@ def __call__(self, **kwargs: Any) -> None:
print(data, end="" if not complete else "\n")

if current_tool_use and current_tool_use.get("name"):
tool_name = current_tool_use.get("name", "Unknown tool")
if self.previous_tool_use != current_tool_use:
self.previous_tool_use = current_tool_use
self.tool_count += 1
print(f"\nTool #{self.tool_count}: {tool_name}")
if self._verbose_tool_use:
tool_name = current_tool_use.get("name", "Unknown tool")
print(f"\nTool #{self.tool_count}: {tool_name}")

if complete and data:
print("\n")
Expand Down
22 changes: 22 additions & 0 deletions tests/strands/handlers/test_callback_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -202,3 +202,25 @@ def test_composite_handler_forwards_to_all_handlers():
# Verify each handler was called with the same arguments
for handler in mock_handlers:
handler.assert_called_once_with(**kwargs)


def test_verbose_tool_use_default():
"""Test that _verbose_tool_use defaults to True."""
handler = PrintingCallbackHandler()
assert handler._verbose_tool_use is True


def test_verbose_tool_use_disabled(mock_print):
"""Test that tool use output is suppressed when verbose_tool_use=False but counting still works."""
handler = PrintingCallbackHandler(verbose_tool_use=False)
assert handler._verbose_tool_use is False

current_tool_use = {"name": "test_tool", "input": {"param": "value"}}
handler(current_tool_use=current_tool_use)

# Should not print tool information when verbose_tool_use is False
mock_print.assert_not_called()

# Should still update tool count and previous_tool_use
assert handler.tool_count == 1
assert handler.previous_tool_use == current_tool_use
Loading