Class: Brute::Turn::ToolPipeline

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

Overview

A ToolPipeline runs a tool call through a middleware stack. Like AgentPipeline it composes a Pipeline rather than inheriting: the definition block is instance_eval'd into the internal Pipeline, so use / run inside it are the builder's methods. The tool's terminal app does the work; middleware wraps it with concerns like file mutation queueing, validation, logging.

Coexists with Brute::Tools::* (which inherit from RubyLLM::Tool). Use a ToolPipeline when you want middleware; use RubyLLM::Tool subclasses for simple cases.

read = Brute::Turn::ToolPipeline.new(
name:        "read",
description: "Read a file's contents",
params:      { file_path: { type: "string", required: true } },
) do
use Brute::Middleware::Tool::ValidateParams
run ->(env) {
  env[:result] = File.read(File.expand_path(env[:arguments][:file_path]))
}
end

read.call(file_path: "lib/brute.rb")

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name:, description:, params: {}, &block) ⇒ ToolPipeline

Returns a new instance of ToolPipeline.



36
37
38
39
40
41
42
# File 'lib/brute/turn/tool_pipeline.rb', line 36

def initialize(name:, description:, params: {}, &block)
  @name        = name.to_s
  @description = description
  @params      = params
  @pipeline    = Pipeline.new
  @pipeline.instance_eval(&block) if block
end

Instance Attribute Details

#descriptionObject (readonly)

Returns the value of attribute description.



34
35
36
# File 'lib/brute/turn/tool_pipeline.rb', line 34

def description
  @description
end

#nameObject (readonly)

Returns the value of attribute name.



34
35
36
# File 'lib/brute/turn/tool_pipeline.rb', line 34

def name
  @name
end

#paramsObject (readonly)

Returns the value of attribute params.



34
35
36
# File 'lib/brute/turn/tool_pipeline.rb', line 34

def params
  @params
end

Instance Method Details

#call(events: Pipeline::NullSink.new, **arguments) ⇒ Object



44
45
46
47
48
49
50
51
52
53
54
# File 'lib/brute/turn/tool_pipeline.rb', line 44

def call(events: Pipeline::NullSink.new, **arguments)
  env = {
    name:      @name,
    arguments: arguments,
    result:    nil,
    events:    events,
    metadata:  {},
  }
  @pipeline.call(env)
  env[:result]
end

#to_ruby_llmObject

Adapter so the LLM can call this tool through ruby_llm.



57
58
59
60
61
62
63
64
65
# File 'lib/brute/turn/tool_pipeline.rb', line 57

def to_ruby_llm
  tool = self
  Class.new(RubyLLM::Tool) do
    description tool.description
    tool.params.each { |k, opts| param k, **opts }
    define_method(:name) { tool.name }
    define_method(:execute) { |**args| tool.call(**args) }
  end.new
end