Class: DSPy::Memory::MemoryManager
- Inherits:
-
Object
- Object
- DSPy::Memory::MemoryManager
- Extended by:
- T::Sig
- Defined in:
- lib/dspy/memory/memory_manager.rb
Overview
High-level memory management interface implementing MemoryTools API
Instance Attribute Summary collapse
-
#compactor ⇒ Object
readonly
Returns the value of attribute compactor.
-
#embedding_engine ⇒ Object
readonly
Returns the value of attribute embedding_engine.
-
#store ⇒ Object
readonly
Returns the value of attribute store.
Instance Method Summary collapse
- #clear_memories(user_id: nil) ⇒ Object
- #compact_if_needed!(user_id = nil) ⇒ Object
- #count_memories(user_id: nil) ⇒ Object
- #delete_memory(memory_id) ⇒ Object
- #export_memories(user_id: nil) ⇒ Object
- #find_similar(memory_id, limit: 5, threshold: 0.7) ⇒ Object
- #force_compact!(user_id = nil) ⇒ Object
- #get_all_memories(user_id: nil, limit: nil, offset: nil) ⇒ Object
- #get_memory(memory_id) ⇒ Object
- #healthy? ⇒ Boolean
- #import_memories(memories_data) ⇒ Object
-
#initialize(store: nil, embedding_engine: nil, compactor: nil) ⇒ MemoryManager
constructor
A new instance of MemoryManager.
- #search_by_tags(tags, user_id: nil, limit: nil) ⇒ Object
- #search_memories(query, user_id: nil, limit: 10, threshold: 0.5) ⇒ Object
- #search_text(query, user_id: nil, limit: nil) ⇒ Object
- #stats ⇒ Object
- #store_memories_batch(contents, user_id: nil, tags: []) ⇒ Object
- #store_memory(content, user_id: nil, tags: [], metadata: {}) ⇒ Object
- #update_memory(memory_id, new_content, tags: nil, metadata: nil) ⇒ Object
Constructor Details
#initialize(store: nil, embedding_engine: nil, compactor: nil) ⇒ MemoryManager
Returns a new instance of MemoryManager.
27 28 29 30 31 |
# File 'lib/dspy/memory/memory_manager.rb', line 27 def initialize(store: nil, embedding_engine: nil, compactor: nil) @store = store || InMemoryStore.new @embedding_engine = || @compactor = compactor || MemoryCompactor.new end |
Instance Attribute Details
#compactor ⇒ Object (readonly)
Returns the value of attribute compactor.
24 25 26 |
# File 'lib/dspy/memory/memory_manager.rb', line 24 def compactor @compactor end |
#embedding_engine ⇒ Object (readonly)
Returns the value of attribute embedding_engine.
21 22 23 |
# File 'lib/dspy/memory/memory_manager.rb', line 21 def @embedding_engine end |
#store ⇒ Object (readonly)
Returns the value of attribute store.
18 19 20 |
# File 'lib/dspy/memory/memory_manager.rb', line 18 def store @store end |
Instance Method Details
#clear_memories(user_id: nil) ⇒ Object
130 131 132 |
# File 'lib/dspy/memory/memory_manager.rb', line 130 def clear_memories(user_id: nil) @store.clear(user_id: user_id) end |
#compact_if_needed!(user_id = nil) ⇒ Object
212 213 214 |
# File 'lib/dspy/memory/memory_manager.rb', line 212 def compact_if_needed!(user_id = nil) @compactor.compact_if_needed!(@store, @embedding_engine, user_id: user_id) end |
#count_memories(user_id: nil) ⇒ Object
124 125 126 |
# File 'lib/dspy/memory/memory_manager.rb', line 124 def count_memories(user_id: nil) @store.count(user_id: user_id) end |
#delete_memory(memory_id) ⇒ Object
85 86 87 |
# File 'lib/dspy/memory/memory_manager.rb', line 85 def delete_memory(memory_id) @store.delete(memory_id) end |
#export_memories(user_id: nil) ⇒ Object
192 193 194 195 |
# File 'lib/dspy/memory/memory_manager.rb', line 192 def export_memories(user_id: nil) memories = get_all_memories(user_id: user_id) memories.map(&:to_h) end |
#find_similar(memory_id, limit: 5, threshold: 0.7) ⇒ Object
136 137 138 139 140 141 142 143 144 |
# File 'lib/dspy/memory/memory_manager.rb', line 136 def find_similar(memory_id, limit: 5, threshold: 0.7) record = @store.retrieve(memory_id) return [] unless record&. results = @store.vector_search(record., user_id: record.user_id, limit: limit + 1, threshold: threshold) # Remove the original record from results results.reject { |r| r.id == memory_id } end |
#force_compact!(user_id = nil) ⇒ Object
218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 |
# File 'lib/dspy/memory/memory_manager.rb', line 218 def force_compact!(user_id = nil) DSPy::Context.with_span( operation: 'memory.compaction_complete', 'memory.user_id' => user_id, 'memory.forced' => true ) do results = {} # Run all compaction strategies regardless of thresholds results[:size_compaction] = @compactor.send(:perform_size_compaction!, @store, user_id) results[:age_compaction] = @compactor.send(:perform_age_compaction!, @store, user_id) results[:deduplication] = @compactor.send(:perform_deduplication!, @store, @embedding_engine, user_id) results[:relevance_pruning] = @compactor.send(:perform_relevance_pruning!, @store, user_id) results[:total_compacted] = results.values.sum { |r| r.is_a?(Hash) ? r[:removed_count] || 0 : 0 } results end end |
#get_all_memories(user_id: nil, limit: nil, offset: nil) ⇒ Object
91 92 93 |
# File 'lib/dspy/memory/memory_manager.rb', line 91 def get_all_memories(user_id: nil, limit: nil, offset: nil) @store.list(user_id: user_id, limit: limit, offset: offset) end |
#get_memory(memory_id) ⇒ Object
60 61 62 |
# File 'lib/dspy/memory/memory_manager.rb', line 60 def get_memory(memory_id) @store.retrieve(memory_id) end |
#healthy? ⇒ Boolean
186 187 188 |
# File 'lib/dspy/memory/memory_manager.rb', line 186 def healthy? @embedding_engine.ready? && @store.respond_to?(:count) end |
#import_memories(memories_data) ⇒ Object
199 200 201 202 203 204 205 206 207 208 |
# File 'lib/dspy/memory/memory_manager.rb', line 199 def import_memories(memories_data) records = memories_data.map { |data| MemoryRecord.from_h(data) } results = @store.store_batch(records) # Compact after batch import user_ids = records.map(&:user_id).compact.uniq user_ids.each { |user_id| compact_if_needed!(user_id) } results.count(true) end |
#search_by_tags(tags, user_id: nil, limit: nil) ⇒ Object
112 113 114 |
# File 'lib/dspy/memory/memory_manager.rb', line 112 def (, user_id: nil, limit: nil) @store.(, user_id: user_id, limit: limit) end |
#search_memories(query, user_id: nil, limit: 10, threshold: 0.5) ⇒ Object
97 98 99 100 101 102 103 104 105 106 107 108 |
# File 'lib/dspy/memory/memory_manager.rb', line 97 def search_memories(query, user_id: nil, limit: 10, threshold: 0.5) # Generate embedding for the query = @embedding_engine.(query) # Perform vector search if supported if @store.supports_vector_search? @store.vector_search(, user_id: user_id, limit: limit, threshold: threshold) else # Fallback to text search @store.search(query, user_id: user_id, limit: limit) end end |
#search_text(query, user_id: nil, limit: nil) ⇒ Object
118 119 120 |
# File 'lib/dspy/memory/memory_manager.rb', line 118 def search_text(query, user_id: nil, limit: nil) @store.search(query, user_id: user_id, limit: limit) end |
#stats ⇒ Object
173 174 175 176 177 178 179 180 181 182 |
# File 'lib/dspy/memory/memory_manager.rb', line 173 def stats store_stats = @store.stats engine_stats = @embedding_engine.stats { store: store_stats, embedding_engine: engine_stats, total_memories: store_stats[:total_memories] || 0 } end |
#store_memories_batch(contents, user_id: nil, tags: []) ⇒ Object
148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 |
# File 'lib/dspy/memory/memory_manager.rb', line 148 def store_memories_batch(contents, user_id: nil, tags: []) # Generate embeddings in batch for efficiency = @embedding_engine.(contents) records = contents.zip().map do |content, | MemoryRecord.new( content: content, user_id: user_id, tags: , embedding: ) end # Store all records results = @store.store_batch(records) # Compact after batch operation compact_if_needed!(user_id) # Return only successfully stored records records.select.with_index { |_, idx| results[idx] } end |
#store_memory(content, user_id: nil, tags: [], metadata: {}) ⇒ Object
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
# File 'lib/dspy/memory/memory_manager.rb', line 35 def store_memory(content, user_id: nil, tags: [], metadata: {}) # Generate embedding for the content = @embedding_engine.(content) # Create memory record record = MemoryRecord.new( content: content, user_id: user_id, tags: , embedding: , metadata: ) # Store in backend success = @store.store(record) raise "Failed to store memory" unless success # Check if compaction is needed after storing compact_if_needed!(user_id) record end |
#update_memory(memory_id, new_content, tags: nil, metadata: nil) ⇒ Object
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/dspy/memory/memory_manager.rb', line 66 def update_memory(memory_id, new_content, tags: nil, metadata: nil) record = @store.retrieve(memory_id) return false unless record # Update content and regenerate embedding record.update_content!(new_content) record. = @embedding_engine.(new_content) # Update tags if provided record. = if # Update metadata if provided record..merge!() if @store.update(record) end |