Class: Llmemory::LongTerm::Episodic::Memory
- Inherits:
-
Object
- Object
- Llmemory::LongTerm::Episodic::Memory
- Includes:
- MemoryModule
- Defined in:
- lib/llmemory/long_term/episodic/memory.rb
Overview
Episodic long-term memory: records agent trajectories and retrieves them by recency, importance and relevance. Designed to coexist with semantic memory (file/graph), not replace it, and to feed reflection (P2), which distills episodes into semantic knowledge.
Deliberately LLM-free: recording and retrieval are deterministic. Higher order summarization belongs to reflection.
Instance Attribute Summary collapse
-
#storage ⇒ Object
readonly
Returns the value of attribute storage.
-
#user_id ⇒ Object
readonly
Returns the value of attribute user_id.
Instance Method Summary collapse
- #count ⇒ Object
- #episodes(limit: nil) ⇒ Object
- #find_episode(id) ⇒ Object
- #forget(ids:, reason: nil) ⇒ Object
-
#initialize(user_id:, storage: nil) ⇒ Memory
constructor
A new instance of Memory.
- #list(user_id: nil, limit: nil) ⇒ Object
- #recent_episodes(limit: 10) ⇒ Object
-
#record_episode(steps:, summary: nil, outcome: nil, importance: 0.5) ⇒ Object
Records a trajectory.
-
#search_candidates(query, user_id: nil, top_k: 20) ⇒ Object
Retrieval Engine integration.
- #stats(user_id: nil) ⇒ Object
-
#write(steps:, summary: nil, outcome: nil, importance: 0.5, **_meta) ⇒ Object
— MemoryModule uniform interface —.
Methods included from MemoryModule
Constructor Details
Instance Attribute Details
#storage ⇒ Object (readonly)
Returns the value of attribute storage.
20 21 22 |
# File 'lib/llmemory/long_term/episodic/memory.rb', line 20 def storage @storage end |
#user_id ⇒ Object (readonly)
Returns the value of attribute user_id.
20 21 22 |
# File 'lib/llmemory/long_term/episodic/memory.rb', line 20 def user_id @user_id end |
Instance Method Details
#count ⇒ Object
58 59 60 |
# File 'lib/llmemory/long_term/episodic/memory.rb', line 58 def count @storage.count_episodes(@user_id) end |
#episodes(limit: nil) ⇒ Object
49 50 51 |
# File 'lib/llmemory/long_term/episodic/memory.rb', line 49 def episodes(limit: nil) @storage.list_episodes(@user_id, limit: limit).map { |e| Episode.from_h(e) } end |
#find_episode(id) ⇒ Object
53 54 55 56 |
# File 'lib/llmemory/long_term/episodic/memory.rb', line 53 def find_episode(id) raw = @storage.get_episode(@user_id, id) raw && Episode.from_h(raw) end |
#forget(ids:, reason: nil) ⇒ Object
97 98 99 100 101 102 103 104 |
# File 'lib/llmemory/long_term/episodic/memory.rb', line 97 def forget(ids:, reason: nil) requested = Array(ids).map(&:to_s) existing = @storage.list_episodes(@user_id).map { |e| (e[:id] || e["id"]).to_s } removed = requested & existing @storage.delete_episodes(@user_id, removed) forget_log.record(@user_id, memory_type: "episodic", ids: removed, reason: reason) removed.size end |
#list(user_id: nil, limit: nil) ⇒ Object
89 90 91 |
# File 'lib/llmemory/long_term/episodic/memory.rb', line 89 def list(user_id: nil, limit: nil) episodes(limit: limit) end |
#recent_episodes(limit: 10) ⇒ Object
45 46 47 |
# File 'lib/llmemory/long_term/episodic/memory.rb', line 45 def recent_episodes(limit: 10) @storage.list_episodes(@user_id, limit: limit).map { |e| Episode.from_h(e) } end |
#record_episode(steps:, summary: nil, outcome: nil, importance: 0.5) ⇒ Object
Records a trajectory. ‘steps` is an array of hashes with any of :observation, :action, :result, :timestamp. Returns the episode id.
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
# File 'lib/llmemory/long_term/episodic/memory.rb', line 29 def record_episode(steps:, summary: nil, outcome: nil, importance: 0.5) episode = Episode.new( id: nil, user_id: @user_id, steps: steps, summary: summary || derive_summary(steps), outcome: outcome, importance: importance ) provenance = Llmemory::Provenance.from_text_fingerprint( episode.searchable_text, method: "episode_recording", confidence: episode.importance ) record = episode.to_h.merge(provenance: provenance) @storage.save_episode(@user_id, record) end |
#search_candidates(query, user_id: nil, top_k: 20) ⇒ Object
Retrieval Engine integration. Returns candidates shaped like the other long-term memories so the Engine can rank episodes by relevance, recency (temporal decay) and importance (P3), with provenance (P10).
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/llmemory/long_term/episodic/memory.rb', line 65 def search_candidates(query, user_id: nil, top_k: 20) uid = user_id || @user_id return [] unless uid == @user_id @storage.search_episodes(uid, query).first(top_k).map do |e| episode = Episode.from_h(e) { id: episode.id, text: episode.summary.to_s.empty? ? episode.searchable_text : episode.summary, timestamp: episode.created_at, score: 1.0, importance: episode.importance, evergreen: false, provenance: e[:provenance] || e["provenance"] } end end |
#stats(user_id: nil) ⇒ Object
93 94 95 |
# File 'lib/llmemory/long_term/episodic/memory.rb', line 93 def stats(user_id: nil) { episodes: count } end |
#write(steps:, summary: nil, outcome: nil, importance: 0.5, **_meta) ⇒ Object
— MemoryModule uniform interface —
85 86 87 |
# File 'lib/llmemory/long_term/episodic/memory.rb', line 85 def write(steps:, summary: nil, outcome: nil, importance: 0.5, **) record_episode(steps: steps, summary: summary, outcome: outcome, importance: importance) end |