ResilientModel wraps any model with automatic key rotation and provider failover. It handles rate limits (429) transparently.
Key Rotation
Distribute load across multiple API keys:
from definable.model.resilience import ResilientModel, KeyPool
from definable.model.openai import OpenAIChat
model = ResilientModel(
inner=OpenAIChat(id="gpt-4o"),
key_pool=KeyPool(
keys=["sk-key1", "sk-key2", "sk-key3"],
strategy="round_robin", # or "lru"
),
)
agent = Agent(model=model)
When a key gets rate-limited (HTTP 429), it enters cooldown with exponential backoff. The next key in the pool is used automatically.
Provider Failover
Fall back to alternative providers when one fails:
from definable.model.resilience import ResilientModel, FailoverChain, FailoverEntry
from definable.model.openai import OpenAIChat
from definable.model.anthropic import Claude
model = ResilientModel(
inner=OpenAIChat(id="gpt-4o"),
failover=FailoverChain(entries=[
FailoverEntry(model=OpenAIChat(id="gpt-4o-mini"), priority=1),
FailoverEntry(model=Claude(id="claude-sonnet-4-20250514"), priority=2),
]),
)
If the primary model fails, ResilientModel tries each failover entry in priority order.
Key Pool Options
API keys to rotate between.
Selection strategy: round_robin or lru (least recently used).
Base cooldown time for rate-limited keys.
Events
from definable.model.resilience.events import KeyRotatedEvent, ProviderFailoverEvent
model.events.on(KeyRotatedEvent, lambda e: print(f"Rotated to key {e.key_index}"))
model.events.on(ProviderFailoverEvent, lambda e: print(f"Failed over to {e.provider}"))
Imports
from definable.model.resilience import ResilientModel, KeyPool, FailoverChain, FailoverEntry