lex-llm-gemini 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 +4 -4
- data/.rubocop.yml +2 -0
- data/CHANGELOG.md +10 -0
- data/lex-llm-gemini.gemspec +1 -1
- data/lib/legion/extensions/llm/gemini/provider.rb +9 -7
- data/lib/legion/extensions/llm/gemini/version.rb +1 -1
- data/lib/legion/extensions/llm/gemini.rb +14 -17
- metadata +3 -7
- data/lib/legion/extensions/llm/gemini/registry_event_builder.rb +0 -75
- data/lib/legion/extensions/llm/gemini/registry_publisher.rb +0 -89
- data/lib/legion/extensions/llm/gemini/transport/exchanges/llm_registry.rb +0 -24
- data/lib/legion/extensions/llm/gemini/transport/messages/registry_event.rb +0 -42
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: '0788daea481b47eead29eb391fa566a2f02540f1f0f5b4c8aca382b457de8c33'
|
|
4
|
+
data.tar.gz: 356fd313c188e9d585ca9d7a3f9f7fd8b1ab9d687edba232266ea168c306135f
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: '09edc833e89707be34a90292622615b2fcd391d19cee2baa73d29ed7a6f12b1d520cee837684f9db28349488e7d54f7ff312414b6e3ede280627da4d821d456e'
|
|
7
|
+
data.tar.gz: 634a5703a52c3d0554a47141265430ea1dbe10b43dfef892923ea4b0b4e7a278a914a76a9c1c109196ea27f09d9c5fb2dabdade8b302aff888185f9731a236b4
|
data/.rubocop.yml
CHANGED
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.2.0 - 2026-04-30
|
|
4
|
+
|
|
5
|
+
- **Breaking**: Adopt the base contract from lex-llm 0.1.9.
|
|
6
|
+
- Replace `default_settings` with a flat settings hash (enabled, default_model, api_key, whitelist/blacklist, tls, instances).
|
|
7
|
+
- Remove local `RegistryPublisher` and `RegistryEventBuilder`; use the parameterized base classes from lex-llm.
|
|
8
|
+
- Remove local `transport/` directory (exchanges and messages); the shared `llm.registry` transport in lex-llm is used instead.
|
|
9
|
+
- Remove the deprecated `Provider.register` call; configuration options are registered directly.
|
|
10
|
+
- Update `parse_list_models_response` to use the new `Model::Info` constructor (context_length, modalities_input/output, metadata for max_output_tokens).
|
|
11
|
+
- Require `lex-llm >= 0.1.9`.
|
|
12
|
+
|
|
3
13
|
## 0.1.7 - 2026-04-30
|
|
4
14
|
|
|
5
15
|
- Audit logging, rescue blocks, and README for full observability.
|
data/lex-llm-gemini.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.
|
|
29
|
+
spec.add_dependency 'lex-llm', '>= 0.2.0'
|
|
30
30
|
end
|
|
@@ -8,7 +8,7 @@ module Legion
|
|
|
8
8
|
module Gemini
|
|
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
|
-
include Legion::Logging::Helper
|
|
11
|
+
include Legion::Logging::Helper
|
|
12
12
|
|
|
13
13
|
class << self
|
|
14
14
|
attr_writer :registry_publisher
|
|
@@ -19,7 +19,7 @@ module Legion
|
|
|
19
19
|
def capabilities = Capabilities
|
|
20
20
|
|
|
21
21
|
def registry_publisher
|
|
22
|
-
@registry_publisher ||= RegistryPublisher.new
|
|
22
|
+
@registry_publisher ||= Legion::Extensions::Llm::RegistryPublisher.new(provider_family: :gemini)
|
|
23
23
|
end
|
|
24
24
|
end
|
|
25
25
|
|
|
@@ -283,16 +283,18 @@ module Legion
|
|
|
283
283
|
Array(response.body['models']).map do |model_data|
|
|
284
284
|
model_id = model_data.fetch('name').delete_prefix('models/')
|
|
285
285
|
methods = Array(model_data['supportedGenerationMethods'])
|
|
286
|
+
input_mods, output_mods = modalities_for(methods)
|
|
286
287
|
|
|
287
288
|
Legion::Extensions::Llm::Model::Info.new(
|
|
288
289
|
id: model_id,
|
|
289
290
|
name: model_data['displayName'] || model_id,
|
|
290
291
|
provider: provider,
|
|
291
|
-
|
|
292
|
-
max_output_tokens: model_data['outputTokenLimit'],
|
|
292
|
+
context_length: model_data['inputTokenLimit'],
|
|
293
293
|
capabilities: capabilities.critical_capabilities_for(model_data),
|
|
294
|
-
|
|
294
|
+
modalities_input: input_mods,
|
|
295
|
+
modalities_output: output_mods,
|
|
295
296
|
metadata: {
|
|
297
|
+
max_output_tokens: model_data['outputTokenLimit'],
|
|
296
298
|
version: model_data['version'],
|
|
297
299
|
description: model_data['description'],
|
|
298
300
|
supported_generation_methods: methods
|
|
@@ -302,9 +304,9 @@ module Legion
|
|
|
302
304
|
end
|
|
303
305
|
|
|
304
306
|
def modalities_for(methods)
|
|
305
|
-
return
|
|
307
|
+
return [%w[text], %w[embeddings]] if methods.include?('embedContent')
|
|
306
308
|
|
|
307
|
-
|
|
309
|
+
[%w[text image audio video], %w[text]]
|
|
308
310
|
end
|
|
309
311
|
|
|
310
312
|
def render_embedding_payload(text, model:, dimensions:)
|
|
@@ -1,42 +1,39 @@
|
|
|
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'
|
|
6
4
|
require 'legion/extensions/llm/gemini/provider'
|
|
7
5
|
require 'legion/extensions/llm/gemini/version'
|
|
8
6
|
|
|
9
7
|
module Legion
|
|
10
8
|
module Extensions
|
|
9
|
+
# LLM provider framework namespace (reopened by provider extensions).
|
|
11
10
|
module Llm
|
|
12
11
|
# Gemini provider extension namespace.
|
|
13
12
|
module Gemini
|
|
14
13
|
extend ::Legion::Extensions::Core if ::Legion::Extensions.const_defined?(:Core, false)
|
|
15
|
-
extend Legion::Logging::Helper
|
|
14
|
+
extend Legion::Logging::Helper
|
|
16
15
|
|
|
17
16
|
PROVIDER_FAMILY = :gemini
|
|
18
17
|
|
|
19
18
|
def self.default_settings
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
)
|
|
19
|
+
{
|
|
20
|
+
enabled: false,
|
|
21
|
+
default_model: 'gemini-2.0-flash',
|
|
22
|
+
api_key: nil,
|
|
23
|
+
model_whitelist: [],
|
|
24
|
+
model_blacklist: [],
|
|
25
|
+
model_cache_ttl: 3600,
|
|
26
|
+
tls: { enabled: false, verify: :peer },
|
|
27
|
+
instances: {}
|
|
28
|
+
}
|
|
31
29
|
end
|
|
32
30
|
|
|
33
31
|
def self.provider_class
|
|
34
32
|
Provider
|
|
35
33
|
end
|
|
36
34
|
end
|
|
35
|
+
|
|
36
|
+
Configuration.register_provider_options(Gemini::Provider.configuration_options)
|
|
37
37
|
end
|
|
38
38
|
end
|
|
39
39
|
end
|
|
40
|
-
|
|
41
|
-
Legion::Extensions::Llm::Provider.register(Legion::Extensions::Llm::Gemini::PROVIDER_FAMILY,
|
|
42
|
-
Legion::Extensions::Llm::Gemini::Provider)
|
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.
|
|
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.
|
|
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.
|
|
67
|
+
version: 0.2.0
|
|
68
68
|
description: Gemini 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-gemini.gemspec
|
|
85
85
|
- lib/legion/extensions/llm/gemini.rb
|
|
86
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
|
|
91
87
|
- lib/legion/extensions/llm/gemini/version.rb
|
|
92
88
|
homepage: https://github.com/LegionIO/lex-llm-gemini
|
|
93
89
|
licenses:
|
|
@@ -1,75 +0,0 @@
|
|
|
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
|
-
include Legion::Logging::Helper if defined?(Legion::Logging::Helper)
|
|
10
|
-
|
|
11
|
-
def model_available(model, readiness:)
|
|
12
|
-
registry_event_class.available(
|
|
13
|
-
model_offering(model),
|
|
14
|
-
runtime: runtime_metadata,
|
|
15
|
-
health: model_health(readiness),
|
|
16
|
-
metadata: model_metadata(model)
|
|
17
|
-
)
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
private
|
|
21
|
-
|
|
22
|
-
def model_offering(model)
|
|
23
|
-
{
|
|
24
|
-
provider_family: :gemini,
|
|
25
|
-
provider_instance: provider_instance,
|
|
26
|
-
transport: :http,
|
|
27
|
-
model: model.id,
|
|
28
|
-
usage_type: usage_type_for(model),
|
|
29
|
-
capabilities: Array(model.capabilities).map(&:to_sym),
|
|
30
|
-
limits: model_limits(model),
|
|
31
|
-
metadata: { lex: :llm_gemini, model_name: model.name }.compact
|
|
32
|
-
}
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
def model_health(readiness)
|
|
36
|
-
ready = readiness.fetch(:ready, true) == true
|
|
37
|
-
{ ready:, status: ready ? :available : :degraded }
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
def model_metadata(model)
|
|
41
|
-
{ extension: :lex_llm_gemini, provider: :gemini, model_type: model.type }
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
def runtime_metadata
|
|
45
|
-
{ node: provider_instance }
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
def model_limits(model)
|
|
49
|
-
{
|
|
50
|
-
context_window: model.context_window,
|
|
51
|
-
max_output_tokens: model.max_output_tokens
|
|
52
|
-
}.compact
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
def usage_type_for(model)
|
|
56
|
-
model.type == 'embedding' ? :embedding : :inference
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
def provider_instance
|
|
60
|
-
configured_node = (::Legion::Settings.dig(:node, :canonical_name) if defined?(::Legion::Settings))
|
|
61
|
-
value = configured_node.to_s.strip
|
|
62
|
-
value.empty? ? :gemini : value.to_sym
|
|
63
|
-
rescue StandardError => e
|
|
64
|
-
handle_exception(e, level: :debug, handled: true, operation: 'gemini.registry.provider_instance')
|
|
65
|
-
:gemini
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
def registry_event_class
|
|
69
|
-
::Legion::Extensions::Llm::Routing::RegistryEvent
|
|
70
|
-
end
|
|
71
|
-
end
|
|
72
|
-
end
|
|
73
|
-
end
|
|
74
|
-
end
|
|
75
|
-
end
|
|
@@ -1,89 +0,0 @@
|
|
|
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
|
-
include Legion::Logging::Helper if defined?(Legion::Logging::Helper)
|
|
10
|
-
|
|
11
|
-
APP_ID = 'lex-llm-gemini'
|
|
12
|
-
|
|
13
|
-
def initialize(builder: RegistryEventBuilder.new)
|
|
14
|
-
@builder = builder
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
def publish_models_async(models, readiness:)
|
|
18
|
-
log.info { "publishing #{Array(models).size} model event(s) to llm.registry" }
|
|
19
|
-
schedule do
|
|
20
|
-
Array(models).each do |model|
|
|
21
|
-
publish_event(@builder.model_available(model, readiness:))
|
|
22
|
-
end
|
|
23
|
-
end
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
private
|
|
27
|
-
|
|
28
|
-
def schedule(&)
|
|
29
|
-
return false unless publishing_available?
|
|
30
|
-
|
|
31
|
-
Thread.new do
|
|
32
|
-
Thread.current.abort_on_exception = false
|
|
33
|
-
yield
|
|
34
|
-
rescue StandardError => e
|
|
35
|
-
handle_exception(e, level: :debug, handled: true, operation: 'gemini.registry.schedule_thread')
|
|
36
|
-
end
|
|
37
|
-
rescue StandardError => e
|
|
38
|
-
handle_exception(e, level: :debug, handled: true, operation: 'gemini.registry.schedule')
|
|
39
|
-
false
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
def publish_event(event)
|
|
43
|
-
return false unless publishing_available?
|
|
44
|
-
|
|
45
|
-
message_class.new(event:, app_id: APP_ID).publish(spool: false)
|
|
46
|
-
rescue StandardError => e
|
|
47
|
-
handle_exception(e, level: :warn, handled: true, operation: 'gemini.registry.publish_event')
|
|
48
|
-
false
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
def publishing_available?
|
|
52
|
-
return false unless registry_event_available?
|
|
53
|
-
return false unless transport_message_available?
|
|
54
|
-
return true unless defined?(::Legion::Transport::Connection)
|
|
55
|
-
return true unless ::Legion::Transport::Connection.respond_to?(:session_open?)
|
|
56
|
-
|
|
57
|
-
::Legion::Transport::Connection.session_open?
|
|
58
|
-
rescue StandardError => e
|
|
59
|
-
handle_exception(e, level: :debug, handled: true, operation: 'gemini.registry.publishing_available?')
|
|
60
|
-
false
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
def registry_event_available?
|
|
64
|
-
defined?(::Legion::Extensions::Llm::Routing::RegistryEvent)
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
def transport_message_available?
|
|
68
|
-
return true if message_class_defined?
|
|
69
|
-
return false unless defined?(::Legion::Transport::Message) && defined?(::Legion::Transport::Exchange)
|
|
70
|
-
|
|
71
|
-
require 'legion/extensions/llm/gemini/transport/messages/registry_event'
|
|
72
|
-
message_class_defined?
|
|
73
|
-
rescue LoadError => e
|
|
74
|
-
handle_exception(e, level: :debug, handled: true, operation: 'gemini.registry.transport_load')
|
|
75
|
-
false
|
|
76
|
-
end
|
|
77
|
-
|
|
78
|
-
def message_class_defined?
|
|
79
|
-
defined?(::Legion::Extensions::Llm::Gemini::Transport::Messages::RegistryEvent)
|
|
80
|
-
end
|
|
81
|
-
|
|
82
|
-
def message_class
|
|
83
|
-
::Legion::Extensions::Llm::Gemini::Transport::Messages::RegistryEvent
|
|
84
|
-
end
|
|
85
|
-
end
|
|
86
|
-
end
|
|
87
|
-
end
|
|
88
|
-
end
|
|
89
|
-
end
|
|
@@ -1,24 +0,0 @@
|
|
|
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
|
|
@@ -1,42 +0,0 @@
|
|
|
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
|