AIR

Providers

A provider is anything implementing air.providers.base.Provider:

python
from abc import ABC, abstractmethod
from air.models import ChatRequest, ChatResponse
 
 
class Provider(ABC):
    name: str
 
    @abstractmethod
    async def chat(self, request: ChatRequest) -> ChatResponse:
        ...

name is a class level string identifying the provider (for example "xai", "gemini", "groq", "openrouter"). It is used as the registration key in AIR.add_provider(...), in routing/event/health tracking, and as the value of ChatResponse.provider.

chat(request) must be an async method that takes a ChatRequest and returns a ChatResponse, or raises one of the exceptions described in reference/exceptions.md.

Registering a provider

python
air.add_provider(my_provider, priority=1, limits={"tokens": 50_000}, capabilities={"coding": True})

See reference/air.md for the full add_provider signature.

Built in providers

AIR currently ships four provider adapters, all built on httpx:

Each one takes an api_key and a model string, converts AIR's provider independent ChatRequest/Message format into that provider's request shape, sends the HTTPS request, converts the response back into a ChatResponse, and classifies any error into AIR's exception hierarchy. None of them read API keys from environment variables themselves; you read the key from wherever you like (environment variable, secret manager, etc.) and pass it to the constructor.

Writing your own provider

Implement Provider, give it a unique name, and make chat(...) return a ChatResponse (or raise the appropriate exception). AIR core has no provider specific logic; it only depends on this interface.

python
from air.providers.base import Provider
from air.models import ChatRequest, ChatResponse
 
 
class EchoProvider(Provider):
    name = "echo"
 
    async def chat(self, request: ChatRequest) -> ChatResponse:
        last = request.messages[-1].content
        return ChatResponse(content=f"echo: {last}", provider=self.name, model="echo-model")