lex-llm-vllm 0.1.8 → 0.1.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3dd53d60a8e1aed0d2e1af84c39bf869b31070b927a932d18a69f79990fdd1ec
4
- data.tar.gz: 739b79d90f9b6744b3eef3ff355978820692337f909cb1bb863270fd0d8114d9
3
+ metadata.gz: c7c1de4a067bd42d4675c0485f5e13c4d6fe3a1a17c29a2e23c46d266588dd20
4
+ data.tar.gz: fe503a3a436ef92bcc88015b1d608180d4f98a226cdac4d825c7433c812ee67c
5
5
  SHA512:
6
- metadata.gz: 3f1c76258f803a948b304fca1e887d4b2d8368057914b761033e7cde5f3f44d926209f1598de2acba905f783443a8cd1015318193dfd594a11febacc9821334a
7
- data.tar.gz: af6c18324720d51fb6460b45463955a1944beff9f16edca35b271fb1168dc0a1b3598b4ee3dbce7c1724b0dcef772b83770f330003cea13fee03187761968d23
6
+ metadata.gz: 00bdc87460cf051250b56def2c2a910efe5ff058451a3eff26a7ad1254c5ec9441d3ddb592fa80fd600a83e8479d3593cd1771042e0bacadf0613bb33735ba26
7
+ data.tar.gz: 7d0df28f8edc25b269f64a987e63de90fe89d098e409bbd2dada20ac8f8b981caec3c046a3eeb591c7edb5c025efc80cd480837fc03b81348ab69e160bef9d2b
data/.rubocop.yml CHANGED
@@ -12,7 +12,12 @@ Metrics/BlockLength:
12
12
  Exclude:
13
13
  - "*.gemspec"
14
14
  - spec/**/*
15
+ Metrics/ClassLength:
16
+ Exclude:
17
+ - lib/legion/extensions/llm/vllm/provider.rb
15
18
  Metrics/MethodLength:
16
19
  Enabled: false
20
+ RSpec/ExampleLength:
21
+ Max: 8
17
22
  RSpec/MultipleExpectations:
18
23
  Enabled: false
data/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.1.9 - 2026-04-30
4
+
5
+ - Adopt base provider contract from lex-llm 0.1.9
6
+ - Replace local `RegistryEventBuilder` and `RegistryPublisher` with parameterized base versions
7
+ - Delete local `transport/` directory; base gem now ships shared exchange and message classes
8
+ - Remove deprecated `Provider.register` call; provider options registered via `Configuration.register_provider_options`
9
+ - Simplify `default_settings` to a flat hash (no longer delegates to `ProviderSettings.build`)
10
+ - Override `parse_list_models_response` to populate `context_length` from vLLM `max_model_len` field
11
+ - Require `lex-llm >= 0.1.9`
12
+
3
13
  ## 0.1.8 - 2026-04-30
4
14
 
5
15
  - Add `Legion::Logging::Helper` to all modules and classes for structured logging
data/lex-llm-vllm.gemspec CHANGED
@@ -26,5 +26,5 @@ Gem::Specification.new do |spec|
26
26
  spec.add_dependency 'legion-json', '>= 1.2.1'
27
27
  spec.add_dependency 'legion-logging', '>= 1.3.2'
28
28
  spec.add_dependency 'legion-settings', '>= 1.3.14'
29
- spec.add_dependency 'lex-llm', '>= 0.1.5'
29
+ spec.add_dependency 'lex-llm', '>= 0.1.9'
30
30
  end
@@ -13,16 +13,14 @@ module Legion
13
13
  include Legion::Logging::Helper
14
14
 
15
15
  class << self
16
- attr_writer :registry_publisher
17
-
18
16
  def slug = 'vllm'
19
- def local? = true
17
+ def local? = false
20
18
  def configuration_options = %i[vllm_api_base vllm_api_key]
21
19
  def configuration_requirements = []
22
20
  def capabilities = Capabilities
23
21
 
24
22
  def registry_publisher
25
- @registry_publisher ||= RegistryPublisher.new
23
+ Vllm.registry_publisher
26
24
  end
27
25
  end
28
26
 
@@ -135,6 +133,22 @@ module Legion
135
133
  false
136
134
  end
137
135
 
136
+ def parse_list_models_response(response, provider, capabilities)
137
+ response.body.fetch('data', []).map do |model|
138
+ critical_capabilities = critical_capabilities_for(capabilities, model)
139
+ Legion::Extensions::Llm::Model::Info.from_hash(
140
+ id: model.fetch('id'),
141
+ name: model['id'],
142
+ provider: provider,
143
+ created_at: model_created_at(model['created']),
144
+ context_length: model['max_model_len'],
145
+ capabilities: critical_capabilities,
146
+ modalities: modalities_for_capabilities(critical_capabilities),
147
+ metadata: model
148
+ )
149
+ end
150
+ end
151
+
138
152
  def with_query(path, positional = [], **params)
139
153
  pairs = positional + params.compact.map { |key, value| [key.to_s, value] }
140
154
  return path if pairs.empty?
@@ -4,7 +4,7 @@ module Legion
4
4
  module Extensions
5
5
  module Llm
6
6
  module Vllm
7
- VERSION = '0.1.8'
7
+ VERSION = '0.1.9'
8
8
  end
9
9
  end
10
10
  end
@@ -1,9 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'legion/extensions/llm'
4
- require 'legion/extensions/llm/vllm/registry_event_builder'
5
4
  require 'legion/extensions/llm/vllm/provider'
6
- require 'legion/extensions/llm/vllm/registry_publisher'
7
5
  require 'legion/extensions/llm/vllm/version'
8
6
 
9
7
  module Legion
@@ -17,25 +15,29 @@ module Legion
17
15
  PROVIDER_FAMILY = :vllm
18
16
 
19
17
  def self.default_settings
20
- ::Legion::Extensions::Llm.provider_settings(
21
- family: PROVIDER_FAMILY,
22
- instance: {
23
- endpoint: 'http://localhost:8000',
24
- tier: :private,
25
- transport: :http,
26
- usage: { inference: true, embedding: true },
27
- limits: { concurrency: 8 }
28
- }
29
- )
18
+ {
19
+ enabled: false,
20
+ base_url: 'localhost:8000/v1',
21
+ default_model: nil,
22
+ enable_thinking: true,
23
+ model_whitelist: [],
24
+ model_blacklist: [],
25
+ model_cache_ttl: 300,
26
+ tls: { enabled: false, verify: :peer },
27
+ instances: {}
28
+ }
30
29
  end
31
30
 
32
31
  def self.provider_class
33
32
  Provider
34
33
  end
34
+
35
+ def self.registry_publisher
36
+ @registry_publisher ||= Legion::Extensions::Llm::RegistryPublisher.new(provider_family: PROVIDER_FAMILY)
37
+ end
38
+
39
+ Legion::Extensions::Llm::Configuration.register_provider_options(Provider.configuration_options)
35
40
  end
36
41
  end
37
42
  end
38
43
  end
39
-
40
- Legion::Extensions::Llm::Provider.register(Legion::Extensions::Llm::Vllm::PROVIDER_FAMILY,
41
- Legion::Extensions::Llm::Vllm::Provider)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lex-llm-vllm
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.8
4
+ version: 0.1.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - LegionIO
@@ -57,14 +57,14 @@ dependencies:
57
57
  requirements:
58
58
  - - ">="
59
59
  - !ruby/object:Gem::Version
60
- version: 0.1.5
60
+ version: 0.1.9
61
61
  type: :runtime
62
62
  prerelease: false
63
63
  version_requirements: !ruby/object:Gem::Requirement
64
64
  requirements:
65
65
  - - ">="
66
66
  - !ruby/object:Gem::Version
67
- version: 0.1.5
67
+ version: 0.1.9
68
68
  description: vLLM provider integration for the LegionIO LLM routing framework.
69
69
  email:
70
70
  - matthewdiverson@gmail.com
@@ -84,10 +84,6 @@ files:
84
84
  - lex-llm-vllm.gemspec
85
85
  - lib/legion/extensions/llm/vllm.rb
86
86
  - lib/legion/extensions/llm/vllm/provider.rb
87
- - lib/legion/extensions/llm/vllm/registry_event_builder.rb
88
- - lib/legion/extensions/llm/vllm/registry_publisher.rb
89
- - lib/legion/extensions/llm/vllm/transport/exchanges/llm_registry.rb
90
- - lib/legion/extensions/llm/vllm/transport/messages/registry_event.rb
91
87
  - lib/legion/extensions/llm/vllm/version.rb
92
88
  homepage: https://github.com/LegionIO/lex-llm-vllm
93
89
  licenses:
@@ -1,125 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Legion
4
- module Extensions
5
- module Llm
6
- module Vllm
7
- # Builds sanitized lex-llm registry envelopes for vLLM provider state.
8
- class RegistryEventBuilder
9
- include Legion::Logging::Helper
10
-
11
- def readiness(readiness)
12
- registry_event_class.public_send(
13
- readiness[:ready] ? :available : :unavailable,
14
- provider_offering(readiness),
15
- runtime: runtime_metadata,
16
- health: readiness_health(readiness),
17
- metadata: readiness_metadata(readiness)
18
- )
19
- end
20
-
21
- def model_available(model, readiness:)
22
- registry_event_class.available(
23
- model_offering(model),
24
- runtime: runtime_metadata,
25
- health: model_health(readiness),
26
- metadata: model_metadata(model)
27
- )
28
- end
29
-
30
- private
31
-
32
- def provider_offering(readiness)
33
- {
34
- provider_family: :vllm,
35
- provider_instance: provider_instance,
36
- transport: :http,
37
- model: 'provider-readiness',
38
- usage_type: :inference,
39
- capabilities: [],
40
- health: readiness_health(readiness),
41
- metadata: { lex: :llm_vllm, provider_readiness: true }
42
- }
43
- end
44
-
45
- def model_offering(model)
46
- {
47
- provider_family: :vllm,
48
- provider_instance: provider_instance,
49
- transport: :http,
50
- model: model.id,
51
- usage_type: usage_type_for(model),
52
- capabilities: Array(model.capabilities).map(&:to_sym),
53
- limits: model_limits(model),
54
- metadata: { lex: :llm_vllm, model_name: model.name }.compact
55
- }
56
- end
57
-
58
- def readiness_health(readiness)
59
- health = {
60
- ready: readiness[:ready] == true,
61
- status: readiness[:ready] ? :available : :unavailable,
62
- checked: readiness.dig(:health, :checked) != false
63
- }
64
- add_readiness_error(health, readiness[:health])
65
- end
66
-
67
- def add_readiness_error(health, source)
68
- error = source.is_a?(Hash) ? source : {}
69
- error_class = error[:error] || error['error']
70
- error_message = error[:message] || error['message']
71
- health[:error_class] = error_class if error_class
72
- health[:error] = error_message if error_message
73
- health
74
- end
75
-
76
- def model_health(readiness)
77
- ready = readiness.fetch(:ready, true) == true
78
- { ready:, status: ready ? :available : :degraded }
79
- end
80
-
81
- def readiness_metadata(readiness)
82
- {
83
- extension: :lex_llm_vllm,
84
- provider: :vllm,
85
- configured: readiness[:configured] == true,
86
- live: readiness[:live] == true
87
- }
88
- end
89
-
90
- def model_metadata(model)
91
- { extension: :lex_llm_vllm, provider: :vllm, model_type: model.type }
92
- end
93
-
94
- def runtime_metadata
95
- { node: provider_instance }
96
- end
97
-
98
- def model_limits(model)
99
- {
100
- context_window: model.context_window,
101
- max_output_tokens: model.max_output_tokens
102
- }.compact
103
- end
104
-
105
- def usage_type_for(model)
106
- model.type == 'embedding' ? :embedding : :inference
107
- end
108
-
109
- def provider_instance
110
- configured_node = (::Legion::Settings.dig(:node, :canonical_name) if defined?(::Legion::Settings))
111
- value = configured_node.to_s.strip
112
- value.empty? ? :vllm : value.to_sym
113
- rescue StandardError => e
114
- handle_exception(e, level: :debug, handled: true, operation: 'vllm.registry.provider_instance')
115
- :vllm
116
- end
117
-
118
- def registry_event_class
119
- ::Legion::Extensions::Llm::Routing::RegistryEvent
120
- end
121
- end
122
- end
123
- end
124
- end
125
- end
@@ -1,94 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Legion
4
- module Extensions
5
- module Llm
6
- module Vllm
7
- # Best-effort publisher for vLLM provider availability events.
8
- class RegistryPublisher
9
- include Legion::Logging::Helper
10
-
11
- APP_ID = 'lex-llm-vllm'
12
-
13
- def initialize(builder: RegistryEventBuilder.new)
14
- @builder = builder
15
- end
16
-
17
- def publish_readiness_async(readiness)
18
- log.info { 'publishing readiness event to llm.registry' }
19
- schedule { publish_event(@builder.readiness(readiness)) }
20
- end
21
-
22
- def publish_models_async(models, readiness:)
23
- log.info { "publishing #{Array(models).size} model event(s) to llm.registry" }
24
- schedule do
25
- Array(models).each do |model|
26
- publish_event(@builder.model_available(model, readiness:))
27
- end
28
- end
29
- end
30
-
31
- private
32
-
33
- def schedule(&)
34
- return false unless publishing_available?
35
-
36
- Thread.new do
37
- Thread.current.abort_on_exception = false
38
- yield
39
- rescue StandardError => e
40
- handle_exception(e, level: :debug, handled: true, operation: 'vllm.registry.schedule_thread')
41
- end
42
- rescue StandardError => e
43
- handle_exception(e, level: :debug, handled: true, operation: 'vllm.registry.schedule')
44
- false
45
- end
46
-
47
- def publish_event(event)
48
- return false unless publishing_available?
49
-
50
- message_class.new(event:, app_id: APP_ID).publish(spool: false)
51
- rescue StandardError => e
52
- handle_exception(e, level: :warn, handled: true, operation: 'vllm.registry.publish_event')
53
- false
54
- end
55
-
56
- def publishing_available?
57
- return false unless registry_event_available?
58
- return false unless transport_message_available?
59
- return true unless defined?(::Legion::Transport::Connection)
60
- return true unless ::Legion::Transport::Connection.respond_to?(:session_open?)
61
-
62
- ::Legion::Transport::Connection.session_open?
63
- rescue StandardError => e
64
- handle_exception(e, level: :debug, handled: true, operation: 'vllm.registry.publishing_available?')
65
- false
66
- end
67
-
68
- def registry_event_available?
69
- defined?(::Legion::Extensions::Llm::Routing::RegistryEvent)
70
- end
71
-
72
- def transport_message_available?
73
- return true if message_class_defined?
74
- return false unless defined?(::Legion::Transport::Message) && defined?(::Legion::Transport::Exchange)
75
-
76
- require 'legion/extensions/llm/vllm/transport/messages/registry_event'
77
- message_class_defined?
78
- rescue LoadError => e
79
- handle_exception(e, level: :debug, handled: true, operation: 'vllm.registry.transport_load')
80
- false
81
- end
82
-
83
- def message_class_defined?
84
- defined?(::Legion::Extensions::Llm::Vllm::Transport::Messages::RegistryEvent)
85
- end
86
-
87
- def message_class
88
- ::Legion::Extensions::Llm::Vllm::Transport::Messages::RegistryEvent
89
- end
90
- end
91
- end
92
- end
93
- end
94
- end
@@ -1,24 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Legion
4
- module Extensions
5
- module Llm
6
- module Vllm
7
- module Transport
8
- module Exchanges
9
- # Topic exchange for vLLM provider availability events.
10
- class LlmRegistry < ::Legion::Transport::Exchange
11
- def exchange_name
12
- 'llm.registry'
13
- end
14
-
15
- def default_type
16
- 'topic'
17
- end
18
- end
19
- end
20
- end
21
- end
22
- end
23
- end
24
- end
@@ -1,42 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'legion/extensions/llm/vllm/transport/exchanges/llm_registry'
4
-
5
- module Legion
6
- module Extensions
7
- module Llm
8
- module Vllm
9
- module Transport
10
- module Messages
11
- # Publishes lex-llm RegistryEvent envelopes to the llm.registry exchange.
12
- class RegistryEvent < ::Legion::Transport::Message
13
- def initialize(event:, **options)
14
- super(**event.to_h.merge(options))
15
- end
16
-
17
- def exchange
18
- Transport::Exchanges::LlmRegistry
19
- end
20
-
21
- def routing_key
22
- @options[:routing_key] || "llm.registry.#{@options.fetch(:event_type)}"
23
- end
24
-
25
- def type
26
- 'llm.registry.event'
27
- end
28
-
29
- def app_id
30
- @options[:app_id] || RegistryPublisher::APP_ID
31
- end
32
-
33
- def persistent # rubocop:disable Naming/PredicateMethod
34
- false
35
- end
36
- end
37
- end
38
- end
39
- end
40
- end
41
- end
42
- end