llmemory 0.1.17 → 0.2.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.
- checksums.yaml +4 -4
- data/README.md +172 -0
- data/lib/llmemory/actions/reason.rb +49 -0
- data/lib/llmemory/actions.rb +8 -0
- data/lib/llmemory/configuration.rb +2 -0
- data/lib/llmemory/forget_log.rb +50 -0
- data/lib/llmemory/long_term/episodic/memory.rb +27 -0
- data/lib/llmemory/long_term/episodic/storages/base.rb +5 -0
- data/lib/llmemory/long_term/episodic/storages/file_storage.rb +9 -0
- data/lib/llmemory/long_term/episodic/storages/memory_storage.rb +7 -0
- data/lib/llmemory/long_term/file_based/memory.rb +31 -0
- data/lib/llmemory/long_term/graph_based/memory.rb +30 -3
- data/lib/llmemory/long_term/procedural/memory.rb +116 -0
- data/lib/llmemory/long_term/procedural/skill.rb +93 -0
- data/lib/llmemory/long_term/procedural/storage.rb +31 -0
- data/lib/llmemory/long_term/procedural/storages/base.rb +53 -0
- data/lib/llmemory/long_term/procedural/storages/file_storage.rb +136 -0
- data/lib/llmemory/long_term/procedural/storages/memory_storage.rb +80 -0
- data/lib/llmemory/long_term/procedural.rb +12 -0
- data/lib/llmemory/long_term.rb +2 -0
- data/lib/llmemory/memory.rb +9 -1
- data/lib/llmemory/memory_module.rb +55 -0
- data/lib/llmemory/retrieval/engine.rb +115 -6
- data/lib/llmemory/retrieval/feedback_store.rb +50 -0
- data/lib/llmemory/short_term/checkpoint.rb +2 -14
- data/lib/llmemory/short_term/session_lifecycle.rb +3 -10
- data/lib/llmemory/short_term/stores.rb +27 -0
- data/lib/llmemory/version.rb +1 -1
- data/lib/llmemory/working_memory.rb +83 -0
- data/lib/llmemory.rb +4 -0
- metadata +15 -1
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "../short_term/stores"
|
|
4
|
+
|
|
5
|
+
module Llmemory
|
|
6
|
+
module Retrieval
|
|
7
|
+
# Persists retrieval feedback: a net utility signal per (user, memory item),
|
|
8
|
+
# accumulated from agents marking retrieved items useful (+1) or harmful (-1).
|
|
9
|
+
#
|
|
10
|
+
# CoALA flags adaptive retrieval — "learning better retrieval procedures" — as
|
|
11
|
+
# understudied. This is the minimal substrate for it: a feedback ledger the
|
|
12
|
+
# Engine consults to boost repeatedly-useful items and dampen noise.
|
|
13
|
+
#
|
|
14
|
+
# Backed by the same pluggable short-term stores as Checkpoint/WorkingMemory,
|
|
15
|
+
# under a per-user pseudo-session key.
|
|
16
|
+
class FeedbackStore
|
|
17
|
+
SESSION_KEY = "__retrieval_feedback__"
|
|
18
|
+
|
|
19
|
+
def initialize(store: nil)
|
|
20
|
+
@store = store || ShortTerm::Stores.build
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def record(user_id, item_id, delta)
|
|
24
|
+
return if user_id.nil? || item_id.nil?
|
|
25
|
+
state = load(user_id)
|
|
26
|
+
key = item_id.to_s
|
|
27
|
+
state[key] = (state[key] || 0) + delta.to_i
|
|
28
|
+
@store.save(user_id, SESSION_KEY, state)
|
|
29
|
+
state[key]
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def net(user_id, item_id)
|
|
33
|
+
return 0 if user_id.nil? || item_id.nil?
|
|
34
|
+
load(user_id)[item_id.to_s] || 0
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def all(user_id)
|
|
38
|
+
load(user_id)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
private
|
|
42
|
+
|
|
43
|
+
def load(user_id)
|
|
44
|
+
state = @store.load(user_id, SESSION_KEY)
|
|
45
|
+
return {} unless state.is_a?(Hash)
|
|
46
|
+
state.each_with_object({}) { |(k, v), acc| acc[k.to_s] = v.to_i }
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative "stores
|
|
4
|
-
require_relative "stores/memory_store"
|
|
5
|
-
require_relative "stores/redis_store"
|
|
6
|
-
require_relative "stores/postgres_store"
|
|
3
|
+
require_relative "stores"
|
|
7
4
|
|
|
8
5
|
module Llmemory
|
|
9
6
|
module ShortTerm
|
|
@@ -31,16 +28,7 @@ module Llmemory
|
|
|
31
28
|
private
|
|
32
29
|
|
|
33
30
|
def build_store
|
|
34
|
-
|
|
35
|
-
when :memory then Stores::MemoryStore.new
|
|
36
|
-
when :redis then Stores::RedisStore.new
|
|
37
|
-
when :postgres then Stores::PostgresStore.new
|
|
38
|
-
when :active_record, :activerecord
|
|
39
|
-
require_relative "stores/active_record_store"
|
|
40
|
-
Stores::ActiveRecordStore.new
|
|
41
|
-
else
|
|
42
|
-
Stores::MemoryStore.new
|
|
43
|
-
end
|
|
31
|
+
Stores.build
|
|
44
32
|
end
|
|
45
33
|
end
|
|
46
34
|
end
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require_relative "stores"
|
|
4
|
+
|
|
3
5
|
module Llmemory
|
|
4
6
|
module ShortTerm
|
|
5
7
|
class SessionLifecycle
|
|
@@ -72,16 +74,7 @@ module Llmemory
|
|
|
72
74
|
private
|
|
73
75
|
|
|
74
76
|
def build_store
|
|
75
|
-
|
|
76
|
-
when :memory then Stores::MemoryStore.new
|
|
77
|
-
when :redis then Stores::RedisStore.new
|
|
78
|
-
when :postgres then Stores::PostgresStore.new
|
|
79
|
-
when :active_record, :activerecord
|
|
80
|
-
require_relative "stores/active_record_store"
|
|
81
|
-
Stores::ActiveRecordStore.new
|
|
82
|
-
else
|
|
83
|
-
Stores::MemoryStore.new
|
|
84
|
-
end
|
|
77
|
+
Stores.build
|
|
85
78
|
end
|
|
86
79
|
end
|
|
87
80
|
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "stores/base"
|
|
4
|
+
require_relative "stores/memory_store"
|
|
5
|
+
require_relative "stores/redis_store"
|
|
6
|
+
require_relative "stores/postgres_store"
|
|
7
|
+
|
|
8
|
+
module Llmemory
|
|
9
|
+
module ShortTerm
|
|
10
|
+
module Stores
|
|
11
|
+
# Single source of truth for selecting a short-term store backend.
|
|
12
|
+
# Shared by Checkpoint, SessionLifecycle and WorkingMemory.
|
|
13
|
+
def self.build(store_type = nil)
|
|
14
|
+
case (store_type || Llmemory.configuration.short_term_store).to_sym
|
|
15
|
+
when :memory then MemoryStore.new
|
|
16
|
+
when :redis then RedisStore.new
|
|
17
|
+
when :postgres then PostgresStore.new
|
|
18
|
+
when :active_record, :activerecord
|
|
19
|
+
require_relative "stores/active_record_store"
|
|
20
|
+
ActiveRecordStore.new
|
|
21
|
+
else
|
|
22
|
+
MemoryStore.new
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
data/lib/llmemory/version.rb
CHANGED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "short_term/stores"
|
|
4
|
+
|
|
5
|
+
module Llmemory
|
|
6
|
+
# CoALA's "working memory": a structured, symbolic scratch space that persists
|
|
7
|
+
# across LLM calls within a session — distinct from the raw message buffer
|
|
8
|
+
# (Checkpoint). It is the central hub an agent reads from and writes to while
|
|
9
|
+
# reasoning (goals, current task, retrieved context, intermediate reasoning,
|
|
10
|
+
# last observation, free-form scratchpad), plus arbitrary custom slots.
|
|
11
|
+
#
|
|
12
|
+
# Backed by the same pluggable short-term stores as Checkpoint, but under a
|
|
13
|
+
# namespaced session key so working-memory slots never collide with messages.
|
|
14
|
+
class WorkingMemory
|
|
15
|
+
DEFAULT_SESSION_ID = "default"
|
|
16
|
+
SESSION_SUFFIX = ":working_memory"
|
|
17
|
+
SLOTS = %i[goals current_task retrieved_context scratchpad last_observation intermediate_reasoning].freeze
|
|
18
|
+
|
|
19
|
+
attr_reader :user_id, :session_id
|
|
20
|
+
|
|
21
|
+
def initialize(user_id:, session_id: DEFAULT_SESSION_ID, store: nil)
|
|
22
|
+
@user_id = user_id
|
|
23
|
+
@session_id = session_id
|
|
24
|
+
@store_key = "#{session_id}#{SESSION_SUFFIX}"
|
|
25
|
+
@store = store || ShortTerm::Stores.build
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
SLOTS.each do |slot|
|
|
29
|
+
define_method(slot) { read[slot] }
|
|
30
|
+
define_method("#{slot}=") { |value| set(slot, value) }
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Read/write an arbitrary slot (typed or custom).
|
|
34
|
+
def get(slot)
|
|
35
|
+
read[slot.to_sym]
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def set(slot, value)
|
|
39
|
+
state = read
|
|
40
|
+
state[slot.to_sym] = value
|
|
41
|
+
persist(state)
|
|
42
|
+
value
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Bulk update in a single write.
|
|
46
|
+
def update(**slots)
|
|
47
|
+
state = read
|
|
48
|
+
slots.each { |k, v| state[k.to_sym] = v }
|
|
49
|
+
persist(state)
|
|
50
|
+
state
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# Slots set by the caller beyond the predefined typed ones.
|
|
54
|
+
def custom_slots
|
|
55
|
+
read.reject { |k, _| SLOTS.include?(k) }
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def to_h
|
|
59
|
+
read
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def clear!
|
|
63
|
+
@store.delete(@user_id, @store_key)
|
|
64
|
+
true
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
private
|
|
68
|
+
|
|
69
|
+
def read
|
|
70
|
+
state = @store.load(@user_id, @store_key)
|
|
71
|
+
return {} unless state.is_a?(Hash)
|
|
72
|
+
symbolize(state)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def persist(state)
|
|
76
|
+
@store.save(@user_id, @store_key, state)
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def symbolize(hash)
|
|
80
|
+
hash.each_with_object({}) { |(k, v), acc| acc[k.to_sym] = v }
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
data/lib/llmemory.rb
CHANGED
|
@@ -3,14 +3,18 @@
|
|
|
3
3
|
require_relative "llmemory/version"
|
|
4
4
|
require_relative "llmemory/configuration"
|
|
5
5
|
require_relative "llmemory/provenance"
|
|
6
|
+
require_relative "llmemory/memory_module"
|
|
7
|
+
require_relative "llmemory/forget_log"
|
|
6
8
|
require_relative "llmemory/llm"
|
|
7
9
|
require_relative "llmemory/short_term"
|
|
10
|
+
require_relative "llmemory/working_memory"
|
|
8
11
|
require_relative "llmemory/long_term"
|
|
9
12
|
require_relative "llmemory/retrieval"
|
|
10
13
|
require_relative "llmemory/vector_store"
|
|
11
14
|
require_relative "llmemory/maintenance"
|
|
12
15
|
require_relative "llmemory/extractors"
|
|
13
16
|
require_relative "llmemory/reflection"
|
|
17
|
+
require_relative "llmemory/actions"
|
|
14
18
|
require_relative "llmemory/memory"
|
|
15
19
|
|
|
16
20
|
module Llmemory
|
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.
|
|
4
|
+
version: 0.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- llmemory
|
|
@@ -127,6 +127,8 @@ files:
|
|
|
127
127
|
- lib/generators/llmemory/install/install_generator.rb
|
|
128
128
|
- lib/generators/llmemory/install/templates/create_llmemory_tables.rb
|
|
129
129
|
- lib/llmemory.rb
|
|
130
|
+
- lib/llmemory/actions.rb
|
|
131
|
+
- lib/llmemory/actions/reason.rb
|
|
130
132
|
- lib/llmemory/cli.rb
|
|
131
133
|
- lib/llmemory/cli/commands/base.rb
|
|
132
134
|
- lib/llmemory/cli/commands/long_term.rb
|
|
@@ -147,6 +149,7 @@ files:
|
|
|
147
149
|
- lib/llmemory/extractors.rb
|
|
148
150
|
- lib/llmemory/extractors/entity_relation_extractor.rb
|
|
149
151
|
- lib/llmemory/extractors/fact_extractor.rb
|
|
152
|
+
- lib/llmemory/forget_log.rb
|
|
150
153
|
- lib/llmemory/llm.rb
|
|
151
154
|
- lib/llmemory/llm/anthropic.rb
|
|
152
155
|
- lib/llmemory/llm/base.rb
|
|
@@ -183,6 +186,13 @@ files:
|
|
|
183
186
|
- lib/llmemory/long_term/graph_based/storages/active_record_storage.rb
|
|
184
187
|
- lib/llmemory/long_term/graph_based/storages/base.rb
|
|
185
188
|
- lib/llmemory/long_term/graph_based/storages/memory_storage.rb
|
|
189
|
+
- lib/llmemory/long_term/procedural.rb
|
|
190
|
+
- lib/llmemory/long_term/procedural/memory.rb
|
|
191
|
+
- lib/llmemory/long_term/procedural/skill.rb
|
|
192
|
+
- lib/llmemory/long_term/procedural/storage.rb
|
|
193
|
+
- lib/llmemory/long_term/procedural/storages/base.rb
|
|
194
|
+
- lib/llmemory/long_term/procedural/storages/file_storage.rb
|
|
195
|
+
- lib/llmemory/long_term/procedural/storages/memory_storage.rb
|
|
186
196
|
- lib/llmemory/maintenance.rb
|
|
187
197
|
- lib/llmemory/maintenance/consolidator.rb
|
|
188
198
|
- lib/llmemory/maintenance/reindexer.rb
|
|
@@ -201,6 +211,7 @@ files:
|
|
|
201
211
|
- lib/llmemory/mcp/tools/memory_timeline.rb
|
|
202
212
|
- lib/llmemory/mcp/tools/memory_timeline_context.rb
|
|
203
213
|
- lib/llmemory/memory.rb
|
|
214
|
+
- lib/llmemory/memory_module.rb
|
|
204
215
|
- lib/llmemory/noise_filter.rb
|
|
205
216
|
- lib/llmemory/provenance.rb
|
|
206
217
|
- lib/llmemory/reflection.rb
|
|
@@ -209,6 +220,7 @@ files:
|
|
|
209
220
|
- lib/llmemory/retrieval/bm25_scorer.rb
|
|
210
221
|
- lib/llmemory/retrieval/context_assembler.rb
|
|
211
222
|
- lib/llmemory/retrieval/engine.rb
|
|
223
|
+
- lib/llmemory/retrieval/feedback_store.rb
|
|
212
224
|
- lib/llmemory/retrieval/mmr_reranker.rb
|
|
213
225
|
- lib/llmemory/retrieval/temporal_ranker.rb
|
|
214
226
|
- lib/llmemory/short_term.rb
|
|
@@ -216,6 +228,7 @@ files:
|
|
|
216
228
|
- lib/llmemory/short_term/message_sanitizer.rb
|
|
217
229
|
- lib/llmemory/short_term/pruner.rb
|
|
218
230
|
- lib/llmemory/short_term/session_lifecycle.rb
|
|
231
|
+
- lib/llmemory/short_term/stores.rb
|
|
219
232
|
- lib/llmemory/short_term/stores/active_record_checkpoint.rb
|
|
220
233
|
- lib/llmemory/short_term/stores/active_record_store.rb
|
|
221
234
|
- lib/llmemory/short_term/stores/base.rb
|
|
@@ -229,6 +242,7 @@ files:
|
|
|
229
242
|
- lib/llmemory/vector_store/memory_store.rb
|
|
230
243
|
- lib/llmemory/vector_store/openai_embeddings.rb
|
|
231
244
|
- lib/llmemory/version.rb
|
|
245
|
+
- lib/llmemory/working_memory.rb
|
|
232
246
|
- lib/tasks/release.rake
|
|
233
247
|
homepage: https://github.com/entaina/llmemory
|
|
234
248
|
licenses:
|