dsh-live-voice 0.3.2 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/README.md +15 -8
  2. package/lib/client.js +5959 -3222
  3. package/lib/server.js +29 -6
  4. package/package.json +9 -30
  5. package/src/app/AGENTS.md +1 -1
  6. package/src/app/ARCHITECTURE.md +1 -1
  7. package/src/app/client/apply.tsx +140 -16
  8. package/src/app/client/composerSelection.ts +92 -0
  9. package/src/app/client/i18n/catalogs/base.ts +33 -0
  10. package/src/app/client/i18n/catalogs/en.ts +36 -0
  11. package/src/app/client/i18n/catalogs/es.ts +36 -0
  12. package/src/app/client/i18n/catalogs/fr.ts +37 -0
  13. package/src/app/client/i18n/catalogs/hi.ts +35 -0
  14. package/src/app/client/i18n/catalogs/pt-BR.ts +37 -0
  15. package/src/app/client/i18n/catalogs/zh.ts +35 -0
  16. package/src/modules/AGENTS.md +1 -1
  17. package/src/modules/conversation/ARCHITECTURE.md +4 -2
  18. package/src/modules/conversation/components/AutoPlaybackToggle.tsx +31 -0
  19. package/src/modules/conversation/components/ConversationControls.tsx +23 -8
  20. package/src/modules/conversation/components/ConversationStatusBar.tsx +72 -94
  21. package/src/modules/conversation/components/DeliveryModeButton.tsx +3 -3
  22. package/src/modules/conversation/components/MeetingControls.tsx +64 -0
  23. package/src/modules/conversation/components/MicrophoneButton.tsx +6 -1
  24. package/src/modules/conversation/components/PlaybackControls.tsx +20 -5
  25. package/src/modules/conversation/components/RecognitionBar.tsx +14 -0
  26. package/src/modules/conversation/components/ScrollingSpeechCaption.tsx +100 -0
  27. package/src/modules/conversation/components/SpeechStatusBar.tsx +99 -0
  28. package/src/modules/conversation/components/Waveform.tsx +8 -3
  29. package/src/modules/conversation/components/conversationStatus.ts +0 -2
  30. package/src/modules/conversation/components/index.ts +1 -0
  31. package/src/modules/conversation/components/speechCaption.ts +27 -0
  32. package/src/modules/conversation/models/chat.ts +14 -2
  33. package/src/modules/conversation/models/meeting.ts +140 -0
  34. package/src/modules/conversation/models/meetingTranscript.ts +56 -0
  35. package/src/modules/core/ARCHITECTURE.md +1 -1
  36. package/src/modules/core/coordinator.ts +204 -51
  37. package/src/modules/core/developerExtension.ts +26 -0
  38. package/src/modules/core/diagnostics.ts +150 -0
  39. package/src/modules/core/filters.ts +20 -15
  40. package/src/modules/core/markdownSpeech.ts +154 -0
  41. package/src/modules/core/settings.ts +17 -13
  42. package/src/modules/core/sharedAudio.ts +82 -0
  43. package/src/modules/core/speechDefaults.ts +21 -0
  44. package/src/modules/recognition/engines/browser/BrowserRecognitionEngine.ts +8 -1
  45. package/src/modules/recognition/engines/whisper/WhisperRecognitionEngine.ts +10 -3
  46. package/src/modules/settings/components/LiveVoiceSettings.tsx +17 -3
  47. package/src/modules/settings/sections/conversation/ConversationDelaySettings.tsx +8 -3
  48. package/src/modules/settings/sections/conversation/DeliverySettings.tsx +25 -2
  49. package/src/modules/speak/engines/audio/HostAudioEngine.ts +19 -2
  50. package/src/modules/speak/engines/browser/BrowserSpeakingEngine.ts +33 -2
  51. package/src/shared/design-system/buttons/ToggleButton.tsx +8 -1
  52. package/src/shared/design-system/icons/icons.ts +4 -0
  53. package/src/styles/index.ts +11 -3
  54. package/CHANGELOG.md +0 -240
  55. package/DEVELOPMENT.md +0 -83
  56. package/PLAN.md +0 -296
  57. package/docs/ARCHITECTURE.md +0 -33
  58. package/docs/CHOOSING-AN-ENGINE.md +0 -120
  59. package/docs/CONFIGURATION.md +0 -163
  60. package/docs/REVIEW.md +0 -35
  61. package/docs/VOICE-LIFECYCLE.md +0 -63
  62. package/scripts/build.ts +0 -62
  63. package/scripts/check-dist.mjs +0 -38
  64. package/scripts/preview-ui.ts +0 -31
  65. package/scripts/probe-browser.ts +0 -46
@@ -23,12 +23,14 @@ const en: LiveVoiceTranslation = {
23
23
  'dsh-live-voice.commons.input.listening': 'listening',
24
24
  'dsh-live-voice.commons.input.listeningBadge': 'LISTENING',
25
25
  'dsh-live-voice.commons.manual': 'manual',
26
+ 'dsh-live-voice.commons.milliseconds': '{milliseconds} ms',
26
27
  'dsh-live-voice.commons.off': 'off',
27
28
  'dsh-live-voice.commons.on': 'on',
28
29
  'dsh-live-voice.commons.pluginName': 'Live Voice',
29
30
  'dsh-live-voice.commons.queue': 'queue',
30
31
  'dsh-live-voice.commons.repository.starLabel': 'Star Us on GitHub',
31
32
  'dsh-live-voice.commons.repository.starLink': 'Star DSH Live Voice on GitHub',
33
+ 'dsh-live-voice.commons.second': '1 second',
32
34
  'dsh-live-voice.commons.seconds': '{seconds} seconds',
33
35
  'dsh-live-voice.commons.send': 'SEND',
34
36
  'dsh-live-voice.commons.status.ready': 'Voice ready',
@@ -44,6 +46,25 @@ const en: LiveVoiceTranslation = {
44
46
  'dsh-live-voice.commons.version.label': 'DSH Live Voice v{version}',
45
47
  'dsh-live-voice.commons.version.link': 'DSH Live Voice v{version}. Open releases',
46
48
  'dsh-live-voice.commons.version.title': 'Version information',
49
+ 'dsh-live-voice.meeting.failed': 'Recognition failed.',
50
+ 'dsh-live-voice.meeting.help':
51
+ 'Independent sources; transcripts stay in the composer until you send them manually.',
52
+ 'dsh-live-voice.meeting.httpRequired': 'Use Qwen or Whisper HTTP for meeting mode.',
53
+ 'dsh-live-voice.meeting.inactive': 'Inactive',
54
+ 'dsh-live-voice.meeting.listening': 'Listening',
55
+ 'dsh-live-voice.meeting.microphone': 'Microphone',
56
+ 'dsh-live-voice.meeting.noAudio': 'No audio was shared. Enable audio in the sharing dialog.',
57
+ 'dsh-live-voice.meeting.processing': 'Transcribing…',
58
+ 'dsh-live-voice.meeting.shared': 'Shared audio',
59
+ 'dsh-live-voice.meeting.start': 'Start source',
60
+ 'dsh-live-voice.meeting.startShared': 'Start audio sharing',
61
+ 'dsh-live-voice.meeting.starting': 'Starting…',
62
+ 'dsh-live-voice.meeting.stop': 'Stop source',
63
+ 'dsh-live-voice.meeting.stopShared': 'Stop audio sharing',
64
+ 'dsh-live-voice.meeting.timestamps': 'Transcript timestamps',
65
+ 'dsh-live-voice.meeting.timestampsBadge': 'Timestamp',
66
+ 'dsh-live-voice.meeting.title': 'Meeting mode',
67
+ 'dsh-live-voice.meeting.unavailable': 'Recognition is unavailable.',
47
68
  'dsh-live-voice.recognition.autoSend.countdownHelp':
48
69
  'Countdown starts after a final recognized phrase. New speech or edits cancel it.',
49
70
  'dsh-live-voice.recognition.browser.autoInstallPack':
@@ -158,6 +179,12 @@ const en: LiveVoiceTranslation = {
158
179
  'dsh-live-voice.settings.autoSend.countdown': 'Sending in {remaining}…',
159
180
  'dsh-live-voice.settings.autoSend.delay': 'Send after silence',
160
181
  'dsh-live-voice.settings.close': 'Close voice settings',
182
+ 'dsh-live-voice.settings.delivery.dshEnterHelp':
183
+ 'Live Voice uses your answer to choose the correct action for Steer and Queue. This does not change DSH settings; match your current DSH configuration and update this answer if it changes.',
184
+ 'dsh-live-voice.settings.delivery.dshEnterQuestion':
185
+ 'In your DSH, what does Enter do when the agent is busy?',
186
+ 'dsh-live-voice.settings.delivery.dshEnterQueue': 'Puts the message in the queue',
187
+ 'dsh-live-voice.settings.delivery.dshEnterSteer': 'Sends the message as steer',
161
188
  'dsh-live-voice.settings.delivery.label': 'Sending mode',
162
189
  'dsh-live-voice.settings.delivery.manualLabel': 'Off — review and send manually',
163
190
  'dsh-live-voice.settings.delivery.queueLabel': 'Queue — automatically add after silence',
@@ -185,6 +212,8 @@ const en: LiveVoiceTranslation = {
185
212
  'This English instruction is sent to the agent only during an active voice conversation with automatic assistant speech enabled.',
186
213
  'dsh-live-voice.speak.agentContext.label': 'Agent voice context',
187
214
  'dsh-live-voice.speak.agentContext.restore': 'Restore default',
215
+ 'dsh-live-voice.speak.autoPlayback.disable': 'Disable automatic assistant speech',
216
+ 'dsh-live-voice.speak.autoPlayback.enable': 'Enable automatic assistant speech',
188
217
  'dsh-live-voice.speak.autoPlayback.enabled': 'Automatically speak new assistant messages',
189
218
  'dsh-live-voice.speak.autoPlayback.help':
190
219
  'During a voice conversation, assistant phrases are announced automatically. Playback waits while you are speaking.',
@@ -200,6 +229,11 @@ const en: LiveVoiceTranslation = {
200
229
  'dsh-live-voice.speak.browser.outputHelp':
201
230
  'Browser speech synthesis may ignore the selected output device; this browser API normally follows the system default.',
202
231
  'dsh-live-voice.speak.browser.voice': 'Local browser voice',
232
+ 'dsh-live-voice.speak.captions.approximate': 'Approximate speech captions',
233
+ 'dsh-live-voice.speak.captions.loading': 'Preparing speech audio',
234
+ 'dsh-live-voice.speak.captions.position': 'Speech segment {index} of {total}',
235
+ 'dsh-live-voice.speak.captions.progress': 'Approximate speech progress',
236
+ 'dsh-live-voice.speak.captions.title': 'Speech and live captions',
203
237
  'dsh-live-voice.speak.engine.label': 'Speech engine',
204
238
  'dsh-live-voice.speak.engine.playbackHelp':
205
239
  'Qwen and macOS say synthesize on the DSH host; compact AAC/M4A audio plays in this browser. Browser speech synthesizes and plays on this device.',
@@ -226,6 +260,7 @@ const en: LiveVoiceTranslation = {
226
260
  'dsh-live-voice.speak.playback.message': 'Speak message',
227
261
  'dsh-live-voice.speak.playback.next': 'Skip to next speech segment',
228
262
  'dsh-live-voice.speak.playback.pause': 'Pause speech',
263
+ 'dsh-live-voice.speak.playback.previous': 'Previous speech segment',
229
264
  'dsh-live-voice.speak.playback.resume': 'Resume speech',
230
265
  'dsh-live-voice.speak.playback.stop': 'Stop speaking',
231
266
  'dsh-live-voice.speak.playback.stopAll': 'Stop all speech',
@@ -258,6 +293,7 @@ const en: LiveVoiceTranslation = {
258
293
  'dsh-live-voice.speak.responseDelay.help':
259
294
  'After you stop speaking, automatic assistant playback waits for this much continuous silence. Speaking again restarts the wait.',
260
295
  'dsh-live-voice.speak.responseDelay.label': 'Assistant response delay',
296
+ 'dsh-live-voice.speak.responseDelay.none': 'No delay',
261
297
  'dsh-live-voice.speak.segmentGap.help':
262
298
  'Wait this many milliseconds between consecutive spoken segments. 400 ms is the default.',
263
299
  'dsh-live-voice.speak.segmentGap.label': 'Pause between speech segments',
@@ -23,12 +23,14 @@ const es: LiveVoiceTranslation = {
23
23
  'dsh-live-voice.commons.input.listening': 'escuchando',
24
24
  'dsh-live-voice.commons.input.listeningBadge': 'ESCUCHANDO',
25
25
  'dsh-live-voice.commons.manual': 'manual',
26
+ 'dsh-live-voice.commons.milliseconds': '{milliseconds} ms',
26
27
  'dsh-live-voice.commons.off': 'desactivado',
27
28
  'dsh-live-voice.commons.on': 'activado',
28
29
  'dsh-live-voice.commons.pluginName': 'Live Voice',
29
30
  'dsh-live-voice.commons.queue': 'cola',
30
31
  'dsh-live-voice.commons.repository.starLabel': 'Danos una estrella en GitHub',
31
32
  'dsh-live-voice.commons.repository.starLink': 'Dar una estrella a DSH Live Voice en GitHub',
33
+ 'dsh-live-voice.commons.second': '1 segundo',
32
34
  'dsh-live-voice.commons.seconds': '{seconds} segundos',
33
35
  'dsh-live-voice.commons.send': 'ENVIAR',
34
36
  'dsh-live-voice.commons.status.ready': 'Funciones de voz listas',
@@ -45,6 +47,25 @@ const es: LiveVoiceTranslation = {
45
47
  'dsh-live-voice.commons.version.label': 'DSH Live Voice v{version}',
46
48
  'dsh-live-voice.commons.version.link': 'DSH Live Voice v{version}. Abrir la lista de versiones',
47
49
  'dsh-live-voice.commons.version.title': 'Información de versión',
50
+ 'dsh-live-voice.meeting.failed': 'Error de reconocimiento.',
51
+ 'dsh-live-voice.meeting.help':
52
+ 'Fuentes independientes; envía las transcripciones manualmente desde el editor.',
53
+ 'dsh-live-voice.meeting.httpRequired': 'Usa Qwen o Whisper HTTP para el modo reunión.',
54
+ 'dsh-live-voice.meeting.inactive': 'Inactivo',
55
+ 'dsh-live-voice.meeting.listening': 'Escuchando',
56
+ 'dsh-live-voice.meeting.microphone': 'Micrófono',
57
+ 'dsh-live-voice.meeting.noAudio': 'No se compartió audio. Activa el audio en el diálogo.',
58
+ 'dsh-live-voice.meeting.processing': 'Transcribiendo…',
59
+ 'dsh-live-voice.meeting.shared': 'Audio compartido',
60
+ 'dsh-live-voice.meeting.start': 'Iniciar fuente',
61
+ 'dsh-live-voice.meeting.startShared': 'Iniciar audio compartido',
62
+ 'dsh-live-voice.meeting.starting': 'Iniciando…',
63
+ 'dsh-live-voice.meeting.stop': 'Detener fuente',
64
+ 'dsh-live-voice.meeting.stopShared': 'Detener audio compartido',
65
+ 'dsh-live-voice.meeting.timestamps': 'Marcas de tiempo de transcripción',
66
+ 'dsh-live-voice.meeting.timestampsBadge': 'Tiempo',
67
+ 'dsh-live-voice.meeting.title': 'Modo reunión',
68
+ 'dsh-live-voice.meeting.unavailable': 'Reconocimiento no disponible.',
48
69
  'dsh-live-voice.recognition.autoSend.countdownHelp':
49
70
  'La cuenta atrás comienza tras el reconocimiento definitivo de una frase. Hablar de nuevo o editar el texto la cancela.',
50
71
  'dsh-live-voice.recognition.browser.autoInstallPack':
@@ -170,6 +191,12 @@ const es: LiveVoiceTranslation = {
170
191
  'dsh-live-voice.settings.autoSend.countdown': 'Enviando en {remaining}…',
171
192
  'dsh-live-voice.settings.autoSend.delay': 'Enviar después del silencio',
172
193
  'dsh-live-voice.settings.close': 'Cerrar configuración de voz',
194
+ 'dsh-live-voice.settings.delivery.dshEnterHelp':
195
+ 'Live Voice usa tu respuesta para elegir la acción correcta para Redirigir y Cola. Esto no cambia la configuración de DSH; indica el comportamiento que ya usas y actualiza esta respuesta si cambia.',
196
+ 'dsh-live-voice.settings.delivery.dshEnterQuestion':
197
+ 'En tu DSH, ¿qué hace Enter cuando el agente está ocupado?',
198
+ 'dsh-live-voice.settings.delivery.dshEnterQueue': 'Añade el mensaje a la cola',
199
+ 'dsh-live-voice.settings.delivery.dshEnterSteer': 'Envía el mensaje para redirigir al agente',
173
200
  'dsh-live-voice.settings.delivery.label': 'Modo de envío',
174
201
  'dsh-live-voice.settings.delivery.manualLabel': 'Desactivado — revisar y enviar manualmente',
175
202
  'dsh-live-voice.settings.delivery.queueLabel': 'Cola — añadir automáticamente tras un silencio',
@@ -198,6 +225,8 @@ const es: LiveVoiceTranslation = {
198
225
  'Esta instrucción en inglés se envía al agente solo durante una conversación de voz activa con habla automática del asistente activada.',
199
226
  'dsh-live-voice.speak.agentContext.label': 'Contexto de voz del agente',
200
227
  'dsh-live-voice.speak.agentContext.restore': 'Restaurar predeterminado',
228
+ 'dsh-live-voice.speak.autoPlayback.disable': 'Desactivar voz automática del asistente',
229
+ 'dsh-live-voice.speak.autoPlayback.enable': 'Activar voz automática del asistente',
201
230
  'dsh-live-voice.speak.autoPlayback.enabled':
202
231
  'Leer automáticamente los nuevos mensajes del asistente en voz alta',
203
232
  'dsh-live-voice.speak.autoPlayback.help':
@@ -214,6 +243,11 @@ const es: LiveVoiceTranslation = {
214
243
  'dsh-live-voice.speak.browser.outputHelp':
215
244
  'La síntesis de voz del navegador puede ignorar el dispositivo de salida seleccionado; esta API del navegador normalmente utiliza el predeterminado del sistema.',
216
245
  'dsh-live-voice.speak.browser.voice': 'Voz local del navegador',
246
+ 'dsh-live-voice.speak.captions.approximate': 'Subtítulos de voz aproximados',
247
+ 'dsh-live-voice.speak.captions.loading': 'Preparando audio de voz',
248
+ 'dsh-live-voice.speak.captions.position': 'Fragmento de voz {index} de {total}',
249
+ 'dsh-live-voice.speak.captions.progress': 'Progreso aproximado de voz',
250
+ 'dsh-live-voice.speak.captions.title': 'Voz y subtítulos en vivo',
217
251
  'dsh-live-voice.speak.engine.label': 'Motor de síntesis de voz',
218
252
  'dsh-live-voice.speak.engine.playbackHelp':
219
253
  'Qwen y macOS say sintetizan en el host de DSH; el audio AAC/M4A compacto se reproduce en este navegador. La voz del navegador se sintetiza y reproduce en este dispositivo.',
@@ -245,6 +279,7 @@ const es: LiveVoiceTranslation = {
245
279
  'dsh-live-voice.speak.playback.message': 'Leer el mensaje en voz alta',
246
280
  'dsh-live-voice.speak.playback.next': 'Saltar al siguiente segmento de voz',
247
281
  'dsh-live-voice.speak.playback.pause': 'Pausar la lectura en voz alta',
282
+ 'dsh-live-voice.speak.playback.previous': 'Fragmento de voz anterior',
248
283
  'dsh-live-voice.speak.playback.resume': 'Reanudar la lectura en voz alta',
249
284
  'dsh-live-voice.speak.playback.stop': 'Detener la lectura en voz alta',
250
285
  'dsh-live-voice.speak.playback.stopAll': 'Detener toda la lectura en voz alta',
@@ -279,6 +314,7 @@ const es: LiveVoiceTranslation = {
279
314
  'dsh-live-voice.speak.responseDelay.help':
280
315
  'Cuando dejas de hablar, la reproducción automática del asistente espera este intervalo de silencio continuo. Si vuelves a hablar, la espera se reinicia.',
281
316
  'dsh-live-voice.speak.responseDelay.label': 'Demora de respuesta del asistente',
317
+ 'dsh-live-voice.speak.responseDelay.none': 'Sin retraso',
282
318
  'dsh-live-voice.speak.segmentGap.help':
283
319
  'Espera esta cantidad de milisegundos entre segmentos hablados consecutivos. El valor predeterminado es 400 ms.',
284
320
  'dsh-live-voice.speak.segmentGap.label': 'Pausa entre segmentos de voz',
@@ -23,12 +23,14 @@ const fr: LiveVoiceTranslation = {
23
23
  'dsh-live-voice.commons.input.listening': 'à l’écoute',
24
24
  'dsh-live-voice.commons.input.listeningBadge': 'À L’ÉCOUTE',
25
25
  'dsh-live-voice.commons.manual': 'manuel',
26
+ 'dsh-live-voice.commons.milliseconds': '{milliseconds} ms',
26
27
  'dsh-live-voice.commons.off': 'désactivé',
27
28
  'dsh-live-voice.commons.on': 'activé',
28
29
  'dsh-live-voice.commons.pluginName': 'Live Voice',
29
30
  'dsh-live-voice.commons.queue': 'file d’attente',
30
31
  'dsh-live-voice.commons.repository.starLabel': 'Soutenez-nous avec une étoile sur GitHub',
31
32
  'dsh-live-voice.commons.repository.starLink': 'Attribuer une étoile à DSH Live Voice sur GitHub',
33
+ 'dsh-live-voice.commons.second': '1 seconde',
32
34
  'dsh-live-voice.commons.seconds': '{seconds} secondes',
33
35
  'dsh-live-voice.commons.send': 'ENVOYER',
34
36
  'dsh-live-voice.commons.status.ready': 'Fonctions vocales prêtes',
@@ -45,6 +47,26 @@ const fr: LiveVoiceTranslation = {
45
47
  'dsh-live-voice.commons.version.label': 'DSH Live Voice v{version}',
46
48
  'dsh-live-voice.commons.version.link': 'DSH Live Voice v{version}. Ouvrir la liste des versions',
47
49
  'dsh-live-voice.commons.version.title': 'Informations de version',
50
+ 'dsh-live-voice.meeting.failed': 'Échec de reconnaissance.',
51
+ 'dsh-live-voice.meeting.help':
52
+ 'Sources indépendantes ; envoyez les transcriptions manuellement depuis l’éditeur.',
53
+ 'dsh-live-voice.meeting.httpRequired': 'Utilisez Qwen ou Whisper HTTP en mode réunion.',
54
+ 'dsh-live-voice.meeting.inactive': 'Inactif',
55
+ 'dsh-live-voice.meeting.listening': 'Écoute',
56
+ 'dsh-live-voice.meeting.microphone': 'Microphone',
57
+ 'dsh-live-voice.meeting.noAudio':
58
+ 'Aucun audio partagé. Activez l’audio dans la fenêtre de partage.',
59
+ 'dsh-live-voice.meeting.processing': 'Transcription…',
60
+ 'dsh-live-voice.meeting.shared': 'Audio partagé',
61
+ 'dsh-live-voice.meeting.start': 'Démarrer la source',
62
+ 'dsh-live-voice.meeting.startShared': 'Démarrer le partage audio',
63
+ 'dsh-live-voice.meeting.starting': 'Démarrage…',
64
+ 'dsh-live-voice.meeting.stop': 'Arrêter la source',
65
+ 'dsh-live-voice.meeting.stopShared': 'Arrêter le partage audio',
66
+ 'dsh-live-voice.meeting.timestamps': 'Horodatage des transcriptions',
67
+ 'dsh-live-voice.meeting.timestampsBadge': 'Horodatage',
68
+ 'dsh-live-voice.meeting.title': 'Mode réunion',
69
+ 'dsh-live-voice.meeting.unavailable': 'Reconnaissance indisponible.',
48
70
  'dsh-live-voice.recognition.autoSend.countdownHelp':
49
71
  'Le compte à rebours démarre après la reconnaissance définitive d’une phrase. Toute nouvelle parole ou modification l’annule.',
50
72
  'dsh-live-voice.recognition.browser.autoInstallPack':
@@ -172,6 +194,12 @@ const fr: LiveVoiceTranslation = {
172
194
  'dsh-live-voice.settings.autoSend.countdown': 'Envoi dans {remaining}…',
173
195
  'dsh-live-voice.settings.autoSend.delay': 'Envoyer après le silence',
174
196
  'dsh-live-voice.settings.close': 'Fermer les paramètres vocaux',
197
+ 'dsh-live-voice.settings.delivery.dshEnterHelp':
198
+ 'Live Voice utilise votre réponse pour choisir la bonne action pour Réorienter et File d’attente. Cela ne modifie pas les paramètres de DSH ; indiquez le comportement actuel et mettez cette réponse à jour s’il change.',
199
+ 'dsh-live-voice.settings.delivery.dshEnterQuestion':
200
+ 'Dans votre DSH, que fait Entrée lorsque l’agent est occupé ?',
201
+ 'dsh-live-voice.settings.delivery.dshEnterQueue': 'Place le message dans la file d’attente',
202
+ 'dsh-live-voice.settings.delivery.dshEnterSteer': 'Envoie le message pour réorienter l’agent',
175
203
  'dsh-live-voice.settings.delivery.label': 'Mode d’envoi',
176
204
  'dsh-live-voice.settings.delivery.manualLabel': 'Désactivé — vérifier et envoyer manuellement',
177
205
  'dsh-live-voice.settings.delivery.queueLabel':
@@ -201,6 +229,8 @@ const fr: LiveVoiceTranslation = {
201
229
  'Cette instruction en anglais est envoyée à l’agent seulement pendant une conversation vocale active avec la parole automatique de l’assistant activée.',
202
230
  'dsh-live-voice.speak.agentContext.label': 'Contexte vocal de l’agent',
203
231
  'dsh-live-voice.speak.agentContext.restore': 'Restaurer la valeur par défaut',
232
+ 'dsh-live-voice.speak.autoPlayback.disable': 'Désactiver la lecture automatique de l’assistant',
233
+ 'dsh-live-voice.speak.autoPlayback.enable': 'Activer la lecture automatique de l’assistant',
204
234
  'dsh-live-voice.speak.autoPlayback.enabled':
205
235
  'Lire automatiquement les nouveaux messages de l’assistant',
206
236
  'dsh-live-voice.speak.autoPlayback.help':
@@ -217,6 +247,11 @@ const fr: LiveVoiceTranslation = {
217
247
  'dsh-live-voice.speak.browser.outputHelp':
218
248
  'La synthèse vocale du navigateur peut ignorer le périphérique de sortie sélectionné ; cette API du navigateur utilise normalement celui défini par défaut sur le système.',
219
249
  'dsh-live-voice.speak.browser.voice': 'Voix locale du navigateur',
250
+ 'dsh-live-voice.speak.captions.approximate': 'Sous-titres vocaux approximatifs',
251
+ 'dsh-live-voice.speak.captions.loading': 'Préparation de l’audio vocal',
252
+ 'dsh-live-voice.speak.captions.position': 'Segment vocal {index} sur {total}',
253
+ 'dsh-live-voice.speak.captions.progress': 'Progression vocale approximative',
254
+ 'dsh-live-voice.speak.captions.title': 'Voix et sous-titres en direct',
220
255
  'dsh-live-voice.speak.engine.label': 'Moteur de synthèse vocale',
221
256
  'dsh-live-voice.speak.engine.playbackHelp':
222
257
  'Qwen et macOS say synthétisent sur l’hôte DSH ; l’audio AAC/M4A compact est lu dans ce navigateur. La synthèse vocale du navigateur est générée et lue sur cet appareil.',
@@ -247,6 +282,7 @@ const fr: LiveVoiceTranslation = {
247
282
  'dsh-live-voice.speak.playback.message': 'Lire le message à voix haute',
248
283
  'dsh-live-voice.speak.playback.next': 'Passer au segment vocal suivant',
249
284
  'dsh-live-voice.speak.playback.pause': 'Mettre la lecture en pause',
285
+ 'dsh-live-voice.speak.playback.previous': 'Segment vocal précédent',
250
286
  'dsh-live-voice.speak.playback.resume': 'Reprendre la lecture',
251
287
  'dsh-live-voice.speak.playback.stop': 'Arrêter la lecture',
252
288
  'dsh-live-voice.speak.playback.stopAll': 'Arrêter toute lecture',
@@ -281,6 +317,7 @@ const fr: LiveVoiceTranslation = {
281
317
  'dsh-live-voice.speak.responseDelay.help':
282
318
  'Après que vous avez cessé de parler, la lecture automatique de l’assistant attend cette durée de silence continu. Si vous reparlez, l’attente recommence.',
283
319
  'dsh-live-voice.speak.responseDelay.label': 'Délai de réponse de l’assistant',
320
+ 'dsh-live-voice.speak.responseDelay.none': 'Sans délai',
284
321
  'dsh-live-voice.speak.segmentGap.help':
285
322
  'Attend ce nombre de millisecondes entre des segments vocaux consécutifs. La valeur par défaut est 400 ms.',
286
323
  'dsh-live-voice.speak.segmentGap.label': 'Pause entre les segments vocaux',
@@ -23,12 +23,14 @@ const hi: LiveVoiceTranslation = {
23
23
  'dsh-live-voice.commons.input.listening': 'सुना जा रहा है',
24
24
  'dsh-live-voice.commons.input.listeningBadge': 'सुना जा रहा है',
25
25
  'dsh-live-voice.commons.manual': 'मैन्युअल',
26
+ 'dsh-live-voice.commons.milliseconds': '{milliseconds} मिलीसेकंड',
26
27
  'dsh-live-voice.commons.off': 'बंद',
27
28
  'dsh-live-voice.commons.on': 'चालू',
28
29
  'dsh-live-voice.commons.pluginName': 'Live Voice',
29
30
  'dsh-live-voice.commons.queue': 'कतार',
30
31
  'dsh-live-voice.commons.repository.starLabel': 'GitHub पर हमें स्टार दें',
31
32
  'dsh-live-voice.commons.repository.starLink': 'GitHub पर DSH Live Voice को स्टार दें',
33
+ 'dsh-live-voice.commons.second': '1 सेकंड',
32
34
  'dsh-live-voice.commons.seconds': '{seconds} सेकंड',
33
35
  'dsh-live-voice.commons.send': 'भेजें',
34
36
  'dsh-live-voice.commons.status.ready': 'वॉइस तैयार है',
@@ -43,6 +45,24 @@ const hi: LiveVoiceTranslation = {
43
45
  'dsh-live-voice.commons.version.label': 'DSH Live Voice v{version}',
44
46
  'dsh-live-voice.commons.version.link': 'DSH Live Voice v{version}। रिलीज़ सूची खोलें',
45
47
  'dsh-live-voice.commons.version.title': 'संस्करण जानकारी',
48
+ 'dsh-live-voice.meeting.failed': 'पहचान विफल हुई।',
49
+ 'dsh-live-voice.meeting.help': 'स्वतंत्र स्रोत; संपादक से लिप्यंतरण स्वयं भेजें।',
50
+ 'dsh-live-voice.meeting.httpRequired': 'बैठक मोड के लिए Qwen या Whisper HTTP उपयोग करें।',
51
+ 'dsh-live-voice.meeting.inactive': 'निष्क्रिय',
52
+ 'dsh-live-voice.meeting.listening': 'सुन रहा है',
53
+ 'dsh-live-voice.meeting.microphone': 'माइक्रोफ़ोन',
54
+ 'dsh-live-voice.meeting.noAudio': 'कोई ऑडियो साझा नहीं हुआ। साझाकरण संवाद में ऑडियो चालू करें।',
55
+ 'dsh-live-voice.meeting.processing': 'लिप्यंतरण…',
56
+ 'dsh-live-voice.meeting.shared': 'साझा ऑडियो',
57
+ 'dsh-live-voice.meeting.start': 'स्रोत शुरू करें',
58
+ 'dsh-live-voice.meeting.startShared': 'ऑडियो साझा करना शुरू करें',
59
+ 'dsh-live-voice.meeting.starting': 'शुरू हो रहा है…',
60
+ 'dsh-live-voice.meeting.stop': 'स्रोत रोकें',
61
+ 'dsh-live-voice.meeting.stopShared': 'ऑडियो साझा करना रोकें',
62
+ 'dsh-live-voice.meeting.timestamps': 'लिप्यंतरण समय चिह्न',
63
+ 'dsh-live-voice.meeting.timestampsBadge': 'समय',
64
+ 'dsh-live-voice.meeting.title': 'बैठक मोड',
65
+ 'dsh-live-voice.meeting.unavailable': 'पहचान उपलब्ध नहीं है।',
46
66
  'dsh-live-voice.recognition.autoSend.countdownHelp':
47
67
  'पहचाने गए वाक्यांश का अंतिम परिणाम मिलने के बाद उलटी गिनती शुरू होती है। दोबारा बोलने या संपादन करने पर यह रद्द हो जाती है।',
48
68
  'dsh-live-voice.recognition.browser.autoInstallPack':
@@ -161,6 +181,12 @@ const hi: LiveVoiceTranslation = {
161
181
  'dsh-live-voice.settings.autoSend.countdown': '{remaining} में भेजा जाएगा…',
162
182
  'dsh-live-voice.settings.autoSend.delay': 'मौन के बाद भेजें',
163
183
  'dsh-live-voice.settings.close': 'वॉइस सेटिंग्स बंद करें',
184
+ 'dsh-live-voice.settings.delivery.dshEnterHelp':
185
+ 'Live Voice आपके उत्तर से दिशा देने और कतार में डालने की सही क्रिया चुनता है। इससे DSH की सेटिंग नहीं बदलती; अपना वर्तमान DSH व्यवहार बताएं और उसके बदलने पर यह उत्तर अपडेट करें।',
186
+ 'dsh-live-voice.settings.delivery.dshEnterQuestion':
187
+ 'आपके DSH में, एजेंट व्यस्त होने पर Enter क्या करता है?',
188
+ 'dsh-live-voice.settings.delivery.dshEnterQueue': 'संदेश को कतार में डालता है',
189
+ 'dsh-live-voice.settings.delivery.dshEnterSteer': 'संदेश से एजेंट को दिशा देता है',
164
190
  'dsh-live-voice.settings.delivery.label': 'भेजने का मोड',
165
191
  'dsh-live-voice.settings.delivery.manualLabel': 'बंद — समीक्षा करके मैन्युअल रूप से भेजें',
166
192
  'dsh-live-voice.settings.delivery.queueLabel': 'कतार — मौन के बाद अपने आप जोड़ें',
@@ -188,6 +214,8 @@ const hi: LiveVoiceTranslation = {
188
214
  'यह अंग्रेज़ी निर्देश एजेंट को केवल सक्रिय वॉइस बातचीत के दौरान भेजा जाता है, जब सहायक का स्वचालित भाषण सक्षम हो.',
189
215
  'dsh-live-voice.speak.agentContext.label': 'एजेंट वॉइस संदर्भ',
190
216
  'dsh-live-voice.speak.agentContext.restore': 'डिफ़ॉल्ट बहाल करें',
217
+ 'dsh-live-voice.speak.autoPlayback.disable': 'सहायक की स्वचालित आवाज़ बंद करें',
218
+ 'dsh-live-voice.speak.autoPlayback.enable': 'सहायक की स्वचालित आवाज़ चालू करें',
191
219
  'dsh-live-voice.speak.autoPlayback.enabled': 'सहायक के नए संदेश अपने आप पढ़कर सुनाएँ',
192
220
  'dsh-live-voice.speak.autoPlayback.help':
193
221
  'वॉइस बातचीत के दौरान सहायक के वाक्यांश अपने आप पढ़कर सुनाए जाते हैं। जब आप बोल रहे हों, तो प्लेबैक प्रतीक्षा करता है।',
@@ -203,6 +231,11 @@ const hi: LiveVoiceTranslation = {
203
231
  'dsh-live-voice.speak.browser.outputHelp':
204
232
  'ब्राउज़र का वाक् संश्लेषण चुने गए आउटपुट डिवाइस को अनदेखा कर सकता है; यह ब्राउज़र API सामान्यतः सिस्टम के डिफ़ॉल्ट का उपयोग करता है।',
205
233
  'dsh-live-voice.speak.browser.voice': 'ब्राउज़र की स्थानीय आवाज़',
234
+ 'dsh-live-voice.speak.captions.approximate': 'अनुमानित वाणी कैप्शन',
235
+ 'dsh-live-voice.speak.captions.loading': 'वाणी ऑडियो तैयार हो रहा है',
236
+ 'dsh-live-voice.speak.captions.position': 'वाणी खंड {index} / {total}',
237
+ 'dsh-live-voice.speak.captions.progress': 'अनुमानित वाणी प्रगति',
238
+ 'dsh-live-voice.speak.captions.title': 'वाणी और लाइव कैप्शन',
206
239
  'dsh-live-voice.speak.engine.label': 'वाक् संश्लेषण इंजन',
207
240
  'dsh-live-voice.speak.engine.playbackHelp':
208
241
  'Qwen और macOS say DSH होस्ट पर आवाज़ बनाते हैं; कॉम्पैक्ट AAC/M4A ऑडियो इस ब्राउज़र में चलता है। ब्राउज़र स्पीच इसी डिवाइस पर बनती और चलती है।',
@@ -230,6 +263,7 @@ const hi: LiveVoiceTranslation = {
230
263
  'dsh-live-voice.speak.playback.message': 'संदेश पढ़कर सुनाएँ',
231
264
  'dsh-live-voice.speak.playback.next': 'अगले वाणी खंड पर जाएँ',
232
265
  'dsh-live-voice.speak.playback.pause': 'वाचन ठहराएँ',
266
+ 'dsh-live-voice.speak.playback.previous': 'पिछला वाणी खंड',
233
267
  'dsh-live-voice.speak.playback.resume': 'वाचन फिर शुरू करें',
234
268
  'dsh-live-voice.speak.playback.stop': 'वाचन बंद करें',
235
269
  'dsh-live-voice.speak.playback.stopAll': 'सभी वाचन बंद करें',
@@ -263,6 +297,7 @@ const hi: LiveVoiceTranslation = {
263
297
  'dsh-live-voice.speak.responseDelay.help':
264
298
  'आपके बोलना बंद करने के बाद सहायक का स्वचालित प्लेबैक इतनी देर तक लगातार मौन रहने की प्रतीक्षा करता है। दोबारा बोलने पर प्रतीक्षा फिर से शुरू होती है।',
265
299
  'dsh-live-voice.speak.responseDelay.label': 'सहायक के जवाब का विलंब',
300
+ 'dsh-live-voice.speak.responseDelay.none': 'कोई विलंब नहीं',
266
301
  'dsh-live-voice.speak.segmentGap.help':
267
302
  'लगातार बोले गए हिस्सों के बीच इतने मिलीसेकंड रुकें। डिफ़ॉल्ट 400 ms है।',
268
303
  'dsh-live-voice.speak.segmentGap.label': 'बोले गए हिस्सों के बीच विराम',
@@ -24,12 +24,14 @@ const ptBR: LiveVoiceTranslation = {
24
24
  'dsh-live-voice.commons.input.listening': 'escutando',
25
25
  'dsh-live-voice.commons.input.listeningBadge': 'ESCUTANDO',
26
26
  'dsh-live-voice.commons.manual': 'manual',
27
+ 'dsh-live-voice.commons.milliseconds': '{milliseconds} ms',
27
28
  'dsh-live-voice.commons.off': 'desativado',
28
29
  'dsh-live-voice.commons.on': 'ativada',
29
30
  'dsh-live-voice.commons.pluginName': 'Live Voice',
30
31
  'dsh-live-voice.commons.queue': 'fila',
31
32
  'dsh-live-voice.commons.repository.starLabel': 'Dê uma estrela no GitHub',
32
33
  'dsh-live-voice.commons.repository.starLink': 'Dar estrela ao DSH Live Voice no GitHub',
34
+ 'dsh-live-voice.commons.second': '1 segundo',
33
35
  'dsh-live-voice.commons.seconds': '{seconds} segundos',
34
36
  'dsh-live-voice.commons.send': 'ENVIAR',
35
37
  'dsh-live-voice.commons.status.ready': 'Voz pronta',
@@ -45,6 +47,26 @@ const ptBR: LiveVoiceTranslation = {
45
47
  'dsh-live-voice.commons.version.label': 'DSH Live Voice v{version}',
46
48
  'dsh-live-voice.commons.version.link': 'DSH Live Voice v{version}. Abrir versões',
47
49
  'dsh-live-voice.commons.version.title': 'Informações da versão',
50
+ 'dsh-live-voice.meeting.failed': 'Falha no reconhecimento.',
51
+ 'dsh-live-voice.meeting.help':
52
+ 'Fontes independentes; as transcrições ficam no composer até você enviá-las manualmente.',
53
+ 'dsh-live-voice.meeting.httpRequired': 'Use Qwen ou Whisper HTTP no modo reunião.',
54
+ 'dsh-live-voice.meeting.inactive': 'Inativo',
55
+ 'dsh-live-voice.meeting.listening': 'Ouvindo',
56
+ 'dsh-live-voice.meeting.microphone': 'Microfone',
57
+ 'dsh-live-voice.meeting.noAudio':
58
+ 'Nenhum áudio foi compartilhado. Ative o áudio na janela de compartilhamento.',
59
+ 'dsh-live-voice.meeting.processing': 'Transcrevendo…',
60
+ 'dsh-live-voice.meeting.shared': 'Áudio compartilhado',
61
+ 'dsh-live-voice.meeting.start': 'Iniciar fonte',
62
+ 'dsh-live-voice.meeting.startShared': 'Iniciar compartilhamento de áudio',
63
+ 'dsh-live-voice.meeting.starting': 'Iniciando…',
64
+ 'dsh-live-voice.meeting.stop': 'Parar fonte',
65
+ 'dsh-live-voice.meeting.stopShared': 'Parar compartilhamento de áudio',
66
+ 'dsh-live-voice.meeting.timestamps': 'Horário das transcrições',
67
+ 'dsh-live-voice.meeting.timestampsBadge': 'Timestamp',
68
+ 'dsh-live-voice.meeting.title': 'Modo reunião',
69
+ 'dsh-live-voice.meeting.unavailable': 'Reconhecimento indisponível.',
48
70
  'dsh-live-voice.recognition.autoSend.countdownHelp':
49
71
  'A contagem regressiva inicia após a frase final reconhecida. Nova fala ou edições cancelam o envio.',
50
72
  'dsh-live-voice.recognition.browser.autoInstallPack':
@@ -164,6 +186,12 @@ const ptBR: LiveVoiceTranslation = {
164
186
  'dsh-live-voice.settings.autoSend.countdown': 'Enviando em {remaining}…',
165
187
  'dsh-live-voice.settings.autoSend.delay': 'Enviar após o silêncio',
166
188
  'dsh-live-voice.settings.close': 'Fechar configurações de voz',
189
+ 'dsh-live-voice.settings.delivery.dshEnterHelp':
190
+ 'O Live Voice usa sua resposta para escolher a ação correta ao enviar como Steer ou colocar na Fila. Isto não altera as configurações do DSH; informe o comportamento que você já usa nele e atualize esta resposta se ele mudar.',
191
+ 'dsh-live-voice.settings.delivery.dshEnterQuestion':
192
+ 'No seu DSH, quando o agente está ocupado, o Enter faz o quê?',
193
+ 'dsh-live-voice.settings.delivery.dshEnterQueue': 'Coloca a mensagem na fila',
194
+ 'dsh-live-voice.settings.delivery.dshEnterSteer': 'Envia a mensagem como steer',
167
195
  'dsh-live-voice.settings.delivery.label': 'Modo de envio',
168
196
  'dsh-live-voice.settings.delivery.manualLabel': 'Desativado — revisar e enviar manualmente',
169
197
  'dsh-live-voice.settings.delivery.queueLabel': 'Fila — adicionar automaticamente após o silêncio',
@@ -192,6 +220,8 @@ const ptBR: LiveVoiceTranslation = {
192
220
  'Esta instrução em inglês é enviada ao agente somente durante uma conversa por voz ativa com fala automática do assistente ativada.',
193
221
  'dsh-live-voice.speak.agentContext.label': 'Contexto de voz do agente',
194
222
  'dsh-live-voice.speak.agentContext.restore': 'Restaurar padrão',
223
+ 'dsh-live-voice.speak.autoPlayback.disable': 'Desativar fala automática da IA',
224
+ 'dsh-live-voice.speak.autoPlayback.enable': 'Ativar fala automática da IA',
195
225
  'dsh-live-voice.speak.autoPlayback.enabled':
196
226
  'Falar automaticamente novas mensagens do assistente',
197
227
  'dsh-live-voice.speak.autoPlayback.help':
@@ -208,6 +238,11 @@ const ptBR: LiveVoiceTranslation = {
208
238
  'dsh-live-voice.speak.browser.outputHelp':
209
239
  'A síntese de fala do navegador pode ignorar o dispositivo de saída selecionado; esta API normalmente segue o padrão do sistema.',
210
240
  'dsh-live-voice.speak.browser.voice': 'Voz local do navegador',
241
+ 'dsh-live-voice.speak.captions.approximate': 'Legendas aproximadas da fala',
242
+ 'dsh-live-voice.speak.captions.loading': 'Preparando áudio da fala',
243
+ 'dsh-live-voice.speak.captions.position': 'Trecho de fala {index} de {total}',
244
+ 'dsh-live-voice.speak.captions.progress': 'Progresso aproximado da fala',
245
+ 'dsh-live-voice.speak.captions.title': 'Fala e legendas ao vivo',
211
246
  'dsh-live-voice.speak.engine.label': 'Mecanismo de fala',
212
247
  'dsh-live-voice.speak.engine.playbackHelp':
213
248
  'Qwen e macOS say sintetizam no host do DSH; o áudio AAC/M4A compacto é reproduzido neste navegador. A fala do navegador é sintetizada e reproduzida neste dispositivo.',
@@ -236,6 +271,7 @@ const ptBR: LiveVoiceTranslation = {
236
271
  'dsh-live-voice.speak.playback.message': 'Falar mensagem',
237
272
  'dsh-live-voice.speak.playback.next': 'Pular para o próximo trecho de fala',
238
273
  'dsh-live-voice.speak.playback.pause': 'Pausar fala',
274
+ 'dsh-live-voice.speak.playback.previous': 'Voltar ao trecho de fala anterior',
239
275
  'dsh-live-voice.speak.playback.resume': 'Retomar fala',
240
276
  'dsh-live-voice.speak.playback.stop': 'Parar de falar',
241
277
  'dsh-live-voice.speak.playback.stopAll': 'Parar toda a fala',
@@ -270,6 +306,7 @@ const ptBR: LiveVoiceTranslation = {
270
306
  'dsh-live-voice.speak.responseDelay.help':
271
307
  'Depois que você parar de falar, a reprodução automática do assistente aguardará esse tempo de silêncio contínuo. Falar novamente reinicia a contagem.',
272
308
  'dsh-live-voice.speak.responseDelay.label': 'Atraso da resposta do assistente',
309
+ 'dsh-live-voice.speak.responseDelay.none': 'Sem atraso',
273
310
  'dsh-live-voice.speak.segmentGap.help':
274
311
  'Aguarde esta quantidade de milissegundos entre trechos falados consecutivos. O padrão é 400 ms.',
275
312
  'dsh-live-voice.speak.segmentGap.label': 'Pausa entre trechos de fala',
@@ -23,12 +23,14 @@ const zh: LiveVoiceTranslation = {
23
23
  'dsh-live-voice.commons.input.listening': '正在聆听',
24
24
  'dsh-live-voice.commons.input.listeningBadge': '聆听中',
25
25
  'dsh-live-voice.commons.manual': '手动',
26
+ 'dsh-live-voice.commons.milliseconds': '{milliseconds} 毫秒',
26
27
  'dsh-live-voice.commons.off': '关闭',
27
28
  'dsh-live-voice.commons.on': '开启',
28
29
  'dsh-live-voice.commons.pluginName': 'Live Voice',
29
30
  'dsh-live-voice.commons.queue': '队列',
30
31
  'dsh-live-voice.commons.repository.starLabel': '在 GitHub 上为我们加星',
31
32
  'dsh-live-voice.commons.repository.starLink': '在 GitHub 上为 DSH Live Voice 加星',
33
+ 'dsh-live-voice.commons.second': '1 秒',
32
34
  'dsh-live-voice.commons.seconds': '{seconds} 秒',
33
35
  'dsh-live-voice.commons.send': '发送',
34
36
  'dsh-live-voice.commons.status.ready': '语音已就绪',
@@ -43,6 +45,24 @@ const zh: LiveVoiceTranslation = {
43
45
  'dsh-live-voice.commons.version.label': 'DSH Live Voice v{version}',
44
46
  'dsh-live-voice.commons.version.link': 'DSH Live Voice v{version}。打开版本发布列表',
45
47
  'dsh-live-voice.commons.version.title': '版本信息',
48
+ 'dsh-live-voice.meeting.failed': '语音识别失败。',
49
+ 'dsh-live-voice.meeting.help': '独立来源;请从编辑器手动发送转写内容。',
50
+ 'dsh-live-voice.meeting.httpRequired': '会议模式需要 Qwen 或 Whisper HTTP。',
51
+ 'dsh-live-voice.meeting.inactive': '未启用',
52
+ 'dsh-live-voice.meeting.listening': '正在聆听',
53
+ 'dsh-live-voice.meeting.microphone': '麦克风',
54
+ 'dsh-live-voice.meeting.noAudio': '未共享音频。请在共享对话框中启用音频。',
55
+ 'dsh-live-voice.meeting.processing': '正在转写…',
56
+ 'dsh-live-voice.meeting.shared': '共享音频',
57
+ 'dsh-live-voice.meeting.start': '启动来源',
58
+ 'dsh-live-voice.meeting.startShared': '开始共享音频',
59
+ 'dsh-live-voice.meeting.starting': '正在启动…',
60
+ 'dsh-live-voice.meeting.stop': '停止来源',
61
+ 'dsh-live-voice.meeting.stopShared': '停止共享音频',
62
+ 'dsh-live-voice.meeting.timestamps': '转写时间戳',
63
+ 'dsh-live-voice.meeting.timestampsBadge': '时间戳',
64
+ 'dsh-live-voice.meeting.title': '会议模式',
65
+ 'dsh-live-voice.meeting.unavailable': '语音识别不可用。',
46
66
  'dsh-live-voice.recognition.autoSend.countdownHelp':
47
67
  '识别出最终语句后开始倒计时。再次说话或编辑文本会取消倒计时。',
48
68
  'dsh-live-voice.recognition.browser.autoInstallPack': '需要时自动安装此浏览器语言包',
@@ -152,6 +172,12 @@ const zh: LiveVoiceTranslation = {
152
172
  'dsh-live-voice.settings.autoSend.countdown': '{remaining} 后发送…',
153
173
  'dsh-live-voice.settings.autoSend.delay': '静音后发送',
154
174
  'dsh-live-voice.settings.close': '关闭语音设置',
175
+ 'dsh-live-voice.settings.delivery.dshEnterHelp':
176
+ 'Live Voice 根据您的回答,为引导和加入队列选择正确的操作。这不会更改 DSH 设置;请填写当前 DSH 的行为,并在该行为变化时更新此回答。',
177
+ 'dsh-live-voice.settings.delivery.dshEnterQuestion':
178
+ '在您的 DSH 中,智能体忙碌时按 Enter 会怎样?',
179
+ 'dsh-live-voice.settings.delivery.dshEnterQueue': '将消息加入队列',
180
+ 'dsh-live-voice.settings.delivery.dshEnterSteer': '发送消息以引导智能体',
155
181
  'dsh-live-voice.settings.delivery.label': '发送模式',
156
182
  'dsh-live-voice.settings.delivery.manualLabel': '关闭 — 审阅后手动发送',
157
183
  'dsh-live-voice.settings.delivery.queueLabel': '队列 — 静音后自动加入队列',
@@ -177,6 +203,8 @@ const zh: LiveVoiceTranslation = {
177
203
  '此英文指令仅在语音对话处于活动状态且启用自动朗读助手回复时发送给代理。',
178
204
  'dsh-live-voice.speak.agentContext.label': '代理语音上下文',
179
205
  'dsh-live-voice.speak.agentContext.restore': '恢复默认值',
206
+ 'dsh-live-voice.speak.autoPlayback.disable': '关闭助手自动朗读',
207
+ 'dsh-live-voice.speak.autoPlayback.enable': '开启助手自动朗读',
180
208
  'dsh-live-voice.speak.autoPlayback.enabled': '自动朗读新的助手消息',
181
209
  'dsh-live-voice.speak.autoPlayback.help':
182
210
  '语音对话期间,助手的语句会自动朗读。你说话时会等待,不会播放。',
@@ -192,6 +220,11 @@ const zh: LiveVoiceTranslation = {
192
220
  'dsh-live-voice.speak.browser.outputHelp':
193
221
  '浏览器语音合成可能忽略所选输出设备;此浏览器 API 通常使用系统默认设备。',
194
222
  'dsh-live-voice.speak.browser.voice': '浏览器本地语音',
223
+ 'dsh-live-voice.speak.captions.approximate': '近似语音字幕',
224
+ 'dsh-live-voice.speak.captions.loading': '正在准备语音音频',
225
+ 'dsh-live-voice.speak.captions.position': '语音片段 {index}/{total}',
226
+ 'dsh-live-voice.speak.captions.progress': '近似语音进度',
227
+ 'dsh-live-voice.speak.captions.title': '语音与实时字幕',
195
228
  'dsh-live-voice.speak.engine.label': '语音合成引擎',
196
229
  'dsh-live-voice.speak.engine.playbackHelp':
197
230
  'Qwen 和 macOS say 在 DSH 主机上合成语音;压缩的 AAC/M4A 音频在此浏览器中播放。浏览器语音则在此设备上合成并播放。',
@@ -216,6 +249,7 @@ const zh: LiveVoiceTranslation = {
216
249
  'dsh-live-voice.speak.playback.message': '朗读消息',
217
250
  'dsh-live-voice.speak.playback.next': '跳至下一语音片段',
218
251
  'dsh-live-voice.speak.playback.pause': '暂停朗读',
252
+ 'dsh-live-voice.speak.playback.previous': '上一语音片段',
219
253
  'dsh-live-voice.speak.playback.resume': '恢复朗读',
220
254
  'dsh-live-voice.speak.playback.stop': '停止朗读',
221
255
  'dsh-live-voice.speak.playback.stopAll': '停止全部朗读',
@@ -248,6 +282,7 @@ const zh: LiveVoiceTranslation = {
248
282
  'dsh-live-voice.speak.responseDelay.help':
249
283
  '你停止说话后,助手会等待此时长的连续静音,然后自动播放语音。再次说话会重新开始等待。',
250
284
  'dsh-live-voice.speak.responseDelay.label': '助手响应延迟',
285
+ 'dsh-live-voice.speak.responseDelay.none': '无延迟',
251
286
  'dsh-live-voice.speak.segmentGap.help': '在连续语音片段之间等待此毫秒数。默认值为 400 ms。',
252
287
  'dsh-live-voice.speak.segmentGap.label': '语音片段之间的停顿',
253
288
  'dsh-live-voice.speak.status.paused': '语音已暂停',
@@ -2,4 +2,4 @@
2
2
 
3
3
  Read the nearest module's `ARCHITECTURE.md` before changing its behavior. `src/modules` owns product policy, feature UI, models, providers, and services. Modules may use `src/shared` and the centralized `src/app/client/i18n` API, but must not register DSH slots or host routes; composition belongs to `src/app`.
4
4
 
5
- Preserve local-first STT and TTS options without claiming DSH itself is offline. Track capture/recognition, synthesis/playback, and agent generation separately. Preserve pause, resume, cancel, ownership, interruption, and stale asynchronous result semantics. Avoid logging raw audio or transcripts by default. Consult [VOICE-LIFECYCLE.md](../../docs/VOICE-LIFECYCLE.md) for the behavioral contract and [root guidance](../../AGENTS.md) for testing and authorization.
5
+ Preserve local-first STT and TTS options without claiming DSH itself is offline. Track capture/recognition, synthesis/playback, and agent generation separately. Preserve pause, resume, cancel, ownership, interruption, and stale asynchronous result semantics. Avoid logging raw audio or transcripts by default. Consult [VOICE-LIFECYCLE.md](../../../../docs/VOICE-LIFECYCLE.md) for the behavioral contract and [root guidance](../../../../AGENTS.md) for testing and authorization.
@@ -1,7 +1,9 @@
1
1
  # Conversation module
2
2
 
3
- Dictation is append-only at the current composer end. Final chunks preserve existing and manually edited text; provisional hypotheses never rewrite the editor. Client synchronization must accept a new manual publication even when the previous voice echo was skipped, while ignoring unchanged stale slot snapshots. Explicit Clear and normal submit actions are separate from dictation.
3
+ Dictation is append-only at the current composer end. Final chunks preserve existing and manually edited text; provisional hypotheses never rewrite the editor. Client synchronization must accept a new manual publication even when the previous voice echo was skipped, while ignoring unchanged stale slot snapshots. Explicit Clear and normal submit actions are separate from dictation. Appends preserve the active caret, directional selection, focus and scroll; `app/client/composerSelection.ts` restores DOM bookmarks after the synchronous DSH editor write and publishes selectionchange through the editor bridge.
4
4
 
5
5
  `models/chat.ts` interprets DSH chat turns and pending questions. `hooks/useConversationController.ts` subscribes to session state; `hooks/useConversationActions.ts` maps user actions onto the controller. `components/` renders composer controls, microphone state, playback controls, status, and waveform; `createConversationComponents.tsx` composes them for the application slot boundary.
6
6
 
7
- Keep UI components session-facing rather than importing host engines or registering slots. Preserve the DSH composer contract: `useInput` provides subscribed input and `inputActions.setDraft()` updates the composer; a recognition result must not be lost to stale interim updates. History pagination must not count as a new user turn. Do not treat sending, recognition, playback, or agent generation as one state. See [voice lifecycle](../../../docs/VOICE-LIFECYCLE.md) before changing interruption or turn-taking.
7
+ Live Voice’s persisted `dshBusyEnterBehavior` is a user-reported fact about DSH, not a DSH configuration write. Delivery matching that behavior uses `inputActions.submit()`; the opposite uses the accelerated Ctrl+Enter gesture. Read the current answer at submission time for every delivery source; Queue is the compatibility default. DSH remains responsible for idle/unsupported-steering behavior.
8
+
9
+ Keep UI components session-facing rather than importing host engines or registering slots. Preserve the DSH composer contract: `useInput` provides subscribed input and `inputActions.setDraft()` updates the composer; a recognition result must not be lost to stale interim updates. History pagination must not count as a new user turn. Do not treat sending, recognition, playback, or agent generation as one state. See [voice lifecycle](../../../../../docs/VOICE-LIFECYCLE.md) before changing interruption or turn-taking.
@@ -0,0 +1,31 @@
1
+ import React from 'react';
2
+ import { useLanguage } from '../../../app/client/i18n/index.js';
3
+ import { IconButton } from '../../../shared/design-system/index.js';
4
+ export function AutoPlaybackToggle({ state, invoke, error }: any) {
5
+ const { scoped: commons } = useLanguage((ctx) => ctx.commons);
6
+ const { scoped: speak } = useLanguage((ctx) => ctx.speak);
7
+ const active = state.settings.announceAssistantMessages !== false;
8
+ const count = state.speechSegmentsRemaining || 0;
9
+ const title =
10
+ count > 0
11
+ ? (speak as any).autoPlayback[count === 1 ? 'remainingOne' : 'remainingOther']({
12
+ state: active ? (commons as any).on() : (commons as any).off(),
13
+ count,
14
+ })
15
+ : (speak as any).autoPlayback.status({
16
+ state: active ? (commons as any).on() : (commons as any).off(),
17
+ });
18
+ return (
19
+ <IconButton
20
+ className="dlv-composer-toggle"
21
+ aria-pressed={active}
22
+ data-toggle-active={String(active)}
23
+ label={(speak as any).autoPlayback.label()}
24
+ title={error || (speak as any).autoPlayback[active ? 'disable' : 'enable']() + ' — ' + title}
25
+ icon={active ? 'speaker' : 'speakerOff'}
26
+ role="switch"
27
+ aria-checked={active}
28
+ onClick={() => invoke('updateSettings', { announceAssistantMessages: !active })}
29
+ />
30
+ );
31
+ }