> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/primeintellect-ai/verifiers/llms.txt
> Use this file to discover all available pages before exploring further.

# OpenAIChatCompletionsClient

> OpenAI Chat Completions API client implementation

The `OpenAIChatCompletionsClient` class provides a wrapper around the OpenAI Chat Completions API using the `AsyncOpenAI` client.

## Overview

This client implements the `Client` interface for OpenAI's Chat Completions API, handling:

* Message format conversion between Verifiers and OpenAI formats
* Tool/function calling support
* Reasoning content extraction (for models with reasoning capabilities)
* Audio input handling with automatic modality detection
* Token usage and logprobs parsing
* Context length error handling

## Type Aliases

```python theme={null}
OpenAIChatMessage = ChatCompletionMessageParam
OpenAIChatMessages = list[OpenAIChatMessage]
OpenAIChatResponse = ChatCompletion
OpenAITool = ChatCompletionToolParam
```

## Class Definition

```python theme={null}
class OpenAIChatCompletionsClient(
    Client[
        AsyncOpenAI,
        OpenAIChatMessages,
        OpenAIChatResponse,
        OpenAITool,
    ]
)
```

Generic type parameters:

* **ClientT**: `AsyncOpenAI` - The OpenAI async client
* **MessagesT**: `OpenAIChatMessages` - List of OpenAI message parameters
* **ResponseT**: `OpenAIChatResponse` - OpenAI ChatCompletion object
* **ToolT**: `OpenAITool` - OpenAI tool parameter type

## Constructor

```python theme={null}
OpenAIChatCompletionsClient(client_or_config: AsyncOpenAI | ClientConfig)
```

<ParamField path="client_or_config" type="AsyncOpenAI | ClientConfig" required>
  Either a pre-configured `AsyncOpenAI` client or a `ClientConfig` to create one.
</ParamField>

### Example

```python theme={null}
from verifiers.clients.openai_chat_completions_client import OpenAIChatCompletionsClient
from verifiers.types import ClientConfig

# Using ClientConfig
client = OpenAIChatCompletionsClient(
    ClientConfig(
        api_key="sk-...",
        base_url="https://api.openai.com/v1"
    )
)

# Using pre-configured AsyncOpenAI client
from openai import AsyncOpenAI
client = OpenAIChatCompletionsClient(
    AsyncOpenAI(api_key="sk-...", base_url="https://api.openai.com/v1")
)
```

## Methods

### setup\_client

```python theme={null}
def setup_client(self, config: ClientConfig) -> AsyncOpenAI
```

Creates an `AsyncOpenAI` client from a `ClientConfig`.

<ParamField path="config" type="ClientConfig" required>
  Configuration with API key, base URL, and other settings.
</ParamField>

**Returns:** Configured `AsyncOpenAI` instance.

### close

```python theme={null}
async def close(self) -> None
```

Closes the underlying `AsyncOpenAI` client connection.

### to\_native\_prompt

```python theme={null}
async def to_native_prompt(
    self, messages: Messages
) -> tuple[OpenAIChatMessages, dict]
```

Converts Verifiers messages to OpenAI's chat completion format.

<ParamField path="messages" type="Messages" required>
  List of Verifiers message objects (`SystemMessage`, `UserMessage`, `AssistantMessage`, `ToolMessage`, or `TextMessage`).
</ParamField>

**Returns:** Tuple of `(openai_messages, extra_kwargs)`. The `extra_kwargs` dict is currently empty.

**Supported message types:**

* `SystemMessage` → `ChatCompletionSystemMessageParam`
* `UserMessage` → `ChatCompletionUserMessageParam`
* `AssistantMessage` → `ChatCompletionAssistantMessageParam` (with tool calls if present)
* `ToolMessage` → `ChatCompletionToolMessageParam`
* `TextMessage` → `ChatCompletionUserMessageParam`

### to\_native\_tool

```python theme={null}
async def to_native_tool(self, tool: Tool) -> OpenAITool
```

Converts a Verifiers `Tool` to OpenAI's tool parameter format.

<ParamField path="tool" type="Tool" required>
  Verifiers tool definition with name, description, parameters, and optional strict mode.
</ParamField>

**Returns:** `ChatCompletionToolParam` with type="function".

### get\_native\_response

```python theme={null}
@handle_openai_overlong_prompt
async def get_native_response(
    self,
    prompt: OpenAIChatMessages,
    model: str,
    sampling_args: SamplingArgs,
    tools: list[OpenAITool] | None = None,
    **kwargs
) -> OpenAIChatResponse
```

Calls the OpenAI Chat Completions API and returns the native response.

<ParamField path="prompt" type="OpenAIChatMessages" required>
  List of OpenAI message parameters.
</ParamField>

<ParamField path="model" type="str" required>
  OpenAI model identifier (e.g., `"gpt-4"`, `"gpt-4o-mini"`, `"o1-preview"`).
</ParamField>

<ParamField path="sampling_args" type="SamplingArgs" required>
  Sampling parameters. `max_tokens` is automatically renamed to `max_completion_tokens` for the API.
</ParamField>

<ParamField path="tools" type="list[OpenAITool] | None" default="None">
  Optional list of tools in OpenAI format.
</ParamField>

**Returns:** OpenAI `ChatCompletion` object.

**Raises:** `OverlongPromptError` if the prompt exceeds the model's context length.

**Special handling:**

* Audio inputs: Automatically sets `modalities=["text"]` unless explicitly specified
* Sampling args: Converts `max_tokens` to `max_completion_tokens`, filters out None values

### raise\_from\_native\_response

```python theme={null}
async def raise_from_native_response(self, response: OpenAIChatResponse) -> None
```

Validates the OpenAI response and raises errors if invalid.

<ParamField path="response" type="OpenAIChatResponse" required>
  The OpenAI ChatCompletion response.
</ParamField>

**Raises:**

* `EmptyModelResponseError` if response is None, has no choices, or the message has no content/tool calls/reasoning
* `InvalidModelResponseError` if the response has more than 1 choice

### from\_native\_response

```python theme={null}
async def from_native_response(self, response: OpenAIChatResponse) -> Response
```

Converts an OpenAI `ChatCompletion` to a Verifiers `Response`.

<ParamField path="response" type="OpenAIChatResponse" required>
  The OpenAI ChatCompletion response.
</ParamField>

**Returns:** Verifiers `Response` object with:

* `id`: Response ID from OpenAI
* `created`: Timestamp from OpenAI
* `model`: Model name from response
* `usage`: Token counts (prompt, completion, total)
* `message`: Response message with content, tool calls, finish reason, and optional tokens/logprobs

**Parsed fields:**

* **Content**: Text content from the message
* **Reasoning content**: Extracted from provider-specific fields (`reasoning`, `reasoning_content`, or `reasoning_details`)
* **Tool calls**: Converted from OpenAI format to Verifiers `ToolCall` objects
* **Finish reason**: Mapped from OpenAI values (`"stop"`, `"length"`, `"tool_calls"`, or `None`)
* **Tokens**: If available, includes prompt IDs, completion IDs, masks, logprobs, and routed experts data

## Usage Example

```python theme={null}
import asyncio
from verifiers.clients.openai_chat_completions_client import OpenAIChatCompletionsClient
from verifiers.types import (
    ClientConfig,
    UserMessage,
    SamplingArgs,
    Tool,
)

async def main():
    # Initialize client
    client = OpenAIChatCompletionsClient(
        ClientConfig(api_key="sk-...")
    )
    
    # Simple message
    messages = [UserMessage(content="What is the capital of France?")]
    sampling_args = SamplingArgs(
        temperature=0.7,
        max_tokens=100
    )
    
    response = await client.get_response(
        prompt=messages,
        model="gpt-4",
        sampling_args=sampling_args
    )
    
    print(response.message.content)
    # "The capital of France is Paris."
    
    # With tools
    weather_tool = Tool(
        name="get_weather",
        description="Get the current weather in a location",
        parameters={
            "type": "object",
            "properties": {
                "location": {
                    "type": "string",
                    "description": "City name"
                }
            },
            "required": ["location"]
        }
    )
    
    messages = [UserMessage(content="What's the weather in Tokyo?")]
    response = await client.get_response(
        prompt=messages,
        model="gpt-4",
        sampling_args=sampling_args,
        tools=[weather_tool]
    )
    
    if response.message.tool_calls:
        for tool_call in response.message.tool_calls:
            print(f"Tool: {tool_call.name}")
            print(f"Arguments: {tool_call.arguments}")
    
    await client.close()

asyncio.run(main())
```

## Reasoning Content Support

The client automatically extracts reasoning content from models that support it. It checks the following fields in order:

1. `reasoning` (vLLM, Together AI, OpenRouter)
2. `reasoning_content` (DeepSeek, Qwen/DashScope, SGLang, Fireworks AI, Kimi/Moonshot)
3. `reasoning_details` (OpenRouter, MiniMax)

Reasoning content is available in `response.message.reasoning_content`.

## Error Handling

### Overlong Prompt Errors

The `@handle_openai_overlong_prompt` decorator catches `BadRequestError` and converts context length errors to `OverlongPromptError`. It detects phrases like:

* "this model's maximum context length is"
* "is longer than the model's context length"
* "prompt\_too\_long"
* "context length"

Authentication and permission errors are re-raised without wrapping.

## See Also

* [Client](/api/client) - Base client class
* [AnthropicMessagesClient](/api/anthropic-client) - Anthropic implementation
* [ClientConfig](/api/types#clientconfig) - Configuration type
* [Response](/api/types#response) - Response type
* [Tool](/api/types#tool) - Tool definition type
