lex-llm-mlx 0.1.6 → 0.1.7
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: b4c018fd3b44a629665783ce38fd5c0f5429ab41452b2e8829079a08c2807860
|
|
4
|
+
data.tar.gz: d75bf991619c7d3bf8bc4d7b0aaf77cdb11e6a352595e210ef36f2b6e094cecb
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: cee424e550ad1ee7cf3a19f791f3bf72434b170efbb50e3e952d5eb502943f442b14ba29344b26575657a390785ad4749ad8d95f7c34454f9d7852160584ff4a
|
|
7
|
+
data.tar.gz: 287b5609ee6788ce4865d1b4f1fb49e344198fe5ca1b828f806742810d82d29e1a18fa28c2404b9a8b0144878ea3d52154fb3e702286f02f2a836239f0d7f316
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.1.7 - 2026-04-30
|
|
4
|
+
|
|
5
|
+
- Add `Legion::Logging::Helper` to `Mlx` module and `RegistryPublisher` for standardized logging.
|
|
6
|
+
- Replace all bare rescue blocks with `handle_exception` calls for full observability.
|
|
7
|
+
- Add info-level action logging for health checks, readiness, model discovery, and registry publishing.
|
|
8
|
+
- Remove custom `log_publish_failure` method in favor of `handle_exception`.
|
|
9
|
+
- Update README to document registry event publishing, transport layer, and architecture.
|
|
10
|
+
|
|
3
11
|
## 0.1.6 - 2026-04-28
|
|
4
12
|
|
|
5
13
|
- Publish best-effort `llm.registry` live readiness and discovered-model availability events using `lex-llm` registry envelopes when transport is already available.
|
data/README.md
CHANGED
|
@@ -12,7 +12,21 @@ Load it with `require 'legion/extensions/llm/mlx'`.
|
|
|
12
12
|
- OpenAI-compatible chat, streaming, model listing, and embeddings endpoint wrappers.
|
|
13
13
|
- Heuristic chat, embedding, and vision capability mapping for discovered local models.
|
|
14
14
|
- Local-first defaults for MLX servers running on MacBook, Mac Studio, or local Apple Silicon hosts.
|
|
15
|
-
-
|
|
15
|
+
- Best-effort `llm.registry` event publishing for readiness and model availability when transport is available.
|
|
16
|
+
- Shared Legion settings, JSON, and logging dependencies with full `Legion::Logging::Helper` integration.
|
|
17
|
+
|
|
18
|
+
## Architecture
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
Legion::Extensions::Llm::Mlx
|
|
22
|
+
Mlx (module) # Extension namespace, provider registration, default settings
|
|
23
|
+
Provider # MLX provider — health, readiness, model listing, OpenAI-compatible adapter
|
|
24
|
+
RegistryPublisher # Async publisher for llm.registry readiness/model availability events
|
|
25
|
+
RegistryEventBuilder # Builds sanitized lex-llm registry envelopes for MLX provider state
|
|
26
|
+
Transport::
|
|
27
|
+
Messages::RegistryEvent # AMQP message for llm.registry exchange
|
|
28
|
+
Exchanges::LlmRegistry # Topic exchange definition for llm.registry
|
|
29
|
+
```
|
|
16
30
|
|
|
17
31
|
## Default Settings
|
|
18
32
|
|
|
@@ -41,3 +55,30 @@ end
|
|
|
41
55
|
- `health_url`: `/health`
|
|
42
56
|
|
|
43
57
|
The provider uses the shared `Legion::Extensions::Llm::Provider::OpenAICompatible` adapter so Legion routing can treat MLX, vLLM, OpenAI, and other compatible servers consistently while preserving provider-specific settings and health behavior.
|
|
58
|
+
|
|
59
|
+
## Registry Event Publishing
|
|
60
|
+
|
|
61
|
+
When `Legion::Transport` and `lex-llm` routing are available, the provider publishes best-effort events to the `llm.registry` topic exchange:
|
|
62
|
+
|
|
63
|
+
- **Readiness events** — published asynchronously when `readiness(live: true)` is called.
|
|
64
|
+
- **Model availability events** — published asynchronously after `list_models` discovers models.
|
|
65
|
+
|
|
66
|
+
Publishing is fire-and-forget in background threads; failures never block the provider.
|
|
67
|
+
|
|
68
|
+
## Dependencies
|
|
69
|
+
|
|
70
|
+
| Gem | Required | Purpose |
|
|
71
|
+
|-----|----------|---------|
|
|
72
|
+
| `legion-json` (>= 1.2.1) | Yes | JSON serialization |
|
|
73
|
+
| `legion-logging` (>= 1.3.2) | Yes | Structured logging via Helper |
|
|
74
|
+
| `legion-settings` (>= 1.3.14) | Yes | Configuration |
|
|
75
|
+
| `lex-llm` (>= 0.1.5) | Yes | Shared provider base, routing, fleet |
|
|
76
|
+
|
|
77
|
+
## Development
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
bundle install
|
|
81
|
+
bundle exec rspec # 0 failures
|
|
82
|
+
bundle exec rubocop -A # auto-fix
|
|
83
|
+
bundle exec rubocop # lint check
|
|
84
|
+
```
|
|
@@ -62,17 +62,21 @@ module Legion
|
|
|
62
62
|
def health_url = '/health'
|
|
63
63
|
|
|
64
64
|
def health
|
|
65
|
+
log.info("Checking MLX health at #{api_base}#{health_url}")
|
|
65
66
|
connection.get(health_url).body
|
|
66
67
|
end
|
|
67
68
|
|
|
68
69
|
def readiness(live: false)
|
|
70
|
+
log.info("Checking MLX readiness (live=#{live})")
|
|
69
71
|
super.tap do |metadata|
|
|
70
72
|
self.class.registry_publisher.publish_readiness_async(metadata) if live
|
|
71
73
|
end
|
|
72
74
|
end
|
|
73
75
|
|
|
74
76
|
def list_models
|
|
77
|
+
log.info('Listing available MLX models')
|
|
75
78
|
super.tap do |models|
|
|
79
|
+
log.info("Discovered #{Array(models).size} MLX models")
|
|
76
80
|
self.class.registry_publisher.publish_models_async(models, readiness: readiness(live: false))
|
|
77
81
|
end
|
|
78
82
|
end
|
|
@@ -6,6 +6,8 @@ module Legion
|
|
|
6
6
|
module Mlx
|
|
7
7
|
# Best-effort publisher for MLX provider availability events.
|
|
8
8
|
class RegistryPublisher
|
|
9
|
+
include Legion::Logging::Helper if defined?(Legion::Logging::Helper)
|
|
10
|
+
|
|
9
11
|
APP_ID = 'lex-llm-mlx'
|
|
10
12
|
|
|
11
13
|
def initialize(builder: RegistryEventBuilder.new)
|
|
@@ -13,10 +15,12 @@ module Legion
|
|
|
13
15
|
end
|
|
14
16
|
|
|
15
17
|
def publish_readiness_async(readiness)
|
|
18
|
+
log.info('Publishing MLX readiness event asynchronously')
|
|
16
19
|
schedule { publish_event(@builder.readiness(readiness)) }
|
|
17
20
|
end
|
|
18
21
|
|
|
19
22
|
def publish_models_async(models, readiness:)
|
|
23
|
+
log.info("Publishing #{Array(models).size} MLX model availability events asynchronously")
|
|
20
24
|
schedule do
|
|
21
25
|
Array(models).each do |model|
|
|
22
26
|
publish_event(@builder.model_available(model, readiness:))
|
|
@@ -33,19 +37,20 @@ module Legion
|
|
|
33
37
|
Thread.current.abort_on_exception = false
|
|
34
38
|
yield
|
|
35
39
|
rescue StandardError => e
|
|
36
|
-
|
|
40
|
+
handle_exception(e, level: :debug, handled: true, operation: 'mlx.registry_publisher.schedule_thread')
|
|
37
41
|
end
|
|
38
42
|
rescue StandardError => e
|
|
39
|
-
|
|
43
|
+
handle_exception(e, level: :debug, handled: true, operation: 'mlx.registry_publisher.schedule')
|
|
40
44
|
false
|
|
41
45
|
end
|
|
42
46
|
|
|
43
47
|
def publish_event(event)
|
|
44
48
|
return false unless publishing_available?
|
|
45
49
|
|
|
50
|
+
log.info("Publishing MLX registry event: #{event.class}")
|
|
46
51
|
message_class.new(event:, app_id: APP_ID).publish(spool: false)
|
|
47
52
|
rescue StandardError => e
|
|
48
|
-
|
|
53
|
+
handle_exception(e, level: :warn, handled: true, operation: 'mlx.registry_publisher.publish_event')
|
|
49
54
|
false
|
|
50
55
|
end
|
|
51
56
|
|
|
@@ -56,7 +61,9 @@ module Legion
|
|
|
56
61
|
return true unless ::Legion::Transport::Connection.respond_to?(:session_open?)
|
|
57
62
|
|
|
58
63
|
::Legion::Transport::Connection.session_open?
|
|
59
|
-
rescue StandardError
|
|
64
|
+
rescue StandardError => e
|
|
65
|
+
handle_exception(e, level: :debug, handled: true,
|
|
66
|
+
operation: 'mlx.registry_publisher.publishing_available?')
|
|
60
67
|
false
|
|
61
68
|
end
|
|
62
69
|
|
|
@@ -70,7 +77,9 @@ module Legion
|
|
|
70
77
|
|
|
71
78
|
require 'legion/extensions/llm/mlx/transport/messages/registry_event'
|
|
72
79
|
message_class_defined?
|
|
73
|
-
rescue LoadError
|
|
80
|
+
rescue LoadError => e
|
|
81
|
+
handle_exception(e, level: :debug, handled: true,
|
|
82
|
+
operation: 'mlx.registry_publisher.transport_message_available?')
|
|
74
83
|
false
|
|
75
84
|
end
|
|
76
85
|
|
|
@@ -81,18 +90,6 @@ module Legion
|
|
|
81
90
|
def message_class
|
|
82
91
|
::Legion::Extensions::Llm::Mlx::Transport::Messages::RegistryEvent
|
|
83
92
|
end
|
|
84
|
-
|
|
85
|
-
def log_publish_failure(error, level: :warn)
|
|
86
|
-
message = "[lex-llm-mlx] llm.registry publish failed: #{error.class}: #{error.message}"
|
|
87
|
-
logger = ::Legion::Extensions::Llm.logger if defined?(::Legion::Extensions::Llm)
|
|
88
|
-
if logger.respond_to?(level)
|
|
89
|
-
logger.public_send(level, message)
|
|
90
|
-
elsif logger.respond_to?(:debug)
|
|
91
|
-
logger.debug(message)
|
|
92
|
-
end
|
|
93
|
-
rescue StandardError
|
|
94
|
-
nil
|
|
95
|
-
end
|
|
96
93
|
end
|
|
97
94
|
end
|
|
98
95
|
end
|
|
@@ -11,6 +11,7 @@ module Legion
|
|
|
11
11
|
module Llm
|
|
12
12
|
# Mlx provider extension namespace.
|
|
13
13
|
module Mlx
|
|
14
|
+
extend Legion::Logging::Helper if defined?(Legion::Logging::Helper)
|
|
14
15
|
extend ::Legion::Extensions::Core if ::Legion::Extensions.const_defined?(:Core, false)
|
|
15
16
|
|
|
16
17
|
PROVIDER_FAMILY = :mlx
|
|
@@ -38,3 +39,6 @@ end
|
|
|
38
39
|
|
|
39
40
|
Legion::Extensions::Llm::Provider.register(Legion::Extensions::Llm::Mlx::PROVIDER_FAMILY,
|
|
40
41
|
Legion::Extensions::Llm::Mlx::Provider)
|
|
42
|
+
if Legion::Extensions::Llm::Mlx.respond_to?(:log)
|
|
43
|
+
Legion::Extensions::Llm::Mlx.log.info('Registered MLX provider as :mlx')
|
|
44
|
+
end
|