Module: Legion::LLM::Discovery
- Extended by:
- Legion::Logging::Helper
- Defined in:
- lib/legion/llm/discovery.rb,
lib/legion/llm/discovery/system.rb,
lib/legion/llm/discovery/memory_gate.rb,
lib/legion/llm/discovery/rule_generator.rb
Defined Under Namespace
Modules: MemoryGate, RuleGenerator, System
Constant Summary collapse
- EMBEDDING_TIER_ORDER =
%w[local direct fleet openai_compat cloud frontier].freeze
Class Attribute Summary collapse
-
.embedding_fallback_chain ⇒ Object
readonly
Returns the value of attribute embedding_fallback_chain.
-
.embedding_instance ⇒ Object
readonly
Returns the value of attribute embedding_instance.
-
.embedding_model ⇒ Object
readonly
Returns the value of attribute embedding_model.
-
.embedding_provider ⇒ Object
readonly
Returns the value of attribute embedding_provider.
Class Method Summary collapse
- .cached_discovered_models ⇒ Object
- .can_embed? ⇒ Boolean
- .detect_embedding_capability ⇒ Object
-
.discovered_instances ⇒ Object
Returns discovered instances grouped by provider for RuleGenerator compatibility.
-
.discovered_models ⇒ Object
Flat list of all discovered models across all registry adapters.
- .fetch_offering_models(entry) ⇒ Object
-
.model_available?(model, provider: nil, instance: nil) ⇒ Boolean
Check whether a specific model is available from any registered provider.
-
.model_size(model, provider: nil, instance: nil) ⇒ Object
Return the size in bytes for a discovered model, or nil if unknown.
- .refresh_all_provider_models ⇒ Object
- .refresh_discovered_models!(provider: nil) ⇒ Object
-
.refresh_provider_models(provider) ⇒ Object
Refresh models for a single provider, preserving other providers’ cached models.
- .reset! ⇒ Object
- .run ⇒ Object
Class Attribute Details
.embedding_fallback_chain ⇒ Object (readonly)
Returns the value of attribute embedding_fallback_chain.
23 24 25 |
# File 'lib/legion/llm/discovery.rb', line 23 def @embedding_fallback_chain end |
.embedding_instance ⇒ Object (readonly)
Returns the value of attribute embedding_instance.
23 24 25 |
# File 'lib/legion/llm/discovery.rb', line 23 def @embedding_instance end |
.embedding_model ⇒ Object (readonly)
Returns the value of attribute embedding_model.
23 24 25 |
# File 'lib/legion/llm/discovery.rb', line 23 def @embedding_model end |
.embedding_provider ⇒ Object (readonly)
Returns the value of attribute embedding_provider.
23 24 25 |
# File 'lib/legion/llm/discovery.rb', line 23 def @embedding_provider end |
Class Method Details
.cached_discovered_models ⇒ Object
94 95 96 |
# File 'lib/legion/llm/discovery.rb', line 94 def cached_discovered_models @discovered_models_cache || [] end |
.can_embed? ⇒ Boolean
25 26 27 |
# File 'lib/legion/llm/discovery.rb', line 25 def @can_embed == true end |
.detect_embedding_capability ⇒ Object
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
# File 'lib/legion/llm/discovery.rb', line 43 def log.debug '[llm][discovery] action=detect_embedding_capability.enter' if log.debug '[llm][discovery] action=detect_embedding_capability registry_hit=true' return end = self. found = () if found @can_embed = true @embedding_provider = found[:provider] @embedding_model = found[:model] @embedding_fallback_chain = () log.info "[llm][discovery] embedding available provider=#{@embedding_provider} model=#{@embedding_model}" else @can_embed = false @embedding_fallback_chain = [] log.info '[llm][discovery] no embedding provider available' end rescue StandardError => e @can_embed = false @embedding_fallback_chain = [] handle_exception(e, level: :warn, operation: 'llm.discovery.detect_embedding_capability') end |
.discovered_instances ⇒ Object
Returns discovered instances grouped by provider for RuleGenerator compatibility. Each provider maps to a hash of instance_id => { models: […], base_url: … }
72 73 74 75 76 77 78 79 80 81 82 83 |
# File 'lib/legion/llm/discovery.rb', line 72 def discovered_instances models = discovered_models result = {} models.each do |m| provider = m[:provider] instance = m[:instance] || :default result[provider] ||= {} result[provider][instance] ||= { models: [] } result[provider][instance][:models] << normalize_model_for_rules(m) end result end |
.discovered_models ⇒ Object
Flat list of all discovered models across all registry adapters. TTL-cached; call refresh_discovered_models! to force a refresh.
87 88 89 90 91 92 |
# File 'lib/legion/llm/discovery.rb', line 87 def discovered_models return @discovered_models_cache if @discovered_models_cache && !discovered_models_stale? refresh_discovered_models! @discovered_models_cache || [] end |
.fetch_offering_models(entry) ⇒ Object
158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 |
# File 'lib/legion/llm/discovery.rb', line 158 def fetch_offering_models(entry) adapter = entry[:adapter] return [] unless adapter.respond_to?(:offerings) begin Array(adapter.offerings(live: true)).map do |offering| data = normalize_offering(offering) { model: (data[:id] || data[:name] || data[:model]).to_s, provider: entry[:provider], instance: normalize_instance_id(data[:instance_id] || data[:provider_instance] || entry[:instance]), tier: data[:tier] || entry.dig(:metadata, :tier), size_bytes: data[:size_bytes] || data[:size], capabilities: data[:capabilities] || [], context_length: data[:context_length] || data[:max_model_len] || data.dig(:limits, :context_window), parameter_count: data[:parameter_count] || data.dig(:metadata, :parameter_count) } end rescue StandardError => e report_discovery_failure(entry, e) [] end end |
.model_available?(model, provider: nil, instance: nil) ⇒ Boolean
Check whether a specific model is available from any registered provider.
99 100 101 102 103 104 105 106 107 |
# File 'lib/legion/llm/discovery.rb', line 99 def model_available?(model, provider: nil, instance: nil) psym = provider&.to_sym isym = instance&.to_sym discovered_models.any? do |m| name_matches?(m[:model], model) && (psym.nil? || m[:provider] == psym) && (isym.nil? || m[:instance] == isym) end end |
.model_size(model, provider: nil, instance: nil) ⇒ Object
Return the size in bytes for a discovered model, or nil if unknown.
110 111 112 113 114 115 116 117 118 119 |
# File 'lib/legion/llm/discovery.rb', line 110 def model_size(model, provider: nil, instance: nil) psym = provider&.to_sym isym = instance&.to_sym entry = discovered_models.find do |m| name_matches?(m[:model], model) && (psym.nil? || m[:provider] == psym) && (isym.nil? || m[:instance] == isym) end entry&.dig(:size_bytes) end |
.refresh_all_provider_models ⇒ Object
148 149 150 151 152 153 154 155 156 |
# File 'lib/legion/llm/discovery.rb', line 148 def refresh_all_provider_models return unless defined?(Call::Registry) models = Call::Registry.all_instances.flat_map { |entry| fetch_offering_models(entry) } @discovered_models_cache = models @discovered_models_at = Time.now log.debug "[llm][discovery] action=refresh_discovered_models count=#{models.size}" end |
.refresh_discovered_models!(provider: nil) ⇒ Object
121 122 123 124 125 126 127 128 129 130 |
# File 'lib/legion/llm/discovery.rb', line 121 def refresh_discovered_models!(provider: nil) log.debug "[llm][discovery] action=refresh_discovered_models provider=#{provider || :all}" return unless defined?(Call::Registry) if provider refresh_provider_models(provider) else refresh_all_provider_models end end |
.refresh_provider_models(provider) ⇒ Object
Refresh models for a single provider, preserving other providers’ cached models.
133 134 135 136 137 138 139 140 141 142 143 144 145 146 |
# File 'lib/legion/llm/discovery.rb', line 133 def refresh_provider_models(provider) return unless defined?(Call::Registry) fresh_models = Call::Registry.all_instances .select { |e| (e[:provider] || '').to_sym == provider } .flat_map { |entry| fetch_offering_models(entry) } existing = @discovered_models_cache || [] other_models = existing.reject { |m| (m[:provider] || '').to_sym == provider } @discovered_models_cache = other_models + fresh_models @discovered_models_at = Time.now log.debug "[llm][discovery] action=refresh_provider_models provider=#{provider} count=#{@discovered_models_cache.size}" end |
.reset! ⇒ Object
182 183 184 185 186 187 188 189 190 191 |
# File 'lib/legion/llm/discovery.rb', line 182 def reset! log.debug '[llm][discovery] reset' @can_embed = nil @embedding_provider = nil @embedding_model = nil @embedding_instance = nil @embedding_fallback_chain = nil @discovered_models_cache = nil @discovered_models_at = nil end |
.run ⇒ Object
29 30 31 32 33 34 35 36 37 38 39 40 41 |
# File 'lib/legion/llm/discovery.rb', line 29 def run log.debug '[llm][discovery] run.enter' System.refresh! if discovery_enabled? refresh_discovered_models! models = discovered_models log.info "[llm][discovery] model_count=#{models.size} " \ "models=#{models.map { |m| m[:model] }.join(', ')}" log.info "[llm][discovery] system total_mb=#{System.total_memory_mb} " \ "available_mb=#{System.available_memory_mb}" rescue StandardError => e handle_exception(e, level: :warn, operation: 'llm.discovery.run') end |