TnsAI

Channels

A channel is one way humans talk to Sona. The framework's tnsai-channels module defines the SPI; each adapter is one implementation that translates a platform-specific transport into the gateway's UnifiedMessage / UnifiedResponse records.

You can run more than one channel at the same time — Sona starts every channel listed under channels: in ~/.sona/sona.yml at boot.

Shipped today

These adapters are production-ready and live in the framework / Sona repos:

  • Telegram — long-poll Bot API, threads, media, pairing flow. The default channel — Sona ships with it enabled out of the box.
  • CLI — interactive REPL (sona chat) or newline-delimited JSON for scripting (sona chat --json). No external dependencies; useful for local dogfooding, headless deployment smoke tests, and shell pipelines.
  • Email (IMAP/SMTP) — async inbox poll + SMTP send, thread tracking via Message-ID. Framework adapter and Sona-side YAML config landed in framework 0.10.4 (TNS-354).

Framework adapter shipped, Sona-side wiring in progress

Each of these landed as a tnsai-channels adapter in framework 0.10.4. Sona discovers them at boot via SPI (ChannelDiscovery.discoverFactories), but the daemon still needs its own YAML config block for the channel to be useful — that wiring is the follow-up task tracked alongside each row.

ChannelFramework PRSona-side wiringStatus
SlackTNS-350TNS-502Socket Mode WebSocket + chat.postMessage
DiscordTNS-351TNS-503Gateway v10 WebSocket + heartbeat
WhatsApp BusinessTNS-352TNS-504Cloud API webhook + HMAC verify

Once a Sona-side wiring task lands, its setup guide follows here. Drop a thumbs-up on the Linear issue if you need one urgently or open a discussion on the Sona repo.

How channels compose

Every adapter sits behind the same ChannelAdapter SPI, so the gateway code is identical for all of them. The flow:

  1. Adapter receives a platform-specific message (Telegram update, Slack event, stdin line, …).
  2. Adapter translates it into a UnifiedMessage with a channelId ("telegram", "cli", …) and a senderId.
  3. Gateway routes by (channelId, senderId) to a session; the session runs the agent.
  4. Gateway hands the reply back as a UnifiedResponse; adapter renders it to the platform.

The How It Works page has a Mermaid sequence diagram that traces one Telegram message end-to-end. The same diagram applies to every adapter — only the first and last hops change.

Writing your own

The framework's Channels reference covers the SPI surface (ChannelAdapter, StreamingChannelAdapter, UnifiedMessage, UnifiedResponse). Sona will auto-discover any ChannelAdapter SPI on the classpath at boot — META-INF/services/com.tnsai.channels.api.ChannelAdapter.

To use a custom adapter with Sona, drop the JAR into ~/.sona/lib/, restart the daemon, and add its channels: config block to sona.yml. No Sona-side code change.

On this page