lex-llm-ollama 0.2.7 → 0.2.8

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: bd3556fdfe59e46af218aa97edcc1f81b3ffb39c8af1c144f4b3f0e23bf17bea
4
- data.tar.gz: cff453247d66070976c3cb74e1f5524e718fbded408d340dc7cb74892750b39c
3
+ metadata.gz: 20e5e1a5989633a805483200893d6d11c6f0af9b3d9b3204defad0e33e0be5ed
4
+ data.tar.gz: 8dd17ebb04df4e90b75438f8f4ba86bb289db4ccde25f1b71d36253a9075450c
5
5
  SHA512:
6
- metadata.gz: a3cac452d99bfb4e0c34285b38979a59e0937a98b3dac849fa401fde6022d9e04887062b062185199294c6d4dafe1ea5f65c9fdbb9be4b5e3cfb0fcbfd9a1159
7
- data.tar.gz: ecbd0541f0ca31ee2979f1424034fd719533d0f86b6631be510ff696b775ee23b4a314bf86596e3062c223a90d3b65d4bc5a1b30c5f69833cf7596cea00295fe
6
+ metadata.gz: '0944f1f288b824bcc09b9ca13e9ece5d67553fe4d706e26a7d77b37c1fa71c594eaeb8b0f2f8fd9817259463e9289257019b700a4a02019077f1c889e0b7aa8a'
7
+ data.tar.gz: 32c4de66b95c05e9b0349a2c1da79f826fd701fd9aa61d25957291076c3e6ca87fa79338fd323e652c1e441342bb54f6a1dc97b03bd5ffafe56c3eb32411eeb1
data/CHANGELOG.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.2.8 - 2026-05-12
4
+
5
+ - Include `Legion::Logging::Helper` directly in Ollama provider, actor, and fleet runner runtime surfaces.
6
+ - Add sanitized debug logging for provider discovery, payload rendering, tool formatting, embeddings, offerings, and fleet handoff.
7
+
3
8
  ## 0.2.7 - 2026-05-07
4
9
 
5
10
  - Render Ollama embedding payloads with the canonical model id when callers pass `Model::Info` objects.
@@ -12,6 +12,7 @@ end
12
12
 
13
13
  require 'legion/extensions/llm/ollama'
14
14
  require 'legion/extensions/llm/fleet/provider_responder'
15
+ require 'legion/logging/helper'
15
16
 
16
17
  module Legion
17
18
  module Extensions
@@ -20,6 +21,8 @@ module Legion
20
21
  module Actor
21
22
  # Subscription actor for Ollama fleet request consumption.
22
23
  class FleetWorker < Legion::Extensions::Actors::Subscription
24
+ include Legion::Logging::Helper
25
+
23
26
  def runner_class
24
27
  'Legion::Extensions::Llm::Ollama::Runners::FleetWorker'
25
28
  end
@@ -33,7 +36,9 @@ module Legion
33
36
  end
34
37
 
35
38
  def enabled?
36
- Legion::Extensions::Llm::Fleet::ProviderResponder.enabled_for?(Ollama.discover_instances)
39
+ enabled = Legion::Extensions::Llm::Fleet::ProviderResponder.enabled_for?(Ollama.discover_instances)
40
+ log.debug { "ollama fleet worker actor enabled=#{enabled}" }
41
+ enabled
37
42
  end
38
43
  end
39
44
  end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'legion/extensions/llm'
4
+ require 'legion/logging/helper'
4
5
 
5
6
  module Legion
6
7
  module Extensions
@@ -8,6 +9,8 @@ module Legion
8
9
  module Ollama
9
10
  # Ollama provider implementation for the Legion::Extensions::Llm base provider contract.
10
11
  class Provider < Legion::Extensions::Llm::Provider # rubocop:disable Metrics/ClassLength
12
+ include Legion::Logging::Helper
13
+
11
14
  class << self
12
15
  attr_writer :registry_publisher
13
16
 
@@ -54,7 +57,7 @@ module Legion
54
57
  def version_url = '/api/version'
55
58
 
56
59
  def list_running_models
57
- log.info { "listing running models from #{api_base}#{running_models_url}" }
60
+ log.debug { "ollama provider listing running models endpoint=#{api_base}#{running_models_url}" }
58
61
  connection.get(running_models_url).body.fetch('models', [])
59
62
  rescue StandardError => e
60
63
  handle_exception(e, level: :error, handled: true, operation: 'ollama.list_running_models')
@@ -62,22 +65,22 @@ module Legion
62
65
  end
63
66
 
64
67
  def readiness(live: false)
65
- log.info { "checking readiness live=#{live} at #{api_base}" }
68
+ log.debug { "ollama provider checking readiness live=#{live} endpoint=#{api_base}" }
66
69
  super.tap do |metadata|
67
70
  self.class.registry_publisher.publish_readiness_async(metadata) if live
68
71
  end
69
72
  end
70
73
 
71
74
  def list_models
72
- log.info { "discovering models from #{api_base}#{models_url}" }
75
+ log.debug { "ollama provider discovering models endpoint=#{api_base}#{models_url}" }
73
76
  super.tap do |models|
74
- log.info { "discovered #{models.size} model(s) from Ollama" }
77
+ log.debug { "ollama provider discovered model_count=#{models.size}" }
75
78
  self.class.registry_publisher.publish_models_async(models, readiness: readiness(live: false))
76
79
  end
77
80
  end
78
81
 
79
82
  def show_model(model)
80
- log.info { "fetching model details for #{model}" }
83
+ log.debug { "ollama provider fetching model details model=#{model}" }
81
84
  connection.post(show_model_url, { model: model }).body
82
85
  rescue StandardError => e
83
86
  handle_exception(e, level: :error, handled: true, operation: 'ollama.show_model')
@@ -85,6 +88,7 @@ module Legion
85
88
  end
86
89
 
87
90
  def pull_model(model, stream: false)
91
+ log.debug { "ollama provider pulling model=#{model} stream=#{stream}" }
88
92
  log.info { "pulling model #{model} stream=#{stream}" }
89
93
  connection.post(pull_url, { model: model, stream: stream }).body
90
94
  rescue StandardError => e
@@ -93,12 +97,17 @@ module Legion
93
97
  end
94
98
 
95
99
  def discover_offerings(live: false, **)
100
+ log.debug do
101
+ "ollama provider discovering offerings live=#{live} cached_model_count=#{Array(@cached_models).size}"
102
+ end
96
103
  models = if live
97
104
  @cached_models = list_models
98
105
  else
99
106
  Array(@cached_models)
100
107
  end
101
- models.map { |model_info| offering_from_model(model_info) }
108
+ models.map { |model_info| offering_from_model(model_info) }.tap do |offerings|
109
+ log.debug { "ollama provider built offering_count=#{offerings.size} live=#{live}" }
110
+ end
102
111
  rescue StandardError => e
103
112
  handle_exception(e, level: :warn, handled: true, operation: 'ollama.discover_offerings')
104
113
  []
@@ -153,8 +162,14 @@ module Legion
153
162
  end
154
163
 
155
164
  def render_payload(messages, tools:, temperature:, model:, stream:, schema:, thinking:, tool_prefs:) # rubocop:disable Metrics/ParameterLists
165
+ model_id = model.respond_to?(:id) ? model.id : model
166
+ log.debug do
167
+ "ollama provider rendering chat payload model=#{model_id} message_count=#{messages.size} " \
168
+ "stream=#{stream} tools=#{tools.size} schema=#{!schema.nil?} thinking=#{thinking ? true : false}"
169
+ end
170
+
156
171
  {
157
- model: model.id,
172
+ model: model_id,
158
173
  messages: format_messages(messages),
159
174
  stream: stream,
160
175
  think: thinking ? true : nil,
@@ -196,6 +211,9 @@ module Legion
196
211
  def format_tools(tools)
197
212
  return nil if tools.empty?
198
213
 
214
+ tool_names = tools.values.filter_map { |tool| tool.respond_to?(:name) ? tool.name : nil }
215
+ log.debug { "ollama provider formatting tools count=#{tools.size} names=#{tool_names.join(',')}" }
216
+
199
217
  tools.values.map do |tool|
200
218
  {
201
219
  type: 'function',
@@ -243,6 +261,8 @@ module Legion
243
261
  def parse_tool_calls(tool_calls)
244
262
  return nil unless tool_calls
245
263
 
264
+ log.debug { "ollama provider parsing tool_call_count=#{tool_calls.size}" }
265
+
246
266
  tool_calls.to_h do |call|
247
267
  function = call.fetch('function', {})
248
268
  [
@@ -289,7 +309,11 @@ module Legion
289
309
  end
290
310
 
291
311
  def render_embedding_payload(text, model:, dimensions:)
292
- { model: model.respond_to?(:id) ? model.id : model, input: text, dimensions: dimensions }.compact
312
+ model_id = model.respond_to?(:id) ? model.id : model
313
+ input_count = text.respond_to?(:size) ? text.size : 1
314
+ log.debug { "ollama provider rendering embedding payload model=#{model_id} input_count=#{input_count}" }
315
+
316
+ { model: model_id, input: text, dimensions: dimensions }.compact
293
317
  end
294
318
 
295
319
  def parse_embedding_response(response, model:, text:)
@@ -302,6 +326,9 @@ module Legion
302
326
  body['embeddings']&.first
303
327
  end
304
328
 
329
+ vector_count = vectors.respond_to?(:size) ? vectors.size : 0
330
+ log.debug { "ollama provider parsed embedding response model=#{model} vector_count=#{vector_count}" }
331
+
305
332
  Legion::Extensions::Llm::Embedding.new(vectors: vectors, model: model,
306
333
  input_tokens: body['prompt_eval_count'].to_i)
307
334
  end
@@ -2,6 +2,7 @@
2
2
 
3
3
  require 'legion/extensions/llm/fleet/provider_responder'
4
4
  require 'legion/extensions/llm/ollama'
5
+ require 'legion/logging/helper'
5
6
 
6
7
  module Legion
7
8
  module Extensions
@@ -10,9 +11,17 @@ module Legion
10
11
  module Runners
11
12
  # Runner entrypoint for Ollama fleet request execution.
12
13
  module FleetWorker
14
+ extend Legion::Logging::Helper
15
+
13
16
  module_function
14
17
 
15
18
  def handle_fleet_request(payload, delivery: nil, properties: nil)
19
+ payload_keys = payload.respond_to?(:keys) ? payload.keys.join(',') : payload.class
20
+ log.debug do
21
+ "ollama fleet worker handing off request payload_keys=#{payload_keys} " \
22
+ "delivery=#{!delivery.nil?} properties=#{!properties.nil?}"
23
+ end
24
+
16
25
  Legion::Extensions::Llm::Fleet::ProviderResponder.call(
17
26
  payload: payload,
18
27
  provider_family: Ollama::PROVIDER_FAMILY,
@@ -4,7 +4,7 @@ module Legion
4
4
  module Extensions
5
5
  module Llm
6
6
  module Ollama
7
- VERSION = '0.2.7'
7
+ VERSION = '0.2.8'
8
8
  end
9
9
  end
10
10
  end
@@ -3,6 +3,7 @@
3
3
  require 'legion/extensions/llm'
4
4
  require 'legion/extensions/llm/ollama/provider'
5
5
  require 'legion/extensions/llm/ollama/version'
6
+ require 'legion/logging/helper'
6
7
 
7
8
  module Legion
8
9
  module Extensions
@@ -49,24 +50,10 @@ module Legion
49
50
  def self.discover_instances
50
51
  instances = {}
51
52
 
52
- if CredentialSources.socket_open?('127.0.0.1', 11_434, timeout: 0.1)
53
- instances[:local] = {
54
- base_url: 'http://127.0.0.1:11434',
55
- tier: :local,
56
- capabilities: %i[completion embedding vision]
57
- }
58
- end
59
-
60
- configured = CredentialSources.setting(:extensions, :llm, :ollama, :instances)
61
- if configured.is_a?(Hash)
62
- configured.each do |name, config|
63
- instances[name.to_sym] = normalize_instance_config(config).merge(
64
- tier: :direct,
65
- capabilities: %i[completion embedding vision]
66
- )
67
- end
68
- end
53
+ discover_local_instance(instances)
54
+ discover_configured_instances(instances)
69
55
 
56
+ log.debug { "ollama discovery returning instance_count=#{instances.size}" }
70
57
  instances
71
58
  end
72
59
 
@@ -77,6 +64,33 @@ module Legion
77
64
  normalized[:base_url] ||= normalized.delete(:endpoint)
78
65
  normalized.compact
79
66
  end
67
+
68
+ def self.discover_local_instance(instances)
69
+ log.debug { 'ollama discovery probing local socket host=127.0.0.1 port=11434' }
70
+ return unless CredentialSources.socket_open?('127.0.0.1', 11_434, timeout: 0.1)
71
+
72
+ log.debug { 'ollama discovery found local socket instance' }
73
+ instances[:local] = {
74
+ base_url: 'http://127.0.0.1:11434',
75
+ tier: :local,
76
+ capabilities: %i[completion embedding vision]
77
+ }
78
+ end
79
+
80
+ def self.discover_configured_instances(instances)
81
+ configured = CredentialSources.setting(:extensions, :llm, :ollama, :instances)
82
+ return unless configured.is_a?(Hash)
83
+
84
+ log.debug { "ollama discovery loading configured instance_count=#{configured.size}" }
85
+ configured.each do |name, config|
86
+ instances[name.to_sym] = normalize_instance_config(config).merge(
87
+ tier: :direct,
88
+ capabilities: %i[completion embedding vision]
89
+ )
90
+ end
91
+ end
92
+
93
+ private_class_method :discover_local_instance, :discover_configured_instances
80
94
  end
81
95
  end
82
96
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lex-llm-ollama
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.7
4
+ version: 0.2.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - LegionIO