Files
flynn/src/channels/types.ts
T
William Valentin b9bfee9c5b feat: add outbound attachment support with media.send tool
Introduces OutboundAttachment type on OutboundMessage, an
OutboundAttachmentCollector (push/drain pattern), and a media.send
tool that queues files for outbound delivery. Each channel adapter
(Telegram, Discord, Slack, WhatsApp) sends attachments after the
text reply. Includes 15 tests for collector and tool.
2026-02-07 09:09:00 -08:00

106 lines
3.2 KiB
TypeScript

/**
* Channel adapter type definitions.
*
* Pure type definitions for the channel abstraction layer.
* Each channel adapter (Telegram, webchat, etc.) implements
* the ChannelAdapter interface to provide a uniform messaging API.
*/
/** Media attachment received from or sent to a channel. */
export interface Attachment {
/** MIME type (e.g. "image/jpeg", "audio/ogg", "application/pdf"). */
mimeType: string;
/** Base64-encoded data (preferred for model APIs). */
data?: string;
/** URL to download the attachment (alternative to data). */
url?: string;
/** Original filename, if available. */
filename?: string;
/** File size in bytes, if known. */
size?: number;
}
/** Inbound message received from a channel platform. */
export interface InboundMessage {
/** Platform message ID. */
id: string;
/** Adapter name: "telegram", "webchat", etc. */
channel: string;
/** Platform user ID. */
senderId: string;
/** Display name (optional). */
senderName?: string;
/** Message text. */
text: string;
/** Media attachments (images, audio, documents). */
attachments?: Attachment[];
/** ID of message being replied to. */
replyTo?: string;
/** Unix ms. */
timestamp: number;
/** Platform-specific extras. */
metadata?: Record<string, unknown>;
}
/** Attachment to send back via a channel adapter. */
export interface OutboundAttachment {
/** MIME type (e.g. "image/png", "application/pdf"). */
mimeType: string;
/** Base64-encoded file content. */
data?: string;
/** URL to the file (alternative to data). */
url?: string;
/** Suggested filename. */
filename?: string;
}
/** Outbound message to send via a channel adapter. */
export interface OutboundMessage {
/** Response text (markdown). */
text: string;
/** Original message ID to reply to. */
replyTo?: string;
/** File or image attachments to send with the response. */
attachments?: OutboundAttachment[];
/** Platform-specific extras. */
metadata?: Record<string, unknown>;
}
/** Tool execution status event for streaming feedback. */
export interface ToolStatusEvent {
type: 'start' | 'end';
tool: string;
args?: unknown;
result?: { success: boolean; output: string; error?: string };
}
/** Connection status of a channel adapter. */
export type ChannelStatus = 'disconnected' | 'connecting' | 'connected' | 'error';
/** Uniform interface that every channel adapter must implement. */
export interface ChannelAdapter {
/** Unique channel name (e.g. "telegram", "webchat"). */
readonly name: string;
/** Current connection status. */
readonly status: ChannelStatus;
/** Start the adapter (connect to platform, begin listening). */
connect(): Promise<void>;
/** Stop the adapter (disconnect, clean up). */
disconnect(): Promise<void>;
/** Send a message to a specific peer on this channel. */
send(peerId: string, message: OutboundMessage): Promise<void>;
/** Register the inbound message handler. Called by registry before connect(). */
onMessage(handler: (msg: InboundMessage) => void): void;
}
/** Callback type for the registry's message handler. */
export type MessageHandler = (
msg: InboundMessage,
reply: (response: OutboundMessage) => Promise<void>,
) => Promise<void>;