Module: LlmGateway::Adapters::OpenAI::Responses::OptionMapper

Defined in:
lib/llm_gateway/adapters/openai/responses/option_mapper.rb

Constant Summary collapse

DEFAULT_MAX_OUTPUT_TOKENS =
20_480
VALID_REASONING_LEVELS =
%w[low medium high xhigh].freeze
VALID_OPTIONS =

Source: developers.openai.com/api/reference/resources/responses/methods/create/index.md API: OpenAI Responses Create; accessed 2026-05-18. Body parameters listed by the API reference: background, context_management, conversation, include, input, instructions, max_output_tokens, max_tool_calls, metadata, model, parallel_tool_calls, previous_response_id, prompt, prompt_cache_key, prompt_cache_retention, reasoning, safety_identifier, service_tier, store, stream, stream_options, temperature, text, tool_choice, tools, top_logprobs, top_p, truncation, user. This mapper intentionally excludes transcript/tool/system structural fields (input, instructions, tools) from option handling.

%i[
  background
  context_management
  conversation
  include
  max_output_tokens
  max_tool_calls
  metadata
  model
  parallel_tool_calls
  previous_response_id
  prompt
  prompt_cache_key
  prompt_cache_retention
  reasoning
  safety_identifier
  service_tier
  store
  stream
  stream_options
  temperature
  text
  tool_choice
  top_logprobs
  top_p
  truncation
  user
].freeze
MANAGED_OPTIONS =
%i[
  max_completion_tokens
  response_format
  cache_key
  cache_retention
].freeze

Class Method Summary collapse

Class Method Details

.map(options) ⇒ Object



60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/llm_gateway/adapters/openai/responses/option_mapper.rb', line 60

def map(options)
  mapped_options = options.reject { |key, _| MANAGED_OPTIONS.include?(key) }
  mapped_options[:max_output_tokens] = options[:max_completion_tokens] || options[:max_output_tokens] || DEFAULT_MAX_OUTPUT_TOKENS

  cache_key = options[:cache_key]
  mapped_options[:prompt_cache_key] = cache_key unless cache_key.nil?

  cache_retention = options[:cache_retention]
  mapped_options[:prompt_cache_retention] = normalize_cache_retention(cache_retention) \
    unless cache_retention.nil?

  if mapped_options[:prompt_cache_key] && !mapped_options[:prompt_cache_retention]
    mapped_options[:prompt_cache_retention] = normalize_cache_retention("short")
  end

  if cache_retention.to_s == "none"
    mapped_options.delete(:prompt_cache_key)
    mapped_options.delete(:prompt_cache_retention)
  end

  response_format = options[:response_format]
  mapped_options[:text] = text_with_response_format(mapped_options[:text], response_format) unless response_format.nil?

  reasoning = mapped_options.delete(:reasoning)
  mapped_options[:reasoning] = normalize_reasoning(reasoning) \
    unless reasoning.nil? || reasoning.to_s == "none"

  validate_options!(mapped_options)
  mapped_options
end

.normalize_cache_retention(cache_retention) ⇒ Object



100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/llm_gateway/adapters/openai/responses/option_mapper.rb', line 100

def normalize_cache_retention(cache_retention)
  case cache_retention.to_s
  when "short"
    "in_memory"
  when "long"
    "24h"
  when "none"
    nil
  else
    raise ArgumentError,
          "Invalid cache_retention '#{cache_retention}'. Use 'short', 'long', or 'none'."
  end
end

.normalize_reasoning(reasoning) ⇒ Object

Raises:

  • (ArgumentError)


114
115
116
117
118
119
# File 'lib/llm_gateway/adapters/openai/responses/option_mapper.rb', line 114

def normalize_reasoning(reasoning)
  effort = reasoning.to_s
  return { effort: effort, summary: "detailed" } if VALID_REASONING_LEVELS.include?(effort)

  raise ArgumentError, "Invalid reasoning '#{reasoning}'. Use 'none', 'low', 'medium', 'high', or 'xhigh'."
end

.text_with_response_format(text, response_format) ⇒ Object



121
122
123
124
125
# File 'lib/llm_gateway/adapters/openai/responses/option_mapper.rb', line 121

def text_with_response_format(text, response_format)
  text_options = text ? text.dup : {}
  text_options[:format] = response_format.is_a?(String) ? { type: response_format } : response_format
  text_options
end

.validate_options!(mapped_options) ⇒ Object

Raises:

  • (ArgumentError)


91
92
93
94
95
96
97
98
# File 'lib/llm_gateway/adapters/openai/responses/option_mapper.rb', line 91

def validate_options!(mapped_options)
  unknown_options = mapped_options.keys - VALID_OPTIONS
  return if unknown_options.empty?

  raise ArgumentError,
        "Unknown OpenAI Responses options: #{unknown_options.join(', ')}. " \
        "Valid options: #{VALID_OPTIONS.join(', ')}."
end