Class: Phronomy::Memory::Retrieval::Composite

Inherits:
Base
  • Object
show all
Defined in:
lib/phronomy/memory/retrieval/composite.rb

Overview

Retrieval strategy that merges results from multiple child retrieval strategies.

Each child is given a weight that controls what fraction of a token budget it should consume. Results are deduplicated (by role + content) and system messages are sorted to the front.

Examples:

composite = Phronomy::Memory::Retrieval::Composite.new(
  sources: [
    { retrieval: Phronomy::Memory::Retrieval::Recent.new(k: 5),    weight: 0.4 },
    { retrieval: Phronomy::Memory::Retrieval::Semantic.new(...),   weight: 0.6 }
  ]
)
manager = Phronomy::Memory::ConversationManager.new(
  storage:   Phronomy::Memory::Storage::InMemory.new,
  retrieval: composite
)

Instance Method Summary collapse

Constructor Details

#initialize(sources:) ⇒ Composite

Returns a new instance of Composite.

Parameters:

  • sources (Array<Hash>)

    each entry: { retrieval:, weight: } (weight default 1.0)



25
26
27
# File 'lib/phronomy/memory/retrieval/composite.rb', line 25

def initialize(sources:)
  @sources = sources.map { |s| {retrieval: s[:retrieval], weight: (s[:weight] || 1.0).to_f} }
end

Instance Method Details

#clear_index(thread_id:) ⇒ Object

Forward clear_index to all child retrievals that support it.

Parameters:

  • thread_id (String)


67
68
69
70
71
# File 'lib/phronomy/memory/retrieval/composite.rb', line 67

def clear_index(thread_id:)
  @sources.each do |source|
    source[:retrieval].clear_index(thread_id: thread_id) if source[:retrieval].respond_to?(:clear_index)
  end
end

#index(thread_id:, messages:) ⇒ Object

Forward index calls to all child retrievals that support it.

Parameters:

  • thread_id (String)
  • messages (Array)


58
59
60
61
62
# File 'lib/phronomy/memory/retrieval/composite.rb', line 58

def index(thread_id:, messages:)
  @sources.each do |source|
    source[:retrieval].index(thread_id: thread_id, messages: messages) if source[:retrieval].respond_to?(:index)
  end
end

#select(messages, query: nil) ⇒ Array

Merge results from all child retrievals, deduplicating by role+content. System messages are sorted to the front; others preserve insertion order.

Parameters:

  • messages (Array)

    full chronological history

  • query (String, nil) (defaults to: nil)

    forwarded to each child retrieval

Returns:

  • (Array)


35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/phronomy/memory/retrieval/composite.rb', line 35

def select(messages, query: nil)
  all_messages = []
  seen = {}

  @sources.each do |source|
    source[:retrieval].select(messages, query: query).each do |msg|
      key = "#{msg.role}:#{msg.content}"
      next if seen[key]

      seen[key] = true
      all_messages << msg
    end
  end

  systems = all_messages.select { |m| m.role.to_sym == :system }
  others = all_messages.reject { |m| m.role.to_sym == :system }
  systems + others
end