Skip to content

fix: only prefix voice-transcribed messages with [Voice input...] prefix (#65827) - #65961

Closed
webtecnica wants to merge 1 commit into
NousResearch:mainfrom
webtecnica:fix/65827-cli-voice-typed
Closed

webtecnica wants to merge 1 commit into
NousResearch:mainfrom
webtecnica:fix/65827-cli-voice-typed

Conversation

@webtecnica

Copy link
Copy Markdown
Contributor

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

@alt-glitch alt-glitch added type/bug Something isn't working comp/cli CLI entry point, hermes_cli/, setup wizard P3 Low — cosmetic, nice to have labels Jul 16, 2026
@alt-glitch

Copy link
Copy Markdown
Contributor

This was generated by AI during triage.

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 tonydwb left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Looks good. No obvious issues found.


Reviewed by Hermes Agent

@webtecnica
webtecnica force-pushed the fix/65827-cli-voice-typed branch from 4c612e9 to cc9e4f6 Compare July 18, 2026 01:55

@teknium1 teknium1 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

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 _VoiceInputMessage at cli.py:3727 is inside HermesCLI.__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 at cli.py:15534 has no matching signature change; current chat() is defined at cli.py:12225 with only message and images.
  • user_input = str(msg) at proposed cli.py:15428 converts existing (text, images) payloads to strings before the tuple handling. The composer creates those payloads at cli.py:13756 and queues them at cli.py:13814.

Suggested changes

  • Put the origin wrapper at module scope, add a defaulted voice_input argument to chat(), 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.

Comment thread cli.py
"""
Initialize the Hermes CLI.


Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

__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.

Comment thread cli.py
@@ -15414,7 +15426,9 @@ def process_loop():
try:
# Check for pending input with timeout
try:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

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().

Comment thread cli.py
@@ -15520,7 +15534,7 @@ def process_loop():
app.invalidate() # Refresh status line

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

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.

@teknium1 teknium1 added 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 18, 2026
@teknium1 teknium1 closed this in 0062107 Jul 28, 2026
randlee pushed a commit to randlee/hermes-agent that referenced this pull request Aug 11, 2026
… 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
prmartinow pushed a commit to prmartinow/hermes-agent that referenced this pull request Aug 26, 2026
… 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
melon-xf added a commit to melon-xf/hermes-agent that referenced this pull request Sep 3, 2026
… 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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/cli CLI entry point, hermes_cli/, setup wizard P3 Low — cosmetic, nice to have 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 type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

CLI voice mode marks typed messages as voice input

4 participants