lex-llm 0.1.7 → 0.1.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: c5b58678c0d7021662b2ef38d80932bd373e3c462b9d05e1004dfc880b1e6d6f
4
- data.tar.gz: 49a88cc742e128df1bd93882585df89e595c9761194da354af6be93bd4bd4c2e
3
+ metadata.gz: d41cf2984b04621d4e0c2a7fa84a7236361a561570b9944358631a76e6699ac9
4
+ data.tar.gz: c84f98866b4f313d240f964d691b6c170d8635f6275ca8c0150b54d6e2d286cf
5
5
  SHA512:
6
- metadata.gz: 273c724d3b7b2945dea092184c8df80952d6ec0c8c38aefbba966a28de91c43c2862be91ac9e918943a7e2e42b5dde4c7b98826852598c7e82c4dd10bbca26e8
7
- data.tar.gz: 68b38d28e88ad07c333ca0f7e94885a3006b1f3fc727f3c2b7206cba5497b42f848927b2d555db5382abac05123b76074572c7ca6834da0de312b2f30fdd3a03
6
+ metadata.gz: a4516de1ebcab041beeabaf718ea11ed3445a943a3c4bbe388936622690001dec8606a8c26d5850f123950ac1d4a09361c4513a8387615e86cc5ef99af133860
7
+ data.tar.gz: 3d10adbbb6684df81ac7090a4a7c0ebd179803069e74b80e13a626b1cd93d67e9ab955bb5259a2ab638373aaf786217b738536478893fe8983366a2f29ee6e99
data/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.1.8 - 2026-04-30
4
+
5
+ - Audit all rescue blocks for handle_exception compliance
6
+ - Add Legion::Logging::Helper to Provider, Chat, and Models for structured exception reporting
7
+ - Replace ad-hoc logger.debug/warn calls in rescue blocks with handle_exception across streaming, chat, models, and provider modules
8
+ - Add require for legion/logging in the main entrypoint
9
+
3
10
  ## 0.1.7 - 2026-04-30
4
11
 
5
12
  - Add thinking extraction from OpenAI-compatible streaming chunks (reasoning_content, reasoning, think tags)
@@ -6,6 +6,7 @@ module Legion
6
6
  # Represents a conversation with an AI model
7
7
  class Chat
8
8
  include Enumerable
9
+ include Legion::Logging::Helper
9
10
 
10
11
  attr_reader :model, :messages, :tools, :tool_prefs, :params, :headers, :schema
11
12
 
@@ -157,8 +158,8 @@ module Legion
157
158
  if @schema && response.content.is_a?(String) && !response.tool_call?
158
159
  begin
159
160
  response.content = Legion::JSON.parse(response.content, symbolize_names: false)
160
- rescue Legion::JSON::ParseError
161
- # If parsing fails, keep content as string
161
+ rescue Legion::JSON::ParseError => e
162
+ handle_exception(e, level: :warn, handled: true, operation: 'llm.chat.complete')
162
163
  end
163
164
  end
164
165
 
@@ -35,6 +35,8 @@ module Legion
35
35
  ].freeze
36
36
 
37
37
  class << self
38
+ include Legion::Logging::Helper
39
+
38
40
  def instance
39
41
  @instance ||= new
40
42
  end
@@ -51,7 +53,8 @@ module Legion
51
53
  data = File.exist?(file) ? File.read(file) : '[]'
52
54
  models = Legion::JSON.parse(data, symbolize_names: true).map { |model| Model::Info.new(model) }
53
55
  filter_models(models)
54
- rescue Legion::JSON::ParseError
56
+ rescue Legion::JSON::ParseError => e
57
+ handle_exception(e, level: :warn, handled: true, operation: 'llm.models.read_from_json')
55
58
  []
56
59
  end
57
60
 
@@ -92,6 +95,8 @@ module Legion
92
95
  result[:models].concat(provider_class.new(config).list_models)
93
96
  result[:fetched_providers] << provider_class.slug
94
97
  rescue StandardError => e
98
+ handle_exception(e, level: :warn, handled: true,
99
+ operation: 'llm.models.fetch_provider_models')
95
100
  result[:failed] << { name: provider_class.name, slug: provider_class.slug, error: e }
96
101
  end
97
102
  end
@@ -170,9 +175,7 @@ module Legion
170
175
  end
171
176
  { models: models.reject { |model| model.provider.nil? || model.id.nil? }, fetched: true }
172
177
  rescue StandardError => e
173
- Legion::Extensions::Llm.logger.warn(
174
- "Failed to fetch models.dev (#{e.class}: #{e.message}). Keeping existing."
175
- )
178
+ handle_exception(e, level: :warn, handled: true, operation: 'llm.models.fetch_models_dev')
176
179
  {
177
180
  models: existing_models.select { |model| model.metadata[:source] == 'models.dev' },
178
181
  fetched: false
@@ -218,7 +218,8 @@ module Legion
218
218
  return arguments if arguments.is_a?(Hash)
219
219
 
220
220
  Legion::JSON.parse(arguments, symbolize_names: false)
221
- rescue Legion::JSON::ParseError
221
+ rescue Legion::JSON::ParseError => e
222
+ handle_exception(e, level: :warn, handled: true, operation: 'llm.provider.parse_tool_arguments')
222
223
  {}
223
224
  end
224
225
 
@@ -6,6 +6,7 @@ module Legion
6
6
  # Base class for LLM providers.
7
7
  class Provider
8
8
  include Streaming
9
+ include Legion::Logging::Helper
9
10
 
10
11
  attr_reader :config, :connection
11
12
 
@@ -131,6 +132,7 @@ module Legion
131
132
  response = @connection.get(metadata[:endpoints][:health])
132
133
  metadata.merge(ready: configured? && health_ready?(response.body), health: response.body)
133
134
  rescue StandardError => e
135
+ handle_exception(e, level: :warn, handled: true, operation: 'llm.provider.readiness')
134
136
  metadata.merge(ready: false, health: { error: e.class.name, message: e.message })
135
137
  end
136
138
 
@@ -91,8 +91,8 @@ module Legion
91
91
  buffer << chunk
92
92
  error_data = Legion::JSON.parse(buffer, symbolize_names: false)
93
93
  handle_parsed_error(error_data, env)
94
- rescue Legion::JSON::ParseError
95
- Legion::Extensions::Llm.logger.debug { "Accumulating error chunk: #{chunk}" }
94
+ rescue Legion::JSON::ParseError => e
95
+ handle_exception(e, level: :warn, handled: true, operation: 'llm.streaming.handle_failed_response')
96
96
  end
97
97
 
98
98
  def handle_sse(chunk, parser, env, &)
@@ -112,7 +112,7 @@ module Legion
112
112
 
113
113
  handle_parsed_error(parsed, env)
114
114
  rescue Legion::JSON::ParseError => e
115
- Legion::Extensions::Llm.logger.debug { "Failed to parse data chunk: #{e.message}" }
115
+ handle_exception(e, level: :warn, handled: true, operation: 'llm.streaming.handle_data')
116
116
  end
117
117
 
118
118
  def handle_error_event(data, env)
@@ -123,7 +123,7 @@ module Legion
123
123
  error_data = Legion::JSON.parse(data, symbolize_names: false)
124
124
  [500, error_data['message'] || 'Unknown streaming error']
125
125
  rescue Legion::JSON::ParseError => e
126
- Legion::Extensions::Llm.logger.debug { "Failed to parse streaming error: #{e.message}" }
126
+ handle_exception(e, level: :warn, handled: true, operation: 'llm.streaming.parse_streaming_error')
127
127
  [500, "Failed to parse error: #{data}"]
128
128
  end
129
129
 
@@ -133,11 +133,11 @@ module Legion
133
133
  ErrorMiddleware.parse_error(provider: self, response: error_response)
134
134
  end
135
135
 
136
- def parse_error_from_json(data, env, error_message)
136
+ def parse_error_from_json(data, env, _error_message)
137
137
  parsed_data = Legion::JSON.parse(data, symbolize_names: false)
138
138
  handle_parsed_error(parsed_data, env)
139
139
  rescue Legion::JSON::ParseError => e
140
- Legion::Extensions::Llm.logger.debug { "#{error_message}: #{e.message}" }
140
+ handle_exception(e, level: :warn, handled: true, operation: 'llm.streaming.parse_error_from_json')
141
141
  end
142
142
 
143
143
  def build_stream_error_response(parsed_data, env, status)
@@ -3,7 +3,7 @@
3
3
  module Legion
4
4
  module Extensions
5
5
  module Llm
6
- VERSION = '0.1.7'
6
+ VERSION = '0.1.8'
7
7
  end
8
8
  end
9
9
  end
@@ -8,6 +8,7 @@ require 'faraday'
8
8
  require 'faraday/multipart'
9
9
  require 'faraday/retry'
10
10
  require 'legion/json'
11
+ require 'legion/logging'
11
12
  require 'logger'
12
13
  require 'marcel'
13
14
  require 'ruby_llm/schema'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lex-llm
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.7
4
+ version: 0.1.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - LegionIO