Current section
Files
Jump to
Current section
Files
lib/responses/internal.ex
defmodule OpenAI.Responses.Internal do
@moduledoc false
@default_model "gpt-4.1-mini"
@doc """
Prepare the payload for API requests.
Handles schema conversion and sets default model.
"""
def prepare_payload(options) do
# Normalize everything to maps with string keys
options = normalize_to_string_keys(options)
{schema, options} = Map.pop(options, "schema")
options =
if schema do
Map.put(options, "text", %{"format" => OpenAI.Responses.Schema.build_output(schema)})
else
options
end
Map.put_new(options, "model", @default_model)
end
# Normalize all input formats to maps with string keys
defp normalize_to_string_keys(options) when is_map(options) do
Map.new(options, fn {k, v} -> {to_string(k), normalize_value(v)} end)
end
defp normalize_to_string_keys(options) when is_list(options) do
options
|> Enum.map(fn
{k, v} -> {to_string(k), normalize_value(v)}
other -> raise ArgumentError, "Invalid option format: #{inspect(other)}"
end)
|> Map.new()
end
# Recursively normalize nested values
defp normalize_value(value) when is_map(value) do
normalize_to_string_keys(value)
end
defp normalize_value(value) when is_list(value) do
# Check if it's a keyword list (has at least one tuple)
if value != [] and is_tuple(hd(value)) do
# Try to convert as keyword list
try do
normalize_to_string_keys(value)
rescue
# If it fails, treat as regular list
ArgumentError -> Enum.map(value, &normalize_value/1)
end
else
# Regular list - keep as array
Enum.map(value, &normalize_value/1)
end
end
defp normalize_value(value), do: value
@doc """
Get the API key from application config or environment variable.
"""
def get_api_key() do
Application.get_env(:openai_responses, :openai_api_key) || System.fetch_env!("OPENAI_API_KEY")
end
end