AIR

Intelligent routing

Intelligent routing is opt in. Enable it with:

python
air = AIR(routing="intelligent")

or

python
from air.config import AIRConfig
air = AIR(config=AIRConfig(routing="intelligent"))

The default is routing="priority", which does not use any of the logic on this page.

What gets classified

air.routing.intelligent.classify_request(request) inspects the request and produces a RequestProfile(required, preferred, estimated_tokens) using deterministic keyword checks. No AI model is called to make this decision.

  • Required capability coding is added if any message contains ``` or one of def , class , function, stack trace, traceback, compile error (case insensitive).
  • Preferred capability reasoning is added if any message contains step by step, explain why, prove that, or walk through your reasoning (case insensitive).
  • Preferred capability speed is added if the estimated token count is under 200 and reasoning was not already added.
  • Anything in ChatRequest.requires (a set[str]) is added directly to the required set, letting you force capabilities like vision that the keyword rules do not detect.

Provider capabilities

Declare what a provider can do when you register it:

python
air.add_provider(
    gemini,
    capabilities={"coding": True, "vision": True, "context_tokens": 128_000, "speed": True},
)

capabilities fields (all optional, air.routing.capabilities.ProviderCapabilities):

  • reasoning: bool = False
  • coding: bool = False
  • vision: bool = False
  • tool_use: bool = False
  • speed: bool = False
  • context_tokens: int | None = None

If you never pass capabilities for a provider, it is treated as having none of these capabilities set, and will be skipped by intelligent routing for any request with required capabilities.

Selection

air.routing.intelligent.select_provider(ordered, states, profile) skips a provider if:

  • its health status is exhausted,
  • it is missing a required coding, vision, or tool_use capability,
  • its declared context_tokens is lower than the request's estimated tokens,
  • its known or estimated remaining capacity (see capacity-tracking.md) is lower than the request's estimated tokens.

Among the remaining candidates, it scores each one: one point per satisfied required capability, one point for reasoning if preferred and available, one point for speed if preferred and available, one point for available health status, and a note (not an extra point difference between known and estimated) for whether capacity is known or estimated rather than unknown. The highest scoring provider is picked; ties keep whichever appears first in priority order.

What happens after selection

The picked provider is moved to the front of the priority ordered list AIR would otherwise use. Normal fallback still applies: if the picked provider fails with a fallback eligible error, AIR proceeds to the next provider in priority order, same as plain priority routing. See core/fallback.md.

If no provider satisfies the required capabilities, intelligent routing does not pick anything, and AIR falls back to plain priority order for that request.

Selection reason

python
response = await air.chat(request)
print(response.selection_reason)

ChatResponse.selection_reason is a short human readable string (for example "coding capability, healthy, sufficient estimated capacity"), set only when intelligent routing's initial pick is the provider that actually produced the response. It is None in priority routing, and None if a different provider ended up answering after a fallback.