Problem
Voice mode always speaks with the same voice. A faculty member building role-play scenarios asked for different voices (and personality fit per scenario). The model already supports multiple voices; we just don't expose a choice.
Current behavior
- Voice mode runs on Nova Sonic 2 (
amazon.nova-2-sonic-v1:0, env-overridable via NOVA_SONIC_MODEL_ID) — backend/src/agents/main_agent/config/constants.py:129.
- The voice is resolved in
VoiceAgent.__init__ (backend/src/agents/main_agent/voice_agent.py:61-72): constructor voice arg → NOVA_SONIC_VOICE env var → default "tiffany". Known options per the docstring: matthew, tiffany, amy.
voice_routes.py never passes a voice (backend/src/apis/inference_api/chat/voice_routes.py:370-375), so today the only knob is the deployment-wide env var.
- No frontend picker exists, and the WebSocket
config frame only carries session_id (voice-chat.service.ts:302-306).
Proposed change
- Add
voice to the voice WebSocket config frame and thread it through voice_routes.py → VoiceAgent (validated against an allowlist of Nova Sonic voices).
- Frontend: a simple voice picker in the voice overlay or chat settings.
- Follow-up (pairs with the Assistant-persona issue): allow an Assistant to pin a default voice so a role-play character always speaks with the same voice.
Notes
Enumerate the currently supported Nova Sonic 2 voice ids from AWS docs before building the allowlist — the three in the docstring may not be exhaustive.
Problem
Voice mode always speaks with the same voice. A faculty member building role-play scenarios asked for different voices (and personality fit per scenario). The model already supports multiple voices; we just don't expose a choice.
Current behavior
amazon.nova-2-sonic-v1:0, env-overridable viaNOVA_SONIC_MODEL_ID) —backend/src/agents/main_agent/config/constants.py:129.VoiceAgent.__init__(backend/src/agents/main_agent/voice_agent.py:61-72): constructorvoicearg →NOVA_SONIC_VOICEenv var → default"tiffany". Known options per the docstring:matthew,tiffany,amy.voice_routes.pynever passes avoice(backend/src/apis/inference_api/chat/voice_routes.py:370-375), so today the only knob is the deployment-wide env var.configframe only carriessession_id(voice-chat.service.ts:302-306).Proposed change
voiceto the voice WebSocketconfigframe and thread it throughvoice_routes.py→VoiceAgent(validated against an allowlist of Nova Sonic voices).Notes
Enumerate the currently supported Nova Sonic 2 voice ids from AWS docs before building the allowlist — the three in the docstring may not be exhaustive.