Class: Llmemory::LongTerm::GraphBased::Memory

Inherits:
Object
  • Object
show all
Includes:
MemoryModule
Defined in:
lib/llmemory/long_term/graph_based/memory.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from MemoryModule

#forget_log, #read

Constructor Details

#initialize(user_id:, storage: nil, vector_store: nil, llm: nil, extractor: nil) ⇒ Memory

Returns a new instance of Memory.



17
18
19
20
21
22
23
24
25
# File 'lib/llmemory/long_term/graph_based/memory.rb', line 17

def initialize(user_id:, storage: nil, vector_store: nil, llm: nil, extractor: nil)
  @user_id = user_id
  @graph_storage = storage || Storages.build
  @kg = KnowledgeGraph.new(user_id: user_id, storage: @graph_storage)
  @conflict_resolver = ConflictResolver.new(@kg)
  @vector_store = vector_store || build_vector_store
  @llm = llm || Llmemory::LLM.client
  @extractor = extractor || Llmemory::Extractors::EntityRelationExtractor.new(llm: @llm)
end

Instance Attribute Details

#user_idObject (readonly)

Returns the value of attribute user_id.



59
60
61
# File 'lib/llmemory/long_term/graph_based/memory.rb', line 59

def user_id
  @user_id
end

Instance Method Details

#forget(ids:, reason: nil) ⇒ Object

Forgets relations by archiving the edges identified by the candidate ids returned from #read/#search_candidates (edge ids), recording the removal in the audit log. Edges are soft-archived (archived_at) so they no longer appear in retrieval; nodes are left in place (a node may still be referenced by other active edges). Returns the number archived.



98
99
100
101
102
# File 'lib/llmemory/long_term/graph_based/memory.rb', line 98

def forget(ids:, reason: nil)
  archived = Array(ids).map(&:to_s).select { |edge_id| @kg.archive_edge(edge_id) }
  forget_log.record(@user_id, memory_type: "graph_based", ids: archived, reason: reason)
  archived.size
end

#list(user_id: nil, limit: nil) ⇒ Object



84
85
86
# File 'lib/llmemory/long_term/graph_based/memory.rb', line 84

def list(user_id: nil, limit: nil)
  @graph_storage.list_nodes(user_id || @user_id, limit: limit)
end

#memorize(conversation_text) ⇒ Object



27
28
29
30
31
32
33
34
35
36
37
# File 'lib/llmemory/long_term/graph_based/memory.rb', line 27

def memorize(conversation_text)
  text = Llmemory.configuration.noise_filter_enabled ? NoiseFilter.filter?(conversation_text) : conversation_text.to_s
  return true if text.strip.empty?

  entities, relations = extract_graph(text)
  return true if entities.empty? && relations.empty?

  provenance = Llmemory::Provenance.from_text_fingerprint(text, method: "entity_relation_extraction")
  ingest(entities, relations, provenance)
  true
end

#remember_fact(content:, category: nil, importance: nil, provenance: nil) ⇒ Object

Stores a fact produced outside the conversational flow (e.g. a reflection insight) by extracting entities/relations from ‘content` and adding them to the graph, preserving caller-supplied provenance. Lets the Reflector target graph-based semantic memory.



69
70
71
72
73
74
75
76
# File 'lib/llmemory/long_term/graph_based/memory.rb', line 69

def remember_fact(content:, category: nil, importance: nil, provenance: nil)
  return nil if content.to_s.strip.empty?
  entities, relations = extract_graph(content)
  return nil if entities.empty? && relations.empty?
  prov = provenance || Llmemory::Provenance.from_text_fingerprint(content, method: "reflection")
  ingest(entities, relations, prov)
  true
end

#retrieve(query, top_k: 10) ⇒ Object



39
40
41
42
# File 'lib/llmemory/long_term/graph_based/memory.rb', line 39

def retrieve(query, top_k: 10)
  results = hybrid_search(query, top_k: top_k)
  format_as_context(results)
end

#search_candidates(query, user_id: nil, top_k: 20) ⇒ Object



44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/llmemory/long_term/graph_based/memory.rb', line 44

def search_candidates(query, user_id: nil, top_k: 20)
  uid = user_id || @user_id
  return [] unless uid == @user_id
  results = hybrid_search(query, top_k: top_k)
  results.map do |r|
    {
      id: r[:id],
      text: r[:text],
      timestamp: r[:created_at] || r[:timestamp],
      score: r[:score] || 1.0,
      importance: r[:importance]
    }
  end
end

#stats(user_id: nil) ⇒ Object



88
89
90
91
# File 'lib/llmemory/long_term/graph_based/memory.rb', line 88

def stats(user_id: nil)
  uid = user_id || @user_id
  { nodes: @graph_storage.count_nodes(uid), edges: @graph_storage.count_edges(uid) }
end

#storageObject



61
62
63
# File 'lib/llmemory/long_term/graph_based/memory.rb', line 61

def storage
  @graph_storage
end

#write(payload, **_meta) ⇒ Object

— MemoryModule uniform interface —



80
81
82
# File 'lib/llmemory/long_term/graph_based/memory.rb', line 80

def write(payload, **_meta)
  memorize(payload)
end