Module: Legion::Extensions::Llm::Vertex::Runners::Discovery

Extended by:
Discovery
Includes:
Discovery::Pipeline
Included in:
Discovery
Defined in:
lib/legion/extensions/llm/vertex/runners/discovery.rb

Overview

Vertex discovery runner: ONLY the Vertex-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 the provider's STATIC_MODELS list (no HTTP endpoint), served by fetch_raw_models. The overrides are the Vertex API base (per project location), the bearer OAuth access token, the per-project models-list readiness, the project:location/credential physical id, and the offering-draft evidence.

Instance Method Summary collapse

Instance Method Details

#auth_token(instance_cfg:) ⇒ Object

Vertex authenticates with a bearer OAuth access token.



36
37
38
39
# File 'lib/legion/extensions/llm/vertex/runners/discovery.rb', line 36

def auth_token(instance_cfg:)
  token = instance_cfg[:vertex_access_token] || instance_cfg[:access_token]
  token if token.is_a?(String) && !token.strip.empty?
end

#build_callable(instance_cfg:) ⇒ Object



74
75
76
# File 'lib/legion/extensions/llm/vertex/runners/discovery.rb', line 74

def build_callable(instance_cfg:)
  Legion::Extensions::Llm::Vertex::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) ───────────────



98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/legion/extensions/llm/vertex/runners/discovery.rb', line 98

def build_offering_draft(instance_cfg:, instance_key:, model_id:, model_data:)
  model_entry = model_data
  is_embedding = model_entry[:usage_type] == :embedding
  is_gen = model_entry.fetch(:api, :generate_content) == :generate_content

  Legion::Extensions::Llm::Inventory::OfferingDraft.new(
    provider_native_key: model_id,
    model: model_id,
    tier: instance_cfg[:tier] || :cloud,
    operation_evidence: build_operation_evidence(is_embedding: is_embedding, is_generate_content: is_gen),
    capability_evidence: build_capability_evidence(model_entry: model_entry, instance_cfg: instance_cfg),
    context_evidence: absent_value_evidence,
    max_output_evidence: absent_value_evidence,
    embedding_dimensions_evidence: absent_value_evidence,
    model_revision_evidence: absent_value_evidence,
    tokenizer_evidence: absent_value_evidence,
    quota_domains: {},
    metadata: (model_entry: model_entry, instance_key: instance_key),
    publication_source: :provider_static_catalog
  )
end

#catalog_base_url(instance_cfg:) ⇒ Object

── Vertex instance-config keys / connection ─────────────────────



31
32
33
# File 'lib/legion/extensions/llm/vertex/runners/discovery.rb', line 31

def catalog_base_url(instance_cfg:)
  instance_cfg[:vertex_api_base] || "https://#{vertex_location(instance_cfg)}-aiplatform.googleapis.com"
end

#check_health(instance_cfg:) ⇒ Object

Readiness is a safe non-inference GET of the project's models list (the path is per instance: project + location).



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/legion/extensions/llm/vertex/runners/discovery.rb', line 43

def check_health(instance_cfg:)
  project = vertex_project(instance_cfg)
  location = vertex_location(instance_cfg)
  path = "/v1/projects/#{project}/locations/#{location}/publishers/google/models"
  conn = build_connection(base_url: catalog_base_url(instance_cfg: instance_cfg),
                          instance_cfg: instance_cfg, timeout: 10, open_timeout: 5)
  response = conn.get(path)
  Legion::Extensions::Llm::Inventory::ReadinessResult.new(
    ready: response.status == 200,
    reason: "Vertex models-list returned #{response.status}",
    metadata: { status: response.status, base_url: catalog_base_url(instance_cfg: instance_cfg) }
  )
rescue Faraday::ConnectionFailed => e
  handle_exception(e, level: :warn, handled: true, operation: 'vertex.runner.discovery.health')
  readiness_failure(error: e)
rescue StandardError => e
  raise e if discovery_programming_error?(e)

  handle_exception(e, level: :warn, handled: true, operation: 'vertex.runner.discovery.health')
  readiness_failure(error: e)
end

#derive_physical_id(instance_cfg:) ⇒ Object

── Secondary physical id (dedup/diagnostics only) ──────────────── project:location/<8-char credential digest>. Never identity — the instance identity is the operator's config name. Returns nil instead of a fallback when no project or credential is resolvable (discover_instances filters those out; a nil is never claimed under a provider-fallback identity).



84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/legion/extensions/llm/vertex/runners/discovery.rb', line 84

def derive_physical_id(instance_cfg:)
  project = vertex_project(instance_cfg)
  return nil if project.nil? || project.to_s.strip.empty?

  fingerprint = Legion::Extensions::Llm::CredentialSources.credential_fingerprint(
    instance_cfg[:vertex_access_token] || instance_cfg[:vertex_credentials] ||
      instance_cfg[:access_token] || instance_cfg[:credentials]
  )
  return nil if fingerprint.nil?

  "#{project}:#{vertex_location(instance_cfg)}/#{fingerprint}"
end

#fetch_raw_modelsObject

The catalog is static per instance: the provider's STATIC_MODELS list, served as raw model hashes with the entry's :model as the catalog id the pipeline iterates. The pipeline passes instance_cfg as the interface arg; the static catalog does not consume it (Provider#list_models is static too).



70
71
72
# File 'lib/legion/extensions/llm/vertex/runners/discovery.rb', line 70

def fetch_raw_models(*)
  Provider::STATIC_MODELS.map { |entry| { **entry, id: entry[:model] } }
end