Skip to content
Open
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
5 changes: 5 additions & 0 deletions src/smolagents/agents.py
Original file line number Diff line number Diff line change
Expand Up @@ -884,6 +884,11 @@ def __call__(self, task: str, **kwargs):
if self.provide_run_summary:
answer += "\n\nFor more detail, find below a summary of this agent's work:\n<summary_of_work>\n"
for message in self.write_memory_to_messages(summary_mode=True):
# Skip tool-call and tool-response messages: they contain raw
# tool arguments, observations, and potentially PII/secrets
# that should not leak into the parent agent's context.
if message.role in (MessageRole.TOOL_CALL, MessageRole.TOOL_RESPONSE):

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] Add regression coverage for the filtered roles

The existing test_call_with_provide_run_summary only supplies an ASSISTANT message, so it passes even if this condition is removed or later regresses. Because the fix is specifically meant to prevent raw tool arguments/outputs (and potentially secrets) from entering the parent context, please extend that test to return ASSISTANT, TOOL_CALL, and TOOL_RESPONSE messages, then assert the assistant summary remains while the raw tool-call and tool-response payloads are absent.

continue
content = message.content
answer += "\n" + truncate_content(str(content)) + "\n---"
answer += "\n</summary_of_work>"
Expand Down
33 changes: 33 additions & 0 deletions tests/test_agents.py
Original file line number Diff line number Diff line change
Expand Up @@ -2120,6 +2120,39 @@ def test_call_with_provide_run_summary(self, provide_run_summary):
)
assert result == expected_summary

def test_call_with_provide_run_summary_filters_tool_messages(self):
"""Regression for #2424: raw TOOL_CALL and TOOL_RESPONSE messages (which
carry tool arguments, observations, and potentially secrets) must not
leak into the parent agent's context via the managed-agent summary.
Only ASSISTANT/USER messages should be included in the summary."""
agent = CodeAgent(tools=[], model=MagicMock(), provide_run_summary=True)
agent.name = "test_agent"
agent.run = MagicMock(return_value="Test output")
# Simulate an inner run that produced an assistant message plus a
# tool-call/tool-response pair containing sensitive raw content.
secret_tool_args = "SUPER_SECRET_API_KEY=sk-leak"
secret_tool_output = "Observation: password=hunter2"
agent.write_memory_to_messages = MagicMock(
return_value=[
ChatMessage(role=MessageRole.ASSISTANT, content="I used the search tool."),
ChatMessage(role=MessageRole.TOOL_CALL, content=secret_tool_args),
ChatMessage(role=MessageRole.TOOL_RESPONSE, content=secret_tool_output),
ChatMessage(role=MessageRole.ASSISTANT, content="Final answer is 42."),
]
)

result = agent("Test request")

# The assistant summaries must be present...
assert "I used the search tool." in result
assert "Final answer is 42." in result
# ...but the raw tool-call arguments and tool-response observations
# (which may contain secrets) must be filtered out.
assert secret_tool_args not in result
assert secret_tool_output not in result
assert "SUPER_SECRET_API_KEY" not in result
assert "password=hunter2" not in result

def test_code_agent_image_output(self):
from PIL import Image

Expand Down