Module: Aireview::ConfigJev
- Included in:
- Config
- Defined in:
- lib/aireview/config_jev.rb
Overview
The critique engine and the Jev (TypeSafe) settings. llm.critique.engine picks who checks the candidates: an LLM (model, the default) or Jev, a fast classifier that decides keep/reject but cannot refine a finding. llm.jev.fallback says what happens when Jev cannot decide: the LLM Critique takes over (model) or the run fails (fail). llm.jev.shadow runs Jev next to the LLM Critique for the log only.
Constant Summary collapse
- CRITIQUE_ENGINES =
%w[model jev].freeze
- JEV_FALLBACKS =
%w[model fail].freeze
- DEFAULT_JEV_MODEL =
A pinned version, not an alias: thresholds are tuned against one version, and an alias moves when a release ships.
'jev-1.13.0'- JEV_ALIASES =
%w[jev-latest jev-preview].freeze
- DEFAULT_JEV_TIMEOUT =
10- JEV_THRESHOLD_DEFAULTS =
Provisional values until real thresholds are chosen from the shadow logs; the logs carry the raw probabilities for that.
{ 'keep_above' => 0.5, 'enough_context' => 0.5, 'version_claim' => 0.5, 'duplicate' => 0.5 }.freeze
Instance Method Summary collapse
- #critique_disabled? ⇒ Boolean
- #critique_engine ⇒ Object
- #jev_api_key ⇒ Object
-
#jev_critique?(critique: true) ⇒ Boolean
Jev decides in this run: the engine is jev and the run has a critique at all (--no-critique switches off every engine, as the critique: argument or as a CLI override of the config).
- #jev_fallback ⇒ Object
- #jev_model ⇒ Object
- #jev_shadow? ⇒ Boolean
-
#jev_signature ⇒ Object
Everything besides the questions that changes a Jev decision; nil when Jev does not decide.
- #jev_thresholds ⇒ Object
- #jev_timeout ⇒ Object
- #jev_warnings ⇒ Object
-
#llm_stages(critique: true) ⇒ Object
The stages that need an LLM in a run.
-
#require_jev!(critique: true) ⇒ Object
Jev as the critic needs a key and a pinned version: the thresholds are tuned against one version, and falling back to the LLM silently would hide a broken setup.
Instance Method Details
#critique_disabled? ⇒ Boolean
54 55 56 |
# File 'lib/aireview/config_jev.rb', line 54 def critique_disabled? @data['critique_disabled'] == true end |
#critique_engine ⇒ Object
30 31 32 |
# File 'lib/aireview/config_jev.rb', line 30 def critique_engine one_of!(dig('llm', 'critique', 'engine') || 'model', CRITIQUE_ENGINES, 'llm.critique.engine') end |
#jev_api_key ⇒ Object
70 71 72 |
# File 'lib/aireview/config_jev.rb', line 70 def jev_api_key @data['jev_api_key'] end |
#jev_critique?(critique: true) ⇒ Boolean
Jev decides in this run: the engine is jev and the run has a critique at all (--no-critique switches off every engine, as the critique: argument or as a CLI override of the config).
41 42 43 |
# File 'lib/aireview/config_jev.rb', line 41 def jev_critique?(critique: true) critique && !critique_disabled? && critique_engine == 'jev' end |
#jev_fallback ⇒ Object
34 35 36 |
# File 'lib/aireview/config_jev.rb', line 34 def jev_fallback one_of!(dig('llm', 'jev', 'fallback') || 'model', JEV_FALLBACKS, 'llm.jev.fallback') end |
#jev_model ⇒ Object
66 67 68 |
# File 'lib/aireview/config_jev.rb', line 66 def jev_model Aireview::Utils.presence(dig('llm', 'jev', 'model')) || DEFAULT_JEV_MODEL end |
#jev_shadow? ⇒ Boolean
58 59 60 61 62 63 64 |
# File 'lib/aireview/config_jev.rb', line 58 def jev_shadow? value = dig('llm', 'jev', 'shadow') return false if value.nil? return value if [true, false].include?(value) raise ConfigError, "llm.jev.shadow must be true or false, got #{value.inspect}" end |
#jev_signature ⇒ Object
Everything besides the questions that changes a Jev decision; nil when Jev does not decide. The fallback is part of it: it decides what happens to the candidates Jev could not judge.
88 89 90 91 92 |
# File 'lib/aireview/config_jev.rb', line 88 def jev_signature return nil unless critique_engine == 'jev' ['jev', jev_model, *jev_thresholds.values, jev_fallback] end |
#jev_thresholds ⇒ Object
78 79 80 81 82 83 |
# File 'lib/aireview/config_jev.rb', line 78 def jev_thresholds JEV_THRESHOLD_DEFAULTS.to_h do |name, default| value = dig('llm', 'jev', name) [name.to_sym, value.nil? ? default : probability!(value, "llm.jev.#{name}")] end end |
#jev_timeout ⇒ Object
74 75 76 |
# File 'lib/aireview/config_jev.rb', line 74 def jev_timeout positive_integer!(dig('llm', 'jev', 'timeout') || DEFAULT_JEV_TIMEOUT, 'llm.jev.timeout') end |
#jev_warnings ⇒ Object
106 107 108 109 110 111 112 113 114 115 116 117 118 119 |
# File 'lib/aireview/config_jev.rb', line 106 def jev_warnings return [] unless jev_shadow? return ['llm.jev.shadow is ignored: Jev already decides as the critique engine'] if critique_engine == 'jev' warnings = [] if Aireview::Utils.blank?(jev_api_key) warnings << 'llm.jev.shadow is on, but JEV_API_KEY is not set: Jev is skipped' end if JEV_ALIASES.include?(jev_model) warnings << "llm.jev.model #{jev_model.inspect} is an alias: its answers change when TypeSafe ships " \ 'a release; pin a version such as jev-1.13.0' end warnings end |
#llm_stages(critique: true) ⇒ Object
The stages that need an LLM in a run. Jev with fallback: model still needs a ready LLM Critique; with fallback: fail it needs none.
47 48 49 50 51 52 |
# File 'lib/aireview/config_jev.rb', line 47 def llm_stages(critique: true) return ['generate'] unless critique && !critique_disabled? return ['generate'] if jev_critique? && jev_fallback == 'fail' STAGES end |
#require_jev!(critique: true) ⇒ Object
Jev as the critic needs a key and a pinned version: the thresholds are tuned against one version, and falling back to the LLM silently would hide a broken setup.
97 98 99 100 101 102 103 104 |
# File 'lib/aireview/config_jev.rb', line 97 def require_jev!(critique: true) return unless jev_critique?(critique: critique) raise ConfigError, 'llm.critique.engine is jev, but JEV_API_KEY is not set' if Aireview::Utils.blank?(jev_api_key) return unless JEV_ALIASES.include?(jev_model) raise ConfigError, "llm.jev.model #{jev_model.inspect} is an alias; with llm.critique.engine: jev " \ 'pin a version such as jev-1.13.0' end |