Class: Engram::Memory

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

Overview

The friendly facade. Bound to one ‘scope` (an owner), it wires the configured store and embedder into the use cases. This is what `user.memory` returns in Rails.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(scope:, store: Engram.config.store, embedder: Engram.config.embedder) ⇒ Memory

Returns a new instance of Memory.



9
10
11
12
13
# File 'lib/engram/memory.rb', line 9

def initialize(scope:, store: Engram.config.store, embedder: Engram.config.embedder)
  @scope = scope
  @store = store
  @embedder = embedder
end

Instance Attribute Details

#scopeObject (readonly)

Returns the value of attribute scope.



7
8
9
# File 'lib/engram/memory.rb', line 7

def scope
  @scope
end

Instance Method Details

#add(content, kind: :semantic, importance: 1.0, metadata: {}) ⇒ Object

Persist a fact. (In v0.2 this is mostly done for you via extract/consolidate.)



16
17
18
19
20
21
22
23
24
25
26
# File 'lib/engram/memory.rb', line 16

def add(content, kind: :semantic, importance: 1.0, metadata: {})
  record = Record.new(
    content: content,
    scope: scope,
    embedding: @embedder.embed(content),
    kind: kind,
    importance: importance,
    metadata: 
  )
  @store.add(record)
end

#allObject



75
76
77
# File 'lib/engram/memory.rb', line 75

def all
  @store.all(scope: scope)
end

#forget_stale(older_than:, min_importance: Float::INFINITY) ⇒ Object

Prune stale memories. ‘older_than` is a duration in seconds; `min_importance` keeps memories at or above that importance even when old. Returns the forgotten records.



81
82
83
84
# File 'lib/engram/memory.rb', line 81

def forget_stale(older_than:, min_importance: Float::INFINITY)
  UseCases::Forget.new(store: @store)
    .call(scope: scope, older_than: older_than, min_importance: min_importance)
end

#inject_into(prompt, query:, limit: Engram.config.default_limit) ⇒ Object

Recall, then inject into a prompt string.



41
42
43
44
# File 'lib/engram/memory.rb', line 41

def inject_into(prompt, query:, limit: Engram.config.default_limit)
  memories = recall(query, limit: limit)
  UseCases::Inject.new.call(prompt: prompt, memories: memories)
end

#observe(messages, completion: Engram.config.completion) ⇒ Object

Derive memories from a conversation turn and consolidate them (v0.2). ‘messages` is an Array of content: hashes (or plain strings). Returns the Array<Decision> applied. Requires a configured Completion.



49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/engram/memory.rb', line 49

def observe(messages, completion: Engram.config.completion)
  if completion.nil?
    raise Engram::Error, "observe requires a Completion. Set Engram.config.completion."
  end

  UseCases::Observe.new(
    store: @store,
    extractor: build_extractor(completion),
    consolidator: build_consolidator(completion),
    processed_turns: Engram.config.processed_turns
  ).call(
    messages: messages,
    scope: scope,
    idempotency_key: TurnDigest.digest(scope: scope, messages: messages)
  )
end

#observe_later(messages) ⇒ Object

Enqueue observation as a background job (Rails only).



67
68
69
70
71
72
73
# File 'lib/engram/memory.rb', line 67

def observe_later(messages)
  unless defined?(Engram::ObserveJob)
    raise Engram::Error, "observe_later needs ActiveJob (Rails). Use #observe outside Rails."
  end

  Engram::ObserveJob.perform_later(scope, messages)
end

#recall(query, limit: Engram.config.default_limit) ⇒ Object

Return the most relevant memories for a query.



29
30
31
32
33
34
35
36
37
38
# File 'lib/engram/memory.rb', line 29

def recall(query, limit: Engram.config.default_limit)
  UseCases::Recall.new(
    store: @store,
    embedder: @embedder,
    importance_weight: Engram.config.importance_weight,
    recency_weight: Engram.config.recency_weight,
    recency_halflife: Engram.config.recency_halflife,
    touch: Engram.config.touch_on_recall
  ).call(query, scope: scope, limit: limit)
end