Module: Brute::Turn::Pipeline::Chainable
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
-
#on ⇒ Object
Subscribe a lifecycle hook (see Brute::Hooks):.
- #run(app = nil, &block) ⇒ Object
-
#use(middleware, *args, &block) ⇒ Object
Enables the following syntax:.
Methods included from Hooks
Instance Method Details
#on ⇒ Object
Subscribe a lifecycle hook (see Brute::Hooks):
Brute.agent
.use(MaxProfit)
.run(->(env) { ... })
.on(:before_llm) { |env| ... }
.on(:approve_tool) { |call| call[:name] != "exec" }
75 |
# File 'lib/brute/turn/pipeline.rb', line 75 def on(...) = tap { hooks.on(...) } |
#run(app = nil, &block) ⇒ Object
60 61 62 63 64 65 |
# File 'lib/brute/turn/pipeline.rb', line 60 def run(app = nil, &block) tap do bind_emitter(app) unless app.nil? super end end |
#use(middleware, *args, &block) ⇒ Object
Enables the following syntax:
Brute.agent
.use(UltraSecurity)
.use(MaxProfit)
.use(DontTellMom)
.run -> (env) {
your_llm_library.complete("How to make money?")
}
Every layer announces itself: :middleware_added when it goes on the stack, then :enter and :exit around its own work on each turn. Both of those carry the middleware instance as self, and :exit fires from an ensure so a layer that raises is still reported.
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
# File 'lib/brute/turn/pipeline.rb', line 27 def use(middleware, *args, &block) tap do super hooks.emit(MIDDLEWARE_ADDED_EVENT, {}, middleware, *args) builder = @use.pop @use << lambda do |app| bind_emitter(builder.call(app)).tap do |layer| layer.define_singleton_method(:call) do |env| emit(ENTER_EVENT, env, self) # The layer's work is :duration's block, so its subscribers # are handed how long this layer took — its own work plus # everything below it. :exit then marks the layer done, # from an ensure so it lands even when the work raised. result = nil begin emit(DURATION_EVENT, env, self) { result = super(env) } ensure emit(EXIT_EVENT, env, self) end result end end end end end |