Skip to main content
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

OpenAIChatMessage = ChatCompletionMessageParam
OpenAIChatMessages = list[OpenAIChatMessage]
OpenAIChatResponse = ChatCompletion
OpenAITool = ChatCompletionToolParam

Class Definition

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

OpenAIChatCompletionsClient(client_or_config: AsyncOpenAI | ClientConfig)
client_or_config
AsyncOpenAI | ClientConfig
required
Either a pre-configured AsyncOpenAI client or a ClientConfig to create one.

Example

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

def setup_client(self, config: ClientConfig) -> AsyncOpenAI
Creates an AsyncOpenAI client from a ClientConfig.
config
ClientConfig
required
Configuration with API key, base URL, and other settings.
Returns: Configured AsyncOpenAI instance.

close

async def close(self) -> None
Closes the underlying AsyncOpenAI client connection.

to_native_prompt

async def to_native_prompt(
    self, messages: Messages
) -> tuple[OpenAIChatMessages, dict]
Converts Verifiers messages to OpenAI’s chat completion format.
messages
Messages
required
List of Verifiers message objects (SystemMessage, UserMessage, AssistantMessage, ToolMessage, or TextMessage).
Returns: Tuple of (openai_messages, extra_kwargs). The extra_kwargs dict is currently empty. Supported message types:
  • SystemMessageChatCompletionSystemMessageParam
  • UserMessageChatCompletionUserMessageParam
  • AssistantMessageChatCompletionAssistantMessageParam (with tool calls if present)
  • ToolMessageChatCompletionToolMessageParam
  • TextMessageChatCompletionUserMessageParam

to_native_tool

async def to_native_tool(self, tool: Tool) -> OpenAITool
Converts a Verifiers Tool to OpenAI’s tool parameter format.
tool
Tool
required
Verifiers tool definition with name, description, parameters, and optional strict mode.
Returns: ChatCompletionToolParam with type=“function”.

get_native_response

@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.
prompt
OpenAIChatMessages
required
List of OpenAI message parameters.
model
str
required
OpenAI model identifier (e.g., "gpt-4", "gpt-4o-mini", "o1-preview").
sampling_args
SamplingArgs
required
Sampling parameters. max_tokens is automatically renamed to max_completion_tokens for the API.
tools
list[OpenAITool] | None
default:"None"
Optional list of tools in OpenAI format.
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

async def raise_from_native_response(self, response: OpenAIChatResponse) -> None
Validates the OpenAI response and raises errors if invalid.
response
OpenAIChatResponse
required
The OpenAI ChatCompletion response.
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

async def from_native_response(self, response: OpenAIChatResponse) -> Response
Converts an OpenAI ChatCompletion to a Verifiers Response.
response
OpenAIChatResponse
required
The OpenAI ChatCompletion response.
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

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

Build docs developers (and LLMs) love