fix(tui): clear TTS env var on voice off, and add TTS indicator to status bar
Bug 1: /voice off in TUI mode did not clear HERMES_VOICE_TTS, leaving TTS stuck ON with no way to disable it (the voice.toggle tts handler requires voice mode to be ON). Bug 2: TUI status bar only showed 'voice on/off' without any indication of whether TTS speech output is active, because the frontend never tracked voiceTts state. - tui_gateway/server.py: clear HERMES_VOICE_TTS when voice is turned off - ui-tui/src/app/useMainApp.ts: add voiceTts state, thread setVoiceTts through voice contexts, display [tts] in status bar - ui-tui/src/app/slash/commands/session.ts: sync tts from voice.toggle response - ui-tui/src/app/interfaces.ts: add setVoiceTts to all voice context interfaces
This commit is contained in:
@@ -216,6 +216,7 @@ export interface InputHandlerContext {
|
||||
setProcessing: StateSetter<boolean>
|
||||
setRecording: StateSetter<boolean>
|
||||
setVoiceEnabled: StateSetter<boolean>
|
||||
setVoiceTts: StateSetter<boolean>
|
||||
}
|
||||
wheelStep: number
|
||||
}
|
||||
@@ -254,6 +255,7 @@ export interface GatewayEventHandlerContext {
|
||||
setProcessing: StateSetter<boolean>
|
||||
setRecording: StateSetter<boolean>
|
||||
setVoiceEnabled: StateSetter<boolean>
|
||||
setVoiceTts: StateSetter<boolean>
|
||||
}
|
||||
}
|
||||
|
||||
@@ -296,6 +298,7 @@ export interface SlashHandlerContext {
|
||||
voice: {
|
||||
setVoiceEnabled: StateSetter<boolean>
|
||||
setVoiceRecordKey: (v: ParsedVoiceRecordKey) => void
|
||||
setVoiceTts: StateSetter<boolean>
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -232,6 +232,7 @@ export const sessionCommands: SlashCommand[] = [
|
||||
ctx.gateway.rpc<VoiceToggleResponse>('voice.toggle', { action }).then(
|
||||
ctx.guarded<VoiceToggleResponse>(r => {
|
||||
ctx.voice.setVoiceEnabled(!!r.enabled)
|
||||
ctx.voice.setVoiceTts(!!r.tts)
|
||||
|
||||
// Render the configured record key (config.yaml ``voice.record_key``)
|
||||
// instead of hardcoded "Ctrl+B" — the gateway response carries the
|
||||
|
||||
@@ -102,6 +102,7 @@ export function useMainApp(gw: GatewayClient) {
|
||||
const [stickyPrompt, setStickyPrompt] = useState('')
|
||||
const [catalog, setCatalog] = useState<null | SlashCatalog>(null)
|
||||
const [voiceEnabled, setVoiceEnabled] = useState(false)
|
||||
const [voiceTts, setVoiceTts] = useState(false)
|
||||
const [voiceRecording, setVoiceRecording] = useState(false)
|
||||
const [voiceProcessing, setVoiceProcessing] = useState(false)
|
||||
const [voiceRecordKey, setVoiceRecordKey] = useState<ParsedVoiceRecordKey>(DEFAULT_VOICE_RECORD_KEY)
|
||||
@@ -555,7 +556,8 @@ export function useMainApp(gw: GatewayClient) {
|
||||
recording: voiceRecording,
|
||||
setProcessing: setVoiceProcessing,
|
||||
setRecording: setVoiceRecording,
|
||||
setVoiceEnabled
|
||||
setVoiceEnabled,
|
||||
setVoiceTts
|
||||
},
|
||||
wheelStep: WHEEL_SCROLL_STEP
|
||||
})
|
||||
@@ -579,7 +581,8 @@ export function useMainApp(gw: GatewayClient) {
|
||||
voice: {
|
||||
setProcessing: setVoiceProcessing,
|
||||
setRecording: setVoiceRecording,
|
||||
setVoiceEnabled
|
||||
setVoiceEnabled,
|
||||
setVoiceTts
|
||||
}
|
||||
}),
|
||||
[
|
||||
@@ -830,7 +833,7 @@ export function useMainApp(gw: GatewayClient) {
|
||||
turnStartedAt: ui.sid ? turnStartedAt : null,
|
||||
// CLI parity: the classic prompt_toolkit status bar shows a red dot
|
||||
// on REC (cli.py:_get_voice_status_fragments line 2344).
|
||||
voiceLabel: voiceRecording ? '● REC' : voiceProcessing ? '◉ STT' : `voice ${voiceEnabled ? 'on' : 'off'}`
|
||||
voiceLabel: voiceRecording ? '● REC' : voiceProcessing ? '◉ STT' : `voice ${voiceEnabled ? 'on' : 'off'}${voiceTts ? ' [tts]' : ''}`
|
||||
}),
|
||||
[
|
||||
cwd,
|
||||
@@ -842,7 +845,8 @@ export function useMainApp(gw: GatewayClient) {
|
||||
ui,
|
||||
voiceEnabled,
|
||||
voiceProcessing,
|
||||
voiceRecording
|
||||
voiceRecording,
|
||||
voiceTts
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user