lex-llm-openai 0.1.7 → 0.2.0

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: '0846dcde3031149be5687b648947d0ad1d450e8ff7cb20684d6cc0dd1754fc78'
4
- data.tar.gz: ccd47540f56d1d8b7f43bcafb42dc2e0b5edc22e4083d216780d82731d94aa5d
3
+ metadata.gz: 3adf2416815789eee25cb13dc0ceaadda14549fa6f897ea8c0216a5ebd728793
4
+ data.tar.gz: 317ad6bcc34b252a9026e9aaae5a9a6fe8f850ab67c7e50e62f67a5c43d3538f
5
5
  SHA512:
6
- metadata.gz: ba683c96276ec71d4f420688e60613a2db35a22c0af2e726050ce1b1ff2b4f8323fc541581d67cae81317252bc561bb9922c2ac45fd7068d8e09b134c15a9e34
7
- data.tar.gz: 7ec2d0bac937e45460281501bd74c41c08ab987f48c631c82fe41ea77d2bc59b53a2974bbff5e5d3185dcd65905b34cca7cbcf6af73ea2e6af142506560d597d
6
+ metadata.gz: 6e5b1684b8a9a328278bb0ab039940f924f43943847fe45d0b485c82702f4cbb426b142e751d407ed736778b9923bfffd8e8b323549bef335c99056f989c4250
7
+ data.tar.gz: 0ff1be0c6ccd2fa4e24a3c9bb8dc816e6dc249ff6a88177240be0f5fc4aedade94cb9955d752f28570af099a64e2dea232e3d7bdef0587ab7ef8a308dbe23684
data/.rubocop.yml CHANGED
@@ -12,7 +12,11 @@ Metrics/BlockLength:
12
12
  Exclude:
13
13
  - "*.gemspec"
14
14
  - spec/**/*
15
+ Metrics/ClassLength:
16
+ Max: 200
15
17
  Metrics/MethodLength:
16
18
  Enabled: false
19
+ RSpec/ExampleLength:
20
+ Max: 10
17
21
  RSpec/MultipleExpectations:
18
22
  Enabled: false
data/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.2.0] - 2026-04-30
4
+ - **BREAKING**: Adopt base contract from lex-llm 0.1.9; require `lex-llm >= 0.1.9`
5
+ - Replace `provider_settings`-based `default_settings` with flat provider defaults (enabled, default_model, api_key, etc.)
6
+ - Remove deprecated `Provider.register` call; configuration options are now registered at class-load time
7
+ - Delete local `RegistryPublisher` and `RegistryEventBuilder`; use parameterized base classes from lex-llm
8
+ - Delete local `transport/` directory (exchanges, messages); use shared transport from lex-llm
9
+ - Add static `CAPABILITY_MAP` for known OpenAI model families; `list_models` now returns `Model::Info` structs directly
10
+ - `list_models` no longer delegates to `parse_list_models_response`; builds `Model::Info` via the static capability map
11
+
12
+ ## [0.1.8] - 2026-04-30
13
+ - Add Legion::Logging::Helper to all modules and classes for structured observability
14
+ - Replace bare rescue blocks with handle_exception for unified error telemetry
15
+ - Add info-level action logging for provider registration, model listing, model retrieval, and registry publishing
16
+ - Remove manual log_publish_failure helper in favor of handle_exception
17
+ - Update README to reflect current capabilities and architecture
18
+
3
19
  ## [0.1.7] - 2026-04-30
4
20
  - Enable stream_usage_supported? for streaming token usage reporting
5
21
 
data/README.md CHANGED
@@ -9,19 +9,42 @@ Load it with `require 'legion/extensions/llm/openai'`.
9
9
  ## What It Provides
10
10
 
11
11
  - `Legion::Extensions::Llm::Provider` registration as `:openai`
12
- - chat completions through `POST /v1/chat/completions`
13
- - streaming chat completions through the same chat completions endpoint
14
- - model discovery through `GET /v1/models`
15
- - model retrieval through `GET /v1/models/{model}`
16
- - embeddings through `POST /v1/embeddings`
17
- - moderation through `POST /v1/moderations`
18
- - image generation through `POST /v1/images/generations`
19
- - image editing through `POST /v1/images/edits`
20
- - image variation endpoint helper for `POST /v1/images/variations`
21
- - audio transcription through `POST /v1/audio/transcriptions`
22
- - shared OpenAI-compatible request/response mapping via `Legion::Extensions::Llm::Provider::OpenAICompatible`
23
- - normalized chat, embedding, moderation, image, and audio capability mapping for discovered models
24
- - shared fleet/default settings via `Legion::Extensions::Llm.provider_settings`
12
+ - Chat completions via `POST /v1/chat/completions`
13
+ - Streaming chat completions (same endpoint, `stream: true`)
14
+ - Model discovery via `GET /v1/models`
15
+ - Model retrieval via `GET /v1/models/{model}`
16
+ - Embeddings via `POST /v1/embeddings`
17
+ - Moderation via `POST /v1/moderations`
18
+ - Image generation via `POST /v1/images/generations`
19
+ - Image editing via `POST /v1/images/edits`
20
+ - Image variation via `POST /v1/images/variations`
21
+ - Audio transcription via `POST /v1/audio/transcriptions`
22
+ - Streaming token usage reporting (`stream_usage_supported?`)
23
+ - Shared OpenAI-compatible request/response mapping via `Legion::Extensions::Llm::Provider::OpenAICompatible`
24
+ - Normalized chat, embedding, moderation, image, and audio capability mapping for discovered models
25
+ - Shared fleet/default settings via `Legion::Extensions::Llm.provider_settings`
26
+ - Best-effort `llm.registry` availability event publishing for discovered models
27
+
28
+ ## Architecture
29
+
30
+ ```
31
+ Legion::Extensions::Llm::Openai
32
+ ├── Provider # OpenAI provider implementation (chat, models, embeddings, etc.)
33
+ │ └── Capabilities # Model family capability predicates
34
+ ├── RegistryPublisher # Async llm.registry event publisher
35
+ ├── RegistryEventBuilder # Sanitized registry event envelope builder
36
+ └── Transport
37
+ ├── Exchanges::LlmRegistry # Topic exchange for llm.registry
38
+ └── Messages::RegistryEvent # AMQP message for registry events
39
+ ```
40
+
41
+ ## Observability
42
+
43
+ All classes include `Legion::Logging::Helper` (when available) providing:
44
+
45
+ - Structured `handle_exception` calls on every rescue block
46
+ - Info-level action logging for provider registration, model listing, model retrieval, and registry publishing
47
+ - Automatic log segment derivation and component type tagging
25
48
 
26
49
  ## Defaults
27
50
 
@@ -47,6 +70,9 @@ Legion::Extensions::Llm::Openai.default_settings
47
70
  ```ruby
48
71
  Legion::Extensions::Llm.configure do |config|
49
72
  config.openai_api_key = ENV.fetch("OPENAI_API_KEY")
73
+ config.openai_api_base = nil # defaults to https://api.openai.com
74
+ config.openai_organization_id = nil # optional OpenAI-Organization header
75
+ config.openai_project_id = nil # optional OpenAI-Project header
50
76
  config.default_model = "gpt-5.2"
51
77
  config.default_embedding_model = "text-embedding-3-small"
52
78
  config.default_moderation_model = "omni-moderation-latest"
@@ -54,3 +80,25 @@ Legion::Extensions::Llm.configure do |config|
54
80
  config.default_transcription_model = "gpt-4o-transcribe"
55
81
  end
56
82
  ```
83
+
84
+ ## Dependencies
85
+
86
+ | Gem | Purpose |
87
+ |-----|---------|
88
+ | `lex-llm` (>= 0.1.5) | Shared provider contract, fleet settings, routing |
89
+ | `legion-json` (>= 1.2.1) | JSON serialization |
90
+ | `legion-logging` (>= 1.3.2) | Structured logging via Helper |
91
+ | `legion-settings` (>= 1.3.14) | Configuration management |
92
+
93
+ ## Development
94
+
95
+ ```bash
96
+ bundle install
97
+ bundle exec rspec --format progress # all pass
98
+ bundle exec rubocop -A # auto-fix
99
+ bundle exec rubocop # lint check (0 offenses)
100
+ ```
101
+
102
+ ## License
103
+
104
+ MIT
@@ -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.2.0'
30
30
  end
@@ -9,6 +9,84 @@ module Legion
9
9
  # OpenAI provider implementation for the Legion::Extensions::Llm base provider contract.
10
10
  class Provider < Legion::Extensions::Llm::Provider
11
11
  include Legion::Extensions::Llm::Provider::OpenAICompatible
12
+ include Legion::Logging::Helper
13
+
14
+ # ── Static capability map for known OpenAI model families ──────
15
+ # Maps model-id prefixes to a set of capabilities and modality
16
+ # vectors. Used by list_models to build Model::Info structs from
17
+ # the raw /v1/models response.
18
+ CAPABILITY_MAP = {
19
+ 'gpt-4o' => {
20
+ capabilities: %i[completion streaming function_calling vision structured_output],
21
+ modalities_input: %w[text image audio],
22
+ modalities_output: %w[text]
23
+ },
24
+ 'gpt-4.1' => {
25
+ capabilities: %i[completion streaming function_calling vision structured_output],
26
+ modalities_input: %w[text image],
27
+ modalities_output: %w[text]
28
+ },
29
+ 'gpt-4' => {
30
+ capabilities: %i[completion streaming function_calling vision],
31
+ modalities_input: %w[text image],
32
+ modalities_output: %w[text]
33
+ },
34
+ 'gpt-5' => {
35
+ capabilities: %i[completion streaming function_calling vision structured_output reasoning],
36
+ modalities_input: %w[text image],
37
+ modalities_output: %w[text]
38
+ },
39
+ 'o4' => {
40
+ capabilities: %i[completion streaming function_calling vision reasoning],
41
+ modalities_input: %w[text image],
42
+ modalities_output: %w[text]
43
+ },
44
+ 'o3' => {
45
+ capabilities: %i[completion streaming function_calling vision reasoning],
46
+ modalities_input: %w[text image],
47
+ modalities_output: %w[text]
48
+ },
49
+ 'o1' => {
50
+ capabilities: %i[completion streaming function_calling vision reasoning],
51
+ modalities_input: %w[text image],
52
+ modalities_output: %w[text]
53
+ },
54
+ 'text-embedding-' => {
55
+ capabilities: %i[embedding],
56
+ modalities_input: %w[text],
57
+ modalities_output: %w[embeddings]
58
+ },
59
+ 'omni-moderation' => {
60
+ capabilities: %i[moderation],
61
+ modalities_input: %w[text image],
62
+ modalities_output: %w[moderation]
63
+ },
64
+ 'text-moderation' => {
65
+ capabilities: %i[moderation],
66
+ modalities_input: %w[text],
67
+ modalities_output: %w[moderation]
68
+ },
69
+ 'gpt-image' => {
70
+ capabilities: %i[image_generation],
71
+ modalities_input: %w[text image],
72
+ modalities_output: %w[image]
73
+ },
74
+ 'dall-e' => {
75
+ capabilities: %i[image_generation],
76
+ modalities_input: %w[text],
77
+ modalities_output: %w[image]
78
+ },
79
+ 'whisper' => {
80
+ capabilities: %i[audio_transcription],
81
+ modalities_input: %w[audio],
82
+ modalities_output: %w[text]
83
+ },
84
+ 'tts' => {
85
+ capabilities: %i[audio_generation],
86
+ modalities_input: %w[text],
87
+ modalities_output: %w[audio]
88
+ }
89
+ }.freeze
12
90
 
13
91
  class << self
14
92
  attr_writer :registry_publisher
@@ -29,7 +107,7 @@ module Legion
29
107
  def capabilities = Capabilities
30
108
 
31
109
  def registry_publisher
32
- @registry_publisher ||= RegistryPublisher.new
110
+ @registry_publisher ||= Legion::Extensions::Llm::RegistryPublisher.new(provider_family: :openai)
33
111
  end
34
112
  end
35
113
 
@@ -94,17 +172,66 @@ module Legion
94
172
  def images_url(with: nil, mask: nil) = super
95
173
 
96
174
  def retrieve_model(model)
175
+ log.info("Retrieving model: #{model}")
97
176
  connection.get("#{models_url}/#{model}").body
177
+ rescue StandardError => e
178
+ handle_exception(e, level: :error, handled: true,
179
+ operation: 'retrieve_model')
180
+ raise
98
181
  end
99
182
 
100
183
  def list_models
101
- super.tap do |models|
102
- self.class.registry_publisher.publish_models_async(models, readiness: readiness(live: false))
103
- end
184
+ log.info('Listing OpenAI models')
185
+ raw = connection.get(models_url)
186
+ models = build_model_infos(raw.body)
187
+ log.info("Discovered #{models.size} OpenAI models")
188
+ self.class.registry_publisher.publish_models_async(models, readiness: readiness(live: false))
189
+ models
190
+ rescue StandardError => e
191
+ handle_exception(e, level: :error, handled: true,
192
+ operation: 'list_models')
193
+ raise
104
194
  end
105
195
 
106
196
  private
107
197
 
198
+ def build_model_infos(body)
199
+ body.fetch('data', []).map do |raw_model|
200
+ id = raw_model.fetch('id')
201
+ cap_entry = capability_entry_for(id)
202
+
203
+ Legion::Extensions::Llm::Model::Info.new(
204
+ id: id,
205
+ name: id,
206
+ provider: :openai,
207
+ capabilities: cap_entry[:capabilities],
208
+ modalities_input: cap_entry[:modalities_input],
209
+ modalities_output: cap_entry[:modalities_output],
210
+ metadata: {
211
+ created_at: model_created_at(raw_model['created']),
212
+ raw: raw_model
213
+ }.compact
214
+ )
215
+ end
216
+ end
217
+
218
+ def capability_entry_for(model_id)
219
+ CAPABILITY_MAP.each do |prefix, entry|
220
+ return entry if model_id.start_with?(prefix)
221
+ end
222
+
223
+ # Fallback for unknown models: assume chat-capable
224
+ {
225
+ capabilities: %i[completion streaming],
226
+ modalities_input: %w[text],
227
+ modalities_output: %w[text]
228
+ }
229
+ end
230
+
231
+ def model_created_at(value)
232
+ value.is_a?(Numeric) ? Time.at(value).utc : value
233
+ end
234
+
108
235
  def maybe_normalize_temperature(temperature, model)
109
236
  model_id = model.id.to_s
110
237
  return nil if model_id.include?('-search')
@@ -117,3 +244,8 @@ module Legion
117
244
  end
118
245
  end
119
246
  end
247
+
248
+ # Register configuration options so Legion::Extensions::Llm::Configuration knows about them.
249
+ Legion::Extensions::Llm::Configuration.register_provider_options(
250
+ Legion::Extensions::Llm::Openai::Provider.configuration_options
251
+ )
@@ -4,7 +4,7 @@ module Legion
4
4
  module Extensions
5
5
  module Llm
6
6
  module Openai
7
- VERSION = '0.1.7'
7
+ VERSION = '0.2.0'
8
8
  end
9
9
  end
10
10
  end
@@ -1,8 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'legion/extensions/llm'
4
- require 'legion/extensions/llm/openai/registry_event_builder'
5
- require 'legion/extensions/llm/openai/registry_publisher'
6
4
  require 'legion/extensions/llm/openai/provider'
7
5
  require 'legion/extensions/llm/openai/version'
8
6
 
@@ -12,21 +10,23 @@ module Legion
12
10
  # Openai provider extension namespace.
13
11
  module Openai
14
12
  extend ::Legion::Extensions::Core if ::Legion::Extensions.const_defined?(:Core, false)
13
+ extend ::Legion::Logging::Helper
15
14
 
16
15
  PROVIDER_FAMILY = :openai
17
16
 
18
17
  def self.default_settings
19
- ::Legion::Extensions::Llm.provider_settings(
20
- family: PROVIDER_FAMILY,
21
- instance: {
22
- endpoint: 'https://api.openai.com',
23
- tier: :frontier,
24
- transport: :http,
25
- credentials: { api_key: 'env://OPENAI_API_KEY' },
26
- usage: { inference: true, embedding: true, moderation: true, image: true, audio: true },
27
- limits: { concurrency: 4 }
28
- }
29
- )
18
+ {
19
+ enabled: false,
20
+ default_model: 'gpt-4o',
21
+ api_key: nil,
22
+ organization_id: nil,
23
+ project_id: nil,
24
+ model_whitelist: [],
25
+ model_blacklist: [],
26
+ model_cache_ttl: 3600,
27
+ tls: { enabled: false, verify: :peer },
28
+ instances: {}
29
+ }
30
30
  end
31
31
 
32
32
  def self.provider_class
@@ -36,6 +36,3 @@ module Legion
36
36
  end
37
37
  end
38
38
  end
39
-
40
- Legion::Extensions::Llm::Provider.register(Legion::Extensions::Llm::Openai::PROVIDER_FAMILY,
41
- Legion::Extensions::Llm::Openai::Provider)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lex-llm-openai
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.7
4
+ version: 0.2.0
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.2.0
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.2.0
68
68
  description: OpenAI 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-openai.gemspec
85
85
  - lib/legion/extensions/llm/openai.rb
86
86
  - lib/legion/extensions/llm/openai/provider.rb
87
- - lib/legion/extensions/llm/openai/registry_event_builder.rb
88
- - lib/legion/extensions/llm/openai/registry_publisher.rb
89
- - lib/legion/extensions/llm/openai/transport/exchanges/llm_registry.rb
90
- - lib/legion/extensions/llm/openai/transport/messages/registry_event.rb
91
87
  - lib/legion/extensions/llm/openai/version.rb
92
88
  homepage: https://github.com/LegionIO/lex-llm-openai
93
89
  licenses:
@@ -1,72 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Legion
4
- module Extensions
5
- module Llm
6
- module Openai
7
- # Builds sanitized lex-llm registry envelopes for OpenAI provider state.
8
- class RegistryEventBuilder
9
- def model_available(model, readiness:)
10
- registry_event_class.available(
11
- model_offering(model),
12
- runtime: runtime_metadata,
13
- health: model_health(readiness),
14
- metadata: model_metadata(model)
15
- )
16
- end
17
-
18
- private
19
-
20
- def model_offering(model)
21
- {
22
- provider_family: :openai,
23
- provider_instance: provider_instance,
24
- transport: :http,
25
- model: model.id,
26
- usage_type: usage_type_for(model),
27
- capabilities: Array(model.capabilities).map(&:to_sym),
28
- limits: model_limits(model),
29
- metadata: { lex: :llm_openai, model_name: model.name }.compact
30
- }
31
- end
32
-
33
- def model_health(readiness)
34
- ready = readiness.fetch(:ready, true) == true
35
- { ready:, status: ready ? :available : :degraded }
36
- end
37
-
38
- def model_metadata(model)
39
- { extension: :lex_llm_openai, provider: :openai, model_type: model.type }
40
- end
41
-
42
- def runtime_metadata
43
- { node: provider_instance }
44
- end
45
-
46
- def model_limits(model)
47
- {
48
- context_window: model.context_window,
49
- max_output_tokens: model.max_output_tokens
50
- }.compact
51
- end
52
-
53
- def usage_type_for(model)
54
- model.type == 'embedding' ? :embedding : :inference
55
- end
56
-
57
- def provider_instance
58
- configured_node = (::Legion::Settings.dig(:node, :canonical_name) if defined?(::Legion::Settings))
59
- value = configured_node.to_s.strip
60
- value.empty? ? :openai : value.to_sym
61
- rescue StandardError
62
- :openai
63
- end
64
-
65
- def registry_event_class
66
- ::Legion::Extensions::Llm::Routing::RegistryEvent
67
- end
68
- end
69
- end
70
- end
71
- end
72
- end
@@ -1,96 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Legion
4
- module Extensions
5
- module Llm
6
- module Openai
7
- # Best-effort publisher for OpenAI provider availability events.
8
- class RegistryPublisher
9
- APP_ID = 'lex-llm-openai'
10
-
11
- def initialize(builder: RegistryEventBuilder.new)
12
- @builder = builder
13
- end
14
-
15
- def publish_models_async(models, readiness:)
16
- schedule do
17
- Array(models).each do |model|
18
- publish_event(@builder.model_available(model, readiness:))
19
- end
20
- end
21
- end
22
-
23
- private
24
-
25
- def schedule(&)
26
- return false unless publishing_available?
27
-
28
- Thread.new do
29
- Thread.current.abort_on_exception = false
30
- yield
31
- rescue StandardError => e
32
- log_publish_failure(e, level: :debug)
33
- end
34
- rescue StandardError => e
35
- log_publish_failure(e, level: :debug)
36
- false
37
- end
38
-
39
- def publish_event(event)
40
- return false unless publishing_available?
41
-
42
- message_class.new(event:, app_id: APP_ID).publish(spool: false)
43
- rescue StandardError => e
44
- log_publish_failure(e)
45
- false
46
- end
47
-
48
- def publishing_available?
49
- return false unless registry_event_available?
50
- return false unless transport_message_available?
51
- return true unless defined?(::Legion::Transport::Connection)
52
- return true unless ::Legion::Transport::Connection.respond_to?(:session_open?)
53
-
54
- ::Legion::Transport::Connection.session_open?
55
- rescue StandardError
56
- false
57
- end
58
-
59
- def registry_event_available?
60
- defined?(::Legion::Extensions::Llm::Routing::RegistryEvent)
61
- end
62
-
63
- def transport_message_available?
64
- return true if message_class_defined?
65
- return false unless defined?(::Legion::Transport::Message) && defined?(::Legion::Transport::Exchange)
66
-
67
- require 'legion/extensions/llm/openai/transport/messages/registry_event'
68
- message_class_defined?
69
- rescue LoadError
70
- false
71
- end
72
-
73
- def message_class_defined?
74
- defined?(::Legion::Extensions::Llm::Openai::Transport::Messages::RegistryEvent)
75
- end
76
-
77
- def message_class
78
- ::Legion::Extensions::Llm::Openai::Transport::Messages::RegistryEvent
79
- end
80
-
81
- def log_publish_failure(error, level: :warn)
82
- message = "[lex-llm-openai] llm.registry publish failed: #{error.class}: #{error.message}"
83
- logger = ::Legion::Extensions::Llm.logger if defined?(::Legion::Extensions::Llm)
84
- if logger.respond_to?(level)
85
- logger.public_send(level, message)
86
- elsif logger.respond_to?(:debug)
87
- logger.debug(message)
88
- end
89
- rescue StandardError
90
- nil
91
- end
92
- end
93
- end
94
- end
95
- end
96
- end
@@ -1,24 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Legion
4
- module Extensions
5
- module Llm
6
- module Openai
7
- module Transport
8
- module Exchanges
9
- # Topic exchange for OpenAI 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/openai/transport/exchanges/llm_registry'
4
-
5
- module Legion
6
- module Extensions
7
- module Llm
8
- module Openai
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