Class: RubynCode::Memory::Store
- Inherits:
-
Object
- Object
- RubynCode::Memory::Store
- Defined in:
- lib/rubyn_code/memory/store.rb
Overview
Writes and manages memories in SQLite, backed by an FTS5 full-text search index for fast retrieval. Handles expiration and relevance decay to keep the memory store manageable over time.
Constant Summary collapse
- MEMORY_ATTR_MAP =
{ content: ->(v) { v }, tier: ->(v) { v }, category: ->(v) { v }, metadata: ->(v) { JSON.generate(v) }, expires_at: ->(v) { v }, relevance_score: lambda(&:to_f) }.freeze
Instance Method Summary collapse
-
#decay!(decay_rate: 0.01) ⇒ void
Reduces the relevance_score of memories that have not been accessed recently, simulating natural memory decay.
-
#delete(id) ⇒ void
Deletes a memory and its FTS index entry.
-
#expire_old! ⇒ Integer
Removes all memories whose expires_at is in the past.
-
#initialize(db, project_path:) ⇒ Store
constructor
A new instance of Store.
-
#update(id, **attrs) ⇒ void
Updates attributes on an existing memory.
-
#write(content:, tier: 'medium', category: nil, metadata: {}, expires_at: nil) ⇒ MemoryRecord
Persists a new memory and updates the FTS index.
Constructor Details
#initialize(db, project_path:) ⇒ Store
Returns a new instance of Store.
15 16 17 18 19 |
# File 'lib/rubyn_code/memory/store.rb', line 15 def initialize(db, project_path:) @db = db @project_path = project_path ensure_tables end |
Instance Method Details
#decay!(decay_rate: 0.01) ⇒ void
This method returns an undefined value.
Reduces the relevance_score of memories that have not been accessed recently, simulating natural memory decay.
105 106 107 108 109 110 111 112 113 114 |
# File 'lib/rubyn_code/memory/store.rb', line 105 def decay!(decay_rate: 0.01) cutoff = (Time.now.utc - 86_400).strftime('%Y-%m-%d %H:%M:%S') # 24 hours ago @db.execute(<<~SQL, [decay_rate, @project_path, cutoff]) UPDATE memories SET relevance_score = MAX(0.0, relevance_score - ?) WHERE project_path = ? AND last_accessed_at < ? SQL end |
#delete(id) ⇒ void
This method returns an undefined value.
Deletes a memory and its FTS index entry.
74 75 76 |
# File 'lib/rubyn_code/memory/store.rb', line 74 def delete(id) @db.execute('DELETE FROM memories WHERE id = ? AND project_path = ?', [id, @project_path]) end |
#expire_old! ⇒ Integer
Removes all memories whose expires_at is in the past.
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
# File 'lib/rubyn_code/memory/store.rb', line 81 def expire_old! now = Time.now.utc.strftime('%Y-%m-%d %H:%M:%S') expired_ids = @db.query( 'SELECT id FROM memories WHERE project_path = ? AND expires_at IS NOT NULL AND expires_at < ?', [@project_path, now] ).to_a.map { |row| row['id'] } return 0 if expired_ids.empty? placeholders = (['?'] * expired_ids.size).join(', ') @db.execute( "DELETE FROM memories WHERE id IN (#{placeholders}) AND project_path = ?", expired_ids + [@project_path] ) expired_ids.size end |
#update(id, **attrs) ⇒ void
This method returns an undefined value.
Updates attributes on an existing memory.
57 58 59 60 61 62 63 64 65 66 67 68 |
# File 'lib/rubyn_code/memory/store.rb', line 57 def update(id, **attrs) return if attrs.empty? sets, params = build_memory_update(attrs) return if sets.empty? params << id @db.execute( "UPDATE memories SET #{sets.join(', ')} WHERE id = ? AND project_path = '#{@project_path}'", params ) end |
#write(content:, tier: 'medium', category: nil, metadata: {}, expires_at: nil) ⇒ MemoryRecord
Persists a new memory and updates the FTS index.
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
# File 'lib/rubyn_code/memory/store.rb', line 29 def write(content:, tier: 'medium', category: nil, metadata: {}, expires_at: nil) validate_tier!(tier) validate_category!(category) if category id = SecureRandom.uuid now = Time.now.utc.strftime('%Y-%m-%d %H:%M:%S') = JSON.generate() @db.execute(<<~SQL, [id, @project_path, tier, category, content, 1.0, 0, now, expires_at, , now]) INSERT INTO memories (id, project_path, tier, category, content, relevance_score, access_count, last_accessed_at, expires_at, metadata, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) SQL MemoryRecord.new( id: id, project_path: @project_path, tier: tier, category: category, content: content, relevance_score: 1.0, access_count: 0, last_accessed_at: now, expires_at: expires_at, metadata: , created_at: now ) end |