AIR

Quick start

This example configures two providers and sends one request. AIR tries them in priority order and falls back automatically if the first one fails.

python
import asyncio
import os
 
from air import AIR
from air.providers.xai import XAIProvider
from air.providers.gemini import GeminiProvider
 
 
async def main():
    air = AIR()
 
    air.add_provider(
        XAIProvider(api_key=os.environ["XAI_API_KEY"], model="grok-4-0709"),
        priority=1,
    )
    air.add_provider(
        GeminiProvider(api_key=os.environ["GEMINI_API_KEY"], model="gemini-2.5-flash"),
        priority=2,
    )
 
    response = await air.chat("Hello")
    print(response.content)
    print(response.provider, response.model)
 
 
asyncio.run(main())

air.chat(...) accepts either a plain string, which becomes a single user message, or a ChatRequest for more control over model, temperature, max_tokens, and other fields. See reference/models.md.

Adding a provider

add_provider(provider, priority=None, limits=None, capabilities=None):

  • provider is an instance of a class implementing air.providers.base.Provider (any of the four built in providers, or your own).
  • priority is an integer. Lower numbers are tried first. If omitted, AIR assigns the next unused priority in registration order.
  • limits is an optional dict such as {"tokens": 100_000, "reserve": 5_000}. See features/capacity-tracking.md.
  • capabilities is an optional dict such as {"coding": True, "context_tokens": 128_000}, used only by intelligent routing. See features/intelligent-routing.md.

Registering the same provider name twice raises ProviderAlreadyRegisteredError.

Sending a request

await air.chat(request) where request is a str or a ChatRequest. It returns a ChatResponse with the answer, which provider and model produced it, and routing metadata. See reference/air.md and reference/models.md.

Next steps