lex-llm-gemini 0.4.4 → 0.4.5
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:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 4fc6c5255eae71b411f35c57a052ac77bb3d9aecdb2855672472f8b1a4f4f514
|
|
4
|
+
data.tar.gz: af8645870657d5f743b398c88f96cb2a74cb849eb15afa3553b723c0d02c2f58
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: cbdc6a0ff9351f061590beedecfaeba3ccd78666aa97db675e9ff2a528834a22ba5542afd3b63bb143f8d34cd7756b0bc3719a48a84cc4423997d9dd0e07fb3e
|
|
7
|
+
data.tar.gz: 5cfcce92073c6e27a86e20b5200ae0b0babf5eec1061c20c43928c9dd34e63b0fce8311f57d7637ca4d70d49c6134d69b5b45950e415604ad3ee77e6597097c9
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.4.5] - 2026-08-19
|
|
4
|
+
|
|
5
|
+
### Changed
|
|
6
|
+
- Publish the validated four-axis lane weight pair on every Gemini offering and reconcile weight-only changes atomically on the existing discovery cadence.
|
|
7
|
+
- Track initializing instances before readiness, rebuild weights from current settings at activation, and serialize activation, replacement, removal, and cache mutation behind one writer mutex.
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
- Report configured-but-unpublished Gemini weight keys once per dormant cycle without adding a settings callback or operator workflow.
|
|
11
|
+
- Render canonical system messages through the actual Gemini callable path as native `systemInstruction` payloads.
|
|
12
|
+
- Validate weighted offering drafts before constructing or claiming a callable scope, so malformed weights leave no orphaned Registry publication and a later corrected ordinary pass activates without restart or operator cleanup.
|
|
13
|
+
- Compare rebuilt catalogs as duplicate-preserving multisets of complete offering contracts, ignoring only evidence observation timestamps so catalog reordering cannot churn snapshots and authoritative metadata, quota, publication-source, or evidence-source changes cannot be missed.
|
|
14
|
+
|
|
15
|
+
### Dependencies
|
|
16
|
+
- Raise the `lex-llm` floor from `>= 0.7.1` to `>= 0.7.6`; the `legion-settings` floor remains unchanged.
|
|
17
|
+
|
|
3
18
|
## [0.4.4] - 2026-08-18
|
|
4
19
|
|
|
5
20
|
### Fixed
|
data/lex-llm-gemini.gemspec
CHANGED
|
@@ -27,5 +27,5 @@ Gem::Specification.new do |spec|
|
|
|
27
27
|
spec.add_dependency 'legion-logging', '>= 1.3.2'
|
|
28
28
|
spec.add_dependency 'legion-settings', '>= 1.4.2'
|
|
29
29
|
spec.add_dependency 'legion-transport', '>= 1.4.14'
|
|
30
|
-
spec.add_dependency 'lex-llm', '>= 0.7.
|
|
30
|
+
spec.add_dependency 'lex-llm', '>= 0.7.6'
|
|
31
31
|
end
|
|
@@ -23,6 +23,7 @@ require 'legion/extensions/llm/inventory/identity'
|
|
|
23
23
|
require 'legion/extensions/llm/inventory/records'
|
|
24
24
|
require 'legion/extensions/llm/inventory/evidence'
|
|
25
25
|
require 'legion/extensions/llm/inventory/probe_coordinator'
|
|
26
|
+
require 'legion/extensions/llm/inventory/weight_reconciler'
|
|
26
27
|
require 'legion/extensions/llm/routing/provider_outcome'
|
|
27
28
|
require 'legion/extensions/llm/taxonomies'
|
|
28
29
|
require 'legion/extensions/llm/capabilities'
|
|
@@ -212,9 +213,18 @@ module Legion
|
|
|
212
213
|
def build_offering_draft(model_id:, model_data:, instance_cfg:, instance_key:)
|
|
213
214
|
tier = instance_cfg[:tier] || :frontier
|
|
214
215
|
generation_methods = extract_generation_methods(model_data: model_data)
|
|
216
|
+
weight_inputs = Legion::Extensions::Llm::Inventory::WeightSchema.weight_inputs(
|
|
217
|
+
settings: Legion::Settings,
|
|
218
|
+
instance_key: instance_key,
|
|
219
|
+
provider_native_key: model_id,
|
|
220
|
+
model: model_id,
|
|
221
|
+
tier: tier
|
|
222
|
+
)
|
|
215
223
|
|
|
216
224
|
Legion::Extensions::Llm::Inventory::OfferingDraft.new(
|
|
217
225
|
provider_native_key: model_id, model: model_id, tier: tier,
|
|
226
|
+
weight_inputs: weight_inputs,
|
|
227
|
+
base_weight: Legion::Extensions::Llm::Inventory::WeightSchema.base_weight(weight_inputs),
|
|
218
228
|
operation_evidence: build_operation_evidence(generation_methods: generation_methods),
|
|
219
229
|
capability_evidence: build_capability_evidence(generation_methods: generation_methods),
|
|
220
230
|
context_evidence: build_context_evidence(model_data: model_data),
|
|
@@ -432,7 +442,7 @@ module Legion
|
|
|
432
442
|
end
|
|
433
443
|
|
|
434
444
|
def handle_reactive_probe(instance_id:, request:)
|
|
435
|
-
state =
|
|
445
|
+
state = tracked_instance_state(instance_id)
|
|
436
446
|
return unless state
|
|
437
447
|
|
|
438
448
|
coordinator = state[:probe_coordinator]
|
|
@@ -537,52 +547,40 @@ module Legion
|
|
|
537
547
|
# ── Instance lifecycle helpers ───────────────────────────────────────
|
|
538
548
|
# ── Offering change comparison helpers ───────────────────────────────
|
|
539
549
|
module OfferingComparison
|
|
550
|
+
SCALAR_EVIDENCE_FIELDS = %i[
|
|
551
|
+
context_evidence max_output_evidence embedding_dimensions_evidence
|
|
552
|
+
model_revision_evidence tokenizer_evidence
|
|
553
|
+
].freeze
|
|
554
|
+
|
|
540
555
|
private
|
|
541
556
|
|
|
542
|
-
#
|
|
543
|
-
#
|
|
544
|
-
#
|
|
545
|
-
# unchanged (replace churn on every tick).
|
|
557
|
+
# Every catalog pass rebuilds evidence observation timestamps. The
|
|
558
|
+
# timestamps are telemetry, but every other draft field remains
|
|
559
|
+
# authoritative. Catalog order is not authoritative; multiplicity is.
|
|
546
560
|
def offerings_changed?(previous:, current:)
|
|
547
|
-
current
|
|
548
|
-
previous.map { |draft| offering_signature(draft) }
|
|
561
|
+
offering_comparison_multiset(current) != offering_comparison_multiset(previous)
|
|
549
562
|
end
|
|
550
563
|
|
|
551
|
-
def
|
|
552
|
-
|
|
553
|
-
draft.provider_native_key,
|
|
554
|
-
draft.model,
|
|
555
|
-
draft.tier,
|
|
556
|
-
operation_signature(draft),
|
|
557
|
-
capability_signature(draft),
|
|
558
|
-
value_signature(draft)
|
|
559
|
-
]
|
|
564
|
+
def offering_comparison_multiset(offerings)
|
|
565
|
+
Array(offerings).map { |draft| offering_comparison_state(draft) }.tally
|
|
560
566
|
end
|
|
561
567
|
|
|
562
|
-
def
|
|
563
|
-
draft.
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
[evidence.capability, evidence.status, evidence.source]
|
|
571
|
-
end.sort
|
|
568
|
+
def offering_comparison_state(draft)
|
|
569
|
+
state = draft.to_h
|
|
570
|
+
state[:operation_evidence] = comparison_evidence_map(draft.operation_evidence)
|
|
571
|
+
state[:capability_evidence] = comparison_evidence_map(draft.capability_evidence)
|
|
572
|
+
SCALAR_EVIDENCE_FIELDS.each do |field|
|
|
573
|
+
state[field] = comparison_evidence(draft.public_send(field))
|
|
574
|
+
end
|
|
575
|
+
state
|
|
572
576
|
end
|
|
573
577
|
|
|
574
|
-
def
|
|
575
|
-
|
|
576
|
-
value_pair(draft.context_evidence),
|
|
577
|
-
value_pair(draft.max_output_evidence),
|
|
578
|
-
value_pair(draft.embedding_dimensions_evidence),
|
|
579
|
-
value_pair(draft.model_revision_evidence),
|
|
580
|
-
value_pair(draft.tokenizer_evidence)
|
|
581
|
-
]
|
|
578
|
+
def comparison_evidence_map(evidence)
|
|
579
|
+
evidence.transform_values { |entry| comparison_evidence(entry) }
|
|
582
580
|
end
|
|
583
581
|
|
|
584
|
-
def
|
|
585
|
-
|
|
582
|
+
def comparison_evidence(evidence)
|
|
583
|
+
evidence.to_h.except(:observed_at)
|
|
586
584
|
end
|
|
587
585
|
end
|
|
588
586
|
|
|
@@ -696,9 +694,9 @@ module Legion
|
|
|
696
694
|
instance_id = name.to_s
|
|
697
695
|
physical_id = derive_physical_id(instance_cfg: instance_cfg)
|
|
698
696
|
instance_key = build_instance_key(instance_id: instance_id, physical_id: physical_id)
|
|
697
|
+
offerings = discover_offerings_for_instance(instance_cfg: instance_cfg, instance_key: instance_key)
|
|
699
698
|
components = build_instance_components(instance_id: instance_id, instance_cfg: instance_cfg,
|
|
700
699
|
instance_key: instance_key)
|
|
701
|
-
offerings = discover_offerings_for_instance(instance_cfg: instance_cfg, instance_key: instance_key)
|
|
702
700
|
state = {
|
|
703
701
|
name: name,
|
|
704
702
|
instance_id: instance_id,
|
|
@@ -708,24 +706,101 @@ module Legion
|
|
|
708
706
|
probe_coordinator: components[:probe_coordinator],
|
|
709
707
|
publisher_token: components[:publisher_token],
|
|
710
708
|
sequence: 0,
|
|
711
|
-
offerings: offerings
|
|
709
|
+
offerings: offerings,
|
|
710
|
+
published: false
|
|
712
711
|
}
|
|
712
|
+
Legion::Extensions::Llm::Inventory::WeightReconciler.track_initializing!(
|
|
713
|
+
states: @instance_states, state_key: instance_id, state: state, mutex: @instance_state_mutex
|
|
714
|
+
)
|
|
713
715
|
settle_initial_readiness(instance_id: instance_id, state: state)
|
|
714
|
-
|
|
715
|
-
sync_display_health(state: state)
|
|
716
|
+
sync_display_health(state: state) if tracked_instance_state(instance_id).equal?(state)
|
|
716
717
|
end
|
|
717
718
|
|
|
718
719
|
def drop_instance(instance_id:, state:)
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
720
|
+
removed = @instance_state_mutex.synchronize do
|
|
721
|
+
next false unless @instance_states[instance_id].equal?(state)
|
|
722
|
+
|
|
723
|
+
publisher.remove_instance(
|
|
724
|
+
instance_id: instance_id, publisher_token: state[:publisher_token],
|
|
725
|
+
physical_id: state[:instance_key].physical_id
|
|
726
|
+
)
|
|
727
|
+
@instance_states.delete(instance_id)
|
|
728
|
+
true
|
|
729
|
+
end
|
|
730
|
+
return false unless removed
|
|
731
|
+
|
|
723
732
|
state[:callable]&.disconnect
|
|
724
733
|
clear_display_health(name: state[:name])
|
|
725
|
-
|
|
734
|
+
true
|
|
726
735
|
rescue StandardError => e
|
|
727
736
|
handle_exception(e, level: :warn, operation: 'gemini.actor.remove_instance',
|
|
728
737
|
instance_id: instance_id)
|
|
738
|
+
false
|
|
739
|
+
end
|
|
740
|
+
end
|
|
741
|
+
|
|
742
|
+
# Shared weight-reconciliation bindings and synchronized state access.
|
|
743
|
+
module WeightPublication
|
|
744
|
+
private
|
|
745
|
+
|
|
746
|
+
def commit_discovered_offerings(instance_id:, state:, offerings:)
|
|
747
|
+
Legion::Extensions::Llm::Inventory::WeightReconciler.commit_if_changed!(
|
|
748
|
+
settings: Legion::Settings,
|
|
749
|
+
instance_id: instance_id,
|
|
750
|
+
state: state,
|
|
751
|
+
discovered_offerings: offerings,
|
|
752
|
+
mutex: @instance_state_mutex,
|
|
753
|
+
equivalent: lambda do |previous, current|
|
|
754
|
+
!offerings_changed?(previous: previous, current: current)
|
|
755
|
+
end,
|
|
756
|
+
replace: method(:replace_weight_snapshot)
|
|
757
|
+
)
|
|
758
|
+
end
|
|
759
|
+
|
|
760
|
+
def replace_weight_snapshot(instance_id:, state:, offerings:, sequence:)
|
|
761
|
+
publisher.replace_instance_snapshot(
|
|
762
|
+
instance_id: instance_id,
|
|
763
|
+
publisher_token: state.fetch(:publisher_token),
|
|
764
|
+
offerings: offerings,
|
|
765
|
+
sequence: sequence,
|
|
766
|
+
physical_id: state.fetch(:instance_key).physical_id
|
|
767
|
+
)
|
|
768
|
+
end
|
|
769
|
+
|
|
770
|
+
def activate_weight_snapshot(instance_id:, state:, offerings:, sequence:, probe_token:)
|
|
771
|
+
publisher.activate_instance_snapshot(
|
|
772
|
+
instance_id: instance_id,
|
|
773
|
+
publisher_token: state.fetch(:publisher_token),
|
|
774
|
+
offerings: offerings,
|
|
775
|
+
sequence: sequence,
|
|
776
|
+
probe_token: probe_token,
|
|
777
|
+
physical_id: state.fetch(:instance_key).physical_id
|
|
778
|
+
)
|
|
779
|
+
end
|
|
780
|
+
|
|
781
|
+
def tracked_instance_state(instance_id)
|
|
782
|
+
return unless @instance_states && @instance_state_mutex
|
|
783
|
+
|
|
784
|
+
@instance_state_mutex.synchronize { @instance_states[instance_id] }
|
|
785
|
+
end
|
|
786
|
+
|
|
787
|
+
def instance_states_snapshot
|
|
788
|
+
@instance_state_mutex.synchronize { @instance_states.each_pair.to_h }
|
|
789
|
+
end
|
|
790
|
+
|
|
791
|
+
def observe_dormant_weights
|
|
792
|
+
Legion::Extensions::Llm::Inventory::WeightReconciler.observe_dormant!(
|
|
793
|
+
settings: Legion::Settings,
|
|
794
|
+
provider_family: :gemini,
|
|
795
|
+
states: @instance_states,
|
|
796
|
+
mutex: @instance_state_mutex,
|
|
797
|
+
tracker: @dormant_weight_tracker,
|
|
798
|
+
dormant_logger: lambda do |key|
|
|
799
|
+
log.info do
|
|
800
|
+
"[llm][gemini] action=dormant_weight weight_key=#{key.inspect} no_lane_published=true"
|
|
801
|
+
end
|
|
802
|
+
end
|
|
803
|
+
)
|
|
729
804
|
end
|
|
730
805
|
end
|
|
731
806
|
|
|
@@ -738,6 +813,8 @@ module Legion
|
|
|
738
813
|
|
|
739
814
|
def initial_discovery
|
|
740
815
|
@instance_states = Concurrent::Map.new
|
|
816
|
+
@instance_state_mutex = Mutex.new
|
|
817
|
+
@dormant_weight_tracker = Legion::Extensions::Llm::Inventory::DormantWeightTracker.new
|
|
741
818
|
reconcile_and_refresh
|
|
742
819
|
end
|
|
743
820
|
|
|
@@ -750,10 +827,10 @@ module Legion
|
|
|
750
827
|
# probe just ran; refresh and cadence probes start next tick.
|
|
751
828
|
def reconcile_and_refresh
|
|
752
829
|
configured = configured_instances
|
|
753
|
-
existing =
|
|
830
|
+
existing = instance_states_snapshot.keys
|
|
754
831
|
add_newly_configured_instances(configured: configured)
|
|
755
832
|
remove_unconfigured_instances(configured: configured)
|
|
756
|
-
|
|
833
|
+
instance_states_snapshot.each do |instance_id, state|
|
|
757
834
|
next unless existing.include?(instance_id)
|
|
758
835
|
|
|
759
836
|
refresh_instance(instance_id: instance_id, state: state)
|
|
@@ -761,6 +838,7 @@ module Legion
|
|
|
761
838
|
handle_exception(e, level: :warn, operation: 'gemini.actor.refresh_instance',
|
|
762
839
|
instance_id: instance_id)
|
|
763
840
|
end
|
|
841
|
+
observe_dormant_weights
|
|
764
842
|
end
|
|
765
843
|
|
|
766
844
|
def add_newly_configured_instances(configured:)
|
|
@@ -769,7 +847,7 @@ module Legion
|
|
|
769
847
|
# id: two config names pointing at the same endpoint are
|
|
770
848
|
# distinct instances (the physical id never participates in
|
|
771
849
|
# identity).
|
|
772
|
-
next if
|
|
850
|
+
next if tracked_instance_state(name.to_s)
|
|
773
851
|
|
|
774
852
|
claim_and_activate_instance(name: name, instance_cfg: instance_cfg)
|
|
775
853
|
rescue StandardError => e
|
|
@@ -778,7 +856,7 @@ module Legion
|
|
|
778
856
|
end
|
|
779
857
|
|
|
780
858
|
def remove_unconfigured_instances(configured:)
|
|
781
|
-
|
|
859
|
+
instance_states_snapshot.each_value do |state|
|
|
782
860
|
next if configured.key?(state[:name])
|
|
783
861
|
|
|
784
862
|
drop_instance(instance_id: state[:instance_id], state: state)
|
|
@@ -796,9 +874,16 @@ module Legion
|
|
|
796
874
|
)
|
|
797
875
|
readiness = check_health(instance_cfg: state[:instance_cfg])
|
|
798
876
|
if readiness.ready?
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
877
|
+
Legion::Extensions::Llm::Inventory::WeightReconciler.activate_tracked!(
|
|
878
|
+
settings: Legion::Settings,
|
|
879
|
+
instance_id: instance_id,
|
|
880
|
+
state_key: instance_id,
|
|
881
|
+
state: state,
|
|
882
|
+
states: @instance_states,
|
|
883
|
+
mutex: @instance_state_mutex,
|
|
884
|
+
probe_token: probe_token,
|
|
885
|
+
activate: method(:activate_weight_snapshot),
|
|
886
|
+
activation_sequence: ->(tracked) { tracked.fetch(:sequence) }
|
|
802
887
|
)
|
|
803
888
|
else
|
|
804
889
|
publisher.readiness_failed(
|
|
@@ -827,36 +912,34 @@ module Legion
|
|
|
827
912
|
# path a transient outage at boot pins the instance for the process
|
|
828
913
|
# lifetime. Re-probe each tick and activate once readiness passes.
|
|
829
914
|
def retry_initial_activation(instance_id:, state:)
|
|
830
|
-
|
|
915
|
+
offerings = discover_offerings_for_instance(
|
|
831
916
|
instance_cfg: state[:instance_cfg], instance_key: state[:instance_key]
|
|
832
917
|
)
|
|
918
|
+
commit_discovered_offerings(instance_id: instance_id, state: state, offerings: offerings)
|
|
833
919
|
settle_initial_readiness(instance_id: instance_id, state: state)
|
|
834
|
-
sync_display_health(state: state)
|
|
920
|
+
sync_display_health(state: state) if tracked_instance_state(instance_id).equal?(state)
|
|
835
921
|
end
|
|
836
922
|
|
|
837
923
|
def replace_offerings_if_changed(instance_id:, state:)
|
|
838
924
|
new_offerings = discover_offerings_for_instance(
|
|
839
925
|
instance_cfg: state[:instance_cfg], instance_key: state[:instance_key]
|
|
840
926
|
)
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
state[:sequence] += 1
|
|
844
|
-
publisher.replace_instance_snapshot(
|
|
845
|
-
instance_id: instance_id, publisher_token: state[:publisher_token],
|
|
846
|
-
offerings: new_offerings, sequence: state[:sequence],
|
|
847
|
-
physical_id: state[:instance_key].physical_id
|
|
927
|
+
changed = commit_discovered_offerings(
|
|
928
|
+
instance_id: instance_id, state: state, offerings: new_offerings
|
|
848
929
|
)
|
|
849
|
-
state
|
|
850
|
-
sync_display_health(state: state)
|
|
930
|
+
sync_display_health(state: state) if changed
|
|
851
931
|
end
|
|
852
932
|
|
|
853
933
|
def remove_all_instances
|
|
854
934
|
return unless @instance_states
|
|
855
935
|
|
|
856
|
-
|
|
936
|
+
instance_states_snapshot.each_value do |state|
|
|
857
937
|
drop_instance(instance_id: state[:instance_id], state: state)
|
|
858
938
|
end
|
|
859
|
-
@
|
|
939
|
+
@instance_state_mutex.synchronize do
|
|
940
|
+
@instance_states.clear
|
|
941
|
+
@dormant_weight_tracker.clear!
|
|
942
|
+
end
|
|
860
943
|
end
|
|
861
944
|
end
|
|
862
945
|
|
|
@@ -880,6 +963,7 @@ module Legion
|
|
|
880
963
|
include OfferingComparison
|
|
881
964
|
include DisplayHealth
|
|
882
965
|
include InstanceComponents
|
|
966
|
+
include WeightPublication
|
|
883
967
|
include InstanceLifecycle
|
|
884
968
|
|
|
885
969
|
def runner_class = self.class
|
|
@@ -6,6 +6,25 @@ module Legion
|
|
|
6
6
|
module Extensions
|
|
7
7
|
module Llm
|
|
8
8
|
module Gemini
|
|
9
|
+
# Message-kind compatibility across legacy and Canonical message types.
|
|
10
|
+
module MessageKinds
|
|
11
|
+
private
|
|
12
|
+
|
|
13
|
+
def tool_call_message?(message)
|
|
14
|
+
return message.tool_call? if message.respond_to?(:tool_call?)
|
|
15
|
+
|
|
16
|
+
calls = message.tool_calls
|
|
17
|
+
!calls.nil? && !calls.empty?
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def tool_result_message?(message)
|
|
21
|
+
return message.tool_result? if message.respond_to?(:tool_result?)
|
|
22
|
+
|
|
23
|
+
tool_call_id = message.tool_call_id
|
|
24
|
+
!tool_call_id.nil? && !tool_call_id.to_s.empty?
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
9
28
|
# Message formatting helpers mixed into Provider.
|
|
10
29
|
module MessageFormatter
|
|
11
30
|
private
|
|
@@ -57,14 +76,14 @@ module Legion
|
|
|
57
76
|
|
|
58
77
|
def gemini_role(message)
|
|
59
78
|
return 'model' if message.role == :assistant
|
|
60
|
-
return 'function' if message
|
|
79
|
+
return 'function' if tool_result_message?(message)
|
|
61
80
|
|
|
62
81
|
message.role.to_s
|
|
63
82
|
end
|
|
64
83
|
|
|
65
84
|
def message_parts(message)
|
|
66
|
-
return tool_call_parts(message) if message
|
|
67
|
-
return tool_result_parts(message) if message
|
|
85
|
+
return tool_call_parts(message) if tool_call_message?(message)
|
|
86
|
+
return tool_result_parts(message) if tool_result_message?(message)
|
|
68
87
|
|
|
69
88
|
content_parts(message.content)
|
|
70
89
|
end
|
|
@@ -327,6 +346,7 @@ module Legion
|
|
|
327
346
|
# Gemini provider implementation for the Legion::Extensions::Llm base provider contract.
|
|
328
347
|
class Provider < Legion::Extensions::Llm::Provider
|
|
329
348
|
include Legion::Logging::Helper
|
|
349
|
+
include MessageKinds
|
|
330
350
|
include MessageFormatter
|
|
331
351
|
include ResponseParser
|
|
332
352
|
include OfferingBuilder
|
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.
|
|
4
|
+
version: 0.4.5
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- LegionIO
|
|
@@ -71,14 +71,14 @@ dependencies:
|
|
|
71
71
|
requirements:
|
|
72
72
|
- - ">="
|
|
73
73
|
- !ruby/object:Gem::Version
|
|
74
|
-
version: 0.7.
|
|
74
|
+
version: 0.7.6
|
|
75
75
|
type: :runtime
|
|
76
76
|
prerelease: false
|
|
77
77
|
version_requirements: !ruby/object:Gem::Requirement
|
|
78
78
|
requirements:
|
|
79
79
|
- - ">="
|
|
80
80
|
- !ruby/object:Gem::Version
|
|
81
|
-
version: 0.7.
|
|
81
|
+
version: 0.7.6
|
|
82
82
|
description: Gemini provider integration for the LegionIO LLM routing framework.
|
|
83
83
|
email:
|
|
84
84
|
- matthewdiverson@gmail.com
|