/** * Platform Adapter Base - Interface for Hermes-style platform adapters */ export interface PlatformMessage { id: string; platform: string; channelId: string; userId: string; content: string; timestamp: number; metadata?: Record; } export interface PlatformConfig { enabled: boolean; platform: string; token?: string; botToken?: string; webhookSecret?: string; } export interface AdapterCallbacks { onMessage: (message: PlatformMessage) => Promise; onTyping?: (userId: string, isTyping: boolean) => void; onDisconnect?: () => void; } export interface PlatformAdapter { readonly platform: string; readonly config: PlatformConfig; /** * Initialize the adapter */ initialize(): Promise; /** * Start listening for messages */ start(callbacks: AdapterCallbacks): Promise; /** * Stop listening */ stop(): Promise; /** * Send a message to a channel */ sendMessage(channelId: string, content: string): Promise; // Returns message ID /** * Edit an existing message */ editMessage(channelId: string, messageId: string, content: string): Promise; /** * Delete a message */ deleteMessage(channelId: string, messageId: string): Promise; /** * Set typing indicator */ setTyping(channelId: string, isTyping: boolean): Promise; /** * Get adapter health status */ getStatus(): Promise<{ connected: boolean; latency?: number }>; } /** * Abstract base class for adapters */ export abstract class BaseAdapter implements PlatformAdapter { abstract readonly platform: string; abstract config: PlatformConfig; protected callbacks: AdapterCallbacks | null = null; protected running = false; async initialize(): Promise { // Override in subclass } async start(callbacks: AdapterCallbacks): Promise { this.callbacks = callbacks; this.running = true; } async stop(): Promise { this.running = false; this.callbacks = null; } abstract sendMessage(channelId: string, content: string): Promise; abstract editMessage(channelId: string, messageId: string, content: string): Promise; abstract deleteMessage(channelId: string, messageId: string): Promise; abstract setTyping(channelId: string, isTyping: boolean): Promise; abstract getStatus(): Promise<{ connected: boolean; latency?: number }>; protected emitMessage(message: PlatformMessage): void { if (this.callbacks?.onMessage) { this.callbacks.onMessage(message); } } protected generateMessageId(): string { return `${this.platform}-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`; } }