lex-llm 0.6.16 → 0.7.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.
Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +14 -0
  3. data/lib/legion/extensions/llm/auto_registration.rb +3 -0
  4. data/lib/legion/extensions/llm/fleet/protocol.rb +12 -0
  5. data/lib/legion/extensions/llm/fleet/provider_responder.rb +40 -5
  6. data/lib/legion/extensions/llm/fleet/token_validator.rb +15 -0
  7. data/lib/legion/extensions/llm/fleet/worker_execution.rb +166 -2
  8. data/lib/legion/extensions/llm/inventory/callable_handle.rb +144 -0
  9. data/lib/legion/extensions/llm/inventory/errors.rb +34 -0
  10. data/lib/legion/extensions/llm/inventory/evidence.rb +134 -0
  11. data/lib/legion/extensions/llm/inventory/identity.rb +119 -0
  12. data/lib/legion/extensions/llm/inventory/immutable_value.rb +96 -0
  13. data/lib/legion/extensions/llm/inventory/probe_coordinator.rb +117 -0
  14. data/lib/legion/extensions/llm/inventory/probe_token.rb +146 -0
  15. data/lib/legion/extensions/llm/inventory/publisher.rb +110 -0
  16. data/lib/legion/extensions/llm/inventory/records.rb +592 -0
  17. data/lib/legion/extensions/llm/inventory/registry.rb +636 -0
  18. data/lib/legion/extensions/llm/inventory/scoped_refresher.rb +206 -0
  19. data/lib/legion/extensions/llm/inventory/snapshot.rb +91 -0
  20. data/lib/legion/extensions/llm/provider.rb +43 -0
  21. data/lib/legion/extensions/llm/routing/lane_key.rb +4 -0
  22. data/lib/legion/extensions/llm/routing/model_offering.rb +3 -0
  23. data/lib/legion/extensions/llm/routing/offering_registry.rb +2 -0
  24. data/lib/legion/extensions/llm/routing/provider_outcome.rb +54 -0
  25. data/lib/legion/extensions/llm/routing/records.rb +288 -0
  26. data/lib/legion/extensions/llm/taxonomies.rb +90 -0
  27. data/lib/legion/extensions/llm/transport/messages/fleet_error.rb +3 -1
  28. data/lib/legion/extensions/llm/transport/messages/fleet_response.rb +3 -1
  29. data/lib/legion/extensions/llm/version.rb +1 -1
  30. data/lib/legion/extensions/llm.rb +15 -0
  31. data/spec/legion/extensions/llm/conformance/fixtures/ssot_identity_vectors.json +84 -0
  32. data/spec/legion/extensions/llm/conformance/ssot_provider_conformance_spec.rb +13 -0
  33. data/spec/legion/extensions/llm/conformance/ssot_provider_examples.rb +196 -0
  34. data/spec/legion/extensions/llm/fleet/exact_offering_spec.rb +179 -0
  35. data/spec/legion/extensions/llm/fleet/provider_responder_spec.rb +26 -0
  36. data/spec/legion/extensions/llm/fleet_messages_spec.rb +14 -0
  37. data/spec/legion/extensions/llm/inventory/boot_spec.rb +80 -0
  38. data/spec/legion/extensions/llm/inventory/callable_handle_spec.rb +127 -0
  39. data/spec/legion/extensions/llm/inventory/evidence_spec.rb +125 -0
  40. data/spec/legion/extensions/llm/inventory/identity_spec.rb +227 -0
  41. data/spec/legion/extensions/llm/inventory/immutable_value_spec.rb +132 -0
  42. data/spec/legion/extensions/llm/inventory/probe_coordinator_spec.rb +107 -0
  43. data/spec/legion/extensions/llm/inventory/probe_token_spec.rb +107 -0
  44. data/spec/legion/extensions/llm/inventory/publisher_spec.rb +104 -0
  45. data/spec/legion/extensions/llm/inventory/records_spec.rb +300 -0
  46. data/spec/legion/extensions/llm/inventory/registry_activation_spec.rb +140 -0
  47. data/spec/legion/extensions/llm/inventory/registry_availability_spec.rb +152 -0
  48. data/spec/legion/extensions/llm/inventory/registry_callable_spec.rb +63 -0
  49. data/spec/legion/extensions/llm/inventory/registry_replacement_spec.rb +69 -0
  50. data/spec/legion/extensions/llm/inventory/scoped_refresher_spec.rb +128 -0
  51. data/spec/legion/extensions/llm/inventory/snapshot_spec.rb +109 -0
  52. data/spec/legion/extensions/llm/provider_contract_spec.rb +20 -0
  53. data/spec/legion/extensions/llm/provider_spec.rb +83 -0
  54. data/spec/legion/extensions/llm/routing/provider_outcome_spec.rb +59 -0
  55. data/spec/legion/extensions/llm/routing/records_spec.rb +173 -0
  56. data/spec/legion/extensions/llm/taxonomies_spec.rb +51 -0
  57. data/spec/support/fake_llm_provider.rb +11 -0
  58. data/spec/support/fake_ssot_harness.rb +137 -0
  59. data/spec/support/ssot_registry_helpers.rb +75 -0
  60. metadata +36 -1
@@ -0,0 +1,110 @@
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
+ def claim_instance(instance_id:, callable:, probe_request_handle:)
28
+ key = instance_key(instance_id)
29
+ token = @registry.claim_instance(instance_key: key, callable: callable, probe_request_handle: probe_request_handle)
30
+ sync_compatibility(key, :claimed)
31
+ token
32
+ end
33
+
34
+ def readiness_probe_started(instance_id:, publisher_token:)
35
+ @registry.readiness_probe_started(instance_key: instance_key(instance_id), publisher_token: publisher_token)
36
+ end
37
+
38
+ def activate_instance_snapshot(instance_id:, publisher_token:, offerings:, sequence:, probe_token:)
39
+ key = instance_key(instance_id)
40
+ result = @registry.activate_instance_snapshot(
41
+ publisher_token: publisher_token, instance_key: key, offerings: offerings,
42
+ sequence: sequence, probe_token: probe_token
43
+ )
44
+ sync_applied(key, result)
45
+ end
46
+
47
+ def replace_instance_snapshot(instance_id:, publisher_token:, offerings:, sequence:)
48
+ key = instance_key(instance_id)
49
+ result = @registry.replace_instance_snapshot(
50
+ publisher_token: publisher_token, instance_key: key, offerings: offerings, sequence: sequence
51
+ )
52
+ sync_applied(key, result)
53
+ end
54
+
55
+ def readiness_succeeded(instance_id:, probe_token:)
56
+ key = instance_key(instance_id)
57
+ sync_applied(key, @registry.readiness_succeeded(instance_key: key, probe_token: probe_token))
58
+ end
59
+
60
+ def readiness_failed(instance_id:, probe_token:, reason:)
61
+ key = instance_key(instance_id)
62
+ sync_applied(key, @registry.readiness_failed(instance_key: key, probe_token: probe_token, reason: reason))
63
+ end
64
+
65
+ def remove_instance(instance_id:, publisher_token:)
66
+ key = instance_key(instance_id)
67
+ sync_applied(key, @registry.remove_instance(instance_key: key, publisher_token: publisher_token))
68
+ end
69
+
70
+ def snapshot
71
+ @registry.snapshot
72
+ end
73
+
74
+ private
75
+
76
+ def instance_key(instance_id)
77
+ Identity::InstanceKey.new(provider_family: @provider_family, instance_id: instance_id)
78
+ end
79
+
80
+ def sync_applied(instance_key, result)
81
+ sync_compatibility(instance_key, result.reason) if result.applied
82
+ result
83
+ end
84
+
85
+ # Best-effort, post-commit projection into the old coordinator. It never
86
+ # changes the local return and can never roll back or authorize the SSOT.
87
+ def sync_compatibility(instance_key, mutation_reason)
88
+ return if @compatibility_adapter.nil?
89
+
90
+ outcome = @compatibility_adapter.sync_snapshot(
91
+ snapshot: @registry.snapshot, instance_key: instance_key, mutation_reason: mutation_reason
92
+ )
93
+ return unless outcome == :failed
94
+
95
+ log.warn(
96
+ '[llm][inventory][publisher] action=compatibility_sync result=failed ' \
97
+ "provider_family=#{instance_key.provider_family} instance=#{instance_key.instance_id} reason=#{mutation_reason}"
98
+ )
99
+ rescue StandardError => e
100
+ handle_exception(
101
+ e, handled: true, level: :warn, operation: 'llm.inventory.publisher.compatibility_sync',
102
+ provider_family: instance_key.provider_family, instance_id: instance_key.instance_id,
103
+ mutation_reason: mutation_reason
104
+ )
105
+ end
106
+ end
107
+ end
108
+ end
109
+ end
110
+ end