module RubyLLM::Providers::OpenAI::Capabilities
Provider-level capability checks and narrow registry fallbacks.
Constants
- MODEL_PATTERNS
- NIL_LIMIT_FAMILIES
- PRICES
Public Class Methods
# File lib/ruby_llm/providers/openai/capabilities.rb, line 224 def cached_input_price_for(model_id) return family_prices(model_id).dig(:text, :cached_input) if image_model?(model_id) family = model_family(model_id).to_sym PRICES.fetch(family, {})[:cached_input] end
# File lib/ruby_llm/providers/openai/capabilities.rb, line 117 def context_window_for(model_id) family = model_family(model_id) return nil if NIL_LIMIT_FAMILIES.include?(family) case family when 'gpt41', 'gpt41_mini', 'gpt41_nano' then 1_047_576 when 'gpt5', 'gpt5_mini', 'gpt5_nano', 'gpt4_turbo', 'gpt4o', 'gpt4o_audio', 'gpt4o_mini', 'gpt4o_mini_audio', 'gpt4o_mini_realtime', 'gpt4o_realtime', 'gpt4o_search', 'gpt4o_transcribe', 'o1_mini' then 128_000 when 'gpt4' then 8_192 when 'gpt4o_mini_transcribe' then 16_000 when 'o1', 'o1_pro', 'o3_mini' then 200_000 when 'gpt35_turbo' then 16_385 else 4_096 end end
# File lib/ruby_llm/providers/openai/capabilities.rb, line 150 def critical_capabilities_for(model_id) capabilities = [] capabilities << 'function_calling' if supports_functions?(model_id) capabilities << 'structured_output' if supports_structured_output?(model_id) capabilities << 'vision' if supports_vision?(model_id) capabilities << 'reasoning' if model_id.match?(/o\d|gpt-5|codex/) capabilities end
Source
# File lib/ruby_llm/providers/openai/capabilities.rb, line 261 def family_prices(model_id) family = model_family(model_id).to_sym PRICES.fetch(family, {}) end
Source
# File lib/ruby_llm/providers/openai/capabilities.rb, line 231 def image_model?(model_id) %w[gpt_image gpt_image_mini gpt_image15].include?(model_family(model_id)) end
Source
# File lib/ruby_llm/providers/openai/capabilities.rb, line 235 def image_pricing_for(model_id) text_pricing = { input_per_million: input_price_for(model_id) } cached_text_price = cached_input_price_for(model_id) text_pricing[:cache_read_input_per_million] = cached_text_price if cached_text_price image_pricing = { input_per_million: family_prices(model_id).dig(:images, :input), output_per_million: family_prices(model_id).dig(:images, :output) } cached_image_price = family_prices(model_id).dig(:images, :cached_input) image_pricing[:cache_read_input_per_million] = cached_image_price if cached_image_price { text_tokens: { standard: text_pricing }, images: { standard: image_pricing } } end
Source
# File lib/ruby_llm/providers/openai/capabilities.rb, line 212 def input_price_for(model_id) return family_prices(model_id).dig(:text, :input) if image_model?(model_id) price_for(model_id, :input, 0.50) end
Source
# File lib/ruby_llm/providers/openai/capabilities.rb, line 134 def max_tokens_for(model_id) family = model_family(model_id) return nil if NIL_LIMIT_FAMILIES.include?(family) case family when 'gpt5', 'gpt5_mini', 'gpt5_nano' then 400_000 when 'gpt41', 'gpt41_mini', 'gpt41_nano' then 32_768 when 'gpt4' then 8_192 when 'gpt35_turbo' then 4_096 when 'gpt4o_mini_transcribe' then 2_000 when 'o1', 'o1_pro', 'o3_mini' then 100_000 when 'o1_mini' then 65_536 else 16_384 end end
Source
# File lib/ruby_llm/providers/openai/capabilities.rb, line 173 def model_family(model_id) MODEL_PATTERNS.each do |family, pattern| return family.to_s if model_id.match?(pattern) end 'other' end
Source
# File lib/ruby_llm/providers/openai/capabilities.rb, line 218 def output_price_for(model_id) return family_prices(model_id).dig(:text, :output) if image_model?(model_id) price_for(model_id, :output, 1.50) end
# File lib/ruby_llm/providers/openai/capabilities.rb, line 255 def price_for(model_id, key, fallback) prices = family_prices(model_id) prices = { key => fallback } if prices.empty? prices[key] || prices[:price] || fallback end
Source
# File lib/ruby_llm/providers/openai/capabilities.rb, line 159 def pricing_for(model_id) return image_pricing_for(model_id) if image_model?(model_id) standard_pricing = { input_per_million: input_price_for(model_id), output_per_million: output_price_for(model_id) } cached_price = cached_input_price_for(model_id) standard_pricing[:cache_read_input_per_million] = cached_price if cached_price { text_tokens: { standard: standard_pricing } } end
# File lib/ruby_llm/providers/openai/capabilities.rb, line 192 def supports_functions?(model_id) case model_family(model_id) when 'gpt5', 'gpt5_mini', 'gpt5_nano', 'gpt41', 'gpt41_mini', 'gpt41_nano', 'gpt4', 'gpt4_turbo', 'gpt4o', 'gpt4o_mini', 'o1', 'o1_pro', 'o3_mini' true else false end end
# File lib/ruby_llm/providers/openai/capabilities.rb, line 202 def supports_structured_output?(model_id) case model_family(model_id) when 'gpt5', 'gpt5_mini', 'gpt5_nano', 'gpt41', 'gpt41_mini', 'gpt41_nano', 'gpt4o', 'gpt4o_mini', 'o1', 'o1_pro', 'o3_mini' true else false end end
Source
# File lib/ruby_llm/providers/openai/capabilities.rb, line 181 def supports_vision?(model_id) case model_family(model_id) when 'gpt_image', 'gpt_image_mini', 'gpt_image15', 'gpt5', 'gpt5_mini', 'gpt5_nano', 'gpt41', 'gpt41_mini', 'gpt41_nano', 'gpt4', 'gpt4_turbo', 'gpt4o', 'gpt4o_mini', 'o1', 'o1_pro', 'moderation', 'gpt4o_search' true else false end end
Public Instance Methods
# File lib/ruby_llm/providers/openai/capabilities.rb, line 109 def supports_tool_choice?(_model_id) true end
# File lib/ruby_llm/providers/openai/capabilities.rb, line 113 def supports_tool_parallel_control?(_model_id) true end