Gateway and Adapters
Multi-channel gateway for connecting Baker Street to Web, Telegram, and Discord.
Gateway and Adapters
The Gateway service bridges external messaging platforms to the Brain. Each adapter handles platform-specific concerns so the Brain can focus on reasoning and tool dispatch.
Architecture
The Gateway is a single service with pluggable adapters. Each adapter:
- Receives messages from its platform (webhooks, WebSocket, polling)
- Normalizes them into a common internal format
- Forwards them to the Brain's REST API
- Receives the streamed response
- Formats and delivers it back to the user on the platform
Each channel maps to its own conversation ID, so context stays separate. A Telegram chat and a Discord channel with the same user maintain independent conversation histories.
Web Adapter
The web adapter serves the React SPA and provides a WebSocket/SSE connection for real-time streaming. Features include:
- Server-Sent Events for streaming responses token by token
- Job monitoring with real-time status updates
- Memory browser for viewing and managing stored memories
- Extension manager for viewing active MCP extensions
- Model configuration for switching between Claude models
Telegram Adapter
The Telegram adapter uses the Bot API with webhook delivery:
- Per-chat conversations -- each Telegram chat maintains its own context
- Message splitting -- long responses are split at natural breakpoints to respect Telegram's 4096-character limit
- Typing indicators -- the bot shows "typing..." while the Brain processes
- Markdown formatting -- responses are formatted with Telegram-compatible Markdown
Discord Adapter
The Discord adapter connects via the Discord Gateway WebSocket:
- Per-channel conversations -- each Discord channel gets its own conversation thread
- Character limit handling -- responses split at 2000 characters for Discord's limit
- Embed formatting -- code blocks and structured data use Discord embeds when appropriate
Adding a New Adapter
To add a new messaging platform, implement the adapter interface:
interface ChannelAdapter {
name: string;
initialize(): Promise<void>;
sendMessage(channelId: string, content: string): Promise<void>;
onMessage(handler: (msg: IncomingMessage) => void): void;
}
Register the adapter in the Gateway's configuration:
# gateway-config.yaml
ADAPTERS: "web,telegram,discord,slack"
SLACK_BOT_TOKEN: "xoxb-..."
The Gateway will initialize all configured adapters at startup. Any adapter whose required environment variables are missing will be skipped with a warning.
Configuration
apiVersion: v1
kind: ConfigMap
metadata:
name: gateway-config
namespace: baker-street
data:
BRAIN_URL: "http://baker-brain:3000"
ADAPTERS: "web,telegram,discord"
WEB_PORT: "3001"
Secrets for each adapter (bot tokens, webhook secrets) are stored in the gateway-secrets Kubernetes Secret, keeping them separate from Brain and Worker credentials.