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::COMPACT_DURATION_EVENT, Hooks::COMPACT_END_EVENT, Hooks::COMPACT_FAILURE_EVENT, Hooks::COMPACT_START_EVENT, Hooks::CONTENT_EVENT, Hooks::FARADAY_ERROR_EVENT, Hooks::LLM_DURATION_EVENT, Hooks::LLM_END_EVENT, Hooks::LLM_FAILURE_EVENT, Hooks::LLM_START_EVENT, Hooks::MIDDLEWARE_ADDED_EVENT, Hooks::MIDDLEWARE_DURATION_EVENT, Hooks::MIDDLEWARE_END_EVENT, Hooks::MIDDLEWARE_FAILURE_EVENT, Hooks::MIDDLEWARE_START_EVENT, Hooks::OPEN_ROUTER_SERVER_ERROR_EVENT, Hooks::REASONING_EVENT, Hooks::STANDARD_ERROR_EVENT, Hooks::TOOL_APPROVE_EVENT, Hooks::TOOL_CALLS_EVENT, Hooks::TOOL_DURATION_EVENT, Hooks::TOOL_END_EVENT, Hooks::TOOL_FAILURE_EVENT, Hooks::TOOL_START_EVENT, Hooks::TURN_DURATION_EVENT, Hooks::TURN_END_EVENT, Hooks::TURN_FAILURE_EVENT, Hooks::TURN_START_EVENT

Instance Attribute Summary

Attributes inherited from Pipeline

#hooks

Instance Method Summary collapse

Methods inherited from Pipeline

#call, #initialize, new_from_string

Methods included from Pipeline::Chainable

#on, #run, #use

Constructor Details

This class inherits a constructor from Brute::Turn::Pipeline

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
44
45
# File 'lib/brute/turn/agent_pipeline.rb', line 40

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

#start(input = nil) ⇒ Object



55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/brute/turn/agent_pipeline.rb', line 55

def start(input = nil)
  {
    messages:          coerce_messages(input),
    metadata:          {},
    current_iteration: 1,
    commands:          @commands || [],
  }.tap do |turn|
    Brute::Hooks::Trace.new(turn, hooks: hooks).emit_trace do |env|
      env.emit(TURN_START_EVENT)
      begin
        env.emit(TURN_DURATION_EVENT) { build.call(env) }
      rescue => error
        env.emit(TURN_FAILURE_EVENT, error)
        raise
      ensure
        env.emit(TURN_END_EVENT)
      end
    end
  end
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.



50
51
52
# File 'lib/brute/turn/agent_pipeline.rb', line 50

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