| """Abstract base class for messaging platforms.""" |
|
|
| from abc import ABC, abstractmethod |
| from collections.abc import AsyncGenerator, Awaitable, Callable |
| from typing import ( |
| Any, |
| Protocol, |
| runtime_checkable, |
| ) |
|
|
| from ..models import IncomingMessage |
|
|
|
|
| @runtime_checkable |
| class CLISession(Protocol): |
| """Protocol for CLI session - avoid circular import from cli package.""" |
|
|
| def start_task( |
| self, prompt: str, session_id: str | None = None, fork_session: bool = False |
| ) -> AsyncGenerator[dict, Any]: |
| """Start a task in the CLI session.""" |
| ... |
|
|
| @property |
| @abstractmethod |
| def is_busy(self) -> bool: |
| """Check if session is busy.""" |
| pass |
|
|
|
|
| @runtime_checkable |
| class SessionManagerInterface(Protocol): |
| """ |
| Protocol for session managers to avoid tight coupling with cli package. |
| |
| Implementations: CLISessionManager |
| """ |
|
|
| async def get_or_create_session( |
| self, session_id: str | None = None |
| ) -> tuple[CLISession, str, bool]: |
| """ |
| Get an existing session or create a new one. |
| |
| Returns: Tuple of (session, session_id, is_new_session) |
| """ |
| ... |
|
|
| async def register_real_session_id( |
| self, temp_id: str, real_session_id: str |
| ) -> bool: |
| """Register the real session ID from CLI output.""" |
| ... |
|
|
| async def stop_all(self) -> None: |
| """Stop all sessions.""" |
| ... |
|
|
| async def remove_session(self, session_id: str) -> bool: |
| """Remove a session from the manager.""" |
| ... |
|
|
| def get_stats(self) -> dict: |
| """Get session statistics.""" |
| ... |
|
|
|
|
| class MessagingPlatform(ABC): |
| """ |
| Base class for all messaging platform adapters. |
| |
| Implement this to add support for Telegram, Discord, Slack, etc. |
| """ |
|
|
| name: str = "base" |
|
|
| @abstractmethod |
| async def start(self) -> None: |
| """Initialize and connect to the messaging platform.""" |
| pass |
|
|
| @abstractmethod |
| async def stop(self) -> None: |
| """Disconnect and cleanup resources.""" |
| pass |
|
|
| @abstractmethod |
| async def send_message( |
| self, |
| chat_id: str, |
| text: str, |
| reply_to: str | None = None, |
| parse_mode: str | None = None, |
| message_thread_id: str | None = None, |
| ) -> str: |
| """ |
| Send a message to a chat. |
| |
| Args: |
| chat_id: The chat/channel ID to send to |
| text: Message content |
| reply_to: Optional message ID to reply to |
| parse_mode: Optional formatting mode ("markdown", "html") |
| message_thread_id: Optional forum topic ID (Telegram) |
| |
| Returns: |
| The message ID of the sent message |
| """ |
| pass |
|
|
| @abstractmethod |
| async def edit_message( |
| self, |
| chat_id: str, |
| message_id: str, |
| text: str, |
| parse_mode: str | None = None, |
| ) -> None: |
| """ |
| Edit an existing message. |
| |
| Args: |
| chat_id: The chat/channel ID |
| message_id: The message ID to edit |
| text: New message content |
| parse_mode: Optional formatting mode |
| """ |
| pass |
|
|
| @abstractmethod |
| async def delete_message( |
| self, |
| chat_id: str, |
| message_id: str, |
| ) -> None: |
| """ |
| Delete a message from a chat. |
| |
| Args: |
| chat_id: The chat/channel ID |
| message_id: The message ID to delete |
| """ |
| pass |
|
|
| @abstractmethod |
| async def queue_send_message( |
| self, |
| chat_id: str, |
| text: str, |
| reply_to: str | None = None, |
| parse_mode: str | None = None, |
| fire_and_forget: bool = True, |
| message_thread_id: str | None = None, |
| ) -> str | None: |
| """ |
| Enqueue a message to be sent. |
| |
| If fire_and_forget is True, returns None immediately. |
| Otherwise, waits for the rate limiter and returns message ID. |
| """ |
| pass |
|
|
| @abstractmethod |
| async def queue_edit_message( |
| self, |
| chat_id: str, |
| message_id: str, |
| text: str, |
| parse_mode: str | None = None, |
| fire_and_forget: bool = True, |
| ) -> None: |
| """ |
| Enqueue a message edit. |
| |
| If fire_and_forget is True, returns immediately. |
| Otherwise, waits for the rate limiter. |
| """ |
| pass |
|
|
| @abstractmethod |
| async def queue_delete_message( |
| self, |
| chat_id: str, |
| message_id: str, |
| fire_and_forget: bool = True, |
| ) -> None: |
| """ |
| Enqueue a message deletion. |
| |
| If fire_and_forget is True, returns immediately. |
| Otherwise, waits for the rate limiter. |
| """ |
| pass |
|
|
| @abstractmethod |
| def on_message( |
| self, |
| handler: Callable[[IncomingMessage], Awaitable[None]], |
| ) -> None: |
| """ |
| Register a message handler callback. |
| |
| The handler will be called for each incoming message. |
| |
| Args: |
| handler: Async function that processes incoming messages |
| """ |
| pass |
|
|
| @abstractmethod |
| def fire_and_forget(self, task: Awaitable[Any]) -> None: |
| """Execute a coroutine without awaiting it.""" |
| pass |
|
|
| @property |
| def is_connected(self) -> bool: |
| """Check if the platform is connected.""" |
| return False |
|
|