Class: Agents::AgentTool
- Defined in:
- lib/agents/agent_tool.rb
Overview
AgentTool wraps an agent as a tool, enabling agent-to-agent collaboration without conversation handoffs. This implementation constrains wrapped agents for safety and predictability.
Key constraints:
-
Wrapped agents cannot perform handoffs (empty registry)
-
Limited turn count to prevent infinite loops
-
Isolated context (only shared state, no conversation history)
-
Always returns to calling agent
Instance Attribute Summary collapse
-
#output_extractor ⇒ Object
readonly
Returns the value of attribute output_extractor.
-
#tool_description ⇒ Object
readonly
Returns the value of attribute tool_description.
-
#tool_name ⇒ Object
readonly
Returns the value of attribute tool_name.
-
#wrapped_agent ⇒ Object
readonly
Returns the value of attribute wrapped_agent.
Instance Method Summary collapse
- #description ⇒ Object
-
#initialize(agent:, name: nil, description: nil, output_extractor: nil) ⇒ AgentTool
constructor
Initialize an AgentTool that wraps an agent as a callable tool.
- #name ⇒ Object
-
#perform(tool_context, input:) ⇒ Object
Execute the wrapped agent with constraints to prevent handoffs and recursion.
Methods inherited from Tool
Constructor Details
#initialize(agent:, name: nil, description: nil, output_extractor: nil) ⇒ AgentTool
Initialize an AgentTool that wraps an agent as a callable tool
51 52 53 54 55 56 57 58 |
# File 'lib/agents/agent_tool.rb', line 51 def initialize(agent:, name: nil, description: nil, output_extractor: nil) @wrapped_agent = agent @tool_name = name || transform_agent_name(agent.name) @tool_description = description || "Execute #{agent.name} agent" @output_extractor = output_extractor super() end |
Instance Attribute Details
#output_extractor ⇒ Object (readonly)
Returns the value of attribute output_extractor.
40 41 42 |
# File 'lib/agents/agent_tool.rb', line 40 def output_extractor @output_extractor end |
#tool_description ⇒ Object (readonly)
Returns the value of attribute tool_description.
40 41 42 |
# File 'lib/agents/agent_tool.rb', line 40 def tool_description @tool_description end |
#tool_name ⇒ Object (readonly)
Returns the value of attribute tool_name.
40 41 42 |
# File 'lib/agents/agent_tool.rb', line 40 def tool_name @tool_name end |
#wrapped_agent ⇒ Object (readonly)
Returns the value of attribute wrapped_agent.
40 41 42 |
# File 'lib/agents/agent_tool.rb', line 40 def wrapped_agent @wrapped_agent end |
Instance Method Details
#description ⇒ Object
64 65 66 |
# File 'lib/agents/agent_tool.rb', line 64 def description @tool_description end |
#name ⇒ Object
60 61 62 |
# File 'lib/agents/agent_tool.rb', line 60 def name @tool_name end |
#perform(tool_context, input:) ⇒ Object
Execute the wrapped agent with constraints to prevent handoffs and recursion
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
# File 'lib/agents/agent_tool.rb', line 69 def perform(tool_context, input:) # Create isolated context for the wrapped agent isolated_context = create_isolated_context(tool_context.context) # Execute with explicit constraints: # 1. Empty registry prevents handoffs # 2. Low max_turns prevents infinite loops # 3. Isolated context prevents history access result = Runner.new.run( @wrapped_agent, input, context: isolated_context, registry: {}, # CONSTRAINT: No handoffs allowed max_turns: 3 # CONSTRAINT: Limited turns for tool execution ) return "Agent execution failed: #{result.error.}" if result.error # Extract output if @output_extractor @output_extractor.call(result) else result.output || "No output from #{@wrapped_agent.name}" end rescue StandardError => e "Error executing #{@wrapped_agent.name}: #{e.}" end |