Class: SmartPrompt::SlidingWindowStrategy

Inherits:
Object
  • Object
show all
Includes:
ContextStrategy
Defined in:
lib/smart_prompt/sliding_window_strategy.rb

Overview

SlidingWindowStrategy implements a simple context selection strategy that keeps the most recent N messages (sliding window approach)

This strategy:

  • Preserves system messages regardless of window size

  • Keeps the most recent N non-system messages

  • Trims messages to fit within token limits if specified

  • Is efficient and predictable for simple conversation flows

Instance Method Summary collapse

Constructor Details

#initialize(config = {}) ⇒ SlidingWindowStrategy

Initialize the sliding window strategy

Parameters:

  • config (Hash) (defaults to: {})

    Configuration options

Options Hash (config):

  • :window_size (Integer) — default: 10

    Number of recent messages to keep

  • :preserve_system (Boolean) — default: true

    Whether to always keep system messages



19
20
21
22
# File 'lib/smart_prompt/sliding_window_strategy.rb', line 19

def initialize(config = {})
  @window_size = config[:window_size] || 10
  @preserve_system = config[:preserve_system] != false
end

Instance Method Details

#select_messages(messages, max_tokens, current_message = nil) ⇒ Array<Message>

Select messages using sliding window approach

Parameters:

  • messages (Array<Message>)

    All messages in the session

  • max_tokens (Integer, nil)

    Maximum token limit for selected messages

  • current_message (Message, nil) (defaults to: nil)

    Not used in this strategy

Returns:

  • (Array<Message>)

    Selected messages



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/smart_prompt/sliding_window_strategy.rb', line 29

def select_messages(messages, max_tokens, current_message = nil)
  return [] if messages.nil? || messages.empty?

  # Separate system and non-system messages
  system_messages = @preserve_system ? messages.select(&:system_message?) : []
  non_system_messages = messages.reject(&:system_message?)

  # Get the most recent messages within window size
  recent_messages = non_system_messages.last(@window_size)

  # Combine system messages (at the beginning) with recent messages
  selected = system_messages + recent_messages

  # Log selection decision
  log_debug "SlidingWindowStrategy: selected #{selected.count}/#{messages.count} messages (window_size=#{@window_size}, system=#{system_messages.count}, recent=#{recent_messages.count})"

  # Trim to token limit if specified
  result = max_tokens ? trim_to_token_limit(selected, max_tokens) : selected
  
  if max_tokens && result.count < selected.count
    tokens_before = selected.sum { |m| m.token_count || 0 }
    tokens_after = result.sum { |m| m.token_count || 0 }
    log_debug "SlidingWindowStrategy: trimmed to token limit #{max_tokens}: #{selected.count} -> #{result.count} messages, #{tokens_before} -> #{tokens_after} tokens"
  end
  
  result
end

#should_compress?(session) ⇒ Boolean

Determine if compression should be triggered Recommends compression when message count exceeds 2x window size

Parameters:

  • session (Session)

    The session to evaluate

Returns:

  • (Boolean)

    true if message count > 2 * window_size



61
62
63
# File 'lib/smart_prompt/sliding_window_strategy.rb', line 61

def should_compress?(session)
  session.message_count > @window_size * 2
end