feat(desktop): mirror voice.auto_tts into an $autoSpeakReplies store

This commit is contained in:
Brooklyn Nicholson 2026-06-29 15:22:37 -05:00
parent bff91f978f
commit 09abbf8a63
2 changed files with 40 additions and 0 deletions

View file

@ -12,6 +12,7 @@ import {
setCurrentServiceTier,
setIntroPersonality
} from '@/store/session'
import { applyAutoSpeakFromConfig } from '@/store/voice-prefs'
const DEFAULT_VOICE_SECONDS = 120
const FAST_TIERS = new Set(['fast', 'priority', 'on'])
@ -65,6 +66,7 @@ export function useHermesConfig({ activeSessionIdRef, refreshProjectBranch }: He
setVoiceMaxRecordingSeconds(recordingLimit(config.voice?.max_recording_seconds))
setSttEnabled(config.stt?.enabled !== false)
applyAutoSpeakFromConfig(config)
} catch {
// Config is nice-to-have; chat still works without it.
}

View file

@ -0,0 +1,38 @@
import { atom } from 'nanostores'
import { getHermesConfigRecord, saveHermesConfig } from '@/hermes'
// "Read replies aloud" — mirrors the canonical `voice.auto_tts` config key (also
// in Settings → Voice, honored by the messaging gateway) so the composer toggle
// and the Settings switch are one source of truth, not two that can disagree.
export const $autoSpeakReplies = atom<boolean>(false)
/** Seed the atom from a loaded config payload (mount / refresh). */
export function applyAutoSpeakFromConfig(config: { voice?: { auto_tts?: unknown } | null } | null | undefined) {
$autoSpeakReplies.set(Boolean(config?.voice?.auto_tts))
}
/**
* Flip the preference and persist it. Optimistic the atom updates instantly and
* reverts if the config write fails. Read-modify-writes the whole record (the
* same path the Settings page uses; there's no partial-update endpoint).
*/
export async function setAutoSpeakReplies(enabled: boolean): Promise<void> {
const previous = $autoSpeakReplies.get()
if (previous === enabled) {
return
}
$autoSpeakReplies.set(enabled)
try {
const record = await getHermesConfigRecord()
const voice = record.voice && typeof record.voice === 'object' ? (record.voice as Record<string, unknown>) : {}
await saveHermesConfig({ ...record, voice: { ...voice, auto_tts: enabled } })
} catch (error) {
$autoSpeakReplies.set(previous)
throw error
}
}