Skip to content

fix(gateway): suppress silent placeholder replies in live chats - #9956

Open
luoxiao6645 wants to merge 1 commit into
NousResearch:mainfrom
luoxiao6645:fix/gateway-silent-placeholder-replies-9840
Open

fix(gateway): suppress silent placeholder replies in live chats#9956
luoxiao6645 wants to merge 1 commit into
NousResearch:mainfrom
luoxiao6645:fix/gateway-silent-placeholder-replies-9840

Conversation

@luoxiao6645

Copy link
Copy Markdown

Summary

  • suppress exact silent placeholder replies in both live gateway response paths and streaming delivery
  • prevent (No message), (No reply), [SILENT], and similar silence markers from being sent to Discord and other live chat platforms
  • add regression coverage for non-streaming and streaming silent placeholder cases

Problem

In live gateway chats, the model can decide it should stay silent but still emit placeholder text such as (No message), (No reply), or [SILENT].

The gateway was treating those placeholders as normal text and delivering them to Discord instead of suppressing delivery entirely.

Root Cause

The original live reply path had no normalization step for silence markers before adapter delivery. After the initial fix, the non-streaming path was covered, but the streaming consumer could still send the same placeholders through its send/edit/commentary/fallback paths.

Changes

  • extract shared live-response normalization into gateway/response_filters.py
  • suppress exact silence markers before normal live response delivery
  • suppress the same markers in the queued follow-up first-response path
  • suppress the same markers in streaming send, edit, commentary, and fallback delivery paths
  • preserve real errors and non-placeholder content
  • add regression tests for non-streaming and streaming placeholder behavior

Testing

  • venv\\Scripts\\python -m pytest tests/gateway/test_live_silent_responses.py tests/gateway/test_stream_consumer.py -q -n 0

Closes #9840

@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 covering both final and streaming delivery paths. Current main has since landed the core protocol-marker fix: gateway/response_filters.py:19-24 defines explicit NO_REPLY/[SILENT] markers, gateway/run.py:12026-12036 suppresses only outbound delivery while preserving transcript alternation, and gateway/stream_consumer.py:597-650 prevents or retracts streamed marker previews.

Problems

  • tests/gateway/test_live_silent_responses.py:20 expects (empty) to be suppressed. Current main intentionally maps that sentinel to a visible exhausted-retry/model-failure explanation in gateway/run.py:11565-11575; suppressing it would hide a real error condition.
  • The proposed new normalizer duplicates the current shared filter rather than extending its explicit marker contract.

Suggested changes

  • Re-scope any salvage to demonstrated additional intentional-control markers, using is_intentional_silence_response() / is_partial_silence_marker(); do not classify (empty) as silence.

Automated hermes-sweeper review.

("[SILENT]", ""),
("`(No reply)`", ""),
("**(No response generated)**", ""),
("(empty)", ""),

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.

(empty) is not an intentional-silence token on current main: gateway/run.py:11565-11575 converts it to a visible exhausted-retry/model-failure explanation. Please remove this expectation so a real failure is not silently dropped.

@teknium1 teknium1 added sweeper:risk-message-delivery Sweeper risk: may drop, duplicate, misroute, or suppress messages sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform labels Jul 12, 2026
@gordan-bobic

Copy link
Copy Markdown

Shouldn't there be instructions for the AI for how to use response suppression strings? Just because the harness knows to suppress such output, it seems it isn't directly useful until the agent directly receives instructions for how to use this built in feature. Something similar to what is proposed here (adding instructions for this feature to agent/prompt_builder.py):

https://github.com/NousResearch/hermes-agent/pull/32879/changes#diff-ff9582231fc715be5184ad8a2ddcaf0c382df06245f7903542feb5ca41405904R181

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

Labels

comp/gateway Gateway runner, session dispatch, delivery P2 Medium — degraded but workaround exists platform/discord Discord bot adapter sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform sweeper:risk-message-delivery Sweeper risk: may drop, duplicate, misroute, or suppress messages type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Discord replying when it's (No message) instead of not sending any message

4 participants