lex-llm-vllm 0.4.5 → 0.4.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/CHANGELOG.md +16 -0
- data/lex-llm-vllm.gemspec +3 -4
- data/lib/legion/extensions/llm/vllm/helpers/offering_builder.rb +11 -1
- data/lib/legion/extensions/llm/vllm/runners/discovery_refresh/claim_activation.rb +51 -27
- data/lib/legion/extensions/llm/vllm/runners/discovery_refresh/health_display.rb +2 -2
- data/lib/legion/extensions/llm/vllm/runners/discovery_refresh/instance_lifecycle.rb +23 -7
- data/lib/legion/extensions/llm/vllm/runners/discovery_refresh/offering_comparison.rb +51 -0
- data/lib/legion/extensions/llm/vllm/runners/discovery_refresh/probing.rb +5 -10
- data/lib/legion/extensions/llm/vllm/runners/discovery_refresh/weight_publication.rb +89 -0
- data/lib/legion/extensions/llm/vllm/runners/discovery_refresh.rb +8 -1
- data/lib/legion/extensions/llm/vllm/version.rb +1 -1
- metadata +5 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: d68ddb8f9c969ef5991b7437e6d0d9cea05f2e4dfe9f39fbb9696ec513988b4f
|
|
4
|
+
data.tar.gz: 9fa21d69ed1c20795872db8648140c4d89b8155487a6def3f0fe7f121bf39e1e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 5a372fff3346ff953fe4265073c19cefe72064a2592adb2d8313f2a61241d657424afd1eeb973284d3c15269500c04bcf47b16402317e9c240aebe2c213d62ad
|
|
7
|
+
data.tar.gz: f2ea87b7809e88965c53c19f412c3c37eb1036a3ffab1cf20bedf60c9c672c6cb918aee3aaf96ee1df513da7815fe287c84ccc8b09808ce6ef96ab5704cc5664
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.4.6] - 2026-08-19
|
|
4
|
+
|
|
5
|
+
### Changed
|
|
6
|
+
- Publish the immutable four-component lane-weight pair from vLLM discovery and reconcile weight-only changes on the existing module-runner cadence.
|
|
7
|
+
- Serialize initial, recovery, replacement, removal, shutdown, and probe publication transitions behind one module-level mutex without adding a Settings callback or operator workflow.
|
|
8
|
+
- Track configured-but-unpublished weight keys on the ordinary discovery pass and log each dormant transition once.
|
|
9
|
+
- Raise the `lex-llm` dependency floor to 0.7.6; the existing `legion-settings` dependency remains unchanged.
|
|
10
|
+
|
|
11
|
+
### Fixed
|
|
12
|
+
- Compare the offering catalog as a duplicate-preserving multiset of complete contracts while excluding only non-authoritative evidence observation timestamps, preventing both reorder-only churn and accidental duplicate suppression while retaining real evidence and weight changes.
|
|
13
|
+
- Complete startup discovery and weight validation before constructing a callable or claiming inventory, so malformed settings leave no orphaned initializing scope and the next valid cadence pass recovers without operator action.
|
|
14
|
+
- Use a real in-memory IO sink for the test logger so Ruby 4 cannot fall back to stdout during the file-only RSpec release gate.
|
|
15
|
+
|
|
16
|
+
### Added
|
|
17
|
+
- Cover the complete writer lifecycle, publication races, failure atomicity, dormant-state cycle, and the actual callable's folded-system OpenAI-compatible wire payload.
|
|
18
|
+
|
|
3
19
|
## [0.4.5] - 2026-08-18
|
|
4
20
|
|
|
5
21
|
### Fixed
|
data/lex-llm-vllm.gemspec
CHANGED
|
@@ -27,8 +27,7 @@ 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
|
-
# 0.7.
|
|
31
|
-
#
|
|
32
|
-
|
|
33
|
-
spec.add_dependency 'lex-llm', '>= 0.7.1'
|
|
30
|
+
# 0.7.6 carries the write-time weight schema/reconciler and the immutable
|
|
31
|
+
# OfferingDraft/OfferingRecord/LaneRecord weight pair used by this writer.
|
|
32
|
+
spec.add_dependency 'lex-llm', '>= 0.7.6'
|
|
34
33
|
end
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require 'legion/extensions/llm/inventory/evidence'
|
|
4
|
+
require 'legion/extensions/llm/inventory/weight_reconciler'
|
|
4
5
|
|
|
5
6
|
module Legion
|
|
6
7
|
module Extensions
|
|
@@ -20,6 +21,13 @@ module Legion
|
|
|
20
21
|
tier = @instance_cfg[:tier] || :direct
|
|
21
22
|
embed_sup = embedding_supported?(model_data)
|
|
22
23
|
max_output = model_data[:max_output_tokens] || model_data[:max_completion_tokens]
|
|
24
|
+
weight_inputs = Legion::Extensions::Llm::Inventory::WeightSchema.weight_inputs(
|
|
25
|
+
settings: Legion::Settings,
|
|
26
|
+
instance_key: instance_key,
|
|
27
|
+
provider_native_key: model_id,
|
|
28
|
+
model: model_id,
|
|
29
|
+
tier: tier
|
|
30
|
+
)
|
|
23
31
|
|
|
24
32
|
Legion::Extensions::Llm::Inventory::OfferingDraft.new(
|
|
25
33
|
provider_native_key: model_id,
|
|
@@ -34,7 +42,9 @@ module Legion
|
|
|
34
42
|
tokenizer_evidence: build_tokenizer_evidence(model_data[:tokenizer]),
|
|
35
43
|
quota_domains: {},
|
|
36
44
|
metadata: build_metadata(model_data),
|
|
37
|
-
publication_source: :provider_catalog
|
|
45
|
+
publication_source: :provider_catalog,
|
|
46
|
+
weight_inputs: weight_inputs,
|
|
47
|
+
base_weight: Legion::Extensions::Llm::Inventory::WeightSchema.base_weight(weight_inputs)
|
|
38
48
|
)
|
|
39
49
|
end
|
|
40
50
|
|
|
@@ -31,30 +31,32 @@ module Legion
|
|
|
31
31
|
# (InstanceKey.instance_id); the derived host:port/ak string is
|
|
32
32
|
# the secondary physical_id (dedup/diagnostics, never identity).
|
|
33
33
|
def claim_and_activate_instance(name:, instance_cfg:)
|
|
34
|
+
instance_id = name.to_s
|
|
34
35
|
instance_key = Legion::Extensions::Llm::Inventory::Identity::InstanceKey.new(
|
|
35
|
-
provider_family: :vllm, instance_id:
|
|
36
|
+
provider_family: :vllm, instance_id: instance_id,
|
|
36
37
|
physical_id: derive_physical_id(instance_cfg: instance_cfg)
|
|
37
38
|
)
|
|
39
|
+
offerings = fetch_offerings(instance_cfg: instance_cfg, instance_key: instance_key)
|
|
38
40
|
callable = Legion::Extensions::Llm::Vllm::VllmCallable.new(instance_cfg: instance_cfg, logger: log)
|
|
39
41
|
probe_coordinator = Legion::Extensions::Llm::Inventory::ProbeCoordinator.new(
|
|
40
|
-
instance_key: instance_key, enqueue: build_probe_enqueue(instance_id:
|
|
42
|
+
instance_key: instance_key, enqueue: build_probe_enqueue(instance_id: instance_id)
|
|
41
43
|
)
|
|
42
44
|
publisher_token = publisher.claim_instance(
|
|
43
|
-
instance_id:
|
|
45
|
+
instance_id: instance_id, physical_id: instance_key.physical_id,
|
|
44
46
|
callable: callable, probe_request_handle: probe_coordinator
|
|
45
47
|
)
|
|
46
|
-
|
|
47
|
-
# Store state BEFORE readiness so a failed boot probe leaves a
|
|
48
|
-
# recoverable :initializing entry for the next tick (D4).
|
|
49
48
|
state = {
|
|
50
|
-
name:
|
|
49
|
+
name: instance_id, instance_key: instance_key, instance_cfg: instance_cfg,
|
|
51
50
|
callable: callable, probe_coordinator: probe_coordinator,
|
|
52
|
-
publisher_token: publisher_token, sequence: 0, offerings:
|
|
51
|
+
publisher_token: publisher_token, sequence: 0, offerings: offerings
|
|
53
52
|
}
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
53
|
+
Legion::Extensions::Llm::Inventory::WeightReconciler.track_initializing!(
|
|
54
|
+
states: instance_states,
|
|
55
|
+
state_key: instance_id,
|
|
56
|
+
state: state,
|
|
57
|
+
mutex: state_mutex
|
|
58
|
+
)
|
|
59
|
+
perform_readiness(instance_id: instance_id, state: state, offerings: offerings)
|
|
58
60
|
end
|
|
59
61
|
|
|
60
62
|
# Run a readiness probe and commit the outcome. While the instance
|
|
@@ -62,7 +64,9 @@ module Legion
|
|
|
62
64
|
# once activated it reports success/failure against the
|
|
63
65
|
# availability fact.
|
|
64
66
|
def perform_readiness(instance_id:, state:, offerings:)
|
|
65
|
-
|
|
67
|
+
reconcile_weight_snapshot(
|
|
68
|
+
instance_id: instance_id, state: state, discovered_offerings: offerings
|
|
69
|
+
)
|
|
66
70
|
probe_token = publisher.readiness_probe_started(
|
|
67
71
|
instance_id: instance_id, publisher_token: state[:publisher_token]
|
|
68
72
|
)
|
|
@@ -75,23 +79,43 @@ module Legion
|
|
|
75
79
|
end
|
|
76
80
|
|
|
77
81
|
def report_probe_result(instance_id:, state:, probe_token:, readiness:)
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
end
|
|
91
|
-
write_instance_health(state)
|
|
82
|
+
committed = if readiness.ready? && tracked_unpublished?(instance_id: instance_id, state: state)
|
|
83
|
+
activate_tracked_state(
|
|
84
|
+
instance_id: instance_id, state: state, probe_token: probe_token
|
|
85
|
+
)
|
|
86
|
+
else
|
|
87
|
+
report_tracked_readiness(
|
|
88
|
+
instance_id: instance_id, state: state,
|
|
89
|
+
probe_token: probe_token, readiness: readiness
|
|
90
|
+
)
|
|
91
|
+
end
|
|
92
|
+
write_instance_health(state) if committed
|
|
93
|
+
committed
|
|
92
94
|
rescue StandardError => e
|
|
93
95
|
handle_exception(e, level: :warn, operation: 'vllm.runner.discovery.report_probe',
|
|
94
96
|
instance_id: instance_id)
|
|
97
|
+
false
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def tracked_unpublished?(instance_id:, state:)
|
|
101
|
+
state_mutex.synchronize do
|
|
102
|
+
instance_states[instance_id].equal?(state) && !state.fetch(:published)
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def report_tracked_readiness(instance_id:, state:, probe_token:, readiness:)
|
|
107
|
+
state_mutex.synchronize do
|
|
108
|
+
return false unless instance_states[instance_id].equal?(state)
|
|
109
|
+
|
|
110
|
+
if readiness.ready?
|
|
111
|
+
publisher.readiness_succeeded(instance_id: instance_id, probe_token: probe_token)
|
|
112
|
+
else
|
|
113
|
+
publisher.readiness_failed(
|
|
114
|
+
instance_id: instance_id, probe_token: probe_token, reason: readiness.reason
|
|
115
|
+
)
|
|
116
|
+
end
|
|
117
|
+
true
|
|
118
|
+
end
|
|
95
119
|
end
|
|
96
120
|
end
|
|
97
121
|
end
|
|
@@ -15,7 +15,7 @@ module Legion
|
|
|
15
15
|
snapshot = publisher.snapshot
|
|
16
16
|
display = display_fact(instance_key: instance_key, snapshot: snapshot)
|
|
17
17
|
|
|
18
|
-
instance_settings = settings.dig(:instances, state[:name])
|
|
18
|
+
instance_settings = settings.dig(:instances, state[:name].to_sym)
|
|
19
19
|
return unless instance_settings.is_a?(Hash)
|
|
20
20
|
|
|
21
21
|
instance_settings[:health] = health_hash(display)
|
|
@@ -26,7 +26,7 @@ module Legion
|
|
|
26
26
|
end
|
|
27
27
|
|
|
28
28
|
def clear_settings_health(name:)
|
|
29
|
-
instance_settings = settings.dig(:instances, name)
|
|
29
|
+
instance_settings = settings.dig(:instances, name.to_sym)
|
|
30
30
|
return unless instance_settings.is_a?(Hash)
|
|
31
31
|
|
|
32
32
|
instance_settings.delete(:health)
|
|
@@ -31,28 +31,36 @@ module Legion
|
|
|
31
31
|
# names pointing at the same endpoint remain distinct instances.
|
|
32
32
|
def reconcile_instances
|
|
33
33
|
configured = Vllm.discover_instances
|
|
34
|
+
configured_ids = configured.keys.map(&:to_s)
|
|
34
35
|
|
|
35
|
-
instance_states.
|
|
36
|
-
|
|
36
|
+
tracked_ids = state_mutex.synchronize { instance_states.keys }
|
|
37
|
+
tracked_ids.each do |instance_id|
|
|
38
|
+
next if configured_ids.include?(instance_id)
|
|
37
39
|
|
|
38
40
|
remove_instance_state(instance_id)
|
|
39
41
|
end
|
|
40
42
|
|
|
41
43
|
configured.each do |name, instance_cfg|
|
|
42
|
-
update_instance(name: name, instance_cfg: instance_cfg)
|
|
44
|
+
update_instance(name: name.to_s, instance_cfg: instance_cfg)
|
|
43
45
|
rescue StandardError => e
|
|
44
46
|
handle_exception(e, level: :warn, operation: 'vllm.runner.discovery.instance',
|
|
45
47
|
instance_name: name.to_s)
|
|
46
48
|
end
|
|
49
|
+
observe_dormant_weights
|
|
47
50
|
end
|
|
48
51
|
|
|
49
52
|
def remove_all_instances(**)
|
|
50
|
-
|
|
53
|
+
tracked_ids = state_mutex.synchronize { instance_states.keys }
|
|
54
|
+
tracked_ids.each { |instance_id| remove_instance_state(instance_id) }
|
|
55
|
+
state_mutex.synchronize do
|
|
56
|
+
instance_states.clear
|
|
57
|
+
dormant_weight_tracker.clear!
|
|
58
|
+
end
|
|
51
59
|
{ success: true }
|
|
52
60
|
end
|
|
53
61
|
|
|
54
62
|
def update_instance(name:, instance_cfg:)
|
|
55
|
-
state = instance_states[name]
|
|
63
|
+
state = state_mutex.synchronize { instance_states[name] }
|
|
56
64
|
if state && physical_id_changed?(state, instance_cfg)
|
|
57
65
|
# The physical target moved (endpoint or API key changed) —
|
|
58
66
|
# the captured callable points at the old endpoint, so drop
|
|
@@ -71,10 +79,18 @@ module Legion
|
|
|
71
79
|
end
|
|
72
80
|
|
|
73
81
|
def remove_instance_state(instance_id)
|
|
74
|
-
state =
|
|
82
|
+
state = state_mutex.synchronize do
|
|
83
|
+
tracked = instance_states[instance_id]
|
|
84
|
+
next unless tracked
|
|
85
|
+
|
|
86
|
+
publisher.remove_instance(
|
|
87
|
+
instance_id: instance_id, publisher_token: tracked[:publisher_token]
|
|
88
|
+
)
|
|
89
|
+
instance_states.delete(instance_id) if instance_states[instance_id].equal?(tracked)
|
|
90
|
+
tracked
|
|
91
|
+
end
|
|
75
92
|
return unless state
|
|
76
93
|
|
|
77
|
-
publisher.remove_instance(instance_id: instance_id, publisher_token: state[:publisher_token])
|
|
78
94
|
clear_settings_health(name: state[:name])
|
|
79
95
|
rescue StandardError => e
|
|
80
96
|
handle_exception(e, level: :warn, operation: 'vllm.runner.discovery.remove_instance',
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Legion
|
|
4
|
+
module Extensions
|
|
5
|
+
module Llm
|
|
6
|
+
module Vllm
|
|
7
|
+
module Runners
|
|
8
|
+
module DiscoveryRefresh
|
|
9
|
+
# vLLM rebuilds fresh evidence timestamps on every catalog pass.
|
|
10
|
+
# Compare the complete draft contract while excluding only that
|
|
11
|
+
# non-authoritative observation telemetry.
|
|
12
|
+
module OfferingComparison
|
|
13
|
+
SCALAR_EVIDENCE_FIELDS = %i[
|
|
14
|
+
context_evidence max_output_evidence embedding_dimensions_evidence
|
|
15
|
+
model_revision_evidence tokenizer_evidence
|
|
16
|
+
].freeze
|
|
17
|
+
|
|
18
|
+
def offerings_equivalent?(previous, current)
|
|
19
|
+
offering_comparison_multiset(previous) == offering_comparison_multiset(current)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
private
|
|
23
|
+
|
|
24
|
+
def offering_comparison_multiset(offerings)
|
|
25
|
+
Array(offerings).map { |draft| offering_comparison_state(draft) }.tally
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def offering_comparison_state(draft)
|
|
29
|
+
state = draft.to_h
|
|
30
|
+
state[:operation_evidence] = comparison_evidence_map(draft.operation_evidence)
|
|
31
|
+
state[:capability_evidence] = comparison_evidence_map(draft.capability_evidence)
|
|
32
|
+
SCALAR_EVIDENCE_FIELDS.each do |field|
|
|
33
|
+
state[field] = comparison_evidence(draft.public_send(field))
|
|
34
|
+
end
|
|
35
|
+
state
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def comparison_evidence_map(evidence)
|
|
39
|
+
evidence.transform_values { |entry| comparison_evidence(entry) }
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def comparison_evidence(evidence)
|
|
43
|
+
evidence.to_h.except(:observed_at)
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
@@ -10,7 +10,7 @@ module Legion
|
|
|
10
10
|
# discovery runner. Mixed into DiscoveryRefresh.
|
|
11
11
|
module Probing
|
|
12
12
|
def refresh_instance(instance_id:, instance_cfg:)
|
|
13
|
-
state = instance_states[instance_id]
|
|
13
|
+
state = state_mutex.synchronize { instance_states[instance_id] }
|
|
14
14
|
return unless state
|
|
15
15
|
|
|
16
16
|
status = publisher.snapshot.publication_status(instance_key: state[:instance_key])
|
|
@@ -29,15 +29,10 @@ module Legion
|
|
|
29
29
|
|
|
30
30
|
def replace_if_changed(instance_id:, state:, instance_cfg:)
|
|
31
31
|
new_offerings = fetch_offerings(instance_cfg: instance_cfg, instance_key: state[:instance_key])
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
state[:sequence] += 1
|
|
35
|
-
publisher.replace_instance_snapshot(
|
|
36
|
-
instance_id: instance_id, publisher_token: state[:publisher_token],
|
|
37
|
-
offerings: new_offerings, sequence: state[:sequence]
|
|
32
|
+
changed = reconcile_weight_snapshot(
|
|
33
|
+
instance_id: instance_id, state: state, discovered_offerings: new_offerings
|
|
38
34
|
)
|
|
39
|
-
state
|
|
40
|
-
write_instance_health(state)
|
|
35
|
+
write_instance_health(state) if changed
|
|
41
36
|
end
|
|
42
37
|
|
|
43
38
|
def run_cadence_probe(instance_id:, state:)
|
|
@@ -58,7 +53,7 @@ module Legion
|
|
|
58
53
|
end
|
|
59
54
|
|
|
60
55
|
def handle_reactive_probe(instance_id:, request:)
|
|
61
|
-
state = instance_states[instance_id]
|
|
56
|
+
state = state_mutex.synchronize { instance_states[instance_id] }
|
|
62
57
|
return unless state
|
|
63
58
|
|
|
64
59
|
coordinator = state[:probe_coordinator]
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Legion
|
|
4
|
+
module Extensions
|
|
5
|
+
module Llm
|
|
6
|
+
module Vllm
|
|
7
|
+
module Runners
|
|
8
|
+
module DiscoveryRefresh
|
|
9
|
+
# Module-runner bindings for the shared writer reconciler. The
|
|
10
|
+
# existing discovery cadence remains the only execution path.
|
|
11
|
+
module WeightPublication
|
|
12
|
+
def reconcile_weight_snapshot(instance_id:, state:, discovered_offerings:)
|
|
13
|
+
Legion::Extensions::Llm::Inventory::WeightReconciler.commit_if_changed!(
|
|
14
|
+
settings: Legion::Settings,
|
|
15
|
+
instance_id: instance_id,
|
|
16
|
+
state: state,
|
|
17
|
+
discovered_offerings: discovered_offerings,
|
|
18
|
+
mutex: state_mutex,
|
|
19
|
+
equivalent: lambda do |previous, current|
|
|
20
|
+
!instance_states[instance_id].equal?(state) ||
|
|
21
|
+
offerings_equivalent?(previous, current)
|
|
22
|
+
end,
|
|
23
|
+
replace: method(:replace_weight_snapshot)
|
|
24
|
+
)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def replace_weight_snapshot(instance_id:, state:, offerings:, sequence:)
|
|
28
|
+
publisher.replace_instance_snapshot(
|
|
29
|
+
instance_id: instance_id,
|
|
30
|
+
publisher_token: state.fetch(:publisher_token),
|
|
31
|
+
offerings: offerings,
|
|
32
|
+
sequence: sequence
|
|
33
|
+
)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def activate_weight_snapshot(instance_id:, state:, offerings:, sequence:, probe_token:)
|
|
37
|
+
publisher.activate_instance_snapshot(
|
|
38
|
+
instance_id: instance_id,
|
|
39
|
+
publisher_token: state.fetch(:publisher_token),
|
|
40
|
+
offerings: offerings,
|
|
41
|
+
sequence: sequence,
|
|
42
|
+
probe_token: probe_token
|
|
43
|
+
)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def activate_tracked_state(instance_id:, state:, probe_token:)
|
|
47
|
+
Legion::Extensions::Llm::Inventory::WeightReconciler.activate_tracked!(
|
|
48
|
+
settings: Legion::Settings,
|
|
49
|
+
instance_id: instance_id,
|
|
50
|
+
state_key: state.fetch(:name),
|
|
51
|
+
state: state,
|
|
52
|
+
states: instance_states,
|
|
53
|
+
mutex: state_mutex,
|
|
54
|
+
probe_token: probe_token,
|
|
55
|
+
activate: method(:activate_weight_snapshot),
|
|
56
|
+
activation_sequence: ->(tracked) { tracked.fetch(:sequence) }
|
|
57
|
+
)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def observe_dormant_weights
|
|
61
|
+
Legion::Extensions::Llm::Inventory::WeightReconciler.observe_dormant!(
|
|
62
|
+
settings: Legion::Settings,
|
|
63
|
+
provider_family: :vllm,
|
|
64
|
+
states: instance_states,
|
|
65
|
+
mutex: state_mutex,
|
|
66
|
+
tracker: dormant_weight_tracker,
|
|
67
|
+
dormant_logger: lambda do |key|
|
|
68
|
+
log.info(
|
|
69
|
+
"[llm][vllm] action=dormant_weight weight_key=#{key.inspect} no_lane_published=true"
|
|
70
|
+
)
|
|
71
|
+
end
|
|
72
|
+
)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def state_mutex
|
|
76
|
+
@state_mutex ||= Mutex.new
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def dormant_weight_tracker
|
|
80
|
+
@dormant_weight_tracker ||=
|
|
81
|
+
Legion::Extensions::Llm::Inventory::DormantWeightTracker.new
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
@@ -7,6 +7,8 @@ require 'legion/logging'
|
|
|
7
7
|
require 'legion/extensions/llm/vllm'
|
|
8
8
|
require 'legion/extensions/llm/inventory/records'
|
|
9
9
|
|
|
10
|
+
require 'legion/extensions/llm/vllm/runners/discovery_refresh/offering_comparison'
|
|
11
|
+
require 'legion/extensions/llm/vllm/runners/discovery_refresh/weight_publication'
|
|
10
12
|
require 'legion/extensions/llm/vllm/runners/discovery_refresh/instance_lifecycle'
|
|
11
13
|
require 'legion/extensions/llm/vllm/runners/discovery_refresh/claim_activation'
|
|
12
14
|
require 'legion/extensions/llm/vllm/runners/discovery_refresh/probing'
|
|
@@ -45,6 +47,8 @@ module Legion
|
|
|
45
47
|
# Http — model/health HTTP, instance identity
|
|
46
48
|
module DiscoveryRefresh
|
|
47
49
|
include Legion::Extensions::Helpers::Lex
|
|
50
|
+
include OfferingComparison
|
|
51
|
+
include WeightPublication
|
|
48
52
|
include InstanceLifecycle
|
|
49
53
|
include ClaimActivation
|
|
50
54
|
include Probing
|
|
@@ -60,7 +64,10 @@ module Legion
|
|
|
60
64
|
end
|
|
61
65
|
|
|
62
66
|
def self.reset_instance_states!
|
|
63
|
-
|
|
67
|
+
state_mutex.synchronize do
|
|
68
|
+
@instance_states.clear
|
|
69
|
+
dormant_weight_tracker.clear!
|
|
70
|
+
end
|
|
64
71
|
end
|
|
65
72
|
end
|
|
66
73
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: lex-llm-vllm
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.4.
|
|
4
|
+
version: 0.4.6
|
|
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: vLLM provider integration for the LegionIO LLM routing framework.
|
|
83
83
|
email:
|
|
84
84
|
- matthewdiverson@gmail.com
|
|
@@ -107,7 +107,9 @@ files:
|
|
|
107
107
|
- lib/legion/extensions/llm/vllm/runners/discovery_refresh/health_display.rb
|
|
108
108
|
- lib/legion/extensions/llm/vllm/runners/discovery_refresh/http.rb
|
|
109
109
|
- lib/legion/extensions/llm/vllm/runners/discovery_refresh/instance_lifecycle.rb
|
|
110
|
+
- lib/legion/extensions/llm/vllm/runners/discovery_refresh/offering_comparison.rb
|
|
110
111
|
- lib/legion/extensions/llm/vllm/runners/discovery_refresh/probing.rb
|
|
112
|
+
- lib/legion/extensions/llm/vllm/runners/discovery_refresh/weight_publication.rb
|
|
111
113
|
- lib/legion/extensions/llm/vllm/runners/fleet_worker.rb
|
|
112
114
|
- lib/legion/extensions/llm/vllm/translator.rb
|
|
113
115
|
- lib/legion/extensions/llm/vllm/version.rb
|