Multi-Channel Gateway
Web UI, Telegram, Discord with per-channel history and format-aware responses.
The Problem
An AI agent locked behind a single interface is an AI agent you forget to use. If you have to open a specific web app every time you want to ask a question, you will default to whatever chat tool is already in front of you. The agent needs to meet you where you are -- in your messaging app, your team chat, your browser -- with context that carries across sessions on each channel.
How Baker Street Solves It
The Gateway service bridges external messaging platforms to the Brain. It handles the protocol translation, message formatting, and conversation persistence so the Brain can focus on reasoning.
Three channels are supported out of the box:
- Web UI -- a React single-page application with streaming chat, job monitoring, memory browsing, extension management, model configuration, and system health dashboards. Built with Vite and Tailwind, served by Caddy.
- Telegram -- full conversational access through a Telegram bot. Per-chat conversation persistence, automatic message splitting for Telegram's 4096-character limit, typing indicators while the agent thinks.
- Discord -- same capabilities adapted for Discord's channel model and 2000-character limit. Supports multi-message responses and thread-based conversations.
Each channel maps to its own conversation context, so what you discuss on Telegram stays separate from your web session. The Gateway handles platform-specific formatting automatically -- rich Markdown for the web UI, simplified formatting for messaging platforms that have their own rendering quirks.
Adding a new channel means implementing a thin adapter that maps platform events to Brain API calls. The Gateway's architecture is deliberately simple to make this straightforward.
Example
// Gateway Telegram adapter (simplified)
import { TelegramBot } from "./telegram-client";
import { BrainClient } from "./brain-client";
const bot = new TelegramBot(process.env.TELEGRAM_TOKEN);
const brain = new BrainClient(process.env.BRAIN_URL);
bot.onMessage(async (msg) => {
const conversationId = `telegram-${msg.chat.id}`;
await bot.sendTypingAction(msg.chat.id);
const stream = brain.chat({
conversationId,
message: msg.text,
channel: "telegram",
});
let buffer = "";
for await (const chunk of stream) {
buffer += chunk;
}
// Split for Telegram's character limit
const parts = splitMessage(buffer, 4096);
for (const part of parts) {
await bot.sendMessage(msg.chat.id, part);
}
});
Learn More
See the Gateway documentation for channel configuration, custom adapter development, and conversation management.