Messaging Gateway
Expose any Agentix agent to Slack, WhatsApp, Email (IMAP inbound/SMTP outbound), HTTP webhooks, and other messaging channels — with built-in session management, authorization, and middleware.
How it works
The gateway is a thin server-side routing layer. It receives webhooks from external channels, maps them to agent sessions, runs the agent query, and delivers the response back — all without touching agent logic.
External Channels
Slack / WhatsApp / Email / Custom
│ webhook
▼
AgentixGateway (aiohttp HTTP server)
┌─────────────────────────────────────────┐
│ Channel Adapters │
│ POST /webhook/slack → SlackAdapter │
│ POST /webhook/whatsapp→ WhatsAppAdapter│
│ POST /webhook/email → EmailAdapter │
│ GET /health → health check │
│ │
│ Middleware Pipeline │
│ Auth / Verify → Rate Limit → Logging │
│ │
│ Session Mapper │
│ (channel, thread_id) → session_id │
│ In-memory (single server) │
│ or Redis (distributed) │
└──────────────┬──────────────────────────┘
│ client.query(text, session_id=...)
▼
AgentixClient (single shared instance)
Semaphore(max_concurrent_queries)
┌─────────────────────────────────────────┐
│ Agent Loop (per query) │
│ Prompt → LLM → Tools → LLM → Result │
│ yields: AssistantMessage, ResultMessage│
└──────────────┬──────────────────────────┘
│
▼
Message Transformer
┌─────────────────────────────────────────┐
│ TextBlock → chunked text │
│ ToolUseBlock→ "Using Bash…" (activity) │
│ ResultMessage → final response │
│ ThinkingBlock, SystemMessage → skipped │
│ │
│ Channel-native formatting: │
│ Slack: **bold** → *bold* │
│ WhatsApp: **bold** → *bold* │
│ Email: markdown → HTML │
└──────────────┬──────────────────────────┘
│
▼
Back to channel (send_response)
Slack → chat.postMessage (threaded)
WhatsApp → Cloud API POST /messages
Email → SMTP (with reply headers)
Key design decisions
- One client, many sessions — the gateway reuses a single
AgentixClientand passes a differentsession_idper channel thread. No client-per-conversation overhead. - Session mapper is the glue —
(slack, #general, thread_abc)maps to session"a3f8". With Redis this works across multiple gateway instances; with in-memory it works for single-server deployments. - Async ACK, async delivery — each incoming webhook returns
200 OKimmediately (Slack requires < 3 s), and the agent query + response is dispatched as a background asyncio task. - Adapters are swappable — implement
ChannelAdapterfor any new channel (Discord, Telegram, Teams) without touching gateway core.
Multi-agent scenario
The gateway is unaware of sub-agents — it simply calls client.query(). The coordinator handles delegation transparently:
Slack: "/budget-impact hire 3 engineers"
│
▼
AgentixGateway → AgentixClient.query(prompt, session_id=...)
│
▼
Coordinator Agent
│ Uses Task tool → financial-analyst → runs own loop, returns result
│ Uses Task tool → recruiter agent → runs own loop, returns result
│ Synthesizes results
│
▼
AssistantMessage → gateway transforms → Slack thread reply
Install
pip install agentix[gateway] # All adapters (Slack, WhatsApp, Email, webhook)
pip install agentix[gateway-slack] # Slack adapter only
pip install agentix[gateway-whatsapp] # WhatsApp Business API + Baileys (both adapters)
pip install agentix[gateway-email] # Email adapter (SMTP/IMAP)
Two configuration modes
| Mode | When to use | Config |
|---|---|---|
| Programmatic | Embed the gateway in your own app | AgentixGateway + add_channel in code — no gateway.yaml required |
| Standalone (YAML + CLI) | Run gateway as its own process | <project>/.agentix/gateway.yaml + agentix-gateway CLI |
Programmatic setup
import asyncio
from agentix import AgentixAgentOptions
from agentix.gateway import AgentixGateway
from agentix.gateway.adapters.slack import SlackAdapter
from agentix.gateway.adapters.whatsapp import WhatsAppAdapter
options = AgentixAgentOptions(
name="support-agent",
provider="anthropic",
model="claude-sonnet-4-20250514",
system_prompt="You are a helpful support agent.",
)
gateway = AgentixGateway(options, session_ttl=7200)
gateway.add_channel(
SlackAdapter(
bot_token="xoxb-...",
signing_secret="...",
)
)
gateway.add_channel(
WhatsAppAdapter(
phone_number_id="...",
access_token="...",
verify_token="...",
app_secret="...",
)
)
asyncio.run(gateway.start(host="0.0.0.0", port=8080))
gateway.start()is blocking — it runs the aiohttp event loop until stopped.
Mounting into an existing app
If you already have an aiohttp or ASGI app, attach the gateway routes instead of running a separate server:
gateway.mount(existing_app, prefix="/gateway")
Email inbound uses IMAP polling (not HTTP webhooks) — see Email adapter.
Standalone YAML + CLI
# Start gateway from a project directory containing .agentix/gateway.yaml
agentix-gateway --cwd /path/to/project
# Or
python -m agentix.gateway --cwd /path/to/project
See YAML Configuration for the full gateway.yaml reference.
Session TTL
Each user gets a dedicated session. session_ttl (seconds) controls how long an inactive session is retained before it is evicted:
gateway = AgentixGateway(options, session_ttl=3600) # 1 hour
For distributed deployments (multiple gateway instances), back the session mapper with Redis — see Storage Backends.