lex-llm-gemini 0.1.4 → 0.1.6

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: 38629e200b20ead1e46cef9d869271abfb744e9696024a6a4f4b25485044e8f6
4
- data.tar.gz: c9b389261ef415cb1d45115918cf27b98bb96346491cf47bf828b567084780d8
3
+ metadata.gz: dfe3fa2fee00d45f7908b00a559606ad3d64b7b7de557da8dec385e7e0e07ada
4
+ data.tar.gz: d03f2f8fde3f41aa6273743b738122ee1ea22c03e4a165308526ddd00919ce3d
5
5
  SHA512:
6
- metadata.gz: af56bb55688b7b51508ad3d3b7733a352e7e7808b7fc27e126ddfe1b437203950cc79cf9f82a72b0607c1fe8c50cb0420213c83006f8dfded3a43f873506425c
7
- data.tar.gz: 5b0be464fb0c6865a6b7df8d7edcb95e0e248db41ca2e37276531e4492cfcf08dc539f56fc81c4169a2dc9d9d8f289b86a112f941575aa5091c0110ff2f6a1ff
6
+ metadata.gz: 9d25e055451f57d145b12389d89bc92d4010236151aae33450396d738d959dfcb6950e5f80f39388a02870a71fb16e881164654b8c204be7165da8b22bb58816
7
+ data.tar.gz: 35144cf3d1e3ccab244650ce8e7b0d4f929eb94c663db4be9fe5930520f31e789084f8962331653c70c0c2fff6f159bdc1293ebf13519cb8a3c7cbed73325444
data/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.1.6 - 2026-04-28
4
+
5
+ - Publish best-effort `llm.registry` discovered-model availability events when transport is already loaded.
6
+
7
+ ## 0.1.5 - 2026-04-28
8
+
9
+ - Require current shared Legion JSON, logging, settings, and `lex-llm >= 0.1.5` runtime dependencies.
10
+
3
11
  ## 0.1.4 - 2026-04-28
4
12
 
5
13
  - Read Gemini `supportedGenerationMethods` from discovered model metadata when mapping chat, streaming, and embedding capabilities.
@@ -23,5 +23,8 @@ Gem::Specification.new do |spec|
23
23
  spec.files = `git ls-files -z`.split("\x0").reject { |file| file.match(%r{^(spec|test|features|tmp|coverage)/}) }
24
24
  spec.require_paths = ['lib']
25
25
 
26
- spec.add_dependency 'lex-llm', '>= 0.1.3'
26
+ spec.add_dependency 'legion-json', '>= 1.2.1'
27
+ spec.add_dependency 'legion-logging', '>= 1.3.2'
28
+ spec.add_dependency 'legion-settings', '>= 1.3.14'
29
+ spec.add_dependency 'lex-llm', '>= 0.1.5'
27
30
  end
@@ -9,10 +9,16 @@ module Legion
9
9
  # Gemini provider implementation for the Legion::Extensions::Llm base provider contract.
10
10
  class Provider < Legion::Extensions::Llm::Provider # rubocop:disable Metrics/ClassLength
11
11
  class << self
12
+ attr_writer :registry_publisher
13
+
12
14
  def slug = 'gemini'
13
15
  def configuration_options = %i[gemini_api_key gemini_api_base]
14
16
  def configuration_requirements = %i[gemini_api_key]
15
17
  def capabilities = Capabilities
18
+
19
+ def registry_publisher
20
+ @registry_publisher ||= RegistryPublisher.new
21
+ end
16
22
  end
17
23
 
18
24
  # Capability predicates for Gemini API models.
@@ -87,6 +93,12 @@ module Legion
87
93
  "#{model_path(model)}:embedContent"
88
94
  end
89
95
 
96
+ def list_models
97
+ super.tap do |models|
98
+ self.class.registry_publisher.publish_models_async(models, readiness: readiness(live: false))
99
+ end
100
+ end
101
+
90
102
  private
91
103
 
92
104
  def model_path(model)
@@ -0,0 +1,72 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Llm
6
+ module Gemini
7
+ # Builds sanitized lex-llm registry envelopes for Gemini 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: :gemini,
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_gemini, 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_gemini, provider: :gemini, 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? ? :gemini : value.to_sym
61
+ rescue StandardError
62
+ :gemini
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
@@ -0,0 +1,96 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Llm
6
+ module Gemini
7
+ # Best-effort publisher for Gemini provider availability events.
8
+ class RegistryPublisher
9
+ APP_ID = 'lex-llm-gemini'
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/gemini/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::Gemini::Transport::Messages::RegistryEvent)
75
+ end
76
+
77
+ def message_class
78
+ ::Legion::Extensions::Llm::Gemini::Transport::Messages::RegistryEvent
79
+ end
80
+
81
+ def log_publish_failure(error, level: :warn)
82
+ message = "[lex-llm-gemini] 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
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Llm
6
+ module Gemini
7
+ module Transport
8
+ module Exchanges
9
+ # Topic exchange for Gemini 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
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'legion/extensions/llm/gemini/transport/exchanges/llm_registry'
4
+
5
+ module Legion
6
+ module Extensions
7
+ module Llm
8
+ module Gemini
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
@@ -4,7 +4,7 @@ module Legion
4
4
  module Extensions
5
5
  module Llm
6
6
  module Gemini
7
- VERSION = '0.1.4'
7
+ VERSION = '0.1.6'
8
8
  end
9
9
  end
10
10
  end
@@ -1,6 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'legion/extensions/llm'
4
+ require 'legion/extensions/llm/gemini/registry_event_builder'
5
+ require 'legion/extensions/llm/gemini/registry_publisher'
4
6
  require 'legion/extensions/llm/gemini/provider'
5
7
  require 'legion/extensions/llm/gemini/version'
6
8
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lex-llm-gemini
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.1.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - LegionIO
@@ -9,20 +9,62 @@ bindir: bin
9
9
  cert_chain: []
10
10
  date: 1980-01-02 00:00:00.000000000 Z
11
11
  dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: legion-json
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - ">="
17
+ - !ruby/object:Gem::Version
18
+ version: 1.2.1
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - ">="
24
+ - !ruby/object:Gem::Version
25
+ version: 1.2.1
26
+ - !ruby/object:Gem::Dependency
27
+ name: legion-logging
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 1.3.2
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: 1.3.2
40
+ - !ruby/object:Gem::Dependency
41
+ name: legion-settings
42
+ requirement: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: 1.3.14
47
+ type: :runtime
48
+ prerelease: false
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: 1.3.14
12
54
  - !ruby/object:Gem::Dependency
13
55
  name: lex-llm
14
56
  requirement: !ruby/object:Gem::Requirement
15
57
  requirements:
16
58
  - - ">="
17
59
  - !ruby/object:Gem::Version
18
- version: 0.1.3
60
+ version: 0.1.5
19
61
  type: :runtime
20
62
  prerelease: false
21
63
  version_requirements: !ruby/object:Gem::Requirement
22
64
  requirements:
23
65
  - - ">="
24
66
  - !ruby/object:Gem::Version
25
- version: 0.1.3
67
+ version: 0.1.5
26
68
  description: Gemini provider integration for the LegionIO LLM routing framework.
27
69
  email:
28
70
  - matthewdiverson@gmail.com
@@ -42,6 +84,10 @@ files:
42
84
  - lex-llm-gemini.gemspec
43
85
  - lib/legion/extensions/llm/gemini.rb
44
86
  - lib/legion/extensions/llm/gemini/provider.rb
87
+ - lib/legion/extensions/llm/gemini/registry_event_builder.rb
88
+ - lib/legion/extensions/llm/gemini/registry_publisher.rb
89
+ - lib/legion/extensions/llm/gemini/transport/exchanges/llm_registry.rb
90
+ - lib/legion/extensions/llm/gemini/transport/messages/registry_event.rb
45
91
  - lib/legion/extensions/llm/gemini/version.rb
46
92
  homepage: https://github.com/LegionIO/lex-llm-gemini
47
93
  licenses: