libre-webui 0.2.4

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 (233) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +204 -0
  3. package/backend/dist/db.d.ts +19 -0
  4. package/backend/dist/db.d.ts.map +1 -0
  5. package/backend/dist/db.js +355 -0
  6. package/backend/dist/db.js.map +1 -0
  7. package/backend/dist/env.d.ts +2 -0
  8. package/backend/dist/env.d.ts.map +1 -0
  9. package/backend/dist/env.js +22 -0
  10. package/backend/dist/env.js.map +1 -0
  11. package/backend/dist/index.d.ts +4 -0
  12. package/backend/dist/index.d.ts.map +1 -0
  13. package/backend/dist/index.js +751 -0
  14. package/backend/dist/index.js.map +1 -0
  15. package/backend/dist/middleware/auth.d.ts +18 -0
  16. package/backend/dist/middleware/auth.d.ts.map +1 -0
  17. package/backend/dist/middleware/auth.js +98 -0
  18. package/backend/dist/middleware/auth.js.map +1 -0
  19. package/backend/dist/middleware/index.d.ts +5 -0
  20. package/backend/dist/middleware/index.d.ts.map +1 -0
  21. package/backend/dist/middleware/index.js +62 -0
  22. package/backend/dist/middleware/index.js.map +1 -0
  23. package/backend/dist/models/personaModel.d.ts +37 -0
  24. package/backend/dist/models/personaModel.d.ts.map +1 -0
  25. package/backend/dist/models/personaModel.js +269 -0
  26. package/backend/dist/models/personaModel.js.map +1 -0
  27. package/backend/dist/models/userModel.d.ts +86 -0
  28. package/backend/dist/models/userModel.d.ts.map +1 -0
  29. package/backend/dist/models/userModel.js +212 -0
  30. package/backend/dist/models/userModel.js.map +1 -0
  31. package/backend/dist/routes/auth.d.ts +3 -0
  32. package/backend/dist/routes/auth.d.ts.map +1 -0
  33. package/backend/dist/routes/auth.js +389 -0
  34. package/backend/dist/routes/auth.js.map +1 -0
  35. package/backend/dist/routes/chat.d.ts +3 -0
  36. package/backend/dist/routes/chat.d.ts.map +1 -0
  37. package/backend/dist/routes/chat.js +767 -0
  38. package/backend/dist/routes/chat.js.map +1 -0
  39. package/backend/dist/routes/documents.d.ts +3 -0
  40. package/backend/dist/routes/documents.d.ts.map +1 -0
  41. package/backend/dist/routes/documents.js +244 -0
  42. package/backend/dist/routes/documents.js.map +1 -0
  43. package/backend/dist/routes/ollama.d.ts +3 -0
  44. package/backend/dist/routes/ollama.d.ts.map +1 -0
  45. package/backend/dist/routes/ollama.js +549 -0
  46. package/backend/dist/routes/ollama.js.map +1 -0
  47. package/backend/dist/routes/personas.d.ts +3 -0
  48. package/backend/dist/routes/personas.d.ts.map +1 -0
  49. package/backend/dist/routes/personas.js +505 -0
  50. package/backend/dist/routes/personas.js.map +1 -0
  51. package/backend/dist/routes/plugins.d.ts +3 -0
  52. package/backend/dist/routes/plugins.d.ts.map +1 -0
  53. package/backend/dist/routes/plugins.js +417 -0
  54. package/backend/dist/routes/plugins.js.map +1 -0
  55. package/backend/dist/routes/preferences.d.ts +3 -0
  56. package/backend/dist/routes/preferences.d.ts.map +1 -0
  57. package/backend/dist/routes/preferences.js +303 -0
  58. package/backend/dist/routes/preferences.js.map +1 -0
  59. package/backend/dist/routes/tts.d.ts +3 -0
  60. package/backend/dist/routes/tts.d.ts.map +1 -0
  61. package/backend/dist/routes/tts.js +304 -0
  62. package/backend/dist/routes/tts.js.map +1 -0
  63. package/backend/dist/routes/users.d.ts +3 -0
  64. package/backend/dist/routes/users.d.ts.map +1 -0
  65. package/backend/dist/routes/users.js +246 -0
  66. package/backend/dist/routes/users.js.map +1 -0
  67. package/backend/dist/services/authService.d.ts +51 -0
  68. package/backend/dist/services/authService.d.ts.map +1 -0
  69. package/backend/dist/services/authService.js +153 -0
  70. package/backend/dist/services/authService.js.map +1 -0
  71. package/backend/dist/services/chatService.d.ts +52 -0
  72. package/backend/dist/services/chatService.d.ts.map +1 -0
  73. package/backend/dist/services/chatService.js +645 -0
  74. package/backend/dist/services/chatService.js.map +1 -0
  75. package/backend/dist/services/documentService.d.ts +34 -0
  76. package/backend/dist/services/documentService.d.ts.map +1 -0
  77. package/backend/dist/services/documentService.js +428 -0
  78. package/backend/dist/services/documentService.js.map +1 -0
  79. package/backend/dist/services/encryptionService.d.ts +62 -0
  80. package/backend/dist/services/encryptionService.d.ts.map +1 -0
  81. package/backend/dist/services/encryptionService.js +284 -0
  82. package/backend/dist/services/encryptionService.js.map +1 -0
  83. package/backend/dist/services/memoryService.d.ts +140 -0
  84. package/backend/dist/services/memoryService.d.ts.map +1 -0
  85. package/backend/dist/services/memoryService.js +867 -0
  86. package/backend/dist/services/memoryService.js.map +1 -0
  87. package/backend/dist/services/mutationEngineService.d.ts +49 -0
  88. package/backend/dist/services/mutationEngineService.d.ts.map +1 -0
  89. package/backend/dist/services/mutationEngineService.js +432 -0
  90. package/backend/dist/services/mutationEngineService.js.map +1 -0
  91. package/backend/dist/services/ollamaService.d.ts +55 -0
  92. package/backend/dist/services/ollamaService.d.ts.map +1 -0
  93. package/backend/dist/services/ollamaService.js +450 -0
  94. package/backend/dist/services/ollamaService.js.map +1 -0
  95. package/backend/dist/services/personaService.d.ts +67 -0
  96. package/backend/dist/services/personaService.d.ts.map +1 -0
  97. package/backend/dist/services/personaService.js +373 -0
  98. package/backend/dist/services/personaService.js.map +1 -0
  99. package/backend/dist/services/pluginService.d.ts +42 -0
  100. package/backend/dist/services/pluginService.d.ts.map +1 -0
  101. package/backend/dist/services/pluginService.js +961 -0
  102. package/backend/dist/services/pluginService.js.map +1 -0
  103. package/backend/dist/services/preferencesService.d.ts +35 -0
  104. package/backend/dist/services/preferencesService.d.ts.map +1 -0
  105. package/backend/dist/services/preferencesService.js +255 -0
  106. package/backend/dist/services/preferencesService.js.map +1 -0
  107. package/backend/dist/services/simpleGitHubOAuth.d.ts +48 -0
  108. package/backend/dist/services/simpleGitHubOAuth.d.ts.map +1 -0
  109. package/backend/dist/services/simpleGitHubOAuth.js +203 -0
  110. package/backend/dist/services/simpleGitHubOAuth.js.map +1 -0
  111. package/backend/dist/services/simpleHuggingFaceOAuth.d.ts +43 -0
  112. package/backend/dist/services/simpleHuggingFaceOAuth.d.ts.map +1 -0
  113. package/backend/dist/services/simpleHuggingFaceOAuth.js +159 -0
  114. package/backend/dist/services/simpleHuggingFaceOAuth.js.map +1 -0
  115. package/backend/dist/services/userService.d.ts +1 -0
  116. package/backend/dist/services/userService.d.ts.map +1 -0
  117. package/backend/dist/services/userService.js +18 -0
  118. package/backend/dist/services/userService.js.map +1 -0
  119. package/backend/dist/storage.d.ts +55 -0
  120. package/backend/dist/storage.d.ts.map +1 -0
  121. package/backend/dist/storage.js +741 -0
  122. package/backend/dist/storage.js.map +1 -0
  123. package/backend/dist/test-encryption.d.ts +2 -0
  124. package/backend/dist/test-encryption.d.ts.map +1 -0
  125. package/backend/dist/test-encryption.js +64 -0
  126. package/backend/dist/test-encryption.js.map +1 -0
  127. package/backend/dist/types/index.d.ts +523 -0
  128. package/backend/dist/types/index.d.ts.map +1 -0
  129. package/backend/dist/types/index.js +31 -0
  130. package/backend/dist/types/index.js.map +1 -0
  131. package/backend/dist/utils/generationUtils.d.ts +10 -0
  132. package/backend/dist/utils/generationUtils.d.ts.map +1 -0
  133. package/backend/dist/utils/generationUtils.js +49 -0
  134. package/backend/dist/utils/generationUtils.js.map +1 -0
  135. package/backend/dist/utils/hash.d.ts +29 -0
  136. package/backend/dist/utils/hash.d.ts.map +1 -0
  137. package/backend/dist/utils/hash.js +73 -0
  138. package/backend/dist/utils/hash.js.map +1 -0
  139. package/backend/dist/utils/jwt.d.ts +37 -0
  140. package/backend/dist/utils/jwt.d.ts.map +1 -0
  141. package/backend/dist/utils/jwt.js +86 -0
  142. package/backend/dist/utils/jwt.js.map +1 -0
  143. package/bin/cli.js +150 -0
  144. package/electron/main.js +322 -0
  145. package/frontend/dist/_redirects +1 -0
  146. package/frontend/dist/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
  147. package/frontend/dist/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
  148. package/frontend/dist/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
  149. package/frontend/dist/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
  150. package/frontend/dist/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
  151. package/frontend/dist/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
  152. package/frontend/dist/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
  153. package/frontend/dist/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
  154. package/frontend/dist/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
  155. package/frontend/dist/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
  156. package/frontend/dist/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
  157. package/frontend/dist/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
  158. package/frontend/dist/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
  159. package/frontend/dist/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
  160. package/frontend/dist/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
  161. package/frontend/dist/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
  162. package/frontend/dist/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
  163. package/frontend/dist/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
  164. package/frontend/dist/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
  165. package/frontend/dist/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
  166. package/frontend/dist/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
  167. package/frontend/dist/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
  168. package/frontend/dist/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
  169. package/frontend/dist/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
  170. package/frontend/dist/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
  171. package/frontend/dist/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
  172. package/frontend/dist/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
  173. package/frontend/dist/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
  174. package/frontend/dist/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
  175. package/frontend/dist/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
  176. package/frontend/dist/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
  177. package/frontend/dist/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
  178. package/frontend/dist/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
  179. package/frontend/dist/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
  180. package/frontend/dist/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
  181. package/frontend/dist/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
  182. package/frontend/dist/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
  183. package/frontend/dist/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
  184. package/frontend/dist/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
  185. package/frontend/dist/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
  186. package/frontend/dist/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
  187. package/frontend/dist/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
  188. package/frontend/dist/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
  189. package/frontend/dist/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
  190. package/frontend/dist/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
  191. package/frontend/dist/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
  192. package/frontend/dist/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
  193. package/frontend/dist/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
  194. package/frontend/dist/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
  195. package/frontend/dist/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
  196. package/frontend/dist/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
  197. package/frontend/dist/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
  198. package/frontend/dist/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
  199. package/frontend/dist/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
  200. package/frontend/dist/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
  201. package/frontend/dist/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
  202. package/frontend/dist/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
  203. package/frontend/dist/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
  204. package/frontend/dist/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
  205. package/frontend/dist/assets/index-CRQkB7Wz.js +3 -0
  206. package/frontend/dist/css/index-B1OjddR-.css +1 -0
  207. package/frontend/dist/favicon-dark.png +0 -0
  208. package/frontend/dist/favicon-light.png +0 -0
  209. package/frontend/dist/index.html +23 -0
  210. package/frontend/dist/js/ArtifactContainer-c_oi7XMs.js +23 -0
  211. package/frontend/dist/js/ArtifactDemoPage-CdfwJVXu.js +98 -0
  212. package/frontend/dist/js/ChatPage-CyotkmS0.js +281 -0
  213. package/frontend/dist/js/ModelsPage-DNaziPHc.js +2 -0
  214. package/frontend/dist/js/PersonasPage-DcnbJf8Q.js +13 -0
  215. package/frontend/dist/js/UserManagementPage-DtTf92dS.js +1 -0
  216. package/frontend/dist/js/markdown-vendor-D-79K2xZ.js +22 -0
  217. package/frontend/dist/js/react-vendor-N--QU9DW.js +8 -0
  218. package/frontend/dist/js/router-vendor-B-t91v39.js +3 -0
  219. package/frontend/dist/js/ui-vendor-VxSCY_bv.js +177 -0
  220. package/frontend/dist/js/utils-vendor-DNzxLBGx.js +6 -0
  221. package/frontend/dist/logo-dark.png +0 -0
  222. package/frontend/dist/logo-light.png +0 -0
  223. package/frontend/dist/logo.svg +14 -0
  224. package/package.json +128 -0
  225. package/plugins/anthropic.json +25 -0
  226. package/plugins/elevenlabs.json +58 -0
  227. package/plugins/gemini.json +57 -0
  228. package/plugins/github.json +23 -0
  229. package/plugins/groq.json +25 -0
  230. package/plugins/mistral.json +73 -0
  231. package/plugins/openai-tts.json +38 -0
  232. package/plugins/openai.json +132 -0
  233. package/plugins/openrouter.json +353 -0
@@ -0,0 +1,303 @@
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 express from 'express';
18
+ import rateLimit from 'express-rate-limit';
19
+ import preferencesService from '../services/preferencesService.js';
20
+ import { getErrorMessage, } from '../types/index.js';
21
+ import { authenticate } from '../middleware/auth.js';
22
+ const router = express.Router();
23
+ // Rate limiter for preferences routes: 30 requests per minute (reasonable for settings)
24
+ const preferencesRateLimiter = rateLimit({
25
+ windowMs: 1 * 60 * 1000, // 1 minute
26
+ max: 30, // limit each IP to 30 requests per minute
27
+ message: {
28
+ success: false,
29
+ message: 'Too many preferences requests, please slow down',
30
+ },
31
+ standardHeaders: true,
32
+ legacyHeaders: false,
33
+ });
34
+ // Apply rate limiter to all preferences routes
35
+ router.use(preferencesRateLimiter);
36
+ // Apply authentication middleware to all preferences routes
37
+ router.use(authenticate);
38
+ // Get user preferences
39
+ router.get('/', async (req, res) => {
40
+ try {
41
+ const userId = req.user?.userId;
42
+ if (!userId) {
43
+ res.status(401).json({
44
+ success: false,
45
+ error: 'User ID not found in token',
46
+ });
47
+ return;
48
+ }
49
+ const preferences = preferencesService.getPreferences(userId);
50
+ res.json({
51
+ success: true,
52
+ data: preferences,
53
+ });
54
+ }
55
+ catch (error) {
56
+ res.status(500).json({
57
+ success: false,
58
+ error: getErrorMessage(error, 'Failed to get preferences'),
59
+ });
60
+ }
61
+ });
62
+ // Update user preferences
63
+ router.put('/', async (req, res) => {
64
+ try {
65
+ const userId = req.user?.userId;
66
+ if (!userId) {
67
+ res.status(401).json({
68
+ success: false,
69
+ error: 'User ID not found in token',
70
+ });
71
+ return;
72
+ }
73
+ const updates = req.body;
74
+ const updatedPreferences = preferencesService.updatePreferences(updates, userId);
75
+ res.json({
76
+ success: true,
77
+ data: updatedPreferences,
78
+ });
79
+ }
80
+ catch (error) {
81
+ res.status(500).json({
82
+ success: false,
83
+ error: getErrorMessage(error, 'Failed to update preferences'),
84
+ });
85
+ }
86
+ });
87
+ // Set default model (convenience endpoint)
88
+ router.put('/default-model', async (req, res) => {
89
+ try {
90
+ const userId = req.user?.userId;
91
+ if (!userId) {
92
+ res.status(401).json({
93
+ success: false,
94
+ error: 'User ID not found in token',
95
+ });
96
+ return;
97
+ }
98
+ const { model } = req.body;
99
+ if (!model) {
100
+ res.status(400).json({
101
+ success: false,
102
+ error: 'Model is required',
103
+ });
104
+ return;
105
+ }
106
+ const updatedPreferences = preferencesService.setDefaultModel(model, userId);
107
+ res.json({
108
+ success: true,
109
+ data: updatedPreferences,
110
+ });
111
+ }
112
+ catch (error) {
113
+ res.status(500).json({
114
+ success: false,
115
+ error: getErrorMessage(error, 'Failed to set default model'),
116
+ });
117
+ }
118
+ });
119
+ // Set system message (convenience endpoint)
120
+ router.put('/system-message', async (req, res) => {
121
+ try {
122
+ const userId = req.user?.userId;
123
+ if (!userId) {
124
+ res.status(401).json({
125
+ success: false,
126
+ error: 'User ID not found in token',
127
+ });
128
+ return;
129
+ }
130
+ const { message } = req.body;
131
+ if (message === undefined) {
132
+ res.status(400).json({
133
+ success: false,
134
+ error: 'Message is required',
135
+ });
136
+ return;
137
+ }
138
+ const updatedPreferences = preferencesService.setSystemMessage(message, userId);
139
+ res.json({
140
+ success: true,
141
+ data: updatedPreferences,
142
+ });
143
+ }
144
+ catch (error) {
145
+ res.status(500).json({
146
+ success: false,
147
+ error: getErrorMessage(error, 'Failed to set system message'),
148
+ });
149
+ }
150
+ });
151
+ // Set generation options (convenience endpoint)
152
+ router.put('/generation-options', async (req, res) => {
153
+ try {
154
+ const userId = req.user?.userId;
155
+ if (!userId) {
156
+ res.status(401).json({
157
+ success: false,
158
+ error: 'User ID not found in token',
159
+ });
160
+ return;
161
+ }
162
+ const options = req.body;
163
+ if (!options || typeof options !== 'object') {
164
+ res.status(400).json({
165
+ success: false,
166
+ error: 'Generation options are required',
167
+ });
168
+ return;
169
+ }
170
+ const updatedPreferences = preferencesService.setGenerationOptions(options, userId);
171
+ res.json({
172
+ success: true,
173
+ data: updatedPreferences,
174
+ });
175
+ }
176
+ catch (error) {
177
+ res.status(500).json({
178
+ success: false,
179
+ error: getErrorMessage(error, 'Failed to set generation options'),
180
+ });
181
+ }
182
+ });
183
+ // Reset generation options to defaults
184
+ router.post('/generation-options/reset', async (req, res) => {
185
+ try {
186
+ const userId = req.user?.userId;
187
+ if (!userId) {
188
+ res.status(401).json({
189
+ success: false,
190
+ error: 'User ID not found in token',
191
+ });
192
+ return;
193
+ }
194
+ const updatedPreferences = preferencesService.resetGenerationOptions(userId);
195
+ res.json({
196
+ success: true,
197
+ data: updatedPreferences,
198
+ });
199
+ }
200
+ catch (error) {
201
+ res.status(500).json({
202
+ success: false,
203
+ error: getErrorMessage(error, 'Failed to reset generation options'),
204
+ });
205
+ }
206
+ });
207
+ // Set embedding settings
208
+ router.put('/embedding-settings', async (req, res) => {
209
+ try {
210
+ const userId = req.user?.userId;
211
+ if (!userId) {
212
+ res.status(401).json({
213
+ success: false,
214
+ error: 'User ID not found in token',
215
+ });
216
+ return;
217
+ }
218
+ const settings = req.body;
219
+ if (!settings || typeof settings !== 'object') {
220
+ res.status(400).json({
221
+ success: false,
222
+ error: 'Embedding settings are required',
223
+ });
224
+ return;
225
+ }
226
+ const updatedPreferences = preferencesService.setEmbeddingSettings(settings, userId);
227
+ res.json({
228
+ success: true,
229
+ data: updatedPreferences,
230
+ });
231
+ }
232
+ catch (error) {
233
+ res.status(500).json({
234
+ success: false,
235
+ error: getErrorMessage(error, 'Failed to set embedding settings'),
236
+ });
237
+ }
238
+ });
239
+ // Reset embedding settings to defaults
240
+ router.post('/embedding-settings/reset', async (req, res) => {
241
+ try {
242
+ const userId = req.user?.userId;
243
+ if (!userId) {
244
+ res.status(401).json({
245
+ success: false,
246
+ error: 'User ID not found in token',
247
+ });
248
+ return;
249
+ }
250
+ const updatedPreferences = preferencesService.resetEmbeddingSettings(userId);
251
+ res.json({
252
+ success: true,
253
+ data: updatedPreferences,
254
+ });
255
+ }
256
+ catch (error) {
257
+ res.status(500).json({
258
+ success: false,
259
+ error: getErrorMessage(error, 'Failed to reset embedding settings'),
260
+ });
261
+ }
262
+ });
263
+ // Import preferences data
264
+ router.post('/import', async (req, res) => {
265
+ try {
266
+ const userId = req.user?.userId;
267
+ if (!userId) {
268
+ res.status(401).json({
269
+ success: false,
270
+ error: 'User ID not found in token',
271
+ });
272
+ return;
273
+ }
274
+ const { data, mergeStrategy } = req.body;
275
+ if (!data) {
276
+ res.status(400).json({
277
+ success: false,
278
+ error: 'Import data is required',
279
+ });
280
+ return;
281
+ }
282
+ if (mergeStrategy && !['merge', 'replace'].includes(mergeStrategy)) {
283
+ res.status(400).json({
284
+ success: false,
285
+ error: 'Invalid merge strategy. Must be "merge" or "replace"',
286
+ });
287
+ return;
288
+ }
289
+ const updatedPreferences = preferencesService.importData(data, mergeStrategy || 'merge', userId);
290
+ res.json({
291
+ success: true,
292
+ data: updatedPreferences,
293
+ });
294
+ }
295
+ catch (error) {
296
+ res.status(500).json({
297
+ success: false,
298
+ error: getErrorMessage(error, 'Failed to import preferences data'),
299
+ });
300
+ }
301
+ });
302
+ export default router;
303
+ //# sourceMappingURL=preferences.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preferences.js","sourceRoot":"","sources":["../../src/routes/preferences.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ declare const router: import("express-serve-static-core").Router;
2
+ export default router;
3
+ //# sourceMappingURL=tts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tts.d.ts","sourceRoot":"","sources":["../../src/routes/tts.ts"],"names":[],"mappings":"AAqBA,QAAA,MAAM,MAAM,4CAAmB,CAAC;AAwThC,eAAe,MAAM,CAAC"}
@@ -0,0 +1,304 @@
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 express from 'express';
18
+ import rateLimit from 'express-rate-limit';
19
+ import pluginService from '../services/pluginService.js';
20
+ const router = express.Router();
21
+ // Rate limiter for TTS routes: 30 requests per minute
22
+ const ttsRateLimiter = rateLimit({
23
+ windowMs: 60 * 1000, // 1 minute
24
+ max: 30, // limit each IP to 30 requests per windowMs
25
+ message: {
26
+ success: false,
27
+ message: 'Too many TTS requests, please try again later',
28
+ },
29
+ standardHeaders: true,
30
+ legacyHeaders: false,
31
+ });
32
+ /**
33
+ * GET /api/tts/models
34
+ * Get all available TTS models from plugins
35
+ */
36
+ router.get('/models', async (_req, res) => {
37
+ try {
38
+ const models = pluginService.getAvailableTTSModels();
39
+ res.json({
40
+ success: true,
41
+ data: models,
42
+ });
43
+ }
44
+ catch (error) {
45
+ console.error('Failed to get TTS models:', error);
46
+ res.status(500).json({
47
+ success: false,
48
+ message: 'Failed to get TTS models',
49
+ });
50
+ }
51
+ });
52
+ /**
53
+ * GET /api/tts/voices/:pluginId
54
+ * Get available voices for a specific TTS plugin
55
+ */
56
+ router.get('/voices/:pluginId', async (req, res) => {
57
+ try {
58
+ const { pluginId } = req.params;
59
+ const config = pluginService.getTTSConfig(pluginId);
60
+ if (!config) {
61
+ res.status(404).json({
62
+ success: false,
63
+ message: 'TTS plugin not found or has no TTS configuration',
64
+ });
65
+ return;
66
+ }
67
+ res.json({
68
+ success: true,
69
+ data: {
70
+ voices: config.voices || [],
71
+ default_voice: config.default_voice,
72
+ formats: config.formats || ['mp3'],
73
+ default_format: config.default_format || 'mp3',
74
+ max_characters: config.max_characters,
75
+ supports_streaming: config.supports_streaming || false,
76
+ },
77
+ });
78
+ }
79
+ catch (error) {
80
+ console.error('Failed to get TTS voices:', error);
81
+ res.status(500).json({
82
+ success: false,
83
+ message: 'Failed to get TTS voices',
84
+ });
85
+ }
86
+ });
87
+ /**
88
+ * POST /api/tts/generate
89
+ * Generate speech from text using a TTS plugin
90
+ */
91
+ router.post('/generate', ttsRateLimiter, async (req, res) => {
92
+ try {
93
+ const { model, input, voice, response_format, speed } = req.body;
94
+ // Validate required fields
95
+ if (!model || typeof model !== 'string') {
96
+ res.status(400).json({
97
+ success: false,
98
+ message: 'Model is required and must be a string',
99
+ });
100
+ return;
101
+ }
102
+ if (!input || typeof input !== 'string') {
103
+ res.status(400).json({
104
+ success: false,
105
+ message: 'Input text is required and must be a string',
106
+ });
107
+ return;
108
+ }
109
+ if (input.length === 0) {
110
+ res.status(400).json({
111
+ success: false,
112
+ message: 'Input text cannot be empty',
113
+ });
114
+ return;
115
+ }
116
+ // Validate optional parameters
117
+ if (speed !== undefined) {
118
+ const speedNum = Number(speed);
119
+ if (isNaN(speedNum) || speedNum < 0.25 || speedNum > 4.0) {
120
+ res.status(400).json({
121
+ success: false,
122
+ message: 'Speed must be a number between 0.25 and 4.0',
123
+ });
124
+ return;
125
+ }
126
+ }
127
+ const validFormats = ['mp3', 'opus', 'aac', 'flac', 'wav', 'pcm'];
128
+ if (response_format && !validFormats.includes(response_format)) {
129
+ res.status(400).json({
130
+ success: false,
131
+ message: `Invalid response_format. Must be one of: ${validFormats.join(', ')}`,
132
+ });
133
+ return;
134
+ }
135
+ // Execute TTS request
136
+ const audioBuffer = await pluginService.executeTTSRequest(model, input, {
137
+ voice,
138
+ response_format,
139
+ speed,
140
+ });
141
+ // Determine content type based on format
142
+ const contentTypeMap = {
143
+ mp3: 'audio/mpeg',
144
+ opus: 'audio/opus',
145
+ aac: 'audio/aac',
146
+ flac: 'audio/flac',
147
+ wav: 'audio/wav',
148
+ pcm: 'audio/pcm',
149
+ };
150
+ const format = response_format || 'mp3';
151
+ const contentType = contentTypeMap[format] || 'audio/mpeg';
152
+ // Set response headers
153
+ res.set({
154
+ 'Content-Type': contentType,
155
+ 'Content-Length': audioBuffer.length.toString(),
156
+ 'Content-Disposition': `inline; filename="speech.${format}"`,
157
+ });
158
+ // Send audio data
159
+ res.send(audioBuffer);
160
+ }
161
+ catch (error) {
162
+ console.error('TTS generation failed:', error);
163
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error';
164
+ // Determine appropriate status code
165
+ let statusCode = 500;
166
+ if (errorMessage.includes('No TTS plugin found')) {
167
+ statusCode = 404;
168
+ }
169
+ else if (errorMessage.includes('API key not found')) {
170
+ statusCode = 503; // Service unavailable
171
+ }
172
+ else if (errorMessage.includes('exceeds maximum length')) {
173
+ statusCode = 400;
174
+ }
175
+ res.status(statusCode).json({
176
+ success: false,
177
+ message: errorMessage,
178
+ });
179
+ }
180
+ });
181
+ /**
182
+ * POST /api/tts/generate-base64
183
+ * Generate speech from text and return as base64 encoded string
184
+ * Useful for frontend playback without streaming
185
+ */
186
+ router.post('/generate-base64', ttsRateLimiter, async (req, res) => {
187
+ try {
188
+ const { model, input, voice, response_format, speed } = req.body;
189
+ // Validate required fields
190
+ if (!model || typeof model !== 'string') {
191
+ res.status(400).json({
192
+ success: false,
193
+ message: 'Model is required and must be a string',
194
+ });
195
+ return;
196
+ }
197
+ if (!input || typeof input !== 'string') {
198
+ res.status(400).json({
199
+ success: false,
200
+ message: 'Input text is required and must be a string',
201
+ });
202
+ return;
203
+ }
204
+ if (input.length === 0) {
205
+ res.status(400).json({
206
+ success: false,
207
+ message: 'Input text cannot be empty',
208
+ });
209
+ return;
210
+ }
211
+ // Validate optional parameters
212
+ if (speed !== undefined) {
213
+ const speedNum = Number(speed);
214
+ if (isNaN(speedNum) || speedNum < 0.25 || speedNum > 4.0) {
215
+ res.status(400).json({
216
+ success: false,
217
+ message: 'Speed must be a number between 0.25 and 4.0',
218
+ });
219
+ return;
220
+ }
221
+ }
222
+ const validFormats = ['mp3', 'opus', 'aac', 'flac', 'wav', 'pcm'];
223
+ if (response_format && !validFormats.includes(response_format)) {
224
+ res.status(400).json({
225
+ success: false,
226
+ message: `Invalid response_format. Must be one of: ${validFormats.join(', ')}`,
227
+ });
228
+ return;
229
+ }
230
+ // Execute TTS request
231
+ const audioBuffer = await pluginService.executeTTSRequest(model, input, {
232
+ voice,
233
+ response_format,
234
+ speed,
235
+ });
236
+ const format = response_format || 'mp3';
237
+ // Determine MIME type for data URL
238
+ const mimeTypeMap = {
239
+ mp3: 'audio/mpeg',
240
+ opus: 'audio/opus',
241
+ aac: 'audio/aac',
242
+ flac: 'audio/flac',
243
+ wav: 'audio/wav',
244
+ pcm: 'audio/pcm',
245
+ };
246
+ const mimeType = mimeTypeMap[format] || 'audio/mpeg';
247
+ // Return base64 encoded audio
248
+ res.json({
249
+ success: true,
250
+ data: {
251
+ audio: audioBuffer.toString('base64'),
252
+ format,
253
+ mimeType,
254
+ size: audioBuffer.length,
255
+ },
256
+ });
257
+ }
258
+ catch (error) {
259
+ console.error('TTS generation failed:', error);
260
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error';
261
+ let statusCode = 500;
262
+ if (errorMessage.includes('No TTS plugin found')) {
263
+ statusCode = 404;
264
+ }
265
+ else if (errorMessage.includes('API key not found')) {
266
+ statusCode = 503;
267
+ }
268
+ else if (errorMessage.includes('exceeds maximum length')) {
269
+ statusCode = 400;
270
+ }
271
+ res.status(statusCode).json({
272
+ success: false,
273
+ message: errorMessage,
274
+ });
275
+ }
276
+ });
277
+ /**
278
+ * GET /api/tts/plugins
279
+ * Get all plugins that support TTS capability
280
+ */
281
+ router.get('/plugins', async (_req, res) => {
282
+ try {
283
+ const plugins = pluginService.getPluginsByCapability('tts');
284
+ res.json({
285
+ success: true,
286
+ data: plugins.map(p => ({
287
+ id: p.id,
288
+ name: p.name,
289
+ models: p.capabilities?.tts?.model_map ||
290
+ (p.type === 'tts' ? p.model_map : []),
291
+ config: p.capabilities?.tts?.config,
292
+ })),
293
+ });
294
+ }
295
+ catch (error) {
296
+ console.error('Failed to get TTS plugins:', error);
297
+ res.status(500).json({
298
+ success: false,
299
+ message: 'Failed to get TTS plugins',
300
+ });
301
+ }
302
+ });
303
+ export default router;
304
+ //# sourceMappingURL=tts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tts.js","sourceRoot":"","sources":["../../src/routes/tts.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ declare const router: import("express-serve-static-core").Router;
2
+ export default router;
3
+ //# sourceMappingURL=users.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"users.d.ts","sourceRoot":"","sources":["../../src/routes/users.ts"],"names":[],"mappings":"AA0BA,QAAA,MAAM,MAAM,4CAAmB,CAAC;AAmRhC,eAAe,MAAM,CAAC"}