mirror of
https://github.com/Alishahryar1/free-claude-code.git
synced 2026-04-28 19:40:54 +00:00
- Introduced message_thread_id to the IncomingMessage model for handling forum topic IDs in Telegram. - Updated messaging platforms (Discord and Telegram) to accept and process message_thread_id in send_message methods. - Modified message handlers to utilize message_thread_id when sending messages. - Enhanced test cases to validate the integration of message_thread_id in message handling. This change improves support for forum supergroups in Telegram and enhances message management across platforms.
218 lines
5.3 KiB
Python
218 lines
5.3 KiB
Python
"""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
|