Module: Legion::Extensions::Llm::Anthropic::Runners::Discovery

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

Overview

Anthropic discovery runner: ONLY the Anthropic-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 OpenAI-shaped (GET /v1/models -> body), so the pipeline's default fetch_raw_models / model_id_from are reused. The overrides are the Anthropic auth scheme (x-api-key + anthropic-version, not bearer), the /v1/models readiness, the 8-char-credential physical id, and the offering-draft evidence.

Instance Method Summary collapse

Instance Method Details

#apply_auth_headers(faraday:, instance_cfg:) ⇒ Object

Anthropic authenticates with x-api-key + anthropic-version, not a bearer Authorization header.



45
46
47
48
49
50
51
52
# File 'lib/legion/extensions/llm/anthropic/runners/discovery.rb', line 45

def apply_auth_headers(faraday:, instance_cfg:)
  api_key = instance_cfg[:anthropic_api_key] || instance_cfg.dig(:credentials, :api_key)
  return unless api_key.is_a?(String) && !api_key.strip.empty?

  faraday.headers['x-api-key'] = api_key
  faraday.headers['anthropic-version'] =
    instance_cfg[:api_version] || instance_cfg[:anthropic_version] || '2023-10-16'
end

#auth_token(instance_cfg:) ⇒ Object



38
39
40
41
# File 'lib/legion/extensions/llm/anthropic/runners/discovery.rb', line 38

def auth_token(instance_cfg:)
  token = instance_cfg[:anthropic_api_key] || instance_cfg.dig(:credentials, :api_key)
  token if token.is_a?(String) && !token.strip.empty?
end

#build_callable(instance_cfg:) ⇒ Object



57
58
59
# File 'lib/legion/extensions/llm/anthropic/runners/discovery.rb', line 57

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



83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/legion/extensions/llm/anthropic/runners/discovery.rb', line 83

def build_offering_draft(instance_cfg:, instance_key:, model_id:, model_data:)
  tier = instance_cfg[:tier] || :frontier

  Legion::Extensions::Llm::Inventory::OfferingDraft.new(
    provider_native_key:           model_id,
    model:                         model_id,
    tier:                          tier,
    operation_evidence:            build_operation_evidence(model_id: model_id, model_data: model_data),
    capability_evidence:           build_capability_evidence(model_id: model_id, model_data: model_data),
    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:                      { raw_model: model_id, instance_id: instance_key.instance_id },
    publication_source:            :provider_catalog
  )
end

#catalog_base_url(instance_cfg:) ⇒ Object

── Anthropic instance-config keys / connection ───────────────────



34
35
36
# File 'lib/legion/extensions/llm/anthropic/runners/discovery.rb', line 34

def catalog_base_url(instance_cfg:)
  instance_cfg[:anthropic_api_base] || 'https://api.anthropic.com'
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.



65
66
67
68
69
70
71
# File 'lib/legion/extensions/llm/anthropic/runners/discovery.rb', line 65

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



73
74
75
76
77
78
79
80
# File 'lib/legion/extensions/llm/anthropic/runners/discovery.rb', line 73

def extract_host_port(url:)
  uri = URI.parse(url.to_s)
  "#{uri.host || 'api.anthropic.com'}:#{uri.port}"
rescue URI::InvalidURIError => e
  handle_exception(e, level: :warn, handled: true,
                      operation: 'anthropic.runner.discovery.extract_host_port', url: url.to_s)
  'unknown:0'
end

#health_pathObject

Readiness is a safe non-inference GET /v1/models.



55
# File 'lib/legion/extensions/llm/anthropic/runners/discovery.rb', line 55

def health_path = '/v1/models'