How It Works
Quick Start
1
Simple Usage
2
With Configuration
What’s Bounded by Default
Recreating agents per request is safe. Agent locks no longer reuse stale
id(agent) keys, so unrelated users cannot share locks or swap histories.Operational Knobs
For mid-run cancellation and stale session cleanup, see Bot Run Control —SessionRunControl.cleanup_stale_sessions(max_age_seconds=3600) removes abandoned run-control state.
Multi-Agent Safety
Earlier releases keyed agent locks onid(agent). CPython may reuse that integer after garbage collection, so long-running gateways that recreated agents per request could silently mix up two users’ histories. Agent locks now follow agent lifetime via WeakKeyDictionary; per-user locks stay bounded even if you never call cleanup helpers.
Released in PR #1972 — Upgrade to pick up the fix. See Session Persistence → Bounded lock caches for details.
Best Practices
Reuse one agent instance per bot
Reuse one agent instance per bot
Create the agent once at startup — agent locks follow instance lifetime via
WeakKeyDictionary, so recreating agents per request is safe but wasteful.Set session_ttl for busy channels
Set session_ttl for busy channels
Default lock caches evict after 1 hour; set
BotConfig(session_ttl=…) when conversations stay idle longer than your support SLA.Run cleanup_stale_sessions periodically
Run cleanup_stale_sessions periodically
Call
SessionRunControl.cleanup_stale_sessions on a schedule in long-lived gateways to drop abandoned run-control state.Upgrade after PR #1972
Upgrade after PR #1972
Ensure you are on a release that includes bounded agent locks — earlier builds could mix histories when
id(agent) was reused.Auto-reconnect (default)
Bot(...).run() now supervises its own inbound connection — if the socket drops, ChannelSupervisor reconnects with capped exponential backoff and restarts an unhealthy channel, matching the resilience BotOS and the gateway already provide.
1
Default supervision on Slack
2
Same code, every platform
The identical pattern works for Discord, Email, Linear, and WhatsApp — no extra flags:
3
Opt out under an external supervisor
Set
enable_supervision=False when embedding, testing, or running under systemd/k8s:Which platforms are supervised by default?
When to opt out (enable_supervision=False)
Don't stack supervisors
Don't stack supervisors
If a
Bot runs inside BotOS or under systemd/Kubernetes, set enable_supervision=False. Two supervisors on one connection means double reconnect attempts and double backoff — let the outer supervisor own restarts.Email / Linear / WhatsApp / AgentMail — `Bot.run()` no longer returns immediately
Email / Linear / WhatsApp / AgentMail — `Bot.run()` no longer returns immediately
Adapters whose
start() returns immediately (Email IMAP poll, Linear/WhatsApp/AgentMail webhook servers) now stay supervised until they actually stop. Scripts that relied on .run() returning early should switch to await bot.start() and manage lifecycle explicitly, or spawn the run in a background task.Related
Session Persistence
Bot session storage and bounded lock behaviour
Messaging Bots
Platform setup, debounce, and chunking
Inbound DLQ
Persist failed messages for replay
Cross-Platform Mirror
One conversation across every channel

