Refactor message sending architecture and implement legacy driver support
- Removed UniversalMessageSender from group_generator.py and private_generator.py. - Updated PlatformIOManager to manage legacy send drivers and ensure send pipeline readiness. - Enhanced LegacyPlatformDriver to utilize prepared messages for sending. - Refactored send_service to unify message sending logic and integrate with Platform IO. - Added regression tests for Platform IO legacy driver and send service functionality.
This commit is contained in:
@@ -1,16 +1,16 @@
|
||||
"""提供 Platform IO 的 legacy 传输驱动骨架。"""
|
||||
"""提供 Platform IO 的 legacy 传输驱动实现。"""
|
||||
|
||||
from typing import TYPE_CHECKING, Any, Dict, Optional
|
||||
|
||||
from src.platform_io.drivers.base import PlatformIODriver
|
||||
from src.platform_io.types import DeliveryReceipt, DriverDescriptor, DriverKind, RouteKey
|
||||
from src.platform_io.types import DeliveryReceipt, DeliveryStatus, DriverDescriptor, DriverKind, RouteKey
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from src.chat.message_receive.message import SessionMessage
|
||||
|
||||
|
||||
class LegacyPlatformDriver(PlatformIODriver):
|
||||
"""面向 ``maim_message`` 旧链路的 Platform IO 驱动骨架。"""
|
||||
"""面向 ``UniversalMessageSender`` 旧链的 Platform IO 驱动。"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
@@ -25,7 +25,7 @@ class LegacyPlatformDriver(PlatformIODriver):
|
||||
Args:
|
||||
driver_id: Broker 内的唯一驱动 ID。
|
||||
platform: 该 legacy 适配器链路负责的平台。
|
||||
account_id: 可选的账号 ID 或 self ID。
|
||||
account_id: 可选的账号 ID。
|
||||
scope: 可选的额外路由作用域。
|
||||
metadata: 可选的额外驱动元数据。
|
||||
"""
|
||||
@@ -45,7 +45,7 @@ class LegacyPlatformDriver(PlatformIODriver):
|
||||
route_key: RouteKey,
|
||||
metadata: Optional[Dict[str, Any]] = None,
|
||||
) -> DeliveryReceipt:
|
||||
"""通过 legacy 传输路径发送消息。
|
||||
"""通过旧链发送一条已经过预处理的消息。
|
||||
|
||||
Args:
|
||||
message: 要投递的内部会话消息。
|
||||
@@ -53,9 +53,40 @@ class LegacyPlatformDriver(PlatformIODriver):
|
||||
metadata: 本次出站投递可选的 Broker 侧元数据。
|
||||
|
||||
Returns:
|
||||
DeliveryReceipt: 由驱动返回的规范化回执。
|
||||
|
||||
Raises:
|
||||
NotImplementedError: 当前仍处于骨架阶段,尚未真正接入旧发送链。
|
||||
DeliveryReceipt: 规范化后的发送回执。
|
||||
"""
|
||||
raise NotImplementedError("LegacyPlatformDriver 仅完成地基实现,尚未接入旧发送链")
|
||||
from src.chat.message_receive.uni_message_sender import send_prepared_message_to_platform
|
||||
|
||||
show_log = False
|
||||
if isinstance(metadata, dict):
|
||||
show_log = bool(metadata.get("show_log", False))
|
||||
|
||||
try:
|
||||
sent = await send_prepared_message_to_platform(message, show_log=show_log)
|
||||
except Exception as exc:
|
||||
return DeliveryReceipt(
|
||||
internal_message_id=message.message_id,
|
||||
route_key=route_key,
|
||||
status=DeliveryStatus.FAILED,
|
||||
driver_id=self.driver_id,
|
||||
driver_kind=self.descriptor.kind,
|
||||
error=str(exc),
|
||||
)
|
||||
|
||||
if not sent:
|
||||
return DeliveryReceipt(
|
||||
internal_message_id=message.message_id,
|
||||
route_key=route_key,
|
||||
status=DeliveryStatus.FAILED,
|
||||
driver_id=self.driver_id,
|
||||
driver_kind=self.descriptor.kind,
|
||||
error="旧链发送失败",
|
||||
)
|
||||
|
||||
return DeliveryReceipt(
|
||||
internal_message_id=message.message_id,
|
||||
route_key=route_key,
|
||||
status=DeliveryStatus.SENT,
|
||||
driver_id=self.driver_id,
|
||||
driver_kind=self.descriptor.kind,
|
||||
)
|
||||
|
||||
@@ -36,6 +36,7 @@ class PlatformIOManager:
|
||||
self._driver_registry = DriverRegistry()
|
||||
self._send_route_table = RouteTable()
|
||||
self._receive_route_table = RouteTable()
|
||||
self._legacy_send_drivers: Dict[str, PlatformIODriver] = {}
|
||||
self._deduplicator = MessageDeduplicator()
|
||||
self._outbound_tracker = OutboundTracker()
|
||||
self._inbound_dispatcher: Optional[InboundDispatcher] = None
|
||||
@@ -75,6 +76,16 @@ class PlatformIOManager:
|
||||
|
||||
self._started = True
|
||||
|
||||
async def ensure_send_pipeline_ready(self) -> None:
|
||||
"""确保出站发送管线已准备就绪。
|
||||
|
||||
该方法会先同步 legacy fallback driver,再在需要时启动 Broker。
|
||||
send service 应只调用这一层准备入口,而不是自行判断旧链或插件链。
|
||||
"""
|
||||
await self._sync_legacy_send_drivers()
|
||||
if not self._started:
|
||||
await self.start()
|
||||
|
||||
async def stop(self) -> None:
|
||||
"""停止 Broker,并按逆序停止全部已注册驱动。
|
||||
|
||||
@@ -272,8 +283,60 @@ class PlatformIOManager:
|
||||
removed_driver.clear_inbound_handler()
|
||||
self._send_route_table.remove_bindings_by_driver(driver_id)
|
||||
self._receive_route_table.remove_bindings_by_driver(driver_id)
|
||||
self._legacy_send_drivers = {
|
||||
platform: driver
|
||||
for platform, driver in self._legacy_send_drivers.items()
|
||||
if driver.driver_id != driver_id
|
||||
}
|
||||
return removed_driver
|
||||
|
||||
async def _sync_legacy_send_drivers(self) -> None:
|
||||
"""根据当前配置同步 legacy fallback driver。"""
|
||||
from src.chat.utils.utils import get_all_bot_accounts
|
||||
from src.platform_io.drivers.legacy_driver import LegacyPlatformDriver
|
||||
|
||||
desired_accounts = get_all_bot_accounts()
|
||||
desired_platforms = set(desired_accounts.keys())
|
||||
current_platforms = set(self._legacy_send_drivers.keys())
|
||||
|
||||
for platform in sorted(current_platforms - desired_platforms):
|
||||
await self._remove_legacy_send_driver(platform)
|
||||
|
||||
for platform, account_id in desired_accounts.items():
|
||||
existing_driver = self._legacy_send_drivers.get(platform)
|
||||
if existing_driver is not None and existing_driver.descriptor.account_id == account_id:
|
||||
continue
|
||||
|
||||
if existing_driver is not None:
|
||||
await self._remove_legacy_send_driver(platform)
|
||||
|
||||
driver = LegacyPlatformDriver(
|
||||
driver_id=f"legacy.send.{platform}",
|
||||
platform=platform,
|
||||
account_id=account_id,
|
||||
)
|
||||
if self._started:
|
||||
await self.add_driver(driver)
|
||||
else:
|
||||
self.register_driver(driver)
|
||||
self._legacy_send_drivers[platform] = driver
|
||||
|
||||
async def _remove_legacy_send_driver(self, platform: str) -> None:
|
||||
"""移除指定平台的 legacy fallback driver。
|
||||
|
||||
Args:
|
||||
platform: 要移除的目标平台。
|
||||
"""
|
||||
driver = self._legacy_send_drivers.get(platform)
|
||||
if driver is None:
|
||||
return
|
||||
|
||||
if self._started:
|
||||
await self.remove_driver(driver.driver_id)
|
||||
else:
|
||||
self.unregister_driver(driver.driver_id)
|
||||
self._legacy_send_drivers.pop(platform, None)
|
||||
|
||||
def bind_send_route(self, binding: RouteBinding) -> None:
|
||||
"""为某个路由键绑定发送驱动。
|
||||
|
||||
@@ -353,7 +416,19 @@ class PlatformIOManager:
|
||||
driver = self._driver_registry.get(binding.driver_id)
|
||||
if driver is not None:
|
||||
drivers.append(driver)
|
||||
return drivers
|
||||
if drivers:
|
||||
return drivers
|
||||
|
||||
fallback_driver = self._legacy_send_drivers.get(route_key.platform)
|
||||
if fallback_driver is None:
|
||||
return []
|
||||
|
||||
descriptor = fallback_driver.descriptor
|
||||
if descriptor.account_id is not None and route_key.account_id not in (None, descriptor.account_id):
|
||||
return []
|
||||
if descriptor.scope is not None and route_key.scope not in (None, descriptor.scope):
|
||||
return []
|
||||
return [fallback_driver]
|
||||
|
||||
def resolve_driver(self, route_key: RouteKey) -> Optional[PlatformIODriver]:
|
||||
"""兼容旧接口,返回首个命中的发送驱动。"""
|
||||
|
||||
Reference in New Issue
Block a user