Interfaces
Connect agents to Slack, Telegram, WhatsApp, and browser clients through AgentOS.
The same agent backend can serve Slack, Telegram, WhatsApp, browser clients, and agent-to-agent systems. AgentOS interface adapters map each surface onto the same run and session model.
These are registration fragments for a served application. Install uv pip install "agno[openai,os,postgres,slack,telegram]", set OPENAI_API_KEY, and configure the PostgreSQL service and interface credentials. After constructing agent_os, create app = agent_os.get_app() and serve the module.
Follow the provider setup to configure a public HTTPS callback: Slack, Telegram, or WhatsApp. Ordinary production Telegram requests require TELEGRAM_WEBHOOK_SECRET_TOKEN and a matching provider secret header; WhatsApp requires WHATSAPP_APP_SECRET for signature verification. Constructing an interface with a bot token does not register its callback with the provider.
from agno.agent import Agent
from agno.db.postgres import PostgresDb
from agno.models.openai import OpenAIResponses
from agno.os import AgentOS
from agno.os.interfaces.slack import Slack
from agno.os.interfaces.telegram import Telegram
db = PostgresDb(db_url="postgresql+psycopg://ai:ai@localhost:5532/ai")
agent = Agent(name="Support", model=OpenAIResponses(id="gpt-5.5"), db=db)
agent_os = AgentOS(
agents=[agent],
db=db,
interfaces=[
Slack(agent=agent, token="xoxb-...", signing_secret="..."),
Telegram(agent=agent, token="bot-token"),
],
)Available surfaces
| Interface | Use case |
|---|---|
| Slack | Team chat, DMs, channel mentions, thread sessions |
| Telegram | Personal assistants, mobile chat |
| Customer support, mobile chat | |
| AG-UI | Browser clients consuming SSE streams |
| A2A | Other agents calling yours over a standard protocol |
Sessions per surface
Each interface maps surface state onto AgentOS sessions, so a follow-up in the same thread continues the same conversation.
| Interface | session_id | user_id |
|---|---|---|
| Slack | <entity_id>:<channel_id>:<thread_ts> | Slack user ID, or resolved email when enabled |
| Telegram | tg:<entity_id>:<chat_id>[:<topic_id>][:<reset_id>] | Telegram user ID |
wa:<entity_id>:<user_id>[:<reset_id>] | Phone number or encrypted user ID | |
| AG-UI | Client thread_id | JWT subject, or forwarded user_id when anonymous |
| A2A | A2A context ID | JWT subject, or request metadata when anonymous |
Slack reuses the older <entity_id>:<thread_ts> form only when a matching legacy session is already stored.
For Telegram and WhatsApp, /new preserves earlier sessions and creates a session whose ID has a new eight-character suffix. This command requires a database.
Stored memory can follow a user across surfaces when the interfaces resolve to the same user_id and use the same agent database and memory configuration. Session history remains scoped to each interface-generated session_id. Interfaces can add surface metadata and dependencies to a run.
Register several interfaces
Install uv pip install "agno[agui,a2a]" for the additional protocol adapters in this fragment. Configure WhatsApp credentials and webhook verification using its setup guide above.
from agno.os.interfaces.a2a import A2A
from agno.os.interfaces.agui import AGUI
from agno.os.interfaces.whatsapp import Whatsapp
agent_os = AgentOS(
agents=[agent],
db=db,
interfaces=[
Slack(agent=agent, token="xoxb-your-token", signing_secret="your-signing-secret"),
Telegram(agent=agent, token="your-bot-token"),
Whatsapp(
agent=agent,
access_token="your-access-token",
phone_number_id="your-phone-number-id",
verify_token="your-verify-token",
),
AGUI(agent=agent),
A2A(agents=[agent]),
],
)Conditional registration
Load the uppercase credential variables below from your application settings, then register only the interfaces you have configured. Callback verification requirements still apply when an interface is registered.
interfaces = []
if SLACK_TOKEN and SLACK_SIGNING_SECRET:
interfaces.append(Slack(agent=agent, token=SLACK_TOKEN, signing_secret=SLACK_SIGNING_SECRET))
if TELEGRAM_TOKEN:
interfaces.append(Telegram(agent=agent, token=TELEGRAM_TOKEN))
agent_os = AgentOS(agents=[agent], db=db, interfaces=interfaces)Resolving Slack identities
Slack hands you opaque IDs like U07ABCXYZ. Set resolve_user_identity=True on the Slack interface and it attempts to resolve the ID to the user's email, which becomes the run's user_id. If email lookup is unavailable, it falls back to the Slack user ID. The display name is added to run metadata. Off by default because it costs an extra Slack API call per message.
One-off webhooks
For a one-off integration, a custom FastAPI route that calls the agent is enough. See Serve as an API.
Next steps
| Task | Guide |
|---|---|
| Keep memory coherent per user | Sessions and memory |