Skip to content

[Feature] session_waiter 支持返回 MessageEventResult 以走完整消息装饰流程 #9548

Description

@Hiraeth-Wave

功能描述

当前 session_waiter 装饰的 handler 内部只能通过 await event.send(...) 发送消息,而 event.send 会绕过 ResultDecorateStage,导致"回复时 @ 发送者""回复时引用消息""分段回复""TTS""文本转图片"等用户配置的装饰功能在会话控制器场景下全部失效,破坏体验一致性。

文档示例也明确标注不能使用 yield,这是当前架构的限制。

根因

  • SessionWaiter.trigger 丢弃了 handler 的返回值(session_waiter.py#L169 原地 await 后无返回)。
  • @filter.event_message_type(filter.EventMessageType.ALL, priority=maxsize)
    async def handle_session_control_agent(self, event: AstrMessageEvent) -> None:
    """会话控制代理"""
    for session_filter in FILTERS:
    session_id = session_filter.filter(event)
    if session_id in USER_SESSIONS:
    await SessionWaiter.trigger(session_id, event)
    event.stop_event()

    handle_session_control_agent 在 trigger 后立即 event.stop_event(),使后续 ResultDecorateStage / RespondStage 被跳过。

建议方案

...然而要解决这个问题却仅仅只要 10 行改动:

  1. SessionWaiter.trigger 返回 handler 的返回值(NoneAny)。
  2. handle_session_control_agent 改为 Async Generator:当 trigger 返回 MessageEventResultyield 它,借助 Scheduler 的洋葱模型自动执行 ResultDecorateStageRespondStage;否则保持原 stop_event 行为。

且完全向后兼容:老插件在 waiter 内用 event.send 且不 return 的,handler 返回 None,走原 stop_event 路径,行为不变。新插件只需把 await event.send(event.plain_result(...)) 改写为 return event.plain_result(...) 即可享受完整装饰流程。

使用场景

任何使用 session_waiter 的多轮会话插件,典型如成语接龙、问答游戏、分步表单收集等。以成语接龙为例:

改前(装饰功能失效):

@session_waiter(timeout=60)
async def idiom_waiter(controller: SessionController, event: AstrMessageEvent):
    # ...
    await event.send(event.plain_result("先见之明"))  # 不走 @回复 / 引用 / 分段
    controller.keep(timeout=60, reset_timeout=True)

改后(装饰功能生效):

@session_waiter(timeout=60)
async def idiom_waiter(controller: SessionController, event: AstrMessageEvent):
    # ...
    controller.keep(timeout=60, reset_timeout=True)
    return event.plain_result("先见之明")  # 自动走 @回复 / 引用 / 分段 / TTS / 转图

检查清单

  • 我已在 Issue 列表中搜索过相关功能,确认该功能想法从未被提出过。
  • 我建议的功能与 AstrBot 本体相关,而非在建议某一插件的功能。
  • 我已阅读并同意本项目的贡献者行为准则
  • (可选)我愿意提交 PR 以帮助实现该功能。

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:coreThe bug / feature is about astrbot's core, backendenhancementNew feature or requestfeature:pluginThe bug / feature is about AstrBot plugin system.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions