How aisuite's Unified Chat Completions API Handles Provider-Specific Parameter Mapping

aisuite maps provider-specific parameters by routing unified requests through provider classes that translate standard fields into vendor-native payloads, using namespaced custom_parameters for vendor-only options.

The andrewyng/aisuite library simplifies multi-provider AI development by exposing a single, provider-agnostic Chat Completions API. When you call this unified endpoint, aisuite handles the complexity of translating your request into the exact format each vendor requires—OpenAI, Anthropic, Google, and others. This article explains how the provider-specific parameter mapping works under the hood, using actual source paths and implementation patterns from the codebase.

The Unified Request Flow

Every call to the Chat Completions API follows a six-step pipeline that preserves consistency while accommodating vendor differences.

Step 1: Parse the Unified Schema

Requests enter the system as a ChatCompletionRequest object defined in aisuite/framework/message.py. This dataclass standardizes common fields across all providers: model, messages, temperature, max_tokens, and custom_parameters.

Step 2: Route to the Correct Provider

The dispatcher in aisuite/provider.py looks up the provider name (e.g., "openai", "anthropic") and instantiates the matching provider class—OpenAIProvider, AnthropicProvider, or similar.

Step 3: Map Parameters to Vendor Format

Each provider implements a parameter-conversion routine (conventionally named _map_chat_params) that builds the vendor's native payload. The mapper:

  • Copies common fields directly (model, messages, temperature, max_tokens)
  • Injects vendor-specific extensions only when present (e.g., OpenAI's logprobs, Anthropic's max_tokens_to_sample)

Here's the pattern from aisuite/providers/openai_provider.py:

def _map_chat_params(self, request):
    payload = {
        "model": request.model,
        "messages": request.messages,
        "temperature": request.temperature,
        "max_tokens": request.max_tokens,
    }
    # Apply any custom OpenAI-only fields

    ParameterMapper._apply_custom_parameters(
        payload, request.custom_parameters, provider="openai"
    )
    return payload

Step 4: Enforce Custom Parameter Namespacing

Vendor-only options are passed through custom_parameters as a namespaced dictionary. The shared utility ParameterMapper._apply_custom_parameters in aisuite/framework/parameter_mapper.py (lines 202-224) enforces this rule: only keys nested under the correct provider name are merged.

class ParameterMapper:
    @classmethod
    def _apply_custom_parameters(cls, params, custom_params, provider):
        if not custom_params:
            return
        if provider in custom_params:
            params.update(custom_params[provider])  # strict namespacing

This prevents accidental parameter leakage—an OpenAI-specific setting won't contaminate an Anthropic request.

Step 5: Execute the HTTP Request

The fully-converted payload is sent via the provider's request method using its native HTTP client (e.g., self.session.post(...) for OpenAI).

Step 6: Normalize the Response

Regardless of vendor format, the response is converted back to a unified ChatCompletionResponse defined in aisuite/framework/chat_completion_response.py. Your downstream code remains provider-agnostic.

Using Provider-Specific Parameters in Practice

To access vendor-only features, nest them under the provider key in custom_parameters:

from aisuite.client import AISuiteClient

client = AISuiteClient(provider="openai", api_key="...")
resp = client.chat.completions.create(
    model="gpt-4o-mini",
    messages=[{"role": "user", "content": "Explain quantum tunnelling"}],
    temperature=0.7,
    # OpenAI-specific: request log probabilities

    custom_parameters={"openai": {"logprobs": 5, "top_logprobs": 3}}
)

print(resp.choices[0].message.content)

Compare with Anthropic's equivalent:

client = AISuiteClient(provider="anthropic", api_key="...")
resp = client.chat.completions.create(
    model="claude-3-sonnet-20240229",
    messages=[{"role": "user", "content": "Explain quantum tunnelling"}],
    temperature=0.7,
    # Anthropic-specific: different parameter name for token limit

    custom_parameters={"anthropic": {"max_tokens_to_sample": 1024}}
)

Key Mapping Rules

Rule Implementation
Direct copy Common fields with identical names pass through unchanged
Conditional injection Vendor extensions added only if the unified request contains matching attributes
Strict namespacing custom_parameters keys filtered by provider name in ParameterMapper._apply_custom_parameters
Response normalization All providers return ChatCompletionResponse instances

Critical Source Files

File Role
aisuite/framework/message.py ChatCompletionRequest dataclass—unified input schema
aisuite/provider.py Provider selection and dispatch logic
aisuite/framework/parameter_mapper.py Shared ParameterMapper class for namespaced parameter merging
aisuite/providers/openai_provider.py OpenAI-specific mapping implementation (_map_chat_params)
aisuite/providers/anthropic_provider.py Anthropic-specific mapping (same pattern)
aisuite/framework/chat_completion_response.py Normalized output schema

Summary

  • aisuite's unified Chat Completions API accepts provider-agnostic requests through ChatCompletionRequest in aisuite/framework/message.py
  • Provider classes in aisuite/providers/ handle vendor-specific translation via _map_chat_params methods
  • Namespaced custom_parameters let you access vendor-only features safely; ParameterMapper._apply_custom_parameters enforces isolation
  • All responses normalize to ChatCompletionResponse, keeping downstream code decoupled from provider specifics

Frequently Asked Questions

What happens if I put a custom parameter in the wrong namespace?

The parameter is ignored. ParameterMapper._apply_custom_parameters only merges keys that match the active provider name. An {"openai": {...}} block has no effect when using provider="anthropic", preventing silent errors from parameter misrouting.

Can I use the same custom_parameters dict for multiple providers in one call?

No—each call targets one provider. The AISuiteClient is initialized with a specific provider, and custom_parameters is evaluated per-request against that provider's namespace. For multi-provider workflows, create separate client instances or change the provider between calls.

Does aisuite validate that provider-specific parameters are valid for the vendor?

No pre-flight validation occurs aisuite-side. The library faithfully passes your namespaced parameters to the vendor's API. Invalid parameters will surface as errors from the provider's HTTP endpoint (e.g., 400 Bad Request from OpenAI). This design keeps aisuite lightweight and avoids maintaining per-vendor validation schemas.

How do I discover which custom parameters a provider supports?

Consult the vendor's official API documentation directly. aisuite does not wrap or restrict provider-specific options—anything valid in the native API can be passed through the corresponding namespace in custom_parameters. For OpenAI, check the OpenAI API reference; for Anthropic, see the Anthropic Messages API.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →