Module: Legion::Extensions::Llm::Vllm

Extended by:
AutoRegistration, Logging::Helper, Settings::Helper
Defined in:
lib/legion/extensions/llm/vllm.rb,
lib/legion/extensions/llm/vllm/version.rb,
lib/legion/extensions/llm/vllm/provider.rb,
lib/legion/extensions/llm/vllm/translator.rb,
lib/legion/extensions/llm/vllm/actors/discovery.rb,
lib/legion/extensions/llm/vllm/helpers/callable.rb,
lib/legion/extensions/llm/vllm/runners/discovery.rb,
lib/legion/extensions/llm/vllm/actors/fleet_worker.rb,
lib/legion/extensions/llm/vllm/runners/fleet_worker.rb

Overview

Vllm provider extension namespace.

Defined Under Namespace

Modules: Actor, Helpers, ProviderCanonicalRequestBridge, ProviderManagementMethods, ProviderRenderParseHelpers, Runners, TranslatorChunkBuilderHelpers, TranslatorChunkHelpers, TranslatorMessageHelpers, TranslatorParamHelpers, TranslatorRenderHelpers, TranslatorResponseHelpers, TranslatorThinkingHelpers, TranslatorToolCallHelpers, TranslatorToolCallParseHelpers, TranslatorToolHelpers Classes: Provider, Translator

Constant Summary collapse

PROVIDER_FAMILY =
:vllm
DEFAULT_INSTANCE_TIER =
{ tier: :direct, capabilities: {}, provider_capabilities: { streaming: true } }.freeze
VERSION =
'0.4.8'

Class Method Summary collapse

Class Method Details

.default_settingsObject



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/legion/extensions/llm/vllm.rb', line 28

def self.default_settings
  ::Legion::Extensions::Llm.provider_settings(
    family: PROVIDER_FAMILY,
    instance: {
      endpoint: 'http://localhost:8000',
      tier: :direct,
      transport: :http,
      credentials: { api_key: nil },
      # V2: no enable_thinking default — thinking intent is the
      # canonical request's fact; a shipped config dial is a second
      # authority and a publication/execution contradiction.
      usage: { inference: true, embedding: true, image: true },
      limits: { concurrency: 1 },
      fleet: {
        enabled: false,
        respond_to_requests: false,
        capabilities: %i[chat stream_chat embed]
      }
    }
  )
end

.discover_instancesObject



54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/legion/extensions/llm/vllm.rb', line 54

def self.discover_instances
  instances = {}
  configured = settings[:instances]
  if configured.is_a?(Hash)
    configured.each do |name, config|
      normalized = normalize_instance_config(config)

      # enabled: false is a skip, not a claimable instance: the shared
      # Discovery::Pipeline reads this method as the single claimable
      # source and would otherwise claim + publish a disabled instance
      # as a live lane (an operator's enabled: false is user-space intent).
      next if normalized[:enabled] == false

      next if normalized[:vllm_api_base].to_s.strip.empty?

      instances[name.to_sym] = DEFAULT_INSTANCE_TIER.merge(normalized)
    end
  end
  log.debug { "discovered #{instances.size} vLLM instance(s): #{instances.keys.join(', ')}" }
  instances
end

.infer_tier_from_endpoint(url) ⇒ Object



103
104
105
106
107
108
109
110
111
112
# File 'lib/legion/extensions/llm/vllm.rb', line 103

def self.infer_tier_from_endpoint(url)
  return :direct if url.nil? || url.to_s.empty?

  require 'uri'
  host = URI.parse(url.to_s).host.to_s.downcase
  %w[localhost 127.0.0.1 ::1].include?(host) ? :local : :direct
rescue URI::InvalidURIError => e
  handle_exception(e, level: :warn, handled: true, operation: 'vllm.infer_tier_from_endpoint')
  :direct
end

.normalize_api_base(url) ⇒ Object



99
100
101
# File 'lib/legion/extensions/llm/vllm.rb', line 99

def self.normalize_api_base(url)
  url.to_s.sub(%r{/v1/?\z}, '')
end

.normalize_instance_config(config) ⇒ Object



76
77
78
79
80
81
82
# File 'lib/legion/extensions/llm/vllm.rb', line 76

def self.normalize_instance_config(config)
  normalized = config.to_h.transform_keys(&:to_sym)
  resolve_api_base_aliases(normalized)
  resolve_credentials(normalized)
  normalized[:tier] ||= infer_tier_from_endpoint(normalized[:vllm_api_base])
  normalized
end

.provider_classObject



50
51
52
# File 'lib/legion/extensions/llm/vllm.rb', line 50

def self.provider_class
  Provider
end

.resolve_api_base_aliases(normalized) ⇒ Object



92
93
94
95
96
97
# File 'lib/legion/extensions/llm/vllm.rb', line 92

def self.resolve_api_base_aliases(normalized)
  normalized[:vllm_api_base] ||= normalized.delete(:base_url)
  normalized[:vllm_api_base] ||= normalized.delete(:api_base)
  normalized[:vllm_api_base] ||= normalized.delete(:endpoint)
  normalized[:vllm_api_base] = normalize_api_base(normalized[:vllm_api_base]) if normalized[:vllm_api_base]
end

.resolve_credentials(normalized) ⇒ Object



84
85
86
87
88
89
90
# File 'lib/legion/extensions/llm/vllm.rb', line 84

def self.resolve_credentials(normalized)
  creds = normalized.delete(:credentials)
  return unless creds.is_a?(Hash)

  creds = creds.transform_keys(&:to_sym)
  normalized[:vllm_api_key] ||= creds[:api_key]
end