lex-llm 0.6.16 → 0.7.2
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 +29 -0
- data/lex-llm.gemspec +1 -1
- data/lib/legion/extensions/llm/auto_registration.rb +3 -0
- data/lib/legion/extensions/llm/canonical/message.rb +5 -1
- data/lib/legion/extensions/llm/fleet/protocol.rb +12 -0
- data/lib/legion/extensions/llm/fleet/provider_responder.rb +40 -5
- data/lib/legion/extensions/llm/fleet/token_validator.rb +15 -0
- data/lib/legion/extensions/llm/fleet/worker_execution.rb +166 -2
- data/lib/legion/extensions/llm/inventory/callable_handle.rb +144 -0
- data/lib/legion/extensions/llm/inventory/errors.rb +34 -0
- data/lib/legion/extensions/llm/inventory/evidence.rb +134 -0
- data/lib/legion/extensions/llm/inventory/identity.rb +141 -0
- data/lib/legion/extensions/llm/inventory/immutable_value.rb +96 -0
- data/lib/legion/extensions/llm/inventory/probe_coordinator.rb +117 -0
- data/lib/legion/extensions/llm/inventory/probe_token.rb +146 -0
- data/lib/legion/extensions/llm/inventory/publisher.rb +116 -0
- data/lib/legion/extensions/llm/inventory/records.rb +599 -0
- data/lib/legion/extensions/llm/inventory/registry.rb +636 -0
- data/lib/legion/extensions/llm/inventory/scoped_refresher.rb +206 -0
- data/lib/legion/extensions/llm/inventory/snapshot.rb +91 -0
- data/lib/legion/extensions/llm/provider.rb +55 -29
- data/lib/legion/extensions/llm/routing/lane_key.rb +4 -0
- data/lib/legion/extensions/llm/routing/model_offering.rb +3 -0
- data/lib/legion/extensions/llm/routing/offering_registry.rb +2 -0
- data/lib/legion/extensions/llm/routing/provider_outcome.rb +54 -0
- data/lib/legion/extensions/llm/routing/records.rb +288 -0
- data/lib/legion/extensions/llm/settings_cascade.rb +120 -0
- data/lib/legion/extensions/llm/taxonomies.rb +90 -0
- data/lib/legion/extensions/llm/transport/messages/fleet_error.rb +3 -1
- data/lib/legion/extensions/llm/transport/messages/fleet_response.rb +3 -1
- data/lib/legion/extensions/llm/version.rb +1 -1
- data/lib/legion/extensions/llm.rb +18 -0
- data/spec/legion/extensions/llm/canonical/message_spec.rb +24 -0
- data/spec/legion/extensions/llm/conformance/fixtures/canonical_params_mapping_request.json +1 -0
- data/spec/legion/extensions/llm/conformance/fixtures/canonical_simple_text_request.json +1 -0
- data/spec/legion/extensions/llm/conformance/fixtures/canonical_system_prompt_request.json +1 -0
- data/spec/legion/extensions/llm/conformance/fixtures/canonical_thinking_request.json +1 -0
- data/spec/legion/extensions/llm/conformance/fixtures/canonical_tool_results_continuation_request.json +1 -0
- data/spec/legion/extensions/llm/conformance/fixtures/canonical_tools_request.json +1 -0
- data/spec/legion/extensions/llm/conformance/fixtures/ssot_identity_vectors.json +84 -0
- data/spec/legion/extensions/llm/conformance/ssot_provider_conformance_spec.rb +13 -0
- data/spec/legion/extensions/llm/conformance/ssot_provider_examples.rb +196 -0
- data/spec/legion/extensions/llm/fleet/exact_offering_spec.rb +179 -0
- data/spec/legion/extensions/llm/fleet/provider_responder_spec.rb +26 -0
- data/spec/legion/extensions/llm/fleet_messages_spec.rb +14 -0
- data/spec/legion/extensions/llm/inventory/boot_spec.rb +80 -0
- data/spec/legion/extensions/llm/inventory/callable_handle_spec.rb +127 -0
- data/spec/legion/extensions/llm/inventory/evidence_spec.rb +138 -0
- data/spec/legion/extensions/llm/inventory/identity_spec.rb +280 -0
- data/spec/legion/extensions/llm/inventory/immutable_value_spec.rb +132 -0
- data/spec/legion/extensions/llm/inventory/probe_coordinator_spec.rb +107 -0
- data/spec/legion/extensions/llm/inventory/probe_token_spec.rb +107 -0
- data/spec/legion/extensions/llm/inventory/publisher_spec.rb +144 -0
- data/spec/legion/extensions/llm/inventory/records_spec.rb +300 -0
- data/spec/legion/extensions/llm/inventory/registry_activation_spec.rb +140 -0
- data/spec/legion/extensions/llm/inventory/registry_availability_spec.rb +152 -0
- data/spec/legion/extensions/llm/inventory/registry_callable_spec.rb +63 -0
- data/spec/legion/extensions/llm/inventory/registry_replacement_spec.rb +69 -0
- data/spec/legion/extensions/llm/inventory/scoped_refresher_spec.rb +128 -0
- data/spec/legion/extensions/llm/inventory/snapshot_spec.rb +109 -0
- data/spec/legion/extensions/llm/provider_contract_spec.rb +20 -0
- data/spec/legion/extensions/llm/provider_spec.rb +83 -0
- data/spec/legion/extensions/llm/routing/provider_outcome_spec.rb +73 -0
- data/spec/legion/extensions/llm/routing/records_spec.rb +173 -0
- data/spec/legion/extensions/llm/settings_cascade_spec.rb +208 -0
- data/spec/legion/extensions/llm/taxonomies_spec.rb +51 -0
- data/spec/support/fake_llm_provider.rb +11 -0
- data/spec/support/fake_ssot_harness.rb +137 -0
- data/spec/support/ssot_registry_helpers.rb +75 -0
- metadata +40 -3
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'legion/logging'
|
|
4
|
+
require 'legion/extensions/llm/inventory/errors'
|
|
5
|
+
require 'legion/extensions/llm/inventory/identity'
|
|
6
|
+
require 'legion/extensions/llm/inventory/registry'
|
|
7
|
+
|
|
8
|
+
module Legion
|
|
9
|
+
module Extensions
|
|
10
|
+
module Llm
|
|
11
|
+
module Inventory
|
|
12
|
+
# Provider-facing direct wrapper over the local Registry. It constructs
|
|
13
|
+
# and validates the exact InstanceKey from its fixed provider family and
|
|
14
|
+
# delegates to the registry with the exact kwargs. It does no retries,
|
|
15
|
+
# selection, scheduling, defaulting, provider discovery, or exception
|
|
16
|
+
# swallowing beyond the explicitly injected, best-effort post-commit
|
|
17
|
+
# old-coordinator projection. See phase-1-lex-llm-additive.md section 13.1.
|
|
18
|
+
class Publisher
|
|
19
|
+
include Legion::Logging::Helper
|
|
20
|
+
|
|
21
|
+
def initialize(provider_family:, registry: Registry, compatibility_adapter: nil)
|
|
22
|
+
@provider_family = provider_family
|
|
23
|
+
@registry = registry
|
|
24
|
+
@compatibility_adapter = compatibility_adapter
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Every instance operation takes `instance_id:` — the operator's
|
|
28
|
+
# CONFIG NAME (the identity the router keys by) — and an optional
|
|
29
|
+
# `physical_id:` carrying the physical/derived id (host:port/ak) for
|
|
30
|
+
# dedup and diagnostics only. See Identity::InstanceKey.
|
|
31
|
+
def claim_instance(instance_id:, callable:, probe_request_handle:, physical_id: nil)
|
|
32
|
+
key = instance_key(instance_id: instance_id, physical_id: physical_id)
|
|
33
|
+
token = @registry.claim_instance(instance_key: key, callable: callable, probe_request_handle: probe_request_handle)
|
|
34
|
+
sync_compatibility(key, :claimed)
|
|
35
|
+
token
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def readiness_probe_started(instance_id:, publisher_token:, physical_id: nil)
|
|
39
|
+
@registry.readiness_probe_started(
|
|
40
|
+
instance_key: instance_key(instance_id: instance_id, physical_id: physical_id), publisher_token: publisher_token
|
|
41
|
+
)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def activate_instance_snapshot(instance_id:, publisher_token:, offerings:, sequence:, probe_token:, physical_id: nil) # rubocop:disable Metrics/ParameterLists
|
|
45
|
+
key = instance_key(instance_id: instance_id, physical_id: physical_id)
|
|
46
|
+
result = @registry.activate_instance_snapshot(
|
|
47
|
+
publisher_token: publisher_token, instance_key: key, offerings: offerings,
|
|
48
|
+
sequence: sequence, probe_token: probe_token
|
|
49
|
+
)
|
|
50
|
+
sync_applied(key, result)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def replace_instance_snapshot(instance_id:, publisher_token:, offerings:, sequence:, physical_id: nil)
|
|
54
|
+
key = instance_key(instance_id: instance_id, physical_id: physical_id)
|
|
55
|
+
result = @registry.replace_instance_snapshot(
|
|
56
|
+
publisher_token: publisher_token, instance_key: key, offerings: offerings, sequence: sequence
|
|
57
|
+
)
|
|
58
|
+
sync_applied(key, result)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def readiness_succeeded(instance_id:, probe_token:, physical_id: nil)
|
|
62
|
+
key = instance_key(instance_id: instance_id, physical_id: physical_id)
|
|
63
|
+
sync_applied(key, @registry.readiness_succeeded(instance_key: key, probe_token: probe_token))
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def readiness_failed(instance_id:, probe_token:, reason:, physical_id: nil)
|
|
67
|
+
key = instance_key(instance_id: instance_id, physical_id: physical_id)
|
|
68
|
+
sync_applied(key, @registry.readiness_failed(instance_key: key, probe_token: probe_token, reason: reason))
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def remove_instance(instance_id:, publisher_token:, physical_id: nil)
|
|
72
|
+
key = instance_key(instance_id: instance_id, physical_id: physical_id)
|
|
73
|
+
sync_applied(key, @registry.remove_instance(instance_key: key, publisher_token: publisher_token))
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def snapshot
|
|
77
|
+
@registry.snapshot
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
private
|
|
81
|
+
|
|
82
|
+
def instance_key(instance_id:, physical_id: nil)
|
|
83
|
+
Identity::InstanceKey.new(provider_family: @provider_family, instance_id: instance_id, physical_id: physical_id)
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def sync_applied(instance_key, result)
|
|
87
|
+
sync_compatibility(instance_key, result.reason) if result.applied
|
|
88
|
+
result
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
# Best-effort, post-commit projection into the old coordinator. It never
|
|
92
|
+
# changes the local return and can never roll back or authorize the SSOT.
|
|
93
|
+
def sync_compatibility(instance_key, mutation_reason)
|
|
94
|
+
return if @compatibility_adapter.nil?
|
|
95
|
+
|
|
96
|
+
outcome = @compatibility_adapter.sync_snapshot(
|
|
97
|
+
snapshot: @registry.snapshot, instance_key: instance_key, mutation_reason: mutation_reason
|
|
98
|
+
)
|
|
99
|
+
return unless outcome == :failed
|
|
100
|
+
|
|
101
|
+
log.warn(
|
|
102
|
+
'[llm][inventory][publisher] action=compatibility_sync result=failed ' \
|
|
103
|
+
"provider_family=#{instance_key.provider_family} instance=#{instance_key.instance_id} reason=#{mutation_reason}"
|
|
104
|
+
)
|
|
105
|
+
rescue StandardError => e
|
|
106
|
+
handle_exception(
|
|
107
|
+
e, handled: true, level: :warn, operation: 'llm.inventory.publisher.compatibility_sync',
|
|
108
|
+
provider_family: instance_key.provider_family, instance_id: instance_key.instance_id,
|
|
109
|
+
mutation_reason: mutation_reason
|
|
110
|
+
)
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
end
|