lex-llm-gemini 0.3.0 → 0.3.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 +4 -4
- data/.github/workflows/ci.yml +13 -1
- data/CHANGELOG.md +33 -0
- data/Gemfile +2 -0
- data/README.md +29 -13
- data/lex-llm-gemini.gemspec +2 -1
- data/lib/legion/extensions/llm/gemini/actors/fleet_worker.rb +43 -0
- data/lib/legion/extensions/llm/gemini/runners/fleet_worker.rb +30 -0
- data/lib/legion/extensions/llm/gemini/version.rb +1 -1
- data/lib/legion/extensions/llm/gemini.rb +51 -18
- metadata +19 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: dc50ce20a2bc5b62e79854004feee5aa14ee1d26a8dfee8698a37f387d72392c
|
|
4
|
+
data.tar.gz: ef401f8e9fa5a521a3b5930e835a6aa11b707ed2dd7c304e51115a27b1ba1732
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 03bb48c71874f80bcad9739a59e0d7d0377aa935bee79e8fe0eb3a2dff8f700537ac480a406a86b1f21f3e35a1dc3401c1443e3004ecec3de6aa9c044f8b89ce
|
|
7
|
+
data.tar.gz: 3c650b57f45a6cc93f1634595dc0fc14926526bd666ab57e7c824e11e889fc0ce44b4494b8b95729303170b8a29e98e31221d1d4afc3953957ae3095c91d6543
|
data/.github/workflows/ci.yml
CHANGED
|
@@ -8,8 +8,20 @@ jobs:
|
|
|
8
8
|
ci:
|
|
9
9
|
uses: LegionIO/.github/.github/workflows/ci.yml@main
|
|
10
10
|
|
|
11
|
+
excluded-files:
|
|
12
|
+
uses: LegionIO/.github/.github/workflows/excluded-files.yml@main
|
|
13
|
+
|
|
14
|
+
security:
|
|
15
|
+
uses: LegionIO/.github/.github/workflows/security-scan.yml@main
|
|
16
|
+
|
|
17
|
+
version-changelog:
|
|
18
|
+
uses: LegionIO/.github/.github/workflows/version-changelog.yml@main
|
|
19
|
+
|
|
20
|
+
dependency-review:
|
|
21
|
+
uses: LegionIO/.github/.github/workflows/dependency-review.yml@main
|
|
22
|
+
|
|
11
23
|
release:
|
|
12
|
-
needs: ci
|
|
24
|
+
needs: [ci, excluded-files, security]
|
|
13
25
|
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
|
|
14
26
|
uses: LegionIO/.github/.github/workflows/release.yml@main
|
|
15
27
|
secrets:
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,38 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.3.6 - 2026-05-06
|
|
4
|
+
|
|
5
|
+
- Load provider-owned fleet actors through the LegionIO subscription base and the canonical Gemini provider root.
|
|
6
|
+
- Keep fleet runners anchored on the provider root namespace so provider constants and instance discovery are always loaded.
|
|
7
|
+
- Strip temporary generic API key fields from discovered Gemini instance configs after credential deduplication.
|
|
8
|
+
- Gate release publishing on the shared security workflow.
|
|
9
|
+
|
|
10
|
+
## 0.3.5 - 2026-05-06
|
|
11
|
+
|
|
12
|
+
- Keep the default Gemini endpoint on the versioned `v1beta` API base when instance settings are normalized.
|
|
13
|
+
- Refresh the README for the current `lex-llm >= 0.4.3` provider registry and fleet responder boundary.
|
|
14
|
+
|
|
15
|
+
## 0.3.4 - 2026-05-06
|
|
16
|
+
|
|
17
|
+
- Use the shared `lex-llm` fleet provider responder helper for provider-owned fleet workers.
|
|
18
|
+
- Remove the runtime `legion-llm` dependency and require `lex-llm >= 0.4.3` for responder-side fleet execution.
|
|
19
|
+
|
|
20
|
+
## 0.3.3 - 2026-05-06
|
|
21
|
+
|
|
22
|
+
- Remove require-time provider self-registration; `legion-llm` now owns adapter creation and registry writes from loaded provider discovery metadata.
|
|
23
|
+
- Bump dependency floors to `lex-llm >= 0.4.1` and `legion-llm >= 0.9.1`.
|
|
24
|
+
|
|
25
|
+
## 0.3.2 - 2026-05-06
|
|
26
|
+
|
|
27
|
+
- Add provider contract specs for the shared keyword-only `lex-llm` provider API.
|
|
28
|
+
- Move Gemini defaults back to `Legion::Extensions::Llm.provider_settings` with credentials and instance-level fleet responder settings.
|
|
29
|
+
- Add provider-owned fleet responder actor and runner backed by `legion-llm` fleet policy execution.
|
|
30
|
+
- Bump the transport dependency floor to `legion-transport >= 1.4.14`.
|
|
31
|
+
|
|
32
|
+
## 0.3.1 - 2026-05-03
|
|
33
|
+
|
|
34
|
+
- Normalize generic settings keys to Gemini provider config keys during instance discovery.
|
|
35
|
+
|
|
3
36
|
## 0.3.0 - 2026-05-01
|
|
4
37
|
|
|
5
38
|
- Add auto-discovery via CredentialSources and AutoRegistration from lex-llm 0.3.0
|
data/Gemfile
CHANGED
|
@@ -4,6 +4,8 @@ source 'https://rubygems.org'
|
|
|
4
4
|
|
|
5
5
|
group :test do
|
|
6
6
|
llm_base_path = ENV.fetch('LEX_LLM_PATH', File.expand_path('../lex-llm', __dir__))
|
|
7
|
+
transport_path = ENV.fetch('LEGION_TRANSPORT_PATH', File.expand_path('../../legion-transport', __dir__))
|
|
8
|
+
gem 'legion-transport', path: transport_path if File.directory?(transport_path)
|
|
7
9
|
gem 'lex-llm', path: llm_base_path if File.directory?(llm_base_path)
|
|
8
10
|
end
|
|
9
11
|
|
data/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
LegionIO LLM provider extension for Google Gemini.
|
|
4
4
|
|
|
5
|
-
This gem lives under `Legion::Extensions::Llm::Gemini` and depends on `lex-llm` for shared provider-neutral routing, fleet, and schema primitives.
|
|
5
|
+
This gem lives under `Legion::Extensions::Llm::Gemini` and depends on `lex-llm >= 0.4.3` for shared provider-neutral routing, response normalization, fleet responder execution, and schema primitives. It does not require or call `legion-llm` at runtime; `legion-llm` owns adapter creation, routing, and registry writes after discovering loaded `lex-llm-*` provider gems.
|
|
6
6
|
|
|
7
7
|
Load it with `require 'legion/extensions/llm/gemini'`.
|
|
8
8
|
|
|
@@ -21,12 +21,10 @@ Load it with `require 'legion/extensions/llm/gemini'`.
|
|
|
21
21
|
|
|
22
22
|
| Path | Purpose |
|
|
23
23
|
|------|---------|
|
|
24
|
-
| `lib/legion/extensions/llm/gemini.rb` | Entry point; provider
|
|
24
|
+
| `lib/legion/extensions/llm/gemini.rb` | Entry point; provider discovery metadata and defaults |
|
|
25
25
|
| `lib/legion/extensions/llm/gemini/provider.rb` | Gemini provider (chat, streaming, models, embeddings) |
|
|
26
|
-
| `lib/legion/extensions/llm/gemini/
|
|
27
|
-
| `lib/legion/extensions/llm/gemini/
|
|
28
|
-
| `lib/legion/extensions/llm/gemini/transport/exchanges/llm_registry.rb` | `llm.registry` AMQP topic exchange |
|
|
29
|
-
| `lib/legion/extensions/llm/gemini/transport/messages/registry_event.rb` | AMQP message wrapper for registry events |
|
|
26
|
+
| `lib/legion/extensions/llm/gemini/actors/fleet_worker.rb` | Provider-owned fleet subscription actor |
|
|
27
|
+
| `lib/legion/extensions/llm/gemini/runners/fleet_worker.rb` | Fleet runner delegating to `Legion::Extensions::Llm::Fleet::ProviderResponder` |
|
|
30
28
|
| `lib/legion/extensions/llm/gemini/version.rb` | `VERSION` constant |
|
|
31
29
|
|
|
32
30
|
## Defaults
|
|
@@ -59,21 +57,39 @@ Legion::Extensions::Llm.configure do |config|
|
|
|
59
57
|
end
|
|
60
58
|
```
|
|
61
59
|
|
|
60
|
+
## Fleet Responder
|
|
61
|
+
|
|
62
|
+
Provider instances can opt in to consuming Legion LLM fleet requests. The provider-owned fleet actor only starts when at least one discovered instance enables `fleet.respond_to_requests`, and execution delegates to `Legion::Extensions::Llm::Fleet::ProviderResponder` from `lex-llm`.
|
|
63
|
+
|
|
64
|
+
```yaml
|
|
65
|
+
extensions:
|
|
66
|
+
llm:
|
|
67
|
+
gemini:
|
|
68
|
+
instances:
|
|
69
|
+
local:
|
|
70
|
+
fleet:
|
|
71
|
+
enabled: true
|
|
72
|
+
respond_to_requests: true
|
|
73
|
+
capabilities:
|
|
74
|
+
- chat
|
|
75
|
+
- stream_chat
|
|
76
|
+
- embed
|
|
77
|
+
```
|
|
78
|
+
|
|
62
79
|
## Observability
|
|
63
80
|
|
|
64
|
-
|
|
81
|
+
The Gemini entry point and provider use `Legion::Logging::Helper`:
|
|
65
82
|
|
|
66
|
-
-
|
|
67
|
-
-
|
|
68
|
-
- Registry publishing is best-effort
|
|
83
|
+
- `list_models` logs model discovery activity and publishes availability through the shared `lex-llm` registry publisher.
|
|
84
|
+
- Fleet request execution is delegated to the shared responder helper so acking, response publishing, and responder failures stay inside the provider-neutral fleet boundary.
|
|
85
|
+
- Registry publishing is best-effort and must not block provider calls when transport is unavailable.
|
|
69
86
|
|
|
70
87
|
## Development
|
|
71
88
|
|
|
72
89
|
```bash
|
|
73
90
|
bundle install
|
|
74
|
-
bundle exec rspec
|
|
75
|
-
bundle exec rubocop -A
|
|
76
|
-
bundle exec rubocop # lint check
|
|
91
|
+
bundle exec rspec --format json --out tmp/rspec_results.json --format progress --out tmp/rspec_progress.txt
|
|
92
|
+
bundle exec rubocop -A
|
|
77
93
|
```
|
|
78
94
|
|
|
79
95
|
## License
|
data/lex-llm-gemini.gemspec
CHANGED
|
@@ -26,5 +26,6 @@ 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 '
|
|
29
|
+
spec.add_dependency 'legion-transport', '>= 1.4.14'
|
|
30
|
+
spec.add_dependency 'lex-llm', '>= 0.4.3'
|
|
30
31
|
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
begin
|
|
4
|
+
require 'legion/extensions/actors/subscription'
|
|
5
|
+
rescue LoadError => e
|
|
6
|
+
warn(e.message) if $VERBOSE
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
unless defined?(Legion::Extensions::Actors::Subscription)
|
|
10
|
+
raise LoadError, 'LegionIO actor runtime is required for Gemini fleet worker'
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
require 'legion/extensions/llm/gemini'
|
|
14
|
+
require 'legion/extensions/llm/fleet/provider_responder'
|
|
15
|
+
|
|
16
|
+
module Legion
|
|
17
|
+
module Extensions
|
|
18
|
+
module Llm
|
|
19
|
+
module Gemini
|
|
20
|
+
module Actor
|
|
21
|
+
# Subscription actor for Gemini fleet request consumption.
|
|
22
|
+
class FleetWorker < Legion::Extensions::Actors::Subscription
|
|
23
|
+
def runner_class
|
|
24
|
+
'Legion::Extensions::Llm::Gemini::Runners::FleetWorker'
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def runner_function
|
|
28
|
+
'handle_fleet_request'
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def use_runner?
|
|
32
|
+
false
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def enabled?
|
|
36
|
+
Legion::Extensions::Llm::Fleet::ProviderResponder.enabled_for?(Gemini.discover_instances)
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'legion/extensions/llm/fleet/provider_responder'
|
|
4
|
+
require 'legion/extensions/llm/gemini'
|
|
5
|
+
|
|
6
|
+
module Legion
|
|
7
|
+
module Extensions
|
|
8
|
+
module Llm
|
|
9
|
+
module Gemini
|
|
10
|
+
module Runners
|
|
11
|
+
# Runner entrypoint for Gemini fleet request execution.
|
|
12
|
+
module FleetWorker
|
|
13
|
+
module_function
|
|
14
|
+
|
|
15
|
+
def handle_fleet_request(payload, delivery: nil, properties: nil)
|
|
16
|
+
Legion::Extensions::Llm::Fleet::ProviderResponder.call(
|
|
17
|
+
payload: payload,
|
|
18
|
+
provider_family: Gemini::PROVIDER_FAMILY,
|
|
19
|
+
provider_class: Gemini::Provider,
|
|
20
|
+
provider_instances: -> { Gemini.discover_instances },
|
|
21
|
+
delivery: delivery,
|
|
22
|
+
properties: properties
|
|
23
|
+
)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -17,16 +17,26 @@ module Legion
|
|
|
17
17
|
PROVIDER_FAMILY = :gemini
|
|
18
18
|
|
|
19
19
|
def self.default_settings
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
20
|
+
::Legion::Extensions::Llm.provider_settings(
|
|
21
|
+
family: PROVIDER_FAMILY,
|
|
22
|
+
instance: {
|
|
23
|
+
endpoint: 'https://generativelanguage.googleapis.com/v1beta',
|
|
24
|
+
default_model: 'gemini-2.0-flash',
|
|
25
|
+
tier: :frontier,
|
|
26
|
+
transport: :http,
|
|
27
|
+
credentials: { api_key: 'env://GEMINI_API_KEY' },
|
|
28
|
+
usage: { inference: true, embedding: true, image: false },
|
|
29
|
+
limits: { concurrency: 4 },
|
|
30
|
+
fleet: {
|
|
31
|
+
enabled: false,
|
|
32
|
+
respond_to_requests: false,
|
|
33
|
+
capabilities: %i[chat stream_chat embed],
|
|
34
|
+
lanes: [],
|
|
35
|
+
concurrency: 4,
|
|
36
|
+
queue_suffix: nil
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
)
|
|
30
40
|
end
|
|
31
41
|
|
|
32
42
|
def self.provider_class
|
|
@@ -37,7 +47,7 @@ module Legion
|
|
|
37
47
|
candidates = {}
|
|
38
48
|
discover_from_env(candidates)
|
|
39
49
|
discover_from_settings(candidates)
|
|
40
|
-
CredentialSources.dedup_credentials(candidates)
|
|
50
|
+
CredentialSources.dedup_credentials(candidates).transform_values { |config| sanitize_instance_config(config) }
|
|
41
51
|
end
|
|
42
52
|
|
|
43
53
|
def self.discover_from_env(candidates)
|
|
@@ -59,23 +69,46 @@ module Legion
|
|
|
59
69
|
api_key = cfg[:api_key] || cfg['api_key']
|
|
60
70
|
return if api_key.nil? || api_key.to_s.strip.empty?
|
|
61
71
|
|
|
62
|
-
candidates[:settings] =
|
|
72
|
+
candidates[:settings] = normalize_instance_config(cfg).merge(api_key: api_key,
|
|
73
|
+
gemini_api_key: api_key,
|
|
74
|
+
tier: :cloud)
|
|
63
75
|
end
|
|
64
76
|
|
|
65
77
|
def self.add_settings_instances(candidates, cfg)
|
|
66
78
|
instances = cfg[:instances] || cfg['instances']
|
|
67
79
|
return unless instances.is_a?(Hash)
|
|
68
80
|
|
|
69
|
-
instances.each
|
|
81
|
+
instances.each do |name, config|
|
|
82
|
+
next unless config.is_a?(Hash)
|
|
83
|
+
|
|
84
|
+
normalized = normalize_instance_config(config)
|
|
85
|
+
next unless normalized[:gemini_api_key]
|
|
86
|
+
|
|
87
|
+
normalized[:api_key] = normalized[:gemini_api_key]
|
|
88
|
+
candidates[name.to_sym] = normalized.merge(tier: :cloud)
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def self.normalize_instance_config(config) # rubocop:disable Metrics/AbcSize
|
|
93
|
+
normalized = config.to_h.transform_keys { |key| key.respond_to?(:to_sym) ? key.to_sym : key }
|
|
94
|
+
normalized[:gemini_api_key] ||= normalized.delete(:api_key)
|
|
95
|
+
normalized[:gemini_api_base] ||= normalized.delete(:base_url)
|
|
96
|
+
normalized[:gemini_api_base] ||= normalized.delete(:api_base)
|
|
97
|
+
normalized[:gemini_api_base] ||= normalized.delete(:endpoint)
|
|
98
|
+
normalized.compact.except(:instances)
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def self.sanitize_instance_config(config)
|
|
102
|
+
config.except(:api_key)
|
|
70
103
|
end
|
|
71
104
|
|
|
72
105
|
private_class_method :discover_from_env, :discover_from_settings,
|
|
73
|
-
:add_settings_api_key, :add_settings_instances
|
|
74
|
-
|
|
106
|
+
:add_settings_api_key, :add_settings_instances, :normalize_instance_config,
|
|
107
|
+
:sanitize_instance_config
|
|
75
108
|
|
|
76
|
-
|
|
109
|
+
Legion::Extensions::Llm::Configuration.register_provider_options(Provider.configuration_options) if
|
|
110
|
+
Legion::Extensions::Llm::Configuration.respond_to?(:register_provider_options)
|
|
111
|
+
end
|
|
77
112
|
end
|
|
78
113
|
end
|
|
79
114
|
end
|
|
80
|
-
|
|
81
|
-
Legion::Extensions::Llm::Gemini.register_discovered_instances
|
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.3.
|
|
4
|
+
version: 0.3.6
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- LegionIO
|
|
@@ -51,20 +51,34 @@ dependencies:
|
|
|
51
51
|
- - ">="
|
|
52
52
|
- !ruby/object:Gem::Version
|
|
53
53
|
version: 1.3.14
|
|
54
|
+
- !ruby/object:Gem::Dependency
|
|
55
|
+
name: legion-transport
|
|
56
|
+
requirement: !ruby/object:Gem::Requirement
|
|
57
|
+
requirements:
|
|
58
|
+
- - ">="
|
|
59
|
+
- !ruby/object:Gem::Version
|
|
60
|
+
version: 1.4.14
|
|
61
|
+
type: :runtime
|
|
62
|
+
prerelease: false
|
|
63
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
64
|
+
requirements:
|
|
65
|
+
- - ">="
|
|
66
|
+
- !ruby/object:Gem::Version
|
|
67
|
+
version: 1.4.14
|
|
54
68
|
- !ruby/object:Gem::Dependency
|
|
55
69
|
name: lex-llm
|
|
56
70
|
requirement: !ruby/object:Gem::Requirement
|
|
57
71
|
requirements:
|
|
58
72
|
- - ">="
|
|
59
73
|
- !ruby/object:Gem::Version
|
|
60
|
-
version: 0.3
|
|
74
|
+
version: 0.4.3
|
|
61
75
|
type: :runtime
|
|
62
76
|
prerelease: false
|
|
63
77
|
version_requirements: !ruby/object:Gem::Requirement
|
|
64
78
|
requirements:
|
|
65
79
|
- - ">="
|
|
66
80
|
- !ruby/object:Gem::Version
|
|
67
|
-
version: 0.3
|
|
81
|
+
version: 0.4.3
|
|
68
82
|
description: Gemini provider integration for the LegionIO LLM routing framework.
|
|
69
83
|
email:
|
|
70
84
|
- matthewdiverson@gmail.com
|
|
@@ -83,7 +97,9 @@ files:
|
|
|
83
97
|
- README.md
|
|
84
98
|
- lex-llm-gemini.gemspec
|
|
85
99
|
- lib/legion/extensions/llm/gemini.rb
|
|
100
|
+
- lib/legion/extensions/llm/gemini/actors/fleet_worker.rb
|
|
86
101
|
- lib/legion/extensions/llm/gemini/provider.rb
|
|
102
|
+
- lib/legion/extensions/llm/gemini/runners/fleet_worker.rb
|
|
87
103
|
- lib/legion/extensions/llm/gemini/version.rb
|
|
88
104
|
homepage: https://github.com/LegionIO/lex-llm-gemini
|
|
89
105
|
licenses:
|