Class: Ace::Review::Molecules::Strategies::AdaptiveStrategy

Inherits:
Object
  • Object
show all
Defined in:
lib/ace/review/molecules/strategies/adaptive_strategy.rb

Overview

Adaptive strategy - auto-selects full or chunked based on model capabilities

This strategy analyzes the subject size and model context limit to automatically select the most appropriate underlying strategy:

  • Full strategy when subject fits within model context (with headroom)

  • Chunked strategy when subject exceeds available context

Examples:

Basic usage

strategy = AdaptiveStrategy.new
units = strategy.prepare(subject, context)
# Automatically uses full or chunked based on size

With custom headroom

strategy = AdaptiveStrategy.new(headroom: 0.20)  # 20% headroom
units = strategy.prepare(subject, context)

Constant Summary collapse

DEFAULT_HEADROOM =

Default headroom percentage for system prompt and output

0.15

Instance Method Summary collapse

Constructor Details

#initialize(config = {}) ⇒ AdaptiveStrategy

Returns a new instance of AdaptiveStrategy.

Parameters:

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

    Strategy configuration

Options Hash (config):

  • :headroom (Float)

    Fraction to reserve (default: 0.15)

  • :max_tokens_per_chunk (Integer)

    Max tokens per chunk for chunked strategy

  • :include_change_summary (Boolean)

    Include file summary in chunks



35
36
37
38
39
40
# File 'lib/ace/review/molecules/strategies/adaptive_strategy.rb', line 35

def initialize(config = {})
  # Normalize keys to symbols for consistent access (supports YAML string keys)
  @config = normalize_config_keys(config)
  @headroom = @config[:headroom] || DEFAULT_HEADROOM
  @logger = @config[:logger]
end

Instance Method Details

#can_handle?(subject, model_context_limit) ⇒ Boolean

Check if this strategy can handle the given subject

Adaptive strategy can always handle any subject by delegating to the appropriate underlying strategy.

Parameters:

  • subject (String)

    The review subject text

  • model_context_limit (Integer)

    Model’s token limit

Returns:

  • (Boolean)

    Always returns true (can handle any subject)



50
51
52
53
54
55
# File 'lib/ace/review/molecules/strategies/adaptive_strategy.rb', line 50

def can_handle?(subject, model_context_limit)
  return false if subject.nil? || subject.empty?
  return false if model_context_limit.nil? || model_context_limit <= 0

  true
end

#prepare(subject, context = {}) ⇒ Array<Hash>

Prepare the subject for review by selecting and delegating to appropriate strategy

Analyzes the subject size against model context limit and selects:

  • FullStrategy if subject fits within available context

  • ChunkedStrategy if subject exceeds available context

Parameters:

  • subject (String)

    The review subject text

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

    Review context

Options Hash (context):

  • :model (String)

    Model identifier for context limit lookup

  • :model_context_limit (Integer)

    Explicit context limit (overrides model lookup)

Returns:

  • (Array<Hash>)

    Array of review units from selected strategy



68
69
70
71
72
73
74
75
76
77
78
# File 'lib/ace/review/molecules/strategies/adaptive_strategy.rb', line 68

def prepare(subject, context = {})
  model = context[:model] || context["model"]
  explicit_limit = context[:model_context_limit] || context["model_context_limit"]

  # Resolve model context limit
  model_limit = explicit_limit || Atoms::ContextLimitResolver.resolve(model)

  # Select and delegate to appropriate strategy
  selected = select_strategy(subject, model_limit, model)
  selected.prepare(subject, context)
end

#select_strategy(subject, model_limit, model = nil) ⇒ Object

Select the appropriate strategy based on subject size and model limit

Parameters:

  • subject (String)

    The review subject text

  • model_limit (Integer)

    Model’s context limit in tokens

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

    Model identifier for logging

Returns:

  • (Object)

    Strategy instance (FullStrategy or ChunkedStrategy)



93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/ace/review/molecules/strategies/adaptive_strategy.rb', line 93

def select_strategy(subject, model_limit, model = nil)
  estimated_tokens = Atoms::TokenEstimator.estimate(subject)
  available = (model_limit * (1 - @headroom)).to_i

  if estimated_tokens < available
    log_selection(
      model: model,
      subject_tokens: estimated_tokens,
      model_limit: model_limit,
      available: available,
      selected: :full,
      reason: "subject fits within available context"
    )
    build_full_strategy
  else
    log_selection(
      model: model,
      subject_tokens: estimated_tokens,
      model_limit: model_limit,
      available: available,
      selected: :chunked,
      reason: "subject exceeds available context"
    )
    build_chunked_strategy
  end
end

#strategy_nameSymbol

Strategy name for logging and debugging

Returns:

  • (Symbol)

    :adaptive



83
84
85
# File 'lib/ace/review/molecules/strategies/adaptive_strategy.rb', line 83

def strategy_name
  :adaptive
end