"""消息总线(MessageBus):用异步队列解耦“渠道层”和“Agent 核心层”。 核心思想: 1. 渠道(Telegram/Discord/CLI 等)只负责收发消息,不直接调用 Agent 内部逻辑 2. Agent 只关心“从入站队列取消息、处理后写回出站队列” 3. 通过队列实现生产者/消费者解耦,提升并发稳定性与可维护性 为什么需要两个队列: - inbound:渠道 -> Agent - outbound:Agent -> 渠道 """ import asyncio from nanobot.bus.events import InboundMessage, OutboundMessage class MessageBus: """ 异步消息总线。 典型流转: - 渠道监听到用户消息后调用 `publish_inbound` - Agent 主循环调用 `consume_inbound` 拿到消息并处理 - Agent 产出回复后调用 `publish_outbound` - 渠道管理器调用 `consume_outbound` 并把回复发送到对应平台 """ def __init__(self): # 入站队列:存放所有“用户 -> Agent”的消息事件。 self.inbound: asyncio.Queue[InboundMessage] = asyncio.Queue() # 出站队列:存放所有“Agent -> 用户”的回复事件。 self.outbound: asyncio.Queue[OutboundMessage] = asyncio.Queue() async def publish_inbound(self, msg: InboundMessage) -> None: """发布入站消息(由渠道层调用)。 参数: - msg: 一个 InboundMessage,包含 channel/sender/chat_id/content 等信息 """ # put 是异步的:当队列受限时可自然背压;当前默认无长度上限。 await self.inbound.put(msg) async def consume_inbound(self) -> InboundMessage: """消费下一条入站消息(由 Agent 主循环调用)。 行为: - 若队列为空会等待(阻塞当前协程,不阻塞事件循环) """ return await self.inbound.get() async def publish_outbound(self, msg: OutboundMessage) -> None: """发布出站消息(由 Agent 调用)。 参数: - msg: 一个 OutboundMessage,包含目标 channel/chat_id 与内容 """ await self.outbound.put(msg) async def consume_outbound(self) -> OutboundMessage: """消费下一条出站消息(由渠道分发器调用)。 行为: - 若队列为空会等待,直到 Agent 写入新的回复 """ return await self.outbound.get() @property def inbound_size(self) -> int: """当前入站队列长度(待处理消息数)。""" # 常用于监控/调试:判断是否出现消息堆积。 return self.inbound.qsize() @property def outbound_size(self) -> int: """当前出站队列长度(待发送回复数)。""" return self.outbound.qsize()