lex-llm-ledger 0.3.2 → 0.3.3

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: 84be271a1d8b2960d1eeef98a01c950ed2d44cab4e2e6d4c8dd6708980d027d4
4
- data.tar.gz: 6da1a77c998891e3b2e1a5fae24b1109c51715c762b52aa308ebb73abb886188
3
+ metadata.gz: bfcca825db5b0e313cbeafc6c9f396b3f964dd4debd911854c89affe3bcb79ef
4
+ data.tar.gz: 1a4ea16c0c4ca34cc1ae4e3d0efa19cab3948c932162d9072c21127dae1ea375
5
5
  SHA512:
6
- metadata.gz: 51705c939e26737dfda07ac40df418887d15550e758b4db28aea1e377579b8c65108614cd5abd1ef6a309696c4b90149d1d3dacce6507011a219b90edb7d3a1e
7
- data.tar.gz: 163077fbadc935cdeb751645fc59d06a59bf3cd47db7d93d427b721cbdc067f6749c0d6adf6641b1ded3c160c03a252f2382b383d778068b7f59ececcb1b6bb0
6
+ metadata.gz: 362b96b3b385cfcca6c2edbe3fa9c6e30a23fbaa80bd5136fa1f95cc35af8ea5aa93ea89cd7cf1415999ac82ce881311aeea084ee44ba19cffadcbef0858a71b
7
+ data.tar.gz: 89c63b437c02355a9cc39182d42ac0a1971b7dcdf80473d7ef237d92bbb39cef96c13dd0ea3b34f13d6ed1f662cb6bb30aa473658dde119739b641bbf7b92dac
data/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.3.3] - 2026-05-17
4
+
5
+ ### Fixed
6
+ - Extract inline `<think>` / `<thinking>` tags from string responses into `response_thinking_json` at write time instead of leaving them in `response_json`.
7
+ - Fall back to `ThinkingExtractor` when `response_thinking` is absent from the audit payload (covers Ollama, vLLM, and OpenAI-compatible gateways that pass thinking inline).
8
+ - Guard `finish_reason` and `thinking_response` against `String#dig` TypeError when `body[:response]` is a plain string.
9
+
3
10
  ## [0.3.2] - 2026-05-13
4
11
 
5
12
  ### Fixed
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'legion/extensions/llm/responses/thinking_extractor'
3
4
  require_relative '../helpers/caller_identity'
4
5
  require_relative '../helpers/json'
5
6
 
@@ -96,7 +97,30 @@ module Legion
96
97
  end
97
98
 
98
99
  def response_thinking(body)
99
- body[:response_thinking] || body[:thinking] || body.dig(:response, :thinking) || {}
100
+ thinking = body[:response_thinking] || body[:thinking]
101
+ thinking ||= body.dig(:response, :thinking) if body[:response].is_a?(Hash)
102
+ if thinking
103
+ thinking.is_a?(Hash) ? thinking : { content: thinking }
104
+ else
105
+ extract_thinking_from_content(body)
106
+ end
107
+ end
108
+
109
+ def extract_thinking_from_content(body)
110
+ content_str = body[:response_content] || body[:response] || body[:content]
111
+ return {} unless content_str.is_a?(String)
112
+
113
+ _clean, extracted = extract_inline_thinking(content_str)
114
+ extracted ? { content: extracted } : {}
115
+ end
116
+
117
+ def extract_inline_thinking(text)
118
+ if defined?(::Legion::Extensions::Llm::Responses::ThinkingExtractor)
119
+ extraction = ::Legion::Extensions::Llm::Responses::ThinkingExtractor.extract(text)
120
+ [extraction.content, extraction.thinking]
121
+ else
122
+ [text, nil]
123
+ end
100
124
  end
101
125
 
102
126
  def official_prompt_payload(body, ctx, props, headers, expires_at)
@@ -4,7 +4,7 @@ module Legion
4
4
  module Extensions
5
5
  module Llm
6
6
  module Ledger
7
- VERSION = '0.3.2'
7
+ VERSION = '0.3.3'
8
8
  end
9
9
  end
10
10
  end
@@ -3,6 +3,7 @@
3
3
  require 'digest'
4
4
  require 'securerandom'
5
5
  require 'legion/logging'
6
+ require 'legion/extensions/llm/responses/thinking_extractor'
6
7
  require_relative '../helpers/json'
7
8
  require_relative '../helpers/persistence_logging'
8
9
 
@@ -580,18 +581,38 @@ module Legion
580
581
 
581
582
  def visible_response(body)
582
583
  response = body[:response] || body[:response_content] || body[:content] || {}
583
- return { content: response } if response.is_a?(String)
584
+ if response.is_a?(String)
585
+ clean, _thinking = extract_inline_thinking(response)
586
+ return { content: clean }
587
+ end
584
588
  return { content: response[:content] } if response.is_a?(Hash) && response.key?(:content)
585
589
 
586
590
  response.is_a?(Hash) ? response.except(:thinking) : { content: response.to_s }
587
591
  end
588
592
 
589
593
  def thinking_response(body)
590
- thinking = body[:response_thinking] || body[:thinking] || body.dig(:response, :thinking)
591
- return {} if thinking.nil?
592
- return { content: thinking } if thinking.is_a?(String)
594
+ thinking = body[:response_thinking] || body[:thinking]
595
+ thinking ||= body.dig(:response, :thinking) if body[:response].is_a?(Hash)
596
+ if thinking
597
+ return { content: thinking } if thinking.is_a?(String)
598
+
599
+ return thinking
600
+ end
593
601
 
594
- thinking
602
+ content_str = body[:response_content] || body[:response] || body[:content]
603
+ return {} unless content_str.is_a?(String)
604
+
605
+ _clean, extracted = extract_inline_thinking(content_str)
606
+ extracted ? { content: extracted } : {}
607
+ end
608
+
609
+ def extract_inline_thinking(text)
610
+ if defined?(::Legion::Extensions::Llm::Responses::ThinkingExtractor)
611
+ extraction = ::Legion::Extensions::Llm::Responses::ThinkingExtractor.extract(text)
612
+ [extraction.content, extraction.thinking]
613
+ else
614
+ [text, nil]
615
+ end
595
616
  end
596
617
 
597
618
  def response_content(body)
@@ -599,7 +620,10 @@ module Legion
599
620
  end
600
621
 
601
622
  def finish_reason(body)
602
- body[:finish_reason] || body.dig(:response, :finish_reason) || body.dig(:response, :stop, :reason)
623
+ return body[:finish_reason] if body[:finish_reason]
624
+ return nil unless body[:response].is_a?(Hash)
625
+
626
+ body.dig(:response, :finish_reason) || body.dig(:response, :stop, :reason)
603
627
  end
604
628
 
605
629
  def classification_level(body)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lex-llm-ledger
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.2
4
+ version: 0.3.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Esity