Class: Agents::Agent
- Inherits:
-
Object
- Object
- Agents::Agent
- Defined in:
- lib/agents/agent.rb
Instance Attribute Summary collapse
-
#handoff_agents ⇒ Object
readonly
Returns the value of attribute handoff_agents.
-
#instructions ⇒ Object
readonly
Returns the value of attribute instructions.
-
#model ⇒ Object
readonly
Returns the value of attribute model.
-
#name ⇒ Object
readonly
Returns the value of attribute name.
-
#response_schema ⇒ Object
readonly
Returns the value of attribute response_schema.
-
#temperature ⇒ Object
readonly
Returns the value of attribute temperature.
-
#tools ⇒ Object
readonly
Returns the value of attribute tools.
Instance Method Summary collapse
-
#all_tools ⇒ Array<Agents::Tool>
Get all tools available to this agent, including any auto-generated handoff tools.
-
#as_tool(name: nil, description: nil, output_extractor: nil) ⇒ Agents::AgentTool
Transform this agent into a tool, callable by other agents.
-
#clone(**changes) ⇒ Agents::Agent
Creates a new agent instance with modified attributes while preserving immutability.
-
#get_system_prompt(context) ⇒ String?
Get the system prompt for the agent, potentially customized based on runtime context.
-
#initialize(name:, instructions: nil, model: "gpt-4.1-mini", tools: [], handoff_agents: [], temperature: 0.7, response_schema: nil) ⇒ Agent
constructor
Initialize a new Agent instance.
-
#register_handoffs(*agents) ⇒ self
Register agents that this agent can hand off to.
Constructor Details
#initialize(name:, instructions: nil, model: "gpt-4.1-mini", tools: [], handoff_agents: [], temperature: 0.7, response_schema: nil) ⇒ Agent
Initialize a new Agent instance
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
# File 'lib/agents/agent.rb', line 64 def initialize(name:, instructions: nil, model: "gpt-4.1-mini", tools: [], handoff_agents: [], temperature: 0.7, response_schema: nil) @name = name @instructions = instructions @model = model @tools = tools.dup @handoff_agents = [] @temperature = temperature @response_schema = response_schema # Mutex for thread-safe handoff registration # While agents are typically configured at startup, we want to ensure # that concurrent handoff registrations don't result in lost data. # For example, in a web server with multiple threads initializing # different parts of the system, we might have: # Thread 1: triage.register_handoffs(billing) # Thread 2: triage.register_handoffs(support) # Without synchronization, one registration could overwrite the other. @mutex = Mutex.new # Register initial handoff agents if provided register_handoffs(*handoff_agents) unless handoff_agents.empty? end |
Instance Attribute Details
#handoff_agents ⇒ Object (readonly)
Returns the value of attribute handoff_agents.
53 54 55 |
# File 'lib/agents/agent.rb', line 53 def handoff_agents @handoff_agents end |
#instructions ⇒ Object (readonly)
Returns the value of attribute instructions.
53 54 55 |
# File 'lib/agents/agent.rb', line 53 def instructions @instructions end |
#model ⇒ Object (readonly)
Returns the value of attribute model.
53 54 55 |
# File 'lib/agents/agent.rb', line 53 def model @model end |
#name ⇒ Object (readonly)
Returns the value of attribute name.
53 54 55 |
# File 'lib/agents/agent.rb', line 53 def name @name end |
#response_schema ⇒ Object (readonly)
Returns the value of attribute response_schema.
53 54 55 |
# File 'lib/agents/agent.rb', line 53 def response_schema @response_schema end |
#temperature ⇒ Object (readonly)
Returns the value of attribute temperature.
53 54 55 |
# File 'lib/agents/agent.rb', line 53 def temperature @temperature end |
#tools ⇒ Object (readonly)
Returns the value of attribute tools.
53 54 55 |
# File 'lib/agents/agent.rb', line 53 def tools @tools end |
Instance Method Details
#all_tools ⇒ Array<Agents::Tool>
Get all tools available to this agent, including any auto-generated handoff tools
91 92 93 94 95 96 97 |
# File 'lib/agents/agent.rb', line 91 def all_tools @mutex.synchronize do # Compute handoff tools dynamically handoff_tools = @handoff_agents.map { |agent| HandoffTool.new(agent) } @tools + handoff_tools end end |
#as_tool(name: nil, description: nil, output_extractor: nil) ⇒ Agents::AgentTool
Transform this agent into a tool, callable by other agents. This enables agent-to-agent collaboration without conversation handoffs.
Agent-as-tool is different from handoffs in two key ways:
-
The wrapped agent receives generated input, not conversation history
-
The wrapped agent returns a result to the calling agent, rather than taking over
233 234 235 236 237 238 239 240 |
# File 'lib/agents/agent.rb', line 233 def as_tool(name: nil, description: nil, output_extractor: nil) AgentTool.new( agent: self, name: name, description: description, output_extractor: output_extractor ) end |
#clone(**changes) ⇒ Agents::Agent
Creates a new agent instance with modified attributes while preserving immutability. The clone method is used when you need to create variations of agents without mutating the original. This can be used for runtime agent modifications, say in a multi-tenant environment we can do something like the following:
The key insight to note here is that clone ensures immutability - you never accidentally modify a shared agent instance that other requests might be using. This is critical for thread safety in concurrent environments.
This also ensures we also get to leverage the syntax sugar defining a class provides us with.
159 160 161 162 163 164 165 166 167 168 169 |
# File 'lib/agents/agent.rb', line 159 def clone(**changes) self.class.new( name: changes.fetch(:name, @name), instructions: changes.fetch(:instructions, @instructions), model: changes.fetch(:model, @model), tools: changes.fetch(:tools, @tools.dup), handoff_agents: changes.fetch(:handoff_agents, @handoff_agents), temperature: changes.fetch(:temperature, @temperature), response_schema: changes.fetch(:response_schema, @response_schema) ) end |
#get_system_prompt(context) ⇒ String?
Get the system prompt for the agent, potentially customized based on runtime context. We will allow setting up a Proc for instructions. This will allow us the inject context in runtime.
196 197 198 199 200 201 202 203 204 205 206 |
# File 'lib/agents/agent.rb', line 196 def get_system_prompt(context) # TODO: Add string interpolation support for instructions # Allow instructions like "You are helping %{customer_name}" that automatically # get state values injected from context[:state] using Ruby's % formatting case instructions when String instructions when Proc instructions.call(context) end end |
#register_handoffs(*agents) ⇒ self
Register agents that this agent can hand off to. This method can be called after agent creation to set up handoff relationships. Thread-safe: Multiple threads can safely call this method concurrently.
115 116 117 118 119 120 121 |
# File 'lib/agents/agent.rb', line 115 def register_handoffs(*agents) @mutex.synchronize do @handoff_agents.concat(agents) @handoff_agents.uniq! # Prevent duplicates end self end |