class RubyLLM::AgentTool
The Tool an Agent class becomes when it goes wherever tools go, so a model can hand work to it: a subagent. Agent::to_tool returns one, and Chat#with_tools and Agent::tools convert an Agent class themselves.
class ResearchAgent < RubyLLM::Agent description "Researches a question across the web and reports back" tools WebSearch, ReadPage end chat.with_tools(ResearchAgent).ask "What changed in Ruby 4.0?"
The tool is named after the agent (research_agent, or billing_research_agent for Billing::ResearchAgent) and takes a task, everything the agent needs written to stand alone, plus the agent’s ::inputs that ::to_tool was not given. Each call runs a fresh instance of the agent on the task, under the owner of the chat that called it, and returns the content of its last answer. When the agent waits, for an approval, a question, or a task of its own, the call pauses on an AgentTask instead, and Chat#complete carries the agent on once nothing holds it.
Attributes
The Agent class this tool runs.
Public Class Methods
Source
# File lib/ruby_llm/agent_tool.rb, line 53 def tool_name Support::Utils.underscore(agent_class.name.gsub('::', '_')) end
Returns the agent’s name in snake case, such as research_agent.
Public Instance Methods
# File lib/ruby_llm/agent_tool.rb, line 68 def execute(task:, tool_call: nil, **inputs) agent = self.class.agent_class.new(**@inputs, **inputs.slice(*self.class.input_parameters)) owner = Accounting::Usage.owner agent.with_owner(owner) unless owner.nil? run = SecureRandom.uuid @lock.synchronize { @agents[run] = agent } running(run) { report(agent, agent.ask(task), run, tool_call) } end
Runs a fresh instance of the agent on task, with the inputs given to Agent::to_tool and those the model chose, and returns the content of its last answer, or an AgentTask when the agent waits.
Source
# File lib/ruby_llm/agent_tool.rb, line 79 def resume(task, **) agent = task.agent return { error: "This agent's work was lost. Start it again with everything it needs." } unless agent return task if agent.awaiting_person? run = task.data['run'] running(run) { report(agent, agent.complete, run, task.tool_call) } end
Carries the agent on once nothing holds it, with Chat#complete, and returns its answer, or task again while it still waits.
Source
# File lib/ruby_llm/agent_tool.rb, line 89 def task(state, tool_call: nil) run = state.dig('task', 'data', 'run') AgentTask.load(state, tool_call:, tool: self, agent: @lock.synchronize { @agents[run] }) end
Returns the AgentTask the call paused on, with the agent it waits for.