Skip to content

fix(feishu): distinguish quote replies from topic sessions - #36233

Open
SergioYin wants to merge 1 commit into
NousResearch:mainfrom
SergioYin:pr/feishu-quote-topic-routing
Open

fix(feishu): distinguish quote replies from topic sessions#36233
SergioYin wants to merge 1 commit into
NousResearch:mainfrom
SergioYin:pr/feishu-quote-topic-routing

Conversation

@SergioYin

@SergioYin SergioYin commented Jun 1, 2026

Copy link
Copy Markdown

Problem

In normal conversation, quoting a message is intended to inject or emphasize context within the current conversation.

Previously, Feishu reply metadata such as root_id could be promoted into the Hermes thread route. As a result, an ordinary quote reply could be routed into a separate topic-scoped session. From the user's perspective, quoting a message unexpectedly opened a fresh context instead of reinforcing the current one.

Quote context versus session routing

What changed

This PR makes the distinction explicit in the active Feishu adapter at plugins/platforms/feishu/adapter.py:

  • quote metadata remains reply context;
  • an explicit thread_id selects a topic-scoped session;
  • ordinary DM and group quote replies remain in the current session;
  • the forum-only root_id compatibility fallback is preserved;
  • quoted text and media remain available to the agent as context.

In short:

Quoting adds context. It does not define a session boundary.

Behavior

  • Ordinary quote reply: continue the current DM/group session and attach the quoted message as context.
  • Explicit topic reply: route through the Feishu thread_id and continue the topic-scoped session.
  • Legacy forum payload: allow the scoped root_id fallback when an explicit thread_id is unavailable.

This avoids the previous behavior where quoting a message could silently move the user into a different Hermes session.

Changes made

  • plugins/platforms/feishu/adapter.py
    • Adds _resolve_inbound_thread_id() to centralize reply/topic routing semantics.
    • Separates the reply anchor from the session-routing identifier.
    • Preserves quoted text/media retrieval through the adapter's blocking-call executor.
  • tests/gateway/test_feishu.py
    • Adds regressions for ordinary DM/group replies, explicit topics, quoted media, and forum fallback behavior.
  • tests/gateway/test_run_progress_topics.py
    • Verifies ordinary Feishu quote replies do not receive topic progress metadata, while explicit topics retain it.
  • website/docs/user-guide/messaging/feishu.md
    • Documents quote-reply versus topic-routing behavior.

Related issue

Fixes #20548.

Related context: #20562, #29467, #30164, #20851.

Type of change

  • Bug fix
  • Documentation update
  • Tests added or improved
  • New feature
  • Refactor without behavior change

Validation

Relevant gateway test suite:

377 passed

Additional checks:

Ruff passed
Python compile checks passed
git diff --check passed

Tested on Ubuntu/WSL2 with a Feishu/Lark gateway, including real-workspace validation of quote replies and topic replies.

Checklist

  • The change targets the active plugin adapter.
  • The commit follows Conventional Commits.
  • The PR contains only changes related to this bug fix.
  • Regression tests cover the affected routing behavior.
  • Relevant documentation has been updated.
  • Cross-platform impact has been considered; no platform-specific filesystem behavior was added.

@alt-glitch alt-glitch added type/bug Something isn't working comp/gateway Gateway runner, session dispatch, delivery platform/feishu Feishu / Lark adapter P2 Medium — degraded but workaround exists labels Jun 1, 2026
@SergioYin

Copy link
Copy Markdown
Author

Thanks for triaging this. Quick reviewer context: this PR is intentionally narrow and fixes Feishu/Lark quoted-message routing so ordinary quote replies stay in the current DM/group session, while topic/thread routing remains preserved.

It also adds targeted gateway tests for quote replies, topic sessions, and the forum root_id fallback. Happy to adjust the approach if there is a preferred pattern for this subsystem.

@SergioYin
SergioYin force-pushed the pr/feishu-quote-topic-routing branch from 687c08d to 6e1b12b Compare June 5, 2026 04:57
@SergioYin

Copy link
Copy Markdown
Author

Rebased/refreshed this fork branch onto current main and verified the narrow Feishu/Lark routing fix locally.

Current state for review:

  • Head: 6e1b12b6b26717b5e2265463fe6dae9b183ea53a
  • git diff --check origin/main...HEAD: clean
  • python -m py_compile gateway/platforms/feishu.py tests/gateway/test_feishu.py tests/gateway/test_run_progress_topics.py: passed
  • python -m pytest tests/gateway/test_feishu.py tests/gateway/test_run_progress_topics.py -q -o 'addopts=': 239 passed, 2 warnings

The two warnings are existing websockets deprecation warnings from the Lark SDK path. The GitHub Actions runs are currently action_required because this is a fork PR and need maintainer approval to run.

@teknium1 teknium1 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the focused routing analysis. The underlying defect is still present on current main: plugins/platforms/feishu/adapter.py:3252 still promotes root_id into thread_id, and gateway/session.py:913-915 then creates a separate DM session key.

Problems

  • The PR edits gateway/platforms/feishu.py, but current main moved the active adapter to plugins/platforms/feishu/adapter.py in 5600105478ffde29d7566b45421b100eaa29c4ef. The old module is deleted, so this change does not reach the live adapter as written.
  • The new tests use the same obsolete module path. Current Feishu tests import plugins.platforms.feishu.adapter.

Suggested changes

  • Port the resolver and regression tests to plugins/platforms/feishu/adapter.py, replacing the current fallback at line 3252 while retaining root_id for reply_to_message_id at lines 3253-3259.

Automated hermes-sweeper review.

@@ -3072,14 +3072,34 @@ async def _process_inbound_message(
if hint:
text = f"{hint}\n\n{text}" if text else hint

thread_id = getattr(message, "thread_id", None) or getattr(message, "root_id", None) or None
chat_id = getattr(message, "chat_id", "") or ""

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Current main removed this module in 5600105478ffde29d7566b45421b100eaa29c4ef; the active adapter is plugins/platforms/feishu/adapter.py. Please port this routing change and its tests to that plugin path so the fix reaches the live inbound pipeline.

@teknium1 teknium1 added sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state sweeper:risk-message-delivery Sweeper risk: may drop, duplicate, misroute, or suppress messages sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform labels Jul 13, 2026
Keep ordinary Feishu/Lark quote replies in the current DM or group session while preserving quoted text/media as reply context. Preserve explicit topic/thread routing and keep a forum-scoped root_id fallback for older topic payloads.
@SergioYin
SergioYin force-pushed the pr/feishu-quote-topic-routing branch from 6e1b12b to ed93e5f Compare July 14, 2026 09:14
@SergioYin

Copy link
Copy Markdown
Author

Thanks for the review. I’ve ported the fix and its regression tests to the active Feishu adapter at plugins/platforms/feishu/adapter.py.

To restate the user-facing issue: in normal conversation, quoting a message is intended to inject or emphasize context within the current conversation. Previously, Feishu reply metadata such as root_id could be promoted into the Hermes thread route, causing an ordinary quote reply to be routed into a separate topic-scoped session. From the user’s perspective, quoting a message unexpectedly opened a fresh context instead of reinforcing the current one.

The updated implementation makes that distinction explicit: quote metadata remains reply context, while an explicit thread_id selects a topic-scoped session. The forum-only root_id compatibility fallback is preserved, and quoted text/media remain available as context.

The regression coverage now verifies that:

  • ordinary DM and group quote replies remain in the current session;
  • explicit thread_id messages continue to use topic sessions;
  • the forum compatibility fallback remains supported;
  • quoted text and media remain available as reply context.

Validation on the updated branch:

  • 377 relevant gateway tests passed;
  • Ruff passed;
  • Python compile checks passed;
  • git diff --check passed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/sessions Session lifecycle, resume, persistence, history comp/gateway Gateway runner, session dispatch, delivery P2 Medium — degraded but workaround exists platform/feishu Feishu / Lark adapter sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:risk-message-delivery Sweeper risk: may drop, duplicate, misroute, or suppress messages sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feishu] root_id fallback for thread_id causes all replies to be threaded

3 participants