Class: Phronomy::Agent::Context::Conversation::CompactionContext
- Inherits:
-
Object
- Object
- Phronomy::Agent::Context::Conversation::CompactionContext
- Defined in:
- lib/phronomy/agent/context/conversation/compaction_context.rb
Overview
Context object passed to the +on_compact+ callback registered on an agent.
The callback calls #compact one or more times to specify which ranges of messages to replace with a summary. Each call:
- Yields the selected message elements to the block.
- Receives the block's return value as the summary text.
- Persists a compaction record to the memory store (if available).
- Updates #result_messages so that the compacted range is replaced by a single +:system+ summary message.
The agent reads #result_messages after the callback returns and uses it as the new message list for this invocation.
Instance Attribute Summary collapse
- #budget ⇒ Phronomy::LlmContextWindow::TokenBudget? readonly
-
#message_elements ⇒ Array<Hash>
readonly
Message elements at compaction time.
-
#result_messages ⇒ Array
readonly
The current message list to be used after all compact calls have been made.
-
#total_tokens ⇒ Integer
readonly
Total estimated token count before compaction.
Instance Method Summary collapse
-
#compact(range) {|elements| ... } ⇒ Array
private
Replace a range of messages with a summary produced by the block.
-
#initialize(message_elements:, budget:, thread_id: nil, memory: nil) ⇒ CompactionContext
constructor
private
mutant:disable - e[:tokens] vs e.fetch(:tokens) and e[:message] vs e.fetch(:message) are genuine equivalent mutations: elements always carry both keys.
Constructor Details
#initialize(message_elements:, budget:, thread_id: nil, memory: nil) ⇒ CompactionContext
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
mutant:disable - e[:tokens] vs e.fetch(:tokens) and e[:message] vs e.fetch(:message) are genuine equivalent mutations: elements always carry both keys
52 53 54 55 56 57 58 59 |
# File 'lib/phronomy/agent/context/conversation/compaction_context.rb', line 52 def initialize(message_elements:, budget:, thread_id: nil, memory: nil) @message_elements = .dup @budget = budget @total_tokens = .sum { |e| e[:tokens] } @thread_id = thread_id @memory = memory @result_messages = @message_elements.map { |e| e[:message] } end |
Instance Attribute Details
#budget ⇒ Phronomy::LlmContextWindow::TokenBudget? (readonly)
33 34 35 |
# File 'lib/phronomy/agent/context/conversation/compaction_context.rb', line 33 def budget @budget end |
#message_elements ⇒ Array<Hash> (readonly)
Returns message elements at compaction time.
30 31 32 |
# File 'lib/phronomy/agent/context/conversation/compaction_context.rb', line 30 def @message_elements end |
#result_messages ⇒ Array (readonly)
The current message list to be used after all compact calls have been made. Updated by each call to #compact.
42 43 44 |
# File 'lib/phronomy/agent/context/conversation/compaction_context.rb', line 42 def @result_messages end |
#total_tokens ⇒ Integer (readonly)
Returns total estimated token count before compaction.
36 37 38 |
# File 'lib/phronomy/agent/context/conversation/compaction_context.rb', line 36 def total_tokens @total_tokens end |
Instance Method Details
#compact(range) {|elements| ... } ⇒ Array
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Replace a range of messages with a summary produced by the block.
The block receives the selected Array
If the memory object responds to #save_compaction, a compaction record { start_seq:, end_seq:, summary_text: } is persisted for auditability.
mutant:disable - multiple genuine equivalent mutations: is_a? vs instance_of? (Array/Range have no subclasses), yield.to_s vs yield (block always returns String), [:seq]/[:message] vs .fetch(:seq)/.fetch(:message) (keys always present), range.to_i vs range/to_int/Integer() (Integer is already integer), || [] vs nothing (Array#[] never returns nil for slice), RubyLLM::Message vs Message (killfork inherits Message=Struct from integration specs, both expose identical role/content interface)
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
# File 'lib/phronomy/agent/context/conversation/compaction_context.rb', line 76 def compact(range) # Normalise: Integer index → single-element Array; Range → Array slice. raw = @message_elements[range] elements = if raw.is_a?(Array) raw elsif raw.nil? [] else [raw] end return @result_messages if elements.empty? summary_text = yield(elements).to_s start_seq = elements.first[:seq] end_seq = elements.last[:seq] if @memory && @thread_id && @memory.respond_to?(:save_compaction) @memory.save_compaction( thread_id: @thread_id, start_seq: start_seq, end_seq: end_seq, summary_text: summary_text ) end # Compute the last included index in the original @message_elements array. last_idx = if range.is_a?(Range) range.exclude_end? ? range.last - 1 : range.last else range.to_i end remaining = (@message_elements[(last_idx + 1)..] || []).map { |e| e[:message] } summary_msg = RubyLLM::Message.new(role: :system, content: summary_text) @result_messages = [summary_msg] + remaining end |