# `ReqLLM.Providers.OpenAI.AdapterHelpers`
[🔗](https://github.com/agentjido/req_llm/blob/main/lib/req_llm/providers/openai/adapter_helpers.ex#L1)

Shared helper functions for OpenAI-compatible model adapters (Azure, etc.).

These functions handle OpenAI-specific request formatting that is shared
across providers hosting OpenAI models.

# `add_parallel_tool_calls`

```elixir
@spec add_parallel_tool_calls(map(), keyword(), keyword()) :: map()
```

Adds parallel_tool_calls option to the request body.

Checks multiple option sources for the value:
- `opts[:parallel_tool_calls]`
- `provider_opts[:openai_parallel_tool_calls]`
- `provider_opts[:parallel_tool_calls]`

# `add_response_format`

```elixir
@spec add_response_format(map(), keyword()) :: map()
```

Adds response_format to the request body with schema normalization.

Handles json_schema response formats by converting ReqLLM schema DSL
to JSON Schema format and enforcing strict OpenAI JSON Schema requirements
when `strict: true` is set. Supports both atom and string key maps.

# `add_strict_to_tools`

```elixir
@spec add_strict_to_tools(map()) :: map()
```

Adds strict mode settings to tools that have `strict: true` on their function.

For tools with strict mode enabled:
- Sets `additionalProperties: false` on the parameters schema
- Makes all properties required

# `add_token_limits`

```elixir
@spec add_token_limits(map(), String.t(), keyword()) :: map()
```

Adds appropriate token limit parameters based on model type.

For reasoning models (o1, o3, o4, gpt-5):
- Uses `max_completion_tokens` instead of `max_tokens`
- Falls back to `max_tokens` value if `max_completion_tokens` not specified

For standard models:
- Uses `max_tokens` and optionally `max_completion_tokens`

Cleans up any existing token limit keys to ensure consistent state.

# `codex_model?`

```elixir
@spec codex_model?(term()) :: boolean()
```

Checks if model is a Codex model (codex-mini, gpt-5-codex, etc.).

# `deepseek_model?`

```elixir
@spec deepseek_model?(term()) :: boolean()
```

Checks if model is a DeepSeek model.

# `ensure_all_properties_required`

```elixir
@spec ensure_all_properties_required(map()) :: map()
```

Ensures all properties in a function's parameters schema are required.

Also sets `additionalProperties: false` for strict JSON schema compliance.

# `gpt4o_model?`

```elixir
@spec gpt4o_model?(term()) :: boolean()
```

Checks if model is a GPT-4o family model.

# `gpt5_model?`

```elixir
@spec gpt5_model?(term()) :: boolean()
```

Checks if model is a GPT-5 reasoning model (excludes gpt-5-chat-latest).

# `gpt5_pro_model?`

```elixir
@spec gpt5_pro_model?(term()) :: boolean()
```

Checks if model is a GPT-5 Pro model.

# `gpt6_astra_model?`

```elixir
@spec gpt6_astra_model?(term()) :: boolean()
```

Checks if model is a GPT-6 Astra reasoning model.

# `gpt6_model?`

```elixir
@spec gpt6_model?(term()) :: boolean()
```

Checks if a model is in the GPT-6 reasoning family.

# `gpt41_model?`

```elixir
@spec gpt41_model?(term()) :: boolean()
```

Checks if model is a GPT-4.1 model.

# `o_series_model?`

```elixir
@spec o_series_model?(term()) :: boolean()
```

Checks if model is an o-series reasoning model (o1, o3, o4).

# `reasoning_model?`

```elixir
@spec reasoning_model?(term()) :: boolean()
```

Checks if a model ID corresponds to an OpenAI reasoning model.

Reasoning models (o-series, gpt-5, gpt-6-astra, codex) require special handling:
- Use `max_completion_tokens` instead of `max_tokens`
- Support `reasoning_effort` parameter

Note: gpt-5-chat-latest is a non-reasoning variant that uses standard conventions.

# `required_reasoning_model?`

```elixir
@spec required_reasoning_model?(term()) :: boolean()
```

Checks if a GPT-6 model requires a nonzero reasoning effort.

# `responses_model?`

```elixir
@spec responses_model?(term()) :: boolean()
```

Checks if a model ID should default to the Responses API.

This includes reasoning/codex families plus GPT-4.1 and GPT-4o models, which
support Responses even when older metadata has not been updated yet.

Search-preview models are excluded: OpenAI serves them only on Chat
Completions, so inferring Responses for them yields a 404.

# `search_preview_model?`

```elixir
@spec search_preview_model?(term()) :: boolean()
```

Checks if a model ID is an OpenAI `*-search-preview` model.

These models are Chat Completions only, and enable web search through the
`web_search_options` body field rather than a tool entry.

# `translate_tool_choice_format`

```elixir
@spec translate_tool_choice_format(map()) :: map()
```

Translates ReqLLM's tool_choice format to OpenAI's function format.

ReqLLM uses `%{type: "tool", name: "tool_name"}` for specific tool selection.
OpenAI requires `%{type: "function", function: %{name: "tool_name"}}`.

Handles both atom and string key maps.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
