Class: Llmemory::Reflection::Reflector

Inherits:
Object
  • Object
show all
Defined in:
lib/llmemory/reflection/reflector.rb

Overview

Reflection distills an agent’s recent episodes (episodic memory) into durable, higher-order insights and writes them to semantic memory. This is CoALA’s “updating semantic memory with knowledge” (Reflexion / Generative Agents): unlike one-shot extraction from raw text, it reasons over lived experience to generalize lessons and patterns.

Each insight is stored with provenance { method: “reflection”, sources: [{ type: “episode”, id: … }] } so it stays traceable to the experiences that produced it.

‘semantic` must respond to:

remember_fact(content:, category:, importance:, provenance:)

(FileBased::Memory implements this; graph-based is a future target.)

Constant Summary collapse

DEFAULT_CATEGORY =
"insights"
DEFAULT_IMPORTANCE =
0.6

Instance Method Summary collapse

Constructor Details

#initialize(episodic:, semantic:, llm: nil) ⇒ Reflector

Returns a new instance of Reflector.



24
25
26
27
28
# File 'lib/llmemory/reflection/reflector.rb', line 24

def initialize(episodic:, semantic:, llm: nil)
  @episodic = episodic
  @semantic = semantic
  @llm = llm || Llmemory::LLM.client
end

Instance Method Details

#reflect(window: 10, category: DEFAULT_CATEGORY) ⇒ Object

Reflects over the most recent ‘window` episodes and writes the resulting insights to semantic memory. Returns the ids of the stored insights.



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/llmemory/reflection/reflector.rb', line 32

def reflect(window: 10, category: DEFAULT_CATEGORY)
  episodes = @episodic.recent_episodes(limit: window)
  return [] if episodes.empty?

  insights = distill(episodes)
  return [] if insights.empty?

  sources = episodes.map(&:id).compact.map { |id| { type: "episode", id: id } }

  insights.filter_map do |insight|
    provenance = Llmemory::Provenance.build(
      method: "reflection",
      sources: sources,
      confidence: insight[:confidence]
    )
    @semantic.remember_fact(
      content: insight[:content],
      category: category,
      importance: insight[:confidence] || DEFAULT_IMPORTANCE,
      provenance: provenance
    )
  end
end