iobroker.javascript 9.1.0 → 9.2.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 (83) hide show
  1. package/README.md +16 -8
  2. package/admin/assets/AiChatPanel-sgt697A2.js +296 -0
  3. package/admin/assets/AiDatapointProvider-B0i3I5Fm.js +2 -0
  4. package/admin/assets/AiDiffView-RPozjjHf.js +1 -0
  5. package/admin/assets/AiInlineProvider-Dd7eKxk4.js +7 -0
  6. package/admin/assets/{Save-Cld9qv9i.js → Save-CkuNSiWL.js} +1 -1
  7. package/admin/assets/{ScriptEditor-BVaX7Hcs.js → ScriptEditor-CH4qJzqq.js} +2 -2
  8. package/admin/assets/ScriptEditorVanillaMonaco-cB_90T0P.js +1 -0
  9. package/admin/assets/{createSvgIcon-DPvF8xqu.js → createSvgIcon-DYs_tNrE.js} +1 -1
  10. package/admin/assets/docs-compact-CKNGiYh2.js +336 -0
  11. package/admin/assets/index-BI3JsAz_.js +1 -0
  12. package/admin/assets/{index-D8iYqogF.js → index-DAkyON1r.js} +5 -5
  13. package/admin/assets/index-DW5CwIma.js +1256 -0
  14. package/admin/assets/index-SHs7_wDh.js +1 -0
  15. package/admin/assets/{index-DlDUIfpA.js → index-dN73sbyQ.js} +1 -1
  16. package/admin/assets/index-hwplVCgv.js +986 -0
  17. package/admin/assets/index-wHNMOf-c.js +5 -0
  18. package/admin/assets/inheritsLoose-CIXm_zPk.js +29 -0
  19. package/admin/assets/{iobroker_javascript__loadShare___mf_0_mui_mf_1_material__loadShare__.mjs-QWG5Arqe.js → iobroker_javascript__loadShare___mf_0_mui_mf_1_material__loadShare__.mjs-CV1_X-Lf.js} +1 -1
  20. package/admin/assets/{localSharedImportMap-AxgBkrOR.js → localSharedImportMap-CqvxvyGG.js} +1 -1
  21. package/admin/assets/useTheme-DuTJsNQ-.js +1 -0
  22. package/admin/assets/{virtual_mf-REMOTE_ENTRY_ID_iobroker_javascript__remoteEntry_js-C9suQF96.js → virtual_mf-REMOTE_ENTRY_ID_iobroker_javascript__remoteEntry_js-BJ03G6Pu.js} +2 -2
  23. package/admin/custom/assets/{Components-FfVbavBM.js → Components-B9ZyjeRI.js} +1 -1
  24. package/admin/custom/assets/{index-Be7j5wvd.js → index-BVwMgafs.js} +1 -1
  25. package/admin/custom/assets/index-CVIpIckw.js +960 -0
  26. package/admin/custom/assets/{index-DNdWk-cT.js → index-DsIn9jH_.js} +1 -1
  27. package/admin/custom/assets/{localSharedImportMap-BRxFonIn.js → localSharedImportMap-C4qXtGUd.js} +1 -1
  28. package/admin/custom/assets/{virtualExposes-DyedJotb.js → virtualExposes-jSvr-kK3.js} +1 -1
  29. package/admin/custom/assets/{virtual_mf-REMOTE_ENTRY_ID_ConfigCustomJavascriptSet__customComponents_js-BtJxKB87.js → virtual_mf-REMOTE_ENTRY_ID_ConfigCustomJavascriptSet__customComponents_js-DFSXB0v2.js} +2 -2
  30. package/admin/custom/customComponents.js +1 -1
  31. package/admin/google-blockly/own/blocks_words.js +7 -0
  32. package/admin/google-blockly/own/field_oid.js +311 -37
  33. package/admin/i18n/de.json +8 -0
  34. package/admin/i18n/en.json +8 -0
  35. package/admin/i18n/es.json +8 -0
  36. package/admin/i18n/flat.txt +427 -0
  37. package/admin/i18n/fr.json +8 -0
  38. package/admin/i18n/it.json +8 -0
  39. package/admin/i18n/nl.json +8 -0
  40. package/admin/i18n/pl.json +8 -0
  41. package/admin/i18n/pt.json +8 -0
  42. package/admin/i18n/ru.json +8 -0
  43. package/admin/i18n/uk.json +8 -0
  44. package/admin/i18n/zh-cn.json +8 -0
  45. package/admin/img/anthropic.svg +1 -0
  46. package/admin/img/custom.svg +1 -0
  47. package/admin/img/deepseek.svg +1 -0
  48. package/admin/img/gemini.svg +1 -0
  49. package/admin/img/openai.svg +1 -0
  50. package/admin/jsonConfig.json +76 -14
  51. package/admin/mf-manifest.json +1 -1
  52. package/admin/remoteEntry.js +1 -1
  53. package/admin/tab.html +6 -6
  54. package/build/lib/debugger.js +2 -2
  55. package/build/lib/debugger.js.map +1 -1
  56. package/build/lib/inspect.js.map +1 -1
  57. package/build/lib/nodeModulesManagement.js +2 -2
  58. package/build/lib/nodeModulesManagement.js.map +1 -1
  59. package/build/lib/protectFs.js +5 -0
  60. package/build/lib/protectFs.js.map +1 -1
  61. package/build/lib/sandbox.js +2 -2
  62. package/build/lib/sandbox.js.map +1 -1
  63. package/build/main.js +72 -17
  64. package/build/main.js.map +1 -1
  65. package/build/types.d.ts +2 -0
  66. package/docs/de/README.md +21 -8
  67. package/docs/de/blockly.md +34 -0
  68. package/docs/en/README.md +21 -8
  69. package/docs/en/blockly.md +34 -0
  70. package/install/installTypings.js +1 -1
  71. package/io-package.json +27 -66
  72. package/package.json +7 -6
  73. package/admin/assets/OpenAiDialog-Dx-XNET0.js +0 -13
  74. package/admin/assets/ScriptEditorVanillaMonaco-yq11eIYC.js +0 -1
  75. package/admin/assets/docs-BrInh2Pn.js +0 -2036
  76. package/admin/assets/index-CLJ6-h9Q.js +0 -1
  77. package/admin/assets/index-COZhHfBn.js +0 -1230
  78. package/admin/assets/index-Cu-TydZj.js +0 -5
  79. package/admin/assets/index-Dnbw7_L3.js +0 -986
  80. package/admin/assets/index-gIA8x-8f.js +0 -1
  81. package/admin/assets/inheritsLoose-B0Ba5G9z.js +0 -29
  82. package/admin/assets/useTheme-hy6f3gra.js +0 -1
  83. package/admin/custom/assets/index-CYc31Gwg.js +0 -960
package/build/main.js CHANGED
@@ -225,6 +225,19 @@ const jsDeclarationServer = new virtual_tsc_1.Server(typescriptSettings_1.jsDecl
225
225
  * Stores the IDs of script objects whose change should be ignored because
226
226
  * the compiled source was just updated
227
227
  */
228
+ function httpStatusText(code) {
229
+ const texts = {
230
+ 400: 'Bad Request',
231
+ 401: 'Unauthorized',
232
+ 403: 'Forbidden',
233
+ 404: 'Not Found',
234
+ 429: 'Too Many Requests / Rate Limit',
235
+ 500: 'Internal Server Error',
236
+ 502: 'Bad Gateway',
237
+ 503: 'Service Unavailable',
238
+ };
239
+ return texts[code] || `Error ${code}`;
240
+ }
228
241
  class JavaScript extends adapter_core_1.Adapter {
229
242
  context;
230
243
  errorLogFunction = {
@@ -565,9 +578,9 @@ class JavaScript extends adapter_core_1.Adapter {
565
578
  await this.loadScriptById(id);
566
579
  }
567
580
  }
568
- else {
569
- // if (obj.common.source !== formerObj.common.source) {
570
- // Source changed => restart the script
581
+ else if (obj.common.engine === `system.adapter.${this.namespace}` ||
582
+ formerObj.common.engine === `system.adapter.${this.namespace}`) {
583
+ // Source changed => restart the script (only on the relevant instance)
571
584
  this.stopCounters[id] = this.stopCounters[id] ? this.stopCounters[id] + 1 : 1;
572
585
  void this.stopScript(id).then(() => {
573
586
  // only start again after stop when "last" object change to prevent problems on
@@ -911,6 +924,7 @@ class JavaScript extends adapter_core_1.Adapter {
911
924
  const apiKey = (obj.message?.apiKey || '').trim();
912
925
  const chatModel = (obj.message?.model || '').trim();
913
926
  const messages = obj.message?.messages;
927
+ const tools = obj.message?.tools;
914
928
  const provider = (obj.message?.provider || 'openai').trim();
915
929
  // Anthropic, Gemini, and DeepSeek always require an API key; OpenAI-compatible allows empty key with custom base URL
916
930
  if (!apiKey &&
@@ -947,19 +961,26 @@ class JavaScript extends adapter_core_1.Adapter {
947
961
  if (apiKey) {
948
962
  chatHeaders.Authorization = `Bearer ${apiKey}`;
949
963
  }
950
- bodyObj = { model: chatModel, messages, stream: false };
964
+ bodyObj = { model: chatModel, messages, stream: false, ...(tools?.length ? { tools } : {}) };
951
965
  }
952
966
  else if (provider === 'deepseek') {
953
967
  url = 'https://api.deepseek.com/chat/completions';
954
968
  chatHeaders.Authorization = `Bearer ${apiKey}`;
955
- bodyObj = { model: chatModel, messages, stream: false };
969
+ bodyObj = { model: chatModel, messages, stream: false, ...(tools?.length ? { tools } : {}) };
956
970
  }
957
971
  else {
958
972
  url = `${baseUrl || 'https://api.openai.com/v1'}/chat/completions`;
959
973
  if (apiKey) {
960
974
  chatHeaders.Authorization = `Bearer ${apiKey}`;
961
975
  }
962
- bodyObj = { model: chatModel, messages, stream: false };
976
+ bodyObj = {
977
+ model: chatModel,
978
+ messages,
979
+ stream: false,
980
+ ...(tools?.length ? { tools } : {}),
981
+ // Disable thinking/reasoning for local models to save context and speed
982
+ ...(baseUrl ? { reasoning_effort: 'none' } : {}),
983
+ };
963
984
  }
964
985
  const body = JSON.stringify(bodyObj);
965
986
  const bodyBuffer = Buffer.from(body, 'utf8');
@@ -988,14 +1009,16 @@ class JavaScript extends adapter_core_1.Adapter {
988
1009
  if (res.statusCode === 200) {
989
1010
  try {
990
1011
  const parsed = JSON.parse(data);
1012
+ const message = provider === 'anthropic' ? null : parsed.choices?.[0]?.message;
991
1013
  const content = provider === 'anthropic'
992
1014
  ? parsed.content?.[0]?.text || ''
993
- : parsed.choices?.[0]?.message?.content || '';
994
- if (!content) {
1015
+ : message?.content || '';
1016
+ const tool_calls = message?.tool_calls;
1017
+ if (!content && !tool_calls?.length) {
995
1018
  this.sendTo(obj.from, obj.command, { error: 'Empty response from API' }, obj.callback);
996
1019
  }
997
1020
  else {
998
- this.sendTo(obj.from, obj.command, { success: true, content }, obj.callback);
1021
+ this.sendTo(obj.from, obj.command, { success: true, content, ...(tool_calls ? { tool_calls } : {}) }, obj.callback);
999
1022
  }
1000
1023
  }
1001
1024
  catch {
@@ -1003,17 +1026,17 @@ class JavaScript extends adapter_core_1.Adapter {
1003
1026
  }
1004
1027
  }
1005
1028
  else {
1006
- let errorMsg = `API returned status ${res.statusCode}`;
1029
+ let detail = '';
1007
1030
  try {
1008
- const parsed = JSON.parse(data);
1009
- if (parsed.error?.message) {
1010
- errorMsg = parsed.error.message;
1011
- }
1031
+ const errParsed = JSON.parse(data);
1032
+ detail = errParsed.error?.message || data.substring(0, 200);
1012
1033
  }
1013
1034
  catch {
1014
- // ignore parse error
1035
+ detail = data.substring(0, 200);
1015
1036
  }
1016
- this.sendTo(obj.from, obj.command, { error: errorMsg }, obj.callback);
1037
+ this.sendTo(obj.from, obj.command, {
1038
+ error: `${detail || httpStatusText(res.statusCode || 0)} (${res.statusCode})`,
1039
+ }, obj.callback);
1017
1040
  }
1018
1041
  });
1019
1042
  });
@@ -1106,7 +1129,18 @@ class JavaScript extends adapter_core_1.Adapter {
1106
1129
  this.sendTo(obj.from, obj.command, { error: 'Access denied (403)' }, obj.callback);
1107
1130
  }
1108
1131
  else {
1109
- this.sendTo(obj.from, obj.command, { error: `API returned status ${res.statusCode}` }, obj.callback);
1132
+ // Include response body for debugging
1133
+ let detail = '';
1134
+ try {
1135
+ const errParsed = JSON.parse(data);
1136
+ detail = errParsed.error?.message || data.substring(0, 200);
1137
+ }
1138
+ catch {
1139
+ detail = data.substring(0, 200);
1140
+ }
1141
+ this.sendTo(obj.from, obj.command, {
1142
+ error: `${detail || httpStatusText(res.statusCode || 0)} (${res.statusCode})`,
1143
+ }, obj.callback);
1110
1144
  }
1111
1145
  });
1112
1146
  });
@@ -1281,6 +1315,10 @@ class JavaScript extends adapter_core_1.Adapter {
1281
1315
  this.context.allowSelfSignedCerts = this.config.allowSelfSignedCerts;
1282
1316
  const doc = await this.getObjectViewAsync('script', 'javascript', {});
1283
1317
  if (doc?.rows?.length) {
1318
+ // sort global scripts if configured
1319
+ if (this.config.sortGlobalScriptsAlphabetically) {
1320
+ doc.rows.sort((a, b) => a.value._id.localeCompare(b.value._id));
1321
+ }
1284
1322
  // assemble global script
1285
1323
  for (let g = 0; g < doc.rows.length; g++) {
1286
1324
  const obj = doc.rows[g].value;
@@ -2145,6 +2183,9 @@ class JavaScript extends adapter_core_1.Adapter {
2145
2183
  }
2146
2184
  }
2147
2185
  async stopScript(name) {
2186
+ if (!this.scripts[name]) {
2187
+ return false;
2188
+ }
2148
2189
  this.log.info(`${name}: Stopping script`);
2149
2190
  await this.setState(`scriptEnabled.${name.substring(SCRIPT_CODE_MARKER.length)}`, false, true);
2150
2191
  if (this.messageBusHandlers[name]) {
@@ -2228,6 +2269,20 @@ class JavaScript extends adapter_core_1.Adapter {
2228
2269
  for (let i = 0; i < this.scripts[name].intervals.length; i++) {
2229
2270
  clearInterval(this.scripts[name].intervals[i]);
2230
2271
  }
2272
+ // Stop all delayed states (setStateDelayed timers)
2273
+ for (const stateId of Object.keys(this.timers)) {
2274
+ if (this.timers[stateId]) {
2275
+ for (let i = this.timers[stateId].length - 1; i >= 0; i--) {
2276
+ if (this.timers[stateId][i].scriptName === name) {
2277
+ clearTimeout(this.timers[stateId][i].t);
2278
+ this.timers[stateId].splice(i, 1);
2279
+ }
2280
+ }
2281
+ if (!this.timers[stateId].length) {
2282
+ delete this.timers[stateId];
2283
+ }
2284
+ }
2285
+ }
2231
2286
  // Stop all scheduled jobs
2232
2287
  for (let i = 0; i < this.scripts[name].schedules.length; i++) {
2233
2288
  if (this.scripts[name].schedules[i]) {