fix(clarify): remove awaiting_text filter from get_pending_for_session so text-intercept works on platforms without buttons#26008
Conversation
The get_pending_for_session() function filters entries by awaiting_text=True,
which means choice-based clarifies (awaiting_text=False) are invisible to the
gateway text-intercept. On platforms without native button support (Discord,
Slack, WhatsApp, etc.), the base send_clarify renders choices as a numbered
text list, and the user's reply ("1", "2", etc.) is never intercepted —
the clarify hangs until the 10-minute timeout.
Fix: remove the awaiting_text filter so get_pending_for_session returns
the oldest pending clarify entry regardless of its text-capture mode.
This is safe because:
- Button-based platforms (Telegram) resolve via callbacks first,
removing the entry before text-intercept runs
- The text-intercept already handles both choice and free-text responses
- All existing confirm paths ("Other" button → mark_awaiting_text → resolve)
still work correctly
PoC: https://github.com/Caixa-git/hermes-agent/tree/fix/clarify-text-intercept-awaiting-text
Docker: docker run --rm ghcr.io/caixa-git/poc-clarify
Fixes: #TBD
|
Competes with #25584 and #25610 for the same underlying bug (#25567 / #26009). Approach difference: This PR removes the |
|
Cross-checking against #25584 (@liuhao1024) since alt-glitch already linked them — adding mechanism-level comparison since they make different bets:
#25584 is the more mechanism-aligned fix (state flag flips at the boundary that actually changes mode), but it relies on platform overrides correctly NOT reaching the base path — which is the implicit contract today. #26008 makes the bug impossible at the read site at the cost of the bit losing one of its meanings. Maintainer's call between "tighten the contract at the writer" vs "make the reader more permissive". Both fix the user-visible symptom; the test diff shows #26008 already updated |
…ttons Re-triggering CI / re-review. The PR body has been cleaned up to follow the upstream PR template (see the inline re-review-request comment on PR NousResearch#40045 for the proposed new body). No code change. Fixes NousResearch#26009 Refs NousResearch#12573 Complements NousResearch#26008
Cross-link: a complementary adapter-side fix is in #41353Heads-up: there's a related fix in #41353 ( What #41353 does
Compatibility with #26008The two PRs are complementary, not conflicting:
Order of merging:
Neither PR modifies the other's diff. No merge conflicts expected. Suggested actionEither order is fine, but a maintainer looking at #26008 might want to coordinate with #41353 to merge them together. I'm fine with whichever lands first — just wanted to flag the overlap so the two don't get reviewed in isolation and miss the cross-platform implication. Also: the related P1 bug is filed as #26009 ( |
|
This appears to be implemented on current main already, via the narrower writer-side fix from the competing clarify PR rather than by removing the reader-side Automated hermes-sweeper review evidence:
Thanks for the clear root-cause writeup and the safety notes here. The mainline fix preserves the |
Problem
When the agent calls
clarifywith multiple choices on platforms that don't support native buttons (Discord, Slack, WhatsApp, etc.), the clarify hangs indefinitely with⏳ Still working...messages until the 10-minute timeout.Root Cause
tools/clarify_gateway.py:get_pending_for_session()filters entries byawaiting_text=True. Choice-based clarifies are registered withawaiting_text=False(because the button path handles them on Telegram). On Discord, the basesend_clarifyrenders choices as a numbered text list, but the user's reply ("1","Option A") is never intercepted — the function returnsNoneand the agent stays blocked onwait_for_response().Fix
Removed the
awaiting_textfilter fromget_pending_for_session(). It now returns the oldest pending clarify entry regardless of its text-capture mode.Safety
resolve_gateway_clarify()directly, removing the entry from_entriesbefore the text-intercept runs. No double-resolution.awaiting_textflag preserved: Still used correctly for tracking "Other" button state. Just no longer gates retrieval.PoC
PoC output confirms:
get_pending_for_session()returned None for choice-based clarify