fix(cli): route voice reply behavior by input origin - #11744
Conversation
teknium1
left a comment
There was a problem hiding this comment.
Thanks for the focused voice-routing fix. The current remote main still queues STT as an unmarked string (cli.py:11293) and applies the voice prefix/TTS based solely on mode state (cli.py:12291, cli.py:12715), so the core premise is valid.
Problems
- The changed enqueue payload will break the unmodified clipboard regression:
tests/tools/test_clipboard.py:1082still expects"hello", while this PR changes the payload to(transcript, [], "voice"). voice.message_reply_modeis user-facing config, but the CLI voice config reference atwebsite/docs/user-guide/configuration.md:1574-1581is not updated.
Suggested changes
- Update the clipboard test and add an end-to-end typed-turn assertion for
voice_onlyrouting. - Document
message_reply_modeand its accepted values.
This is an automated hermes-sweeper review.
| if hasattr(self, '_app') and self._app: | ||
| self._app.invalidate() | ||
| self._pending_input.put(transcript) | ||
| self._pending_input.put((transcript, [], "voice")) |
There was a problem hiding this comment.
Please also update tests/tools/test_clipboard.py:1082: it exercises this same successful-transcription path and still asserts the old raw-string queue payload, so it will fail after this three-tuple change.
b9005f8 to
0694614
Compare
|
Rebased and refactored onto current Teknium1 feedback is addressed:
The old tuple extension was refactored into a typed queued-turn object plus one normalization boundary. The conflict resolution preserves current-main Verification:
The full repository suite was attempted but has unrelated baseline/environment failures and timed out; no failure implicated this PR's changed paths. |
|
@KeroZelvin this fixes #65827. When you get a chance can you link that issue to avoid others picking it up and attempting the same fix? |
|
Thanks for catching that — I’ve linked #65827 in the PR body with |
… 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
Bug Description
The classic CLI voice path did not distinguish typed turns from STT-originated turns while voice mode was enabled. Typed prompts could therefore inherit the concise voice-only prompt and spoken-output behavior, and the old routing attempt lacked a complete input-origin path.
Related Issue
Fixes #65827
Current-Main Validation
The bug remains present on current upstream
main(7b5ba2054721dde998ed47fd4a0f031955278e99):_voice_stop_and_transcribe()queues STT output as an unmarked string.(text, images)tuples.chat()gates its voice prefix and both streaming/batch TTS only on global voice/TTS state.Newer gateway message-type routing and provider-level streaming TTS do not carry origin metadata into the classic CLI, so they do not supersede this fix.
Fix
_CLIQueuedInputpayload and_CLIInputOriginenum.(text, images)queue payloads at one process-loop boundary.chat().voice.message_reply_mode.persist_user_message._voice_speak_response_async()completion signaling, beep configuration, transcription-failure recording retention, terminal-input recovery, and legacy image queue handling.Teknium1 Feedback Addressed
tests/tools/test_clipboard.pyfor the structured STT queue payload.voice_onlymicrophone turns are spoken and typed turns remain unprefixed, do not initialize streaming TTS, and do not invoke batch TTS.voice.message_reply_mode, accepted values (all,voice_only), default behavior, CLI scope, and TTS-disabled behavior in both CLI configuration and voice-mode documentation._clear_current_inputhelper from the old patch.Test Plan
250 passedacrosstests/cli/test_cli_init.py,tests/tools/test_voice_cli_integration.py, andtests/tools/test_clipboard.py.117 passedacrosstests/tools/test_voice_mode.pyandtests/hermes_cli/test_voice_wrapper.py.git diff --checkpassed.main; conflicts resolved semantically.A repository-wide test run was also attempted. The full suite has unrelated baseline/environment failures and did not complete within ten minutes; no failure implicated these changed paths.
Risk Assessment
Low-to-moderate and localized to classic CLI queue normalization and voice-output policy. Legacy string and
(text, images)payloads remain supported, the defaultmessage_reply_mode: allpreserves existing spoken-output behavior, and newer async TTS completion handling remains intact.