From 08c5ce95f265c84c96b876cac80885a0c0e54e66 Mon Sep 17 00:00:00 2001 From: chengyongru <2755839590@qq.com> Date: Mon, 20 Apr 2026 00:07:25 +0800 Subject: [PATCH] feat(feishu): per-message session for group top-level messages Align with deer-flow: group top-level messages (no root_id) now get their own session keyed by message_id instead of sharing a single group-wide session. Topic replies continue to share session via root_id. --- nanobot/channels/feishu.py | 8 ++++---- tests/channels/test_feishu_reply.py | 7 +++---- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/nanobot/channels/feishu.py b/nanobot/channels/feishu.py index 6f3503236..457f83854 100644 --- a/nanobot/channels/feishu.py +++ b/nanobot/channels/feishu.py @@ -1728,11 +1728,11 @@ class FeishuChannel(BaseChannel): return # Build topic-scoped session key for conversation isolation. - # Group chat: thread replies (root_id != message_id) get a scoped - # session so each Feishu thread has its own conversation context. + # Group chat: each topic gets its own session via root_id (replies + # inside a topic) or message_id (top-level messages start a new topic). # Private chat: no override — same behavior as Telegram/Slack. - if chat_type == "group" and root_id and root_id != message_id: - session_key = f"feishu:{chat_id}:{root_id}" + if chat_type == "group": + session_key = f"feishu:{chat_id}:{root_id or message_id}" else: session_key = None diff --git a/tests/channels/test_feishu_reply.py b/tests/channels/test_feishu_reply.py index c09d4ae55..9ce8cb357 100644 --- a/tests/channels/test_feishu_reply.py +++ b/tests/channels/test_feishu_reply.py @@ -480,8 +480,8 @@ async def test_session_key_group_with_root_id_is_thread_scoped() -> None: @pytest.mark.asyncio -async def test_session_key_group_no_root_id_uses_default() -> None: - """Group message without root_id uses default session key (no override).""" +async def test_session_key_group_no_root_id_uses_message_id() -> None: + """Group message without root_id gets session keyed by message_id (per-message session).""" channel = _make_feishu_channel(group_policy="open") bus_spy = [] original_publish = channel.bus.publish_inbound @@ -504,8 +504,7 @@ async def test_session_key_group_no_root_id_uses_default() -> None: await channel._on_message(event) assert len(bus_spy) == 1 - assert bus_spy[0].session_key_override is None - assert bus_spy[0].session_key == "feishu:oc_abc" + assert bus_spy[0].session_key == "feishu:oc_abc:om_001" @pytest.mark.asyncio