Module: Ace::Review::Atoms::ContextLimitResolver

Defined in:
lib/ace/review/atoms/context_limit_resolver.rb

Overview

Pure function for resolving model context limits

Maps model names to their context window sizes. Handles provider prefixes (google:, anthropic:, openai:) and uses pattern matching for model families.

Resolution order:

  1. ace-llm provider config (context_limit in providers/*.yml)

  2. Hardcoded pattern matching (MODEL_LIMITS)

  3. Conservative default for unknown models

Examples:

Basic usage

ContextLimitResolver.resolve("google:gemini-2.5-pro")
#=> 1_000_000

Without provider prefix

ContextLimitResolver.resolve("claude-3-sonnet")
#=> 200_000

Constant Summary collapse

DEFAULT_LIMIT =

Conservative default for unknown models

200_000
MODEL_LIMITS =

Model patterns and their context limits (fallback when ace-llm config unavailable) Order matters - first match wins Patterns use regex for flexible matching

[
  # Gemini models
  {pattern: /gemini-1\.5-pro/i, limit: 2_000_000},
  {pattern: /gemini-1\.5-flash/i, limit: 1_000_000},
  {pattern: /gemini-2\.5-pro/i, limit: 1_000_000},
  {pattern: /gemini-2\.5-flash/i, limit: 1_000_000},
  {pattern: /gemini-2\.0/i, limit: 1_000_000},
  # Fallback for any other gemini model
  {pattern: /gemini/i, limit: 1_000_000},

  # Claude models (all variants: opus, sonnet, haiku)
  {pattern: /claude.*opus/i, limit: 1_000_000},
  {pattern: /claude.*sonnet/i, limit: 1_000_000},
  {pattern: /claude.*haiku/i, limit: 1_000_000},
  # Fallback for any other claude model
  {pattern: /claude/i, limit: 1_000_000},

  # OpenAI models
  {pattern: /gpt-5\.\d/i, limit: 1_050_000},
  {pattern: /o4-/i, limit: 1_050_000},
  {pattern: /gpt-4o/i, limit: 128_000},
  {pattern: /gpt-4-turbo/i, limit: 128_000},
  {pattern: /gpt-4-32k/i, limit: 32_768},
  {pattern: /gpt-4-\d+-preview/i, limit: 128_000}, # gpt-4-1106-preview, gpt-4-0125-preview
  {pattern: /gpt-4-\d+$/i, limit: 8_192}, # legacy gpt-4-0613, etc.
  {pattern: /gpt-4$/i, limit: 8_192}, # base gpt-4 model
  {pattern: /o1-/i, limit: 200_000},
  {pattern: /o3-/i, limit: 200_000}
].freeze

Class Method Summary collapse

Class Method Details

.default_limitInteger

Get the default limit for unknown models

Returns:

  • (Integer)

    Default context limit



97
98
99
# File 'lib/ace/review/atoms/context_limit_resolver.rb', line 97

def self.default_limit
  DEFAULT_LIMIT
end

.resolve(model_name) ⇒ Integer

Resolve context limit for a model

Resolution order:

  1. ace-llm provider config (if available and provider specified)

  2. Hardcoded pattern matching

  3. Default limit

Examples:

With provider prefix

ContextLimitResolver.resolve("google:gemini-2.5-pro")
#=> 1_000_000

Without provider prefix

ContextLimitResolver.resolve("claude-3-opus")
#=> 200_000

Unknown model

ContextLimitResolver.resolve("unknown-model")
#=> 128_000

Parameters:

  • model_name (String, nil)

    Model identifier, optionally with provider prefix

Returns:

  • (Integer)

    Context limit in tokens



81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/ace/review/atoms/context_limit_resolver.rb', line 81

def self.resolve(model_name)
  return DEFAULT_LIMIT if model_name.nil? || model_name.empty?

  # Try to get limit from ace-llm provider config first
  limit = load_from_ace_llm(model_name)
  return limit if limit

  # Fall back to hardcoded pattern matching
  normalized = strip_provider_prefix(model_name)
  match = MODEL_LIMITS.find { |entry| normalized.match?(entry[:pattern]) }
  match ? match[:limit] : DEFAULT_LIMIT
end