@goodandready/dsh-tts 0.2.0 → 0.2.1

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.
package/lib/client.js CHANGED
@@ -66,6 +66,7 @@ window.__ModuleLoader__.load({
66
66
  rate: 1,
67
67
  chime: 'ding',
68
68
  queue: [],
69
+ bargeIn: true,
69
70
  busy: false,
70
71
  paused: false,
71
72
  listeners: new Set(),
@@ -190,6 +191,24 @@ window.__ModuleLoader__.load({
190
191
  playerChanged()
191
192
  }
192
193
 
194
+ // Человек заговорил — замолкаем.
195
+ //
196
+ // Событие приходит из плагина голосового ввода, но никакой связи с ним
197
+ // нет: если его не установили, событие просто никогда не придёт. Слушаем
198
+ // окно, а не чужую службу, ровно поэтому.
199
+ function listenForVoice() {
200
+ if (typeof window === 'undefined') return () => {}
201
+ const onSpeaking = (event) => {
202
+ const phase = event && event.detail && event.detail.phase
203
+ if (phase !== 'start') return
204
+ if (!player.bargeIn) return
205
+ if (!player.audio && !player.queue.length && !player.busy) return
206
+ stopPlayback()
207
+ }
208
+ window.addEventListener('dsh-voice:speaking', onSpeaking)
209
+ return () => window.removeEventListener('dsh-voice:speaking', onSpeaking)
210
+ }
211
+
193
212
  async function pollPending() {
194
213
  try {
195
214
  const st = await fetch('/dsh-tts/status', { cache: 'no-store' })
@@ -198,6 +217,7 @@ window.__ModuleLoader__.load({
198
217
  player.enabled = !!(meta && meta.speakReplies)
199
218
  if (meta && typeof meta.rate === 'number') player.rate = meta.rate
200
219
  if (meta && meta.chime) player.chime = meta.chime
220
+ if (meta && typeof meta.bargeIn === 'boolean') player.bargeIn = meta.bargeIn
201
221
  if (!player.enabled) return
202
222
  const res = await fetch('/dsh-tts/pending?after=' + encodeURIComponent(player.after || ''), { cache: 'no-store' })
203
223
  if (!res.ok) return
@@ -420,6 +440,8 @@ window.__ModuleLoader__.load({
420
440
  boolField('speakAsItGoes', 'Speak as it goes',
421
441
  'Read each reply the moment it lands, sentence by sentence, instead of waiting for the whole turn.'),
422
442
  numberField('rate', 'Playback speed', '0.5 to 2. Synthesis is untouched; the browser plays faster or slower.', 0.1),
443
+ boolField('bargeIn', 'Fall silent when you speak',
444
+ 'Stop reading the moment the microphone opens.'),
423
445
  boolField('announceApproval', 'Announce approvals',
424
446
  'Say it out loud and play a chime when the agent stops for an approval or asks a question.'),
425
447
  textField('approvalText', 'Approval wording', 'Said when an approval is asked for; the tool name is appended.'),
@@ -479,6 +501,7 @@ window.__ModuleLoader__.load({
479
501
  exports.apply = function apply(ctx) {
480
502
  registerSettings(ctx)
481
503
  registerSpeaker(ctx)
504
+ ctx.effect(() => listenForVoice(), 'dsh-tts: замолкать, когда человек заговорил')
482
505
  setInterval(pollPending, 1000)
483
506
  }
484
507
  return module.exports
package/lib/index.js CHANGED
@@ -45,6 +45,11 @@ export const Config = z.object({
45
45
  .number()
46
46
  .description('Playback speed, 0.5 to 2. Synthesis is untouched; the browser plays faster or slower.')
47
47
  .default(1),
48
+ bargeIn: z
49
+ .boolean()
50
+ .description('Fall silent the moment the microphone opens. Listening to a reply and talking over it '
51
+ + 'at the same time does not work, and the reply would be recorded along with the voice.')
52
+ .default(true),
48
53
  announceApproval: z
49
54
  .boolean()
50
55
  .description('Say out loud when the agent stops and waits for an approval, and play a short chime. '
@@ -360,6 +365,7 @@ export function apply(ctx, config) {
360
365
  speakReplies: cfg.speakReplies,
361
366
  rate: cfg.rate,
362
367
  chime: cfg.chime,
368
+ bargeIn: cfg.bargeIn,
363
369
  language: cfg.language,
364
370
  chain: cfg.chain,
365
371
  providers: PROVIDER_KEYS,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@goodandready/dsh-tts",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "description": "Text-to-speech for DeepSeek Harness: speak agent replies in the Web UI with a provider fallback chain (OpenAI, ElevenLabs, Google, Azure, Groq, Deepgram, OpenRouter, Edge, Piper, eSpeak).",
5
5
  "license": "MIT",
6
6
  "type": "module",