Class: Aireview::StageChains

Inherits:
Object
  • Object
show all
Defined in:
lib/aireview/stage_chains.rb

Overview

A routing plan of independent chains: every stage has its own primary model and reserves in walking order. Critique does not depend on which model answered in Generate.

The plan interface (ModelPool implements it too): chain(stage), critique_chain(after:), primary(stage), weaker?, signature, rule, pool?, pool_stage?, pool_member?, start_used?, warnings.

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(chains) ⇒ StageChains

Returns a new instance of StageChains.



64
65
66
# File 'lib/aireview/stage_chains.rb', line 64

def initialize(chains)
  @chains = chains
end

Class Method Details

.build(settings, only_primary: false) ⇒ Object

settings — per stage: provider, model, fallbacks (the raw list from the config), max_prompt_chars. only_primary keeps one model.



18
19
20
21
22
23
# File 'lib/aireview/stage_chains.rb', line 18

def self.build(settings, only_primary: false)
  chains = settings.to_h do |stage, stage_settings|
    [stage.to_s, stage_chain(stage.to_s, stage_settings, only_primary: only_primary)]
  end
  new(chains)
end

.fallbacks(stage, items, primary) ⇒ Object

A reserve without a provider inherits the stage provider, without a limit its limit. The address is not inherited: a reserve on another server names its own.



40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/aireview/stage_chains.rb', line 40

def self.fallbacks(stage, items, primary)
  items.each_with_index.map do |item, index|
    item = ModelCandidate.parse_item(item)
    name = "llm.#{stage}.fallbacks[#{index}]"
    raise ConfigError, "#{name} must be a model name or a hash with model" unless item.is_a?(Hash)
    raise ConfigError, "#{name}.model is required" if Aireview::Utils.blank?(item['model'])

    limit = item['max_prompt_chars']
    ModelCandidate.new(
      provider: (item['provider'] || primary.provider).to_s,
      model: item['model'].to_s,
      max_prompt_chars: limit.nil? ? primary.max_prompt_chars : positive_limit(limit, name),
      api_base: ModelCandidate.api_base(item['api_base'], "#{name}.api_base")
    )
  end
end

.positive_limit(value, name) ⇒ Object

Raises:



57
58
59
60
61
62
# File 'lib/aireview/stage_chains.rb', line 57

def self.positive_limit(value, name)
  integer = Integer(value, exception: false)
  return integer if integer&.positive?

  raise ConfigError, "#{name}.max_prompt_chars must be a positive integer, got #{value.inspect}"
end

.stage_chain(stage, settings, only_primary:) ⇒ Object



25
26
27
28
29
30
31
32
33
34
35
# File 'lib/aireview/stage_chains.rb', line 25

def self.stage_chain(stage, settings, only_primary:)
  primary = ModelCandidate.new(
    provider: settings.fetch(:provider).to_s,
    model: settings[:model],
    max_prompt_chars: settings.fetch(:max_prompt_chars),
    api_base: ModelCandidate.api_base(settings[:api_base], "llm.#{stage}.api_base")
  )
  return [primary] if only_primary

  [primary, *fallbacks(stage, Array(settings[:fallbacks]), primary)]
end

Instance Method Details

#chain(stage) ⇒ Object



68
69
70
# File 'lib/aireview/stage_chains.rb', line 68

def chain(stage)
  @chains.fetch(stage.to_s) { raise ArgumentError, "unknown LLM stage #{stage.inspect}" }
end

#critique_chain(after:) ⇒ Object



76
77
78
# File 'lib/aireview/stage_chains.rb', line 76

def critique_chain(after:)
  chain('critique')
end

#pool? ⇒ Boolean

Returns:

  • (Boolean)


96
97
98
# File 'lib/aireview/stage_chains.rb', line 96

def pool?
  false
end

#pool_member?(_model) ⇒ Boolean

Returns:

  • (Boolean)


104
105
106
# File 'lib/aireview/stage_chains.rb', line 104

def pool_member?(_model)
  false
end

#pool_stage?(_stage) ⇒ Boolean

Returns:

  • (Boolean)


100
101
102
# File 'lib/aireview/stage_chains.rb', line 100

def pool_stage?(_stage)
  false
end

#primary(stage) ⇒ Object



80
81
82
# File 'lib/aireview/stage_chains.rb', line 80

def primary(stage)
  chain(stage).first
end

#rule ⇒ Object



92
93
94
# File 'lib/aireview/stage_chains.rb', line 92

def rule
  nil
end

#signature ⇒ Object



88
89
90
# File 'lib/aireview/stage_chains.rb', line 88

def signature
  nil
end

#stage?(stage) ⇒ Boolean

Returns:

  • (Boolean)


72
73
74
# File 'lib/aireview/stage_chains.rb', line 72

def stage?(stage)
  @chains.key?(stage.to_s)
end

#start_used?(_stage) ⇒ Boolean

Returns:

  • (Boolean)


108
109
110
# File 'lib/aireview/stage_chains.rb', line 108

def start_used?(_stage)
  false
end

#warnings ⇒ Object



112
113
114
# File 'lib/aireview/stage_chains.rb', line 112

def warnings
  []
end

#weaker?(_critique_candidate, _generate_candidate) ⇒ Boolean

Returns:

  • (Boolean)


84
85
86
# File 'lib/aireview/stage_chains.rb', line 84

def weaker?(_critique_candidate, _generate_candidate)
  false
end