Module: Legion::Extensions::Llm::Gemini::Runners::Discovery
- Extended by:
- Discovery
- Includes:
- Discovery::Pipeline
- Included in:
- Discovery
- Defined in:
- lib/legion/extensions/llm/gemini/runners/discovery.rb
Overview
Gemini discovery runner: ONLY the Gemini-specific work. The generic reconcile / claim / activate / probe (cadence + reactive) / replace / weight-publication / health-display pipeline is mixed in from the shared Discovery::Pipeline. Weight is NOT computed here — the shared WeightReconciler recomputes it from live settings at publish.
The catalog is Gemini's own list-models API (GET models ->
body, entries named models/<id>), not OpenAI-shaped, so
fetch_raw_models / model_id_from / check_health are overridden.
The overrides are the x-goog-api-key auth header (not bearer), the
/v1beta base URL, the 8-char-credential physical id, and the
offering-draft evidence.
Instance Method Summary collapse
-
#apply_auth_headers(faraday:, instance_cfg:) ⇒ Object
Gemini authenticates with the x-goog-api-key header, not a bearer Authorization header.
- #auth_token(instance_cfg:) ⇒ Object
- #build_callable(instance_cfg:) ⇒ Object
-
#build_offering_draft(instance_cfg:, instance_key:, model_id:, model_data:) ⇒ Object
── Offering draft (evidence + metadata; NO weight) ───────────────.
-
#catalog_base_url(instance_cfg:) ⇒ Object
── Gemini instance-config keys / connection ─────────────────────.
-
#check_health(instance_cfg:) ⇒ Object
Readiness is a safe non-inference models listing (GET models?pageSize=1).
-
#derive_physical_id(instance_cfg:) ⇒ Object
── Secondary physical id (dedup/diagnostics only) ──────────────── host:port, or host:port/ak:<8-char credential digest> when a key is present.
- #extract_host_port(url:) ⇒ Object
- #fetch_raw_models(instance_cfg:) ⇒ Object
-
#model_id_from(model_data) ⇒ Object
The models API lists each entry under :name as
models/<id>.
Instance Method Details
#apply_auth_headers(faraday:, instance_cfg:) ⇒ Object
Gemini authenticates with the x-goog-api-key header, not a bearer Authorization header.
48 49 50 51 52 53 54 |
# File 'lib/legion/extensions/llm/gemini/runners/discovery.rb', line 48 def apply_auth_headers(faraday:, instance_cfg:) api_key = instance_cfg[:gemini_api_key] || instance_cfg[:api_key] || instance_cfg.dig(:credentials, :api_key) return unless api_key.is_a?(String) && !api_key.strip.empty? faraday.headers['x-goog-api-key'] = api_key end |
#auth_token(instance_cfg:) ⇒ Object
40 41 42 43 44 |
# File 'lib/legion/extensions/llm/gemini/runners/discovery.rb', line 40 def auth_token(instance_cfg:) token = instance_cfg[:gemini_api_key] || instance_cfg[:api_key] || instance_cfg.dig(:credentials, :api_key) token if token.is_a?(String) && !token.strip.empty? end |
#build_callable(instance_cfg:) ⇒ Object
100 101 102 |
# File 'lib/legion/extensions/llm/gemini/runners/discovery.rb', line 100 def build_callable(instance_cfg:) Legion::Extensions::Llm::Gemini::Helpers::Callable.new(instance_cfg: instance_cfg, logger: log) end |
#build_offering_draft(instance_cfg:, instance_key:, model_id:, model_data:) ⇒ Object
── Offering draft (evidence + metadata; NO weight) ───────────────
126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 |
# File 'lib/legion/extensions/llm/gemini/runners/discovery.rb', line 126 def build_offering_draft(instance_cfg:, instance_key:, model_id:, model_data:) tier = instance_cfg[:tier] || :frontier generation_methods = extract_generation_methods(model_data: model_data) Legion::Extensions::Llm::Inventory::OfferingDraft.new( provider_native_key: model_id, model: model_id, tier: tier, operation_evidence: build_operation_evidence(generation_methods: generation_methods), capability_evidence: build_capability_evidence(generation_methods: generation_methods), context_evidence: build_context_evidence(model_data: model_data), max_output_evidence: build_max_output_evidence(model_data: model_data), embedding_dimensions_evidence: ( model_data: model_data, generation_methods: generation_methods ), model_revision_evidence: build_model_revision_evidence(model_data: model_data), tokenizer_evidence: build_tokenizer_evidence, quota_domains: {}, metadata: (model_data: model_data, instance_key: instance_key), publication_source: :provider_catalog ) end |
#catalog_base_url(instance_cfg:) ⇒ Object
── Gemini instance-config keys / connection ─────────────────────
35 36 37 38 |
# File 'lib/legion/extensions/llm/gemini/runners/discovery.rb', line 35 def catalog_base_url(instance_cfg:) (instance_cfg[:gemini_api_base] || instance_cfg[:endpoint] || 'https://generativelanguage.googleapis.com/v1beta').to_s end |
#check_health(instance_cfg:) ⇒ Object
Readiness is a safe non-inference models listing (GET models?pageSize=1). The probe is overridden rather than health_path: an absolute path would resolve against the host root and drop the /v1beta prefix of the base URL.
60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
# File 'lib/legion/extensions/llm/gemini/runners/discovery.rb', line 60 def check_health(instance_cfg:) base_url = catalog_base_url(instance_cfg: instance_cfg) conn = build_connection(base_url: base_url, instance_cfg: instance_cfg, timeout: 15, open_timeout: 5) response = conn.get('models', { pageSize: 1 }) models_api_readiness(response: response, base_url: base_url) rescue Faraday::ConnectionFailed => e handle_exception(e, level: :warn, handled: true, operation: 'gemini.runner.discovery.health.connection', base_url: base_url) readiness_error_result(error: e, reason: "Gemini models API connection failed: #{e.}") rescue StandardError => e raise e if discovery_programming_error?(e) handle_exception(e, level: :warn, handled: true, operation: 'gemini.runner.discovery.health', base_url: base_url) readiness_error_result(error: e, reason: "Gemini models API error: #{e.}") end |
#derive_physical_id(instance_cfg:) ⇒ Object
── Secondary physical id (dedup/diagnostics only) ──────────────── host:port, or host:port/ak:<8-char credential digest> when a key is present. Never identity — the instance identity is the operator's config name.
108 109 110 111 112 113 114 |
# File 'lib/legion/extensions/llm/gemini/runners/discovery.rb', line 108 def derive_physical_id(instance_cfg:) host_port = extract_host_port(url: catalog_base_url(instance_cfg: instance_cfg)) api_key = auth_token(instance_cfg: instance_cfg) return "#{host_port}/ak:#{::Digest::SHA256.hexdigest(api_key)[0, 8]}" if api_key host_port end |
#extract_host_port(url:) ⇒ Object
116 117 118 119 120 121 122 123 |
# File 'lib/legion/extensions/llm/gemini/runners/discovery.rb', line 116 def extract_host_port(url:) uri = URI.parse(url.to_s) "#{uri.host || 'generativelanguage.googleapis.com'}:#{uri.port}" rescue URI::InvalidURIError => e handle_exception(e, level: :warn, handled: true, operation: 'gemini.runner.discovery.extract_host_port', url: url.to_s) 'unknown:0' end |
#fetch_raw_models(instance_cfg:) ⇒ Object
79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
# File 'lib/legion/extensions/llm/gemini/runners/discovery.rb', line 79 def fetch_raw_models(instance_cfg:) base_url = catalog_base_url(instance_cfg: instance_cfg) conn = build_connection(base_url: base_url, instance_cfg: instance_cfg, timeout: 15, open_timeout: 5) response = conn.get('models') unless response.status.between?( 200, 299 ) raise CatalogFetchFailure, "catalog fetch returned HTTP #{response.status}" end Array(Legion::JSON.load(response.body)[:models]) end |
#model_id_from(model_data) ⇒ Object
The models API lists each entry under :name as models/<id>.
95 96 97 98 |
# File 'lib/legion/extensions/llm/gemini/runners/discovery.rb', line 95 def model_id_from(model_data) name = model_data[:name] || model_data['name'] || '' name.to_s.delete_prefix('models/') end |