Class: Ask::Agent::Compactor
- Inherits:
-
Object
- Object
- Ask::Agent::Compactor
- Defined in:
- lib/ask/agent/compactor.rb
Constant Summary collapse
- CONTEXT_WINDOWS =
{ "gpt-4o" => 128_000, "gpt-4o-mini" => 128_000, "gpt-4-turbo" => 128_000, "claude-sonnet-4" => 200_000, "claude-4" => 200_000, "gemini-2.0-flash" => 1_048_576, "gemini-2.5-pro" => 1_048_576, "deepseek-v4-flash" => 1_000_000, "deepseek-v4-pro" => 1_000_000, }.tap { |h| h.default = 128_000 }
Instance Attribute Summary collapse
-
#chat ⇒ Object
Returns the value of attribute chat.
-
#llm ⇒ Object
Returns the value of attribute llm.
Instance Method Summary collapse
- #compact! ⇒ Object
- #context_window ⇒ Object
- #estimate_tokens(text) ⇒ Object
- #estimate_total_tokens ⇒ Object
-
#initialize(threshold: 0.8, strategy: :proactive, llm: nil) ⇒ Compactor
constructor
A new instance of Compactor.
- #microcompact! ⇒ Object
- #overflow_recovered? ⇒ Boolean
- #recover_from_overflow ⇒ Object
- #run(event_emitter: nil) ⇒ Object
- #should_compact? ⇒ Boolean
Constructor Details
#initialize(threshold: 0.8, strategy: :proactive, llm: nil) ⇒ Compactor
Returns a new instance of Compactor.
20 21 22 23 24 25 26 |
# File 'lib/ask/agent/compactor.rb', line 20 def initialize(threshold: 0.8, strategy: :proactive, llm: nil) @threshold = threshold @strategy = strategy @llm = llm @already_compacted = false @overflow_recovered = false end |
Instance Attribute Details
#chat ⇒ Object
Returns the value of attribute chat.
18 19 20 |
# File 'lib/ask/agent/compactor.rb', line 18 def chat @chat end |
#llm ⇒ Object
Returns the value of attribute llm.
18 19 20 |
# File 'lib/ask/agent/compactor.rb', line 18 def llm @llm end |
Instance Method Details
#compact! ⇒ Object
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/ask/agent/compactor.rb', line 48 def compact! return unless @chat = @chat..dup return if .size < 6 keep_count = [.size, 8].min recent = .last(keep_count) older = .first(.size - keep_count) return if older.empty? summary = if @llm generate_llm_summary(older) || generate_summary(older) else generate_summary(older) end older.size.times { @chat..delete_at(0) } @chat.(role: :system, content: "[Previous conversation summary]: #{summary}") end |
#context_window ⇒ Object
91 92 93 94 |
# File 'lib/ask/agent/compactor.rb', line 91 def context_window model = @chat.model.to_s CONTEXT_WINDOWS[model] end |
#estimate_tokens(text) ⇒ Object
82 83 84 |
# File 'lib/ask/agent/compactor.rb', line 82 def estimate_tokens(text) (text.to_s.length / 4.0).ceil end |
#estimate_total_tokens ⇒ Object
86 87 88 89 |
# File 'lib/ask/agent/compactor.rb', line 86 def estimate_total_tokens return 0 unless @chat @chat..sum { |msg| (msg) } end |
#microcompact! ⇒ Object
68 69 70 71 72 73 74 |
# File 'lib/ask/agent/compactor.rb', line 68 def microcompact! return unless @chat @chat..each do |msg| next unless msg.role == :tool msg.content = "[Tool result cleared by compaction]" if msg.content.to_s.length > 200 end end |
#overflow_recovered? ⇒ Boolean
28 |
# File 'lib/ask/agent/compactor.rb', line 28 def overflow_recovered? = @overflow_recovered |
#recover_from_overflow ⇒ Object
76 77 78 79 80 |
# File 'lib/ask/agent/compactor.rb', line 76 def recover_from_overflow if @already_compacted then microcompact! else compact! end @already_compacted = true @overflow_recovered = true end |
#run(event_emitter: nil) ⇒ Object
37 38 39 40 41 42 43 44 45 46 |
# File 'lib/ask/agent/compactor.rb', line 37 def run(event_emitter: nil) return unless @chat tokens_before = estimate_total_tokens event_emitter&.emit(Events::CompactionStart.new(tokens_before: tokens_before, reason: :threshold)) compact! tokens_after = estimate_total_tokens @already_compacted = true event_emitter&.emit(Events::CompactionEnd.new(tokens_before: tokens_before, tokens_after: tokens_after, summary: extract_summary)) end |
#should_compact? ⇒ Boolean
30 31 32 33 34 35 |
# File 'lib/ask/agent/compactor.rb', line 30 def should_compact? return false unless @chat current = estimate_total_tokens window = context_window current >= window * @threshold end |