Module: RubyLLM::Providers::OpenAIResponses::Capabilities

Defined in:
lib/ruby_llm/providers/openai_responses/capabilities.rb

Overview

Model capabilities for OpenAI Responses API models. Defines which models support which features.

Constant Summary collapse

RESPONSES_API_MODELS =

Models that support the Responses API

%w[
  gpt-5.5
  gpt-5.2 gpt-5.1 gpt-5.1-codex-max gpt-5.1-codex gpt-5.1-codex-mini gpt-5.1-chat
  gpt-5 gpt-5-pro gpt-5-mini gpt-5-nano
  gpt-4o gpt-4o-mini gpt-4o-2024-05-13 gpt-4o-2024-08-06 gpt-4o-2024-11-20
  gpt-4o-mini-2024-07-18
  gpt-4.1 gpt-4.1-mini gpt-4.1-nano
  gpt-4-turbo gpt-4-turbo-2024-04-09 gpt-4-turbo-preview
  o1 o1-mini o1-preview o1-2024-12-17
  o3 o3-mini o4-mini
  chatgpt-4o-latest
].freeze
VISION_MODELS =

Models with vision capabilities

%w[
  gpt-5.5
  gpt-5.2 gpt-5.1 gpt-5.1-chat gpt-5 gpt-5-pro gpt-5-mini gpt-5-nano
  gpt-4o gpt-4o-mini gpt-4o-2024-05-13 gpt-4o-2024-08-06 gpt-4o-2024-11-20
  gpt-4o-mini-2024-07-18
  gpt-4.1 gpt-4.1-mini gpt-4.1-nano
  gpt-4-turbo gpt-4-turbo-2024-04-09
  o1 o3 o4-mini
  chatgpt-4o-latest
].freeze
REASONING_MODELS =

Reasoning models (o-series)

%w[
  gpt-5.5 gpt-5.2 gpt-5.1 gpt-5.1-codex-max gpt-5.1-codex gpt-5.1-codex-mini
  gpt-5 gpt-5-pro gpt-5-mini gpt-5-nano
  o1 o1-mini o1-preview o1-2024-12-17 o3 o3-mini o4-mini
].freeze
WEB_SEARCH_MODELS =

Models that support web search

%w[
  gpt-5.5 gpt-5.2 gpt-5.1 gpt-5.1-codex-max gpt-5 gpt-5-pro gpt-5-mini
  gpt-4o gpt-4o-mini gpt-4.1 gpt-4.1-mini gpt-4.1-nano
  o1 o3 o3-mini o4-mini
].freeze
CODE_INTERPRETER_MODELS =

Models that support code interpreter

%w[
  gpt-5.5 gpt-5.2 gpt-5.1 gpt-5 gpt-5-pro gpt-5-mini
  gpt-4o gpt-4o-mini gpt-4.1 gpt-4.1-mini gpt-4.1-nano
  o1 o3 o3-mini o4-mini
].freeze
CONTEXT_WINDOWS =

Context windows by model

{
  'gpt-5.5' => 1_050_000,
  'gpt-5.2' => 400_000,
  'gpt-5.1' => 400_000,
  'gpt-5.1-codex-max' => 400_000,
  'gpt-5.1-codex' => 400_000,
  'gpt-5.1-codex-mini' => 400_000,
  'gpt-5.1-chat' => 128_000,
  'gpt-5' => 400_000,
  'gpt-5-pro' => 400_000,
  'gpt-5-mini' => 400_000,
  'gpt-5-nano' => 400_000,
  'gpt-4o' => 128_000,
  'gpt-4o-mini' => 128_000,
  'gpt-4o-2024-05-13' => 128_000,
  'gpt-4o-2024-08-06' => 128_000,
  'gpt-4o-2024-11-20' => 128_000,
  'gpt-4o-mini-2024-07-18' => 128_000,
  'gpt-4.1' => 1_000_000,
  'gpt-4.1-mini' => 1_000_000,
  'gpt-4.1-nano' => 1_000_000,
  'gpt-4-turbo' => 128_000,
  'gpt-4-turbo-2024-04-09' => 128_000,
  'o1' => 200_000,
  'o1-mini' => 128_000,
  'o1-preview' => 128_000,
  'o3' => 200_000,
  'o3-mini' => 200_000,
  'o4-mini' => 200_000
}.freeze
MAX_OUTPUT_TOKENS =

Max output tokens by model

{
  'gpt-5.5' => 128_000,
  'gpt-5.2' => 128_000,
  'gpt-5.1' => 128_000,
  'gpt-5.1-codex-max' => 128_000,
  'gpt-5.1-codex' => 128_000,
  'gpt-5.1-codex-mini' => 128_000,
  'gpt-5.1-chat' => 16_384,
  'gpt-5' => 128_000,
  'gpt-5-pro' => 128_000,
  'gpt-5-mini' => 128_000,
  'gpt-5-nano' => 128_000,
  'gpt-4o' => 16_384,
  'gpt-4o-mini' => 16_384,
  'gpt-4o-2024-05-13' => 4_096,
  'gpt-4o-2024-08-06' => 16_384,
  'gpt-4o-2024-11-20' => 16_384,
  'gpt-4o-mini-2024-07-18' => 16_384,
  'gpt-4.1' => 32_768,
  'gpt-4.1-mini' => 32_768,
  'gpt-4.1-nano' => 32_768,
  'gpt-4-turbo' => 4_096,
  'o1' => 100_000,
  'o1-mini' => 65_536,
  'o3' => 100_000,
  'o3-mini' => 100_000,
  'o4-mini' => 100_000
}.freeze
PRICING =

Pricing per million tokens (as of late 2024)

{
  'gpt-4o' => { input: 2.50, output: 10.00, cached_input: 1.25 },
  'gpt-4o-mini' => { input: 0.15, output: 0.60, cached_input: 0.075 },
  'gpt-4.1' => { input: 2.00, output: 8.00, cached_input: 0.50 },
  'gpt-4.1-mini' => { input: 0.40, output: 1.60, cached_input: 0.10 },
  'gpt-4.1-nano' => { input: 0.10, output: 0.40, cached_input: 0.025 },
  'o1' => { input: 15.00, output: 60.00, cached_input: 7.50 },
  'o1-mini' => { input: 1.10, output: 4.40, cached_input: 0.55 },
  'o3' => { input: 10.00, output: 40.00, cached_input: 2.50 },
  'o3-mini' => { input: 1.10, output: 4.40, cached_input: 0.275 },
  'o4-mini' => { input: 1.10, output: 4.40, cached_input: 0.275 }
}.freeze

Class Method Summary collapse

Class Method Details

.capabilities_for(model_id) ⇒ Object



203
204
205
206
207
208
209
210
# File 'lib/ruby_llm/providers/openai_responses/capabilities.rb', line 203

def capabilities_for(model_id)
  caps = %w[streaming function_calling structured_output]
  caps << 'vision' if supports_vision?(model_id)
  caps << 'web_search' if supports_web_search?(model_id)
  caps << 'code_interpreter' if supports_code_interpreter?(model_id)
  caps << 'reasoning' if reasoning_model?(model_id)
  caps
end

.context_window_for(model_id) ⇒ Object



162
163
164
# File 'lib/ruby_llm/providers/openai_responses/capabilities.rb', line 162

def context_window_for(model_id)
  find_capability(model_id, CONTEXT_WINDOWS) || 128_000
end

.format_display_name(model_id) ⇒ Object



229
230
231
232
233
234
235
# File 'lib/ruby_llm/providers/openai_responses/capabilities.rb', line 229

def format_display_name(model_id)
  model_id
    .gsub(/[-_]/, ' ')
    .split
    .map(&:capitalize)
    .join(' ')
end

.input_price_for(model_id) ⇒ Object



170
171
172
173
# File 'lib/ruby_llm/providers/openai_responses/capabilities.rb', line 170

def input_price_for(model_id)
  pricing = find_capability(model_id, PRICING)
  pricing ? pricing[:input] : 0.0
end

.max_tokens_for(model_id) ⇒ Object



166
167
168
# File 'lib/ruby_llm/providers/openai_responses/capabilities.rb', line 166

def max_tokens_for(model_id)
  find_capability(model_id, MAX_OUTPUT_TOKENS) || 16_384
end

.modalities_for(model_id) ⇒ Object



193
194
195
196
197
198
199
200
201
# File 'lib/ruby_llm/providers/openai_responses/capabilities.rb', line 193

def modalities_for(model_id)
  input = ['text']
  input << 'image' if supports_vision?(model_id)

  {
    input: input,
    output: ['text']
  }
end

.model_family(model_id) ⇒ Object



212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
# File 'lib/ruby_llm/providers/openai_responses/capabilities.rb', line 212

def model_family(model_id)
  case model_id
  when /^gpt-5\.5/ then 'gpt-5.5'
  when /^gpt-5\.2/ then 'gpt-5.2'
  when /^gpt-5\.1/ then 'gpt-5.1'
  when /^gpt-5/ then 'gpt-5'
  when /^gpt-4\.1/ then 'gpt-4.1'
  when /^gpt-4o-mini/ then 'gpt-4o-mini'
  when /^gpt-4o/ then 'gpt-4o'
  when /^gpt-4-turbo/ then 'gpt-4-turbo'
  when /^o1/ then 'o1'
  when /^o3/ then 'o3'
  when /^o4/ then 'o4'
  else 'other'
  end
end

.normalize_temperature(temperature, model_id) ⇒ Object

Temperature is not supported for reasoning models



238
239
240
241
242
# File 'lib/ruby_llm/providers/openai_responses/capabilities.rb', line 238

def normalize_temperature(temperature, model_id)
  return nil if reasoning_model?(model_id)

  temperature
end

.output_price_for(model_id) ⇒ Object



175
176
177
178
# File 'lib/ruby_llm/providers/openai_responses/capabilities.rb', line 175

def output_price_for(model_id)
  pricing = find_capability(model_id, PRICING)
  pricing ? pricing[:output] : 0.0
end

.pricing_for(model_id) ⇒ Object



180
181
182
183
184
185
186
187
188
189
190
191
# File 'lib/ruby_llm/providers/openai_responses/capabilities.rb', line 180

def pricing_for(model_id)
  pricing = find_capability(model_id, PRICING) || { input: 0.0, output: 0.0 }
  {
    text_tokens: {
      standard: {
        input_per_million: pricing[:input],
        output_per_million: pricing[:output],
        cached_input_per_million: pricing[:cached_input] || (pricing[:input] / 2)
      }
    }
  }
end

.reasoning_model?(model_id) ⇒ Boolean

Returns:

  • (Boolean)


158
159
160
# File 'lib/ruby_llm/providers/openai_responses/capabilities.rb', line 158

def reasoning_model?(model_id)
  model_matches?(model_id, REASONING_MODELS)
end

.supports_code_interpreter?(model_id) ⇒ Boolean

Returns:

  • (Boolean)


154
155
156
# File 'lib/ruby_llm/providers/openai_responses/capabilities.rb', line 154

def supports_code_interpreter?(model_id)
  model_matches?(model_id, CODE_INTERPRETER_MODELS)
end

.supports_functions?(model_id) ⇒ Boolean

Returns:

  • (Boolean)


142
143
144
# File 'lib/ruby_llm/providers/openai_responses/capabilities.rb', line 142

def supports_functions?(model_id)
  supports_responses_api?(model_id)
end

.supports_responses_api?(model_id) ⇒ Boolean

Returns:

  • (Boolean)


134
135
136
# File 'lib/ruby_llm/providers/openai_responses/capabilities.rb', line 134

def supports_responses_api?(model_id)
  model_matches?(model_id, RESPONSES_API_MODELS)
end

.supports_structured_output?(model_id) ⇒ Boolean

Returns:

  • (Boolean)


146
147
148
# File 'lib/ruby_llm/providers/openai_responses/capabilities.rb', line 146

def supports_structured_output?(model_id)
  supports_responses_api?(model_id)
end

.supports_vision?(model_id) ⇒ Boolean

Returns:

  • (Boolean)


138
139
140
# File 'lib/ruby_llm/providers/openai_responses/capabilities.rb', line 138

def supports_vision?(model_id)
  model_matches?(model_id, VISION_MODELS)
end

.supports_web_search?(model_id) ⇒ Boolean

Returns:

  • (Boolean)


150
151
152
# File 'lib/ruby_llm/providers/openai_responses/capabilities.rb', line 150

def supports_web_search?(model_id)
  model_matches?(model_id, WEB_SEARCH_MODELS)
end