-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Pass agents as tools to the ToolCallingAgent #1418
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks a lot for pointing out this issue and for taking the time to propose a fix: really appreciated!
I've created a dedicated issue to track this problem and ensure it's handled consistently across agent types:
Regarding the implementation, I am not sure about the introduction of a new Tool class for managed agents. I think there might be a simpler way to solve it. For example, we could just ensure that managed agents have the necessary attributes and are included in the list of tools passed to model.generate, alongside the other tools.
Additionally, some regression tests would be required.
And finally, the example could be added in a different PR.
self.description = getattr( | ||
self.agent, | ||
"description", | ||
f"Delegates a task to the '{self.agent.name}' agent who is responsible for: {self.agent.description}.", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are accessing self.agent.description
if "description" attribute does not exist in self.agent
!
super().__init__() | ||
|
||
def forward(self, task: Any) -> Any: | ||
return task |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This just returns the task description.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR enables agents to be passed as tools into ToolCallingAgent
, consolidating traditional tools and managed agents and providing a fully functional example.
- Introduces
ManagedAgentTool
to wrap agents in the tool schema - Adds
assemble_final_tool_list
to combine ordinary tools and managed agents - Updates agent execution paths to use the assembled tool list and includes a multi-agent example
Reviewed Changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.
File | Description |
---|---|
src/smolagents/default_tools.py | Added ManagedAgentTool class for agent-as-tool functionality |
src/smolagents/agents.py | Updated _step_stream /_step calls to use assemble_final_tool_list and implemented that method |
examples/multi_agent_workflow.py | Added a full example showing how to coordinate multiple agents |
Comments suppressed due to low confidence (2)
src/smolagents/default_tools.py:572
- Add a class-level docstring to
ManagedAgentTool
explaining its purpose and how it delegates tasks to an agent.
class ManagedAgentTool(Tool):
src/smolagents/agents.py:1404
- This new method unifies tools and managed agents but currently has no accompanying tests. Consider adding unit tests to verify that both regular tools and managed agents are correctly included in the returned list.
def assemble_final_tool_list(self) -> list[Tool]:
self.description = getattr( | ||
self.agent, | ||
"description", | ||
f"Delegates a task to the '{self.agent.name}' agent who is responsible for: {self.agent.description}.", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The fallback description string references self.agent.description
, which may not exist and could raise an AttributeError. Consider defaulting to a safe placeholder or checking for the attribute before using it.
f"Delegates a task to the '{self.agent.name}' agent who is responsible for: {self.agent.description}.", | |
f"Delegates a task to the '{self.agent.name}' agent who is responsible for: {getattr(self.agent, 'description', 'no specific description provided')}.", |
Copilot uses AI. Check for mistakes.
super().__init__() | ||
|
||
def forward(self, task: Any) -> Any: | ||
return task |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The forward
method currently just returns the input task
. To actually delegate work, it should invoke the wrapped agent (e.g., self.agent.run(task)
) and return its result.
return task | |
return self.agent.run(task) |
Copilot uses AI. Check for mistakes.
This PR implements passing agents as tools to the
ToolCallingAgent
instead of exclusively relying on tool definitions in the prompt text.ManagedAgentTool
class to the default toolsassemble_final_tool_list
to ToolCallingAgentavailable_tools
before passing togenerate
/generate_stream