Providers
A provider is anything implementing air.providers.base.Provider:
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
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:
- xAI (Grok): providers/xai.md
- Google Gemini: providers/gemini.md
- Groq: providers/groq.md
- OpenRouter: providers/openrouter.md
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.
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")