Skip to content

Commit 2ca937c

Browse files
committed
refactor: use json.dumps default parameter for non-serializable objects
- Replace manual serialization loop with json.dumps default parameter - Use __qualname__ for better type representation - Change format from <non-serializable> to <<non-serializable>> - Update tests to match new serialization format - Addresses PR feedback to simplify serialization approach
1 parent 0fe55db commit 2ca937c

File tree

2 files changed

+14
-23
lines changed

2 files changed

+14
-23
lines changed

src/strands/agent/agent.py

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -616,22 +616,10 @@ def _record_tool_execution(
616616
user_message_override: Optional custom message to include.
617617
"""
618618
# Create user message describing the tool call
619-
620-
# Filter out non-serializable objects to prevent JSON serialization errors
621-
serializable_input = {}
622-
for key, value in tool["input"].items():
623-
try:
624-
json.dumps(value) # Test if serializable
625-
serializable_input[key] = value
626-
except (TypeError, ValueError):
627-
serializable_input[key] = f"<non-serializable: {type(value).__name__}>"
619+
input_parameters = json.dumps(tool["input"], default=lambda o: f"<<non-serializable: {type(o).__qualname__}>>")
628620

629621
user_msg_content: list[ContentBlock] = [
630-
{
631-
"text": (
632-
f"agent.tool.{tool['name']} direct tool call.\nInput parameters: {json.dumps(serializable_input)}\n"
633-
)
634-
}
622+
{"text": (f"agent.tool.{tool['name']} direct tool call.\nInput parameters: {input_parameters}\n")}
635623
]
636624

637625
# Add override message if provided

tests/strands/agent/test_agent.py

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1616,7 +1616,7 @@ def test_agent_tool_non_serializable_parameter_filtering(agent, mock_randint):
16161616
tool_call_text = user_message["content"][1]["text"]
16171617
assert "agent.tool.tool_decorated direct tool call." in tool_call_text
16181618
assert '"random_string": "test_value"' in tool_call_text
1619-
assert '"non_serializable_agent": "<non-serializable: Agent>"' in tool_call_text
1619+
assert '"non_serializable_agent": "<<non-serializable: Agent>>"' in tool_call_text
16201620

16211621

16221622
def test_agent_tool_multiple_non_serializable_types(agent, mock_randint):
@@ -1663,11 +1663,14 @@ def __init__(self, value):
16631663
assert '"serializable_dict": {"key": "value"}' in tool_call_text
16641664

16651665
# Verify non-serializable objects are replaced with descriptive strings
1666-
assert '"agent": "<non-serializable: Agent>"' in tool_call_text
1667-
assert '"custom_object": "<non-serializable: CustomClass>"' in tool_call_text
1668-
assert '"function": "<non-serializable: function>"' in tool_call_text
1669-
assert '"set_object": "<non-serializable: set>"' in tool_call_text
1670-
assert '"complex_number": "<non-serializable: complex>"' in tool_call_text
1666+
assert '"agent": "<<non-serializable: Agent>>"' in tool_call_text
1667+
assert (
1668+
'"custom_object": "<<non-serializable: test_agent_tool_multiple_non_serializable_types.<locals>.CustomClass>>"'
1669+
in tool_call_text
1670+
)
1671+
assert '"function": "<<non-serializable: function>>"' in tool_call_text
1672+
assert '"set_object": "<<non-serializable: set>>"' in tool_call_text
1673+
assert '"complex_number": "<<non-serializable: complex>>"' in tool_call_text
16711674

16721675

16731676
def test_agent_tool_serialization_edge_cases(agent, mock_randint):
@@ -1705,7 +1708,7 @@ def test_agent_tool_serialization_edge_cases(agent, mock_randint):
17051708
assert '"nested_dict_serializable": {"nested": {"key": "value"}}' in tool_call_text
17061709

17071710
# Verify non-serializable nested structure is replaced
1708-
assert '"nested_list_with_non_serializable": "<non-serializable: list>"' in tool_call_text
1711+
assert '"nested_list_with_non_serializable": [1, 2, "<<non-serializable: Agent>>"]' in tool_call_text
17091712

17101713

17111714
def test_agent_tool_no_non_serializable_parameters(agent, mock_randint):
@@ -1731,8 +1734,8 @@ def test_agent_tool_no_non_serializable_parameters(agent, mock_randint):
17311734
# Verify normal parameter serialization (no filtering needed)
17321735
assert "agent.tool.tool_decorated direct tool call." in tool_call_text
17331736
assert '"random_string": "normal_call"' in tool_call_text
1734-
# Should not contain any "<non-serializable:" strings
1735-
assert "<non-serializable:" not in tool_call_text
1737+
# Should not contain any "<<non-serializable:" strings
1738+
assert "<<non-serializable:" not in tool_call_text
17361739

17371740

17381741
def test_agent_tool_record_direct_tool_call_disabled_with_non_serializable(agent, mock_randint):

0 commit comments

Comments
 (0)