Class: Brute::Tools::SubAgent

Inherits:
Brute::Turn::AgentPipeline show all
Defined in:
lib/brute/tools/sub_agent.rb

Overview

A SubAgent is an Agent that exposes a tool-shaped facade so it can be dropped into another agent's tools list. The parent agent hands it to the LLM as a regular tool; when invoked, the SubAgent runs its own pipeline against a fresh Session built from the tool arguments, then returns the final assistant message as the tool result.

Usage:

researcher = Brute::Tools::SubAgent.new(
name:        "research",
description: "Delegate a research task to a read-only sub-agent.",
) do
use Brute::Middleware::SystemPrompt
use Brute::Middleware::Loop::ToolResult
use Brute::Middleware::MaxIterations, max_iterations: 10
use Brute::Middleware::ToolPipeline, tools: [Brute::Tools::FSRead, Brute::Tools::FSSearch]
run ->(env) do
  # The LLM call, written with your library of choice. Convert
  # env[:messages] to its format, call it, and append the response
  # back as Brute::Message values (the MessageTransport pattern —
  # see examples/ruby_llm.rb, examples/openai.rb, ...).
end
end

# The SubAgent IS a tool — hand it to a parent agent's ToolPipeline:
main_agent = Brute.agent do
use Brute::Middleware::ToolPipeline, tools: [Brute::Tools::FSRead, researcher]
run ->(env) { ... }
end
main_agent.start("delegate some research")

Constant Summary collapse

DEFAULT_PARAMS =
{
  task: { type: "string", desc: "A clear, detailed description of the task", required: true },
}.freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods inherited from Brute::Turn::AgentPipeline

#generate_map, #map, #start

Methods inherited from Brute::Turn::Pipeline

new_from_string

Methods included from Brute::Turn::Pipeline::Chainable

#run, #use

Constructor Details

#initialize(name:, description:, params: DEFAULT_PARAMS, &block) ⇒ SubAgent

Returns a new instance of SubAgent.



47
48
49
50
51
52
# File 'lib/brute/tools/sub_agent.rb', line 47

def initialize(name:, description:, params: DEFAULT_PARAMS, &block)
  @sub_agent_name = name.to_s
  @description    = description
  @params         = params
  super(&block)
end

Instance Attribute Details

#descriptionObject (readonly)

Returns the value of attribute description.



45
46
47
# File 'lib/brute/tools/sub_agent.rb', line 45

def description
  @description
end

#paramsObject (readonly)

Returns the value of attribute params.



45
46
47
# File 'lib/brute/tools/sub_agent.rb', line 45

def params
  @params
end

#sub_agent_nameObject (readonly)

Returns the value of attribute sub_agent_name.



45
46
47
# File 'lib/brute/tools/sub_agent.rb', line 45

def sub_agent_name
  @sub_agent_name
end

Instance Method Details

#execute(arguments) ⇒ Object

Tool-shaped entry point. Builds a session from arguments, runs the agent loop, returns the last assistant message as a string.



56
57
58
59
60
# File 'lib/brute/tools/sub_agent.rb', line 56

def execute(arguments)
  session = build_session(arguments)
  start(session)
  extract_result(session)
end

#nameObject

Lets ToolPipeline treat SubAgents the same as any other tool without checking respond_to? everywhere.



64
65
66
# File 'lib/brute/tools/sub_agent.rb', line 64

def name
  @sub_agent_name
end