iobroker.assistant 0.1.2

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 (98) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +176 -0
  3. package/admin/assistant.svg +19 -0
  4. package/admin/custom/.vite/manifest.json +169 -0
  5. package/admin/custom/assets/Components-DcnuVFM6.js +1 -0
  6. package/admin/custom/assets/_virtual_mf-localSharedImportMap___mfe_internal__ConfigCustomAssistant__mf_owner__1-DogEjv3U.js +1 -0
  7. package/admin/custom/assets/_virtual_mf___mfe_internal__ConfigCustomAssistant__mf_owner__1__loadShare___mf_0_emotion_mf_1_react__loadShare__.js-Dw5TkU1t.js +1 -0
  8. package/admin/custom/assets/_virtual_mf___mfe_internal__ConfigCustomAssistant__mf_owner__1__loadShare___mf_0_emotion_mf_1_styled__loadShare__.js-BEFjTs9S.js +1 -0
  9. package/admin/custom/assets/_virtual_mf___mfe_internal__ConfigCustomAssistant__mf_owner__1__loadShare___mf_0_iobroker_mf_1_gui_mf_2_components__loadShare__.js-C4r3udVz.js +1243 -0
  10. package/admin/custom/assets/_virtual_mf___mfe_internal__ConfigCustomAssistant__mf_owner__1__loadShare___mf_0_iobroker_mf_1_json_mf_2_config__loadShare__.js-DlOBHPL0.js +1494 -0
  11. package/admin/custom/assets/hostInit-DKMI-sLp.js +1 -0
  12. package/admin/custom/assets/index-B8wW0kQx.js +1 -0
  13. package/admin/custom/assets/lib-DpE8sc4h.js +3 -0
  14. package/admin/custom/assets/mf-entry-bootstrap-0-e7fa582d.js +36 -0
  15. package/admin/custom/assets/rolldown-runtime-C0FnF6B9.js +1 -0
  16. package/admin/custom/assets/virtualExposes-DOTO22UK.js +1 -0
  17. package/admin/custom/assets/virtual_mf-REMOTE_ENTRY_ID___mfe_internal__ConfigCustomAssistant__customComponents_js-CQa59yVi.js +1 -0
  18. package/admin/custom/assets/virtual_mf-exposes-ssr___mfe_internal__ConfigCustomAssistant__customComponents_js-9g2Fj8tk.js +2 -0
  19. package/admin/custom/assets/virtual_mf-exposes___mfe_internal__ConfigCustomAssistant__customComponents_js-BTUQTbYo.js +2 -0
  20. package/admin/custom/assets/vite-preload-helper-B7qeedMF.js +1 -0
  21. package/admin/custom/customComponents.js +1 -0
  22. package/admin/custom/customComponents.ssr.js +1 -0
  23. package/admin/custom/i18n/de.json +58 -0
  24. package/admin/custom/i18n/en.json +58 -0
  25. package/admin/custom/i18n/es.json +34 -0
  26. package/admin/custom/i18n/fr.json +34 -0
  27. package/admin/custom/i18n/it.json +34 -0
  28. package/admin/custom/i18n/nl.json +34 -0
  29. package/admin/custom/i18n/pl.json +34 -0
  30. package/admin/custom/i18n/pt.json +34 -0
  31. package/admin/custom/i18n/ru.json +34 -0
  32. package/admin/custom/i18n/uk.json +34 -0
  33. package/admin/custom/i18n/zh-cn.json +34 -0
  34. package/admin/custom/index.html +32 -0
  35. package/admin/custom/mf-manifest.json +1 -0
  36. package/admin/custom/mf-stats.json +1 -0
  37. package/admin/i18n/de.json +130 -0
  38. package/admin/i18n/en.json +130 -0
  39. package/admin/i18n/es.json +106 -0
  40. package/admin/i18n/fr.json +106 -0
  41. package/admin/i18n/it.json +106 -0
  42. package/admin/i18n/nl.json +106 -0
  43. package/admin/i18n/pl.json +106 -0
  44. package/admin/i18n/pt.json +106 -0
  45. package/admin/i18n/ru.json +106 -0
  46. package/admin/i18n/uk.json +106 -0
  47. package/admin/i18n/zh-cn.json +106 -0
  48. package/admin/jsonConfig.json +743 -0
  49. package/admin/sounds/alarm.wav +0 -0
  50. package/admin/sounds/timer.wav +0 -0
  51. package/build/lib/alarms.js +281 -0
  52. package/build/lib/alarms.js.map +1 -0
  53. package/build/lib/context.js +52 -0
  54. package/build/lib/context.js.map +1 -0
  55. package/build/lib/credentials.js +121 -0
  56. package/build/lib/credentials.js.map +1 -0
  57. package/build/lib/llm.js +303 -0
  58. package/build/lib/llm.js.map +1 -0
  59. package/build/lib/localLlm.js +221 -0
  60. package/build/lib/localLlm.js.map +1 -0
  61. package/build/lib/memory.js +190 -0
  62. package/build/lib/memory.js.map +1 -0
  63. package/build/lib/nlu.js +929 -0
  64. package/build/lib/nlu.js.map +1 -0
  65. package/build/lib/timers.js +245 -0
  66. package/build/lib/timers.js.map +1 -0
  67. package/build/lib/tools.js +299 -0
  68. package/build/lib/tools.js.map +1 -0
  69. package/build/lib/voice/aws.js +102 -0
  70. package/build/lib/voice/aws.js.map +1 -0
  71. package/build/lib/voice/azure.js +144 -0
  72. package/build/lib/voice/azure.js.map +1 -0
  73. package/build/lib/voice/download.js +76 -0
  74. package/build/lib/voice/download.js.map +1 -0
  75. package/build/lib/voice/engines.js +89 -0
  76. package/build/lib/voice/engines.js.map +1 -0
  77. package/build/lib/voice/lang.js +33 -0
  78. package/build/lib/voice/lang.js.map +1 -0
  79. package/build/lib/voice/piper.js +191 -0
  80. package/build/lib/voice/piper.js.map +1 -0
  81. package/build/lib/voice/protocol.js +35 -0
  82. package/build/lib/voice/protocol.js.map +1 -0
  83. package/build/lib/voice/stt.js +116 -0
  84. package/build/lib/voice/stt.js.map +1 -0
  85. package/build/lib/voice/tts.js +36 -0
  86. package/build/lib/voice/tts.js.map +1 -0
  87. package/build/lib/voice/voiceServer.js +249 -0
  88. package/build/lib/voice/voiceServer.js.map +1 -0
  89. package/build/lib/voice/vosk.js +260 -0
  90. package/build/lib/voice/vosk.js.map +1 -0
  91. package/build/lib/voice/wyoming.js +320 -0
  92. package/build/lib/voice/wyoming.js.map +1 -0
  93. package/build/lib/weather.js +423 -0
  94. package/build/lib/weather.js.map +1 -0
  95. package/build/main.js +3152 -0
  96. package/build/main.js.map +1 -0
  97. package/io-package.json +528 -0
  98. package/package.json +68 -0
@@ -0,0 +1,743 @@
1
+ {
2
+ "i18n": true,
3
+ "type": "tabs",
4
+ "items": {
5
+ "_main": {
6
+ "type": "panel",
7
+ "label": "Settings",
8
+ "items": {
9
+ "_header": {
10
+ "type": "header",
11
+ "size": 2,
12
+ "text": "LLM assistant"
13
+ },
14
+ "provider": {
15
+ "newLine": true,
16
+ "type": "select",
17
+ "label": "Provider",
18
+ "options": [
19
+ { "label": "OpenAI", "value": "openai" },
20
+ { "label": "Anthropic (Claude)", "value": "anthropic" },
21
+ { "label": "Google Gemini", "value": "gemini" },
22
+ { "label": "DeepSeek", "value": "deepseek" },
23
+ { "label": "OpenAI-compatible (custom)", "value": "custom" }
24
+ ],
25
+ "default": "openai",
26
+ "sm": 12,
27
+ "md": 4
28
+ },
29
+ "credentialType": {
30
+ "newLine": true,
31
+ "type": "select",
32
+ "label": "Credential mode",
33
+ "options": [
34
+ { "label": "Store key in adapter", "value": "manual" },
35
+ { "label": "Central credential store", "value": "manager" }
36
+ ],
37
+ "default": "manual",
38
+ "sm": 12,
39
+ "md": 4
40
+ },
41
+ "apiKey": {
42
+ "type": "password",
43
+ "label": "API key",
44
+ "hidden": "data.credentialType === 'manager'",
45
+ "sm": 12,
46
+ "md": 4
47
+ },
48
+ "credentialIdApiKey": {
49
+ "type": "credential",
50
+ "credentialType": "ai",
51
+ "label": "API-key credential",
52
+ "hidden": "data.credentialType !== 'manager'",
53
+ "sm": 12,
54
+ "md": 4
55
+ },
56
+ "model": {
57
+ "newLine": true,
58
+ "type": "autocompleteSendTo",
59
+ "command": "getModels",
60
+ "jsonData": "{\"provider\":\"${data.provider}\",\"apiKey\":\"${data.apiKey}\",\"credentialType\":\"${data.credentialType}\",\"credentialId\":\"${data.credentialIdApiKey}\",\"baseUrl\":\"${data.baseUrl}\"}",
61
+ "alsoDependsOn": ["provider", "credentialType", "apiKey", "credentialIdApiKey", "baseUrl"],
62
+ "freeSolo": true,
63
+ "label": "Model",
64
+ "help": "Loaded from the provider (instance must run); you can also type a model id.",
65
+ "default": "gpt-4o-mini",
66
+ "sm": 12,
67
+ "md": 4
68
+ },
69
+ "baseUrl": {
70
+ "type": "text",
71
+ "label": "Base URL (optional)",
72
+ "help": "Override the endpoint, e.g. https://api.groq.com/openai/v1 for Groq. Leave empty for the provider default.",
73
+ "hidden": "data.provider !== 'custom'",
74
+ "sm": 12,
75
+ "md": 8
76
+ },
77
+ "_testConnection": {
78
+ "newLine": true,
79
+ "type": "sendTo",
80
+ "label": "Test connection",
81
+ "command": "testApiConnection",
82
+ "jsonData": "{\"provider\":\"${data.provider}\",\"apiKey\":\"${data.apiKey}\",\"credentialType\":\"${data.credentialType}\",\"model\":\"${data.model}\",\"baseUrl\":\"${data.baseUrl}\",\"credentialId\":\"${data.credentialIdApiKey}\"}",
83
+ "variant": "outlined",
84
+ "disabled": "data.credentialType === 'manager' ? !data.credentialIdApiKey : !data.apiKey",
85
+ "sm": 12,
86
+ "md": 4
87
+ },
88
+ "maxTokens": {
89
+ "newLine": true,
90
+ "type": "number",
91
+ "label": "Max tokens",
92
+ "default": 1024,
93
+ "min": 64,
94
+ "max": 8192,
95
+ "sm": 6,
96
+ "md": 2
97
+ },
98
+ "useLocalNlu": {
99
+ "type": "checkbox",
100
+ "label": "Answer simple commands locally (fast, offline)",
101
+ "help": "Try the built-in rule-based intent matching for turn on/off, dimming and status before calling the LLM.",
102
+ "default": true,
103
+ "sm": 6,
104
+ "md": 4
105
+ },
106
+ "nluAliases": {
107
+ "type": "table",
108
+ "label": "Synonym dictionary",
109
+ "help": "Rewrite spoken or typed variants to your device/room names before local matching, e.g. \"TV\" to \"Fernseher\". Leave the language empty to apply to all languages. Also used for the text channels.",
110
+ "hidden": "!data.useLocalNlu",
111
+ "sm": 12,
112
+ "md": 12,
113
+ "items": [
114
+ { "type": "text", "attr": "from", "title": "Said or typed", "width": "40%" },
115
+ { "type": "text", "attr": "to", "title": "Canonical term", "width": "40%" },
116
+ { "type": "text", "attr": "language", "title": "Language (empty = all)", "width": "20%" }
117
+ ]
118
+ },
119
+ "useConversationContext": {
120
+ "type": "checkbox",
121
+ "label": "Remember the conversation (follow-up questions)",
122
+ "help": "Keep the last few turns per source (chat, telegram, satellite) for a few minutes so follow-ups like 'and the kitchen too' work. In-memory only.",
123
+ "default": true,
124
+ "sm": 6,
125
+ "md": 4
126
+ },
127
+ "useLongTermMemory": {
128
+ "type": "checkbox",
129
+ "label": "Long-term memory (remember facts across sessions)",
130
+ "help": "Lets the assistant durably remember facts you tell it (names, preferences, where things are) and use them in later conversations. Stored in the memory.* states; the LLM gets remember/forget tools.",
131
+ "default": true,
132
+ "sm": 6,
133
+ "md": 4
134
+ },
135
+ "weatherInstance": {
136
+ "newLine": true,
137
+ "type": "selectSendTo",
138
+ "command": "getWeatherInstances",
139
+ "label": "Weather source",
140
+ "help": "Pick an installed weather adapter to answer weather questions from (Open-Meteo, Weather Underground, OpenWeatherMap are fully understood; others are read best-effort). Start that adapter once so its data/locations appear here.",
141
+ "sm": 12,
142
+ "md": 6
143
+ },
144
+ "timerAnnounce": {
145
+ "newLine": true,
146
+ "type": "checkbox",
147
+ "label": "Announce when a timer expires",
148
+ "help": "Speak an announcement on the satellite a countdown timer was set from (or on all satellites) when it runs out. Timers are always mirrored into the timers.* states for scripts and visualization.",
149
+ "default": true,
150
+ "sm": 6,
151
+ "md": 4
152
+ },
153
+ "alarmAnnounce": {
154
+ "type": "checkbox",
155
+ "label": "Announce when an alarm goes off",
156
+ "help": "Speak an announcement when an alarm at a fixed clock time fires. Alarms are always mirrored into the alarms.* states for scripts and visualization.",
157
+ "default": true,
158
+ "sm": 6,
159
+ "md": 4
160
+ },
161
+ "_soundsHint": {
162
+ "newLine": true,
163
+ "type": "staticText",
164
+ "text": "Two default sounds (timer.wav, alarm.wav) are preinstalled — pick one below or upload your own mp3/wav. The selected sound plays before the spoken announcement. Needs ffmpeg on the host and at least one satellite.",
165
+ "sm": 12,
166
+ "md": 12
167
+ },
168
+ "ringSeconds": {
169
+ "newLine": true,
170
+ "type": "number",
171
+ "label": "Ring duration (seconds)",
172
+ "help": "A fired timer/alarm keeps ringing (looping the sound) for up to this long, or until you say 'stop'/'halt'/'aufhören'/'cancel' (or write the stopRinging state). 0 = play the sound once.",
173
+ "default": 60,
174
+ "min": 0,
175
+ "max": 600,
176
+ "sm": 6,
177
+ "md": 3
178
+ },
179
+ "timerSound": {
180
+ "newLine": true,
181
+ "type": "fileSelector",
182
+ "objectID": "assistant.%INSTANCE%",
183
+ "upload": "sounds",
184
+ "pattern": "sounds/*",
185
+ "fileTypes": "audio",
186
+ "delete": true,
187
+ "refresh": true,
188
+ "maxSize": 5242880,
189
+ "label": "Timer sound (mp3/wav, optional)",
190
+ "sm": 12,
191
+ "md": 5
192
+ },
193
+ "_playTimerSound": {
194
+ "type": "sendTo",
195
+ "command": "playSound",
196
+ "label": "Play",
197
+ "variant": "outlined",
198
+ "jsonData": "{\"name\":\"${data.timerSound}\"}",
199
+ "disabled": "!data.timerSound",
200
+ "sm": 6,
201
+ "md": 2
202
+ },
203
+ "alarmSound": {
204
+ "newLine": true,
205
+ "type": "fileSelector",
206
+ "objectID": "assistant.%INSTANCE%",
207
+ "upload": "sounds",
208
+ "pattern": "sounds/*",
209
+ "fileTypes": "audio",
210
+ "delete": true,
211
+ "refresh": true,
212
+ "maxSize": 5242880,
213
+ "label": "Alarm sound (mp3/wav, optional)",
214
+ "sm": 12,
215
+ "md": 5
216
+ },
217
+ "_playAlarmSound": {
218
+ "type": "sendTo",
219
+ "command": "playSound",
220
+ "label": "Play",
221
+ "variant": "outlined",
222
+ "jsonData": "{\"name\":\"${data.alarmSound}\"}",
223
+ "disabled": "!data.alarmSound",
224
+ "sm": 6,
225
+ "md": 2
226
+ },
227
+ "useLocalLlm": {
228
+ "newLine": true,
229
+ "type": "checkbox",
230
+ "label": "Use a local LLM before the cloud (installed on demand)",
231
+ "help": "Runs a small local model (node-llama-cpp) for general questions; escalates to the cloud LLM when it needs live device data. Install it with the button below.",
232
+ "default": false,
233
+ "sm": 12,
234
+ "md": 6
235
+ },
236
+ "localLlmModelUrl": {
237
+ "type": "text",
238
+ "label": "Local model URL (GGUF, optional)",
239
+ "help": "Direct URL of a GGUF model. Leave empty for the default (Qwen2.5-1.5B-Instruct). Small models recommended on Raspberry Pi / arm64.",
240
+ "hidden": "!data.useLocalLlm",
241
+ "sm": 12,
242
+ "md": 6
243
+ },
244
+ "_installLocalLlm": {
245
+ "newLine": true,
246
+ "type": "sendTo",
247
+ "label": "Install local model",
248
+ "command": "installLocalLlm",
249
+ "variant": "outlined",
250
+ "hidden": "!data.useLocalLlm",
251
+ "showProcess": true,
252
+ "timeout": 600000,
253
+ "help": "Downloads the engine and model (several hundred MB). Progress is shown below.",
254
+ "sm": 12,
255
+ "md": 4
256
+ },
257
+ "_localLlmProgress": {
258
+ "newLine": true,
259
+ "type": "custom",
260
+ "i18n": true,
261
+ "url": "custom/customComponents.js",
262
+ "name": "ConfigCustomAssistant/Components/LocalLlmProgress",
263
+ "bundlerType": "module",
264
+ "guiApi": 2,
265
+ "hidden": "!data.useLocalLlm",
266
+ "sm": 12,
267
+ "md": 8
268
+ },
269
+ "_accessHeader": {
270
+ "newLine": true,
271
+ "type": "header",
272
+ "size": 2,
273
+ "text": "Access / permissions"
274
+ },
275
+ "readObjects": {
276
+ "newLine": true,
277
+ "type": "select",
278
+ "label": "Object read access",
279
+ "options": [
280
+ { "label": "Only devices, rooms, functions", "value": "devices" },
281
+ { "label": "Any object (get_object/search_objects)", "value": "all" }
282
+ ],
283
+ "default": "devices",
284
+ "sm": 12,
285
+ "md": 4
286
+ },
287
+ "allowWriteStates": {
288
+ "newLine": true,
289
+ "type": "checkbox",
290
+ "label": "Allow writing states (control devices)",
291
+ "default": true,
292
+ "sm": 6,
293
+ "md": 3
294
+ },
295
+ "allowHistory": {
296
+ "type": "checkbox",
297
+ "label": "Allow reading history",
298
+ "default": true,
299
+ "sm": 6,
300
+ "md": 3
301
+ },
302
+ "allowReadLogs": {
303
+ "newLine": true,
304
+ "type": "checkbox",
305
+ "label": "Allow reading logs",
306
+ "default": false,
307
+ "sm": 6,
308
+ "md": 3
309
+ },
310
+ "allowWriteLogs": {
311
+ "type": "checkbox",
312
+ "label": "Allow writing to the log",
313
+ "default": false,
314
+ "sm": 6,
315
+ "md": 3
316
+ },
317
+ "allowFiles": {
318
+ "newLine": true,
319
+ "type": "checkbox",
320
+ "label": "Allow reading files",
321
+ "default": false,
322
+ "sm": 6,
323
+ "md": 3
324
+ },
325
+ "allowSystemInfo": {
326
+ "type": "checkbox",
327
+ "label": "Allow system info (hosts, instances, adapters)",
328
+ "default": true,
329
+ "sm": 6,
330
+ "md": 3
331
+ },
332
+ "allowObjectChange": {
333
+ "newLine": true,
334
+ "type": "checkbox",
335
+ "label": "Allow changing objects and files (dangerous)",
336
+ "default": false,
337
+ "sm": 12,
338
+ "md": 6
339
+ },
340
+ "systemPrompt": {
341
+ "newLine": true,
342
+ "type": "text",
343
+ "label": "System prompt",
344
+ "minRows": 4,
345
+ "sm": 12,
346
+ "md": 12
347
+ }
348
+ }
349
+ },
350
+ "_devices": {
351
+ "type": "panel",
352
+ "label": "Devices",
353
+ "items": {
354
+ "_deviceAcl": {
355
+ "type": "custom",
356
+ "i18n": true,
357
+ "url": "custom/customComponents.js",
358
+ "name": "ConfigCustomAssistant/Components/DeviceAclComponent",
359
+ "guiApi": 2,
360
+ "bundlerType": "module",
361
+ "sm": 12
362
+ }
363
+ }
364
+ },
365
+ "_voice": {
366
+ "type": "panel",
367
+ "label": "Voice",
368
+ "items": {
369
+ "_voiceHeader": {
370
+ "type": "header",
371
+ "size": 2,
372
+ "text": "Voice satellites"
373
+ },
374
+ "voiceEnabled": {
375
+ "newLine": true,
376
+ "type": "checkbox",
377
+ "label": "Enable voice (STT/TTS for satellites)",
378
+ "help": "Enables speech recognition/synthesis. ioBroker-native satellites reach it over the message bus — no port needed. Turn on the UDP server below only for ESP / Hannah satellites.",
379
+ "default": false,
380
+ "sm": 12,
381
+ "md": 6
382
+ },
383
+ "udpServerEnabled": {
384
+ "newLine": true,
385
+ "type": "checkbox",
386
+ "label": "Run the UDP voice server (ESP / Hannah satellites)",
387
+ "help": "Opens a UDP port for streaming microphone satellites (Hannah-compatible / ESP). Not needed for ioBroker-native satellites.",
388
+ "default": false,
389
+ "hidden": "!data.voiceEnabled",
390
+ "sm": 12,
391
+ "md": 6
392
+ },
393
+ "bind": {
394
+ "newLine": true,
395
+ "type": "ip",
396
+ "freeSolo": true,
397
+ "label": "Bind address",
398
+ "help": "Interface the UDP voice server listens on. 0.0.0.0 = all interfaces; pick a specific host IP so satellites on the LAN can reach it.",
399
+ "default": "0.0.0.0",
400
+ "listenOnAllPorts": true,
401
+ "hidden": "!data.voiceEnabled || !data.udpServerEnabled",
402
+ "sm": 6,
403
+ "md": 3
404
+ },
405
+ "port": {
406
+ "type": "number",
407
+ "label": "UDP port",
408
+ "default": 7775,
409
+ "min": 1,
410
+ "max": 65535,
411
+ "hidden": "!data.voiceEnabled || !data.udpServerEnabled",
412
+ "sm": 6,
413
+ "md": 3
414
+ },
415
+ "wyomingEnabled": {
416
+ "newLine": true,
417
+ "type": "checkbox",
418
+ "label": "Also accept Wyoming clients (TCP)",
419
+ "help": "Home Assistant Voice PE / wyoming-satellite / ESPHome voice devices can stream to this adapter over the Wyoming protocol.",
420
+ "default": false,
421
+ "hidden": "!data.voiceEnabled",
422
+ "sm": 8,
423
+ "md": 5
424
+ },
425
+ "wyomingPort": {
426
+ "type": "number",
427
+ "label": "Wyoming TCP port",
428
+ "default": 10700,
429
+ "min": 1,
430
+ "max": 65535,
431
+ "hidden": "!data.voiceEnabled || !data.wyomingEnabled",
432
+ "sm": 4,
433
+ "md": 3
434
+ },
435
+ "voiceLanguage": {
436
+ "newLine": true,
437
+ "type": "select",
438
+ "label": "Voice language",
439
+ "help": "Language for speech recognition and the spoken reply.",
440
+ "options": [
441
+ { "label": "System language", "value": "" },
442
+ { "label": "Deutsch", "value": "de" },
443
+ { "label": "English", "value": "en" },
444
+ { "label": "Русский", "value": "ru" },
445
+ { "label": "Français", "value": "fr" },
446
+ { "label": "Italiano", "value": "it" },
447
+ { "label": "Español", "value": "es" },
448
+ { "label": "Nederlands", "value": "nl" },
449
+ { "label": "Polski", "value": "pl" },
450
+ { "label": "Português", "value": "pt" },
451
+ { "label": "Українська", "value": "uk" },
452
+ { "label": "中文", "value": "zh-cn" }
453
+ ],
454
+ "default": "",
455
+ "hidden": "!data.voiceEnabled",
456
+ "sm": 6,
457
+ "md": 3
458
+ },
459
+ "sttProvider": {
460
+ "newLine": true,
461
+ "type": "select",
462
+ "label": "Speech-to-text provider",
463
+ "options": [
464
+ { "label": "OpenAI (Whisper)", "value": "openai" },
465
+ { "label": "Azure Speech", "value": "azure" },
466
+ { "label": "AWS Transcribe", "value": "aws" },
467
+ { "label": "Vosk (local)", "value": "vosk" }
468
+ ],
469
+ "default": "openai",
470
+ "hidden": "!data.voiceEnabled",
471
+ "sm": 6,
472
+ "md": 3
473
+ },
474
+ "ttsProvider": {
475
+ "type": "select",
476
+ "label": "Text-to-speech provider",
477
+ "options": [
478
+ { "label": "OpenAI", "value": "openai" },
479
+ { "label": "Azure Speech", "value": "azure" },
480
+ { "label": "AWS Polly", "value": "aws" },
481
+ { "label": "Piper (local)", "value": "piper" }
482
+ ],
483
+ "default": "openai",
484
+ "hidden": "!data.voiceEnabled",
485
+ "sm": 6,
486
+ "md": 3
487
+ },
488
+ "voiceCredentialType": {
489
+ "newLine": true,
490
+ "type": "select",
491
+ "label": "Speech credential mode",
492
+ "options": [
493
+ { "label": "Store keys in adapter", "value": "manual" },
494
+ { "label": "Central credential store", "value": "manager" }
495
+ ],
496
+ "default": "manual",
497
+ "hidden": "!data.voiceEnabled || (data.sttProvider === 'vosk' && data.ttsProvider === 'piper')",
498
+ "sm": 12,
499
+ "md": 4
500
+ },
501
+ "_openaiSpeechHeader": {
502
+ "newLine": true,
503
+ "type": "header",
504
+ "size": 3,
505
+ "text": "OpenAI speech",
506
+ "hidden": "!data.voiceEnabled || (data.sttProvider !== 'openai' && data.ttsProvider !== 'openai')"
507
+ },
508
+ "voiceApiKey": {
509
+ "newLine": true,
510
+ "type": "password",
511
+ "label": "OpenAI key for speech (optional)",
512
+ "help": "Leave empty to reuse the main API key when the LLM provider is OpenAI; required otherwise.",
513
+ "hidden": "!data.voiceEnabled || (data.sttProvider !== 'openai' && data.ttsProvider !== 'openai') || data.voiceCredentialType === 'manager'",
514
+ "sm": 12,
515
+ "md": 8
516
+ },
517
+ "voiceCredentialId": {
518
+ "newLine": true,
519
+ "type": "credential",
520
+ "credentialType": "ai",
521
+ "label": "OpenAI credential",
522
+ "hidden": "!data.voiceEnabled || (data.sttProvider !== 'openai' && data.ttsProvider !== 'openai') || data.voiceCredentialType !== 'manager'",
523
+ "sm": 12,
524
+ "md": 6
525
+ },
526
+ "ttsVoice": {
527
+ "newLine": true,
528
+ "type": "autocompleteSendTo",
529
+ "command": "getVoices",
530
+ "jsonData": "{\"ttsProvider\":\"${data.ttsProvider}\",\"language\":\"${data.voiceLanguage}\",\"voiceCredentialType\":\"${data.voiceCredentialType}\",\"voiceApiKey\":\"${data.voiceApiKey}\",\"voiceCredentialId\":\"${data.voiceCredentialId}\"}",
531
+ "alsoDependsOn": ["ttsProvider", "voiceLanguage", "voiceCredentialType"],
532
+ "freeSolo": true,
533
+ "label": "TTS voice",
534
+ "help": "Loaded from the provider (instance must run); you can also type a voice id.",
535
+ "default": "alloy",
536
+ "hidden": "!data.voiceEnabled || data.ttsProvider !== 'openai'",
537
+ "sm": 6,
538
+ "md": 4
539
+ },
540
+ "sttModel": {
541
+ "newLine": true,
542
+ "type": "text",
543
+ "label": "OpenAI STT model (optional)",
544
+ "help": "Empty = whisper-1. Also: gpt-4o-transcribe, gpt-4o-mini-transcribe.",
545
+ "hidden": "!data.voiceEnabled || data.sttProvider !== 'openai'",
546
+ "sm": 6,
547
+ "md": 4
548
+ },
549
+ "ttsModel": {
550
+ "type": "text",
551
+ "label": "OpenAI TTS model (optional)",
552
+ "help": "Empty = tts-1. Also: tts-1-hd, gpt-4o-mini-tts.",
553
+ "hidden": "!data.voiceEnabled || data.ttsProvider !== 'openai'",
554
+ "sm": 6,
555
+ "md": 4
556
+ },
557
+ "_azureSpeechHeader": {
558
+ "newLine": true,
559
+ "type": "header",
560
+ "size": 3,
561
+ "text": "Azure Speech",
562
+ "hidden": "!data.voiceEnabled || (data.sttProvider !== 'azure' && data.ttsProvider !== 'azure')"
563
+ },
564
+ "azureSpeechKey": {
565
+ "newLine": true,
566
+ "type": "password",
567
+ "label": "Azure subscription key",
568
+ "hidden": "!data.voiceEnabled || (data.sttProvider !== 'azure' && data.ttsProvider !== 'azure') || data.voiceCredentialType === 'manager'",
569
+ "sm": 12,
570
+ "md": 5
571
+ },
572
+ "azureSpeechRegion": {
573
+ "type": "text",
574
+ "label": "Azure region",
575
+ "help": "e.g. westeurope",
576
+ "hidden": "!data.voiceEnabled || (data.sttProvider !== 'azure' && data.ttsProvider !== 'azure') || data.voiceCredentialType === 'manager'",
577
+ "sm": 6,
578
+ "md": 3
579
+ },
580
+ "azureCredentialId": {
581
+ "newLine": true,
582
+ "type": "credential",
583
+ "credentialType": "azure",
584
+ "label": "Azure credential",
585
+ "hidden": "!data.voiceEnabled || (data.sttProvider !== 'azure' && data.ttsProvider !== 'azure') || data.voiceCredentialType !== 'manager'",
586
+ "sm": 12,
587
+ "md": 6
588
+ },
589
+ "azureVoice": {
590
+ "newLine": true,
591
+ "type": "autocompleteSendTo",
592
+ "command": "getVoices",
593
+ "jsonData": "{\"ttsProvider\":\"${data.ttsProvider}\",\"language\":\"${data.voiceLanguage}\",\"voiceCredentialType\":\"${data.voiceCredentialType}\",\"azureSpeechKey\":\"${data.azureSpeechKey}\",\"azureSpeechRegion\":\"${data.azureSpeechRegion}\",\"azureCredentialId\":\"${data.azureCredentialId}\"}",
594
+ "alsoDependsOn": [
595
+ "ttsProvider",
596
+ "voiceLanguage",
597
+ "voiceCredentialType",
598
+ "azureSpeechKey",
599
+ "azureSpeechRegion",
600
+ "azureCredentialId"
601
+ ],
602
+ "freeSolo": true,
603
+ "label": "Azure voice (optional)",
604
+ "help": "Loaded from Azure (instance must run); empty = pick by language. e.g. de-DE-KatjaNeural.",
605
+ "hidden": "!data.voiceEnabled || data.ttsProvider !== 'azure'",
606
+ "sm": 6,
607
+ "md": 5
608
+ },
609
+ "_awsSpeechHeader": {
610
+ "newLine": true,
611
+ "type": "header",
612
+ "size": 3,
613
+ "text": "AWS speech",
614
+ "hidden": "!data.voiceEnabled || (data.sttProvider !== 'aws' && data.ttsProvider !== 'aws')"
615
+ },
616
+ "awsAccessKeyId": {
617
+ "newLine": true,
618
+ "type": "text",
619
+ "label": "AWS access key id",
620
+ "hidden": "!data.voiceEnabled || (data.sttProvider !== 'aws' && data.ttsProvider !== 'aws') || data.voiceCredentialType === 'manager'",
621
+ "sm": 12,
622
+ "md": 4
623
+ },
624
+ "awsSecretAccessKey": {
625
+ "type": "password",
626
+ "label": "AWS secret access key",
627
+ "hidden": "!data.voiceEnabled || (data.sttProvider !== 'aws' && data.ttsProvider !== 'aws') || data.voiceCredentialType === 'manager'",
628
+ "sm": 12,
629
+ "md": 4
630
+ },
631
+ "awsRegion": {
632
+ "type": "text",
633
+ "label": "AWS region",
634
+ "help": "e.g. eu-central-1",
635
+ "hidden": "!data.voiceEnabled || (data.sttProvider !== 'aws' && data.ttsProvider !== 'aws') || data.voiceCredentialType === 'manager'",
636
+ "sm": 6,
637
+ "md": 3
638
+ },
639
+ "awsCredentialId": {
640
+ "newLine": true,
641
+ "type": "credential",
642
+ "credentialType": "aws",
643
+ "label": "AWS credential",
644
+ "hidden": "!data.voiceEnabled || (data.sttProvider !== 'aws' && data.ttsProvider !== 'aws') || data.voiceCredentialType !== 'manager'",
645
+ "sm": 12,
646
+ "md": 6
647
+ },
648
+ "awsVoice": {
649
+ "newLine": true,
650
+ "type": "autocompleteSendTo",
651
+ "command": "getVoices",
652
+ "jsonData": "{\"ttsProvider\":\"${data.ttsProvider}\",\"language\":\"${data.voiceLanguage}\",\"voiceCredentialType\":\"${data.voiceCredentialType}\",\"awsAccessKeyId\":\"${data.awsAccessKeyId}\",\"awsSecretAccessKey\":\"${data.awsSecretAccessKey}\",\"awsRegion\":\"${data.awsRegion}\",\"awsCredentialId\":\"${data.awsCredentialId}\"}",
653
+ "alsoDependsOn": [
654
+ "ttsProvider",
655
+ "voiceLanguage",
656
+ "voiceCredentialType",
657
+ "awsAccessKeyId",
658
+ "awsSecretAccessKey",
659
+ "awsRegion",
660
+ "awsCredentialId"
661
+ ],
662
+ "freeSolo": true,
663
+ "label": "AWS Polly voice (optional)",
664
+ "help": "Loaded from Polly (instance must run); empty = default per language. e.g. Vicki, Tatyana.",
665
+ "hidden": "!data.voiceEnabled || data.ttsProvider !== 'aws'",
666
+ "sm": 6,
667
+ "md": 5
668
+ },
669
+ "_localSpeechHeader": {
670
+ "newLine": true,
671
+ "type": "header",
672
+ "size": 3,
673
+ "text": "Local speech (no cloud)",
674
+ "hidden": "!data.voiceEnabled || (data.sttProvider !== 'vosk' && data.ttsProvider !== 'piper')"
675
+ },
676
+ "_localSpeechHint": {
677
+ "newLine": true,
678
+ "type": "staticText",
679
+ "text": "Vosk (STT) and Piper (TTS) run on this host. Models and the Piper binary are downloaded automatically on first use (needs internet, plus 'unzip'/'tar'). No API key required.",
680
+ "hidden": "!data.voiceEnabled || (data.sttProvider !== 'vosk' && data.ttsProvider !== 'piper')",
681
+ "sm": 12,
682
+ "md": 12
683
+ },
684
+ "voskModel": {
685
+ "newLine": true,
686
+ "type": "autocompleteSendTo",
687
+ "command": "getSttModels",
688
+ "jsonData": "{\"sttProvider\":\"${data.sttProvider}\",\"language\":\"${data.voiceLanguage}\"}",
689
+ "alsoDependsOn": ["sttProvider", "voiceLanguage"],
690
+ "freeSolo": true,
691
+ "label": "Vosk model (optional)",
692
+ "help": "Model name from alphacephei.com/vosk/models, e.g. vosk-model-small-de-0.15. Empty = small default per language.",
693
+ "hidden": "!data.voiceEnabled || data.sttProvider !== 'vosk'",
694
+ "sm": 12,
695
+ "md": 6
696
+ },
697
+ "piperVoice": {
698
+ "newLine": true,
699
+ "type": "autocompleteSendTo",
700
+ "command": "getVoices",
701
+ "jsonData": "{\"ttsProvider\":\"${data.ttsProvider}\",\"language\":\"${data.voiceLanguage}\"}",
702
+ "alsoDependsOn": ["ttsProvider", "voiceLanguage"],
703
+ "freeSolo": true,
704
+ "label": "Piper voice (optional)",
705
+ "help": "e.g. de_DE-thorsten-medium, ru_RU-irina-medium. Empty = default per language.",
706
+ "hidden": "!data.voiceEnabled || data.ttsProvider !== 'piper'",
707
+ "sm": 6,
708
+ "md": 5
709
+ }
710
+ }
711
+ },
712
+ "_chat": {
713
+ "type": "panel",
714
+ "label": "Chat",
715
+ "items": {
716
+ "_chatComponent": {
717
+ "type": "custom",
718
+ "i18n": true,
719
+ "url": "custom/customComponents.js",
720
+ "name": "ConfigCustomAssistant/Components/ChatComponent",
721
+ "guiApi": 2,
722
+ "bundlerType": "module",
723
+ "sm": 12
724
+ }
725
+ }
726
+ },
727
+ "_satellites": {
728
+ "type": "panel",
729
+ "label": "Satellites",
730
+ "items": {
731
+ "_satellitesComponent": {
732
+ "type": "custom",
733
+ "i18n": true,
734
+ "url": "custom/customComponents.js",
735
+ "name": "ConfigCustomAssistant/Components/SatellitesComponent",
736
+ "guiApi": 2,
737
+ "bundlerType": "module",
738
+ "sm": 12
739
+ }
740
+ }
741
+ }
742
+ }
743
+ }