Class: RubyLLM::Contract::Pipeline::Base

Inherits:
Object
  • Object
show all
Extended by:
Concerns::EvalHost
Defined in:
lib/ruby_llm/contract/pipeline/base.rb

Constant Summary

Constants included from Concerns::EvalHost

Concerns::EvalHost::SAMPLE_RESPONSE_COMPARE_WARNING

Class Method Summary collapse

Methods included from Concerns::EvalHost

clear_file_sourced_evals!, compare_models, compare_with, define_eval, eval_defined?, eval_names, run_eval

Class Method Details

.inherited(subclass) ⇒ Object



7
8
9
10
# File 'lib/ruby_llm/contract/pipeline/base.rb', line 7

def self.inherited(subclass)
  super
  Contract.register_eval_host(subclass) if respond_to?(:eval_defined?) && eval_defined?
end

.run(input, context: {}, timeout_ms: nil) ⇒ Object



50
51
52
# File 'lib/ruby_llm/contract/pipeline/base.rb', line 50

def run(input, context: {}, timeout_ms: nil)
  Runner.new(steps: steps, context: context, timeout_ms: timeout_ms, token_budget: token_budget).call(input)
end

.step(step_class, as:, depends_on: nil, model: nil) ⇒ Object

depends_on is accepted for forward compatibility with DAG pipelines (v0.3). Currently, execution is always linear in declaration order.



17
18
19
20
# File 'lib/ruby_llm/contract/pipeline/base.rb', line 17

def step(step_class, as:, depends_on: nil, model: nil)
  validate_dependency!(depends_on) if depends_on
  steps_registry << { step_class: step_class, alias: as, depends_on: depends_on, model: model }
end

.stepsObject



22
23
24
# File 'lib/ruby_llm/contract/pipeline/base.rb', line 22

def steps
  steps_registry.map { |s| s.dup.freeze }.freeze
end

.steps_registryObject

Internal mutable steps list for registration



27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/ruby_llm/contract/pipeline/base.rb', line 27

def steps_registry
  @steps_registry ||= begin
    inherited_steps =
      if superclass.respond_to?(:steps_registry, true)
        superclass.send(:steps_registry).map(&:dup)
      else
        []
      end

    inherited_steps
  end
end

.test(input, responses: {}, timeout_ms: nil) ⇒ Object



54
55
56
57
58
# File 'lib/ruby_llm/contract/pipeline/base.rb', line 54

def test(input, responses: {}, timeout_ms: nil)
  ordered_responses = steps.map { |step_entry| responses.fetch(step_entry[:alias], "") }
  adapter = Adapters::Test.new(responses: ordered_responses)
  run(input, context: { adapter: adapter }, timeout_ms: timeout_ms)
end

.token_budget(limit = nil) ⇒ Object



40
41
42
43
44
45
46
47
48
# File 'lib/ruby_llm/contract/pipeline/base.rb', line 40

def token_budget(limit = nil)
  if limit
    raise ArgumentError, "token_budget must be positive, got #{limit}" unless limit.positive?

    return @token_budget = limit
  end

  @token_budget
end