Class: Boxcars::StationAgent
- Defined in:
- lib/boxcars/train/station_agent.rb
Overview
Agent abstraction that wraps ToolTrain with ergonomic DSL and agent-as-tool semantics.
Provides agent-friendly vocabulary (‘instructions`, `tools`, `model`) and proper agent-as-tool nesting for multi-agent composition. When passed as a tool to another agent, the outer agent sees a single `input` string parameter and receives the inner agent’s final answer as an observation.
Defined Under Namespace
Classes: HandoffBoxcar
Constant Summary collapse
- DEFAULT_NAME =
"Station Agent"- DEFAULT_DESCRIPTION =
"A helpful AI agent"
Constants inherited from ToolTrain
Constants inherited from Boxcar
Boxcar::SCHEMA_KEY_ALIASES, Boxcar::TYPE_ALIASES
Instance Attribute Summary collapse
-
#handoffs ⇒ Object
readonly
Returns the value of attribute handoffs.
-
#instructions ⇒ Object
readonly
Returns the value of attribute instructions.
-
#on_complete ⇒ Object
readonly
Returns the value of attribute on_complete.
-
#on_event ⇒ Object
readonly
Returns the value of attribute on_event.
-
#on_tool_call ⇒ Object
readonly
Returns the value of attribute on_tool_call.
-
#on_tool_result ⇒ Object
readonly
Returns the value of attribute on_tool_result.
Attributes inherited from ToolTrain
Attributes inherited from Train
#boxcars, #early_stopping_method, #engine_prefix, #final_answer_prefix, #max_iterations, #name_to_boxcar_map, #observation_prefix, #question_prefix, #return_intermediate_steps, #return_values, #thought_prefix, #using_xml
Attributes inherited from EngineBoxcar
#engine, #prompt, #stop, #top_k
Attributes inherited from Boxcar
#description, #name, #parameters, #return_direct
Instance Method Summary collapse
-
#call(inputs:) ⇒ Object
Override ToolTrain#call to track handoffs, fire callbacks, and emit events.
-
#initialize(instructions:, tools: [], engine: nil, name: DEFAULT_NAME, description: DEFAULT_DESCRIPTION, **kwargs) ⇒ StationAgent
constructor
A new instance of StationAgent.
- #output_keys ⇒ Object
-
#prediction_additional(_inputs) ⇒ Object
No template placeholders beyond %<input>s, so no extra variables needed.
-
#run_stream(input) {|AgentEvent| ... } ⇒ ConductResult, Enumerator<AgentEvent>
Stream agent events during execution.
Methods inherited from Train
#boxcar_descriptions, #boxcar_names, #construct_scratchpad, #extract_boxcar_and_input, #finish_boxcar_name, #get_boxcar_result, #get_next_action, #init_prefixes, #input_keys, #key_and_value_text, #next_actions, #observation_text, #plan, #pre_return, #prepare_for_new_call, #return_stopped_response, #should_continue?
Methods inherited from EngineBoxcar
#apply, #extract_code, #generate, #input_keys, #output_key, #predict, #prediction_variables
Methods inherited from Boxcar
#apply, assi, #conduct, #conduct_result, hist, #input_keys, #parameters_json_schema, #run, #run_result, #schema, syst, #tool_call_name, #tool_definition, #tool_spec, user, #validate_inputs, #validate_outputs
Constructor Details
#initialize(instructions:, tools: [], engine: nil, name: DEFAULT_NAME, description: DEFAULT_DESCRIPTION, **kwargs) ⇒ StationAgent
Returns a new instance of StationAgent.
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
# File 'lib/boxcars/train/station_agent.rb', line 58 def initialize(instructions:, tools: [], engine: nil, name: DEFAULT_NAME, description: DEFAULT_DESCRIPTION, **kwargs) @instructions = instructions model = kwargs.delete(:model) mcp_clients = kwargs.delete(:mcp_clients) || [] @on_tool_call = kwargs.delete(:on_tool_call) @on_tool_result = kwargs.delete(:on_tool_result) @on_complete = kwargs.delete(:on_complete) @on_event = kwargs.delete(:on_event) handoff_agents = kwargs.delete(:handoffs) || [] resolved_engine = engine || (model ? Boxcars::Engines.engine(model: model) : nil) combined_tools = Array(tools) Array(mcp_clients).each do |client| combined_tools.concat(Boxcars::MCP.boxcars_from_client(client)) end prompt = build_prompt kwargs[:parameters] ||= { input: { type: :string, description: "The task or question for this agent", required: true } } super(boxcars: combined_tools, engine: resolved_engine, name: name, description: description, prompt: prompt, **kwargs) install_handoffs(handoff_agents) end |
Instance Attribute Details
#handoffs ⇒ Object (readonly)
Returns the value of attribute handoffs.
11 12 13 |
# File 'lib/boxcars/train/station_agent.rb', line 11 def handoffs @handoffs end |
#instructions ⇒ Object (readonly)
Returns the value of attribute instructions.
11 12 13 |
# File 'lib/boxcars/train/station_agent.rb', line 11 def instructions @instructions end |
#on_complete ⇒ Object (readonly)
Returns the value of attribute on_complete.
11 12 13 |
# File 'lib/boxcars/train/station_agent.rb', line 11 def on_complete @on_complete end |
#on_event ⇒ Object (readonly)
Returns the value of attribute on_event.
11 12 13 |
# File 'lib/boxcars/train/station_agent.rb', line 11 def on_event @on_event end |
#on_tool_call ⇒ Object (readonly)
Returns the value of attribute on_tool_call.
11 12 13 |
# File 'lib/boxcars/train/station_agent.rb', line 11 def on_tool_call @on_tool_call end |
#on_tool_result ⇒ Object (readonly)
Returns the value of attribute on_tool_result.
11 12 13 |
# File 'lib/boxcars/train/station_agent.rb', line 11 def on_tool_result @on_tool_result end |
Instance Method Details
#call(inputs:) ⇒ Object
Override ToolTrain#call to track handoffs, fire callbacks, and emit events.
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
# File 'lib/boxcars/train/station_agent.rb', line 93 def call(inputs:) @pending_handoff = nil @current_iteration = 0 @total_tool_calls = 0 emit_event(:agent_start, input: inputs[:input], agent_name: name) result = super if @pending_handoff result[:handoff] = @pending_handoff emit_event(:handoff, from_agent: name, to_agent: @pending_handoff[:agent].name, reason: @pending_handoff[:reason]) else on_complete&.call(result) emit_event(:agent_complete, output: result[:output], iterations: @current_iteration, tool_calls_count: @total_tool_calls) end result end |
#output_keys ⇒ Object
87 88 89 90 |
# File 'lib/boxcars/train/station_agent.rb', line 87 def output_keys base = super base.include?(:handoff) ? base : base + [:handoff] end |
#prediction_additional(_inputs) ⇒ Object
No template placeholders beyond %<input>s, so no extra variables needed.
129 130 131 |
# File 'lib/boxcars/train/station_agent.rb', line 129 def prediction_additional(_inputs) {} end |
#run_stream(input) {|AgentEvent| ... } ⇒ ConductResult, Enumerator<AgentEvent>
Stream agent events during execution.
116 117 118 119 120 121 122 123 124 125 126 |
# File 'lib/boxcars/train/station_agent.rb', line 116 def run_stream(input, &block) if block previous_on_event = @on_event @on_event = block conduct(input) else Enumerator.new { |y| run_stream(input) { |event| y << event } } end ensure @on_event = previous_on_event if block end |