node-red-contrib-knx-ultimate 6.3.26 → 6.3.28

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/CHANGELOG.md CHANGED
@@ -6,6 +6,18 @@
6
6
 
7
7
  # CHANGELOG
8
8
 
9
+ **Version 6.3.28** - August 2026<br/>
10
+
11
+ - **KNX AI — patient provider-neutral model requests**: every LLM chat request now receives the same 30-minute minimum deadline, regardless of provider, model or model manager, while longer legacy configured values remain honored. The model transport carries that deadline through both streaming and non-streaming responses instead of inheriting a shorter HTTP-library header timeout; fast responses are returned immediately, model-response timeouts remain distinct from unreachable-server errors, and Telegram audio operations retain their separate two-minute safeguard.<br/>
12
+ - **KNX AI — provider-neutral reasoning control and responsive chat**: added a localized **Reasoning effort** selector with provider/model default, `none`, `minimal`, `low`, `medium`, `high`, `xhigh` and `max` choices. The default sends no preference; explicit supported values are mapped by request protocol to Chat Completions `reasoning_effort`, Anthropic `output_config.effort` or Ollama `think`, without model-name allowlists, and a rejected preference is removed while preserving the rest of the request. OpenAI-compatible and Ollama chats now stream responses for every configured endpoint, keep reasoning traces separate from the structured user reply and retry without streaming when an endpoint rejects it. Abort and HTTP transport timeouts are reported as model-response timeouts instead of as false connection failures; genuine unreachable-server errors retain their provider-specific setup guidance. Context-error compaction remains in force. Editor help and wiki documentation were aligned in EN, IT, DE, FR, ES and zh-CN.<br/>
13
+ - **KNX AI — optional model-sized local context**: added a localized **No KNX AI limit** choice to the local-model chat-context selector. The existing 4K, 8K and 16K budgets are unchanged and 16K remains the backward-compatible default; when the new choice is explicit, KNX AI uses the active/reported Ollama or Bionic LM Studio context window instead of imposing its own token cap, while the model's physical limit and the existing context-error fallback remain authoritative.<br/>
14
+ - **KNX AI editor — quieter Setup Doctor placement**: moved Setup Doctor to the bottom of the **Chat and home** page, below the available-chat-context overview, and made it an accessible collapsed-by-default section so routine configuration stays compact while every diagnostic and refresh action remains available on demand.<br/>
15
+ - **KNX AI — semantic persistent chat scheduling and fixed AI Education**: added model-selected `scheduleActions` for creating, listing and cancelling one-time or recurring reminders, monitors and future home commands from normal human-language chat, without keywords, trigger phrases or rigid intent classifiers. Each node persists authoritative schedule state in JSON and a generated readable Markdown view across restarts; due tasks reuse both the model's execution instruction and the exact original user request while retaining Web budgets, detected-camera limits, explicit TTS Ultimate wiring, ETS/DPT validation and configured KNX confirmation. Empty structured replies from smaller local models receive one general semantic recovery pass instead of surfacing the old “No response text” placeholder. Scheduled camera results are delivered back to sidebar chat, and cancelling a plan also invalidates any pending camera work or KNX confirmation belonging to it. `reset` clears all schedules for the node, while `clear_chat` cancels only the current session's schedules. AI Education remains a fixed, user-edited node property stored in the Node-RED flow: the model reads it as authoritative guidance but never writes it; learned chat memory stores facts and preferences requested in chat, while scheduler storage holds plans and reminders. The previously introduced legacy `knxai-education-<node-id>.md` file is no longer read or written; existing copies are left untouched and ignored. Localized editor strings, help and wiki pages were aligned in EN, IT, DE, FR, ES and zh-CN.<br/>
16
+
17
+ **Version 6.3.27** - August 2026<br/>
18
+
19
+ - KNX AI: enabled some things by default.
20
+
9
21
  **Version 6.3.26** - August 2026<br/>
10
22
 
11
23
  - **KNX AI — opt-in Web Intelligence with verified sources**: added a provider-independent general Web tool that the conversational model selects semantically from the current request, without topic-specific logic, keywords or intent classifiers. Web access is off by default; proactive Web checks require a separate opt-in, explicit user-authored AI Education, a destination learned from at least one normal chat request and a configurable 5, 10, 15, 30, 60 or 180-minute minimum interval. Setup Doctor reports Web/proactive readiness, missing Education or recipient and the live hourly budget. Interactive and proactive requests share a rolling hourly call budget, with at most three Web operations in total per user turn or proactive cycle. Web-backed answers carry runtime-validated numbered citations (`[S1]`, …) with sanitized URLs and available publication/retrieval times; external content remains untrusted data and cannot override assistant rules or permissions. Only bounded public HTTPS resources are accepted, with private/local/link-local/cloud-metadata targets, unsafe redirects, authenticated browsing and cookies blocked. Queries and the server's public IP are disclosed to external sites or the search service, while KNX/ETS data, camera content, chat identifiers, learned memory and credentials are never added automatically. Once verified Web results are available, the model can compose other enabled tools when authorized by the current chat or AI Education; existing tool availability, KNX permissions, ETS/DPT validation and configured write confirmation remain unchanged. Editor help and wiki documentation were aligned in EN, IT, DE, FR, ES and zh-CN.<br/>
@@ -144,7 +144,7 @@
144
144
  "llmSystemPrompt": "You are a KNX building automation assistant. Analyze KNX bus traffic and provide actionable insights.",
145
145
  "llmTemperature": "0.2",
146
146
  "llmMaxTokens": "600",
147
- "llmTimeoutMs": "30000",
147
+ "llmTimeoutMs": "1800000",
148
148
  "llmMaxEventsInPrompt": "600",
149
149
  "llmIncludeRaw": false,
150
150
  "x": 560,
@@ -187,7 +187,6 @@
187
187
  margin: 18px 0 0;
188
188
  }
189
189
 
190
- #knx-ai-setup-doctor-panel>h4,
191
190
  #knx-ai-detected-adapters-panel>h4,
192
191
  #knx-ai-chat-context-panel>h4,
193
192
  #knx-ai-chat-learning-link-panel>h4 {
@@ -197,11 +196,53 @@
197
196
  }
198
197
 
199
198
  #knx-ai-setup-doctor-panel {
200
- margin: 16px 0 18px;
199
+ margin: 24px 0 0;
201
200
  border-color: rgba(255, 152, 0, 0.55);
202
201
  background: linear-gradient(135deg, rgba(255, 152, 0, 0.10), var(--red-ui-secondary-background, #f7f7f7));
203
202
  }
204
203
 
204
+ .knx-ai-setup-doctor-toggle {
205
+ display: flex;
206
+ align-items: center;
207
+ justify-content: space-between;
208
+ gap: 12px;
209
+ margin: 0;
210
+ color: var(--red-ui-primary-text-color, #555);
211
+ font-size: 14px;
212
+ font-weight: 600;
213
+ cursor: pointer;
214
+ list-style: none;
215
+ user-select: none;
216
+ }
217
+
218
+ .knx-ai-setup-doctor-toggle::-webkit-details-marker {
219
+ display: none;
220
+ }
221
+
222
+ .knx-ai-setup-doctor-toggle>span>i {
223
+ width: 18px;
224
+ text-align: center;
225
+ }
226
+
227
+ .knx-ai-setup-doctor-toggle:focus-visible {
228
+ outline: 2px solid var(--red-ui-primary-color, #377e00);
229
+ outline-offset: 3px;
230
+ border-radius: 2px;
231
+ }
232
+
233
+ .knx-ai-setup-doctor-chevron {
234
+ flex: 0 0 auto;
235
+ transition: transform 0.16s ease;
236
+ }
237
+
238
+ #knx-ai-setup-doctor-panel[open] .knx-ai-setup-doctor-chevron {
239
+ transform: rotate(90deg);
240
+ }
241
+
242
+ .knx-ai-setup-doctor-body {
243
+ margin-top: 11px;
244
+ }
245
+
205
246
  #knx-ai-setup-doctor-panel.status-ready {
206
247
  border-color: rgba(46, 125, 50, 0.55);
207
248
  background: linear-gradient(135deg, rgba(46, 125, 50, 0.10), var(--red-ui-secondary-background, #f7f7f7));
@@ -437,14 +478,15 @@
437
478
  llmProvider: { value: "openai_compat" },
438
479
  llmBaseUrl: { value: "https://api.openai.com/v1/chat/completions" },
439
480
  llmModel: { value: "gpt-5.4" },
481
+ llmReasoningEffort: { value: "default" },
440
482
  llmContextLength: { value: 0 },
441
483
  llmPromptContextTokens: { value: 16384 },
442
484
  llmAllowKnxCommands: { value: false },
443
485
  llmRequireCommandConfirmation: { value: true },
444
- webAccessEnabled: { value: false },
445
- webProactiveEnabled: { value: false },
446
- webProactiveIntervalMinutes: { value: 30 },
447
- webMaxCallsPerHour: { value: 12 },
486
+ webAccessEnabled: { value: true },
487
+ webProactiveEnabled: { value: true },
488
+ webProactiveIntervalMinutes: { value: 5 },
489
+ webMaxCallsPerHour: { value: 40 },
448
490
  chatAdapterPreset: { value: "none" },
449
491
  chatInputCode: { value: "" },
450
492
  chatOutputCode: { value: "" },
@@ -813,12 +855,16 @@
813
855
  const contextLimit = overview.contextLimit && typeof overview.contextLimit === "object" ? overview.contextLimit : {};
814
856
  const currentProvider = String(contextLimit.provider || $("#node-input-llmProvider").val() || "").toLowerCase();
815
857
  let contextLimitTokens = Math.max(0, Number(contextLimit.tokens) || 0);
816
- if (!contextLimitTokens && (currentProvider === "lmstudio" || currentProvider === "ollama")) {
817
- contextLimitTokens = Math.min(
818
- Math.max(0, Number($("#node-input-llmContextLength").val()) || 16384),
819
- Math.max(0, Number($("#node-input-llmPromptContextTokens").val()) || 16384),
820
- 16384
821
- );
858
+ const contextIsProviderManaged = String(contextLimit.mode || "") === "provider-managed";
859
+ if (!contextLimitTokens && !contextIsProviderManaged && (currentProvider === "lmstudio" || currentProvider === "ollama")) {
860
+ const modelContextTokens = Math.max(0, Number($("#node-input-llmContextLength").val()) || 16384);
861
+ const selectedContextValue = String($("#node-input-llmPromptContextTokens").val() || "16384");
862
+ const selectedContextTokens = selectedContextValue === "0"
863
+ ? 0
864
+ : Math.min(16384, Math.max(4096, Number(selectedContextValue) || 16384));
865
+ contextLimitTokens = selectedContextTokens === 0
866
+ ? modelContextTokens
867
+ : Math.min(modelContextTokens, selectedContextTokens);
822
868
  }
823
869
  const contextLimitValue = contextLimitTokens
824
870
  ? formatCompactTokens(contextLimitTokens) + " " + t("knxUltimateAI.messages.chatContextTokens", "tokens")
@@ -852,7 +898,7 @@
852
898
  knxTraffic: t("knxUltimateAI.messages.chatContextSourceKnxTraffic", "Live KNX summary, anomalies, topology and selected telegrams."),
853
899
  adapterHistory: t("knxUltimateAI.messages.chatContextSourceAdapterHistory", "Persistent history of automatically detected adapter events."),
854
900
  etsProject: t("knxUltimateAI.messages.chatContextSourceEtsProject", "ETS semantics and the full Node-RED project inventory."),
855
- memoryEducation: t("knxUltimateAI.messages.chatContextSourceMemoryEducation", "Session context, AI Education and bounded home memory."),
901
+ memoryEducation: t("knxUltimateAI.messages.chatContextSourceMemoryEducation", "Session context, AI Education, bounded home memory and active plans."),
856
902
  cameras: t("knxUltimateAI.messages.chatContextSourceCameras", "Detected cameras and their available capabilities.")
857
903
  };
858
904
  (Array.isArray(overview.sources) ? overview.sources : []).forEach(function (sourceId) {
@@ -867,7 +913,9 @@
867
913
 
868
914
  const fileDescriptions = {
869
915
  chatContext: t("knxUltimateAI.messages.chatContextFileChatContext", "Persistent conversation turns, instructions and camera notification rules."),
870
- homeMemory: t("knxUltimateAI.messages.chatContextFileHomeMemory", "AI Education and bounded learned home memory."),
916
+ homeMemory: t("knxUltimateAI.messages.chatContextFileHomeMemory", "Bounded learned home memory only; AI Education remains in the node property."),
917
+ schedules: t("knxUltimateAI.messages.chatContextFileSchedules", "Authoritative structured plans and reminders for this node."),
918
+ schedulesReadable: t("knxUltimateAI.messages.chatContextFileSchedulesReadable", "Human-readable plans and reminders generated from the scheduler state."),
871
919
  assistantConfig: t("knxUltimateAI.messages.chatContextFileAssistantConfig", "Persistent web Assistant configuration and semantic areas for this node.")
872
920
  };
873
921
  (Array.isArray(overview.files) ? overview.files : []).forEach(function (item) {
@@ -1017,8 +1065,11 @@
1017
1065
  text += " · " + t("knxUltimateAI.messages.lmStudioContextCurrentlyLoaded", "currently loaded") + ": " + loadedTokens + " token";
1018
1066
  }
1019
1067
  if (provider === "lmstudio" || provider === "ollama") {
1020
- const selectedBudget = Math.max(4096, Number($("#node-input-llmPromptContextTokens").val()) || 16384);
1021
- text += " · " + t("knxUltimateAI.messages.localContextBudget", "KNX AI context budget") + ": " + (selectedBudget / 1024) + "K";
1068
+ const selectedContextValue = String($("#node-input-llmPromptContextTokens").val() || "16384");
1069
+ const selectedBudget = selectedContextValue === "0"
1070
+ ? t("knxUltimateAI.selectlists.promptContext.unlimited", "No KNX AI limit (model context)")
1071
+ : (Math.max(4096, Number(selectedContextValue) || 16384) / 1024) + "K";
1072
+ text += " · " + t("knxUltimateAI.messages.localContextBudget", "KNX AI context budget") + ": " + selectedBudget;
1022
1073
  }
1023
1074
  $status.text(text).css("color", color).show();
1024
1075
  };
@@ -1119,9 +1170,13 @@
1119
1170
  : Number(detail.maxContextLength);
1120
1171
  $("#node-input-llmContextLength").val(activeContextLength);
1121
1172
  if (provider === "ollama") {
1122
- detail.configuredContextLength = Math.min(Number(detail.maxContextLength), 16384);
1173
+ const selectedContextValue = String($("#node-input-llmPromptContextTokens").val() || "16384");
1174
+ const selectedContextTokens = selectedContextValue === "0"
1175
+ ? Number(detail.maxContextLength)
1176
+ : Math.min(16384, Math.max(4096, Number(selectedContextValue) || 16384));
1177
+ detail.configuredContextLength = Math.min(Number(detail.maxContextLength), selectedContextTokens);
1123
1178
  $("#node-input-llmContextLength").val(detail.configuredContextLength);
1124
- setLocalModelContextStatus(detail, "configured");
1179
+ setLocalModelContextStatus(detail);
1125
1180
  return;
1126
1181
  }
1127
1182
 
@@ -1142,7 +1197,7 @@
1142
1197
  type: "POST",
1143
1198
  contentType: "application/json",
1144
1199
  data: JSON.stringify(payload)
1145
- })
1200
+ })
1146
1201
  .done(function (data) {
1147
1202
  if (requestVersion !== localContextRequestVersion) return;
1148
1203
  const resolvedContextLength = Math.max(0, Number(data && data.contextLength) || 0);
@@ -1312,7 +1367,12 @@
1312
1367
  });
1313
1368
  $("#node-input-llmPromptContextTokens").on("change", function () {
1314
1369
  const detail = localModelDetailsById.get(String($("#node-input-llmModel").val() || "").trim());
1315
- if (detail) setLocalModelContextStatus(detail, detail.loadedContextLength > 0 ? "configured" : "inactive");
1370
+ if (!detail) return;
1371
+ if ($("#node-input-llmProvider").val() === "ollama") {
1372
+ configureSelectedLocalModel();
1373
+ return;
1374
+ }
1375
+ setLocalModelContextStatus(detail, detail.loadedContextLength > 0 ? "configured" : "inactive");
1316
1376
  });
1317
1377
  $("#knx-ai-downloadOllamaModel").on("click", function (evt) {
1318
1378
  evt.preventDefault();
@@ -1389,34 +1449,6 @@
1389
1449
  </div>
1390
1450
  </div>
1391
1451
 
1392
- <div id="knx-ai-setup-doctor-panel">
1393
- <h4><i class="fa fa-magic"></i> <span data-i18n="knxUltimateAI.sections.setupDoctor"></span></h4>
1394
- <div id="knx-ai-setup-doctor-status" data-i18n="knxUltimateAI.messages.setupDoctorLoading"></div>
1395
- <div id="knx-ai-setup-doctor-content" style="display:none;">
1396
- <div class="knx-ai-setup-doctor-hero">
1397
- <div class="knx-ai-setup-doctor-summary">
1398
- <strong id="knx-ai-setup-doctor-state"></strong>
1399
- <div id="knx-ai-setup-doctor-summary"></div>
1400
- </div>
1401
- <div id="knx-ai-setup-doctor-score" class="knx-ai-setup-doctor-score"></div>
1402
- </div>
1403
- <div id="knx-ai-setup-doctor-checks"></div>
1404
- <div class="knx-ai-setup-doctor-prompts">
1405
- <strong data-i18n="knxUltimateAI.messages.setupDoctorPromptsTitle"></strong>
1406
- <div class="knx-ai-setup-doctor-prompts-hint" data-i18n="knxUltimateAI.messages.setupDoctorPromptsHint"></div>
1407
- <div id="knx-ai-setup-doctor-prompt-list" class="knx-ai-setup-doctor-prompt-list"></div>
1408
- </div>
1409
- <div class="knx-ai-setup-doctor-footer">
1410
- <div class="knx-ai-setup-doctor-deploy-hint">
1411
- <i class="fa fa-info-circle"></i> <span data-i18n="knxUltimateAI.messages.setupDoctorDeployHint"></span>
1412
- </div>
1413
- <button type="button" class="red-ui-button" id="knx-ai-setup-doctor-refresh">
1414
- <i class="fa fa-refresh"></i> <span data-i18n="knxUltimateAI.buttons.refreshSetupDoctor"></span>
1415
- </button>
1416
- </div>
1417
- </div>
1418
- </div>
1419
-
1420
1452
  <div id="knx-ai-tabs">
1421
1453
  <ul>
1422
1454
  <li><a href="#knx-ai-tabs-assistant"><i class="fa fa-magic"></i> <span data-i18n="knxUltimateAI.sections.groupAssistant"></span></a></li>
@@ -1470,6 +1502,38 @@
1470
1502
  <div id="knx-ai-chat-context-pattern" class="knx-ai-chat-context-pattern"></div>
1471
1503
  </div>
1472
1504
  </div>
1505
+ <details id="knx-ai-setup-doctor-panel">
1506
+ <summary class="knx-ai-setup-doctor-toggle">
1507
+ <span><i class="fa fa-magic"></i> <span data-i18n="knxUltimateAI.sections.setupDoctor"></span></span>
1508
+ <i class="fa fa-chevron-right knx-ai-setup-doctor-chevron" aria-hidden="true"></i>
1509
+ </summary>
1510
+ <div class="knx-ai-setup-doctor-body">
1511
+ <div id="knx-ai-setup-doctor-status" data-i18n="knxUltimateAI.messages.setupDoctorLoading"></div>
1512
+ <div id="knx-ai-setup-doctor-content" style="display:none;">
1513
+ <div class="knx-ai-setup-doctor-hero">
1514
+ <div class="knx-ai-setup-doctor-summary">
1515
+ <strong id="knx-ai-setup-doctor-state"></strong>
1516
+ <div id="knx-ai-setup-doctor-summary"></div>
1517
+ </div>
1518
+ <div id="knx-ai-setup-doctor-score" class="knx-ai-setup-doctor-score"></div>
1519
+ </div>
1520
+ <div id="knx-ai-setup-doctor-checks"></div>
1521
+ <div class="knx-ai-setup-doctor-prompts">
1522
+ <strong data-i18n="knxUltimateAI.messages.setupDoctorPromptsTitle"></strong>
1523
+ <div class="knx-ai-setup-doctor-prompts-hint" data-i18n="knxUltimateAI.messages.setupDoctorPromptsHint"></div>
1524
+ <div id="knx-ai-setup-doctor-prompt-list" class="knx-ai-setup-doctor-prompt-list"></div>
1525
+ </div>
1526
+ <div class="knx-ai-setup-doctor-footer">
1527
+ <div class="knx-ai-setup-doctor-deploy-hint">
1528
+ <i class="fa fa-info-circle"></i> <span data-i18n="knxUltimateAI.messages.setupDoctorDeployHint"></span>
1529
+ </div>
1530
+ <button type="button" class="red-ui-button" id="knx-ai-setup-doctor-refresh">
1531
+ <i class="fa fa-refresh"></i> <span data-i18n="knxUltimateAI.buttons.refreshSetupDoctor"></span>
1532
+ </button>
1533
+ </div>
1534
+ </div>
1535
+ </div>
1536
+ </details>
1473
1537
  </div>
1474
1538
 
1475
1539
  </div>
@@ -1504,6 +1568,20 @@
1504
1568
  <i class="fa fa-refresh"></i> <span data-i18n="knxUltimateAI.buttons.refreshModels"></span>
1505
1569
  </button>
1506
1570
  </div>
1571
+ <div class="form-row">
1572
+ <label style="width:290px" for="node-input-llmReasoningEffort"><i class="fa fa-tachometer"></i> <span data-i18n="knxUltimateAI.properties.llmReasoningEffort"></span></label>
1573
+ <select style="width:100%" id="node-input-llmReasoningEffort">
1574
+ <option value="default" data-i18n="knxUltimateAI.selectlists.reasoningEffort.default"></option>
1575
+ <option value="none" data-i18n="knxUltimateAI.selectlists.reasoningEffort.none"></option>
1576
+ <option value="minimal" data-i18n="knxUltimateAI.selectlists.reasoningEffort.minimal"></option>
1577
+ <option value="low" data-i18n="knxUltimateAI.selectlists.reasoningEffort.low"></option>
1578
+ <option value="medium" data-i18n="knxUltimateAI.selectlists.reasoningEffort.medium"></option>
1579
+ <option value="high" data-i18n="knxUltimateAI.selectlists.reasoningEffort.high"></option>
1580
+ <option value="xhigh" data-i18n="knxUltimateAI.selectlists.reasoningEffort.xhigh"></option>
1581
+ <option value="max" data-i18n="knxUltimateAI.selectlists.reasoningEffort.max"></option>
1582
+ </select>
1583
+ <div class="knx-ai-prompt-context-hint" data-i18n="knxUltimateAI.messages.reasoningEffortHint"></div>
1584
+ </div>
1507
1585
  <input type="hidden" id="node-input-llmContextLength">
1508
1586
  <div id="knx-ai-local-context-status" style="display:none;"></div>
1509
1587
  <div class="form-row" id="knx-ai-prompt-context-row" style="display:none;">
@@ -1512,6 +1590,7 @@
1512
1590
  <option value="4096" data-i18n="knxUltimateAI.selectlists.promptContext.small"></option>
1513
1591
  <option value="8192" data-i18n="knxUltimateAI.selectlists.promptContext.medium"></option>
1514
1592
  <option value="16384" data-i18n="knxUltimateAI.selectlists.promptContext.full"></option>
1593
+ <option value="0" data-i18n="knxUltimateAI.selectlists.promptContext.unlimited"></option>
1515
1594
  </select>
1516
1595
  <div class="knx-ai-prompt-context-hint" data-i18n="knxUltimateAI.messages.promptContextHint"></div>
1517
1596
  </div>
@@ -1554,13 +1633,13 @@
1554
1633
  <div class="form-row">
1555
1634
  <input type="checkbox" id="node-input-webAccessEnabled" style="display:inline-block; width:auto; vertical-align:top;">
1556
1635
  <label style="width:auto" for="node-input-webAccessEnabled">&nbsp;&nbsp;<span data-i18n="knxUltimateAI.properties.webAccessEnabled"></span></label>
1557
- <div class="knx-ai-prompt-context-hint" data-i18n="knxUltimateAI.messages.webAccessHint"></div>
1636
+ <!-- <div class="knx-ai-prompt-context-hint" data-i18n="knxUltimateAI.messages.webAccessHint"></div> -->
1558
1637
  </div>
1559
1638
  <div id="knx-ai-web-access-settings">
1560
1639
  <div class="form-row">
1561
1640
  <label style="width:290px" for="node-input-webMaxCallsPerHour"><i class="fa fa-tachometer"></i> <span data-i18n="knxUltimateAI.properties.webMaxCallsPerHour"></span></label>
1562
1641
  <input type="number" id="node-input-webMaxCallsPerHour" min="1" max="60" step="1" style="width:100%;">
1563
- <div class="knx-ai-prompt-context-hint" data-i18n="knxUltimateAI.messages.webBudgetHint"></div>
1642
+ <!-- <div class="knx-ai-prompt-context-hint" data-i18n="knxUltimateAI.messages.webBudgetHint"></div> -->
1564
1643
  </div>
1565
1644
  <div class="form-row">
1566
1645
  <input type="checkbox" id="node-input-webProactiveEnabled" style="display:inline-block; width:auto; vertical-align:top;">