Module: Aireview::ConfigLayers

Included in:
Config
Defined in:
lib/aireview/config_layers.rb

Overview

Configuration layers in ascending priority: built-in values, image defaults (AIREVIEW_DEFAULTS), the project's .aireview.yml, env, CLI. The layer name is shown by --dry-run, so that it is clear where a model came from.

Defined Under Namespace

Classes: Layer

Constant Summary collapse

BUILT_IN_LAYER =
'built-in'
DATA_LAYER =
'config'
IMAGE_LAYER =
'image defaults'
FILE_LAYER =
'.aireview.yml'
ENV_LAYER =
'env'
CLI_LAYER =
'cli'

Instance Method Summary collapse

Instance Method Details

#layer_paths ⇒ Object

The paths of the file layers, for --dry-run.



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

def layer_paths
  @layers.select(&:path).to_h { |layer| [layer.name, layer.path] }
end

#source_of(*keys) ⇒ Object

The name of the layer a value came from; nil — not set anywhere.



20
21
22
# File 'lib/aireview/config_layers.rb', line 20

def source_of(*keys)
  layer_of(*keys)&.name
end

#stage_fallbacks_source(stage) ⇒ Object



53
54
55
56
# File 'lib/aireview/config_layers.rb', line 53

def stage_fallbacks_source(stage)
  stage = stage.to_s
  routing.pool_stage?(stage) ? source_of('llm', 'models') : source_of('llm', stage, 'fallbacks')
end

#stage_model_source(stage) ⇒ Object

In pool mode the stage model is set by the start or the pool itself, the reserves by the pool.



45
46
47
48
49
50
51
# File 'lib/aireview/config_layers.rb', line 45

def stage_model_source(stage)
  stage = stage.to_s
  return source_of('llm', stage, 'model') unless routing.pool_stage?(stage)
  return source_of('llm', stage, 'start') if routing.start_used?(stage)

  source_of('llm', 'models')
end

#stage_provider_source(stage) ⇒ Object



40
41
42
# File 'lib/aireview/config_layers.rb', line 40

def stage_provider_source(stage)
  stage_setting_layer(stage, 'provider')&.name
end

#stage_provider_warnings(stage) ⇒ Object

A reserve without a provider inherits the stage provider. When a project overrode the provider above the layer that set the reserves, the inherited reserves silently become "models" of the new provider.



79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/aireview/config_layers.rb', line 79

def stage_provider_warnings(stage)
  stage = stage.to_s
  inherited = inherited_fallback_names(stage)
  return [] if inherited.empty?

  provider_layer = stage_setting_layer(stage, 'provider')
  fallbacks_layer = layer_of('llm', stage, 'fallbacks')
  return [] unless provider_layer && fallbacks_layer
  return [] if @layers.index(provider_layer) <= @layers.index(fallbacks_layer)

  provider = public_send("#{stage}_provider")
  ["#{stage}: provider #{provider.inspect} comes from #{provider_layer.name}, " \
   "but fallbacks without an explicit provider come from #{fallbacks_layer.name} " \
   "and now inherit it: #{inherited.join(', ')}"]
end

#stage_setting(stage, key) ⇒ Object

A stage setting resolved layer by layer: in every layer, top down, the stage value (llm..) first, then the shared one (llm.). A stage value from the image defaults must not beat a shared value from the project or the environment: LLM_PROVIDER=ollama must switch both stages.



28
29
30
31
# File 'lib/aireview/config_layers.rb', line 28

def stage_setting(stage, key)
  layer = stage_setting_layer(stage, key)
  layer && (Utils.dig(layer.data, 'llm', stage.to_s, key) || Utils.dig(layer.data, 'llm', key))
end

#stage_setting_layer(stage, key) ⇒ Object



33
34
35
36
37
38
# File 'lib/aireview/config_layers.rb', line 33

def stage_setting_layer(stage, key)
  stage = stage.to_s
  @layers.reverse.find do |layer|
    !Utils.dig(layer.data, 'llm', stage, key).nil? || !Utils.dig(layer.data, 'llm', key).nil?
  end
end

#start_inherited?(stage) ⇒ Boolean

The stage start came from a layer below the one that set the pool: the image defaults versus the project's LLM_MODELS.

Returns:

  • (Boolean)


60
61
62
63
64
# File 'lib/aireview/config_layers.rb', line 60

def start_inherited?(stage)
  start_layer = layer_of('llm', stage.to_s, 'start')
  models_layer = layer_of('llm', 'models')
  !!(start_layer && models_layer && @layers.index(start_layer) < @layers.index(models_layer))
end

#warnings ⇒ Object

Configuration and plan warnings; the CLI and --dry-run print them.



67
68
69
# File 'lib/aireview/config_layers.rb', line 67

def warnings
  llm_stages.flat_map { |stage| stage_provider_warnings(stage) } + routing.warnings + jev_warnings
end