@ekairos/channel
Channel domain library.
Unified multichannel communication for agent threads: one canonical message model across web, email, whatsapp, slack, teams and more — persisted on InstantDB.
Schema
channel_messages
Canonical message crossing any channel: kind, direction, role, text/parts, status, externalId, participant — linked to event_contexts and event_items.
channel_state
Internal runtime key/value state with TTL for platform delivery (caches, lists).
channel_locks
Per-conversation delivery locks (token + TTL) so one handler runs at a time.
channel_subscriptions
Conversations the runtime is subscribed to, durable across restarts.
channel_queues
Pending inbound entries per conversation while a handler is running.
Actions
createChannels
Boots the multichannel runtime: configured platforms feed one inbound pipeline and expose one webhook handler each.
inbound.reply
Posts a reply on the same platform conversation and persists the outbound message.
ChannelRegistry.send
Sends an outbound message through a registered channel adapter by kind.
createChannelMessage
Constructs a canonical message record ready to persist and link.
useThread (agent)
The agent hook queries channel_messages alongside context items, so timelines span every channel for free.
Configure platforms. Everything else is domain state.
Apps configure platform credentials and two callbacks; messages, subscriptions, locks and queues persist on InstantDB through the channel domain.
import { createChannels } from "@ekairos/channel";
const channels = await createChannels({
db,
userName: "ekairos",
platforms: {
slack: { botToken: process.env.SLACK_BOT_TOKEN!, signingSecret: process.env.SLACK_SIGNING_SECRET! },
telegram: { botToken: process.env.TELEGRAM_BOT_TOKEN! },
},
resolveContextId: async ({ channel, threadKey }) =>
ensureThreadContext(`${channel}:${threadKey}`),
react: async (inbound) => {
const reaction = await agentThread(inbound.contextId).react(inbound.message);
return reaction.text;
},
});
// app/api/channels/[platform]/route.ts
export const POST = (req: Request, { params }) =>
channels.webhooks[params.platform](req);