# How aisuite Validates and Maps ASR Parameters: A Deep Dive into the ParamValidator Architecture

> Learn how aisuite validates and maps ASR parameters with its ParamValidator architecture. Discover its OpenAI-style translation, provider whitelists, and flexible handling of unknown parameters.

- Repository: [Andrew Ng/aisuite](https://github.com/andrewyng/aisuite)
- Tags: deep-dive
- Published: 2026-08-03

---

**aisuite validates and maps ASR parameters through a centralized `ParamValidator` class that translates OpenAI-style common parameters to provider-specific formats, enforces provider whitelists, and handles unknown parameters via configurable strict, warn, or permissive modes.**

The `aisuite` library by Andrew Ng provides a unified interface for multiple AI providers, including automatic speech recognition (ASR) services. Managing parameters across disparate transcription APIs—each with different naming conventions and value formats—requires a robust validation and mapping system. This article examines how `aisuite` implements this through the `ParamValidator` class in [`aisuite/framework/asr_params.py`](https://github.com/andrewyng/aisuite/blob/main/aisuite/framework/asr_params.py).

## The Three-Stage Validation Pipeline

The `ParamValidator` performs ASR parameter validation through three distinct stages. Understanding this pipeline is essential for configuring `aisuite` correctly and troubleshooting parameter-related issues.

### 1. Common-Parameter Mapping

Parameters following the OpenAI API convention are automatically translated to provider-specific keys using the **`COMMON_PARAMS`** dictionary. This ensures users can write provider-agnostic code while `aisuite` handles the translation.

The mapping works as follows:

- `"language"` → `"language_code"` for Google
- `"language"` → `"language"` for OpenAI and Deepgram (unchanged)
- `"prompt"` and `"temperature"` similarly mapped per provider

When a common parameter has no mapping for a specific provider, it is silently skipped.

### 2. Provider-Specific Validation

Each supported provider maintains a whitelist of additional parameters in **`PROVIDER_PARAMS`**. Parameters in this set pass through unchanged, allowing access to provider-specific features without translation layers.

### 3. Unknown-Parameter Handling

The validator's constructor accepts an **`extra_param_mode`** parameter controlling behavior for unrecognized parameters:

| Mode | Behavior |
|------|----------|
| **`strict`** | Raises `ValueError` immediately |
| **`warn`** | Emits `UserWarning` but discards the parameter |
| **`permissive`** | Forwards unknown parameters unchanged |

This configuration is typically set through the global configuration in [`aisuite/mcp/config.py`](https://github.com/andrewyng/aisuite/blob/main/aisuite/mcp/config.py).

## Core Implementation: The validate_and_map Method

The heart of the validation system is the `validate_and_map` method in [`aisuite/framework/asr_params.py`](https://github.com/andrewyng/aisuite/blob/main/aisuite/framework/asr_params.py):

```python
def validate_and_map(self, provider_key: str, params: Dict[str, Any]) -> Dict[str, Any]:
    result = {}
    unknown_params = []
    provider_params = PROVIDER_PARAMS.get(provider_key, set())

    for key, value in params.items():
        if key in COMMON_PARAMS:                       # 1️⃣ map common param

            mapped_key = COMMON_PARAMS[key].get(provider_key)
            if mapped_key is None:
                continue                               # provider does not support it

            result[mapped_key] = self._transform_value(provider_key, key, value)
        elif key in provider_params:                   # 2️⃣ accept provider‑specific

            result[key] = value
        else:                                          # 3️⃣ unknown param

            unknown_params.append(key)

    # post‑process unknowns according to mode

    if unknown_params:
        self._handle_unknown(provider_key, unknown_params)
        if self.extra_param_mode == "permissive":
            for key in unknown_params:
                result[key] = params[key]

    return result

```

This implementation prioritizes explicit handling: common parameters are transformed first, provider-specific parameters pass through, and only truly unknown parameters trigger mode-dependent behavior.

## Provider-Specific Value Transformations

Some ASR providers require value reshaping beyond simple key renaming. The private **`_transform_value`** method implements these transformations:

### Google Provider Transformations

| Parameter | Transformation |
|-----------|---------------|
| `language` | Expands two-letter codes using **`GOOGLE_LANGUAGE_MAP`** (e.g., `"en"` → `"en-US"`) |
| `prompt` | Wraps string in speech-context format: `[{ "phrases": [value] }]` |

### Deepgram Provider Transformations

| Parameter | Transformation |
|-----------|---------------|
| `prompt` | Splits string into keyword list: `"meeting notes"` → `["meeting", "notes"]` |

Parameters without defined transformations return unchanged.

## Unknown Parameter Handling Implementation

The **`_handle_unknown`** method enforces the configured strictness level:

```python
def _handle_unknown(self, provider_key: str, unknown_params: list):
    msg = (
        f"Unknown parameters for {provider_key}: {unknown_params}. "
        f"See {provider_key} documentation for valid parameters."
    )
    if self.extra_param_mode == "strict":
        raise ValueError(msg)
    elif self.extra_param_mode == "warn":
        import warnings
        warnings.warn(msg, UserWarning)
    # permissive: silent pass‑through

```

Note that in `permissive` mode, the method remains silent but the caller in `validate_and_map` actually forwards the parameters—this separates concern (notification vs. action) for cleaner code structure.

## Practical Code Examples

### Strict Mode: Fail Fast on Unknown Parameters

```python
from aisuite.framework.asr_params import ParamValidator

# Unknown parameters raise ValueError immediately

validator = ParamValidator(extra_param_mode="strict")
params = {"language": "en", "prompt": "meeting notes", "temperature": 0.3}
openai_payload = validator.validate_and_map("openai", params)

# → {'language': 'en', 'prompt': 'meeting notes', 'temperature': 0.3}

# This would raise: validator.validate_and_map("openai", {"unknown": True})

```

### Google: Automatic Mapping and Transformation

```python
google_payload = validator.validate_and_map("google", {"language": "en", "prompt": "tech talk"})

# → {

#     'language_code': 'en-US',

#     'speech_contexts': [{'phrases': ['tech talk']}]

#   }

```

The two-letter language code expands to region-qualified format, and the prompt becomes a structured speech context.

### Deepgram: Keyword Extraction from Prompt

```python
deepgram_payload = validator.validate_and_map(
    "deepgram",
    {"language": "en", "prompt": "meeting notes", "punctuate": True},
)

# → {

#     'language': 'en',

#     'keywords': ['meeting', 'notes'],

#     'punctuate': True

#   }

```

Provider-specific parameter `punctuate` passes through unchanged while `prompt` transforms to `keywords`.

### Permissive Mode: Experimental Parameter Support

```python
permissive = ParamValidator(extra_param_mode="permissive")
payload = permissive.validate_and_map("openai", {"experimental_feature": True})

# → {'experimental_feature': True}

```

Use this mode when testing beta features not yet in `aisuite`'s parameter dictionaries.

## Test Coverage and Validation

The test suite in **[`tests/framework/test_asr_params.py`](https://github.com/andrewyng/aisuite/blob/main/tests/framework/test_asr_params.py)** provides comprehensive verification:

- Correct mapping of common parameters per provider
- Provider-specific parameter pass-through
- Value transformation accuracy (Google language expansion, Deepgram keyword split, Google prompt wrapping)
- All three `extra_param_mode` behaviors
- Edge cases: empty input, unknown providers, `None` values

Running these tests ensures parameter handling remains consistent across `aisuite` updates.

## Key Source Files

| File | Purpose |
|------|---------|
| [`aisuite/framework/asr_params.py`](https://github.com/andrewyng/aisuite/blob/main/aisuite/framework/asr_params.py) | `ParamValidator` implementation, parameter maps, transformation logic |
| [`tests/framework/test_asr_params.py`](https://github.com/andrewyng/aisuite/blob/main/tests/framework/test_asr_params.py) | Unit tests for validation, mapping, and mode handling |
| [`aisuite/framework/provider_interface.py`](https://github.com/andrewyng/aisuite/blob/main/aisuite/framework/provider_interface.py) | Abstract contract receiving validated parameter dictionaries |
| [`aisuite/mcp/config.py`](https://github.com/andrewyng/aisuite/blob/main/aisuite/mcp/config.py) | Global configuration selecting `extra_param_mode` |

## Summary

- **`ParamValidator`** in [`aisuite/framework/asr_params.py`](https://github.com/andrewyng/aisuite/blob/main/aisuite/framework/asr_params.py) centralizes all ASR parameter handling
- **Three validation stages**: common-parameter mapping → provider-specific whitelist → unknown-parameter mode handling
- **Value transformations** adapt parameters for Google (language expansion, prompt wrapping) and Deepgram (keyword splitting)
- **`extra_param_mode`** (`strict`/`warn`/`permissive`) controls unknown parameter tolerance
- **Comprehensive tests** in [`tests/framework/test_asr_params.py`](https://github.com/andrewyng/aisuite/blob/main/tests/framework/test_asr_params.py) ensure reliability across providers

## Frequently Asked Questions

### How do I enable strict parameter validation in aisuite?

Initialize `ParamValidator` with `extra_param_mode="strict"` or configure it globally through [`aisuite/mcp/config.py`](https://github.com/andrewyng/aisuite/blob/main/aisuite/mcp/config.py). In strict mode, any parameter not in `COMMON_PARAMS` or the provider's `PROVIDER_PARAMS` whitelist raises `ValueError` immediately.

### Why does my Google ASR request use `language_code` instead of `language`?

`aisuite` automatically maps OpenAI-style `language` to Google's `language_code` through the `COMMON_PARAMS` dictionary. It also expands two-letter codes like `"en"` to `"en-US"` using `GOOGLE_LANGUAGE_MAP`. This translation happens in `_transform_value` without requiring manual intervention.

### Can I use provider-specific parameters that aisuite doesn't explicitly support?

Yes. Set `extra_param_mode="permissive"` to forward any unknown parameter unchanged, or use `extra_param_mode="warn"` to receive notifications while still discarding unsupported parameters. Provider-specific parameters already in `PROVIDER_PARAMS` for your provider pass through automatically regardless of mode.