@goodandready/dsh-tts 0.3.11 → 0.3.13

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
@@ -473,8 +473,18 @@ window.__ModuleLoader__.load({
473
473
  'customBaseUrlHint': 'OpenAI-compatible origin, e.g. http://localhost:8880/v1; empty = off.',
474
474
  'customKeyEnv': 'Custom key env',
475
475
  'customKeyEnvHint': 'Credential name for the custom endpoint bearer key.',
476
+
477
+ 'dockLabel': 'Speech',
478
+ 'dockPause': 'Pause',
479
+ 'dockResume': 'Resume speech',
480
+ 'dockStop': 'Stop speech',
476
481
  }
477
482
  const ru = {
483
+ 'dockLabel': 'Чтение',
484
+ 'dockPause': 'Пауза',
485
+ 'dockResume': 'Продолжить чтение',
486
+ 'dockStop': 'Прекратить чтение',
487
+
478
488
  'general': 'Общее',
479
489
  'loading': 'Загрузка…',
480
490
  'chainHintCard': 'Выберите провайдера, вставьте ключ и нажмите «Сохранить» (или просто уйдите из поля). Ключ сразу попадает в хранилище учётных данных харнесса; браузер его обратно не читает.',
@@ -949,7 +959,11 @@ window.__ModuleLoader__.load({
949
959
 
950
960
  // Кнопка в строке ввода: видно, что сейчас читается, можно остановить и
951
961
  // открыть недавние озвучки для реплая.
952
- function SpeakerControl() {
962
+ function SpeakerControl(props) {
963
+ // Слот с `locale` кладёт перевод в props; запасной путь — привязка,
964
+ // сделанная при регистрации. Второй нужен на случай, если слот перевод
965
+ // не донесёт: без него кнопки остались бы без подписей вовсе.
966
+ const t = (props && props.t) || fallbackDockText
953
967
  const p = usePlayer()
954
968
  const [showList, setShowList] = React.useState(false)
955
969
  const active = !!p.audio || p.queue.length > 0 || p.busy
@@ -985,21 +999,39 @@ window.__ModuleLoader__.load({
985
999
  React.createElement('button', {
986
1000
  type: 'button',
987
1001
  className: 'dts-link',
988
- title: p.paused ? 'Продолжить чтение' : 'Пауза',
1002
+ title: p.paused ? t('dockResume') : t('dockPause'),
989
1003
  onClick: togglePause,
990
1004
  }, p.paused ? '▶' : '❚❚'),
991
1005
  React.createElement('button', {
992
1006
  type: 'button',
993
1007
  className: 'dts-link',
994
- title: 'Прекратить чтение',
1008
+ title: t('dockStop'),
995
1009
  onClick: stopPlayback,
996
1010
  }, '■'),
997
1011
  )
998
1012
  }
999
1013
 
1014
+ /**
1015
+ * Запасной перевод дока.
1016
+ *
1017
+ * Ставится при регистрации и живёт до конца работы страницы. Нужен
1018
+ * потому, что подпись слота рисует ядро: `props.t` туда не доходит в
1019
+ * принципе, и привязка — единственный способ дать ей язык.
1020
+ */
1021
+ let fallbackDockText = (key) => key
1022
+
1000
1023
  function registerSpeaker(ctx) {
1024
+ // `locale` в описании слота — то, чем ядро кладёт перевод в props
1025
+ // компонента. Без него внутри дока не было бы ничего, кроме ключей.
1026
+ fallbackDockText = ctx.locale.bind(NS)
1001
1027
  ctx.slots.inject('conversation.input.dock', () => ctx.slots.register(
1002
- { name: 'conversation.input.dock', id: '@goodandready/dsh-tts', order: 5, label: () => 'Чтение' },
1028
+ {
1029
+ name: 'conversation.input.dock',
1030
+ id: '@goodandready/dsh-tts',
1031
+ locale: NS,
1032
+ order: 5,
1033
+ label: () => fallbackDockText('dockLabel'),
1034
+ },
1003
1035
  SpeakerControl,
1004
1036
  ))
1005
1037
  }
package/lib/index.js CHANGED
@@ -68,7 +68,7 @@ export const Config = z.object({
68
68
  })).default([])
69
69
  .description('Say this instead of that. Applied top-down; /regex/ form allowed in from.'),
70
70
  longReply: z.string().default('truncate')
71
- .description('What to do when a reply exceeds the length limit.'), .description('What to do when a reply exceeds the length limit.'),
71
+ .description('What to do when a reply exceeds the length limit.'),
72
72
  summaryModel: z.string().default('')
73
73
  .description('provider/model for the spoken retelling; empty uses the conversation default.'),
74
74
  summarySentences: z.number().default(3)
@@ -278,8 +278,6 @@ export function apply(ctx, config) {
278
278
  // Счётчики синтеза: в памяти, обнуляются рестартом и DELETE /stats.
279
279
  const stats = { total: 0, cacheHits: 0, errors: 0, providers: {} }
280
280
 
281
- const llm = ctx.llm
282
-
283
281
  // Кэш синтеза живёт рядом с прочими данными харнесса.
284
282
  const speechCache = createSpeechCache({
285
283
  root: process.env.DSH_HOME || path.join(os.homedir(), '.dsh'),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@goodandready/dsh-tts",
3
- "version": "0.3.11",
3
+ "version": "0.3.13",
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",