Class: SmartPrompt::HybridStrategy

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

Overview

HybridStrategy implements a flexible context selection strategy that combines multiple strategies for optimal results

This strategy supports two modes:

  • Adaptive mode: Automatically selects the best strategy based on message count

  • Combined mode: Merges results from multiple strategies

Adaptive mode selection logic:

  • < 20 messages: Use SlidingWindowStrategy (simple and efficient)

  • 20-50 messages: Use RelevanceBasedStrategy (balance recency and relevance)

  • > 50 messages: Use SummaryBasedStrategy (compress older messages)

Combined mode:

  • Runs multiple strategies and merges their results

  • Removes duplicates and sorts by importance

  • Provides comprehensive context from different perspectives

Instance Method Summary collapse

Constructor Details

#initialize(config = {}) ⇒ HybridStrategy

Initialize the hybrid strategy

Parameters:

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

    Configuration options

Options Hash (config):

  • :mode (Symbol) — default: :adaptive

    Strategy mode - :adaptive or :combined

  • :sliding_window (Hash) — default: {}

    Configuration for SlidingWindowStrategy

  • :relevance_based (Hash) — default: {}

    Configuration for RelevanceBasedStrategy

  • :summary_based (Hash) — default: {}

    Configuration for SummaryBasedStrategy

  • :adaptive_threshold_low (Integer) — default: 20

    Message count threshold for adaptive mode (low)

  • :adaptive_threshold_high (Integer) — default: 50

    Message count threshold for adaptive mode (high)



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/smart_prompt/hybrid_strategy.rb', line 34

def initialize(config = {})
  @mode = config[:mode] || :adaptive
  @adaptive_threshold_low = config[:adaptive_threshold_low] || 20
  @adaptive_threshold_high = config[:adaptive_threshold_high] || 50

  # Initialize sub-strategies with their configurations
  @sliding_window = SlidingWindowStrategy.new(config[:sliding_window] || {})
  @relevance_based = RelevanceBasedStrategy.new(config[:relevance_based] || {})
  @summary_based = SummaryBasedStrategy.new(config[:summary_based] || {})

  # Validate mode
  unless [:adaptive, :combined].include?(@mode)
    raise ArgumentError, "Invalid mode: #{@mode}. Must be :adaptive or :combined"
  end
end

Instance Method Details

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

Select messages using hybrid 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)

    The current message for relevance calculation

Returns:

  • (Array<Message>)

    Selected messages



55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/smart_prompt/hybrid_strategy.rb', line 55

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

  case @mode
  when :adaptive
    select_adaptive(messages, max_tokens, current_message)
  when :combined
    select_combined(messages, max_tokens, current_message)
  else
    # Fallback to sliding window if mode is somehow invalid
    @sliding_window.select_messages(messages, max_tokens, current_message)
  end
end

#should_compress?(session) ⇒ Boolean

Determine if compression should be triggered Uses the most conservative threshold from all strategies

Parameters:

  • session (Session)

    The session to evaluate

Returns:

  • (Boolean)

    true if any strategy recommends compression



73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/smart_prompt/hybrid_strategy.rb', line 73

def should_compress?(session)
  return false if session.nil?
  
  # In adaptive mode, use the threshold of the currently selected strategy
  if @mode == :adaptive
    message_count = session.message_count
    
    if message_count < @adaptive_threshold_low
      @sliding_window.should_compress?(session)
    elsif message_count < @adaptive_threshold_high
      @relevance_based.should_compress?(session)
    else
      @summary_based.should_compress?(session)
    end
  else
    # In combined mode, compress if any strategy recommends it
    @sliding_window.should_compress?(session) ||
      @relevance_based.should_compress?(session) ||
      @summary_based.should_compress?(session)
  end
end