llmemory 0.2.11 → 0.3.0

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.
Files changed (70) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +23 -0
  3. data/lib/generators/llmemory/install/templates/create_llmemory_tables.rb +71 -0
  4. data/lib/generators/llmemory/upgrade_zero_mem/templates/create_llmemory_zero_mem_tables.rb +77 -0
  5. data/lib/generators/llmemory/upgrade_zero_mem/upgrade_zero_mem_generator.rb +19 -0
  6. data/lib/llmemory/cli/commands/zero_mem.rb +107 -0
  7. data/lib/llmemory/cli.rb +3 -0
  8. data/lib/llmemory/configuration.rb +59 -1
  9. data/lib/llmemory/instrumentation.rb +10 -1
  10. data/lib/llmemory/maintenance/cognitive_pass.rb +29 -1
  11. data/lib/llmemory/maintenance/zero_mem_ttl.rb +26 -0
  12. data/lib/llmemory/maintenance.rb +1 -0
  13. data/lib/llmemory/mcp/server.rb +2 -0
  14. data/lib/llmemory/mcp/store_helpers.rb +16 -0
  15. data/lib/llmemory/mcp/tools/memory_add_message.rb +17 -4
  16. data/lib/llmemory/mcp/tools/memory_consolidate.rb +9 -4
  17. data/lib/llmemory/mcp/tools/memory_maintain.rb +6 -1
  18. data/lib/llmemory/mcp/tools/memory_retrieve.rb +3 -1
  19. data/lib/llmemory/mcp/tools/memory_retrieve_evidence.rb +70 -0
  20. data/lib/llmemory/mcp/tools/memory_stats.rb +22 -0
  21. data/lib/llmemory/memory.rb +257 -9
  22. data/lib/llmemory/retrieval/bm25_scorer.rb +5 -0
  23. data/lib/llmemory/tokenizer.rb +18 -8
  24. data/lib/llmemory/vector_store/memory_store.rb +23 -1
  25. data/lib/llmemory/vector_store/openai_embeddings.rb +47 -21
  26. data/lib/llmemory/version.rb +1 -1
  27. data/lib/llmemory/zero_mem/answer_calibrator.rb +63 -0
  28. data/lib/llmemory/zero_mem/backfill.rb +43 -0
  29. data/lib/llmemory/zero_mem/budget_assembler.rb +62 -0
  30. data/lib/llmemory/zero_mem/circuit_breaker.rb +37 -0
  31. data/lib/llmemory/zero_mem/embedding_provider.rb +73 -0
  32. data/lib/llmemory/zero_mem/engine.rb +247 -0
  33. data/lib/llmemory/zero_mem/entity.rb +31 -0
  34. data/lib/llmemory/zero_mem/entity_extractor.rb +23 -0
  35. data/lib/llmemory/zero_mem/entity_index.rb +65 -0
  36. data/lib/llmemory/zero_mem/entity_mention.rb +35 -0
  37. data/lib/llmemory/zero_mem/errors.rb +7 -0
  38. data/lib/llmemory/zero_mem/evidence.rb +43 -0
  39. data/lib/llmemory/zero_mem/evidence_calibrator.rb +158 -0
  40. data/lib/llmemory/zero_mem/evidence_closure.rb +98 -0
  41. data/lib/llmemory/zero_mem/evidence_fusion.rb +57 -0
  42. data/lib/llmemory/zero_mem/evidence_set.rb +54 -0
  43. data/lib/llmemory/zero_mem/extractors/heuristic.rb +44 -0
  44. data/lib/llmemory/zero_mem/extractors/http.rb +58 -0
  45. data/lib/llmemory/zero_mem/graph_retriever.rb +107 -0
  46. data/lib/llmemory/zero_mem/hierarchy_builder.rb +123 -0
  47. data/lib/llmemory/zero_mem/hierarchy_retriever.rb +133 -0
  48. data/lib/llmemory/zero_mem/indexer.rb +73 -0
  49. data/lib/llmemory/zero_mem/mode.rb +30 -0
  50. data/lib/llmemory/zero_mem/pagerank.rb +42 -0
  51. data/lib/llmemory/zero_mem/query_profile.rb +48 -0
  52. data/lib/llmemory/zero_mem/query_profiler.rb +138 -0
  53. data/lib/llmemory/zero_mem/repair.rb +31 -0
  54. data/lib/llmemory/zero_mem/router.rb +69 -0
  55. data/lib/llmemory/zero_mem/sidecar_client.rb +82 -0
  56. data/lib/llmemory/zero_mem/storage.rb +124 -0
  57. data/lib/llmemory/zero_mem/storages/active_record.rb +311 -0
  58. data/lib/llmemory/zero_mem/storages/active_record_models.rb +21 -0
  59. data/lib/llmemory/zero_mem/storages/file.rb +67 -0
  60. data/lib/llmemory/zero_mem/storages/memory.rb +294 -0
  61. data/lib/llmemory/zero_mem/storages/postgres.rb +85 -0
  62. data/lib/llmemory/zero_mem/storages/snapshot_codec.rb +180 -0
  63. data/lib/llmemory/zero_mem/storages.rb +43 -0
  64. data/lib/llmemory/zero_mem/trace.rb +100 -0
  65. data/lib/llmemory/zero_mem/trace_state_link.rb +64 -0
  66. data/lib/llmemory/zero_mem/trace_unit.rb +83 -0
  67. data/lib/llmemory/zero_mem.rb +42 -0
  68. data/lib/llmemory.rb +7 -0
  69. data/lib/tasks/llmemory.rake +52 -0
  70. metadata +48 -2
@@ -0,0 +1,64 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "time"
4
+
5
+ module Llmemory
6
+ module ZeroMem
7
+ class TraceStateLink
8
+ SOURCES = %i[explicit deterministic].freeze
9
+
10
+ attr_reader :user_id, :state_key, :trace_id, :valid_from, :valid_to,
11
+ :supersedes_trace_id, :source, :created_at
12
+
13
+ def self.build(user_id:, state_key:, trace_id:, valid_from:, valid_to: nil,
14
+ supersedes_trace_id: nil, source: :explicit, created_at: nil)
15
+ src = source.to_sym
16
+ raise ValidationError, "invalid state link source" unless SOURCES.include?(src)
17
+
18
+ new(
19
+ user_id: user_id.to_s,
20
+ state_key: state_key.to_s,
21
+ trace_id: trace_id.to_s,
22
+ valid_from: Trace.coerce_time(valid_from),
23
+ valid_to: valid_to ? Trace.coerce_time(valid_to) : nil,
24
+ supersedes_trace_id: supersedes_trace_id&.to_s,
25
+ source: src,
26
+ created_at: created_at ? Trace.coerce_time(created_at) : Time.now
27
+ )
28
+ end
29
+
30
+ def initialize(user_id:, state_key:, trace_id:, valid_from:, valid_to:,
31
+ supersedes_trace_id:, source:, created_at:)
32
+ @user_id = user_id
33
+ @state_key = state_key
34
+ @trace_id = trace_id
35
+ @valid_from = valid_from
36
+ @valid_to = valid_to
37
+ @supersedes_trace_id = supersedes_trace_id
38
+ @source = source
39
+ @created_at = created_at
40
+ end
41
+
42
+ def active_at?(as_of)
43
+ t = as_of.is_a?(Time) ? as_of : Time.parse(as_of.to_s)
44
+ return false if t < valid_from
45
+ return true if valid_to.nil?
46
+
47
+ t <= valid_to
48
+ end
49
+
50
+ def to_h
51
+ {
52
+ user_id: user_id,
53
+ state_key: state_key,
54
+ trace_id: trace_id,
55
+ valid_from: valid_from.utc.iso8601(6),
56
+ valid_to: valid_to&.utc&.iso8601(6),
57
+ supersedes_trace_id: supersedes_trace_id,
58
+ source: source,
59
+ created_at: created_at.utc.iso8601(6)
60
+ }
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,83 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "securerandom"
4
+
5
+ module Llmemory
6
+ module ZeroMem
7
+ class TraceUnit
8
+ KINDS = %i[turn window episode].freeze
9
+
10
+ attr_reader :id, :user_id, :kind, :session_id, :boundary_id, :start_sequence, :end_sequence,
11
+ :occurred_from, :occurred_to, :member_trace_ids, :embedding_ref, :index_version
12
+
13
+ def self.build(user_id:, kind:, session_id:, member_trace_ids:, start_sequence:, end_sequence:,
14
+ occurred_from:, occurred_to:, id: nil, boundary_id: nil, embedding_ref: nil,
15
+ index_version: 0)
16
+ k = kind.to_sym
17
+ raise ValidationError, "invalid trace unit kind" unless KINDS.include?(k)
18
+
19
+ new(
20
+ id: id || "tu_#{SecureRandom.hex(10)}",
21
+ user_id: user_id.to_s,
22
+ kind: k,
23
+ session_id: session_id.to_s,
24
+ boundary_id: boundary_id&.to_s,
25
+ start_sequence: start_sequence.to_i,
26
+ end_sequence: end_sequence.to_i,
27
+ occurred_from: Trace.coerce_time(occurred_from),
28
+ occurred_to: Trace.coerce_time(occurred_to),
29
+ member_trace_ids: Array(member_trace_ids).map(&:to_s),
30
+ embedding_ref: embedding_ref,
31
+ index_version: index_version.to_i
32
+ )
33
+ end
34
+
35
+ def initialize(id:, user_id:, kind:, session_id:, boundary_id:, start_sequence:, end_sequence:,
36
+ occurred_from:, occurred_to:, member_trace_ids:, embedding_ref:, index_version:)
37
+ @id = id
38
+ @user_id = user_id
39
+ @kind = kind
40
+ @session_id = session_id
41
+ @boundary_id = boundary_id
42
+ @start_sequence = start_sequence
43
+ @end_sequence = end_sequence
44
+ @occurred_from = occurred_from
45
+ @occurred_to = occurred_to
46
+ @member_trace_ids = member_trace_ids
47
+ @embedding_ref = embedding_ref
48
+ @index_version = index_version
49
+ end
50
+
51
+ def episode_key
52
+ boundary_id || session_id
53
+ end
54
+
55
+ def to_h
56
+ {
57
+ id: id,
58
+ user_id: user_id,
59
+ kind: kind,
60
+ session_id: session_id,
61
+ boundary_id: boundary_id,
62
+ start_sequence: start_sequence,
63
+ end_sequence: end_sequence,
64
+ occurred_from: occurred_from.utc.iso8601(6),
65
+ occurred_to: occurred_to.utc.iso8601(6),
66
+ member_trace_ids: member_trace_ids,
67
+ embedding_ref: embedding_ref,
68
+ index_version: index_version
69
+ }
70
+ end
71
+
72
+ def with(**changes)
73
+ attrs = {
74
+ id: id, user_id: user_id, kind: kind, session_id: session_id, boundary_id: boundary_id,
75
+ start_sequence: start_sequence, end_sequence: end_sequence,
76
+ occurred_from: occurred_from, occurred_to: occurred_to,
77
+ member_trace_ids: member_trace_ids, embedding_ref: embedding_ref, index_version: index_version
78
+ }.merge(changes)
79
+ self.class.new(**attrs)
80
+ end
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "zero_mem/mode"
4
+ require_relative "zero_mem/errors"
5
+ require_relative "zero_mem/trace"
6
+ require_relative "zero_mem/trace_state_link"
7
+ require_relative "zero_mem/storage"
8
+ require_relative "zero_mem/storages"
9
+ require_relative "zero_mem/indexer"
10
+ require_relative "zero_mem/repair"
11
+ require_relative "zero_mem/backfill"
12
+ require_relative "zero_mem/trace_unit"
13
+ require_relative "zero_mem/hierarchy_builder"
14
+ require_relative "zero_mem/query_profile"
15
+ require_relative "zero_mem/query_profiler"
16
+ require_relative "zero_mem/hierarchy_retriever"
17
+ require_relative "zero_mem/evidence"
18
+ require_relative "zero_mem/evidence_set"
19
+ require_relative "zero_mem/evidence_calibrator"
20
+ require_relative "zero_mem/budget_assembler"
21
+ require_relative "zero_mem/router"
22
+ require_relative "zero_mem/evidence_fusion"
23
+ require_relative "zero_mem/evidence_closure"
24
+ require_relative "zero_mem/answer_calibrator"
25
+ require_relative "zero_mem/engine"
26
+ require_relative "zero_mem/embedding_provider"
27
+ require_relative "zero_mem/entity_extractor"
28
+ require_relative "zero_mem/extractors/heuristic"
29
+ require_relative "zero_mem/extractors/http"
30
+ require_relative "zero_mem/entity"
31
+ require_relative "zero_mem/entity_mention"
32
+ require_relative "zero_mem/entity_index"
33
+ require_relative "zero_mem/pagerank"
34
+ require_relative "zero_mem/graph_retriever"
35
+ require_relative "zero_mem/circuit_breaker"
36
+ require_relative "zero_mem/sidecar_client"
37
+
38
+ module Llmemory
39
+ module ZeroMem
40
+ MEMORY_TYPE = "zero_mem_trace"
41
+ end
42
+ end
data/lib/llmemory.rb CHANGED
@@ -26,7 +26,14 @@ module Llmemory
26
26
  class ConfigurationError < Error; end
27
27
  class StoreError < Error; end
28
28
  class LLMError < Error; end
29
+ class GenerativeOperationDisabled < Error
30
+ def initialize(message = "Generative memory operation is disabled in this memory mode")
31
+ super
32
+ end
33
+ end
29
34
  end
30
35
 
36
+ require_relative "llmemory/zero_mem"
37
+
31
38
  require_relative "llmemory/crypto/cipher"
32
39
  require_relative "llmemory/railtie" if defined?(Rails::Railtie)
@@ -1,6 +1,58 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  namespace :llmemory do
4
+ namespace :zero_mem do
5
+ desc "Repair Zero-Mem trace watermarks vs checkpoint (requires trace_store configured in app)"
6
+ task :repair, %i[user_id session_id] do |_t, args|
7
+ require "llmemory"
8
+ user_id = args[:user_id] || ENV["USER_ID"] || abort("USER_ID or user_id argument required")
9
+ session_id = args[:session_id] || ENV["SESSION_ID"] || Llmemory::Memory::DEFAULT_SESSION_ID
10
+ store = Llmemory::ZeroMem::Storages.build
11
+ memory = Llmemory::Memory.new(user_id: user_id, session_id: session_id, trace_store: store, memory_mode: :zero_mem)
12
+ report = Llmemory::ZeroMem::Repair.new(storage: store).run!(
13
+ user_id: user_id,
14
+ session_id: session_id,
15
+ checkpoint_messages: memory.messages
16
+ )
17
+ puts "Zero-Mem repair user_id=#{user_id} session_id=#{session_id}: #{report.inspect}"
18
+ end
19
+
20
+ desc "Reindex Zero-Mem traces for a user session (ENV: USER_ID, SESSION_ID)"
21
+ task :reindex, %i[user_id session_id] do |_t, args|
22
+ require "llmemory"
23
+ user_id = args[:user_id] || ENV["USER_ID"] || abort("USER_ID or user_id argument required")
24
+ session_id = args[:session_id] || ENV["SESSION_ID"] || Llmemory::Memory::DEFAULT_SESSION_ID
25
+ store = Llmemory::ZeroMem::Storages.build
26
+ memory = Llmemory::Memory.new(user_id: user_id, session_id: session_id, trace_store: store, memory_mode: :zero_mem)
27
+ status = memory.reindex_traces!(session_id: session_id)
28
+ puts "Zero-Mem reindex: #{status.inspect}"
29
+ end
30
+
31
+ desc "Backfill checkpoint messages into traces (ENV: USER_ID, SESSION_ID)"
32
+ task :backfill, %i[user_id session_id] do |_t, args|
33
+ require "llmemory"
34
+ user_id = args[:user_id] || ENV["USER_ID"] || abort("USER_ID required")
35
+ session_id = args[:session_id] || ENV["SESSION_ID"] || Llmemory::Memory::DEFAULT_SESSION_ID
36
+ store = Llmemory::ZeroMem::Storages.build
37
+ memory = Llmemory::Memory.new(user_id: user_id, session_id: session_id, trace_store: store, memory_mode: :zero_mem)
38
+ report = Llmemory::ZeroMem::Backfill.new(storage: store).run!(
39
+ user_id: user_id,
40
+ session_id: session_id,
41
+ messages: memory.messages
42
+ )
43
+ puts "Zero-Mem backfill: #{report.inspect}"
44
+ end
45
+
46
+ desc "Archive Zero-Mem traces past TTL (ENV: USER_ID, DRY_RUN=1)"
47
+ task :expire, [:user_id] do |_t, args|
48
+ require "llmemory"
49
+ user_id = args[:user_id] || ENV["USER_ID"] || abort("USER_ID required")
50
+ store = Llmemory::ZeroMem::Storages.build
51
+ dry_run = ENV["DRY_RUN"].to_s == "1"
52
+ report = Llmemory::Maintenance::ZeroMemTTL.new(storage: store).run!(user_id: user_id, dry_run: dry_run)
53
+ puts "Zero-Mem expire: #{report.inspect}"
54
+ end
55
+ end
4
56
  desc "Backfill search_tokens blind index (and name_det on skills) for encrypted keyword search. " \
5
57
  "Env: FORCE=1 (re-backfill all rows), DRY_RUN=1 (count only), STORE=active_record|postgres"
6
58
  task :backfill_search_tokens, [:user_id] do |_t, args|
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: llmemory
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.11
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - llmemory
@@ -124,6 +124,8 @@ files:
124
124
  - exe/llmemory-mcp
125
125
  - lib/generators/llmemory/install/install_generator.rb
126
126
  - lib/generators/llmemory/install/templates/create_llmemory_tables.rb
127
+ - lib/generators/llmemory/upgrade_zero_mem/templates/create_llmemory_zero_mem_tables.rb
128
+ - lib/generators/llmemory/upgrade_zero_mem/upgrade_zero_mem_generator.rb
127
129
  - lib/llmemory.rb
128
130
  - lib/llmemory/actions.rb
129
131
  - lib/llmemory/actions/reason.rb
@@ -148,6 +150,7 @@ files:
148
150
  - lib/llmemory/cli/commands/stats.rb
149
151
  - lib/llmemory/cli/commands/users.rb
150
152
  - lib/llmemory/cli/commands/working.rb
153
+ - lib/llmemory/cli/commands/zero_mem.rb
151
154
  - lib/llmemory/configuration.rb
152
155
  - lib/llmemory/consolidation.rb
153
156
  - lib/llmemory/consolidation/filter.rb
@@ -227,6 +230,7 @@ files:
227
230
  - lib/llmemory/maintenance/search_tokens_backfill.rb
228
231
  - lib/llmemory/maintenance/summarizer.rb
229
232
  - lib/llmemory/maintenance/ttl_expiry.rb
233
+ - lib/llmemory/maintenance/zero_mem_ttl.rb
230
234
  - lib/llmemory/mcp.rb
231
235
  - lib/llmemory/mcp/authentication.rb
232
236
  - lib/llmemory/mcp/server.rb
@@ -240,6 +244,7 @@ files:
240
244
  - lib/llmemory/mcp/tools/memory_maintain.rb
241
245
  - lib/llmemory/mcp/tools/memory_mine_skills.rb
242
246
  - lib/llmemory/mcp/tools/memory_retrieve.rb
247
+ - lib/llmemory/mcp/tools/memory_retrieve_evidence.rb
243
248
  - lib/llmemory/mcp/tools/memory_save.rb
244
249
  - lib/llmemory/mcp/tools/memory_search.rb
245
250
  - lib/llmemory/mcp/tools/memory_skill_register.rb
@@ -287,6 +292,47 @@ files:
287
292
  - lib/llmemory/vector_store/openai_embeddings.rb
288
293
  - lib/llmemory/version.rb
289
294
  - lib/llmemory/working_memory.rb
295
+ - lib/llmemory/zero_mem.rb
296
+ - lib/llmemory/zero_mem/answer_calibrator.rb
297
+ - lib/llmemory/zero_mem/backfill.rb
298
+ - lib/llmemory/zero_mem/budget_assembler.rb
299
+ - lib/llmemory/zero_mem/circuit_breaker.rb
300
+ - lib/llmemory/zero_mem/embedding_provider.rb
301
+ - lib/llmemory/zero_mem/engine.rb
302
+ - lib/llmemory/zero_mem/entity.rb
303
+ - lib/llmemory/zero_mem/entity_extractor.rb
304
+ - lib/llmemory/zero_mem/entity_index.rb
305
+ - lib/llmemory/zero_mem/entity_mention.rb
306
+ - lib/llmemory/zero_mem/errors.rb
307
+ - lib/llmemory/zero_mem/evidence.rb
308
+ - lib/llmemory/zero_mem/evidence_calibrator.rb
309
+ - lib/llmemory/zero_mem/evidence_closure.rb
310
+ - lib/llmemory/zero_mem/evidence_fusion.rb
311
+ - lib/llmemory/zero_mem/evidence_set.rb
312
+ - lib/llmemory/zero_mem/extractors/heuristic.rb
313
+ - lib/llmemory/zero_mem/extractors/http.rb
314
+ - lib/llmemory/zero_mem/graph_retriever.rb
315
+ - lib/llmemory/zero_mem/hierarchy_builder.rb
316
+ - lib/llmemory/zero_mem/hierarchy_retriever.rb
317
+ - lib/llmemory/zero_mem/indexer.rb
318
+ - lib/llmemory/zero_mem/mode.rb
319
+ - lib/llmemory/zero_mem/pagerank.rb
320
+ - lib/llmemory/zero_mem/query_profile.rb
321
+ - lib/llmemory/zero_mem/query_profiler.rb
322
+ - lib/llmemory/zero_mem/repair.rb
323
+ - lib/llmemory/zero_mem/router.rb
324
+ - lib/llmemory/zero_mem/sidecar_client.rb
325
+ - lib/llmemory/zero_mem/storage.rb
326
+ - lib/llmemory/zero_mem/storages.rb
327
+ - lib/llmemory/zero_mem/storages/active_record.rb
328
+ - lib/llmemory/zero_mem/storages/active_record_models.rb
329
+ - lib/llmemory/zero_mem/storages/file.rb
330
+ - lib/llmemory/zero_mem/storages/memory.rb
331
+ - lib/llmemory/zero_mem/storages/postgres.rb
332
+ - lib/llmemory/zero_mem/storages/snapshot_codec.rb
333
+ - lib/llmemory/zero_mem/trace.rb
334
+ - lib/llmemory/zero_mem/trace_state_link.rb
335
+ - lib/llmemory/zero_mem/trace_unit.rb
290
336
  - lib/tasks/llmemory.rake
291
337
  - lib/tasks/release.rake
292
338
  homepage: https://github.com/entaina/llmemory
@@ -309,7 +355,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
309
355
  - !ruby/object:Gem::Version
310
356
  version: '0'
311
357
  requirements: []
312
- rubygems_version: 4.0.16
358
+ rubygems_version: 4.0.20
313
359
  specification_version: 4
314
360
  summary: Persistent memory system for LLM agents
315
361
  test_files: []