chump-messaging 0.1.0

Platform-agnostic messaging trait for LLM agents: a MessagingAdapter contract that Telegram / Slack / Matrix / Discord / web adapters implement, with capabilities-as-fields IncomingMessage / OutgoingMessage types so adapters with weaker features just leave fields empty.
Documentation

chump-messaging

Platform-agnostic messaging trait for LLM agents. Define one MessagingAdapter impl per platform (Telegram, Slack, Matrix, Discord, IRC, your own) and the agent loop talks to all of them through the same contract.

Capabilities are carried as fields on IncomingMessage / OutgoingMessage rather than per-platform enums, so adapters with weaker features just leave fields empty (e.g. an IRC adapter sets attachments = vec![] and thread_id = None — the agent loop already handles that case).

Why a separate crate

If you're building an agent that needs multi-platform reach, you don't want to copy ~1400 lines of platform-specific glue per platform and let them diverge. The MessagingAdapter trait is the contract — implement it once per platform, plug all of them into the same router (MessagingHub).

The trait is async-first (async fn via async-trait), platform-agnostic, and has zero opinions about how the agent loop is structured underneath.

Install

cargo add chump-messaging

Use

use chump_messaging::{MessagingAdapter, IncomingMessage, OutgoingMessage};
use async_trait::async_trait;

pub struct MyTelegramAdapter { /* ... */ }

#[async_trait]
impl MessagingAdapter for MyTelegramAdapter {
    async fn start(&self) -> anyhow::Result<()> { /* spin up bot loop */ }
    async fn send_reply(&self, channel: &str, text: &str) -> anyhow::Result<()> { /* ... */ }
    async fn send_dm(&self, user: &str, text: &str) -> anyhow::Result<()> { /* ... */ }
    async fn request_approval(&self, user: &str, prompt: &str) -> anyhow::Result<bool> { /* ... */ }
}

Core types

symbol what
MessagingAdapter the contract; 4 async methods (start / send_reply / send_dm / request_approval)
IncomingMessage platform-agnostic user-sent message (text, channel_id, user_id, dm flag, attachments, thread context)
OutgoingMessage the agent's reply (text, optional attachments, optional thread_id)
ApprovalResponse yes / no / timeout result from request_approval
MessagingHub dispatches incoming events from N adapters into a single agent loop, routes outgoing replies back by channel_id prefix

Channel-id namespacing convention

To route a reply back to the right adapter, channel ids are prefixed by platform:

  • telegram:<chat_id>
  • slack:<channel_id>
  • discord:<channel_id>
  • web:<session_id>

MessagingHub::send_reply() strips the prefix and dispatches to the matching adapter.

Status

  • v0.1.0 — initial publish (extracted from the chump repo, where it powers the Telegram + Discord + PWA adapters via chump --serve / chump --discord / chump --telegram)

License

MIT.

Companion crates