Class: Brute::Turn::AgentPipeline

Inherits:
Pipeline
  • Object
show all
Defined in:
lib/brute/turn/agent_pipeline.rb

Overview

agent = Brute.agent # => AgentPipeline .use(Middleware::X) # => same AgentPipeline (.use returns self) .run ->(env) { ... } # => same AgentPipeline (.run returns self)

agent.start("what changed?")   # => runs the turn, returns env

Direct Known Subclasses

Brute::Tools::SubAgent

Constant Summary

Constants included from Hooks

Hooks::AFTER_LLM_EVENT, Hooks::AFTER_TOOL_EVENT, Hooks::APPROVE_TOOL_EVENT, Hooks::BEFORE_LLM_EVENT, Hooks::BEFORE_TOOL_EVENT, Hooks::COMPACTED_EVENT, Hooks::COMPACT_DURATION_EVENT, Hooks::DURATION_EVENT, Hooks::ENTER_EVENT, Hooks::EXIT_EVENT, Hooks::FARADAY_ERROR_EVENT, Hooks::LLM_DURATION_EVENT, Hooks::LLM_FAILURE_EVENT, Hooks::MIDDLEWARE_ADDED_EVENT, Hooks::OPEN_ROUTER_SERVER_ERROR_EVENT, Hooks::STANDARD_ERROR_EVENT, Hooks::TOOL_DURATION_EVENT, Hooks::TURN_DURATION_EVENT, Hooks::TURN_END_EVENT, Hooks::TURN_START_EVENT

Instance Method Summary collapse

Methods inherited from Pipeline

#hooks, new_from_string

Methods included from Pipeline::Chainable

#on, #run, #use

Methods included from Hooks

new

Instance Method Details

#map(matcher, &block) ⇒ Object

Register a slash command:

map("/compact") { |env| ... }
map(/\Aplease compact/i) { |env| ... }
map(->(said) { said.length > 10_000 }) { |env| ... }

Whatever is given becomes a check: a function of what was said that answers true or false. A String is a slash command -- "/compact" becomes ^/compact.*, the command and whatever rides after it -- and a Regexp is wrapped in a function that evaluates it, so by the time a command is registered there are only functions. Anything that already answers to #call is taken as the check itself.

This is Rack::Builder's map overridden: an agent routes on what was said, not on a path, so there are no sub-builders and no URLMap.

The block is a middleware. start puts the registry into the turn as env, and SlashCommands -- which the builder puts at the head of every chain -- runs the first command whose check passes on the newest message, only when it is a user message, before the rest of the stack.



40
41
42
43
# File 'lib/brute/turn/agent_pipeline.rb', line 40

def map(matcher, &block)
  (@commands ||= []) << [check(matcher), block]
  self
end

#start(input = nil, events: NullSink.new) ⇒ Object



53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/brute/turn/agent_pipeline.rb', line 53

def start(input = nil, events: NullSink.new)
  env = {
    messages:          coerce_messages(input),
    events:            events,
    metadata:          {},
    current_iteration: 1,
    commands:          @commands || [],
  }
  hooks.emit(TURN_START_EVENT, env)
  begin
    hooks.emit(TURN_DURATION_EVENT, env) { build.call(env) }
  ensure
    hooks.emit(TURN_END_EVENT, env)
  end
  env
end

#to_appObject Also known as: build

Every chain starts with the commands, registry or no registry: the builder puts SlashCommands at its head rather than leaving it to a use someone has to remember.



48
49
50
# File 'lib/brute/turn/agent_pipeline.rb', line 48

def to_app
  Brute::Middleware::SlashCommands.new(super)
end