lex-agentic-memory 0.1.33 → 0.1.34

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: 01630a8c5fd981fb85c69337d299f71dc215b79b9ce3dca7a9b0aef57545fde3
4
- data.tar.gz: 6eb6bd8f8e924aacb9a805561f9f39c0ac18b5d1f559faa7f58a1af3a6d3ad8a
3
+ metadata.gz: 606b711547732f1f697b57ce2392509c2774397c725b51f87baeaee591cf2ae2
4
+ data.tar.gz: f9f704beca9f4f33c8d71ad54627ef400561819898aeebf06c0097a0c0a535b1
5
5
  SHA512:
6
- metadata.gz: 69c12558b2cb6d7a883a9f0bd345ad0934273847b1a44f2dcaed02682a347d9a88dfddbbf6b2ab48d91a418c83f137eb585723dc3aecf19c0a2fb2e1454e7bd3
7
- data.tar.gz: 8200e4e37b770d4afa344153cd6dc95b9bd047dd55d34079b1bfc6c87c7f261e0049ee2c6f77e4f2b04bf7455745f88eb06160ad006eb81dda7ee0d2053093f9
6
+ metadata.gz: 35f855a01efbfb5b29f23fe12f92e89082a3a4c8001b149dd16f6ccd648bc9d67a699755230e5b08c4a86f1147522f86b71d5fea3e31f3842448c20e4af3d094
7
+ data.tar.gz: 8e9afdf79c62437fefe856a61a0432d1574a7fba7dadab51c4a6b19a0e8a6d6a3658a19fbfa725d5cdb5c4c8de300169818aeee15c1e204e9cf7ff15a9cf12d3
data/CHANGELOG.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.1.34] - 2026-05-08
4
+ ### Fixed
5
+ - Deferred GAIA heartbeat maintenance no longer initializes the shared trace store just to return a deferred summary, avoiding idle local trace table scans.
6
+ - `Store#parse_db_content` now returns bracket-prefixed raw trace/log text without JSON parse attempts or malformed JSON debug noise while still parsing real JSON objects and arrays.
7
+
3
8
  ## [0.1.33] - 2026-05-07
4
9
  ### Fixed
5
10
  - `PostgresStore#parse_json_or_raw` no longer attempts JSON parse on plain-text content — checks for `{`/`[` prefix before parsing, eliminating ERROR log spam during bulk reads with mixed content types
@@ -18,12 +18,14 @@ module Legion
18
18
  attr_reader :store
19
19
 
20
20
  def initialize(store: nil, **)
21
- @default_store = store || Legion::Extensions::Agentic::Memory::Trace.shared_store
21
+ @default_store = store if store
22
22
  end
23
23
 
24
24
  private
25
25
 
26
- attr_reader :default_store
26
+ def default_store
27
+ @default_store ||= Legion::Extensions::Agentic::Memory::Trace.shared_store
28
+ end
27
29
  end
28
30
  end
29
31
  end
@@ -348,15 +348,22 @@ module Legion
348
348
  return raw unless raw.is_a?(String)
349
349
 
350
350
  stripped = raw.strip
351
- return raw unless stripped.start_with?('{', '[')
351
+ return raw unless parseable_content_json?(stripped)
352
352
 
353
353
  parsed = Legion::JSON.load(stripped)
354
354
  parsed.is_a?(Hash) || parsed.is_a?(Array) ? parsed : raw
355
- rescue StandardError => e
356
- log.debug "[trace_persistence] malformed JSON in content column, returning raw: #{e.message}"
355
+ rescue StandardError => _e
357
356
  raw
358
357
  end
359
358
 
359
+ def parseable_content_json?(value)
360
+ return true if value.start_with?('{')
361
+ return false unless value.start_with?('[')
362
+
363
+ first_array_value = value[1..]&.lstrip&.[](0)
364
+ %w[{ [ " ]].include?(first_array_value)
365
+ end
366
+
360
367
  def parse_db_json(raw, field, symbolize: false, &default)
361
368
  return default&.call if raw.nil? || raw.to_s.strip.empty?
362
369
 
@@ -31,12 +31,12 @@ module Legion
31
31
  end
32
32
 
33
33
  def decay_cycle(store: nil, tick_count: 1, maintenance: true, **)
34
- store ||= default_store
35
34
  unless maintenance
36
- deferred = deferred_decay_summary(store)
35
+ deferred = deferred_decay_summary(store || cached_default_store)
37
36
  return { **deferred }
38
37
  end
39
38
 
39
+ store ||= default_store
40
40
  decayed = 0
41
41
  pruned = 0
42
42
  total = trace_count(store)
@@ -139,7 +139,7 @@ module Legion
139
139
 
140
140
  def deferred_decay_summary(store)
141
141
  summary = Legion::Extensions::Agentic::Memory::Trace.last_maintenance_summary || {}
142
- current_count = trace_count(store)
142
+ current_count = store ? trace_count(store) : 0
143
143
 
144
144
  {
145
145
  decayed: summary[:decayed] || 0,
@@ -173,6 +173,10 @@ module Legion
173
173
  @default_store ||= Legion::Extensions::Agentic::Memory::Trace.shared_store
174
174
  end
175
175
 
176
+ def cached_default_store
177
+ @default_store if instance_variable_defined?(:@default_store)
178
+ end
179
+
176
180
  include Legion::Extensions::Helpers::Lex if defined?(Legion::Extensions::Helpers::Lex)
177
181
  end
178
182
  end
@@ -4,7 +4,7 @@ module Legion
4
4
  module Extensions
5
5
  module Agentic
6
6
  module Memory
7
- VERSION = '0.1.33'
7
+ VERSION = '0.1.34'
8
8
  end
9
9
  end
10
10
  end
@@ -24,6 +24,14 @@ RSpec.describe Legion::Extensions::Agentic::Memory::Trace::Client do
24
24
  expect(client).to respond_to(:erase_by_agent)
25
25
  end
26
26
 
27
+ it 'does not initialize the shared trace store until a store-backed operation needs it' do
28
+ allow(Legion::Extensions::Agentic::Memory::Trace).to receive(:shared_store)
29
+
30
+ described_class.new
31
+
32
+ expect(Legion::Extensions::Agentic::Memory::Trace).not_to have_received(:shared_store)
33
+ end
34
+
27
35
  it 'uses provided store' do
28
36
  store = Legion::Extensions::Agentic::Memory::Trace::Helpers::Store.new
29
37
  client = described_class.new(store: store)
@@ -128,6 +128,30 @@ RSpec.describe Legion::Extensions::Agentic::Memory::Trace::Helpers::Store do
128
128
  end
129
129
  end
130
130
 
131
+ describe '#parse_db_content' do
132
+ let(:parser) { described_class.allocate }
133
+
134
+ it 'returns bracket-prefixed raw log text without logging malformed JSON noise' do
135
+ expect(parser).not_to receive(:log)
136
+
137
+ result = parser.send(:parse_db_content, '[tool][file_read] opened file')
138
+
139
+ expect(result).to eq('[tool][file_read] opened file')
140
+ end
141
+
142
+ it 'still parses JSON object content' do
143
+ result = parser.send(:parse_db_content, '{"event":"meeting"}')
144
+
145
+ expect(result).to eq({ event: 'meeting' })
146
+ end
147
+
148
+ it 'still parses JSON array content when it looks like serialized payload data' do
149
+ result = parser.send(:parse_db_content, '[{"event":"meeting"}]')
150
+
151
+ expect(result).to eq([{ event: 'meeting' }])
152
+ end
153
+ end
154
+
131
155
  describe '#count' do
132
156
  it 'returns number of stored traces' do
133
157
  expect(store.count).to eq(0)
@@ -53,6 +53,23 @@ RSpec.describe Legion::Extensions::Agentic::Memory::Trace::Runners::Consolidatio
53
53
  end
54
54
 
55
55
  describe '#decay_cycle' do
56
+ it 'does not initialize the shared store when Gaia defers heartbeat maintenance' do
57
+ runner = Object.new.extend(described_class)
58
+ allow(Legion::Extensions::Agentic::Memory::Trace).to receive(:shared_store)
59
+
60
+ result = runner.decay_cycle(maintenance: false)
61
+
62
+ expect(Legion::Extensions::Agentic::Memory::Trace).not_to have_received(:shared_store)
63
+ expect(result).to include(
64
+ decayed: 0,
65
+ pruned: 0,
66
+ total: 0,
67
+ remaining: 0,
68
+ deferred: true,
69
+ reason: :background_decay_actor
70
+ )
71
+ end
72
+
56
73
  it 'defers Gaia heartbeat decay work to the background actor when maintenance is false' do
57
74
  client.store_trace(type: :semantic, content_payload: {})
58
75
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lex-agentic-memory
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.33
4
+ version: 0.1.34
5
5
  platform: ruby
6
6
  authors:
7
7
  - Esity