Skip to content

fix(gateway): always inject reply-to pointer, not just when quoted text is absent - #13676

Merged
teknium1 merged 1 commit into
mainfrom
hermes/hermes-ac879c8b
Apr 21, 2026
Merged

fix(gateway): always inject reply-to pointer, not just when quoted text is absent#13676
teknium1 merged 1 commit into
mainfrom
hermes/hermes-ac879c8b

Conversation

@teknium1

Copy link
Copy Markdown
Contributor

Summary

The [Replying to: "..."] prefix is disambiguation, not deduplication — it must be injected whenever the user explicitly replies, even if the quoted text already appears in history.

Root cause

_prepare_inbound_message_text in gateway/run.py gated the prefix on found_in_history (introduced in #1594). Intent was to avoid redundancy, but history can contain the same or similar text multiple times, and the prefix's job is to point to which prior message the user is referencing — not to supply the text. When the guard suppresses the prefix, the agent sees a bare user message and has to guess.

Concrete failure (thanks @smartYi for flagging):

User discusses Japan vs Italy. Agent describes both. User replies to the Japan message: "What's the best time to go?" — both destinations are in history, guard fires, prefix dropped, agent answers for the wrong one or both.

Changes

  • gateway/run.py: drop found_in_history check; always prepend [Replying to: "..."] when reply_to_text and reply_to_message_id are set. Comment explains why.
  • tests/gateway/test_reply_to_injection.py (new): 5 tests covering prefix present when quoted text is absent from history, prefix still present when quoted text IS in history (regression guard), no prefix without reply context, no prefix when reply_to_text is empty, 500-char snippet truncation.

Validation

Before After
Reply to unique prior turn pointer injected pointer injected
Reply to turn whose text appears elsewhere in history pointer dropped, agent guesses pointer injected, unambiguous
No reply context no prefix no prefix
reply_to_text is None no prefix no prefix

scripts/run_tests.sh tests/gateway/test_reply_to_injection.py tests/gateway/test_shared_group_sender_prefix.py — 7 passed.

Cost

Token overhead is minimal: snippet capped at 500 chars, applied only to the new user turn, cached prefix unaffected. Behavior becomes deterministic: reply sent ⇒ pointer present.

…xt is absent

The [Replying to: "..."] prefix is disambiguation, not deduplication. When
a user explicitly replies to a prior message, the agent needs a pointer to
which specific message they're referencing — even when the quoted text
already exists somewhere in history. History can contain the same or
similar text multiple times; without an explicit pointer the agent has to
guess (or answer for both subjects), and the reply signal is silently
dropped.

Example: in a conversation comparing Japan and Italy, replying to the
"Japan is great for culture..." message and asking "What's the best time
to go?" — previously the found_in_history check suppressed the prefix
because the quoted text was already in history, leaving the agent to
guess which destination the user meant. Now the pointer is always present.

Drops the found_in_history guard added in #1594. Token overhead is
minimal (snippet capped at 500 chars on the new user turn; cached prefix
unaffected). Behavior becomes deterministic: reply sent ⇒ pointer present.

Thanks to smartyi for flagging this.
@teknium1
teknium1 merged commit e889332 into main Apr 21, 2026
10 of 11 checks passed
@teknium1
teknium1 deleted the hermes/hermes-ac879c8b branch April 21, 2026 20:33
@alt-glitch alt-glitch added type/bug Something isn't working comp/gateway Gateway runner, session dispatch, delivery labels Apr 21, 2026
aj-nt pushed a commit to aj-nt/hermes-agent that referenced this pull request May 1, 2026
…xt is absent (NousResearch#13676)

The [Replying to: "..."] prefix is disambiguation, not deduplication. When
a user explicitly replies to a prior message, the agent needs a pointer to
which specific message they're referencing — even when the quoted text
already exists somewhere in history. History can contain the same or
similar text multiple times; without an explicit pointer the agent has to
guess (or answer for both subjects), and the reply signal is silently
dropped.

Example: in a conversation comparing Japan and Italy, replying to the
"Japan is great for culture..." message and asking "What's the best time
to go?" — previously the found_in_history check suppressed the prefix
because the quoted text was already in history, leaving the agent to
guess which destination the user meant. Now the pointer is always present.

Drops the found_in_history guard added in NousResearch#1594. Token overhead is
minimal (snippet capped at 500 chars on the new user turn; cached prefix
unaffected). Behavior becomes deterministic: reply sent ⇒ pointer present.

Thanks to smartyi for flagging this.
Luminet2023 pushed a commit to Luminet2023/hermes-agent that referenced this pull request May 1, 2026
…xt is absent (NousResearch#13676)

The [Replying to: "..."] prefix is disambiguation, not deduplication. When
a user explicitly replies to a prior message, the agent needs a pointer to
which specific message they're referencing — even when the quoted text
already exists somewhere in history. History can contain the same or
similar text multiple times; without an explicit pointer the agent has to
guess (or answer for both subjects), and the reply signal is silently
dropped.

Example: in a conversation comparing Japan and Italy, replying to the
"Japan is great for culture..." message and asking "What's the best time
to go?" — previously the found_in_history check suppressed the prefix
because the quoted text was already in history, leaving the agent to
guess which destination the user meant. Now the pointer is always present.

Drops the found_in_history guard added in NousResearch#1594. Token overhead is
minimal (snippet capped at 500 chars on the new user turn; cached prefix
unaffected). Behavior becomes deterministic: reply sent ⇒ pointer present.

Thanks to smartyi for flagging this.
Luminet2023 added a commit to Luminet2023/hermes-agent that referenced this pull request May 1, 2026
* upstream/main: (160 commits)
  feat(llm-wiki): port provenance markers, source hashing, and quality signals from llm-wiki-compiler (NousResearch#13700)
  fix(vision): restore tier-aware Nous vision model selection (NousResearch#13703)
  fix(vision): route Nous main-provider vision through tier-aware backend
  test(approval): regression guards for thread-local callback contract
  fix(security): TUI approval overlay accepts blind keystrokes, CLI thread-local callback invisible to agent
  chore(release): add Ifkellx to AUTHOR_MAP for PR NousResearch#12687
  fix(vision): resolve Nous vision model correctly in auto-detect path
  docs(delegate): clarify that the parent agent, not the user, populates goal/context (NousResearch#13698)
  fix(auxiliary): refresh Nous runtime credentials after aux 401s
  feat(delegate): orchestrator role and configurable spawn depth (default flat)
  fix(tui): inject VS16 so text-default emoji render as color glyphs
  feat(gateway): recognize .pdf in MEDIA: tag extraction (NousResearch#13683)
  test(delegate): make default_toolsets regression test robust to user config
  docs(delegate): remove default_toolsets from example config and docs
  refactor(delegate): drop dead default_toolsets from CLI default config
  feat(image-gen): add GPT Image 2 to FAL catalog (NousResearch#13677)
  fix(gateway): always inject reply-to pointer, not just when quoted text is absent (NousResearch#13676)
  fix(skills/llama-cpp): concise description, restore python bindings, fix curl
  improve llama.cpp skill
  fix(tui): route skills.manage through the long-handler thread pool
  ...

# Conflicts:
#	tools/file_tools.py
#	uv.lock
02356abc pushed a commit to 02356abc/hermes-agent that referenced this pull request May 14, 2026
…xt is absent (NousResearch#13676)

The [Replying to: "..."] prefix is disambiguation, not deduplication. When
a user explicitly replies to a prior message, the agent needs a pointer to
which specific message they're referencing — even when the quoted text
already exists somewhere in history. History can contain the same or
similar text multiple times; without an explicit pointer the agent has to
guess (or answer for both subjects), and the reply signal is silently
dropped.

Example: in a conversation comparing Japan and Italy, replying to the
"Japan is great for culture..." message and asking "What's the best time
to go?" — previously the found_in_history check suppressed the prefix
because the quoted text was already in history, leaving the agent to
guess which destination the user meant. Now the pointer is always present.

Drops the found_in_history guard added in NousResearch#1594. Token overhead is
minimal (snippet capped at 500 chars on the new user turn; cached prefix
unaffected). Behavior becomes deterministic: reply sent ⇒ pointer present.

Thanks to smartyi for flagging this.
exiao added a commit to exiao/hermes-agent that referenced this pull request May 29, 2026
…test

- test_reply_snippet_truncated_to_500_chars -> _to_2000_chars (matches new cap)
- Fix pre-existing failure: test_no_prefix_when_reply_to_text_is_empty asserted
  no prefix, but NousResearch#13676 changed behavior to always inject a no-text pointer.
  Renamed to test_no_text_reply_injects_generic_pointer and updated assertions.
gweeteve pushed a commit to gweeteve/hermes-agent that referenced this pull request Jun 2, 2026
…xt is absent (NousResearch#13676)

The [Replying to: "..."] prefix is disambiguation, not deduplication. When
a user explicitly replies to a prior message, the agent needs a pointer to
which specific message they're referencing — even when the quoted text
already exists somewhere in history. History can contain the same or
similar text multiple times; without an explicit pointer the agent has to
guess (or answer for both subjects), and the reply signal is silently
dropped.

Example: in a conversation comparing Japan and Italy, replying to the
"Japan is great for culture..." message and asking "What's the best time
to go?" — previously the found_in_history check suppressed the prefix
because the quoted text was already in history, leaving the agent to
guess which destination the user meant. Now the pointer is always present.

Drops the found_in_history guard added in NousResearch#1594. Token overhead is
minimal (snippet capped at 500 chars on the new user turn; cached prefix
unaffected). Behavior becomes deterministic: reply sent ⇒ pointer present.

Thanks to smartyi for flagging this.
waefrebeorn pushed a commit to waefrebeorn/slermes that referenced this pull request Jul 2, 2026
…xt is absent (NousResearch#13676)

The [Replying to: "..."] prefix is disambiguation, not deduplication. When
a user explicitly replies to a prior message, the agent needs a pointer to
which specific message they're referencing — even when the quoted text
already exists somewhere in history. History can contain the same or
similar text multiple times; without an explicit pointer the agent has to
guess (or answer for both subjects), and the reply signal is silently
dropped.

Example: in a conversation comparing Japan and Italy, replying to the
"Japan is great for culture..." message and asking "What's the best time
to go?" — previously the found_in_history check suppressed the prefix
because the quoted text was already in history, leaving the agent to
guess which destination the user meant. Now the pointer is always present.

Drops the found_in_history guard added in NousResearch#1594. Token overhead is
minimal (snippet capped at 500 chars on the new user turn; cached prefix
unaffected). Behavior becomes deterministic: reply sent ⇒ pointer present.

Thanks to smartyi for flagging this.
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 type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants