fix: only prefix voice-transcribed messages with [Voice input...] prefix (#65827) - #65961
webtecnica wants to merge 1 commit into
Conversation
Related to #11744, which already provides broader structured CLI input-origin routing. This PR focuses on the voice-prefix provenance path; the implementations should be compared before choosing a canonical fix. |
tonydwb
left a comment
There was a problem hiding this comment.
Looks good. No obvious issues found.
Reviewed by Hermes Agent
4c612e9 to
cc9e4f6
Compare
teknium1
left a comment
There was a problem hiding this comment.
Thanks for isolating a real current-main bug: cli.py:11440 queues STT text without origin metadata, and cli.py:12466 prefixes every string when voice mode is active.
Problems
- The proposed
_VoiceInputMessageatcli.py:3727is insideHermesCLI.__init__'s docstring (cli.py:3724-3738), so it is not defined at runtime. The proposed transcription path therefore cannot construct it. - The proposed
self.chat(..., voice_input=is_voice_input)call atcli.py:15534has no matching signature change; currentchat()is defined atcli.py:12225with onlymessageandimages. user_input = str(msg)at proposedcli.py:15428converts existing(text, images)payloads to strings before the tuple handling. The composer creates those payloads atcli.py:13756and queues them atcli.py:13814.
Suggested changes
- Put the origin wrapper at module scope, add a defaulted
voice_inputargument tochat(), and normalize wrapped, legacy string, and(text, images)payloads without stringifying tuples. - Add production-path regressions for STT, typed input while voice mode is on, and typed image attachments.
This is an automated hermes-sweeper review.
| """ | ||
| Initialize the Hermes CLI. | ||
|
|
||
|
|
There was a problem hiding this comment.
__init__'s triple-quoted docstring is still open here (it closes after the existing Args block), so this class declaration becomes docstring text rather than a runtime definition. Move the sentinel to module scope before HermesCLI.
| @@ -15414,7 +15426,9 @@ def process_loop(): | |||
| try: | |||
| # Check for pending input with timeout | |||
| try: | |||
There was a problem hiding this comment.
This stringifies legacy (text, images) queue payloads before the existing tuple branch below can unpack them. Preserve tuples during normalization so image attachments continue to reach chat().
| @@ -15520,7 +15534,7 @@ def process_loop(): | |||
| app.invalidate() # Refresh status line | |||
There was a problem hiding this comment.
HermesCLI.chat is unchanged in this diff and currently accepts only message and images (cli.py:12225), so this keyword raises TypeError. Add a backward-compatible defaulted parameter to the method signature.
… instruction (NousResearch#65827) Typed messages sent while voice mode was active were also getting the '[Voice input — respond concisely...]' API-local prefix, because the gate checked only self._voice_mode. Route STT transcripts through a _VoiceInputMessage sentinel in _pending_input (both the PTT/continuous transcription path and the barge-in utterance path), unwrap it in process_loop, and thread voice_input= through chat() so the prefix applies only to genuinely voice-transcribed messages. Re-cut of PR NousResearch#65961 (@webtecnica) — the original diff had the sentinel class embedded inside __init__'s docstring. Credit also to the earliest route-by-origin attempt in PR NousResearch#11744 (@KeroZelvin). Fixes NousResearch#65827 Closes NousResearch#65961 Closes NousResearch#11744
… instruction (NousResearch#65827) Typed messages sent while voice mode was active were also getting the '[Voice input — respond concisely...]' API-local prefix, because the gate checked only self._voice_mode. Route STT transcripts through a _VoiceInputMessage sentinel in _pending_input (both the PTT/continuous transcription path and the barge-in utterance path), unwrap it in process_loop, and thread voice_input= through chat() so the prefix applies only to genuinely voice-transcribed messages. Re-cut of PR NousResearch#65961 (@webtecnica) — the original diff had the sentinel class embedded inside __init__'s docstring. Credit also to the earliest route-by-origin attempt in PR NousResearch#11744 (@KeroZelvin). Fixes NousResearch#65827 Closes NousResearch#65961 Closes NousResearch#11744
… instruction (NousResearch#65827) Typed messages sent while voice mode was active were also getting the '[Voice input — respond concisely...]' API-local prefix, because the gate checked only self._voice_mode. Route STT transcripts through a _VoiceInputMessage sentinel in _pending_input (both the PTT/continuous transcription path and the barge-in utterance path), unwrap it in process_loop, and thread voice_input= through chat() so the prefix applies only to genuinely voice-transcribed messages. Re-cut of PR NousResearch#65961 (@webtecnica) — the original diff had the sentinel class embedded inside __init__'s docstring. Credit also to the earliest route-by-origin attempt in PR NousResearch#11744 (@KeroZelvin). Fixes NousResearch#65827 Closes NousResearch#65961 Closes NousResearch#11744
Fixes CLI voice mode incorrectly prefixing typed messages with '[Voice input...]'.
Root cause: chat() used (global flag) instead of checking whether the specific message was voice-transcribed.
Fix: Added sentinel class to wrap STT transcripts in . process_loop unwraps the sentinel and passes to chat(). chat() uses the parameter instead of the global flag.
Closes #65827