libre-webui 0.10.0 → 0.12.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 (298) hide show
  1. package/README.md +75 -61
  2. package/backend/dist/db.d.ts.map +1 -1
  3. package/backend/dist/db.js +21 -19
  4. package/backend/dist/db.js.map +1 -1
  5. package/backend/dist/index.d.ts.map +1 -1
  6. package/backend/dist/index.js +39 -908
  7. package/backend/dist/index.js.map +1 -1
  8. package/backend/dist/middleware/auth.d.ts.map +1 -1
  9. package/backend/dist/middleware/auth.js +4 -2
  10. package/backend/dist/middleware/auth.js.map +1 -1
  11. package/backend/dist/middleware/index.d.ts.map +1 -1
  12. package/backend/dist/middleware/index.js +4 -2
  13. package/backend/dist/middleware/index.js.map +1 -1
  14. package/backend/dist/models/personaModel.d.ts.map +1 -1
  15. package/backend/dist/models/personaModel.js +11 -9
  16. package/backend/dist/models/personaModel.js.map +1 -1
  17. package/backend/dist/routes/auth.d.ts.map +1 -1
  18. package/backend/dist/routes/auth.js +36 -14
  19. package/backend/dist/routes/auth.js.map +1 -1
  20. package/backend/dist/routes/chat.d.ts.map +1 -1
  21. package/backend/dist/routes/chat.js +61 -249
  22. package/backend/dist/routes/chat.js.map +1 -1
  23. package/backend/dist/routes/documents.d.ts.map +1 -1
  24. package/backend/dist/routes/documents.js +10 -8
  25. package/backend/dist/routes/documents.js.map +1 -1
  26. package/backend/dist/routes/imageGen.d.ts.map +1 -1
  27. package/backend/dist/routes/imageGen.js +9 -7
  28. package/backend/dist/routes/imageGen.js.map +1 -1
  29. package/backend/dist/routes/libreClaw.d.ts +3 -0
  30. package/backend/dist/routes/libreClaw.d.ts.map +1 -0
  31. package/backend/dist/routes/libreClaw.js +156 -0
  32. package/backend/dist/routes/libreClaw.js.map +1 -0
  33. package/backend/dist/routes/ollama.d.ts.map +1 -1
  34. package/backend/dist/routes/ollama.js +7 -247
  35. package/backend/dist/routes/ollama.js.map +1 -1
  36. package/backend/dist/routes/plugins.d.ts.map +1 -1
  37. package/backend/dist/routes/plugins.js +7 -105
  38. package/backend/dist/routes/plugins.js.map +1 -1
  39. package/backend/dist/routes/tts.d.ts.map +1 -1
  40. package/backend/dist/routes/tts.js +7 -5
  41. package/backend/dist/routes/tts.js.map +1 -1
  42. package/backend/dist/routes/users.d.ts.map +1 -1
  43. package/backend/dist/routes/users.js +7 -5
  44. package/backend/dist/routes/users.js.map +1 -1
  45. package/backend/dist/services/assistantCompletionService.d.ts +26 -0
  46. package/backend/dist/services/assistantCompletionService.d.ts.map +1 -0
  47. package/backend/dist/services/assistantCompletionService.js +53 -0
  48. package/backend/dist/services/assistantCompletionService.js.map +1 -0
  49. package/backend/dist/services/authService.d.ts +2 -0
  50. package/backend/dist/services/authService.d.ts.map +1 -1
  51. package/backend/dist/services/authService.js +9 -5
  52. package/backend/dist/services/authService.js.map +1 -1
  53. package/backend/dist/services/chatGenerationService.d.ts +32 -0
  54. package/backend/dist/services/chatGenerationService.d.ts.map +1 -0
  55. package/backend/dist/services/chatGenerationService.js +118 -0
  56. package/backend/dist/services/chatGenerationService.js.map +1 -0
  57. package/backend/dist/services/chatRequestService.d.ts +55 -0
  58. package/backend/dist/services/chatRequestService.d.ts.map +1 -0
  59. package/backend/dist/services/chatRequestService.js +103 -0
  60. package/backend/dist/services/chatRequestService.js.map +1 -0
  61. package/backend/dist/services/chatService.d.ts +0 -1
  62. package/backend/dist/services/chatService.d.ts.map +1 -1
  63. package/backend/dist/services/chatService.js +13 -27
  64. package/backend/dist/services/chatService.js.map +1 -1
  65. package/backend/dist/services/documentService.d.ts.map +1 -1
  66. package/backend/dist/services/documentService.js +21 -19
  67. package/backend/dist/services/documentService.js.map +1 -1
  68. package/backend/dist/services/embeddingService.d.ts.map +1 -1
  69. package/backend/dist/services/embeddingService.js +3 -1
  70. package/backend/dist/services/embeddingService.js.map +1 -1
  71. package/backend/dist/services/encryptionService.d.ts.map +1 -1
  72. package/backend/dist/services/encryptionService.js +26 -24
  73. package/backend/dist/services/encryptionService.js.map +1 -1
  74. package/backend/dist/services/galleryService.d.ts.map +1 -1
  75. package/backend/dist/services/galleryService.js +8 -6
  76. package/backend/dist/services/galleryService.js.map +1 -1
  77. package/backend/dist/services/libreClawService.d.ts +105 -0
  78. package/backend/dist/services/libreClawService.d.ts.map +1 -0
  79. package/backend/dist/services/libreClawService.js +169 -0
  80. package/backend/dist/services/libreClawService.js.map +1 -0
  81. package/backend/dist/services/memoryService.d.ts +2 -13
  82. package/backend/dist/services/memoryService.d.ts.map +1 -1
  83. package/backend/dist/services/memoryService.js +37 -198
  84. package/backend/dist/services/memoryService.js.map +1 -1
  85. package/backend/dist/services/memoryUtils.d.ts +29 -0
  86. package/backend/dist/services/memoryUtils.d.ts.map +1 -0
  87. package/backend/dist/services/memoryUtils.js +165 -0
  88. package/backend/dist/services/memoryUtils.js.map +1 -0
  89. package/backend/dist/services/mutationEngineService.d.ts.map +1 -1
  90. package/backend/dist/services/mutationEngineService.js +3 -1
  91. package/backend/dist/services/mutationEngineService.js.map +1 -1
  92. package/backend/dist/services/ollamaService.d.ts.map +1 -1
  93. package/backend/dist/services/ollamaService.js +36 -34
  94. package/backend/dist/services/ollamaService.js.map +1 -1
  95. package/backend/dist/services/personaService.d.ts.map +1 -1
  96. package/backend/dist/services/personaService.js +3 -1
  97. package/backend/dist/services/personaService.js.map +1 -1
  98. package/backend/dist/services/pluginCapabilityRegistryService.d.ts +11 -0
  99. package/backend/dist/services/pluginCapabilityRegistryService.d.ts.map +1 -0
  100. package/backend/dist/services/pluginCapabilityRegistryService.js +70 -0
  101. package/backend/dist/services/pluginCapabilityRegistryService.js.map +1 -0
  102. package/backend/dist/services/pluginCredentialsService.d.ts.map +1 -1
  103. package/backend/dist/services/pluginCredentialsService.js +13 -11
  104. package/backend/dist/services/pluginCredentialsService.js.map +1 -1
  105. package/backend/dist/services/pluginEmbeddingService.d.ts +26 -0
  106. package/backend/dist/services/pluginEmbeddingService.d.ts.map +1 -0
  107. package/backend/dist/services/pluginEmbeddingService.js +159 -0
  108. package/backend/dist/services/pluginEmbeddingService.js.map +1 -0
  109. package/backend/dist/services/pluginImageGenerationService.d.ts +29 -0
  110. package/backend/dist/services/pluginImageGenerationService.d.ts.map +1 -0
  111. package/backend/dist/services/pluginImageGenerationService.js +402 -0
  112. package/backend/dist/services/pluginImageGenerationService.js.map +1 -0
  113. package/backend/dist/services/pluginService.d.ts +9 -18
  114. package/backend/dist/services/pluginService.d.ts.map +1 -1
  115. package/backend/dist/services/pluginService.js +118 -1469
  116. package/backend/dist/services/pluginService.js.map +1 -1
  117. package/backend/dist/services/pluginTTSService.d.ts +28 -0
  118. package/backend/dist/services/pluginTTSService.d.ts.map +1 -0
  119. package/backend/dist/services/pluginTTSService.js +286 -0
  120. package/backend/dist/services/pluginTTSService.js.map +1 -0
  121. package/backend/dist/services/pluginVariablesService.d.ts.map +1 -1
  122. package/backend/dist/services/pluginVariablesService.js +7 -5
  123. package/backend/dist/services/pluginVariablesService.js.map +1 -1
  124. package/backend/dist/services/preferencesService.d.ts.map +1 -1
  125. package/backend/dist/services/preferencesService.js +9 -7
  126. package/backend/dist/services/preferencesService.js.map +1 -1
  127. package/backend/dist/services/simpleGitHubOAuth.d.ts.map +1 -1
  128. package/backend/dist/services/simpleGitHubOAuth.js +10 -8
  129. package/backend/dist/services/simpleGitHubOAuth.js.map +1 -1
  130. package/backend/dist/services/simpleHuggingFaceOAuth.d.ts.map +1 -1
  131. package/backend/dist/services/simpleHuggingFaceOAuth.js +11 -9
  132. package/backend/dist/services/simpleHuggingFaceOAuth.js.map +1 -1
  133. package/backend/dist/services/systemSettingsService.d.ts.map +1 -1
  134. package/backend/dist/services/systemSettingsService.js +4 -2
  135. package/backend/dist/services/systemSettingsService.js.map +1 -1
  136. package/backend/dist/services/titleGenerationService.d.ts +55 -0
  137. package/backend/dist/services/titleGenerationService.d.ts.map +1 -0
  138. package/backend/dist/services/titleGenerationService.js +121 -0
  139. package/backend/dist/services/titleGenerationService.js.map +1 -0
  140. package/backend/dist/services/turnstileService.d.ts +13 -0
  141. package/backend/dist/services/turnstileService.d.ts.map +1 -0
  142. package/backend/dist/services/turnstileService.js +79 -0
  143. package/backend/dist/services/turnstileService.js.map +1 -0
  144. package/backend/dist/storage.d.ts +2 -22
  145. package/backend/dist/storage.d.ts.map +1 -1
  146. package/backend/dist/storage.js +22 -170
  147. package/backend/dist/storage.js.map +1 -1
  148. package/backend/dist/storageMappers.d.ts +82 -0
  149. package/backend/dist/storageMappers.d.ts.map +1 -0
  150. package/backend/dist/storageMappers.js +85 -0
  151. package/backend/dist/storageMappers.js.map +1 -0
  152. package/backend/dist/test-encryption.js +20 -18
  153. package/backend/dist/test-encryption.js.map +1 -1
  154. package/backend/dist/types/index.d.ts.map +1 -1
  155. package/backend/dist/types/index.js.map +1 -1
  156. package/backend/dist/utils/assistantBranching.d.ts +8 -0
  157. package/backend/dist/utils/assistantBranching.d.ts.map +1 -0
  158. package/backend/dist/utils/assistantBranching.js +30 -0
  159. package/backend/dist/utils/assistantBranching.js.map +1 -0
  160. package/backend/dist/utils/chatContext.d.ts +17 -0
  161. package/backend/dist/utils/chatContext.d.ts.map +1 -0
  162. package/backend/dist/utils/chatContext.js +82 -0
  163. package/backend/dist/utils/chatContext.js.map +1 -0
  164. package/backend/dist/utils/chatDocumentContext.d.ts +7 -0
  165. package/backend/dist/utils/chatDocumentContext.d.ts.map +1 -0
  166. package/backend/dist/utils/chatDocumentContext.js +51 -0
  167. package/backend/dist/utils/chatDocumentContext.js.map +1 -0
  168. package/backend/dist/utils/logger.d.ts +12 -0
  169. package/backend/dist/utils/logger.d.ts.map +1 -0
  170. package/backend/dist/utils/logger.js +82 -0
  171. package/backend/dist/utils/logger.js.map +1 -0
  172. package/backend/dist/utils/ollamaLibrary.d.ts +17 -0
  173. package/backend/dist/utils/ollamaLibrary.d.ts.map +1 -0
  174. package/backend/dist/utils/ollamaLibrary.js +253 -0
  175. package/backend/dist/utils/ollamaLibrary.js.map +1 -0
  176. package/backend/dist/utils/ollamaStreaming.d.ts +19 -0
  177. package/backend/dist/utils/ollamaStreaming.d.ts.map +1 -0
  178. package/backend/dist/utils/ollamaStreaming.js +67 -0
  179. package/backend/dist/utils/ollamaStreaming.js.map +1 -0
  180. package/backend/dist/utils/pluginChatAdapter.d.ts +32 -0
  181. package/backend/dist/utils/pluginChatAdapter.d.ts.map +1 -0
  182. package/backend/dist/utils/pluginChatAdapter.js +308 -0
  183. package/backend/dist/utils/pluginChatAdapter.js.map +1 -0
  184. package/backend/dist/utils/pluginChatContext.d.ts +23 -0
  185. package/backend/dist/utils/pluginChatContext.d.ts.map +1 -0
  186. package/backend/dist/utils/pluginChatContext.js +77 -0
  187. package/backend/dist/utils/pluginChatContext.js.map +1 -0
  188. package/backend/dist/utils/pluginResponse.d.ts +6 -0
  189. package/backend/dist/utils/pluginResponse.d.ts.map +1 -0
  190. package/backend/dist/utils/pluginResponse.js +70 -0
  191. package/backend/dist/utils/pluginResponse.js.map +1 -0
  192. package/backend/dist/utils/pluginStreamAdapter.d.ts +16 -0
  193. package/backend/dist/utils/pluginStreamAdapter.d.ts.map +1 -0
  194. package/backend/dist/utils/pluginStreamAdapter.js +141 -0
  195. package/backend/dist/utils/pluginStreamAdapter.js.map +1 -0
  196. package/backend/dist/utils/pluginStreaming.d.ts +24 -0
  197. package/backend/dist/utils/pluginStreaming.d.ts.map +1 -0
  198. package/backend/dist/utils/pluginStreaming.js +106 -0
  199. package/backend/dist/utils/pluginStreaming.js.map +1 -0
  200. package/backend/dist/utils/pluginUpload.d.ts +8 -0
  201. package/backend/dist/utils/pluginUpload.d.ts.map +1 -0
  202. package/backend/dist/utils/pluginUpload.js +51 -0
  203. package/backend/dist/utils/pluginUpload.js.map +1 -0
  204. package/backend/dist/utils/pluginValidation.d.ts +9 -0
  205. package/backend/dist/utils/pluginValidation.d.ts.map +1 -0
  206. package/backend/dist/utils/pluginValidation.js +84 -0
  207. package/backend/dist/utils/pluginValidation.js.map +1 -0
  208. package/backend/dist/utils/pluginVariableValidation.d.ts +10 -0
  209. package/backend/dist/utils/pluginVariableValidation.d.ts.map +1 -0
  210. package/backend/dist/utils/pluginVariableValidation.js +80 -0
  211. package/backend/dist/utils/pluginVariableValidation.js.map +1 -0
  212. package/backend/dist/utils/websocketMessages.d.ts +26 -0
  213. package/backend/dist/utils/websocketMessages.d.ts.map +1 -0
  214. package/backend/dist/utils/websocketMessages.js +74 -0
  215. package/backend/dist/utils/websocketMessages.js.map +1 -0
  216. package/backend/dist/websocketServer.d.ts +3 -0
  217. package/backend/dist/websocketServer.d.ts.map +1 -0
  218. package/backend/dist/websocketServer.js +332 -0
  219. package/backend/dist/websocketServer.js.map +1 -0
  220. package/backend/package.json +2 -2
  221. package/frontend/dist/assets/index-Dc8Q4dJZ.css +1 -0
  222. package/frontend/dist/assets/index-ONn9VIq7.js +5 -0
  223. package/frontend/dist/assets/markdown-math-CYlHEDRF.css +1 -0
  224. package/frontend/dist/index.html +11 -10
  225. package/frontend/dist/js/ArtifactContainer-CqKsiKz0.js +1 -0
  226. package/frontend/dist/js/ArtifactDemoPage-Dd5BjIu2.js +200 -0
  227. package/frontend/dist/js/ArtifactSlideOutPanel-Yc7ttIaY.js +1 -0
  228. package/frontend/dist/js/Button-BUjLpHmR.js +1 -0
  229. package/frontend/dist/js/ChatPage-Cpy7lQ0D.js +16 -0
  230. package/frontend/dist/js/FirstTimeSetup-DcGhm0H0.js +1 -0
  231. package/frontend/dist/js/GalleryPage-DNI2Evvf.js +1 -0
  232. package/frontend/dist/js/LibreClawPage-CmTiROsJ.js +1 -0
  233. package/frontend/dist/js/ModelManagerModals-CfvSeNsT.js +1 -0
  234. package/frontend/dist/js/ModelsPage-CeTGqx4q.js +2 -0
  235. package/frontend/dist/js/OptimizedSyntaxHighlighter-CNjLqj1Z.js +1 -0
  236. package/frontend/dist/js/PersonasPage-BUqu7gJ3.js +13 -0
  237. package/frontend/dist/js/RichMessageContent-B0JO8vkR.js +3 -0
  238. package/frontend/dist/js/SettingsModal-B5aJ5vfV.js +1 -0
  239. package/frontend/dist/js/UserManagementPage-BqIIWX2M.js +1 -0
  240. package/frontend/dist/js/api-CbmZzKBu.js +15 -0
  241. package/frontend/dist/js/ar-BAOdgn6O.js +2 -0
  242. package/frontend/dist/js/artifactHtml-B7Oy2e__.js +27 -0
  243. package/frontend/dist/js/bn-Bp2KS5mx.js +2 -0
  244. package/frontend/dist/js/cs-DOgJ0c5p.js +2 -0
  245. package/frontend/dist/js/da-BCKTkC35.js +2 -0
  246. package/frontend/dist/js/de-BXyECph5.js +2 -0
  247. package/frontend/dist/js/demoMode-BhEpMVh5.js +1 -0
  248. package/frontend/dist/js/es-Db4bDYIF.js +2 -0
  249. package/frontend/dist/js/fr-BPIkf6zH.js +2 -0
  250. package/frontend/dist/js/hi-Bm8D_Aux.js +2 -0
  251. package/frontend/dist/js/id-DiWaH74_.js +2 -0
  252. package/frontend/dist/js/is-DLgJywtZ.js +2 -0
  253. package/frontend/dist/js/it-lldrM8pE.js +2 -0
  254. package/frontend/dist/js/ja-Cfe9uZmQ.js +2 -0
  255. package/frontend/dist/js/ko-BhChO3MQ.js +2 -0
  256. package/frontend/dist/js/logger-BmpKNkls.js +1 -0
  257. package/frontend/dist/js/markdown-core-fkbHPd-g.js +16 -0
  258. package/frontend/dist/js/markdown-math-Ci4QOsf-.js +261 -0
  259. package/frontend/dist/js/ms-SWtmetXo.js +2 -0
  260. package/frontend/dist/js/nl-CUO6I3nO.js +2 -0
  261. package/frontend/dist/js/pl-BUAu96P6.js +2 -0
  262. package/frontend/dist/js/pt-DCHwoWiE.js +2 -0
  263. package/frontend/dist/js/{react-vendor-Dh6nfvM2.js → react-vendor-Co1u1rWb.js} +2 -2
  264. package/frontend/dist/js/ru-Ciz053N7.js +2 -0
  265. package/frontend/dist/js/sv-D38ZHjv-.js +2 -0
  266. package/frontend/dist/js/syntax-highlight-D5wpTVgr.js +8 -0
  267. package/frontend/dist/js/th-D2cAucvn.js +2 -0
  268. package/frontend/dist/js/tr-Go355oDu.js +2 -0
  269. package/frontend/dist/js/ui-vendor-BJAeWL11.js +177 -0
  270. package/frontend/dist/js/uk-cdzjhgya.js +2 -0
  271. package/frontend/dist/js/useBaseQuery-6OJiOiyu.js +1 -0
  272. package/frontend/dist/js/useQuery-DfkI6VAv.js +1 -0
  273. package/frontend/dist/js/utils-BaPYjs_z.js +1 -0
  274. package/frontend/dist/js/utils-vendor-BX3ZwoIK.js +9 -0
  275. package/frontend/dist/js/vi-BSOpE423.js +2 -0
  276. package/frontend/dist/js/zh-BFh6sHZG.js +2 -0
  277. package/package.json +12 -8
  278. package/backend/dist/services/openclawSessionService.d.ts +0 -63
  279. package/backend/dist/services/openclawSessionService.d.ts.map +0 -1
  280. package/backend/dist/services/openclawSessionService.js +0 -307
  281. package/backend/dist/services/openclawSessionService.js.map +0 -1
  282. package/frontend/dist/assets/index-cOuIFv6G.js +0 -314
  283. package/frontend/dist/assets/index-tuVjvNle.css +0 -1
  284. package/frontend/dist/js/ArtifactContainer-DXa2t8GS.js +0 -24
  285. package/frontend/dist/js/ArtifactDemoPage-Dms7P2gI.js +0 -98
  286. package/frontend/dist/js/ChatPage-C6hOVIAS.js +0 -15
  287. package/frontend/dist/js/GalleryPage-CGKPECJV.js +0 -1
  288. package/frontend/dist/js/ModelsPage-CNB-c-JM.js +0 -1
  289. package/frontend/dist/js/PersonasPage-hDiS0Rvl.js +0 -13
  290. package/frontend/dist/js/UserManagementPage-1H9kcHeR.js +0 -1
  291. package/frontend/dist/js/api-MQ7bONaU.js +0 -3
  292. package/frontend/dist/js/appStore-BpzQfKOd.js +0 -2
  293. package/frontend/dist/js/authStore-Cn_WS6Kb.js +0 -2
  294. package/frontend/dist/js/demoMode-PKHbba1m.js +0 -1
  295. package/frontend/dist/js/markdown-vendor-DLzJCMRQ.js +0 -22
  296. package/frontend/dist/js/ui-vendor-ClcVY3m-.js +0 -177
  297. package/frontend/dist/js/utils-vendor-BCQRX-0Q.js +0 -9
  298. package/plugins/openclaw-agent.json +0 -69
@@ -0,0 +1,141 @@
1
+ /*
2
+ * Libre WebUI
3
+ * Copyright (C) 2025 Kroonen AI, Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at:
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ function getChoiceDelta(payload) {
18
+ if (!payload || typeof payload !== 'object') {
19
+ return null;
20
+ }
21
+ const choices = payload.choices;
22
+ if (!Array.isArray(choices)) {
23
+ return null;
24
+ }
25
+ const firstChoice = choices[0];
26
+ if (!firstChoice || typeof firstChoice !== 'object') {
27
+ return null;
28
+ }
29
+ const delta = firstChoice.delta;
30
+ if (!delta || typeof delta !== 'object') {
31
+ return null;
32
+ }
33
+ return delta;
34
+ }
35
+ function parseToolCallDelta(toolCall) {
36
+ if (!toolCall || typeof toolCall !== 'object') {
37
+ return null;
38
+ }
39
+ const toolCallRecord = toolCall;
40
+ const functionRecord = toolCallRecord.function && typeof toolCallRecord.function === 'object'
41
+ ? toolCallRecord.function
42
+ : undefined;
43
+ return {
44
+ index: typeof toolCallRecord.index === 'number' ? toolCallRecord.index : 0,
45
+ id: typeof toolCallRecord.id === 'string' ? toolCallRecord.id : undefined,
46
+ function: functionRecord
47
+ ? {
48
+ name: typeof functionRecord.name === 'string'
49
+ ? functionRecord.name
50
+ : undefined,
51
+ arguments: typeof functionRecord.arguments === 'string'
52
+ ? functionRecord.arguments
53
+ : undefined,
54
+ }
55
+ : undefined,
56
+ };
57
+ }
58
+ function applyToolCallDelta(toolCallsInProgress, delta) {
59
+ if (!toolCallsInProgress.has(delta.index)) {
60
+ toolCallsInProgress.set(delta.index, {
61
+ id: '',
62
+ name: '',
63
+ arguments: '',
64
+ });
65
+ }
66
+ const existing = toolCallsInProgress.get(delta.index);
67
+ if (!existing) {
68
+ return;
69
+ }
70
+ if (delta.id) {
71
+ existing.id = delta.id;
72
+ }
73
+ if (delta.function?.name) {
74
+ existing.name = delta.function.name;
75
+ }
76
+ if (delta.function?.arguments) {
77
+ existing.arguments += delta.function.arguments;
78
+ }
79
+ }
80
+ export async function* streamOpenAICompatibleResponse(response) {
81
+ if (!response.ok) {
82
+ const errorText = await response.text();
83
+ throw new Error(`Plugin API error: ${response.status} - ${errorText.slice(0, 200)}`);
84
+ }
85
+ if (!response.body) {
86
+ throw new Error('No response body for streaming');
87
+ }
88
+ const reader = response.body.getReader();
89
+ const decoder = new TextDecoder();
90
+ let buffer = '';
91
+ const toolCallsInProgress = new Map();
92
+ try {
93
+ while (true) {
94
+ const { done, value } = await reader.read();
95
+ if (done)
96
+ break;
97
+ buffer += decoder.decode(value, { stream: true });
98
+ const lines = buffer.split('\n');
99
+ buffer = lines.pop() || '';
100
+ for (const line of lines) {
101
+ const trimmed = line.trim();
102
+ if (!trimmed || trimmed === 'data: [DONE]') {
103
+ if (trimmed === 'data: [DONE]') {
104
+ for (const toolCall of toolCallsInProgress.values()) {
105
+ yield { type: 'tool_call', toolCall };
106
+ }
107
+ yield { type: 'done' };
108
+ }
109
+ continue;
110
+ }
111
+ if (!trimmed.startsWith('data: ')) {
112
+ continue;
113
+ }
114
+ try {
115
+ const delta = getChoiceDelta(JSON.parse(trimmed.slice(6)));
116
+ if (!delta) {
117
+ continue;
118
+ }
119
+ if (typeof delta.content === 'string' && delta.content) {
120
+ yield { type: 'content', content: delta.content };
121
+ }
122
+ if (Array.isArray(delta.tool_calls)) {
123
+ for (const toolCall of delta.tool_calls) {
124
+ const parsedDelta = parseToolCallDelta(toolCall);
125
+ if (parsedDelta) {
126
+ applyToolCallDelta(toolCallsInProgress, parsedDelta);
127
+ }
128
+ }
129
+ }
130
+ }
131
+ catch {
132
+ // Ignore malformed SSE payloads and keep the stream alive.
133
+ }
134
+ }
135
+ }
136
+ }
137
+ finally {
138
+ reader.releaseLock();
139
+ }
140
+ }
141
+ //# sourceMappingURL=pluginStreamAdapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pluginStreamAdapter.js","sourceRoot":"","sources":["../../src/utils/pluginStreamAdapter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ import { type WebSocketLike } from './websocketMessages.js';
2
+ export interface PluginStreamToolCall {
3
+ id: string;
4
+ name: string;
5
+ arguments: string;
6
+ }
7
+ export type PluginStreamChunk = {
8
+ type: 'content';
9
+ content?: string;
10
+ } | {
11
+ type: 'tool_call';
12
+ toolCall?: PluginStreamToolCall;
13
+ } | {
14
+ type: 'done';
15
+ };
16
+ export interface StreamPluginResponseOptions {
17
+ ws: WebSocketLike;
18
+ chunks: AsyncIterable<PluginStreamChunk>;
19
+ messageId?: string;
20
+ pauseThresholdMs?: number;
21
+ }
22
+ export declare function formatPluginStreamToolCalls(toolCalls: readonly PluginStreamToolCall[]): string;
23
+ export declare function streamPluginResponse({ ws, chunks, messageId, pauseThresholdMs, }: StreamPluginResponseOptions): Promise<string>;
24
+ //# sourceMappingURL=pluginStreaming.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pluginStreaming.d.ts","sourceRoot":"","sources":["../../src/utils/pluginStreaming.ts"],"names":[],"mappings":"AAkBA,OAAO,EAGL,KAAK,aAAa,EACnB,MAAM,wBAAwB,CAAC;AAEhC,MAAM,WAAW,oBAAoB;IACnC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,MAAM,iBAAiB,GACzB;IACE,IAAI,EAAE,SAAS,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,GACD;IACE,IAAI,EAAE,WAAW,CAAC;IAClB,QAAQ,CAAC,EAAE,oBAAoB,CAAC;CACjC,GACD;IACE,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEN,MAAM,WAAW,2BAA2B;IAC1C,EAAE,EAAE,aAAa,CAAC;IAClB,MAAM,EAAE,aAAa,CAAC,iBAAiB,CAAC,CAAC;IACzC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAID,wBAAgB,2BAA2B,CACzC,SAAS,EAAE,SAAS,oBAAoB,EAAE,GACzC,MAAM,CAaR;AAED,wBAAsB,oBAAoB,CAAC,EACzC,EAAE,EACF,MAAM,EACN,SAAS,EACT,gBAAuB,GACxB,EAAE,2BAA2B,GAAG,OAAO,CAAC,MAAM,CAAC,CAwF/C"}
@@ -0,0 +1,106 @@
1
+ /*
2
+ * Libre WebUI
3
+ * Copyright (C) 2025 Kroonen AI, Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at:
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ import { formatPluginToolArguments } from './pluginResponse.js';
18
+ import { sendAssistantChunk, sendToolStatus, } from './websocketMessages.js';
19
+ const PAUSE_TOOL_ID = 'tool-activity';
20
+ export function formatPluginStreamToolCalls(toolCalls) {
21
+ if (toolCalls.length === 0) {
22
+ return '';
23
+ }
24
+ let toolContent = '\n\n---\n**🔧 Tool Calls:**\n';
25
+ for (const toolCall of toolCalls) {
26
+ const argsFormatted = formatPluginToolArguments(toolCall.arguments);
27
+ toolContent += `\n**${toolCall.name}** (\`${toolCall.id}\`)\n\`\`\`json\n${argsFormatted}\n\`\`\`\n`;
28
+ }
29
+ return toolContent;
30
+ }
31
+ export async function streamPluginResponse({ ws, chunks, messageId, pauseThresholdMs = 2000, }) {
32
+ let totalContent = '';
33
+ const toolCalls = [];
34
+ let pauseTimer = null;
35
+ let toolActivitySent = false;
36
+ const sendPauseToolStatus = (phase) => {
37
+ sendToolStatus(ws, {
38
+ toolCallId: PAUSE_TOOL_ID,
39
+ name: 'working',
40
+ phase,
41
+ }, { ignoreClosedSocket: true });
42
+ };
43
+ const clearPauseTimer = () => {
44
+ if (pauseTimer) {
45
+ clearTimeout(pauseTimer);
46
+ pauseTimer = null;
47
+ }
48
+ };
49
+ const startPauseDetection = () => {
50
+ clearPauseTimer();
51
+ pauseTimer = setTimeout(() => {
52
+ if (!toolActivitySent) {
53
+ toolActivitySent = true;
54
+ sendPauseToolStatus('running');
55
+ }
56
+ }, pauseThresholdMs);
57
+ };
58
+ const finishToolActivity = () => {
59
+ clearPauseTimer();
60
+ if (toolActivitySent) {
61
+ sendPauseToolStatus('done');
62
+ toolActivitySent = false;
63
+ }
64
+ };
65
+ startPauseDetection();
66
+ try {
67
+ for await (const chunk of chunks) {
68
+ if (chunk.type === 'content' && chunk.content) {
69
+ finishToolActivity();
70
+ startPauseDetection();
71
+ totalContent += chunk.content;
72
+ sendAssistantChunk(ws, {
73
+ content: chunk.content,
74
+ total: totalContent,
75
+ done: false,
76
+ messageId,
77
+ });
78
+ }
79
+ else if (chunk.type === 'tool_call' && chunk.toolCall) {
80
+ clearPauseTimer();
81
+ toolActivitySent = true;
82
+ toolCalls.push(chunk.toolCall);
83
+ sendToolStatus(ws, {
84
+ toolCallId: PAUSE_TOOL_ID,
85
+ name: chunk.toolCall.name,
86
+ phase: 'running',
87
+ }, { ignoreClosedSocket: true });
88
+ }
89
+ else if (chunk.type === 'done') {
90
+ finishToolActivity();
91
+ totalContent += formatPluginStreamToolCalls(toolCalls);
92
+ sendAssistantChunk(ws, {
93
+ content: '',
94
+ total: totalContent,
95
+ done: true,
96
+ messageId,
97
+ });
98
+ }
99
+ }
100
+ }
101
+ finally {
102
+ clearPauseTimer();
103
+ }
104
+ return totalContent;
105
+ }
106
+ //# sourceMappingURL=pluginStreaming.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pluginStreaming.js","sourceRoot":"","sources":["../../src/utils/pluginStreaming.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import type { Request } from 'express';
2
+ import multer from 'multer';
3
+ export interface MulterRequest extends Request {
4
+ file?: Express.Multer.File;
5
+ }
6
+ export declare function safeCleanupFile(filePath: string, tempDir: string): void;
7
+ export declare const pluginUpload: multer.Multer;
8
+ //# sourceMappingURL=pluginUpload.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pluginUpload.d.ts","sourceRoot":"","sources":["../../src/utils/pluginUpload.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,MAA8B,MAAM,QAAQ,CAAC;AAKpD,MAAM,WAAW,aAAc,SAAQ,OAAO;IAC5C,IAAI,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC;CAC5B;AAED,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAcvE;AAED,eAAO,MAAM,YAAY,eAmBvB,CAAC"}
@@ -0,0 +1,51 @@
1
+ /*
2
+ * Libre WebUI
3
+ * Copyright (C) 2025 Kroonen AI, Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at:
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ import fs from 'fs';
18
+ import path from 'path';
19
+ import multer from 'multer';
20
+ import { createLogger } from './logger.js';
21
+ const logger = createLogger('utils:plugin-upload');
22
+ export function safeCleanupFile(filePath, tempDir) {
23
+ try {
24
+ const resolvedPath = path.resolve(filePath);
25
+ const resolvedTempDir = path.resolve(tempDir);
26
+ if (resolvedPath.startsWith(resolvedTempDir) &&
27
+ fs.existsSync(resolvedPath)) {
28
+ fs.unlinkSync(resolvedPath);
29
+ }
30
+ }
31
+ catch (error) {
32
+ logger.error('Failed to cleanup file:', error);
33
+ }
34
+ }
35
+ export const pluginUpload = multer({
36
+ dest: 'temp/',
37
+ fileFilter: (req, file, cb) => {
38
+ const allowedTypes = ['.json', '.zip'];
39
+ const fileExt = path.extname(file.originalname).toLowerCase();
40
+ if (allowedTypes.includes(fileExt)) {
41
+ cb(null, true);
42
+ }
43
+ else {
44
+ cb(new Error('Only .json and .zip files are allowed'));
45
+ }
46
+ },
47
+ limits: {
48
+ fileSize: 10 * 1024 * 1024,
49
+ },
50
+ });
51
+ //# sourceMappingURL=pluginUpload.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pluginUpload.js","sourceRoot":"","sources":["../../src/utils/pluginUpload.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,OAAO,MAA8B,MAAM,QAAQ,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,MAAM,MAAM,GAAG,YAAY,CAAC,qBAAqB,CAAC,CAAC;AAMnD,MAAM,UAAU,eAAe,CAAC,QAAgB,EAAE,OAAe;IAC/D,IAAI,CAAC;QACH,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QAC5C,MAAM,eAAe,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QAE9C,IACE,YAAY,CAAC,UAAU,CAAC,eAAe,CAAC;YACxC,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,EAC3B,CAAC;YACD,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;QAC9B,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,CAAC,KAAK,CAAC,yBAAyB,EAAE,KAAK,CAAC,CAAC;IACjD,CAAC;AACH,CAAC;AAED,MAAM,CAAC,MAAM,YAAY,GAAG,MAAM,CAAC;IACjC,IAAI,EAAE,OAAO;IACb,UAAU,EAAE,CACV,GAAY,EACZ,IAAyB,EACzB,EAAsB,EACtB,EAAE;QACF,MAAM,YAAY,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QACvC,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,WAAW,EAAE,CAAC;QAE9D,IAAI,YAAY,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;YACnC,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QACjB,CAAC;aAAM,CAAC;YACN,EAAE,CAAC,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC,CAAC;QACzD,CAAC;IACH,CAAC;IACD,MAAM,EAAE;QACN,QAAQ,EAAE,EAAE,GAAG,IAAI,GAAG,IAAI;KAC3B;CACF,CAAC,CAAC"}
@@ -0,0 +1,9 @@
1
+ import type { Plugin } from '../types/index.js';
2
+ export declare function validatePluginModel(model: string): void;
3
+ export declare function isSafePluginEndpoint(endpoint: string): boolean;
4
+ export declare function validatePluginEndpointOverride(endpoint: string): string | null;
5
+ export declare function assertSafePluginEndpoint(endpoint: string, label?: string): void;
6
+ export declare function resolvePluginEndpoint(endpoint: string, endpointOverride?: string): string;
7
+ export declare function applyModelEndpointTemplate(endpoint: string, model: string): string;
8
+ export declare function buildPluginAuthHeaders(plugin: Plugin, apiKey?: string | null): Record<string, string>;
9
+ //# sourceMappingURL=pluginValidation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pluginValidation.d.ts","sourceRoot":"","sources":["../../src/utils/pluginValidation.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAShD,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAgBvD;AAED,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAQ9D;AAED,wBAAgB,8BAA8B,CAC5C,QAAQ,EAAE,MAAM,GACf,MAAM,GAAG,IAAI,CAcf;AAED,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,MAAM,EAChB,KAAK,GAAE,MAAuB,GAC7B,IAAI,CAgBN;AAED,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,MAAM,EAChB,gBAAgB,CAAC,EAAE,MAAM,GACxB,MAAM,CAKR;AAED,wBAAgB,0BAA0B,CACxC,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,GACZ,MAAM,CAER;AAED,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,GACrB,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAYxB"}
@@ -0,0 +1,84 @@
1
+ /*
2
+ * Libre WebUI
3
+ * Copyright (C) 2025 Kroonen AI, Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at:
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ import { createLogger } from './logger.js';
18
+ const logger = createLogger('utils:plugin-validation');
19
+ const MODEL_PATTERN = /^[a-zA-Z0-9\-_:./]+$/;
20
+ const PRIVATE_NETWORK_PATTERN = /^(192\.168\.|10\.|172\.(1[6-9]|2[0-9]|3[01])\.)/;
21
+ export function validatePluginModel(model) {
22
+ if (!model || typeof model !== 'string') {
23
+ throw new Error('Invalid model parameter: must be a non-empty string');
24
+ }
25
+ if (!MODEL_PATTERN.test(model)) {
26
+ throw new Error(`Invalid model parameter: ${model} contains invalid characters`);
27
+ }
28
+ if (model.includes('..') || model.includes('\\')) {
29
+ throw new Error(`Invalid model parameter: ${model} contains invalid patterns`);
30
+ }
31
+ }
32
+ export function isSafePluginEndpoint(endpoint) {
33
+ const url = new URL(endpoint);
34
+ const isLocalhost = ['localhost', '127.0.0.1', '[::1]'].includes(url.hostname);
35
+ const isPrivateNetwork = PRIVATE_NETWORK_PATTERN.test(url.hostname);
36
+ return url.protocol === 'https:' || isLocalhost || isPrivateNetwork;
37
+ }
38
+ export function validatePluginEndpointOverride(endpoint) {
39
+ try {
40
+ if (!isSafePluginEndpoint(endpoint)) {
41
+ logger.warn(`Rejected insecure endpoint override: ${endpoint} (only HTTPS or localhost/private IPs allowed)`);
42
+ return null;
43
+ }
44
+ return endpoint;
45
+ }
46
+ catch {
47
+ logger.warn(`Rejected invalid endpoint override URL: ${endpoint}`);
48
+ return null;
49
+ }
50
+ }
51
+ export function assertSafePluginEndpoint(endpoint, label = 'endpoint URL') {
52
+ try {
53
+ if (!isSafePluginEndpoint(endpoint)) {
54
+ const url = new URL(endpoint);
55
+ throw new Error(`Insecure endpoint protocol: ${url.protocol}. Only HTTPS is allowed for remote endpoints. ` +
56
+ `(HTTP is permitted for localhost and private network IPs)`);
57
+ }
58
+ }
59
+ catch (error) {
60
+ if (error instanceof Error && error.message.startsWith('Insecure')) {
61
+ throw error;
62
+ }
63
+ throw new Error(`Invalid ${label}: ${endpoint}`);
64
+ }
65
+ }
66
+ export function resolvePluginEndpoint(endpoint, endpointOverride) {
67
+ return ((endpointOverride && validatePluginEndpointOverride(endpointOverride)) ||
68
+ endpoint);
69
+ }
70
+ export function applyModelEndpointTemplate(endpoint, model) {
71
+ return endpoint.replace('{model}', encodeURIComponent(model));
72
+ }
73
+ export function buildPluginAuthHeaders(plugin, apiKey) {
74
+ const headers = {
75
+ 'Content-Type': 'application/json',
76
+ };
77
+ if (apiKey && plugin.auth.header) {
78
+ headers[plugin.auth.header] = plugin.auth.prefix
79
+ ? `${plugin.auth.prefix}${apiKey}`
80
+ : apiKey;
81
+ }
82
+ return headers;
83
+ }
84
+ //# sourceMappingURL=pluginValidation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pluginValidation.js","sourceRoot":"","sources":["../../src/utils/pluginValidation.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import type { PluginVariableDefinition } from '../types/index.js';
2
+ export type ValidatedPluginVariables = Record<string, string | number | boolean>;
3
+ export declare function validatePluginVariables(definitions: PluginVariableDefinition[], values: Record<string, unknown>): {
4
+ success: true;
5
+ variables: ValidatedPluginVariables;
6
+ } | {
7
+ success: false;
8
+ error: string;
9
+ };
10
+ //# sourceMappingURL=pluginVariableValidation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pluginVariableValidation.d.ts","sourceRoot":"","sources":["../../src/utils/pluginVariableValidation.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,mBAAmB,CAAC;AAElE,MAAM,MAAM,wBAAwB,GAAG,MAAM,CAC3C,MAAM,EACN,MAAM,GAAG,MAAM,GAAG,OAAO,CAC1B,CAAC;AAEF,wBAAgB,uBAAuB,CACrC,WAAW,EAAE,wBAAwB,EAAE,EACvC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAE7B;IAAE,OAAO,EAAE,IAAI,CAAC;IAAC,SAAS,EAAE,wBAAwB,CAAA;CAAE,GACtD;IAAE,OAAO,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAsEpC"}
@@ -0,0 +1,80 @@
1
+ /*
2
+ * Libre WebUI
3
+ * Copyright (C) 2025 Kroonen AI, Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at:
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ export function validatePluginVariables(definitions, values) {
18
+ const schemaMap = new Map(definitions.map(definition => [definition.name, definition]));
19
+ const validated = {};
20
+ for (const [key, value] of Object.entries(values)) {
21
+ const definition = schemaMap.get(key);
22
+ if (!definition)
23
+ continue;
24
+ if (definition.type === 'number') {
25
+ const num = Number(value);
26
+ if (isNaN(num)) {
27
+ return { success: false, error: `Variable "${key}" must be a number` };
28
+ }
29
+ if (definition.min !== undefined && num < definition.min) {
30
+ return {
31
+ success: false,
32
+ error: `Variable "${key}" must be >= ${definition.min}`,
33
+ };
34
+ }
35
+ if (definition.max !== undefined && num > definition.max) {
36
+ return {
37
+ success: false,
38
+ error: `Variable "${key}" must be <= ${definition.max}`,
39
+ };
40
+ }
41
+ validated[key] = num;
42
+ continue;
43
+ }
44
+ if (definition.type === 'boolean') {
45
+ validated[key] = value === true || value === 'true';
46
+ continue;
47
+ }
48
+ if (definition.type === 'select') {
49
+ if (definition.options && !definition.options.includes(String(value))) {
50
+ return {
51
+ success: false,
52
+ error: `Variable "${key}" must be one of: ${definition.options.join(', ')}`,
53
+ };
54
+ }
55
+ validated[key] = String(value);
56
+ continue;
57
+ }
58
+ const str = String(value);
59
+ if (str.length > 2048) {
60
+ return {
61
+ success: false,
62
+ error: `Variable "${key}" exceeds maximum length of 2048 characters`,
63
+ };
64
+ }
65
+ if (key === 'endpoint' && str.length > 0) {
66
+ try {
67
+ new URL(str);
68
+ }
69
+ catch {
70
+ return {
71
+ success: false,
72
+ error: `Variable "${key}" must be a valid URL`,
73
+ };
74
+ }
75
+ }
76
+ validated[key] = str;
77
+ }
78
+ return { success: true, variables: validated };
79
+ }
80
+ //# sourceMappingURL=pluginVariableValidation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pluginVariableValidation.js","sourceRoot":"","sources":["../../src/utils/pluginVariableValidation.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ export interface WebSocketLike {
2
+ send(data: string): void;
3
+ }
4
+ export interface AssistantChunkData {
5
+ content: string;
6
+ total: string;
7
+ done: boolean;
8
+ messageId?: string;
9
+ }
10
+ export interface ToolStatusData {
11
+ toolCallId: string;
12
+ name: string;
13
+ phase: string;
14
+ }
15
+ export interface SendOptions {
16
+ ignoreClosedSocket?: boolean;
17
+ }
18
+ export declare function sendConnected(ws: WebSocketLike): boolean;
19
+ export declare function sendUserMessage(ws: WebSocketLike, data: unknown): boolean;
20
+ export declare function sendAssistantChunk(ws: WebSocketLike, data: AssistantChunkData, options?: SendOptions): boolean;
21
+ export declare function sendAssistantComplete(ws: WebSocketLike, data: unknown): boolean;
22
+ export declare function sendToolStatus(ws: WebSocketLike, data: ToolStatusData, options?: SendOptions): boolean;
23
+ export declare function sendError(ws: WebSocketLike, data: unknown): boolean;
24
+ export declare function buildAssistantFakeStreamChunks(content: string, messageId?: string, batchSize?: number): AssistantChunkData[];
25
+ export declare function streamAssistantFakeChunks(ws: WebSocketLike, content: string, messageId?: string, delayMs?: number): Promise<void>;
26
+ //# sourceMappingURL=websocketMessages.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"websocketMessages.d.ts","sourceRoot":"","sources":["../../src/utils/websocketMessages.ts"],"names":[],"mappings":"AAiBA,MAAM,WAAW,aAAa;IAC5B,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,OAAO,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,WAAW;IAC1B,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B;AA4BD,wBAAgB,aAAa,CAAC,EAAE,EAAE,aAAa,GAAG,OAAO,CAIxD;AAED,wBAAgB,eAAe,CAAC,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,OAAO,GAAG,OAAO,CAEzE;AAED,wBAAgB,kBAAkB,CAChC,EAAE,EAAE,aAAa,EACjB,IAAI,EAAE,kBAAkB,EACxB,OAAO,CAAC,EAAE,WAAW,GACpB,OAAO,CAET;AAED,wBAAgB,qBAAqB,CACnC,EAAE,EAAE,aAAa,EACjB,IAAI,EAAE,OAAO,GACZ,OAAO,CAET;AAED,wBAAgB,cAAc,CAC5B,EAAE,EAAE,aAAa,EACjB,IAAI,EAAE,cAAc,EACpB,OAAO,CAAC,EAAE,WAAW,GACpB,OAAO,CAET;AAED,wBAAgB,SAAS,CAAC,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,OAAO,GAAG,OAAO,CAEnE;AAED,wBAAgB,8BAA8B,CAC5C,OAAO,EAAE,MAAM,EACf,SAAS,CAAC,EAAE,MAAM,EAClB,SAAS,GAAE,MAAU,GACpB,kBAAkB,EAAE,CAkBtB;AAED,wBAAsB,yBAAyB,CAC7C,EAAE,EAAE,aAAa,EACjB,OAAO,EAAE,MAAM,EACf,SAAS,CAAC,EAAE,MAAM,EAClB,OAAO,GAAE,MAAY,GACpB,OAAO,CAAC,IAAI,CAAC,CAUf"}