78 lines
2.7 KiB
Python
78 lines
2.7 KiB
Python
"""消息总线(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()
|