From 7bf631b24cf96f7034a48c16bc212909733664ae Mon Sep 17 00:00:00 2001 From: "Gokhan (Joe) Gultekin" Date: Sun, 25 May 2025 15:28:46 +0200 Subject: [PATCH 1/3] feat(handlers): add reasoning text to callback handler and related tests --- .gitignore | 2 ++ src/strands/handlers/callback_handler.py | 6 ++++- .../strands/handlers/test_callback_handler.py | 25 +++++++++++++++++++ 3 files changed, 32 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index a80f4bd1..d75c369a 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,5 @@ __pycache__* .pytest_cache .ruff_cache *.bak +.vscode +# Ignore Python bytecode files \ No newline at end of file diff --git a/src/strands/handlers/callback_handler.py b/src/strands/handlers/callback_handler.py index d6d104d8..57bb6791 100644 --- a/src/strands/handlers/callback_handler.py +++ b/src/strands/handlers/callback_handler.py @@ -17,15 +17,19 @@ def __call__(self, **kwargs: Any) -> None: Args: **kwargs: Callback event data including: - + - reasoningText (bool|str): Whether to print reasoning text. If string is provided, it is printed. - data (str): Text content to stream. - complete (bool): Whether this is the final chunk of a response. - current_tool_use (dict): Information about the current tool being used. """ + reasoningText = kwargs.get("reasoningText", False) data = kwargs.get("data", "") complete = kwargs.get("complete", False) current_tool_use = kwargs.get("current_tool_use", {}) + if reasoningText: + print(reasoningText, end="") + if data: print(data, end="" if not complete else "\n") diff --git a/tests/strands/handlers/test_callback_handler.py b/tests/strands/handlers/test_callback_handler.py index 20e238cb..6fb2af07 100644 --- a/tests/strands/handlers/test_callback_handler.py +++ b/tests/strands/handlers/test_callback_handler.py @@ -30,6 +30,31 @@ def test_call_with_empty_args(handler, mock_print): mock_print.assert_not_called() +def test_call_handler_reasoningText(handler, mock_print): + """Test calling the handler with reasoningText.""" + handler(reasoningText="This is reasoning text") + # Should print reasoning text without newline + mock_print.assert_called_once_with("This is reasoning text", end="") + + +def test_call_without_reasoningText(handler, mock_print): + """Test calling the handler without reasoningText argument.""" + handler(data="Some output") + # Should only print data, not reasoningText + mock_print.assert_called_once_with("Some output", end="") + + +def test_call_with_reasoningText_and_data(handler, mock_print): + """Test calling the handler with both reasoningText and data.""" + handler(reasoningText="Reasoning", data="Output") + # Should print reasoningText and data, both without newline + calls = [ + unittest.mock.call("Reasoning", end=""), + unittest.mock.call("Output", end=""), + ] + mock_print.assert_has_calls(calls) + + def test_call_with_data_incomplete(handler, mock_print): """Test calling the handler with data but not complete.""" handler(data="Test output") From 942a7dd6305f74641f9f795b21b0b07c2f1e5ed4 Mon Sep 17 00:00:00 2001 From: "Gokhan (Joe) Gultekin" Date: Sun, 25 May 2025 17:23:54 +0200 Subject: [PATCH 2/3] feat(handlers): removed redundant comment in .gitignore file --- .gitignore | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index d75c369a..a5cf11c4 100644 --- a/.gitignore +++ b/.gitignore @@ -7,5 +7,4 @@ __pycache__* .pytest_cache .ruff_cache *.bak -.vscode -# Ignore Python bytecode files \ No newline at end of file +.vscode \ No newline at end of file From 9f47dd8f39739448e6ae308d9ad2e18426a73e61 Mon Sep 17 00:00:00 2001 From: "Gokhan (Joe) Gultekin" Date: Sun, 25 May 2025 17:31:46 +0200 Subject: [PATCH 3/3] feat(handlers): Updated reasoningText type as (Optional[str] --- src/strands/handlers/callback_handler.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/strands/handlers/callback_handler.py b/src/strands/handlers/callback_handler.py index 57bb6791..e46cb326 100644 --- a/src/strands/handlers/callback_handler.py +++ b/src/strands/handlers/callback_handler.py @@ -17,10 +17,10 @@ def __call__(self, **kwargs: Any) -> None: Args: **kwargs: Callback event data including: - - reasoningText (bool|str): Whether to print reasoning text. If string is provided, it is printed. - - data (str): Text content to stream. - - complete (bool): Whether this is the final chunk of a response. - - current_tool_use (dict): Information about the current tool being used. + - reasoningText (Optional[str]): Reasoning text to print if provided. + - data (str): Text content to stream. + - complete (bool): Whether this is the final chunk of a response. + - current_tool_use (dict): Information about the current tool being used. """ reasoningText = kwargs.get("reasoningText", False) data = kwargs.get("data", "")