Skip to main content

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 AgentixClient and passes a different session_id per 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 OK immediately (Slack requires < 3 s), and the agent query + response is dispatched as a background asyncio task.
  • Adapters are swappable — implement ChannelAdapter for 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

ModeWhen to useConfig
ProgrammaticEmbed the gateway in your own appAgentixGateway + 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.