AIR

Example: TTS announcements

python
import asyncio
 
from air import AIR, ChatRequest, ChatResponse, Provider
from air.exceptions import RateLimitError
 
 
class FlakyProvider(Provider):
    name = "flaky"
 
    async def chat(self, request: ChatRequest) -> ChatResponse:
        raise RateLimitError("simulated rate limit", provider=self.name)
 
 
class BackupProvider(Provider):
    name = "backup"
 
    async def chat(self, request: ChatRequest) -> ChatResponse:
        return ChatResponse(content="ok", provider=self.name, model="demo")
 
 
class PrintBackend:
    """Minimal custom TTS backend: prints instead of speaking out loud."""
 
    def speak(self, text: str) -> None:
        print("(spoken):", text)
 
 
async def main():
    air = AIR()
    air.announcer.enable(events=["provider_switch"], backend=PrintBackend())
 
    air.add_provider(FlakyProvider(), priority=1)
    air.add_provider(BackupProvider(), priority=2)
 
    await air.chat("Hello")
 
 
if __name__ == "__main__":
    asyncio.run(main())

This uses a custom backend (PrintBackend) instead of SystemTTSBackend, so it runs the same way on any machine, including servers with no audio device. To use the built in desktop convenience backend instead, call air.announcer.enable(events=["provider_switch"]) without a backend argument; it will speak through say (macOS), espeak/espeak-ng (Linux), or System.Speech (Windows) if one is available, and silently do nothing if none is found. See ../features/tts.md.