Class: Rubino::Memory::Backend

Inherits:
Object
  • Object
show all
Defined in:
lib/rubino/memory/backend.rb

Overview

Duck-typed contract for a pluggable memory backend.

A backend owns the WRITE path (store / replace / forget / extract), the READ path the prompt assembler depends on (user_profile / project_context / retrieve), and the admin surface that powers ‘rubino memory …` (list / find). The method set is the union of what the rest of the gem already calls today — extracting this interface is a mechanical refactor, not a rewrite.

The injection-defense floor (ThreatScanner + the char-budget enforced in Memory::Store) lives in the shared write path, so no backend can splice tainted or over-budget content into a future system prompt. Concrete backends override only what they need; the base raises NotImplementedError for the operations that have no sensible default.

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(config: nil) ⇒ Backend

Returns a new instance of Backend.



25
26
27
# File 'lib/rubino/memory/backend.rb', line 25

def initialize(config: nil)
  @config = config || Rubino.configuration
end

Class Method Details

.backend_nameObject

Backend registry key (e.g. “default”). Subclasses must override.

Raises:

  • (NotImplementedError)


21
22
23
# File 'lib/rubino/memory/backend.rb', line 21

def self.backend_name
  raise NotImplementedError, "#{self} must define .backend_name"
end

Instance Method Details

#available?Boolean

Deps present + configured (no network). Backends with optional dependencies override this; the default is always available.

Returns:

  • (Boolean)


31
32
33
# File 'lib/rubino/memory/backend.rb', line 31

def available?
  true
end

#countObject

Total number of stored memories. Powers the CLI /status line and the web dashboard’s memory card via GET /v1/memory/stats.

Raises:

  • (NotImplementedError)


99
100
101
# File 'lib/rubino/memory/backend.rb', line 99

def count
  raise NotImplementedError, "#{self.class} must implement #count"
end

#delete(id) ⇒ Object

Raises:

  • (NotImplementedError)


93
94
95
# File 'lib/rubino/memory/backend.rb', line 93

def delete(id)
  raise NotImplementedError, "#{self.class} must implement #delete"
end

#extract(session_id) ⇒ Object

Mine a session’s messages for durable facts and persist them. Returns the list of stored entries.

Raises:

  • (NotImplementedError)


57
58
59
# File 'lib/rubino/memory/backend.rb', line 57

def extract(session_id)
  raise NotImplementedError, "#{self.class} must implement #extract"
end

#find(id) ⇒ Object

Raises:

  • (NotImplementedError)


89
90
91
# File 'lib/rubino/memory/backend.rb', line 89

def find(id)
  raise NotImplementedError, "#{self.class} must implement #find"
end

#forget(kind:, old_text:) ⇒ Object

Delete the first entry of ‘kind` whose content includes `old_text`. Returns the matched row, or nil if nothing matched.

Raises:

  • (NotImplementedError)


51
52
53
# File 'lib/rubino/memory/backend.rb', line 51

def forget(kind:, old_text:)
  raise NotImplementedError, "#{self.class} must implement #forget"
end

#list(kind: nil, limit: 20, include_retired: false) ⇒ Object

Live entries only by default; ‘include_retired: true` opts into the supersession history on backends that soft-retire (sqlite).

Raises:

  • (NotImplementedError)


85
86
87
# File 'lib/rubino/memory/backend.rb', line 85

def list(kind: nil, limit: 20, include_retired: false)
  raise NotImplementedError, "#{self.class} must implement #list"
end

#project_contextObject

Project-context text (String) or nil.

Raises:

  • (NotImplementedError)


69
70
71
# File 'lib/rubino/memory/backend.rb', line 69

def project_context
  raise NotImplementedError, "#{self.class} must implement #project_context"
end

#replace(kind:, old_text:, content:) ⇒ Object

Replace the content of the first entry of ‘kind` whose content includes `old_text`. Returns the matched row, or nil if nothing matched.

Raises:

  • (NotImplementedError)


45
46
47
# File 'lib/rubino/memory/backend.rb', line 45

def replace(kind:, old_text:, content:)
  raise NotImplementedError, "#{self.class} must implement #replace"
end

#retrieve(session_id:, query: nil) ⇒ Object

Memories relevant to the turn. ‘query` lets a relevance-aware backend rank by the last user message; the default backend ignores it and returns everything that fits, exactly as today. Returns an array of rows ([kind:, content:, …]).

Raises:

  • (NotImplementedError)


77
78
79
# File 'lib/rubino/memory/backend.rb', line 77

def retrieve(session_id:, query: nil)
  raise NotImplementedError, "#{self.class} must implement #retrieve"
end

#store(kind:, content:, source_session_id: nil, confidence: 1.0, metadata: {}) ⇒ Object

Persist one memory entry. Returns the stored row (Hash) or raises a Memory::Store::ThreatDetectedError / BudgetExceededError on refusal.

Raises:

  • (NotImplementedError)


39
40
41
# File 'lib/rubino/memory/backend.rb', line 39

def store(kind:, content:, source_session_id: nil, confidence: 1.0, metadata: {})
  raise NotImplementedError, "#{self.class} must implement #store"
end

#user_profileObject

User-profile text (String) or nil.

Raises:

  • (NotImplementedError)


64
65
66
# File 'lib/rubino/memory/backend.rb', line 64

def 
  raise NotImplementedError, "#{self.class} must implement #user_profile"
end