feat: add channel adapter abstraction with Telegram and WebChat adapters
Implement Phase 3 channel adapters that decouple message sources from the agent via a uniform ChannelAdapter interface and ChannelRegistry. - Add ChannelAdapter/InboundMessage/OutboundMessage types - Add ChannelRegistry for adapter lifecycle and message routing - Add TelegramAdapter (grammy bot, auth middleware, confirmations, chunking) - Add WebChatAdapter (thin shim over GatewayServer) - Refactor daemon to use ChannelRegistry with per-channel-per-user agents - Add config.get/config.patch gateway handlers (Phase 2 loose end) - Add system.restart gateway handler (Phase 2 loose end) - Add implementation plans and design docs Tests: 225 passing (33 new channel adapter + gateway handler tests)
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/** 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;
|
||||
/** ID of message being replied to. */
|
||||
replyTo?: string;
|
||||
/** Unix ms. */
|
||||
timestamp: number;
|
||||
/** Platform-specific extras. */
|
||||
metadata?: Record<string, unknown>;
|
||||
}
|
||||
|
||||
/** Outbound message to send via a channel adapter. */
|
||||
export interface OutboundMessage {
|
||||
/** Response text (markdown). */
|
||||
text: string;
|
||||
/** Original message ID to reply to. */
|
||||
replyTo?: string;
|
||||
/** 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>;
|
||||
Reference in New Issue
Block a user