libre-webui 0.25.0 → 0.27.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 (588) hide show
  1. package/README.md +32 -22
  2. package/backend/dist/index.d.ts.map +1 -1
  3. package/backend/dist/index.js +33 -4
  4. package/backend/dist/index.js.map +1 -1
  5. package/backend/dist/middleware/auth.d.ts +7 -0
  6. package/backend/dist/middleware/auth.d.ts.map +1 -1
  7. package/backend/dist/middleware/auth.js +26 -0
  8. package/backend/dist/middleware/auth.js.map +1 -1
  9. package/backend/dist/middleware/index.d.ts +20 -0
  10. package/backend/dist/middleware/index.d.ts.map +1 -1
  11. package/backend/dist/middleware/index.js +105 -2
  12. package/backend/dist/middleware/index.js.map +1 -1
  13. package/backend/dist/models/personaModel.d.ts.map +1 -1
  14. package/backend/dist/models/personaModel.js +2 -0
  15. package/backend/dist/models/personaModel.js.map +1 -1
  16. package/backend/dist/observability/otel.d.ts +40 -0
  17. package/backend/dist/observability/otel.d.ts.map +1 -0
  18. package/backend/dist/observability/otel.js +337 -0
  19. package/backend/dist/observability/otel.js.map +1 -0
  20. package/backend/dist/observability/requestContext.d.ts +14 -0
  21. package/backend/dist/observability/requestContext.d.ts.map +1 -0
  22. package/backend/dist/observability/requestContext.js +21 -0
  23. package/backend/dist/observability/requestContext.js.map +1 -0
  24. package/backend/dist/persistence/chatGenerationTypes.d.ts +9 -0
  25. package/backend/dist/persistence/chatGenerationTypes.d.ts.map +1 -1
  26. package/backend/dist/persistence/extensionTypes.d.ts +13 -0
  27. package/backend/dist/persistence/extensionTypes.d.ts.map +1 -1
  28. package/backend/dist/persistence/extensionTypes.js.map +1 -1
  29. package/backend/dist/persistence/index.d.ts +1 -1
  30. package/backend/dist/persistence/index.d.ts.map +1 -1
  31. package/backend/dist/persistence/index.js.map +1 -1
  32. package/backend/dist/persistence/postgresAgentFoundationMigration.d.ts +9 -0
  33. package/backend/dist/persistence/postgresAgentFoundationMigration.d.ts.map +1 -0
  34. package/backend/dist/persistence/postgresAgentFoundationMigration.js +164 -0
  35. package/backend/dist/persistence/postgresAgentFoundationMigration.js.map +1 -0
  36. package/backend/dist/persistence/postgresExtensionRepositories.d.ts.map +1 -1
  37. package/backend/dist/persistence/postgresExtensionRepositories.js +46 -2
  38. package/backend/dist/persistence/postgresExtensionRepositories.js.map +1 -1
  39. package/backend/dist/persistence/postgresMediaEnterpriseOpsMigration.d.ts +10 -0
  40. package/backend/dist/persistence/postgresMediaEnterpriseOpsMigration.d.ts.map +1 -0
  41. package/backend/dist/persistence/postgresMediaEnterpriseOpsMigration.js +148 -0
  42. package/backend/dist/persistence/postgresMediaEnterpriseOpsMigration.js.map +1 -0
  43. package/backend/dist/persistence/postgresMfaPushRecoveryMigration.d.ts +9 -0
  44. package/backend/dist/persistence/postgresMfaPushRecoveryMigration.d.ts.map +1 -0
  45. package/backend/dist/persistence/postgresMfaPushRecoveryMigration.js +107 -0
  46. package/backend/dist/persistence/postgresMfaPushRecoveryMigration.js.map +1 -0
  47. package/backend/dist/persistence/postgresMigrationRegistry.d.ts.map +1 -1
  48. package/backend/dist/persistence/postgresMigrationRegistry.js +12 -0
  49. package/backend/dist/persistence/postgresMigrationRegistry.js.map +1 -1
  50. package/backend/dist/persistence/postgresNotesV2Migration.d.ts +4 -0
  51. package/backend/dist/persistence/postgresNotesV2Migration.d.ts.map +1 -0
  52. package/backend/dist/persistence/postgresNotesV2Migration.js +57 -0
  53. package/backend/dist/persistence/postgresNotesV2Migration.js.map +1 -0
  54. package/backend/dist/persistence/postgresResourceRepositories.d.ts.map +1 -1
  55. package/backend/dist/persistence/postgresResourceRepositories.js +1930 -133
  56. package/backend/dist/persistence/postgresResourceRepositories.js.map +1 -1
  57. package/backend/dist/persistence/postgresSecurityRepositories.d.ts.map +1 -1
  58. package/backend/dist/persistence/postgresSecurityRepositories.js +150 -0
  59. package/backend/dist/persistence/postgresSecurityRepositories.js.map +1 -1
  60. package/backend/dist/persistence/postgresSkillFilesMigration.d.ts +9 -0
  61. package/backend/dist/persistence/postgresSkillFilesMigration.d.ts.map +1 -0
  62. package/backend/dist/persistence/postgresSkillFilesMigration.js +50 -0
  63. package/backend/dist/persistence/postgresSkillFilesMigration.js.map +1 -0
  64. package/backend/dist/persistence/postgresTeamCollaborationMigration.d.ts +10 -0
  65. package/backend/dist/persistence/postgresTeamCollaborationMigration.d.ts.map +1 -0
  66. package/backend/dist/persistence/postgresTeamCollaborationMigration.js +161 -0
  67. package/backend/dist/persistence/postgresTeamCollaborationMigration.js.map +1 -0
  68. package/backend/dist/persistence/resourceTypes.d.ts +600 -3
  69. package/backend/dist/persistence/resourceTypes.d.ts.map +1 -1
  70. package/backend/dist/persistence/resourceTypes.js.map +1 -1
  71. package/backend/dist/persistence/securityTypes.d.ts +59 -0
  72. package/backend/dist/persistence/securityTypes.d.ts.map +1 -1
  73. package/backend/dist/persistence/sqliteExtensionRepositories.d.ts.map +1 -1
  74. package/backend/dist/persistence/sqliteExtensionRepositories.js +26 -4
  75. package/backend/dist/persistence/sqliteExtensionRepositories.js.map +1 -1
  76. package/backend/dist/persistence/sqliteMigrations.d.ts +10 -0
  77. package/backend/dist/persistence/sqliteMigrations.d.ts.map +1 -1
  78. package/backend/dist/persistence/sqliteMigrations.js +1492 -131
  79. package/backend/dist/persistence/sqliteMigrations.js.map +1 -1
  80. package/backend/dist/persistence/sqliteResourceRepositories.d.ts.map +1 -1
  81. package/backend/dist/persistence/sqliteResourceRepositories.js +1657 -134
  82. package/backend/dist/persistence/sqliteResourceRepositories.js.map +1 -1
  83. package/backend/dist/persistence/sqliteSecurityRepositories.d.ts.map +1 -1
  84. package/backend/dist/persistence/sqliteSecurityRepositories.js +134 -0
  85. package/backend/dist/persistence/sqliteSecurityRepositories.js.map +1 -1
  86. package/backend/dist/persistence/sqliteToPostgresMigration.d.ts.map +1 -1
  87. package/backend/dist/persistence/sqliteToPostgresMigration.js +302 -3
  88. package/backend/dist/persistence/sqliteToPostgresMigration.js.map +1 -1
  89. package/backend/dist/platform/jobs/domainJobContracts.d.ts +10 -0
  90. package/backend/dist/platform/jobs/domainJobContracts.d.ts.map +1 -1
  91. package/backend/dist/platform/jobs/domainJobContracts.js +10 -0
  92. package/backend/dist/platform/jobs/domainJobContracts.js.map +1 -1
  93. package/backend/dist/platform/jobs/domainJobHandlers.d.ts.map +1 -1
  94. package/backend/dist/platform/jobs/domainJobHandlers.js +374 -4
  95. package/backend/dist/platform/jobs/domainJobHandlers.js.map +1 -1
  96. package/backend/dist/platform/jobs/embeddedDurableJobWorker.d.ts.map +1 -1
  97. package/backend/dist/platform/jobs/embeddedDurableJobWorker.js +4 -2
  98. package/backend/dist/platform/jobs/embeddedDurableJobWorker.js.map +1 -1
  99. package/backend/dist/platform/jobs/postgresDurableJobWorker.d.ts.map +1 -1
  100. package/backend/dist/platform/jobs/postgresDurableJobWorker.js +4 -2
  101. package/backend/dist/platform/jobs/postgresDurableJobWorker.js.map +1 -1
  102. package/backend/dist/platform/storage/pgVectorStore.d.ts +2 -1
  103. package/backend/dist/platform/storage/pgVectorStore.d.ts.map +1 -1
  104. package/backend/dist/platform/storage/pgVectorStore.js +51 -0
  105. package/backend/dist/platform/storage/pgVectorStore.js.map +1 -1
  106. package/backend/dist/platform/storage/platformDomainRepositories.d.ts +8 -2
  107. package/backend/dist/platform/storage/platformDomainRepositories.d.ts.map +1 -1
  108. package/backend/dist/platform/storage/postgresPlatformDomainRepositories.d.ts.map +1 -1
  109. package/backend/dist/platform/storage/postgresPlatformDomainRepositories.js +25 -4
  110. package/backend/dist/platform/storage/postgresPlatformDomainRepositories.js.map +1 -1
  111. package/backend/dist/platform/storage/sqliteEncryptedVectorStore.d.ts +2 -1
  112. package/backend/dist/platform/storage/sqliteEncryptedVectorStore.d.ts.map +1 -1
  113. package/backend/dist/platform/storage/sqliteEncryptedVectorStore.js +35 -0
  114. package/backend/dist/platform/storage/sqliteEncryptedVectorStore.js.map +1 -1
  115. package/backend/dist/platform/storage/sqlitePlatformDomainRepositories.d.ts.map +1 -1
  116. package/backend/dist/platform/storage/sqlitePlatformDomainRepositories.js +26 -3
  117. package/backend/dist/platform/storage/sqlitePlatformDomainRepositories.js.map +1 -1
  118. package/backend/dist/platform/storage/vectorStore.d.ts +14 -0
  119. package/backend/dist/platform/storage/vectorStore.d.ts.map +1 -1
  120. package/backend/dist/platform/storage/vectorStore.js.map +1 -1
  121. package/backend/dist/routes/access.d.ts.map +1 -1
  122. package/backend/dist/routes/access.js +84 -3
  123. package/backend/dist/routes/access.js.map +1 -1
  124. package/backend/dist/routes/auth.d.ts.map +1 -1
  125. package/backend/dist/routes/auth.js +419 -1
  126. package/backend/dist/routes/auth.js.map +1 -1
  127. package/backend/dist/routes/calendar.d.ts.map +1 -1
  128. package/backend/dist/routes/calendar.js +125 -22
  129. package/backend/dist/routes/calendar.js.map +1 -1
  130. package/backend/dist/routes/channels.d.ts +3 -0
  131. package/backend/dist/routes/channels.d.ts.map +1 -0
  132. package/backend/dist/routes/channels.js +447 -0
  133. package/backend/dist/routes/channels.js.map +1 -0
  134. package/backend/dist/routes/chat.d.ts.map +1 -1
  135. package/backend/dist/routes/chat.js +195 -7
  136. package/backend/dist/routes/chat.js.map +1 -1
  137. package/backend/dist/routes/costs.d.ts +3 -0
  138. package/backend/dist/routes/costs.d.ts.map +1 -0
  139. package/backend/dist/routes/costs.js +191 -0
  140. package/backend/dist/routes/costs.js.map +1 -0
  141. package/backend/dist/routes/documents.d.ts.map +1 -1
  142. package/backend/dist/routes/documents.js +68 -21
  143. package/backend/dist/routes/documents.js.map +1 -1
  144. package/backend/dist/routes/evaluations.d.ts +3 -0
  145. package/backend/dist/routes/evaluations.d.ts.map +1 -0
  146. package/backend/dist/routes/evaluations.js +352 -0
  147. package/backend/dist/routes/evaluations.js.map +1 -0
  148. package/backend/dist/routes/imageGen.d.ts.map +1 -1
  149. package/backend/dist/routes/imageGen.js +2 -1
  150. package/backend/dist/routes/imageGen.js.map +1 -1
  151. package/backend/dist/routes/media.d.ts.map +1 -1
  152. package/backend/dist/routes/media.js +228 -7
  153. package/backend/dist/routes/media.js.map +1 -1
  154. package/backend/dist/routes/notes.d.ts.map +1 -1
  155. package/backend/dist/routes/notes.js +149 -36
  156. package/backend/dist/routes/notes.js.map +1 -1
  157. package/backend/dist/routes/notifications.d.ts +3 -0
  158. package/backend/dist/routes/notifications.d.ts.map +1 -0
  159. package/backend/dist/routes/notifications.js +213 -0
  160. package/backend/dist/routes/notifications.js.map +1 -0
  161. package/backend/dist/routes/openaiCompat.d.ts +3 -0
  162. package/backend/dist/routes/openaiCompat.d.ts.map +1 -0
  163. package/backend/dist/routes/openaiCompat.js +314 -0
  164. package/backend/dist/routes/openaiCompat.js.map +1 -0
  165. package/backend/dist/routes/personas.js +1 -1
  166. package/backend/dist/routes/personas.js.map +1 -1
  167. package/backend/dist/routes/prompts.d.ts +3 -0
  168. package/backend/dist/routes/prompts.d.ts.map +1 -0
  169. package/backend/dist/routes/prompts.js +173 -0
  170. package/backend/dist/routes/prompts.js.map +1 -0
  171. package/backend/dist/routes/push.d.ts +3 -0
  172. package/backend/dist/routes/push.d.ts.map +1 -0
  173. package/backend/dist/routes/push.js +105 -0
  174. package/backend/dist/routes/push.js.map +1 -0
  175. package/backend/dist/routes/recovery.d.ts +3 -0
  176. package/backend/dist/routes/recovery.d.ts.map +1 -0
  177. package/backend/dist/routes/recovery.js +83 -0
  178. package/backend/dist/routes/recovery.js.map +1 -0
  179. package/backend/dist/routes/search.d.ts.map +1 -1
  180. package/backend/dist/routes/search.js +29 -1
  181. package/backend/dist/routes/search.js.map +1 -1
  182. package/backend/dist/routes/skills.d.ts +3 -0
  183. package/backend/dist/routes/skills.d.ts.map +1 -0
  184. package/backend/dist/routes/skills.js +246 -0
  185. package/backend/dist/routes/skills.js.map +1 -0
  186. package/backend/dist/routes/stt.d.ts.map +1 -1
  187. package/backend/dist/routes/stt.js +2 -1
  188. package/backend/dist/routes/stt.js.map +1 -1
  189. package/backend/dist/routes/tools.d.ts +3 -0
  190. package/backend/dist/routes/tools.d.ts.map +1 -0
  191. package/backend/dist/routes/tools.js +359 -0
  192. package/backend/dist/routes/tools.js.map +1 -0
  193. package/backend/dist/routes/tts.d.ts.map +1 -1
  194. package/backend/dist/routes/tts.js +63 -8
  195. package/backend/dist/routes/tts.js.map +1 -1
  196. package/backend/dist/routes/users.d.ts.map +1 -1
  197. package/backend/dist/routes/users.js +35 -0
  198. package/backend/dist/routes/users.js.map +1 -1
  199. package/backend/dist/routes/voiceAccess.d.ts +3 -0
  200. package/backend/dist/routes/voiceAccess.d.ts.map +1 -0
  201. package/backend/dist/routes/voiceAccess.js +102 -0
  202. package/backend/dist/routes/voiceAccess.js.map +1 -0
  203. package/backend/dist/services/apiTokenService.d.ts +2 -2
  204. package/backend/dist/services/apiTokenService.d.ts.map +1 -1
  205. package/backend/dist/services/apiTokenService.js +7 -0
  206. package/backend/dist/services/apiTokenService.js.map +1 -1
  207. package/backend/dist/services/authService.d.ts +6 -0
  208. package/backend/dist/services/authService.d.ts.map +1 -1
  209. package/backend/dist/services/authService.js +9 -0
  210. package/backend/dist/services/authService.js.map +1 -1
  211. package/backend/dist/services/authorizationService.d.ts +8 -4
  212. package/backend/dist/services/authorizationService.d.ts.map +1 -1
  213. package/backend/dist/services/authorizationService.js +31 -1
  214. package/backend/dist/services/authorizationService.js.map +1 -1
  215. package/backend/dist/services/automationSchedulerService.d.ts.map +1 -1
  216. package/backend/dist/services/automationSchedulerService.js +40 -3
  217. package/backend/dist/services/automationSchedulerService.js.map +1 -1
  218. package/backend/dist/services/automationService.d.ts +4 -1
  219. package/backend/dist/services/automationService.d.ts.map +1 -1
  220. package/backend/dist/services/automationService.js +25 -2
  221. package/backend/dist/services/automationService.js.map +1 -1
  222. package/backend/dist/services/builtinToolsService.d.ts +20 -0
  223. package/backend/dist/services/builtinToolsService.d.ts.map +1 -0
  224. package/backend/dist/services/builtinToolsService.js +661 -0
  225. package/backend/dist/services/builtinToolsService.js.map +1 -0
  226. package/backend/dist/services/calendarService.d.ts +74 -0
  227. package/backend/dist/services/calendarService.d.ts.map +1 -0
  228. package/backend/dist/services/calendarService.js +339 -0
  229. package/backend/dist/services/calendarService.js.map +1 -0
  230. package/backend/dist/services/channelService.d.ts +195 -0
  231. package/backend/dist/services/channelService.d.ts.map +1 -0
  232. package/backend/dist/services/channelService.js +1057 -0
  233. package/backend/dist/services/channelService.js.map +1 -0
  234. package/backend/dist/services/chatRequestService.d.ts.map +1 -1
  235. package/backend/dist/services/chatRequestService.js +29 -1
  236. package/backend/dist/services/chatRequestService.js.map +1 -1
  237. package/backend/dist/services/chatService.d.ts +61 -1
  238. package/backend/dist/services/chatService.d.ts.map +1 -1
  239. package/backend/dist/services/chatService.js +218 -1
  240. package/backend/dist/services/chatService.js.map +1 -1
  241. package/backend/dist/services/chatToolRuntimeService.d.ts +55 -0
  242. package/backend/dist/services/chatToolRuntimeService.d.ts.map +1 -0
  243. package/backend/dist/services/chatToolRuntimeService.js +389 -0
  244. package/backend/dist/services/chatToolRuntimeService.js.map +1 -0
  245. package/backend/dist/services/costGovernanceService.d.ts +102 -0
  246. package/backend/dist/services/costGovernanceService.d.ts.map +1 -0
  247. package/backend/dist/services/costGovernanceService.js +463 -0
  248. package/backend/dist/services/costGovernanceService.js.map +1 -0
  249. package/backend/dist/services/dataArchiveService.d.ts +6 -0
  250. package/backend/dist/services/dataArchiveService.d.ts.map +1 -1
  251. package/backend/dist/services/dataArchiveService.js +26 -4
  252. package/backend/dist/services/dataArchiveService.js.map +1 -1
  253. package/backend/dist/services/documentMediaExtractionService.d.ts +40 -0
  254. package/backend/dist/services/documentMediaExtractionService.d.ts.map +1 -0
  255. package/backend/dist/services/documentMediaExtractionService.js +157 -0
  256. package/backend/dist/services/documentMediaExtractionService.js.map +1 -0
  257. package/backend/dist/services/documentService.d.ts +64 -1
  258. package/backend/dist/services/documentService.d.ts.map +1 -1
  259. package/backend/dist/services/documentService.js +342 -83
  260. package/backend/dist/services/documentService.js.map +1 -1
  261. package/backend/dist/services/durableChatGenerationService.d.ts +9 -0
  262. package/backend/dist/services/durableChatGenerationService.d.ts.map +1 -1
  263. package/backend/dist/services/durableChatGenerationService.js +152 -11
  264. package/backend/dist/services/durableChatGenerationService.js.map +1 -1
  265. package/backend/dist/services/encryptionService.d.ts +6 -0
  266. package/backend/dist/services/encryptionService.d.ts.map +1 -1
  267. package/backend/dist/services/encryptionService.js +12 -0
  268. package/backend/dist/services/encryptionService.js.map +1 -1
  269. package/backend/dist/services/evaluationService.d.ts +111 -0
  270. package/backend/dist/services/evaluationService.d.ts.map +1 -0
  271. package/backend/dist/services/evaluationService.js +403 -0
  272. package/backend/dist/services/evaluationService.js.map +1 -0
  273. package/backend/dist/services/galleryService.d.ts +6 -0
  274. package/backend/dist/services/galleryService.d.ts.map +1 -1
  275. package/backend/dist/services/galleryService.js +26 -0
  276. package/backend/dist/services/galleryService.js.map +1 -1
  277. package/backend/dist/services/mcpClientService.d.ts +29 -0
  278. package/backend/dist/services/mcpClientService.d.ts.map +1 -0
  279. package/backend/dist/services/mcpClientService.js +189 -0
  280. package/backend/dist/services/mcpClientService.js.map +1 -0
  281. package/backend/dist/services/mfaService.d.ts +64 -0
  282. package/backend/dist/services/mfaService.d.ts.map +1 -0
  283. package/backend/dist/services/mfaService.js +263 -0
  284. package/backend/dist/services/mfaService.js.map +1 -0
  285. package/backend/dist/services/noteService.d.ts +71 -0
  286. package/backend/dist/services/noteService.d.ts.map +1 -0
  287. package/backend/dist/services/noteService.js +397 -0
  288. package/backend/dist/services/noteService.js.map +1 -0
  289. package/backend/dist/services/notificationService.d.ts +60 -0
  290. package/backend/dist/services/notificationService.d.ts.map +1 -0
  291. package/backend/dist/services/notificationService.js +340 -0
  292. package/backend/dist/services/notificationService.js.map +1 -0
  293. package/backend/dist/services/openApiToolService.d.ts +38 -0
  294. package/backend/dist/services/openApiToolService.d.ts.map +1 -0
  295. package/backend/dist/services/openApiToolService.js +254 -0
  296. package/backend/dist/services/openApiToolService.js.map +1 -0
  297. package/backend/dist/services/personaService.d.ts +18 -2
  298. package/backend/dist/services/personaService.d.ts.map +1 -1
  299. package/backend/dist/services/personaService.js +113 -4
  300. package/backend/dist/services/personaService.js.map +1 -1
  301. package/backend/dist/services/pluginImageGenerationService.d.ts +19 -0
  302. package/backend/dist/services/pluginImageGenerationService.d.ts.map +1 -1
  303. package/backend/dist/services/pluginImageGenerationService.js +121 -0
  304. package/backend/dist/services/pluginImageGenerationService.js.map +1 -1
  305. package/backend/dist/services/pluginService.d.ts +7 -0
  306. package/backend/dist/services/pluginService.d.ts.map +1 -1
  307. package/backend/dist/services/pluginService.js +8 -2
  308. package/backend/dist/services/pluginService.js.map +1 -1
  309. package/backend/dist/services/preferencesService.d.ts +1 -1
  310. package/backend/dist/services/preferencesService.d.ts.map +1 -1
  311. package/backend/dist/services/preferencesService.js +1 -0
  312. package/backend/dist/services/preferencesService.js.map +1 -1
  313. package/backend/dist/services/promptService.d.ts +74 -0
  314. package/backend/dist/services/promptService.d.ts.map +1 -0
  315. package/backend/dist/services/promptService.js +513 -0
  316. package/backend/dist/services/promptService.js.map +1 -0
  317. package/backend/dist/services/recoveryDrillService.d.ts +57 -0
  318. package/backend/dist/services/recoveryDrillService.d.ts.map +1 -0
  319. package/backend/dist/services/recoveryDrillService.js +363 -0
  320. package/backend/dist/services/recoveryDrillService.js.map +1 -0
  321. package/backend/dist/services/resourceGrantService.d.ts.map +1 -1
  322. package/backend/dist/services/resourceGrantService.js +62 -17
  323. package/backend/dist/services/resourceGrantService.js.map +1 -1
  324. package/backend/dist/services/searchService.d.ts +29 -0
  325. package/backend/dist/services/searchService.d.ts.map +1 -0
  326. package/backend/dist/services/searchService.js +0 -0
  327. package/backend/dist/services/searchService.js.map +1 -0
  328. package/backend/dist/services/securityAuditService.d.ts.map +1 -1
  329. package/backend/dist/services/securityAuditService.js +2 -1
  330. package/backend/dist/services/securityAuditService.js.map +1 -1
  331. package/backend/dist/services/sharedResourceAccess.d.ts +25 -0
  332. package/backend/dist/services/sharedResourceAccess.d.ts.map +1 -0
  333. package/backend/dist/services/sharedResourceAccess.js +59 -0
  334. package/backend/dist/services/sharedResourceAccess.js.map +1 -0
  335. package/backend/dist/services/skillService.d.ts +137 -0
  336. package/backend/dist/services/skillService.d.ts.map +1 -0
  337. package/backend/dist/services/skillService.js +852 -0
  338. package/backend/dist/services/skillService.js.map +1 -0
  339. package/backend/dist/services/toolAccessService.d.ts +9 -0
  340. package/backend/dist/services/toolAccessService.d.ts.map +1 -0
  341. package/backend/dist/services/toolAccessService.js +60 -0
  342. package/backend/dist/services/toolAccessService.js.map +1 -0
  343. package/backend/dist/services/toolApprovalService.d.ts +34 -0
  344. package/backend/dist/services/toolApprovalService.d.ts.map +1 -0
  345. package/backend/dist/services/toolApprovalService.js +188 -0
  346. package/backend/dist/services/toolApprovalService.js.map +1 -0
  347. package/backend/dist/services/toolGatewayService.d.ts +53 -0
  348. package/backend/dist/services/toolGatewayService.d.ts.map +1 -0
  349. package/backend/dist/services/toolGatewayService.js +249 -0
  350. package/backend/dist/services/toolGatewayService.js.map +1 -0
  351. package/backend/dist/services/toolServerService.d.ts +57 -0
  352. package/backend/dist/services/toolServerService.d.ts.map +1 -0
  353. package/backend/dist/services/toolServerService.js +521 -0
  354. package/backend/dist/services/toolServerService.js.map +1 -0
  355. package/backend/dist/services/voiceAccessService.d.ts +10 -0
  356. package/backend/dist/services/voiceAccessService.d.ts.map +1 -0
  357. package/backend/dist/services/voiceAccessService.js +74 -0
  358. package/backend/dist/services/voiceAccessService.js.map +1 -0
  359. package/backend/dist/services/voiceProfileService.d.ts +20 -0
  360. package/backend/dist/services/voiceProfileService.d.ts.map +1 -1
  361. package/backend/dist/services/voiceProfileService.js +60 -0
  362. package/backend/dist/services/voiceProfileService.js.map +1 -1
  363. package/backend/dist/services/webPushService.d.ts +71 -0
  364. package/backend/dist/services/webPushService.d.ts.map +1 -0
  365. package/backend/dist/services/webPushService.js +328 -0
  366. package/backend/dist/services/webPushService.js.map +1 -0
  367. package/backend/dist/services/webauthnService.d.ts +58 -0
  368. package/backend/dist/services/webauthnService.d.ts.map +1 -0
  369. package/backend/dist/services/webauthnService.js +300 -0
  370. package/backend/dist/services/webauthnService.js.map +1 -0
  371. package/backend/dist/storage.d.ts +28 -1
  372. package/backend/dist/storage.d.ts.map +1 -1
  373. package/backend/dist/storage.js +100 -1
  374. package/backend/dist/storage.js.map +1 -1
  375. package/backend/dist/storageMappers.d.ts +2 -2
  376. package/backend/dist/storageMappers.d.ts.map +1 -1
  377. package/backend/dist/storageMappers.js.map +1 -1
  378. package/backend/dist/types/index.d.ts +199 -3
  379. package/backend/dist/types/index.d.ts.map +1 -1
  380. package/backend/dist/types/index.js.map +1 -1
  381. package/backend/dist/types/tools.d.ts +137 -0
  382. package/backend/dist/types/tools.d.ts.map +1 -0
  383. package/backend/dist/types/tools.js +25 -0
  384. package/backend/dist/types/tools.js.map +1 -0
  385. package/backend/dist/utils/chatDocumentContext.d.ts +26 -1
  386. package/backend/dist/utils/chatDocumentContext.d.ts.map +1 -1
  387. package/backend/dist/utils/chatDocumentContext.js +87 -18
  388. package/backend/dist/utils/chatDocumentContext.js.map +1 -1
  389. package/backend/dist/utils/documentExtraction.d.ts +97 -0
  390. package/backend/dist/utils/documentExtraction.d.ts.map +1 -0
  391. package/backend/dist/utils/documentExtraction.js +651 -0
  392. package/backend/dist/utils/documentExtraction.js.map +1 -0
  393. package/backend/dist/utils/hybridRetrieval.d.ts +34 -0
  394. package/backend/dist/utils/hybridRetrieval.d.ts.map +1 -0
  395. package/backend/dist/utils/hybridRetrieval.js +119 -0
  396. package/backend/dist/utils/hybridRetrieval.js.map +1 -0
  397. package/backend/dist/utils/icsCalendar.d.ts +27 -0
  398. package/backend/dist/utils/icsCalendar.d.ts.map +1 -0
  399. package/backend/dist/utils/icsCalendar.js +313 -0
  400. package/backend/dist/utils/icsCalendar.js.map +1 -0
  401. package/backend/dist/utils/imageEditUpload.d.ts +29 -0
  402. package/backend/dist/utils/imageEditUpload.d.ts.map +1 -0
  403. package/backend/dist/utils/imageEditUpload.js +82 -0
  404. package/backend/dist/utils/imageEditUpload.js.map +1 -0
  405. package/backend/dist/utils/logRedaction.d.ts +2 -0
  406. package/backend/dist/utils/logRedaction.d.ts.map +1 -0
  407. package/backend/dist/utils/logRedaction.js +66 -0
  408. package/backend/dist/utils/logRedaction.js.map +1 -0
  409. package/backend/dist/utils/logger.d.ts +3 -0
  410. package/backend/dist/utils/logger.d.ts.map +1 -1
  411. package/backend/dist/utils/logger.js +63 -20
  412. package/backend/dist/utils/logger.js.map +1 -1
  413. package/backend/dist/utils/pluginChatAdapter.d.ts +5 -1
  414. package/backend/dist/utils/pluginChatAdapter.d.ts.map +1 -1
  415. package/backend/dist/utils/pluginChatAdapter.js +83 -0
  416. package/backend/dist/utils/pluginChatAdapter.js.map +1 -1
  417. package/backend/dist/utils/pluginDefinitionTrust.js +1 -1
  418. package/backend/dist/utils/resourceLimits.d.ts +61 -2
  419. package/backend/dist/utils/resourceLimits.d.ts.map +1 -1
  420. package/backend/dist/utils/resourceLimits.js +59 -0
  421. package/backend/dist/utils/resourceLimits.js.map +1 -1
  422. package/backend/dist/utils/toolEgress.d.ts +23 -0
  423. package/backend/dist/utils/toolEgress.d.ts.map +1 -0
  424. package/backend/dist/utils/toolEgress.js +169 -0
  425. package/backend/dist/utils/toolEgress.js.map +1 -0
  426. package/backend/dist/utils/totp.d.ts +19 -0
  427. package/backend/dist/utils/totp.d.ts.map +1 -0
  428. package/backend/dist/utils/totp.js +117 -0
  429. package/backend/dist/utils/totp.js.map +1 -0
  430. package/backend/dist/utils/webauthn.d.ts +43 -0
  431. package/backend/dist/utils/webauthn.d.ts.map +1 -0
  432. package/backend/dist/utils/webauthn.js +294 -0
  433. package/backend/dist/utils/webauthn.js.map +1 -0
  434. package/backend/dist/utils/websocketMessages.d.ts +6 -0
  435. package/backend/dist/utils/websocketMessages.d.ts.map +1 -1
  436. package/backend/dist/utils/websocketMessages.js +8 -0
  437. package/backend/dist/utils/websocketMessages.js.map +1 -1
  438. package/backend/dist/utils/zipArchive.d.ts +32 -0
  439. package/backend/dist/utils/zipArchive.d.ts.map +1 -0
  440. package/backend/dist/utils/zipArchive.js +171 -0
  441. package/backend/dist/utils/zipArchive.js.map +1 -0
  442. package/backend/dist/websocketServer.d.ts.map +1 -1
  443. package/backend/dist/websocketServer.js +142 -35
  444. package/backend/dist/websocketServer.js.map +1 -1
  445. package/backend/package.json +1 -1
  446. package/frontend/dist/artifact-runtime/.build-fingerprint +1 -1
  447. package/frontend/dist/assets/index-DBAf_VaS.js +47 -0
  448. package/frontend/dist/assets/index-kn_Axjts.css +1 -0
  449. package/frontend/dist/fonts/jetbrains-mono-latin-400-normal.woff2 +0 -0
  450. package/frontend/dist/fonts/jetbrains-mono-latin-700-normal.woff2 +0 -0
  451. package/frontend/dist/fonts/jetbrains-mono.css +24 -0
  452. package/frontend/dist/index.html +27 -20
  453. package/frontend/dist/js/ArtifactContainer-C9zNtCay.js +1 -0
  454. package/frontend/dist/js/{ArtifactDemoPage-BeNs3gHp.js → ArtifactDemoPage-C-EBFBCt.js} +1 -1
  455. package/frontend/dist/js/ArtifactSandboxFrame-CTA1j_d1.js +111 -0
  456. package/frontend/dist/js/ArtifactSlideOutPanel-BOENbOiv.js +1 -0
  457. package/frontend/dist/js/AutomationsPage-C58MQ4te.js +1 -0
  458. package/frontend/dist/js/{Button-BPf_pOxH.js → Button-C0r3J9G_.js} +1 -1
  459. package/frontend/dist/js/CalendarPage-BcdAZ292.js +1 -0
  460. package/frontend/dist/js/ChannelsPage-DPr9Yajs.js +1 -0
  461. package/frontend/dist/js/ChatPage-DsbB748s.js +14 -0
  462. package/frontend/dist/js/EvaluationsPage-FWIJu2fI.js +2 -0
  463. package/frontend/dist/js/FirstTimeSetup-Cy-w6xko.js +1 -0
  464. package/frontend/dist/js/GalleryPage-DDAtxM-x.js +1 -0
  465. package/frontend/dist/js/HomePage-DLKwmE7n.js +1 -0
  466. package/frontend/dist/js/LibreClawPage-vKOj-9w9.js +1 -0
  467. package/frontend/dist/js/{ModelManagerModals-DcLGYN3l.js → ModelManagerModals-BY5TK38_.js} +1 -1
  468. package/frontend/dist/js/ModelSelector-CoCS6MZ9.js +1 -0
  469. package/frontend/dist/js/NotesPage-BElIpXgA.js +3 -0
  470. package/frontend/dist/js/OptimizedSyntaxHighlighter-xgyE3dRA.js +1 -0
  471. package/frontend/dist/js/PersonasPage-P40jVbfU.js +13 -0
  472. package/frontend/dist/js/PluginUsagePage-CKUEPCJN.js +1 -0
  473. package/frontend/dist/js/RichMessageContent-Bm2WaEGi.js +3 -0
  474. package/frontend/dist/js/SettingsModal-DxSGzx9A.js +19 -0
  475. package/frontend/dist/js/{SettingsToggle-woG_WebF.js → SettingsToggle-BIVyfGjl.js} +1 -1
  476. package/frontend/dist/js/SystemPage-BT07dTMT.js +1 -0
  477. package/frontend/dist/js/UserManagementPage-B9Vz5cm3.js +1 -0
  478. package/frontend/dist/js/WorkPage-qoN_e_jK.js +6 -0
  479. package/frontend/dist/js/api-D7Ff5M2Q.js +14 -0
  480. package/frontend/dist/js/appStore-DmV5wqDz.js +2 -0
  481. package/frontend/dist/js/ar-YHHTVP8f.js +2 -0
  482. package/frontend/dist/js/artifactHtml-DDmfpcB0.js +41 -0
  483. package/frontend/dist/js/{authStore-DbMdvNgJ.js → authStore-BYW8-kP6.js} +3 -3
  484. package/frontend/dist/js/{babel-BsYoxD-7.js → babel-DSqqk5kt.js} +1 -1
  485. package/frontend/dist/js/bn-C8VTxBVl.js +2 -0
  486. package/frontend/dist/js/chatStore-D-NTlArO.js +3 -0
  487. package/frontend/dist/js/{config-DSOYQ9a3.js → config-BqZ5304Q.js} +1 -1
  488. package/frontend/dist/js/cs-CCngB5fC.js +2 -0
  489. package/frontend/dist/js/da-CM2PP2ma.js +2 -0
  490. package/frontend/dist/js/de-BqVkD-dw.js +2 -0
  491. package/frontend/dist/js/es-BtWsWBjZ.js +2 -0
  492. package/frontend/dist/js/{estree-BcnBcOAx.js → estree-DPkpBuOU.js} +3 -3
  493. package/frontend/dist/js/evaluationsApi-Dnf2dTd-.js +1 -0
  494. package/frontend/dist/js/fr-C68w9abT.js +2 -0
  495. package/frontend/dist/js/hi-DtBlcyXZ.js +2 -0
  496. package/frontend/dist/js/{html-DkY55Jys.js → html-BpGUXG8E.js} +2 -2
  497. package/frontend/dist/js/id-BWzIu8tn.js +2 -0
  498. package/frontend/dist/js/is-yeFwu4dJ.js +2 -0
  499. package/frontend/dist/js/it-AxEMG8Jg.js +2 -0
  500. package/frontend/dist/js/ja-B-VyokB8.js +2 -0
  501. package/frontend/dist/js/ko-CvwzYr9k.js +2 -0
  502. package/frontend/dist/js/{markdown-IZSI9DXw.js → markdown-DCBRWJSK.js} +3 -3
  503. package/frontend/dist/js/markdown-core-BK7WVOb7.js +32 -0
  504. package/frontend/dist/js/{markdown-math-DK846gXU.js → markdown-math-e1ByS3KY.js} +5 -5
  505. package/frontend/dist/js/messageCodeStyles-BQwf7sSz.js +2 -0
  506. package/frontend/dist/js/ms-BhEwb4b7.js +2 -0
  507. package/frontend/dist/js/nl-Dq-QRx1L.js +2 -0
  508. package/frontend/dist/js/pl-BNEy8mQm.js +2 -0
  509. package/frontend/dist/js/{postcss-BJ0okz7n.js → postcss-Bg15EcFE.js} +1 -1
  510. package/frontend/dist/js/pt-_3Jl3FdY.js +2 -0
  511. package/frontend/dist/js/{react-vendor-C5yShNlM.js → react-vendor-BG_HPV6X.js} +1 -1
  512. package/frontend/dist/js/router-vendor-CbexJIsv.js +1 -0
  513. package/frontend/dist/js/ru-IhQiJ8ta.js +2 -0
  514. package/frontend/dist/js/{standalone-Csw3jfJ_.js → standalone-BFrK0R2A.js} +3 -3
  515. package/frontend/dist/js/sv-DWunXUNz.js +2 -0
  516. package/frontend/dist/js/{syntax-highlight-3EEX6CGL.js → syntax-highlight-P2zo9o06.js} +4 -4
  517. package/frontend/dist/js/th-DVnW2yyh.js +2 -0
  518. package/frontend/dist/js/tr-Do8CFmhR.js +2 -0
  519. package/frontend/dist/js/{typescript-CnF4UVx7.js → typescript-DYVyvmm_.js} +1 -1
  520. package/frontend/dist/js/ui-db9meqAB.js +2 -0
  521. package/frontend/dist/js/ui-vendor-C0DZ8-Cm.js +177 -0
  522. package/frontend/dist/js/uk-BNPKIZga.js +2 -0
  523. package/frontend/dist/js/{useTranslation-Bho4HCyg.js → useTranslation-5b5UhAc9.js} +1 -1
  524. package/frontend/dist/js/{utils-D9W1Lnkn.js → utils-BGrdX9ie.js} +1 -1
  525. package/frontend/dist/js/{utils-vendor-DWh39_3x.js → utils-vendor-9bQ62WeD.js} +1 -1
  526. package/frontend/dist/js/vi-CZMFo9je.js +2 -0
  527. package/frontend/dist/js/{workApi-C3uy9EDT.js → workApi-CcprMH_1.js} +3 -3
  528. package/frontend/dist/js/{yaml-DzT5hBSH.js → yaml-DUeWcOOH.js} +2 -2
  529. package/frontend/dist/js/zh-Pg0881v0.js +2 -0
  530. package/frontend/dist/manifest.webmanifest +32 -0
  531. package/frontend/dist/sw.js +125 -0
  532. package/package.json +2 -2
  533. package/plugins/openai.json +52 -9
  534. package/frontend/dist/assets/index-6o-Hc2wS.js +0 -41
  535. package/frontend/dist/assets/index-D-pM957b.css +0 -1
  536. package/frontend/dist/js/ArtifactContainer-CpUi6ekF.js +0 -1
  537. package/frontend/dist/js/ArtifactSandboxFrame-qsj_Y3LV.js +0 -151
  538. package/frontend/dist/js/ArtifactSlideOutPanel-CSFRluWA.js +0 -1
  539. package/frontend/dist/js/AutomationsPage-KUeWoZNv.js +0 -1
  540. package/frontend/dist/js/CalendarPage-D9I972w8.js +0 -1
  541. package/frontend/dist/js/ChatPage-CmBx4oAL.js +0 -16
  542. package/frontend/dist/js/FirstTimeSetup-Df0YJni3.js +0 -1
  543. package/frontend/dist/js/GalleryPage-bLCrdJN_.js +0 -1
  544. package/frontend/dist/js/HomePage-Uc6PEg-U.js +0 -1
  545. package/frontend/dist/js/LibreClawPage-CG63DHg1.js +0 -1
  546. package/frontend/dist/js/ModelSelector-yxJC64rM.js +0 -1
  547. package/frontend/dist/js/ModelsPage-1R_TxgmJ.js +0 -2
  548. package/frontend/dist/js/NotesPage-L65j5HoW.js +0 -1
  549. package/frontend/dist/js/OptimizedSyntaxHighlighter-Dz7D1LPB.js +0 -1
  550. package/frontend/dist/js/PersonasPage-CKeBpHIH.js +0 -13
  551. package/frontend/dist/js/PluginUsagePage-BX1SKMbW.js +0 -1
  552. package/frontend/dist/js/RichMessageContent-DiySVYGB.js +0 -3
  553. package/frontend/dist/js/SettingsModal-68SG1uZ2.js +0 -1
  554. package/frontend/dist/js/SystemPage-CytpZiQV.js +0 -1
  555. package/frontend/dist/js/UserManagementPage-BzJBvZiS.js +0 -1
  556. package/frontend/dist/js/WorkPage-C8gr0QJe.js +0 -6
  557. package/frontend/dist/js/api-BDtqBtqw.js +0 -14
  558. package/frontend/dist/js/appStore-0JnCUlEq.js +0 -2
  559. package/frontend/dist/js/ar-CSpi37Gr.js +0 -2
  560. package/frontend/dist/js/bn-CyH1BeDD.js +0 -2
  561. package/frontend/dist/js/chatStore-CHQ2uINS.js +0 -3
  562. package/frontend/dist/js/cs-Cv2NfRK5.js +0 -2
  563. package/frontend/dist/js/da-D6D6IvPK.js +0 -2
  564. package/frontend/dist/js/de-BNoJJTrT.js +0 -2
  565. package/frontend/dist/js/es-kzo9C7q_.js +0 -2
  566. package/frontend/dist/js/fr-CjHYvJRp.js +0 -2
  567. package/frontend/dist/js/hi-BU98AdCQ.js +0 -2
  568. package/frontend/dist/js/id-CpdedejX.js +0 -2
  569. package/frontend/dist/js/is-Cp5dDWBH.js +0 -2
  570. package/frontend/dist/js/it-CuH_cK4U.js +0 -2
  571. package/frontend/dist/js/ja-BWXXXiHn.js +0 -2
  572. package/frontend/dist/js/ko-DQgv2M1t.js +0 -2
  573. package/frontend/dist/js/markdown-core-BmPPZiuD.js +0 -31
  574. package/frontend/dist/js/messageCodeStyles-BFNR9Wv6.js +0 -2
  575. package/frontend/dist/js/ms-DCcRoIcX.js +0 -2
  576. package/frontend/dist/js/nl-CbKR1_EU.js +0 -2
  577. package/frontend/dist/js/pl-CRyJZccn.js +0 -2
  578. package/frontend/dist/js/pt-BXYmHFGH.js +0 -2
  579. package/frontend/dist/js/router-vendor-DGFGM3EP.js +0 -1
  580. package/frontend/dist/js/ru-M9SyZG4b.js +0 -2
  581. package/frontend/dist/js/sv-DJ486LTU.js +0 -2
  582. package/frontend/dist/js/th-Ch7gKtZv.js +0 -2
  583. package/frontend/dist/js/tr-ClehWhSC.js +0 -2
  584. package/frontend/dist/js/ui-CC-K19wO.js +0 -2
  585. package/frontend/dist/js/ui-vendor-B1UgO3vd.js +0 -177
  586. package/frontend/dist/js/uk-BqAd5zHF.js +0 -2
  587. package/frontend/dist/js/vi-D9gjlDVB.js +0 -2
  588. package/frontend/dist/js/zh-DKTyHkiR.js +0 -2
@@ -0,0 +1,3 @@
1
+ const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["js/api-D7Ff5M2Q.js","js/rolldown-runtime-hePW80VL.js","js/logger-DSXjF4ye.js","js/config-BqZ5304Q.js","js/workApi-CcprMH_1.js","js/router-vendor-CbexJIsv.js","js/markdown-core-BK7WVOb7.js","js/utils-vendor-9bQ62WeD.js","js/authStore-BYW8-kP6.js","js/appStore-DmV5wqDz.js"])))=>i.map(i=>d[i]);
2
+ import{a as e}from"./router-vendor-CbexJIsv.js";import{t}from"./i18next-DgmgtwsV.js";import{d as n,i as r,l as i}from"./utils-BGrdX9ie.js";import{fr as a}from"./ui-vendor-C0DZ8-Cm.js";import{o}from"./utils-vendor-9bQ62WeD.js";import{t as s}from"./logger-DSXjF4ye.js";import{M as c,c as l,m as u,u as ee,v as d}from"./api-D7Ff5M2Q.js";var f={type:`3rdParty`,init(e){n(e.options.react),i(e)}},{slice:p,forEach:m}=[];function h(e){return m.call(p.call(arguments,1),t=>{if(t)for(let n in t)e[n]===void 0&&(e[n]=t[n])}),e}function g(e){return typeof e==`string`&&[/<\s*script.*?>/i,/<\s*\/\s*script\s*>/i,/<\s*img.*?on\w+\s*=/i,/<\s*\w+\s*on\w+\s*=.*?>/i,/javascript\s*:/i,/vbscript\s*:/i,/expression\s*\(/i,/eval\s*\(/i,/alert\s*\(/i,/document\.cookie/i,/document\.write\s*\(/i,/window\.location/i,/innerHTML/i].some(t=>t.test(e))}var _=/^[\u0009\u0020-\u007e\u0080-\u00ff]+$/,v=function(e,t){let n=arguments.length>2&&arguments[2]!==void 0?arguments[2]:{path:`/`},r=`${e}=${encodeURIComponent(t)}`;if(n.maxAge>0){let e=n.maxAge-0;if(Number.isNaN(e))throw Error(`maxAge should be a Number`);r+=`; Max-Age=${Math.floor(e)}`}if(n.domain){if(!_.test(n.domain))throw TypeError(`option domain is invalid`);r+=`; Domain=${n.domain}`}if(n.path){if(!_.test(n.path))throw TypeError(`option path is invalid`);r+=`; Path=${n.path}`}if(n.expires){if(typeof n.expires.toUTCString!=`function`)throw TypeError(`option expires is invalid`);r+=`; Expires=${n.expires.toUTCString()}`}if(n.httpOnly&&(r+=`; HttpOnly`),n.secure&&(r+=`; Secure`),n.sameSite)switch(typeof n.sameSite==`string`?n.sameSite.toLowerCase():n.sameSite){case!0:r+=`; SameSite=Strict`;break;case`lax`:r+=`; SameSite=Lax`;break;case`strict`:r+=`; SameSite=Strict`;break;case`none`:r+=`; SameSite=None`;break;default:throw TypeError(`option sameSite is invalid`)}return n.partitioned&&(r+=`; Partitioned`),r},y={create(e,t,n,r){let i=arguments.length>4&&arguments[4]!==void 0?arguments[4]:{path:`/`,sameSite:`strict`};n&&(i.expires=new Date,i.expires.setTime(i.expires.getTime()+n*60*1e3)),r&&(i.domain=r),document.cookie=v(e,t,i)},read(e){let t=`${e}=`,n=document.cookie.split(`;`);for(let e=0;e<n.length;e++){let r=n[e];for(;r.charAt(0)===` `;)r=r.substring(1,r.length);if(r.indexOf(t)===0)return r.substring(t.length,r.length)}return null},remove(e,t){this.create(e,``,-1,t)}},te={name:`cookie`,lookup(e){let{lookupCookie:t}=e;if(t&&typeof document<`u`)return y.read(t)||void 0},cacheUserLanguage(e,t){let{lookupCookie:n,cookieMinutes:r,cookieDomain:i,cookieOptions:a}=t;n&&typeof document<`u`&&y.create(n,e,r,i,a)}},ne={name:`querystring`,lookup(e){let{lookupQuerystring:t}=e,n;if(typeof window<`u`){let{search:e}=window.location;!window.location.search&&window.location.hash?.indexOf(`?`)>-1&&(e=window.location.hash.substring(window.location.hash.indexOf(`?`)));let r=e.substring(1).split(`&`);for(let e=0;e<r.length;e++){let i=r[e].indexOf(`=`);i>0&&r[e].substring(0,i)===t&&(n=r[e].substring(i+1))}}return n}},re={name:`hash`,lookup(e){let{lookupHash:t,lookupFromHashIndex:n}=e,r;if(typeof window<`u`){let{hash:e}=window.location;if(e&&e.length>2){let i=e.substring(1);if(t){let e=i.split(`&`);for(let n=0;n<e.length;n++){let i=e[n].indexOf(`=`);i>0&&e[n].substring(0,i)===t&&(r=e[n].substring(i+1))}}if(r)return r;if(!r&&n>-1){let t=e.match(/\/([a-zA-Z-]*)/g);return Array.isArray(t)?t[typeof n==`number`?n:0]?.replace(`/`,``):void 0}}}return r}},b=null,x=()=>{if(b!==null)return b;try{if(b=typeof window<`u`&&window.localStorage!==null,!b)return!1;let e=`i18next.translate.boo`;window.localStorage.setItem(e,`foo`),window.localStorage.removeItem(e)}catch{b=!1}return b},ie={name:`localStorage`,lookup(e){let{lookupLocalStorage:t}=e;if(t&&x())return window.localStorage.getItem(t)||void 0},cacheUserLanguage(e,t){let{lookupLocalStorage:n}=t;n&&x()&&window.localStorage.setItem(n,e)}},S=null,C=()=>{if(S!==null)return S;try{if(S=typeof window<`u`&&window.sessionStorage!==null,!S)return!1;let e=`i18next.translate.boo`;window.sessionStorage.setItem(e,`foo`),window.sessionStorage.removeItem(e)}catch{S=!1}return S},ae={name:`sessionStorage`,lookup(e){let{lookupSessionStorage:t}=e;if(t&&C())return window.sessionStorage.getItem(t)||void 0},cacheUserLanguage(e,t){let{lookupSessionStorage:n}=t;n&&C()&&window.sessionStorage.setItem(n,e)}},oe={name:`navigator`,lookup(e){let t=[];if(typeof navigator<`u`){let{languages:e,userLanguage:n,language:r}=navigator;if(e)for(let n=0;n<e.length;n++)t.push(e[n]);n&&t.push(n),r&&t.push(r)}return t.length>0?t:void 0}},se={name:`htmlTag`,lookup(e){let{htmlTag:t}=e,n,r=t||(typeof document<`u`?document.documentElement:null);return r&&typeof r.getAttribute==`function`&&(n=r.getAttribute(`lang`)),n}},ce={name:`path`,lookup(e){let{lookupFromPathIndex:t}=e;if(typeof window>`u`)return;let n=window.location.pathname.match(/\/([a-zA-Z-]*)/g);if(Array.isArray(n))return n[typeof t==`number`?t:0]?.replace(`/`,``)}},le={name:`subdomain`,lookup(e){let{lookupFromSubdomainIndex:t}=e,n=typeof t==`number`?t+1:1,r=typeof window<`u`&&window.location?.hostname?.match(/^(\w{2,5})\.(([a-z0-9-]{1,63}\.[a-z]{2,6})|localhost)/i);if(r)return r[n]}},w=!1;try{document.cookie,w=!0}catch{}var T=[`querystring`,`cookie`,`localStorage`,`sessionStorage`,`navigator`,`htmlTag`];w||T.splice(1,1);var ue=()=>({order:T,lookupQuerystring:`lng`,lookupCookie:`i18next`,lookupLocalStorage:`i18nextLng`,lookupSessionStorage:`i18nextLng`,caches:[`localStorage`],excludeCacheFor:[`cimode`],convertDetectedLanguage:e=>e}),E=class{constructor(e){let t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};this.type=`languageDetector`,this.detectors={},this.init(e,t)}init(){let e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{languageUtils:{}},t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},n=arguments.length>2&&arguments[2]!==void 0?arguments[2]:{};this.services=e,this.options=h(t,this.options||{},ue()),typeof this.options.convertDetectedLanguage==`string`&&this.options.convertDetectedLanguage.indexOf(`15897`)>-1&&(this.options.convertDetectedLanguage=e=>e.replace(`-`,`_`)),this.options.lookupFromUrlIndex&&(this.options.lookupFromPathIndex=this.options.lookupFromUrlIndex),this.i18nOptions=n,this.addDetector(te),this.addDetector(ne),this.addDetector(ie),this.addDetector(ae),this.addDetector(oe),this.addDetector(se),this.addDetector(ce),this.addDetector(le),this.addDetector(re)}addDetector(e){return this.detectors[e.name]=e,this}detect(){let e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:this.options.order,t=[];return e.forEach(e=>{if(this.detectors[e]){let n=this.detectors[e].lookup(this.options);n&&typeof n==`string`&&(n=[n]),n&&(t=t.concat(n))}}),t=t.filter(e=>e!=null&&!g(e)).map(e=>this.options.convertDetectedLanguage(e)),this.services&&this.services.languageUtils&&this.services.languageUtils.getBestMatchFromCodes?t:t.length>0?t[0]:null}cacheUserLanguage(e){let t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:this.options.caches;t&&(this.options.excludeCacheFor&&this.options.excludeCacheFor.indexOf(e)>-1||t.forEach(t=>{this.detectors[t]&&this.detectors[t].cacheUserLanguage(e,this.options)}))}};E.type=`languageDetector`;var D={common:{loading:`Loading...`,save:`Save`,saving:`Saving...`,cancel:`Cancel`,delete:`Delete`,edit:`Edit`,close:`Close`,back:`Back`,next:`Next`,confirm:`Confirm`,error:`Error`,success:`Success`,warning:`Warning`,or:`or`,optional:`optional`,enabled:`Enabled`,disabled:`Disabled`,on:`On`,off:`Off`,yes:`Yes`,no:`No`,search:`Search`,noResults:`No results found`,retry:`Retry`,refresh:`Refresh`,download:`Download`,upload:`Upload`,export:`Export`,import:`Import`,reset:`Reset`,apply:`Apply`,clear:`Clear`,all:`All`,none:`None`,default:`Default`,custom:`Custom`,remove:`Remove`,home:`Home`,more:`More`},brand:{name:`Libre WebUI`,shortName:`Libre`},auth:{login:{title:`Welcome Back`,subtitle:`Sign in to your account to continue`,username:`Username`,usernamePlaceholder:`Enter your username`,password:`Password`,passwordPlaceholder:`Enter your password`,signIn:`Sign In`,signingIn:`Signing in...`,noAccount:`Don't have an account?`,signUpHere:`Sign up here`,loginSuccess:`Login successful!`,loginFailed:`Login failed`,checkCredentials:`Login failed. Please check your credentials.`,approvalPending:`Your account is waiting for administrator approval.`,enterBoth:`Please enter both username and password`,githubSuccess:`GitHub login successful!`,githubFailed:`GitHub authentication failed`,githubVerifyFailed:`Failed to verify GitHub authentication`,verificationFailed:`Security verification failed. Please refresh and try again.`},signup:{title:`Create Account`,subtitle:`Sign up for your new account`,username:`Username`,usernamePlaceholder:`Choose a username`,email:`Email`,emailPlaceholder:`your@email.com`,password:`Password`,passwordPlaceholder:`Choose a password`,confirmPassword:`Confirm Password`,confirmPasswordPlaceholder:`Confirm your password`,createAccount:`Create Account`,creatingAccount:`Creating account...`,hasAccount:`Already have an account?`,signInHere:`Sign in here`,signupSuccess:`Account created successfully!`,approvalPending:`Registration received. An administrator must approve your account.`,awaitingApproval:`Awaiting approval`,awaitingApprovalDescription:`Your account has been created, but an administrator must activate it before you can sign in.`,backToSignIn:`Back to sign in`,signupFailed:`Signup failed`,tryAgain:`Signup failed. Please try again.`,usernameRequired:`Username and password are required`,passwordMismatch:`Passwords do not match`},logout:{button:`Log out`,success:`Logged out successfully`},oauth:{continueWith:`Continue with {{provider}}`,connectingTo:`Connecting to {{provider}}...`,github:`GitHub`,huggingFace:`Hugging Face`},checkingAuth:`Checking authentication...`,welcome:`Welcome`,noEmail:`No email provided`,role:`Role`,id:`ID`,userId:`User ID`,signInDescription:`Sign in with your GitHub account to continue`,signInWithGitHub:`Sign in with GitHub`,jwtActive:`JWT Authentication Active`,jwtDescription:`JWT-based authentication with GitHub OAuth`,github:`GitHub`,provider:`Provider`,tagline:`Your AI stack should answer to you.`,selfHosted:`Self-hosted · Apache 2.0`,highlights:{local:{title:`Local first`,body:`Your conversations and files stay on the machine you run this on.`},providers:{title:`Any provider`,body:`Local models through Ollama, plus the remote providers you choose to add.`},work:{title:`Isolated Work`,body:`Give a model a sandboxed workspace with files, a terminal, and a preview.`}},oidc:{defaultProviderName:`Single sign-on`},mfa:{sectionTitle:`Two-factor authentication`,sectionDescription:`Protect your account with an authenticator app and passkeys.`,totpTitle:`Authenticator app`,totpEnabledHint:`Enabled. Unused recovery codes: {{count}}`,totpDisabledHint:`Add a second step to password sign-in with a one-time code.`,enableButton:`Enable`,disableButton:`Disable`,activateButton:`Confirm`,regenerateCodes:`New recovery codes`,confirmWithCode:`Confirm with a code from your app or a recovery code`,enabled:`Two-factor authentication is enabled.`,disabled:`Two-factor authentication is disabled.`,invalidCode:`That code is not valid.`,enrollFailed:`Setup could not be started.`,challengeExpired:`The sign-in challenge expired. Please sign in again.`,setupTitle:`Set up two-factor authentication`,setupSubtitle:`This instance requires a second sign-in step. Add the secret to your authenticator app to continue.`,verifyTitle:`Enter your code`,verifyHint:`Enter the 6-digit code from your authenticator app, or a recovery code.`,secretHint:`Add this secret to your authenticator app, then confirm with the current code.`,openAuthenticator:`Open in authenticator app`,codeLabel:`6-digit code`,codeOrRecoveryLabel:`Code or recovery code`,codePlaceholder:`123456`,verifyButton:`Verify`,backToSignIn:`Back to sign in`,recoveryCodesTitle:`Recovery codes`,recoveryCodesHint:`Store these codes somewhere safe. Each one signs you in once if you lose your authenticator.`,recoveryCodesSaved:`I saved my recovery codes`,recoveryCodesRegenerated:`New recovery codes created. The old ones no longer work.`},passkeys:{sectionTitle:`Passkeys`,sectionDescription:`Sign in without a password using your device's screen lock or security key.`,addButton:`Add passkey`,empty:`No passkeys yet.`,unnamed:`Passkey`,createdAt:`Added`,lastUsedAt:`Last used`,removeButton:`Remove passkey`,registered:`Passkey added.`,registerFailed:`The passkey could not be added.`,removed:`Passkey removed.`,removeFailed:`The passkey could not be removed.`,signInButton:`Sign in with a passkey`,signInFailed:`Passkey sign-in failed.`}},setup:{welcome:{title:`Welcome to Libre WebUI`,subtitle:`Let's Get Started`,description:`Set up your Libre WebUI instance in just a few steps`,createAdmin:`Create Admin Account`,features:{secure:{title:`Secure & Private`,description:`Your conversations stay on your device`},fast:{title:`Fast & Responsive`,description:`Optimized for speed and performance`},openSource:{title:`Open Source`,description:`Free and open source software`}}},admin:{title:`Create Admin Account`,subtitle:`Administrator Setup`,description:`Create the first admin account for your Libre WebUI instance`,usernamePlaceholder:`Enter admin username`,passwordPlaceholder:`Enter password (at least 12 characters)`,confirmPlaceholder:`Confirm your password`,creating:`Creating...`,createAdmin:`Create Admin`,success:`Admin account created successfully!`,failed:`Failed to create admin account`,approvalUnexpected:`The initial administrator could not be activated. Please try again.`,fillAllFields:`Please fill in all fields`,note:`This will be the primary administrator account for your Libre WebUI instance`},encryptionKey:{title:`Save Your Encryption Key`,subtitle:`Important: Save This Key`,description:`This encryption key protects your sensitive data. Store it securely - you'll need it if you ever need to restore your database.`,warning:`Warning`,warningText:`If you lose this key and need to restore your database, your encrypted data (API keys, preferences) will be unrecoverable.`,label:`Your Encryption Key`,loading:`Loading...`,copyToClipboard:`Copy to clipboard`,copied:`Encryption key copied to clipboard!`,copyFailed:`Failed to copy key to clipboard`,envNote:`This key is also saved in your backend/.env file as ENCRYPTION_KEY`,acknowledgment:`I have saved my encryption key in a secure location and understand that losing it may result in data loss.`,confirmRequired:`Please confirm that you have saved the encryption key`,continue:`Continue to Libre WebUI`}},chat:{greeting:{morning:`Good morning`,afternoon:`Good afternoon`,evening:`Good evening`,night:`Good night`},followUp:`Follow up`,welcome:{helpToday:`What can I help with today?`,helpTonight:`What can I help with tonight?`,variety:{create:{title:`What should we make?`,subtitle:`Start with a thought, a sketch, or a stubborn problem.`},explore:{title:`Where should we begin?`,subtitle:`Bring the question you keep returning to.`},imagine:{title:`What are you imagining?`,subtitle:`We can shape it together.`},focus:{title:`What deserves your attention?`,subtitle:`Let's make the next step clear.`},untangle:{title:`What's tangled?`,subtitle:`Give me the messy version first.`},momentum:{title:`Ready when you are.`,subtitle:`Pick up an idea, plan, or unfinished thread.`},open:{title:`What's on your mind?`,subtitle:`Small thought or ambitious project. Both work.`},challenge:{title:`What are we solving?`,subtitle:`Tell me what isn't working yet.`},draft:{title:`Let's start somewhere.`,subtitle:`It doesn't have to be polished.`},possibility:{title:`What could this become?`,subtitle:`Show me the raw material.`},unexpected:{title:`Make something unexpected.`,subtitle:`Give me a constraint, a mood, or a half-formed idea.`}}},input:{placeholder:`Send a message`,messagePlaceholder:`Message...`,attachImages:`Attach images`,attachments:`Attachments and advanced features`,sendMessage:`Send message`,stopGeneration:`Stop generation`,menu:{uploadImages:`Upload images`,attachDocument:`Attach document`,attachWebpage:`Attach webpage`,structuredOutput:`Structured output`,attach:`Attach`,documentAttached:`Document attached`,webpageAttached:`Webpage attached`,attachFailed:`Could not attach that`,attachKnowledge:`Attach knowledge`,noCollections:`No collections yet — create one in Settings → Documents`},voiceInput:`Voice input`,voiceStop:`Stop listening`,transcriptionSource:`Speech recognition source`,browserSpeech:`Browser speech service`,providerTranscriptionDisclosure:`Record and send audio to {{provider}} for transcription`,webSearchOn:`Web search on — replies use live results`,webSearchOff:`Search the web for this message`,toolsOn:`Tools on — the model can call approved tools`,toolsOff:`Let the model call tools for this message`,thinkingOn:`Thinking on ({{level}})`,thinkingOff:`Think before answering`},session:{new:`New Chat`,work:`Work`,chat:`Chat`,private:`Private`,incognito:`Incognito Chat`,privateMode:`Private Mode`,privateDescription:`This conversation won't be saved`,privateTooltip:`Start a private conversation that won't be saved`,deleteConfirm:`Are you sure you want to delete this chat?`,generatingTitle:`Generating title`,noChats:`No chats yet`,createFirst:`Create your first chat above`,chats:`Chats`,renameChat:`Rename chat`,openNewTab:`Open in new tab`,pinChat:`Pin`,unpinChat:`Unpin`,deleteChat:`Delete chat`,archiveChat:`Archive chat`,groups:{pinned:`Pinned`,today:`Today`,yesterday:`Yesterday`,previous7Days:`Previous 7 days`,previous30Days:`Previous 30 days`,older:`Older`},folder:{new:`New folder`,namePlaceholder:`Folder name`,move:`Move to folder`,remove:`Remove from folder`,delete:`Delete folder`,deleteConfirm:`Delete this folder? Chats inside are kept.`},shareChat:`Share chat…`},persona:{applied:`Persona applied`,label:`Persona`,loadFailed:`Failed to load persona details`,removeFailed:`Failed to remove persona`},model:{updated:`Model updated`,noModels:`No models available`,noModelsDescription:`No models available. Make sure Ollama is running and has models installed.`,pullCommand:`ollama pull llama3.2:3b`,noModelsTooltip:`No models available. Please ensure Ollama is running and models are installed.`,selectBeforePrivateChat:`Select an available model before starting private chat`,selectBeforeSending:`Select an available model before sending`},footer:{disclaimer:`LLM can make mistakes - verify important information`,images:`{{count}} image`,images_plural:`{{count}} images`,structuredOutput:`Structured output`},mediaUpload:{dropImagesHere:`Drop images here or`,supportedFormats:`Supports: JPG, PNG, GIF, WebP (max 10MB each)`,browse:`browse`},structuredOutput:{title:`Response Format`,none:`None (Natural Language)`,noneDescription:`Default natural language response`,json:`JSON`,jsonDescription:`Structured JSON format`,list:`List`,listDescription:`Array of items`,summary:`Summary`,summaryDescription:`Document summary with key points`,analysis:`Analysis`,analysisDescription:`Structured analysis with pros/cons`,custom:`Custom Schema`,customDescription:`Define your own JSON schema`,customSchema:`Custom JSON schema`,schemaPreview:`Schema Preview`,applySchema:`Apply Schema`,cancel:`Cancel`,enabled:`Structured output enabled`},controls:{title:`Chat controls`,systemPrompt:`System prompt`,systemPromptPlaceholder:`Instructions that apply only to this chat…`,advancedParams:`Advanced parameters`,advancedParamsDescription:`Overrides for this chat. Empty fields use your global defaults.`,fromModel:`from model`,fromModelHint:`This value comes from the model's own recommended settings.`,contextCapped:`Context capped at {{context}} of the {{trained}} this model was trained for, so it still loads.`,saved:`Chat controls saved`,saveFailed:`Could not save chat controls`,params:{temperature:`Temperature`,topP:`Top P`,topK:`Top K`,minP:`Min P`,maxTokens:`Max tokens`,repeatPenalty:`Repeat penalty`,seed:`Seed`,contextLength:`Context length`},thinking:`Thinking`,thinkingDescription:`How much the model reasons before answering. Models that cannot reason ignore this.`,compaction:`Context compaction`,compactionDescription:`When the server compacts long conversations, this chat can opt out and keep its full history.`,compactionDefault:`Server default`,compactionOff:`Off for this chat`},message:{sources:`Sources`},toasts:{chatCreated:`New chat created`,createFailed:`Failed to create session`,loadFailed:`Failed to load sessions`,chatDeleted:`Chat deleted`,deleteFailed:`Failed to delete chat`,deleteSessionFailed:`Failed to delete session`,historyCleared:`All chat history cleared`,historyClearFailed:`Failed to clear chat history`,titleUpdated:`Chat title updated`,updateFailed:`Failed to update session`,noValidSession:`No valid chat session. Please create or select a chat.`,sessionNotFound:`Session not found or invalid. Please select or create a valid chat session.`,noModelProvider:`No model provider is available`,modelUnavailable:`Selected model "{{model}}" is unavailable from {{provider}}. Reactivate that provider or select another model.`,modelSwitched:`Switched to {{model}} (previous model no longer available)`,modelsLoadFailed:`Failed to load models`,modelUpdated:`Model updated for current chat`,modelUpdateFailed:`Failed to update session model`},documents:{title:`Documents in context`},context:{title:`Context window:`,full:`{{percent}}% full`,tokensUsed:`{{used}} / {{budget}} tokens used`,tokensUsedNoBudget:`{{used}} tokens used`,capped:`capped from {{trained}}`},queue:{title:`Queued ({{total}})`,moveUp:`Move up`,moveDown:`Move down`,updateFailed:`Could not update the queued prompt`,enqueueFailed:`Could not queue the prompt`},compare:{title:`Compare models`,hint:`Answer with up to {{max}} extra models`},fork:{action:`Fork from here`,created:`Chat forked`,failed:`Could not fork the chat`,origin:`Forked from {{title}}`,originUnknown:`another chat`},sharedReadOnly:`Shared by {{owner}} — view only`},sidebar:{navigation:{chat:`Chat`,models:`Models`,personas:`Personas`,imagine:`Imagine`,agents:`Agents`,work:`Work`,settings:`Settings`,usageAnalytics:`Provider Usage`,system:`System`,userManagement:`User Management`,signOut:`Sign Out`,exploreLabel:`Explore`,notes:`Notes`,calendar:`Calendar`,automations:`Automations`,prompts:`Prompts`,skills:`Skills`,tools:`Tools`,channels:`Channels`},toggleSize:`Toggle sidebar size`,expandSidebar:`Expand sidebar`},user:{menu:{changePicture:`Change Picture`,settings:`Settings`,usageAnalytics:`Provider Usage`,system:`System`,userManagement:`User Management`,logout:`Log out`,pinShortcut:`Pin to sidebar`,unpinShortcut:`Unpin from sidebar`,evaluations:`Evaluations`},avatar:{title:`Change Profile Picture`,updated:`Profile picture updated`,updateFailed:`Failed to update profile picture`,saving:`Saving...`,label:`Avatar`,uploadAvatarImage:`Upload avatar image`,dragAndDrop:`Drag and drop an image or click to browse`,chooseImage:`Choose Image`,uploading:`Uploading...`,enterImageUrl:`Or enter image URL`,supportedFormats:`Supports: JPG, PNG, GIF, WebP (max 2MB). Square images work best.`,customAvatar:`Custom avatar image`,clickToChange:`Click to change or remove`,removed:`Avatar removed`,uploaded:`Avatar uploaded successfully`,invalidFile:`Please select a valid image file`,fileTooLarge:`Avatar image size must be less than 2MB`,readFailed:`Failed to read image file`,uploadFailed:`Failed to upload avatar image`},profile:{noEmail:`No email provided`}},settings:JSON.parse(`{"title":"Settings","tabs":{"appearance":"Appearance","model":"Model","systemMessage":"System Message","plugins":"Plugins","search":"Search","generation":"Generation","documents":"Documents","tts":"Speech","imageGen":"Images","data":"Data","shortcuts":"Shortcuts","about":"About","sessions":"Sessions","apiKeys":"API keys","notifications":"Notifications"},"appearance":{"title":"Appearance","language":{"title":"Language","description":"Select your preferred language"},"theme":{"title":"Theme","light":"Light","dark":"Dark","amoled":"Pure Black","system":"System"},"accent":{"title":"Accent color","custom":"Custom color","useColor":"Use {{color}} accent","behaviorTitle":"Interface palette","behaviorDescription":"Choose whether the accent stays on controls or adapts the entire light or dark interface.","defaultStyle":"Default","defaultStyleDescription":"Keep the neutral light and dark surfaces.","adaptedStyle":"Adapt to accent","adaptedStyleDescription":"Tint surfaces, borders, and text with your accent."},"chatInterface":{"title":"Chat Interface","showUsername":"Show Username","showUsernameDescription":"Display username in chat messages","followUpSuggestions":"Follow-up suggestions","followUpSuggestionsDescription":"Suggest quick replies after each response","hapticFeedback":"Haptic feedback (Android)","hapticFeedbackDescription":"Use subtle vibration for important mobile actions","autoOpenArtifacts":"Auto-open artifacts","autoOpenArtifactsDescription":"Open the artifact panel when a response creates one"},"background":{"title":"Background Image","enable":"Enable background image","enableDescription":"Show custom background with blur effect","blur":"Blur","opacity":"Opacity","upload":"Upload background image","dragDrop":"Drag and drop an image or click to browse","chooseImage":"Choose Image"}},"saveSettings":"Save Settings","model":{"title":"Model Settings","defaultModel":"Default Model","defaultModelDescription":"This model will be used by default for new conversations","selectModel":"Select a model","specializedModels":"Specialized Models","visionModel":"Vision Model","selectVisionModel":"Use the current chat model","visionModelDescription":"Used automatically whenever the outgoing chat context contains images. Choose a model that supports image input.","visionModelUpdateFailed":"Failed to update vision model: {{error}}","visionModelNoProvider":"This vision model has no provider identity. Select an available model.","persona":"Persona","updateAll":"Update All Models","updateAllDescription":"Check for updates and pull latest versions of all installed models","updateAllButton":"Update All","updating":"Updating models...","currentModelInfo":"Current Model Info","name":"Name","size":"Size","family":"Family","format":"Format","status":"Status","statusStarting":"Starting...","statusComplete":"Complete","statusError":"Error","bulkOperations":"Bulk Operations","autoTitle":{"title":"Auto Title Generation","enable":"Enable Auto Title","enableDescription":"Automatically generate titles for new conversations","taskModel":"Task Model","selectTaskModel":"Select task model","taskModelDescription":"Model used for generating conversation titles"},"updatingModel":"Updating {{name}} ({{current}}/{{total}})","modelsProgress":"{{current}} of {{total}} models"},"systemMessage":{"title":"System Message","description":"Set a custom system message that will be used for all new conversations.","placeholder":"Enter a system message...","saved":"System message saved","saveFailed":"Failed to save system message"},"plugins":{"title":"Plugins","description":"Manage your installed plugins","providerConnections":"Provider connections","providerConnectionsDescription":"Connect, configure, and inspect model providers through plugins.","providers":"Providers","searchProviders":"Search providers","noProvidersFound":"No providers match your search.","selectProvider":"Select a provider","selectProviderDescription":"Choose a provider to inspect its connection and model catalog.","addNew":"Add New Plugin","upload":"Upload Plugin","addJson":"Add JSON","uploading":"Uploading...","jsonPlaceholder":"Paste plugin JSON configuration...","install":"Install Plugin","noPlugins":"No plugins installed","noPluginsDescription":"Add a plugin to extend functionality","loading":"Loading plugins...","installed":"Installed Plugins","active":"Active Plugins","activeLabel":"Active","inactive":"Inactive","activate":"Activate","deactivate":"Deactivate","models":"models","apiKeySet":"API Key Set","apiKeyConfiguration":"API Key Configuration","apiKeyDescription":"Store a personal API key for {{name}}.","apiKeyEnvAlternative":"Alternatively, set the","environmentVariable":"environment variable","apiKeyConfigured":"API key configured","apiKeyPlaceholder":"Enter your API key...","saveApiKey":"Save API Key","showApiKey":"Show API key","hideApiKey":"Hide API key","configure":"Configure","providerSettings":"Provider settings","status":"Status","defaultEndpoint":"Default endpoint","modelCatalog":"Model catalog","modelCatalogDescription":"Discovered and configured models for this provider and its capabilities.","refreshModels":"Refresh models","noModelsConfigured":"No models are configured for this provider.","modelId":"Model ID","capabilities":"Capabilities","modelCatalogUpdated":"Model catalog updated: {{count}} models.","modelCatalogUnchanged":"Model catalog is already up to date.","modelCatalogNeedsApiKey":"Add a valid API key for this provider to load its live model list.","modelCatalogUnavailable":"Could not load the provider's model list.","modelCatalogRefreshFailed":"Failed to refresh the model catalog","capability":{"chat":"Chat","embedding":"Embedding","image":"Image","speech":"Speech","transcription":"Transcription"},"exportPlugin":"Export plugin","deletePlugin":"Delete plugin","apiKey":{"title":"API Key","placeholder":"Enter API key","save":"Save Key","remove":"Remove Key","configured":"API Key Configured","notConfigured":"API Key Required","saved":"API key saved successfully","removed":"API key removed","saveFailed":"Failed to save API key","removeFailed":"Failed to remove API key","enterKey":"Please enter an API key"},"variables":"Variables"},"generation":{"title":"Generation Options","description":"Configure how the AI generates responses","scopeLabel":"Applies to","scopeAll":"All models","scopeModel":"Only {{model}}","scopeAllHint":"The values every model uses unless it has its own.","scopeModelHint":"Saved for this model alone, and it wins over the values above.","advancedSettings":"Advanced generation settings","advancedSettingsDescription":"Sampling, token limits, context, penalties, and stop sequences","coreParameters":"Core Parameters","temperature":"Temperature","temperatureDescription":"Controls randomness. Lower values are more focused, higher values more creative.","topP":"Top P","topPDescription":"Controls diversity via nucleus sampling. Lower values focus on likely tokens.","topK":"Top K","topKDescription":"Limits token selection to top K most likely. Set to 0 to disable.","minP":"Min P","minPDescription":"Minimum probability threshold for token selection.","generationControl":"Generation Control","maxTokens":"Max Tokens","maxTokensDescription":"Maximum number of tokens to generate in the response.","repeatPenalty":"Repeat Penalty","repeatPenaltyDescription":"Penalizes repeated tokens. Higher values reduce repetition.","contextLength":"Context Length","contextLengthDescription":"Maximum context window size for conversations.","seed":"Seed","optional":"optional","random":"Random","seedDescription":"Set a specific seed for reproducible outputs.","advancedOptions":"Advanced Options","presencePenalty":"Presence Penalty","presencePenaltyDescription":"Penalizes tokens that appear in the context.","frequencyPenalty":"Frequency Penalty","frequencyPenaltyDescription":"Penalizes frequently used tokens.","stopSequences":"Stop Sequences","commaSeparated":"comma separated","stopSequencesDescription":"Custom tokens that will stop generation when encountered.","resetDefaults":"Reset to Defaults","saveOptions":"Save Options","embeddingSettings":"Embedding Settings","enableEmbeddings":"Enable Document Embeddings","thinking":"Thinking","thinkingDescription":"Default reasoning effort for replies. Each chat can override it.","thinkingLevels":{"default":"Model default","defaultWith":"Model default ({{level}})","off":"Off","on":"On","low":"Low","medium":"Medium","high":"High"}},"documents":{"title":"Document Settings","embeddings":{"title":"Embeddings","enable":"Enable document embeddings","model":"Embedding Model","modelDescription":"Select the model used for document embedding","chunkSize":"Chunk Size","chunkSizeInTokens":"(in tokens)","chunkSizeDescription":"Size of text chunks for embedding","chunkOverlap":"Chunk Overlap","chunkOverlapInTokens":"(in tokens)","chunkOverlapDescription":"Overlap between consecutive chunks","similarityThreshold":"Similarity Threshold","similarityDescription":"Minimum similarity score to include results","status":"Embedding Status","statusLabel":"Status","available":"Available","unavailable":"Unavailable","chunksWithEmbeddings":"Chunks with embeddings","coverage":"Coverage","regenerate":"Regenerate Embeddings","regenerating":"Regenerating..."},"collections":{"title":"Knowledge collections","description":"Group documents into collections and attach them to any chat.","namePlaceholder":"Collection name","create":"Create","none":"No collection","deleteConfirm":"Delete this collection? Documents inside are kept.","createFailed":"Failed to create the collection","deleteFailed":"Failed to delete the collection","assignFailed":"Failed to move the document","share":"Share collection","shared":"shared"},"library":{"title":"Uploaded documents","description":"Documents available as chat context. A document uploaded in a chat stays in its own conversation; a document with no chat and no collection joins every conversation.","empty":"No documents uploaded yet.","chatScope":"One chat","everyChatScope":"Every chat","deleteConfirm":"Delete \\"{{name}}\\"? It disappears from every chat.","deleteFailed":"Failed to delete the document","extractionFailed":"Extraction failed","extractionQueued":"Extracting…"}},"tts":{"title":"Text-to-Speech","description":"Configure text-to-speech settings for reading messages aloud","loadingProviders":"Loading TTS providers...","noProviders":"No TTS Providers","noProvidersDescription":"Configure a plugin with TTS support to enable text-to-speech","enable":"Enable TTS","enableDescription":"Allow text-to-speech for assistant messages","autoPlay":"Auto-play Responses","autoPlayDescription":"Automatically read new assistant messages aloud","streamSentences":"Natural Batched Playback","streamSentencesDescription":"Generate several phrase-aware batches ahead and play them as one continuous response.","voiceConfiguration":"Voice Configuration","model":"TTS Model","modelDescription":"Select the model for text-to-speech generation","voice":"Voice","selectVoice":"Select a voice","voiceDescription":"Choose the voice for text-to-speech","providerDefaultVoice":"This model chooses its default voice unless you provide a reference recording when generating speech.","voiceCloningAvailable":"Voice cloning available","voiceCloningAvailableDescription":"Use Imagine → Audio to create speech from a consented reference recording and exact transcript. You can optionally save the reference as a reusable voice.","savedVoiceOption":"{{name}} (saved voice)","savedVoices":"Saved voices","loadingSavedVoices":"Loading saved voices…","deleteSavedVoice":"Delete saved voice {{name}}","deleteSavedVoiceConfirm":"Delete the saved voice “{{name}}”? Its reference recording and transcript will be removed.","savedVoiceDeleted":"Saved voice deleted","savedVoicePreferenceCleanupFailed":"Saved voice deleted, but Speech settings could not be reset","savedVoiceDeleteFailed":"Failed to delete saved voice","speed":"Speed","speedSlow":"0.5x","speedNormal":"1.0x","speedFast":"2.0x","availableProviders":"Available Providers","models":"models","test":"Test","testing":"Testing...","stop":"Stop","consentRevoked":"Consent withdrawn","consentExpired":"Consent expired","transferCount":"sent to provider {{total}}×","consentExpires":"consent until {{date}}","revokeSavedVoice":"Withdraw consent for {{name}}","revokeSavedVoiceConfirm":"Withdraw consent for “{{name}}”? The saved voice can no longer be used, but the consent record is kept.","savedVoiceRevoked":"Consent withdrawn","savedVoiceRevokeFailed":"Failed to withdraw consent"},"imageGen":{"title":"Image Generation","description":"Configure image generation settings and providers","loadingProviders":"Loading image generation providers...","noProviders":"No Image Generation Providers","noProvidersDescription":"Configure a plugin with image generation support","enable":"Enable Image Generation","enableDescription":"Allow AI image generation in conversations","configuration":"Configuration","model":"Model","modelDescription":"Select the model for image generation","size":"Size","sizeDescription":"Resolution of generated images","quality":"Quality","qualityDescription":"Quality level of generated images","style":"Style","styleDescription":"Style preset for generated images","availableProviders":"Available Providers","models":"models"},"data":{"title":"Data Management","export":"Export Data","exportDescription":"Download a portable archive of preferences, chat folders, sessions and messages, Notes, knowledge collections, and extracted document text.","archiveScopeV3":"Includes preferences, chats, folders, Notes, knowledge collections, and extracted document text. Excludes accounts and secrets, biometric cloned voices, generated media, personas and memory, and Work data or volumes.","exportAll":"Export Portable Archive","import":"Import Data","importDescription":"Validate and import a Libre WebUI portable archive. Existing records not present in the archive are never deleted.","importData":"Import Data","importing":"Importing...","clearSessions":"Clear Sessions","clearSessionsDescription":"Delete all chat sessions. This action cannot be undone.","clearAll":"Clear All","clearing":"Clearing...","importOptions":"Import Options","importOptionsDescription":"Choose how to handle records with matching IDs. Preferences are merged when duplicates are skipped and replaced when matching records are overwritten.","validatingArchive":"Validating archive and calculating changes…","archiveValidationFailed":"Archive validation failed","preflightReport":"Import preview","preflightIncoming":"{{folders}} folders · {{sessions}} chats · {{messages}} messages · {{notes}} Notes · {{collections}} collections · {{documents}} documents · {{chunks}} chunks","preflightRemappedIds":"{{count}} IDs will be remapped to protect another account's data.","skipDuplicates":"Skip duplicates","overwrite":"Overwrite existing","importResults":"Import Results","preferences":"Preferences","imported":"Imported","failed":"Failed","sessions":"Sessions","sessionFolders":"Session folders","notes":"Notes","knowledgeCollections":"Knowledge collections","importedLabel":"imported","overwrittenLabel":"overwritten","skipped":"skipped","toCreate":"to create","toOverwrite":"to overwrite","toSkip":"to skip","documents":"Documents","warnings":"Warnings","refreshAfterImportFailed":"Data was imported, but some views could not be refreshed. Reload Libre WebUI to see every change.","errors":"Errors","archivedChats":{"title":"Archived chats","empty":"No archived chats","unarchive":"Unarchive"}},"about":{"title":"About","versionLabel":"Version","ollama":{"title":"Ollama Status","version":"Version","healthy":"Healthy","unhealthy":"Unhealthy"},"stats":{"models":"Models","sessions":"Sessions"},"features":{"privacy":{"title":"Privacy First","description":"Your data stays on your device"},"openSource":{"title":"Open Source","description":"Free and open source software"},"localInference":{"title":"Local Inference","description":"Run AI models locally with Ollama"}},"openSourceBy":"Open source by {{company}}","links":{"title":"Links","github":"GitHub","githubDescription":"View source code and contribute","website":"Website","websiteDescription":"Visit our website","documentation":"Documentation","reportIssue":"Report Issues","reportIssueDescription":"Bug reports & feature requests","documentationDescription":"Guides, tutorials and API reference","forgejo":"Forgejo Mirror","forgejoDescription":"Self-hosted Forgejo repository","sponsor":"Sponsor","sponsorDescription":"Help fund the project","star":"Star on GitHub","starDescription":"A star helps others discover the project"},"version":"Version {{version}}","updates":{"checking":"Checking for updates…","upToDate":"You're on the latest version","updateAvailable":"Version {{version}} is available","ahead":"Running ahead of the latest release ({{version}})","checkFailed":"Couldn't check for updates","viewChangelog":"View changelog"}},"groups":{"general":"General","chat":"Chat","media":"Speech & images","connections":"Connections"},"search":{"title":"Web search","description":"Search the web through a self-hosted SearXNG instance. When enabled, the chat composer offers a search toggle and Work tasks with network access can search.","enableLabel":"Enable web search","enableDescription":"Offer web search to chats and Work tasks. Searches run server-side against the configured instance.","urlLabel":"SearXNG URL","urlDescription":"Base URL of the SearXNG instance, reachable from the server. The bundled private deploy stack provides http://searxng:8080.","maxResultsLabel":"Results per search","maxResultsDescription":"How many results feed a reply or tool call, 1-100.","maxResultsInvalid":"Results per search must be between 1 and 100.","safeSearchLabel":"Safe search","safeSearchDescription":"Ask the engine to filter explicit results.","test":"Test connection","testing":"Testing…","testOk":"Search works — {{results}} results returned","testFailed":"Search test failed","save":"Save","saved":"Search settings saved","saveFailed":"Could not save the search settings"},"compaction":{"title":"Context compaction","description":"When a conversation grows past the token threshold, the server summarizes its older messages and keeps only the most recent ones verbatim. Applies to every user on this server.","thresholdLabel":"Token threshold","thresholdDescription":"Estimated context tokens above which older history is summarized, 500-1,000,000.","thresholdInvalid":"Token threshold must be between 500 and 1,000,000.","keepRecentLabel":"Recent messages kept","keepRecentDescription":"How many of the latest messages always stay verbatim, 2-200.","keepRecentInvalid":"Recent messages kept must be between 2 and 200.","modelLabel":"Compaction model","modelDescription":"The model that writes the summaries. The session's own model is used when none is picked.","sessionModelOption":"Use the session's model","promptLabel":"Custom summary prompt","promptPlaceholder":"Leave empty to use the built-in prompt","promptDescription":"The template variables {{previousSummaryVariable}} and {{messagesVariable}} are replaced with the previous summary and the messages being summarized.","saved":"Compaction settings saved","saveFailed":"Could not save the compaction settings","loadFailed":"Could not load the compaction settings"},"sessions":{"title":"Sessions","description":"Everywhere this account is signed in. Signing a session out takes effect immediately; signing in again restores access.","signOutOthers":"Sign out other sessions","signingOutOthers":"Signing out…","signOut":"Sign out","signingOut":"Signing out…","revoked":"Session signed out.","revokeFailed":"The session could not be signed out.","othersRevoked":"Other sessions signed out: {{count}}","loadFailed":"The sessions could not be loaded.","empty":"No sessions found.","current":"This session","revokedBadge":"Signed out","unknownDevice":"Unknown device","createdAt":"Signed in","lastSeenAt":"Last active","expiresAt":"Expires"},"apiKeys":{"title":"API keys","description":"Scoped tokens for scripts and integrations. Each key only has access to the scopes you pick.","newKeyTitle":"Your new API key","copy":"Copy","copied":"Copied to clipboard.","copyFailed":"Copy failed.","showOnceWarning":"Copy it now — it will not be shown again.","dismiss":"Done","createTitle":"Create a key","nameLabel":"Name","namePlaceholder":"e.g. CI pipeline","nameRequired":"Give the key a name.","expiryLabel":"Expires in days (optional)","expiryPlaceholder":"Never","expiryInvalid":"Expiry must be a whole number of days.","scopesLabel":"Scopes","scopesRequired":"Select at least one scope.","create":"Create key","creating":"Creating…","created":"API key created.","createFailed":"The API key could not be created.","revoke":"Revoke","revoking":"Revoking…","revoked":"API key revoked.","revokeFailed":"The API key could not be revoked.","revokedBadge":"Revoked","loadFailed":"The API keys could not be loaded.","empty":"No API keys yet.","createdAt":"Created","lastUsedAt":"Last used","expiresAt":"Expires","neverExpires":"Never"},"notifications":{"title":"Notifications","description":"How this browser is told about mentions, shares, reminders, and finished work.","pushTitle":"Browser notifications","pushHint":"Show system notifications from this device even when the tab is in the background.","enabled":"Browser notifications are on for this device.","disabled":"Browser notifications are off for this device.","enableFailed":"Browser notifications could not be enabled.","permissionDenied":"Notifications are blocked in the browser settings for this site.","unsupported":"This browser does not support push notifications.","workerMissing":"Push needs the installed app. Reload the production app and try again.","deviceNote":"Notifications are per device. Signing the session out also removes its push registration."}}`),models:{title:`Models`,subtitle:`Pull, manage, and monitor your Ollama models`,installed:`Installed Models`,available:`Available Models`,pull:`Pull Model`,pulling:`Pulling...`,delete:`Delete Model`,deleting:`Deleting...`,size:`Size`,modified:`Modified`,family:`Family`,parameters:`Parameters`,quantization:`Quantization`,noModels:`No models installed`,pullFirst:`Pull a model to get started`,noModelsFound:`No models found`},personas:{title:`Personas`,create:`Create Persona`,edit:`Edit Persona`,delete:`Delete Persona`,name:`Name`,description:`Description`,systemPrompt:`System Prompt`,model:`Model`,avatar:`Avatar`,background:`Background`,noPersonas:`No personas created`,createFirst:`Create your first persona to customize your chat experience`},gallery:{title:`Gallery`,subtitle:`Your AI-generated images, videos, and audio`,imageCount:`{{count}} images`,generate:`Generate Image`,generateDescription:`Create images with AI`,generating:`Generating...`,prompt:`Prompt`,promptPlaceholder:`Describe the image you want to generate...`,noImages:`No images generated yet`,download:`Download`,delete:`Delete`,regenerate:`Regenerate`,model:`Model`,size:`Size`,quality:`Quality`,created:`Created`},errors:{generic:`An error occurred`,network:`Network error. Please check your connection.`,unauthorized:`You are not authorized to perform this action.`,notFound:`The requested resource was not found.`,serverError:`Server error. Please try again later.`,validation:`Please check your input and try again.`},keyboard:{title:`Keyboard Shortcuts`,toggleSidebar:`Toggle sidebar`,openSettings:`Open settings`,toggleDarkMode:`Toggle dark mode`,showShortcuts:`Show keyboard shortcuts`,closeModals:`Close modals`,groups:{navigation:`Navigation`,general:`General`,chat:`Chat`,workspace:`Workspace`},actions:{sendMessage:`Send message`,newLine:`New line in message`,saveEdit:`Save an edited message`,cancelEdit:`Cancel editing`,saveFile:`Save file`,formatCode:`Format code`},description:`Every keyboard shortcut available in Libre WebUI.`,newChat:`New chat`,newWork:`New Work session`,openPalette:`Open command palette`},modelManager:{title:`Models`,loading:`Loading models...`,systemStatus:{online:`Ollama Online`,offline:`Ollama Offline`,models:`model`,models_plural:`models`,running:`running`,vram:`VRAM`},sections:{pull:`Pull New Model`,library:`Browse Library`,huggingface:`HuggingFace Hub`,running:`Running Models`,local:`Local Models`,advanced:`Advanced Actions`,catalog:`Model Catalog`},catalog:{searchPlaceholder:`Search models by name or provider...`,noModels:`No models are available yet.`,empty:`No models match your search.`,providerOllama:`Ollama`,hidden:`Hidden`,visibilityFailed:`Could not update model visibility.`,filterAll:`All models`,filterLocal:`Local`,filterProviders:`Providers`,filterHidden:`Hidden`,enableAll:`Enable shown`,disableAll:`Disable shown`,rename:`Edit name and picture`,setPicture:`Set picture`,clearPicture:`Remove picture`,pictureInvalid:`Choose an image file.`,pictureTooLarge:`Pictures must be under 192 KB.`,saving:`Saving…`,hide:`Hide from users`,show:`Show to users`},pull:{placeholder:`Enter model name (e.g., llama3.2:3b, deepseek-r1:14b)`,button:`Pull`,cancel:`Cancel`,popular:`Popular models:`,browseAll:`Browse all models on ollama.com`,success:`Model {{name}} pulled successfully`,cancelled:`Model pull cancelled`,failed:`Failed to pull model`,enterName:`Please enter a model name`,restricted:`Model installation is restricted to administrators on this instance.`},progress:{starting:`Initializing...`,pulling:`Downloading model...`,pullingLayer:`pulling`,verifying:`Verifying integrity...`,verifyingDigest:`verifying sha256 digest`,writing:`Writing manifest...`,cleaning:`Cleaning up...`},library:{available:`available`,search:`Search models...`,noResults:`No models found matching your criteria`,installed:`Installed`,more:`+{{count}} more`,refresh:`Refresh Library`},huggingface:{browseAll:`Browse all on HuggingFace`,checkingGguf:`Checking for GGUF files...`,noGgufAvailable:`No GGUF files available for direct Ollama pull`,ggufFilesCount:`GGUF Files ({{count}}) - Pull directly to Ollama`,noModelsFound:`No models found`,noResults:`No models found. Try adjusting your search or filters.`,browseAllLink:`Browse all`,search:`Search HuggingFace models...`,by:`by`,gated:`Gated`,viewOnHF:`View on HuggingFace`,sortDownloads:`Downloads`,sortLikes:`Likes`,sortRecent:`Recent`,taskTextGeneration:`Text Generation`,taskTextToSpeech:`Text to Speech`,taskTextToImage:`Text to Image`,taskSpeechRecognition:`Speech Recognition`,tasks:{textGen:`Text Generation`,tts:`Text to Speech`,image:`Text to Image`,stt:`Speech Recognition`},sort:{downloads:`Most Downloads`,likes:`Most Liked`,recent:`Recently Updated`}},local:{noModels:`No models installed yet`,pullToStart:`Pull a model above to get started`,installed:`installed`,running:`Running`,info:`Info`,copy:`Copy`,delete:`Delete`,deleteConfirm:`Are you sure you want to delete model "{{name}}"?`,deleteSuccess:`Model {{name}} deleted successfully`,deleteFailed:`Failed to delete model`},advanced:{createModel:`Create Model`,fromModelfile:`From Modelfile`,copyModel:`Copy Model`,duplicateExisting:`Duplicate existing`,testEmbeddings:`Test Embeddings`,generateVectors:`Generate vectors`,healthCheck:`Health Check`,testConnection:`Test connection`,healthy:`Ollama is healthy!`},modals:{details:{title:`Model Details`,info:`Model Information`,family:`Family`,parameters:`Parameters`,quantization:`Quantization`,format:`Format`,systemPrompt:`System Prompt`,template:`Template`,license:`License`,modelfile:`Modelfile`,noDetails:`No details available`},copy:{title:`Copy Model`,source:`Source Model`,selectModel:`Select a model...`,newName:`New Model Name`,placeholder:`e.g., my-custom-model`,copying:`Copying...`,button:`Copy Model`,success:`Model copied to {{name}}`,failed:`Failed to copy model`,enterBoth:`Please enter both source and destination names`},create:{title:`Create Custom Model`,name:`Model Name`,namePlaceholder:`e.g., my-assistant`,modelfile:`Modelfile`,modelfilePlaceholder:`FROM llama3.2
3
+ SYSTEM You are a helpful assistant.`,see:`See`,docs:`Modelfile docs`,docsLink:`for syntax reference`,creating:`Creating...`,button:`Create Model`,success:`Model {{name}} created successfully`,failed:`Failed to create model`,enterBoth:`Please enter model name and Modelfile content`},embeddings:{title:`Test Embeddings`,model:`Embedding Model`,selectModel:`Select a model...`,recommended:`Recommended: nomic-embed-text, mxbai-embed-large`,input:`Input Text`,placeholder:`Enter text to generate embeddings for...`,generating:`Generating...`,button:`Generate Embeddings`,result:`Result ({{count}} dimensions)`,success:`Generated {{count}}-dimensional embedding vector`,failed:`Failed to generate embeddings`,enterBoth:`Please select a model and enter text`}}},personaManager:{title:`Personas`,subtitle:`Create and manage AI personas with custom personalities, memories, and behaviors`,loading:`Loading personas...`,createButton:`Create Persona`,importExport:`Import/Export`,stats:{title:`Your Personas`,count:`{{count}} persona created`,count_plural:`{{count}} personas created`},empty:{title:`No personas yet`,description:`Create your first persona to get started with personalized AI interactions`,button:`Create Your First Persona`},deleteConfirm:`Are you sure you want to delete "{{name}}"?`,deleteSuccess:`Persona "{{name}}" deleted successfully`,downloadSuccess:`Persona "{{name}}" downloaded successfully`,failed:`Failed to {{action}} persona`},personaForm:{title:{create:`Create New Persona`,edit:`Edit Persona`},subtitle:{create:`Create a new AI persona with custom personality, memory systems, and adaptive learning capabilities`,edit:`Customize your AI persona with advanced memory, adaptive learning, and intelligent parameters`},loading:`Loading form...`,saved:`Saved`,tabs:{basic:`Basic`,parameters:`Parameters`,memory:`Memory & Learning`,advanced:`Advanced`,bindings:`Bindings`},basic:{name:`Name`,namePlaceholder:`Enter persona name`,model:`Model`,selectModel:`Select a model`,description:`Description`,descriptionPlaceholder:`Describe your persona...`,systemPrompt:`System Prompt`,systemPromptPlaceholder:`Enter the system prompt that defines your persona behavior...`,systemPromptHint:`The system prompt defines how your persona will behave and respond.`},parameters:{temperature:`Temperature`,temperatureHint:`Controls creativity vs consistency`,topP:`Top-P`,topPHint:`Controls response diversity`,topK:`Top-K`,topKHint:`Limits vocabulary to top-k tokens`,contextWindow:`Context Window`,contextWindowHint:`Maximum conversation history length`,maxTokens:`Max Tokens`,maxTokensHint:`Maximum response length`,repeatPenalty:`Repeat Penalty`,repeatPenaltyHint:`Reduces repetitive responses`},memory:{title:`Memory System`,subtitle:`Persona remembers conversations over time`,enableHint:`Enable the memory system to let your persona remember conversations and build context over time.`,loading:`Loading memory status...`,noData:`No memory data yet`,memories:`Memories`,mbUsed:`MB Used`,lastBackup:`Last Backup`,never:`Never`,maxMemories:`Maximum Memories`,maxMemoriesHint:`How many memories this persona can store`,retention:`Memory Retention`,retentionHint:`Days to keep memories before cleanup`,autoCleanup:`Auto-cleanup old memories`,wipeAll:`Wipe All Memories`,wipeCannot:`This cannot be undone`,wipeButton:`Wipe`,wiping:`Wiping...`,wipeConfirm:`Are you sure you want to wipe all memories? This cannot be undone.`,wipeSuccess:`Wiped {{count}} memories`},learning:{title:`Adaptive Learning`,subtitle:`Persona evolves based on interactions`,enableHint:`Enable adaptive learning to let your persona evolve and personalize responses based on your interactions.`,speed:`Learning Speed`,slow:`Slow`,slowDesc:`Gradual changes`,balanced:`Balanced`,balancedDesc:`Moderate pace`,fast:`Fast`,fastDesc:`Quick adaptation`,autoAdapt:`Auto-adapt to user preferences`,whatLearns:`What the persona learns:`,conversationTone:`Conversation tone`,responseStyle:`Response style`,userPreferences:`User preferences`,topicInterests:`Topic interests`},advanced:{embeddingModel:`Embedding Model`,embeddingHint:`Select the model used for memory encoding and semantic search. Embedding models are shown first, followed by other available models.`,noModels:`No models found`,embeddingModels:`Embedding Models`,otherModels:`Other Models`,installHint:`Install an embedding model:`,recommended:`Recommended: nomic-embed-text, mxbai-embed-large, bge-m3, snowflake-arctic-embed`,aboutTitle:`About Advanced Settings`,aboutDescription:`The embedding model is used by the memory system to understand semantic meaning and find relevant memories during conversations. Choose a model that matches your use case and available resources.`},actions:{cancel:`Cancel`,save:`Save`,saving:`Saving...`,saveClose:`Save & Close`,create:`Create`},success:{created:`Persona created`,updated:`Persona updated`},error:{saveFailed:`Failed to save`},bindings:{toolServers:`Tool servers`,toolServersHint:`Servers this persona may call. Leaving this empty offers every server the user can already reach.`,noToolServers:`No tool servers are available to you.`,builtinTools:`Built-in tools`,builtinToolsHint:`Tools the server implements itself. Leaving this empty offers all of them.`,noBuiltinTools:`No built-in tools are available.`,builtin:{web_search:`Web search`,search_documents:`Search documents`,load_skill:`Load skill`},skills:`Skills`,skillsHint:`Skills the model may load while this persona is active.`,noSkills:`You have not created any skills yet.`,collections:`Knowledge collections`,collectionsHint:`Document collections this persona can search.`,noCollections:`You have not created any collections yet.`,prompt:`Prompt`,promptHint:`A prompt to seed every new chat with this persona.`,noPrompt:`No prompt`,version:`Bindings revision {{version}}`}},personaCard:{enhanced:`Enhanced`,systemPrompt:`System Prompt`,memories:`memories`,use:`Use`,editTooltip:`Edit persona`,downloadTooltip:`Download persona`,backup:`Backup`,exportDNA:`Export DNA`,wipeMemories:`Wipe Memories`,wipeConfirm:`Are you sure you want to wipe all memories for this persona? This action cannot be undone.`,wipeSuccess:`Wiped {{count}} memories`,backupSuccess:`Persona backup downloaded successfully`,dnaSuccess:`Persona DNA exported successfully`,failed:`Failed to {{action}}`,shareTooltip:`Share this persona`},userManager:{title:`User Management`,subtitle:`Manage user accounts and permissions`,pageDescription:`Manage user accounts, permissions, and access controls for your Libre WebUI instance.`,loading:`Loading users...`,createUser:`Create User`,search:`Search users...`,noUsers:`No users found`,noUsersMatching:`No users matching your search`,columns:{user:`User`,email:`Email`,role:`Role`,created:`Created`,actions:`Actions`},roles:{admin:`Admin`,user:`User`},noEmail:`No email`,deleteConfirm:`Are you sure you want to delete user "{{name}}"?`,deleteSuccess:`User deleted successfully`,deleteFailed:`Failed to delete user`,cannotDeleteSelf:`You cannot delete your own account`,approval:{title:`Pending approvals`,description:`Review new registrations before allowing them into this instance.`,registered:`Registered`,activate:`Activate account`,reject:`Reject registration`,approved:`{{name}} can now sign in.`,failed:`The account could not be approved.`,notification:`{{count}} registration(s) are waiting for your approval.`,notificationBadge:`{{count}} pending user approvals`},form:{title:{create:`Create User`,edit:`Edit User`},username:`Username`,usernamePlaceholder:`Enter username`,email:`Email`,emailPlaceholder:`Enter email (optional)`,password:`Password`,passwordPlaceholder:`Enter password`,passwordHint:`Leave blank to keep current password`,role:`Role`,creating:`Creating...`,updating:`Updating...`,createButton:`Create User`,updateButton:`Update User`,createSuccess:`User created successfully`,updateSuccess:`User updated successfully`,createFailed:`Failed to create user`,updateFailed:`Failed to update user`},workAccess:{title:`Work access`,description:`Allow all active users to create and run Work tasks in isolated sandboxes. Administrators always have access; host folder workspaces remain admin-only.`,saved:`Work access updated`,saveFailed:`Could not update Work access`},workPolicies:{title:`Work policies`,description:`Named runtime presets (image, limits, idle stop) a task can be created under. Empty fields inherit the global defaults.`,add:`Add policy`,name:`Name`,image:`Image`,memory:`Memory`,cpu:`CPUs`,pids:`PID limit`,workspaceSize:`Workspace size`,idleMinutes:`Idle stop (minutes)`,networkDefault:`Network default`,networkInherit:`Inherit default`,networkOn:`Enabled`,networkOff:`Disabled`,save:`Save`,cancel:`Cancel`,edit:`Edit policy`,delete:`Delete policy`,deleteConfirm:`Delete this policy? Tasks using it fall back to the global defaults.`,empty:`No policies yet. Tasks use the global runtime defaults.`,saved:`Work policy saved`,deleted:`Work policy deleted`,failed:`Could not save the Work policy`,invalidNumber:`PID limit and idle stop must be numbers.`},modelAccess:{title:`Model downloads`,description:`Allow all active users to pull models from Ollama and the Hugging Face browser. Administrators can always download models.`,saved:`Model download access updated`,saveFailed:`Could not update model download access`},webSearchAccess:{title:`Web search`,description:`Allow all active users to use web search in chats and Work tasks. Administrators can always use it. Configure the engine in Settings > Search.`,saved:`Web search access updated`,saveFailed:`Could not update web search access`},agentAccess:{title:`Agents`,description:`Offer the Agents section (Libre Claw) to administrators. Agent CLIs run on the host as the server user, outside the Work sandbox.`,saved:`Agent access updated`,saveFailed:`Could not update agent access`,lockedByEnv:`Pinned by the AGENT_CLI_MODELS_ENABLED environment variable.`},groups:{title:`Groups`,description:`Group accounts to manage shared access, and inspect what any account can effectively do.`,newGroup:`New group`,nameLabel:`Name`,nameRequired:`Give the group a name.`,descriptionLabel:`Description (optional)`,create:`Create group`,creating:`Creating…`,created:`Group created.`,createFailed:`The group could not be created.`,deleted:`Group deleted.`,deleteFailed:`The group could not be deleted.`,deleteGroup:`Delete group`,loadFailed:`The groups could not be loaded.`,empty:`No groups yet.`,memberCount:`Members: {{count}}`,noMembers:`No members yet.`,addedAt:`Added`,addMember:`Add member`,add:`Add`,selectUser:`Select a user…`,memberAdded:`Member added.`,memberAddFailed:`The member could not be added.`,removeMember:`Remove member`,memberRemoved:`Member removed.`,memberRemoveFailed:`The member could not be removed.`,effectiveTitle:`Effective access`,effectiveDescription:`Pick an account to see the access it ends up with across role, groups, and grants.`,accessLookupFailed:`The effective access could not be loaded.`,roleLabel:`Role`,statusLabel:`Status`,memberOf:`Groups`,featuresLabel:`Feature access`,grantsLabel:`Grants`,grantVia:`via`},audit:{title:`Security audit log`,description:`Recent sign-ins, permission checks, and administrative changes on this instance.`,actionFilter:`Action`,actionPlaceholder:`e.g. auth.login`,resultFilter:`Result`,resultSuccess:`Success`,resultDenied:`Denied`,resultFailure:`Failure`,limitFilter:`Limit`,loadFailed:`The audit log could not be loaded.`,empty:`No audit events recorded yet.`,actor:`Actor`,target:`Target`},tools:{title:`Tool access`,description:`Allow everyone to call tool servers. When off, only administrators can.`,saved:`Tool access updated`,saveFailed:`Could not update tool access.`,lockedByEnv:`Locked by an environment variable on this server.`},voice:{title:`Voice access`,description:`Control who may use speech features. Administrators always have access.`,lockedByEnv:`Pinned by an environment variable`,saved:`Voice access updated`,saveFailed:`Failed to update voice access`,features:{stt:`Speech to text`,tts:`Text to speech`,voiceMode:`Voice mode`,voiceCloning:`Voice cloning`}},mfaPolicy:{title:`Two-factor policy`,description:`Whether accounts must complete a second sign-in step.`,requireAll:`Require two-factor for all users`,requireAllHint:`Users without a second factor must set one up at their next sign-in.`,lockedByEnv:`Pinned by MFA_REQUIRED_MODE.`,saved:`Two-factor policy saved.`,saveFailed:`The two-factor policy could not be saved.`},mfaReset:`Reset two-factor`,mfaResetConfirm:`Remove the second factor for {{name}}? They can sign in with their password and set it up again.`,mfaResetSuccess:`Two-factor removed for {{name}}.`,mfaResetNothing:`{{name}} had no two-factor enrollment.`,mfaResetFailed:`The two-factor reset failed.`},usageAnalytics:{eyebrow:`Administration`,title:`Provider Usage`,description:`Follow outbound API calls and model consumption across the enabled plugins on this instance.`,days:`{{count}} days`,refresh:`Refresh usage`,loadFailed:`Provider usage could not be loaded.`,metrics:{calls:`Calls`,tokens:`Tokens`},cards:{calls:`API calls`,callsDetail:`Across {{count}} active user(s)`,tokens:`Reported tokens`,tokensDetail:`Usage reported on {{count}} call(s)`,success:`Success rate`,successDetail:`{{count}} failed call(s)`,latency:`Average latency`,latencyDetail:`End-to-end provider time`},activity:{title:`Consumption over time`,callsDescription:`Daily outbound requests to enabled plugins`,tokensDescription:`Daily token totals reported by providers`,chartLabel:`Daily provider {{metric}} chart`},models:{title:`Model consumption`,description:`The models carrying the most traffic in this period.`,model:`Model`,success:`Success`,latency:`Latency`},providers:{title:`Enabled plugin traffic`},capabilities:{title:`Capability mix`,characters:`{{count}} characters`,bytes:`{{count}} bytes`,images:`{{count}} images`,jobs:`{{count}} video jobs`,inputs:`{{count}} inputs`,reportedTokens:`{{count}} reported tokens`},empty:{title:`No provider calls yet`,description:`Calls will appear here after an enabled plugin handles chat, Work, embedding, image, speech, sound, or video requests.`},privacyNote:`Usage is metered on the server at the outbound plugin boundary. Libre WebUI stores provider, model, timing, status, and reported counters—never prompts, responses, endpoints, credentials, or provider error bodies. Token totals include only calls where the provider returned usage metadata.`,heatmap:{title:`A year of activity`,description:`Daily provider calls over the past year, colored by each day's most-used model.`,calls:`calls`,noCalls:`No calls`,other:`Other models`,less:`Less`,more:`More`,yearTotal:`{{formatted}} calls in the last year`}},systemPage:{eyebrow:`Administration`,title:`System`,description:`Monitor the machine and runtime hosting this Libre WebUI instance.`,updated:`Updated {{date}}`,refresh:`Refresh system information`,loadFailed:`System information could not be loaded.`,cards:{uptime:`Host uptime`,uptimeDetail:`Running since {{date}}`,memory:`Memory used`,memoryDetail:`{{used}} of {{total}}`,freeSpace:`Free space`,freeSpaceDetail:`{{label}} · {{total}} total`,containers:`Running containers`,containersDetail:`{{total}} container(s) known to Docker`,dockerUnavailable:`Docker unavailable`,unavailable:`Unavailable`},host:{title:`Host & runtime`,description:`Operating system, processor, and Libre WebUI process details.`,container:`Container runtime`,native:`Native runtime`,hostname:`Hostname`,operatingSystem:`Operating system`,processor:`Processor`,logicalCpus:`logical CPUs`,loadAverage:`Load average · 1 / 5 / 15 min`,libreVersion:`Libre WebUI`,nodeVersion:`Node.js`,process:`Process`,workingDirectory:`Working directory`},memory:{title:`Memory`,description:`Runtime-visible system memory and application process usage.`,usedOf:`{{used}} used of {{total}}`,free:`{{value}} free`,processRss:`Process RSS`,heapUsed:`V8 heap used`,heapTotal:`V8 heap total`,external:`External memory`},storage:{title:`Storage`,description:`Available space for the runtime filesystem and persistent application data.`,used:`{{value}} used`,free:`{{value}} free`,empty:`Filesystem information is unavailable in this runtime.`},docker:{title:`Docker`,description:`Read-only Docker Engine status and a reduced list of containers.`,connected:`Connected`,unavailable:`Unavailable`,unavailableDetail:`Docker Engine diagnostics are unavailable.`,socketStatus:`Local socket: {{status}}`,mounted:`mounted`,notMounted:`not mounted`,running:`Running`,stopped:`Stopped`,paused:`Paused`,total:`Total`,version:`Version`,host:`Host`,architecture:`Architecture`,cpus:`CPUs`,memory:`Memory`,container:`Container`,image:`Image`,state:`State`,created:`Created`,empty:`Docker is connected and no containers are currently listed.`},network:{title:`Network`,description:`Runtime-visible interfaces, addresses, and Linux traffic counters.`,internal:`internal`,empty:`No network interfaces are visible to the application runtime.`},securityNote:`This page is restricted to administrators. The server returns operational summaries only: it does not expose environment variables, credentials, Docker labels, mounts, container commands, or inspect payloads. When Libre WebUI runs in a container, host-level CPU and memory details come from Docker Engine when its local socket is available; other values describe the application runtime.`,work:{title:`Work`,description:`Sandboxes across every user`,access:`Access`,accessAdmins:`Administrators only`,accessAllUsers:`All users`,runtimeAvailable:`Available`,runtimeUnavailable:`Unavailable`,activeRuntimes:`Active runtimes`,pendingCleanups:`Pending cleanups`,orphans:`Orphaned containers`,owner:`Owner`,task:`Task`,state:`State`,preview:`Preview`,terminals:`Terminals`,updated:`Updated`,stateRunning:`Running`,stateStopped:`Stopped`,stateStarting:`Starting`,stateUnknown:`Unknown`,noTasks:`No Work tasks yet.`},recovery:{title:`Recovery drills`,scheduleOn:`Runs automatically every {{hours}} h — each drill backs up, restores into an isolated copy, and verifies the result.`,scheduleOff:`Not scheduled — set RECOVERY_DRILL_INTERVAL_HOURS to run drills automatically.`,teamUnsupported:`Drills cover the solo (SQLite) profile; the team profile uses the coordinated backup CLI.`,runNow:`Run drill now`,running:`Running…`,passed:`Recovery drill passed.`,failed:`The recovery drill failed.`,lastPassed:`Last passed`,restoreTime:`Restore time (RTO)`,drillSpacing:`Drill spacing (RPO)`,archiveSize:`Archive size`,lastFailed:`Last drill failed on {{date}}`,originManual:`Manual`,originScheduled:`Scheduled`,columns:{when:`When`,origin:`Origin`,status:`Status`,restore:`Restore`},status:{passed:`Passed`,failed:`Failed`,running:`Running`}}},chatHistory:{label:`Conversation history`,jumpToTurn:`Jump to turn {{index}} of {{total}}`},chatMessage:{you:`You`,assistant:`Assistant`,system:`System`,conversationSummary:`Conversation summary`,restoreCompacted:`Restore the summarized messages`,restoreFailed:`Could not restore the summarized messages`,copy:`Copy`,copyMessage:`Copy message`,copied:`Copied!`,regenerate:`Regenerate`,regenerateResponse:`Regenerate response`,edit:`Edit`,editSystemMessage:`Edit system message`,saveChanges:`Save changes`,cancelEditing:`Cancel editing`,saveAndSubmit:`Save & submit`,goodResponse:`Good response`,badResponse:`Bad response`,delete:`Delete`,deleteConfirm:`Delete this message?`,branch:`Branch`,speaking:`Speaking...`,speakMessage:`Speak message`,stopSpeaking:`Stop speaking`,showMore:`Show more`,showLess:`Show less`,thinking:`Thinking`,thoughtFor:`Thought for {{duration}}`,hiddenLines:`{{count}} hidden lines`,systemMessagePlaceholder:`Enter your system message...`,fullSizeImage:`Full size image`,startConversation:`Start a conversation`,startConversationDescription:`Send a message to begin chatting with your AI assistant. Ask questions, get help with code, or have a natural conversation.`,scrollToBottom:`Scroll to bottom`,newMessages:`New messages`,feedbackTags:{accuracy:`Accuracy`,style:`Style`,incomplete:`Incomplete`,harmful:`Harmful`,formatting:`Formatting`},feedbackComment:`Add a comment…`},imageGallery:{title:`Image Gallery`,noImages:`No images yet`,noImagesHint:`Generate your first image using the panel on the right`,delete:`Delete`,download:`Download`,deleteConfirm:`Are you sure you want to delete this image?`,deleteSuccess:`Image deleted`,deleteFailed:`Failed to delete image`,downloadFailed:`Failed to download image`,loadMore:`Load More ({{current}} of {{total}})`,loadFailed:`Failed to load gallery`},imageGeneration:{title:`Generate Image`,prompt:`Prompt`,promptPlaceholder:`Describe the image you want to create...`,model:`Model`,selectModel:`Select model`,noModels:`No image generation models available`,configurePlugin:`Configure a plugin with image generation support`,size:`Size`,quality:`Quality`,style:`Style`,generate:`Generate`,generating:`Generating...`,success:`Image generated successfully`,failed:`Failed to generate image`,enterPrompt:`Please enter a prompt`,promptTooLong:`Prompt exceeds maximum length of {{max}} characters`},mediaGeneration:{title:`Generate media`,description:`Create video, sound, music, or speech with an activated media provider.`,image:`Image`,video:`Video`,audio:`Audio`,sound:`Sound`,speech:`Speech`,model:`Model`,voice:`Voice or voice ID`,cloneVoice:`Clone a reference voice`,cloneVoiceDescription:`Condition this speech on a reference recording instead of a preset voice.`,referenceAudio:`Reference audio`,referenceTranscript:`Exact reference transcript`,referenceTranscriptPlaceholder:`Enter exactly what is spoken in the reference recording…`,referenceAudioTooLarge:`Reference audio must be {{max}} or smaller.`,cloneConsent:`Only clone a voice when you have the speaker’s permission. The recording is sent to the selected provider for this generation and is not saved by Libre WebUI.`,saveVoiceProfile:`Save as a reusable voice`,saveVoiceProfileDescription:`Store this reference recording and transcript securely. Libre WebUI sends them to the selected provider for every Speech batch that uses this voice.`,voiceProfileName:`Saved voice name`,voiceProfileNamePlaceholder:`For example, My voice`,voiceStorageConsent:`I confirm that I have the speaker’s permission to clone and store this voice. The reference stays saved until I delete it.`,resolution:`Resolution`,aspectRatio:`Aspect ratio`,duration:`Duration`,providerDefault:`Provider default`,generateAudio:`Generate audio with the video when supported`,prompt:`Prompt`,text:`Text to speak`,videoPlaceholder:`Describe the scene, motion, camera, and lighting...`,audioPlaceholder:`Enter the text you want the voice to speak...`,soundPlaceholder:`Describe the sound, music, atmosphere, or spoken response you want...`,generate:`Generate`,generating:`Generating… this can take several minutes`,success:`Media generated and saved to Imagine`,successWithSavedVoice:`Media generated and “{{name}}” is now available in Speech settings`,failed:`Failed to generate media`,loadFailed:`Failed to load media providers`,noModels:`No {{kind}} models are available. Activate a compatible provider and save its credential first.`,consentTtl:{label:`Consent duration`,never:`Until I withdraw it`,days30:`30 days`,days90:`90 days`,days365:`One year`}},mediaGallery:{itemCount:`{{count}} items`,empty:`No generated media yet`,emptyHint:`Generate an image, video, or voice clip and it will appear here.`,filters:{all:`All`,image:`Images`,video:`Videos`,audio:`Audio`}},errorBoundary:{title:`Something went wrong`,description:`We encountered an unexpected error. Please try refreshing the page.`,tryAgain:`Refresh Page`,goHome:`Go to Home`,errorDetails:`Error Details (Development)`},documents:{title:`Documents`,upload:`Upload Document`,uploading:`Uploading...`,noDocuments:`No documents uploaded`,uploadHint:`Upload documents to use in your conversations`,delete:`Delete`,deleteConfirm:`Are you sure you want to delete this document?`,deleteSuccess:`Document deleted`,deleteFailed:`Failed to delete document`,uploadSuccess:`Document uploaded successfully`,uploadFailed:`Failed to upload document`,types:`Supported: PDF, TXT, MD, DOCX`,unsupportedFileType:`This file type is not supported`,fileSizeTooLarge:`File size must be less than 10MB`,uploadSuccessWithName:`Document "{{name}}" uploaded successfully`,removeSuccess:`Document removed successfully`,removeFailed:`Failed to remove document`,removeError:`An error occurred while removing the document`,clickToUpload:`Click to upload`,orDragAndDrop:`or drag and drop`,fileTypesAndSize:`PDF, Office, Markdown, HTML, code, CSV, image, and audio files up to 10MB`,uploadedDocuments:`Uploaded Documents`,removeDocument:`Remove document`,fullContextToggle:`Send full documents`,fullContextEstimate:`≈ {{tokens}} tokens`,fullContextTooLarge:`The attached documents exceed the full-context limit, so retrieval was used instead`,fullDocument:`Full document`},ttsButton:{speak:`Speak`,stop:`Stop`,speaking:`Speaking...`,generateFailed:`Failed to generate speech`,playbackFailed:`Audio playback failed`,stopSpeaking:`Stop speaking`,preparingSpeech:`Preparing speech...`,generatingSpeech:`Generating speech...`,bufferingSpeech:`Buffering speech...`,enableAudio:`Enable audio and read aloud`,enableAudioShort:`Enable audio`,readAloud:`Read aloud`},artifacts:{title:`Artifacts`,code:`Code`,preview:`Preview`,copy:`Copy code`,copied:`Copied!`,download:`Download`,expand:`Expand`,collapse:`Collapse`,openInNewTab:`Open in new tab`,invalidSvg:`Invalid SVG content`,invalidJson:`Invalid JSON content`,previewMode:`Preview mode`,codeMode:`Code mode`,copyContent:`Copy content`,openInPanel:`Open in panel`,created:`Created`,closePanelEsc:`Close panel (Esc)`,copyButton:`Copy`,dragEdgeToResize:`Drag edge to resize`,previewUnavailable:`Preview unavailable`,previewUnavailableDescription:`This artifact does not contain renderable preview content. Switch to code view to inspect the source.`,versionOf:`Version {{current}} of {{total}}`,previousVersion:`Previous version`,nextVersion:`Next version`},personaImportExport:{title:`Import & Export Personas`,description:`Export your personas to share them or import personas from others`,exportPersonas:`Export Personas`,importPersonas:`Import Personas`,noPersonasToExport:`No personas to export`,personasAvailable:`{{count}} persona available`,personasAvailable_plural:`{{count}} personas available`,exportAll:`Export All`,uploadJsonFile:`Upload JSON File`,pasteJsonLabel:`Paste JSON Data`,pasteJsonPlaceholder:`Paste persona JSON data here...`,importing:`Importing...`,importButton:`Import Persona(s)`,expectedFormat:`Expected JSON Format:`,exportSuccess:`Persona "{{name}}" exported successfully`,exportFailed:`Failed to export persona`,exportAllSuccess:`All {{count}} personas exported successfully`,exportAllFailed:`Failed to export personas`,pasteJsonData:`Please paste the persona JSON data`,importMultipleSuccess:`Successfully imported {{count}} personas`,importMultipleFailed:`Failed to import {{count}} personas`,importNoneFailed:`Failed to import any personas`,importSuccess:`Persona imported successfully`,importFailed:`Failed to import persona`},generationStats:{details:`Details`,promptTokens:`Prompt tokens:`,generatedTokens:`Generated tokens:`,totalTokens:`Total tokens:`,speed:`Speed:`,promptEval:`Prompt eval:`,generation:`Generation:`,modelLoad:`Model load:`,totalTime:`Total time:`,generatedAt:`Generated at:`},userMenu:{loggedOut:`Logged out successfully`,pictureUpdated:`Profile picture updated`,failedUpdateAvatar:`Failed to update avatar`,failedUpdatePicture:`Failed to update profile picture`,noEmail:`No email provided`,changePicture:`Change Picture`,settings:`Settings`,userManagement:`User Management`,signOut:`Sign Out`,changeProfilePicture:`Change Profile Picture`},pluginManager:{title:`Plugin Manager`,upload:`Upload`,addJson:`Add JSON`,browseHF:`Browse HF Hub`,confirmDelete:`Are you sure you want to delete this plugin?`,uploading:`Uploading plugin...`,pasteJson:`Paste plugin JSON here...`,installPlugin:`Install Plugin`,loading:`Loading plugins...`,noPlugins:`No Plugins Installed`,noPluginsDescription:`Upload a plugin file or add a plugin from JSON to get started.`,active:`Active`,id:`ID`,endpoint:`Endpoint`,activate:`Activate`,deactivate:`Deactivate`,activePlugin:`Active Plugin`,activePluginDescription:`All chat requests will be routed through this plugin`,variables:{title:`Variables`,save:`Save`,saving:`Saving...`,saved:`Variables saved`,saveFailed:`Failed to save variables`,resetDefaults:`Reset to Defaults`,reset:`Variables reset to defaults`,resetFailed:`Failed to reset variables`,sensitiveSet:`Value is set (enter new value to change)`,showValue:`Show {{label}} value`,hideValue:`Hide {{label}} value`,connection:`Connection`,advanced:`Advanced parameters`,inherited:`Use provider default`,inheritedValue:`Use provider default ({{value}})`,enabled:`Enabled`,disabled:`Disabled`,required:`A value is required`,fullApiEndpoint:`Full API endpoint URL`,endpointHelp:`Enter the complete request URL, including its operation path (for example, /v1/chat/completions), not only the provider base URL.`,invalidUrl:`Enter a valid full API endpoint URL, for example https://provider.example/v1/chat/completions`,insecureUrl:`API endpoints must use HTTP or HTTPS.`,httpWarning:`HTTP does not encrypt credentials or traffic. Use it only on a trusted network.`,invalidBaseUrl:`Base URLs cannot contain a query string or fragment.`,invalidApiPath:`Must start with / and contain no URL, query, fragment, or .. segment`,tooLong:`Value is too long`}},huggingface:{title:`HuggingFace Model Browser`,subtitle:`Browse and select models from the Hub`,searchPlaceholder:`Search models...`,filters:`Filters`,task:`Task`,sortBy:`Sort By`,noModels:`No models found`,adjustSearch:`Try adjusting your search or filters`,gated:`Gated`,selected:`Selected`,select:`Select`,refresh:`Refresh`,modelsFound:`models found`},demoMode:{title:`Demo Mode`,github:`GitHub`},libreClaw:{title:`Agents`,subtitle:`Local agent runs, approvals, schedules, memory, tools, and usage.`,dashboard:`Dashboard`,connection:{disconnectedTitle:`Libre Claw daemon is not connected`,disconnectedDescription:`Start it locally with <command>libre-claw start</command> or set <env>LIBRE_CLAW_BASE_URL</env> in the backend environment.`},status:{connected:`Connected`,disconnected:`Disconnected`,activeRuns:`{{count}} active`,activeRuns_plural:`{{count}} active`},states:{queued:`Queued`,running:`Running`,blocked:`Blocked`,done:`Done`,failed:`Failed`,cancelled:`Cancelled`},startRun:{title:`Start Agent Run`,placeholder:`Ask Libre Claw to inspect a repo, fix a bug, run a review, schedule a report...`,chatRun:`Chat run`,goalMode:`Goal mode`,providerOverride:`Provider override`,modelOverride:`Model override`,run:`Run`},modelRoute:{title:`Model Route`,providerPlaceholder:`provider`,modelPlaceholder:`model`,persistGlobal:`Persist to Libre Claw global config`,saveModel:`Save model`,theme:`Libre Claw theme`,saveTheme:`Save theme`},runs:{title:`Runs`,empty:`No Libre Claw runs yet.`},timeline:{title:`Run Timeline`,empty:`Select a run to inspect its events.`,streaming:`Streaming...`,assistantResponse:`Assistant response`,resultOk:`ok`,resultError:`error`,labels:{userMessage:`User message`,toolCall:`Tool call`,toolResult:`Tool result`,approvalRequest:`Approval request`,approvalResponse:`Approval response`,runStarted:`Run started`,runFinished:`Run finished`,usage:`Usage`,error:`Error`}},approvals:{needed:`Approval needed`,allowOnce:`Allow once`,alwaysAllowTool:`Always allow tool`,deny:`Deny`,toolApprovalRequested:`Tool approval requested`},automations:{title:`Automations`,namePlaceholder:`Name`,schedulePlaceholder:`daily 09:00`,promptPlaceholder:`Automation prompt`,create:`Create`,empty:`No scheduled Libre Claw automations.`,runNow:`Run now`,pause:`Pause`,resume:`Resume`,routes:{report:`Report`,telegram:`Telegram`},status:{active:`Active`,paused:`Paused`}},usageFallback:{title:`Usage And Fallback`,usage:`Usage`,fallbackRoute:`Fallback Route`,noUsage:`No usage records yet.`},metrics:{provider:`Provider`,model:`Model`,input:`Input`,output:`Output`,cached:`Cached`,reasoning:`Reasoning`,cost:`Cost`,tool:`Tool`,resolution:`Resolution`,state:`State`,stopReason:`Stop reason`,tokens:`{{formatted}} token`,tokens_plural:`{{formatted}} tokens`},fallbacks:{tool:`tool`,unknown:`unknown`,resolved:`resolved`,unknownError:`Unknown error`},toasts:{loadStatusFailed:`Could not load Libre Claw status`,enterTask:`Enter a task for Libre Claw`,runStarted:`Libre Claw run started`,startRunFailed:`Could not start Libre Claw run`,runCancelled:`Run cancelled`,cancelRunFailed:`Could not cancel run`,approved:`Approved`,denied:`Denied`,resolvePermissionFailed:`Could not resolve permission`,providerModelRequired:`Provider and model are required`,modelUpdated:`Libre Claw model updated`,updateModelFailed:`Could not update model`,themeUpdated:`Libre Claw theme updated`,updateThemeFailed:`Could not update theme`,automationRequired:`Automation name, schedule, and prompt are required`,automationCreated:`Automation created`,createAutomationFailed:`Could not create automation`,automationUpdated:`Automation updated`,updateAutomationFailed:`Could not update automation`}},work:{title:`Work`,subtitle:`Isolated model workspaces`,tasks:{title:`Work tasks`,subtitle:`Persistent local workspaces`,new:`New task`,emptyTitle:`No Work tasks yet`,empty:`Your Work tasks will appear here after you send the first message.`,untitled:`Untitled task`,actions:`Task actions`,delete:`Delete task`,deleteNamed:`Delete {{title}}`,deleteConfirm:`Delete “{{title}}” and its workspace permanently?`,close:`Close Work tasks`,open:`Open Work tasks`,rename:`Task title`,loading:`Loading task…`,notFound:`This Work task is unavailable`,back:`Start a new task`,status:`Status: {{status}}`},landing:{title:`Start a new Work task`,description:`Give a local or configured provider model a durable, isolated workspace. It can inspect files, run tools, and continue where it left off when you return.`,isolated:`Isolated`,isolatedBody:`Every task gets its own container and files.`,durable:`Durable`,durableBody:`Return to its conversation and workspace later.`,controlled:`Controlled`,controlledBody:`The runtime and task files stay isolated from the host.`},composer:{placeholder:`Describe what you want to build or change…`,model:`Work model`,noModels:`No Work-compatible models`,cancel:`Stop`,send:`Run`,hint:`Each task keeps its own files and history. Review model output before using it.`,remoteTitle:`Remote provider`,remoteHint:`Conversation and tool output are sent to the configured service. One autonomous run can make multiple provider calls and may incur charges. Workspace files stay local unless a tool returns their contents.`,remoteDismiss:`Dismiss`,remoteDismissLabel:`Dismiss remote provider notice`,remoteDismissFailed:`Could not save the remote provider preference.`,noModelSelected:`No Work-compatible model is selected.`},conversation:{ready:`Workspace ready`,empty:`Continue the task below. This conversation and its files stay attached to this workspace.`,loadOlder:`Load older messages`},status:{preparing:`Preparing isolated workspace…`,running:`Working in the local workspace…`},statusLabels:{idle:`Idle`,thinking:`Thinking`,complete:`Complete`,needsInput:`Needs input`,error:`Error`},live:{connecting:`Connecting to live updates…`,reconnecting:`Reconnecting to live updates…`,unavailable:`Live updates unavailable`,newActivity:`New activity`,skillsLoaded:`Workspace skills · {{count}}`},runtime:{unavailable:`Runtime unavailable`,ready:`Runtime ready`,readyOllama:`Docker ready`,readyPlugin:`Docker + plugin ready`,readyHybrid:`Docker + models ready`,reason:`Docker and an available Ollama or plugin model provider are required.`},workspace:{label:`Workspace views`,files:`Files`,activity:`Activity`,preview:`Preview`,resize:`Resize conversation and workspace`,resizeHint:`Drag to resize. Use arrow keys for precise control. Double-click or press Enter to reset.`,splitSize:`Conversation {{conversation}}%, workspace {{workspace}}%`,terminal:`Terminal`,git:`Git`},files:{discard:`Discard unsaved file changes?`,leaveWithDraft:`Leave this file? Your unsaved edit will remain as a browser draft.`,up:`Parent folder`,back:`Back to files`,empty:`No files in this folder yet.`,select:`Select a file to inspect and edit it.`,editorLabel:`File editor: {{path}}`,format:`Format`,formatted:`Code formatted.`,formatFailed:`Could not format this file.`,formatShortcut:`Format (Shift+Alt+F)`,formatTooLarge:`Formatting is limited to files under 100,000 characters and 4,000 lines.`,formatUnsupported:`Formatting is not available for this file type.`,saveShortcut:`Save (⌘/Ctrl+S)`,highlightPaused:`Live highlighting is paused for large files to keep editing responsive.`,plainTextLarge:`Plain text · large file`,changes:`Changes`,changesSince:`What changed since the last turn`,diffLabel:`Changes since the last turn: {{path}}`,diffFolded:`{{count}} unchanged lines`},activity:{empty:`Commands, file operations, and tool results will appear here.`,toolActivity:`Tool activity`,details:`Details`,kinds:{message:`Message`,toolCall:`Tool call`,toolResult:`Tool result`,error:`Error`}},preview:{command:`Optional start command`,start:`Start preview`,stop:`Stop preview`,open:`Open`,starting:`Starting preview…`,frameTitle:`Workspace preview`,failed:`The preview could not start. Check Activity, then try another command.`,empty:`Start the app inside this workspace to inspect it here.`},mobile:{surface:`Task surface`,conversation:`Conversation`,workspace:`Workspace`},toasts:{runFailed:`Could not start the Work task.`,updateFailed:`Could not update this task.`,renameFailed:`Could not rename this task.`,cancelled:`Work run stopped.`,cancelFailed:`Could not stop the Work run.`,deleteFailed:`Could not delete this Work task.`,saveFailed:`Could not save this file.`,saved:`File saved.`,previewFailed:`Could not start the preview.`,previewStopFailed:`Could not stop the preview.`},terminal:{connecting:`Opening a shell in the sandbox…`,closed:`Terminal session ended.`,failed:`The terminal session could not start.`,reconnect:`Reconnect`,unavailable:`The interactive terminal is not available in this deployment.`,blockedByRun:`The model is using this container. The terminal opens when the turn finishes.`,taskRunning:`Model turn in progress`},policy:{label:`Runtime policy`,default:`Default (global limits)`},git:{actionFailed:`Git action failed.`,blockedByPreview:`Stop the preview before changing Git state.`,blockedByRun:`Git write actions unlock when the model turn finishes.`,branchCreated:`Created {{name}}.`,branchSwitched:`Switched to {{name}}.`,clean:`Working tree is clean.`,commit:`Commit staged changes`,commitMessage:`Commit message`,committed:`Commit created.`,detached:`detached HEAD`,diff:`Diff preview`,diffFailed:`Could not load this diff.`,history:`Local history`,initialize:`Initialize Git`,initializeDescription:`Create a local repository for status, diffs, branches, and commits. No remote credentials are connected.`,initialized:`Git repository initialized.`,loadFailed:`Could not load Git status.`,localOnly:`Local Git only. Push, pull, and pull requests require a separate trusted credential broker.`,newBranch:`New local branch`,noCommits:`No commits yet.`,noDiff:`No textual diff is available yet. Untracked files appear after staging.`,notInitialized:`Git is not initialized`,selectChange:`Select a changed file to inspect its diff.`,selectPath:`Select {{path}}`,stageAll:`Stage all`,stageSelected:`Stage {{count}}`,staged:`Changes staged.`,switchBranch:`Switch local branch`,changes:`Changes`,createBranch:`Create`,filterFiles:`Filter changed files`,noFilterMatches:`No changed files match this filter.`,allChanges:`All changes`,diffTruncated:`This diff is truncated.`,binaryFile:`Binary file, no text diff.`},hostWorkspace:{hint:`Leave blank for an isolated workspace, or point the task at a folder on this machine.`,label:`Workspace folder (optional)`,warning:`The task can read and write this folder directly. Leave blank to use an isolated workspace instead.`}},personaBackground:{label:`Background Image`,uploadBackgroundImage:`Upload background image`,dragAndDrop:`Drag and drop an image or click to browse`,chooseImage:`Choose Image`,uploading:`Uploading...`,enterImageUrl:`Or enter image URL`,supportedFormats:`Supports: JPG, PNG, GIF, WebP (max 5MB). Wide landscape images work best.`,customBackground:`Custom background image`,clickToChange:`Click to change or remove`,removed:`Background removed`,uploaded:`Background uploaded successfully`,invalidFile:`Please select a valid image file`,fileTooLarge:`Background image size must be less than 5MB`,readFailed:`Failed to read image file`,uploadFailed:`Failed to upload background image`},modelSelector:{searchInstalled:`Search installed models...`,searchOllama:`Search Ollama library...`,searchHuggingFace:`Search HuggingFace...`,selectModel:`Select a model`,personas:`Personas`,ollamaModels:`Ollama Models`,pluginModels:`Plugin Models`,actions:`Actions`,installed:`Installed`,use:`Use`,pull:`Pull`,pullRestricted:`Model installation is restricted to administrators on this instance.`,adminOnlyPull:`Admins only`,legacyProvider:`provider not recorded`,providerNotRecorded:`Provider not recorded`,providerUnavailable:`provider unavailable`,reselectProvider:`reselect a provider to pin this model`,unavailable:`unavailable`,unavailableSelections:`Unavailable selections`,agentModels:`Agents`},whatsNew:{title:`What's new`,releaseNotes:`Release notes`,cta:`Okay, let's go`,starAsk:`Enjoying Libre WebUI? Leave a star on GitHub`},notes:{title:`Notes`,new:`New note`,untitled:`Untitled`,empty:`No notes yet`,selectOrCreate:`Select a note or create a new one`,contentPlaceholder:`Write in Markdown…`,saved:`Saved`,saveFailed:`Could not save the note`,createFailed:`Could not create a note`,deleteConfirm:`Delete this note?`,deleteFailed:`Could not delete the note`,tools:`Note tools`,revisions:`History`,attachments:`Attachments`,share:`Share`,assist:`AI edit`,noRevisions:`No earlier versions yet`,restore:`Restore`,revisionRestored:`Version restored`,revisionRestoreFailed:`Could not restore this version`,addAttachment:`Add attachment`,noAttachments:`No attachments yet`,attachmentAdded:`Attachment added`,attachmentFailed:`Could not add the attachment`,attachmentDownloadFailed:`Could not download the attachment`,shareUsernamePlaceholder:`Username`,permissionRead:`Can view`,permissionWrite:`Can edit`,shareAction:`Share`,notShared:`Not shared with anyone yet`,revokeShare:`Revoke access`,shareHint:`Shared notes appear in the other person's note list. Access can be revoked at any time.`,shareUserNotFound:`No user with that name`,shareAdded:`Shared with {{username}}`,shareFailed:`Could not share the note`,assistPlaceholder:`Describe the change, e.g. tighten the summary or fix the grammar`,assistGenerate:`Propose edit`,assistNoModel:`Select a model in Chat first`,assistNoChanges:`The model proposed no changes`,assistApply:`Apply`,assistDiscard:`Discard`,assistApplied:`Edit applied`,assistRevisionHint:`Applying keeps the previous version in History, so any AI edit can be undone.`,assistFailed:`Could not generate the edit`,pin:`Pin note`,unpin:`Unpin note`,pinned:`Pinned`,export:`Download as Markdown`,sharedWithYou:`Shared with you`},calendar:{title:`Calendar`,today:`Today`,month:`Month`,week:`Week`,previous:`Previous`,next:`Next`,newEvent:`New event`,editEvent:`Edit event`,eventTitle:`Title`,titlePlaceholder:`Event title`,date:`Date`,start:`Start`,end:`End`,allDay:`All day`,repeat:`Repeat`,repeatNone:`Does not repeat`,repeatDaily:`Daily`,repeatWeekly:`Weekly`,repeatMonthly:`Monthly`,repeatYearly:`Yearly`,notes:`Notes`,more:`+{{n}} more`,loadFailed:`Failed to load calendar`,saveFailed:`Failed to save event`,deleteFailed:`Failed to delete event`,day:`Day`,calendarLabel:`Calendar`,personalCalendar:`Personal`,reminderLabel:`Reminder`,reminderNone:`No reminder`,reminderMinutes:`{{minutes}} minutes before`,reminderHour:`1 hour before`,reminderDay:`1 day before`,sharedReadOnly:`This event is shared with you as view-only.`,sharedBadge:`shared`,shareCalendar:`Share calendar`,newCalendarPlaceholder:`New calendar…`,calendarSaveFailed:`The calendar could not be saved`,exportFailed:`The calendar could not be exported`,importFailed:`The file could not be imported`,importResult:`Imported {{total}} events`,importIcs:`Import`,exportIcs:`Export`},automations:{title:`Automations`,tab:{automations:`Automations`,runs:`Runs`},newAutomation:`New automation`,editAutomation:`Edit automation`,empty:`No automations yet. Create one to run a task on a schedule.`,loadFailed:`Failed to load automations`,saveFailed:`Failed to save the automation`,actionFailed:`The action failed`,runQueued:`Run started`,status:{active:`Active`,paused:`Paused`},nextRun:`Next run {{when}}`,actions:`Actions`,pause:`Pause`,resume:`Resume`,runNow:`Run now`,openChat:`Open chat`,noRuns:`No runs yet`,deletedAutomation:`Deleted automation`,runHistory:`Run history (last 30 days)`,succeeded:`succeeded`,failed:`failed`,form:{name:`Name`,namePlaceholder:`My automation`,triggers:`Triggers`,addTrigger:`Add trigger`,instructions:`Instructions`,instructionsPlaceholder:`What should run on this schedule?`,model:`Model`,modelAuto:`Auto`,notification:`Notification`,notifyApp:`App`,notifyOff:`Off`,frequency:`Frequency`,time:`Time`,minute:`Minute`,fromHour:`From`,toHour:`To`,weekday:`Weekday`,dayOfMonth:`Day`,month:`Month`},kind:{once:`Once`,hourly:`Hourly`,daily:`Daily`,weekly:`Weekly`,monthly:`Monthly`,yearly:`Yearly`},trigger:{once:`Once on {{when}}`,hourly:`Hourly at :{{minute}}`,daily:`Daily at {{time}}`,weekly:`Weekly on {{day}} at {{time}}`,monthly:`Monthly on day {{day}} at {{time}}`,yearly:`Yearly on {{date}} at {{time}}`},finishedNotification:`{{n}} automation run(s) finished`,templatesTitle:`Templates`,templates:{morningBrief:{name:`Morning brief`,description:`Start the day with headlines and priorities.`},newsDigest:{name:`AI news digest`,description:`Model releases, research, and funding that matter.`},weeklyReview:{name:`Weekly review`,description:`Wrap the week: wins, loose ends, next priorities.`},monthlyReport:{name:`Monthly report`,description:`A status report outline on the first of each month.`}}},home:{active:`active`,continue:`Continue`,start:`Start`,explore:`Explore`},palette:{empty:`No matches.`,placeholder:`Search chats, Work, actions…`,toggleTheme:`Toggle theme`,actions:`Actions`,chats:`Chats`,search:`Search`,settings:`Settings`,work:`Work`,messages:`Messages`,notes:`Notes`,documents:`Documents`},tabs:{actions:`Tab actions`,close:`Close tab`,closeAll:`Close all tabs`,closeOthers:`Close other tabs`,closeRight:`Close tabs to the right`,home:`Home`,label:`Open tabs`,new:`New tab`,newWork:`New Work`,chat:`Chat`,newChat:`New Chat`,work:`Work`},tools:{arguments:`Arguments`,result:`Result`,callStatus:{awaiting_approval:`Waiting for approval`,running:`Running`,succeeded:`Done`,failed:`Failed`,denied:`Denied`,cancelled:`Cancelled`},approval:{title:`Tool approval needed`,description:`The model wants to run {{tool}} on {{server}}. This call can change data outside this chat.`,builtinSource:`this server`,allowOnce:`Allow once`,allowSession:`Allow for this chat`,allowAlways:`Always allow`,deny:`Deny`}},promptsPage:{title:`Prompts`,description:`Reusable prompt templates with typed variables. Type / in the chat composer to insert one.`,newPrompt:`New prompt`,editPrompt:`Edit prompt`,empty:`No prompts yet`,emptyHint:`A prompt is a saved message template. Once you create one, typing /slug in the chat composer inserts it and asks for any variables it declares.`,loadFailed:`Could not load your prompts.`,saved:`Prompt saved`,saveFailed:`Could not save the prompt.`,deleted:`Prompt deleted`,deleteFailed:`Could not delete the prompt.`,deleteTitle:`Delete prompt`,deleteConfirm:`Delete "{{title}}"? This also removes its version history.`,exportFailed:`Could not export the prompt.`,imported:`Prompt imported`,importFailed:`Could not import that file.`,historyFailed:`Could not load the version history.`,rolledBack:`Prompt rolled back`,rollbackFailed:`Could not roll the prompt back.`,versionLabel:`v{{version}}`,updated:`Updated {{when}}`,form:{slug:`Slug`,slugPlaceholder:`weekly-report`,slugHint:`Used as /slug in the composer.`,slugInvalid:`Lowercase letters, digits and hyphens only.`,title:`Title`,titlePlaceholder:`Weekly report`,description:`Description`,descriptionPlaceholder:`What this prompt is for`,content:`Content`,contentPlaceholder:`Write the prompt. Wrap anything you want filled in later in double braces.`,contentHint:`A placeholder is a name in double braces. Declare it below to give it a label or a default.`,tags:`Tags`,tagsPlaceholder:`research, writing`,variables:`Variables`,variablesHint:`Optional. Declare a placeholder here to give it a label, a default or a set of choices.`,variableName:`Name`,variableType:`Type`,variableLabel:`Label`,variableDefault:`Default`,variableRequired:`Required`,variableOptions:`Options`,variableOptionsPlaceholder:`Comma-separated choices`,addVariable:`Add variable`,removeVariable:`Remove variable`},variableTypes:{text:`Text`,number:`Number`,select:`Choice`,boolean:`Yes or no`},history:{open:`Version history`,title:`History of {{title}}`,subtitle:`Rolling back saves the picked revision as a new version. Nothing is overwritten.`,empty:`No earlier versions yet.`,current:`Current`,rollback:`Roll back`,rollingBack:`Rolling back...`},templatesTitle:`Start from a template`,templates:{reviewPr:{name:`Pull request review`,description:`Structured code review with adjustable strictness.`},summarize:{name:`Summarize for an audience`,description:`Bullet-point summary tuned to a reader.`},translate:{name:`Translate`,description:`Translation that preserves tone and formatting.`},explainCode:{name:`Explain code`,description:`Walkthrough plus edge cases and risks.`}}},skillsPage:{title:`Skills`,description:`Named instruction sets the model can load on demand while it works.`,newSkill:`New skill`,editSkill:`Edit skill`,empty:`No skills yet`,emptyHint:`A skill is a set of instructions the model loads only when it needs them. Mention $slug in a message, or let the model reach for it through the load_skill tool.`,loadFailed:`Could not load your skills.`,saved:`Skill saved`,saveFailed:`Could not save the skill.`,toggleFailed:`Could not change the skill.`,deleted:`Skill deleted`,deleteFailed:`Could not delete the skill.`,deleteTitle:`Delete skill`,deleteConfirm:`Delete "{{name}}"? This also removes its version history.`,exportFailed:`Could not export the skill.`,imported:`Skill imported`,importFailed:`Could not import that file.`,historyFailed:`Could not load the version history.`,rolledBack:`Skill rolled back`,rollbackFailed:`Could not roll the skill back.`,versionLabel:`v{{version}}`,updated:`Updated {{when}}`,form:{slug:`Slug`,slugPlaceholder:`code-review`,slugHint:`Used as $slug when you mention the skill.`,slugInvalid:`Lowercase letters, digits and hyphens only.`,name:`Name`,namePlaceholder:`Code review`,description:`Description`,descriptionPlaceholder:`When to use this skill`,descriptionHint:`This is the manifest the model sees. Write it so the model can tell when the skill applies without loading it.`,instructions:`Instructions`,instructionsPlaceholder:`Markdown instructions the model reads once it loads this skill.`,instructionsHint:`Loaded only when the skill is used, so length here costs nothing until then.`,enabled:`Enabled`,enabledHint:`Disabled skills stay saved but are never offered to the model.`},history:{open:`Version history`,title:`History of {{name}}`},templatesTitle:`Start from a template`,templates:{citeSources:{name:`Cite sources`,description:`Numbered references with URLs, no unreferenced claims.`},releaseNotes:{name:`Release notes style`,description:`Grouped, user-facing entries without internal ids.`},meetingNotes:{name:`Meeting notes format`,description:`Decisions, action items, and open questions from a transcript.`}},importUrl:{button:`From URL`,title:`Import a skill from a URL`,hint:`Paste a skills.sh or GitHub link, owner/repo/skill, or a direct link to a SKILL.md file.`,placeholder:`https://skills.sh/owner/repo/skill or owner/repo/skill`,overwrite:`Overwrite my skill if the slug already exists`},files:{title:`Bundled files`,hint:`Reference documents and scripts the model reads on demand with read_skill_file.`,add:`Add file`,empty:`No bundled files yet.`,pathPlaceholder:`docs/reference.md`,contentPlaceholder:`File content…`,loadFailed:`Failed to load the file`,saveFailed:`Failed to save the file`,deleteFailed:`Failed to delete the file`},folderImport:{button:`From folder`,missingSkillMd:`The folder needs a SKILL.md file`,done:`Skill imported with {{count}} bundled files`}},toolsPage:{title:`Tools`,description:`Tool servers the model can call, and the approvals you have granted them.`,approvalNotice:`Tools that change data outside the chat always ask for approval, unless you granted that tool an always or per-chat approval.`,registerServer:`Register server`,registerHint:`Libre WebUI reads the server once and pins the tools it exposes. Refresh the server later to pick up changes.`,editServer:`Edit server`,empty:`No tool servers`,emptyHintAdmin:`Register an OpenAPI or MCP server to give the model something to call.`,emptyHintUser:`An administrator has not shared any tool servers with you yet.`,loadFailed:`Could not load the tool servers.`,saved:`Tool server saved`,saveFailed:`Could not save the tool server.`,deleted:`Tool server deleted`,deleteFailed:`Could not delete the tool server.`,deleteTitle:`Delete tool server`,deleteConfirm:`Delete "{{name}}"? Everyone loses access to its tools.`,refresh:`Refresh tools`,refreshed:`Tools re-read from the server`,refreshFailed:`Could not read the server.`,toolsLoadFailed:`Could not load the pinned tools.`,overrideFailed:`Could not change the tool.`,pinnedTools:`Pinned tools`,noPinnedTools:`This server exposed no tools.`,sideEffect:`Side effect`,sideEffectOverride:`Side effect`,specRevision:`Revision {{revision}}`,credential:`Personal credential`,credentialHint:`Stored encrypted and used only for your own calls to this server.`,credentialPlaceholder:`Paste your token`,credentialSet:`Credential set`,credentialMissing:`Credential needed`,credentialSaved:`Credential saved`,credentialSaveFailed:`Could not save the credential.`,credentialRemove:`Remove`,credentialRemoved:`Credential removed`,credentialRemoveFailed:`Could not remove the credential.`,builtinSource:`This server`,kinds:{openapi:`OpenAPI`,mcp:`MCP`},authModes:{none:`No authentication`,bearer:`Bearer token`,header:`Custom header`},accessModes:{"admins-only":`Administrators only`,"all-users":`Everyone`,granted:`Only people granted access`},form:{name:`Name`,namePlaceholder:`Weather API`,kind:`Kind`,description:`Description`,descriptionPlaceholder:`What this server does`,baseUrl:`Base URL`,specUrl:`Spec URL`,specUrlHint:`Optional. Defaults to the base URL when left empty.`,authMode:`Authentication`,authHeader:`Header name`,accessMode:`Who can use it`,timeoutMs:`Timeout (ms)`,maxResponseBytes:`Max response (bytes)`,serverDefault:`Server default`,enabled:`Enabled`,enabledHint:`Disabled servers stay registered but are never offered to the model.`},approvals:{title:`Standing approvals`,description:`Tools you allowed to run without asking again. Revoke one and it will ask the next time.`,empty:`No standing approvals.`,revoke:`Revoke`,revoked:`Approval revoked`,revokeFailed:`Could not revoke the approval.`,scope:{once:`Once`,session:`This chat`,always:`Always`}},templatesTitle:`Start from a template`,templates:{petstore:{name:`Petstore demo`,description:`A public demo API for a safe first end-to-end test.`},internalOpenApi:{name:`Internal API`,description:`A starting point for your own OpenAPI service.`},mcpServer:{name:`MCP server`,description:`A starting point for an MCP server over Streamable HTTP.`}}},composer:{promptMenu:{label:`Prompt library`,empty:`No prompts yet — create one in Settings → Prompts, or start typing a slug.`},skillMenu:{label:`Skills`,empty:`No skills yet — create one in Settings → Skills.`},variables:{title:`Fill in {{title}}`,insert:`Insert`,cancel:`Cancel`,required:`{{name}} is required`},toolsMenu:{enable:`Use tools for this message`,builtin:`Built-in tools`,servers:`Tool servers`,hint:`Side-effecting calls still ask for approval before they run.`}},share:{title:`Share “{{name}}”`,subtitle:`Give people or groups access. Only you can manage shares.`,kindUser:`User`,kindGroup:`Group`,usernamePlaceholder:`Exact username`,groupPlaceholder:`Exact group name`,permissionRead:`Can view`,permissionWrite:`Can edit`,action:`Share`,empty:`Not shared with anyone yet.`,hint:`Enter the exact username or group name. Recipients see it in their own workspace; revoking removes access immediately.`,revoke:`Revoke access`,added:`Shared with {{name}}`,failed:`Sharing failed`,userNotFound:`No user with that name`,groupNotFound:`No group with that name`},channels:{title:`Channels`,browsePublic:`Browse public channels`,newDm:`New direct message`,newChannel:`New channel`,empty:`No channels yet. Create one or browse public channels.`,selectPrompt:`Pick a channel to start talking`,pins:`Pinned`,members:`Members`,settings:`Channel settings`,sendFailed:`The message could not be sent`,uploadFailed:`The file could not be uploaded`,memberAdded:`Member added`,memberAddFailed:`That user could not be added`,attach:`Attach a file`,askModel:`Ask a model with this message`,noModel:`No model`,composerPlaceholder:`Write a message…`,thread:`Thread`,replyPlaceholder:`Reply…`,invitePlaceholder:`Username to invite`,roleOwner:`owner`,removeMember:`Remove from channel`,leave:`Leave channel`,noPins:`Nothing pinned yet.`,noMessages:`No messages yet — say hi.`,create:`Create`,createFailed:`The channel could not be created`,nameLabel:`Name`,typeLabel:`Type`,typePublic:`Public — anyone can join`,typePrivate:`Private — invite only`,descriptionLabel:`Description`,openDm:`Open conversation`,dmFailed:`The conversation could not be opened`,dmHint:`Direct messages are private between the two of you.`,dmPlaceholder:`Exact username`,noPublic:`No public channels to browse.`,joined:`Joined`,join:`Join`,save:`Save`,delete:`Delete channel`,modelAuthor:`Model`,unknownAuthor:`Someone`,edited:`edited`,deletedMessage:`This message was deleted`,modelThinking:`The model is thinking…`,react:`Add a reaction`,reply:`Reply in thread`,pin:`Pin message`,unpin:`Unpin message`,edit:`Edit message`,deleteMessage:`Delete message`,replyCount:`{{total}} replies`},notifications:{title:`Notifications`,empty:`You are all caught up.`,markAllRead:`Mark all as read`,markRead:`Mark as read`},voiceMode:{title:`Voice mode`,open:`Start voice mode`,close:`Close voice mode`,starting:`Starting…`,listening:`Listening…`,muted:`Microphone muted`,transcribing:`Transcribing…`,generating:`Thinking…`,speaking:`Speaking…`,mute:`Mute microphone`,unmute:`Unmute microphone`,finishTurn:`Done speaking`,skipReply:`Skip reply`,microphoneFailed:`Microphone unavailable`,transcriptionFailed:`Transcription failed`,replyTimeout:`The reply took too long`,unsupported:`Voice mode is unavailable`,unsupportedHint:`Voice mode needs a microphone and either a speech-to-text provider or browser speech recognition.`},imageEdit:{title:`Edit image`,prompt:`Describe the change`,promptPlaceholder:`For example: replace the sky with a sunset`,model:`Model`,apply:`Apply edit`,maskHint:`Paint over the areas to repaint; leave the canvas untouched to edit the whole image.`,brushSize:`Brush size`,clearMask:`Clear mask`,referenceImages:`Reference images (up to {{total}})`,noModels:`No configured model supports image editing.`,saved:`Edited image saved to the gallery`,failed:`Image edit failed`,loadFailed:`Failed to load the source image`},costs:{title:`Costs and budgets`,description:`Tariff prices applied to the usage ledger; budgets watch or cap spending.`,loadFailed:`Failed to load cost data`,saveFailed:`Save failed`,exportFailed:`Export failed`,exportCsv:`Export CSV`,totalSpend:`Total spend`,meteredEvents:`Priced events`,unmeteredEvents:`Unpriced events`,topModel:`Top model`,budgets:`Budgets`,noBudgets:`No budgets yet.`,budgetName:`Budget name`,principalId:`User or group id`,addBudget:`Add budget`,deleteBudget:`Delete budget`,budgetSaved:`Budget saved`,scope:{instance:`Whole instance`,user:`User`,group:`Group`},period:{daily:`Daily`,weekly:`Weekly`,monthly:`Monthly`},mode:{observe:`Observe`,soft:`Alert`,hard:`Alert and block`},tariffs:`Tariffs`,noTariffs:`No tariffs yet — costs stay unpriced until you add prices.`,plugin:`Plugin`,model:`Model`,modelOptional:`Model (optional)`,allModels:`All models`,inputPerMillion:`Input $/M tokens`,outputPerMillion:`Output $/M tokens`,unitPrice:`Unit price`,effectiveFrom:`Effective from`,addTariff:`Add tariff`,deleteTariff:`Delete tariff`,tariffSaved:`Tariff saved`},evaluations:{title:`Evaluations`,description:`Blind arena matches, an Elo leaderboard, reusable evaluation sets, and your feedback dataset.`,loadFailed:`Failed to load evaluations`,matchFailed:`The arena match failed`,voteRecorded:`Vote recorded`,voteFailed:`Failed to record the vote`,saveFailed:`Save failed`,exportFailed:`Export failed`,setSaved:`Evaluation set saved`,runStarted:`Evaluation run started`,pickModel:`Pick a model`,tabs:{arena:`Arena`,leaderboard:`Leaderboard`,sets:`Eval sets`,feedback:`Feedback`},arenaModelA:`Model A`,arenaModelB:`Model B`,arenaPrompt:`Ask both models the same question…`,startMatch:`Start match`,arenaHint:`Model identities stay hidden until you vote.`,candidate:`Response {{letter}}`,voteFirst:`First is better`,voteSecond:`Second is better`,voteTie:`Tie`,voteBothBad:`Both bad`,model:`Model`,rating:`Rating`,record:`Record`,votes:`Votes`,noVotes:`No arena votes yet — start a match to build the leaderboard.`,newSet:`New evaluation set`,setName:`Set name`,setPrompts:`One prompt per line…`,saveSet:`Save set`,yourSets:`Your sets`,noSets:`No evaluation sets yet.`,itemCount:`{{total}} prompts`,run:`Run`,deleteSet:`Delete set`,cancelRun:`Cancel run`,exportRun:`Export run`,status:{queued:`Queued`,running:`Running`,completed:`Completed`,failed:`Failed`,cancelled:`Cancelled`},noFeedback:`No feedback yet — rate assistant replies to build your dataset.`},passwordStrength:{levels:{weak:`Weak`,fair:`Fair`,good:`Good`,strong:`Strong`},checks:{minLength:`At least 12 characters`,hasCase:`Uppercase and lowercase letters`,hasNumber:`At least one number`,tooLong:`No more than 72 bytes`}}},de={en:{translation:D}},O=[{code:`en`,name:`English`,nativeName:`English`,dir:`ltr`},{code:`ar`,name:`Arabic`,nativeName:`العربية`,dir:`rtl`},{code:`bn`,name:`Bengali`,nativeName:`বাংলা`,dir:`ltr`},{code:`cs`,name:`Czech`,nativeName:`Čeština`,dir:`ltr`},{code:`da`,name:`Danish`,nativeName:`Dansk`,dir:`ltr`},{code:`de`,name:`German`,nativeName:`Deutsch`,dir:`ltr`},{code:`es`,name:`Spanish`,nativeName:`Español`,dir:`ltr`},{code:`fr`,name:`French`,nativeName:`Français`,dir:`ltr`},{code:`hi`,name:`Hindi`,nativeName:`हिन्दी`,dir:`ltr`},{code:`id`,name:`Indonesian`,nativeName:`Bahasa Indonesia`,dir:`ltr`},{code:`is`,name:`Icelandic`,nativeName:`Íslenska`,dir:`ltr`},{code:`it`,name:`Italian`,nativeName:`Italiano`,dir:`ltr`},{code:`ja`,name:`Japanese`,nativeName:`日本語`,dir:`ltr`},{code:`ko`,name:`Korean`,nativeName:`한국어`,dir:`ltr`},{code:`ms`,name:`Malay`,nativeName:`Bahasa Melayu`,dir:`ltr`},{code:`nl`,name:`Dutch`,nativeName:`Nederlands`,dir:`ltr`},{code:`pl`,name:`Polish`,nativeName:`Polski`,dir:`ltr`},{code:`pt`,name:`Portuguese`,nativeName:`Português`,dir:`ltr`},{code:`ru`,name:`Russian`,nativeName:`Русский`,dir:`ltr`},{code:`sv`,name:`Swedish`,nativeName:`Svenska`,dir:`ltr`},{code:`th`,name:`Thai`,nativeName:`ไทย`,dir:`ltr`},{code:`tr`,name:`Turkish`,nativeName:`Türkçe`,dir:`ltr`},{code:`uk`,name:`Ukrainian`,nativeName:`Українська`,dir:`ltr`},{code:`vi`,name:`Vietnamese`,nativeName:`Tiếng Việt`,dir:`ltr`},{code:`zh`,name:`Chinese`,nativeName:`中文`,dir:`ltr`}],fe=[`ar`,`he`,`fa`,`ur`],k=O.map(e=>e.code),pe={en:()=>Promise.resolve(D),ar:()=>e(()=>import(`./ar-YHHTVP8f.js`).then(e=>e.default),[]),bn:()=>e(()=>import(`./bn-C8VTxBVl.js`).then(e=>e.default),[]),cs:()=>e(()=>import(`./cs-CCngB5fC.js`).then(e=>e.default),[]),da:()=>e(()=>import(`./da-CM2PP2ma.js`).then(e=>e.default),[]),de:()=>e(()=>import(`./de-BqVkD-dw.js`).then(e=>e.default),[]),es:()=>e(()=>import(`./es-BtWsWBjZ.js`).then(e=>e.default),[]),fr:()=>e(()=>import(`./fr-C68w9abT.js`).then(e=>e.default),[]),hi:()=>e(()=>import(`./hi-DtBlcyXZ.js`).then(e=>e.default),[]),id:()=>e(()=>import(`./id-BWzIu8tn.js`).then(e=>e.default),[]),is:()=>e(()=>import(`./is-yeFwu4dJ.js`).then(e=>e.default),[]),it:()=>e(()=>import(`./it-AxEMG8Jg.js`).then(e=>e.default),[]),ja:()=>e(()=>import(`./ja-B-VyokB8.js`).then(e=>e.default),[]),ko:()=>e(()=>import(`./ko-CvwzYr9k.js`).then(e=>e.default),[]),ms:()=>e(()=>import(`./ms-BhEwb4b7.js`).then(e=>e.default),[]),nl:()=>e(()=>import(`./nl-Dq-QRx1L.js`).then(e=>e.default),[]),pl:()=>e(()=>import(`./pl-BNEy8mQm.js`).then(e=>e.default),[]),pt:()=>e(()=>import(`./pt-_3Jl3FdY.js`).then(e=>e.default),[]),ru:()=>e(()=>import(`./ru-IhQiJ8ta.js`).then(e=>e.default),[]),sv:()=>e(()=>import(`./sv-DWunXUNz.js`).then(e=>e.default),[]),th:()=>e(()=>import(`./th-DVnW2yyh.js`).then(e=>e.default),[]),tr:()=>e(()=>import(`./tr-Do8CFmhR.js`).then(e=>e.default),[]),uk:()=>e(()=>import(`./uk-BNPKIZga.js`).then(e=>e.default),[]),vi:()=>e(()=>import(`./vi-CZMFo9je.js`).then(e=>e.default),[]),zh:()=>e(()=>import(`./zh-Pg0881v0.js`).then(e=>e.default),[])},A=e=>{let t=e?.toLowerCase().split(`-`)[0];return k.includes(t)?t:`en`},j=e=>fe.includes(A(e)),M=e=>{if(typeof document>`u`)return;let t=A(e);document.documentElement.lang=t,document.documentElement.dir=j(t)?`rtl`:`ltr`},me=async e=>{let n=A(e);if(!t.hasResourceBundle(n,`translation`)){let e=await pe[n]();t.addResourceBundle(n,`translation`,e,!0,!0)}return n},he=async e=>{let n=await me(e);return await t.changeLanguage(n),n};if(typeof window<`u`){let e=navigator.language;try{e=window.localStorage.getItem(`i18nextLng`)||e}catch{}M(e),t.on(`languageChanged`,M)}var ge=(async()=>{t.isInitialized||await t.use(E).use(f).init({resources:de,fallbackLng:`en`,supportedLngs:k,nonExplicitSupportedLngs:!0,load:`languageOnly`,debug:!1,interpolation:{escapeValue:!1},detection:{order:[`localStorage`,`navigator`,`htmlTag`],caches:[`localStorage`],lookupLocalStorage:`i18nextLng`}});let e=A(t.language||t.resolvedLanguage);if(e!==`en`)try{await me(e),A(t.language)===e&&await t.changeLanguage(e)}catch{await t.changeLanguage(`en`)}M(t.resolvedLanguage||t.language||`en`)})(),N=t,_e=[`Chat`,`Image`,`Video`,`Audio`,`Speech`,`Transcription`,`Embedding`],ve={chat:`Chat`,completion:`Chat`,embedding:`Embedding`,image:`Image`,audio:`Audio`,stt:`Transcription`,tts:`Speech`,video:`Video`},ye={completion:`Chat`,embedding:`Embedding`,image:`Image`,audio:`Audio`,stt:`Transcription`,tts:`Speech`,video:`Video`};function P(e){let t=new Map,n=(e,n)=>{for(let r of e||[]){if(typeof r!=`string`||!r.trim())continue;let e=r.trim(),i=t.get(e)??new Set;i.add(n),t.set(e,i)}};n(e.model_map,ve[e.type]);for(let t of Object.keys(e.capabilities||{}))n(e.capabilities?.[t]?.model_map,ye[t]);return Array.from(t,([e,t])=>({id:e,capabilities:_e.filter(e=>t.has(e))}))}function be(e){return e.type===`chat`||e.type===`completion`}var xe=[`dall-e`,`embed`,`gpt-image`,`moderation`,`rerank`,`sora`,`stable-diffusion`,`text-to-speech`,`tts`,`whisper`];function Se(e){let t=e.toLocaleLowerCase();return!xe.some(e=>t.includes(e))}function Ce(e){let t=new Set;for(let[n,r]of Object.entries(e.capabilities||{}))if(n!==`completion`)for(let e of r?.model_map||[])t.add(e.trim());return(e.model_map||[]).filter(e=>typeof e==`string`&&e.trim().length>0&&!t.has(e.trim())&&Se(e))}function we(e,t){let n=t.trim().toLocaleLowerCase();return!n||[e.name,e.id,e.type,...P(e).map(e=>e.id)].some(e=>e?.toLocaleLowerCase().includes(n))}var F=(e,t)=>{if(e&&typeof e==`object`&&`response`in e){let t=e;if(t.response?.data?.error)return t.response.data.error}return e instanceof Error?e.message:t};function Te(e){return{...e,id:e.id||r(),timestamp:Date.now()}}function I(e,t){return e.currentSession?.isPrivate&&e.currentSession?.id===t}function L(e,t){return e.sessions.some(e=>e.id===t)}function Ee(e,t){return!!e.currentSession&&(I(e,t)||L(e,e.currentSession.id))}function De(e,t,n){if(I(e,t))return e.currentSession.messages.find(e=>e.id===n.id)?e:{currentSession:{...e.currentSession,messages:[...e.currentSession.messages,n],updatedAt:Date.now()},sessions:e.sessions};if(e.sessions.find(e=>e.id===t)?.messages.some(e=>e.id===n.id))return e;let r=e.sessions.map(e=>{if(e.id!==t)return e;let r=[...e.messages];if(n.parentId){let e=n.parentId;r=r.map(t=>t.id!==e&&t.parentId!==e?t:{...t,isActive:!1,branchIndex:t.branchIndex??0,siblingCount:(n.branchIndex||0)+1})}return{...e,messages:[...r,n],updatedAt:Date.now()}});return{sessions:r,currentSession:e.currentSession?.id===t&&r.find(e=>e.id===t)||e.currentSession}}function Oe(e,t,n,r){if(e.currentSession?.id!==t)return e;if(e.currentSession?.isPrivate){let t=e.currentSession.messages.find(e=>e.id===n);return!t||t.content===r?e:{sessions:e.sessions,currentSession:{...e.currentSession,messages:e.currentSession.messages.map(e=>e.id===n?{...e,content:r}:e),updatedAt:Date.now()}}}let i=e.sessions.find(e=>e.id===t),a=i?.messages.find(e=>e.id===n);if(!i||!a||a.content===r)return e;let o=e.sessions.map(e=>e.id===t?{...e,messages:e.messages.map(e=>e.id===n?{...e,content:r}:e),updatedAt:Date.now()}:e);return{sessions:o,currentSession:e.currentSession?.id===t&&o.find(e=>e.id===t)||e.currentSession}}function ke(e,t,n,r,i,a,o){if(e.currentSession?.id!==t)return e;if(e.currentSession?.isPrivate)return{sessions:e.sessions,currentSession:{...e.currentSession,messages:e.currentSession.messages.map(e=>e.id===n?{...e,content:r,thinking:o,statistics:i,...a?{providerMetadata:a}:{}}:e),updatedAt:Date.now()}};let s=e.sessions.map(e=>e.id===t?{...e,messages:e.messages.map(e=>e.id===n?{...e,content:r,thinking:o,statistics:i,...a?{providerMetadata:a}:{}}:e),updatedAt:Date.now()}:e);return{sessions:s,currentSession:e.currentSession?.id===t&&s.find(e=>e.id===t)||e.currentSession}}function R(e){return e.reduce((e,t)=>(e[t.id]=t,e),{})}function Ae(e){return e.map(e=>({name:`persona:${e.id}`,model:e.model,size:0,digest:``,details:{parent_model:e.model,format:`persona`,family:`persona`,families:[`persona`],parameter_size:``,quantization_level:``},modified_at:new Date(e.updated_at).toISOString(),expires_at:new Date().toISOString(),size_vram:0,isPersona:!0,personaName:e.name,personaDescription:e.description}))}function je(e){return e.filter(e=>e.active&&e.type!==`tts`&&e.type!==`image`).flatMap(e=>Ce(e).map(t=>({name:t,model:t,size:0,digest:``,details:{parent_model:``,format:``,family:``,families:[],parameter_size:``,quantization_level:``},modified_at:new Date().toISOString(),expires_at:new Date().toISOString(),size_vram:0,isPlugin:!0,pluginId:e.id,pluginName:e.name,...e.model_context?.[t]?{contextLength:e.model_context[t]}:{},...e.model_reasoning?.[t]===void 0?{}:{reasoningSupport:e.model_reasoning[t]}})))}var z=`persona:`,B=`plugin:`,V=`ollama:`,H=`legacy:`,U=`agent:`,W=e=>{try{return decodeURIComponent(e)}catch{return null}};function G(e){return e.isLegacySelection?{model:e.name,providerType:null,providerId:null}:e.isPersona?{model:e.name,providerType:`ollama`,providerId:null}:e.isPlugin&&e.pluginId?{model:e.name,providerType:`plugin`,providerId:e.pluginId}:e.isAgent?{model:e.name,providerType:`agent`,providerId:e.agentId||e.name}:{model:e.name,providerType:`ollama`,providerId:null}}function K(e){return e.providerType?e.providerType===`plugin`&&e.providerId?`${B}${encodeURIComponent(e.providerId)}:${encodeURIComponent(e.model)}`:e.providerType===`agent`&&e.providerId?`${U}${encodeURIComponent(e.providerId)}:${encodeURIComponent(e.model)}`:e.providerType===`ollama`&&e.model.startsWith(z)?`${z}${encodeURIComponent(e.model.slice(8))}`:e.providerType===`ollama`?`${V}${encodeURIComponent(e.model)}`:`${H}${encodeURIComponent(e.model)}`:`${H}${encodeURIComponent(e.model)}`}function q(e){return K(G(e))}function Me(e){if(e.startsWith(z)){let t=W(e.slice(8));return t===null?null:{model:`${z}${t}`,providerType:`ollama`,providerId:null}}if(e.startsWith(B)){let t=e.slice(7),n=t.indexOf(`:`);if(n<1)return null;let r=W(t.slice(0,n)),i=W(t.slice(n+1));return r&&i?{model:i,providerType:`plugin`,providerId:r}:null}if(e.startsWith(U)){let t=e.slice(6),n=t.indexOf(`:`);if(n<1)return null;let r=W(t.slice(0,n)),i=W(t.slice(n+1));return r&&i?{model:i,providerType:`agent`,providerId:r}:null}if(e.startsWith(V)){let t=W(e.slice(7));return t?{model:t,providerType:`ollama`,providerId:null}:null}if(e.startsWith(H)){let t=W(e.slice(7));return t?{model:t,providerType:null,providerId:null}:null}return null}function J(e,t){return t.providerType===`plugin`?e.find(e=>e.isPlugin&&e.pluginId===t.providerId&&e.name===t.model):t.providerType===`agent`?e.find(e=>e.isAgent&&e.name===t.model):t.providerType===`ollama`?t.model.startsWith(z)?e.find(e=>e.isPersona&&e.name===t.model):e.find(e=>!e.isPlugin&&!e.isPersona&&e.name===t.model):e.find(e=>e.isLegacySelection&&e.name===t.model)??e.find(e=>e.name===t.model)}function Ne(e,t){if(!t.providerType)return K(t);let n=J(e,t);return n?q(n):K(t)}function Pe(e,t){let n=e.find(e=>q(e)===t);return n?G(n):Me(t)}function Fe(e){return!e.isPlugin&&!e.isPersona&&!e.isAgent&&!e.isLegacySelection&&!e.isUnavailable}function Ie(e,t){return t.model?!!J(e.filter(e=>!e.isLegacySelection&&!e.isUnavailable),t):!1}function Le(e,t){if(!t.model)return e;if(!t.providerType){if(e.some(e=>e.isLegacySelection&&e.name===t.model))return e;let n=!!J(e,t);return[...e,{name:t.model,model:t.model,size:0,digest:``,modified_at:``,details:{},isLegacySelection:!0,isUnavailable:!n}]}if(J(e,t))return e;let n=t.providerType,r=n===`ollama`&&t.model.startsWith(z),i=n===`plugin`&&t.providerId||void 0;return[...e,{name:t.model,model:t.model,size:0,digest:``,modified_at:``,details:{},isPlugin:n===`plugin`,pluginId:i,pluginName:i,isAgent:n===`agent`,agentId:n===`agent`&&t.providerId||void 0,isPersona:r,personaName:r?t.model.slice(8):void 0,isUnavailable:!0}]}function Y(e){return e.isPlugin&&e.pluginId?`${e.pluginId}/${e.name}`:e.name}var Re=4,ze=10,X=`[Conversation summary] `,Z=e=>e.startsWith(X),Be=/[\u1100-\u11FF\u2E80-\uA4CF\uAC00-\uD7AF\uF900-\uFAFF\uFE30-\uFE4F\uFF00-\uFFEF]/g,Ve=768,Q=e=>{if(!e)return 0;let t=e.match(Be)?.length??0;return t+Math.ceil((e.length-t)/4)},He=e=>Re+Q(e.content)+Q(e.thinking)+(e.images?.length??0)*Ve;function Ue({model:e,sessionOptions:t,pinnedOptions:n,modelDefaults:r,globalOptions:i}){if(!(!e||e.isAgent))return e.isPlugin?e.contextLength:[t?.num_ctx,n?.num_ctx,r?.num_ctx,i?.num_ctx].find(e=>typeof e==`number`&&e>0)}function We(e,t=ze){let n=e.filter(e=>e.isActive!==!1),r=n.filter(e=>e.role===`system`),i=n.filter(e=>e.role!==`system`).slice(-Math.max(1,t)),a=i.findIndex(e=>e.role===`user`);return[...r,...a>=0?i.slice(a):[]]}function Ge(e){for(let t=e.length-1;t>=0;--t){let n=e[t];if(n.role!==`assistant`||n.isActive===!1)continue;let r=n.statistics?.prompt_eval_count;if(typeof r==`number`)return{tokens:r+(n.statistics?.eval_count??0),index:t}}}function Ke({messages:e,budget:t,systemPrompt:n,windowMessages:r}){let i=!!n?.trim(),a=We(e,r).filter(e=>!i||e.role!==`system`||Z(e.content)),o=Ge(e);if(o===void 0){let e=Q(n)+a.reduce((e,t)=>e+He(t),0);return{used:e,budget:t,ratio:t?e/t:void 0,measured:!1}}let s=0;for(let t=o.index+1;t<e.length;t+=1){let n=e[t];n.isActive!==!1&&(s+=He(n))}let c=o.tokens+s;return{used:c,budget:t,ratio:t?c/t:void 0,measured:!0}}function qe(e,t){try{return new Intl.NumberFormat(t,{notation:`compact`,maximumFractionDigits:1}).format(e)}catch{return String(e)}}var $=s(`chat-store`),Je=o((t,n)=>({sessions:[],currentSession:null,setCurrentSession:e=>{t({currentSession:e})},draftSessionSettings:{},setDraftSessionSettings:e=>{t({draftSessionSettings:e})},createSession:async(e,n,r,i,o)=>{try{t({loading:!0,error:null});let s=e.startsWith(`persona:`),l=await c.createSession(e,n,r,s?null:i,s?null:o);if(l.success&&l.data){let e=l.data;return t(t=>({sessions:[e,...t.sessions],currentSession:e,loading:!1})),a.success(N.t(`chat.toasts.chatCreated`)),e}}catch(e){let n=F(e,N.t(`chat.toasts.createFailed`));t({error:n,loading:!1}),a.error(n)}},loadSessions:async()=>{try{t({loading:!0,error:null});let e=await c.getSessions();e.success&&e.data&&t(t=>{let n=e.data||[],r=n.map(e=>e.id),i=null;return t.currentSession?.isPrivate?i=t.currentSession:t.currentSession&&r.includes(t.currentSession.id)?i=n.find(e=>e.id===t.currentSession.id)||null:n.length>0&&(i=n[0],t.currentSession&&$.warn(`Previous currentSession not found in backend sessions:`,t.currentSession.id)),{sessions:n,currentSession:i,loading:!1}})}catch(e){let n=F(e,N.t(`chat.toasts.loadFailed`));t({error:n,loading:!1}),a.error(n)}},deleteSession:async e=>{try{let n=await c.deleteSession(e);n.success?(t(t=>{let n=t.sessions.filter(t=>t.id!==e),r=t.currentSession?.id===e?n[0]||null:t.currentSession;return $.debug(`Store: Updating state, sessions count:`,n.length),{sessions:n,currentSession:r}}),a.success(N.t(`chat.toasts.chatDeleted`))):($.error(`Store: deleteSession failed:`,n),a.error(N.t(`chat.toasts.deleteFailed`)))}catch(e){$.error(`Store: deleteSession error:`,e);let t=F(e,N.t(`chat.toasts.deleteSessionFailed`));a.error(t)}},clearAllSessions:async()=>{try{t({loading:!0,error:null});let e=await c.clearAllSessions();e.success?(t({sessions:[],currentSession:null,loading:!1}),a.success(N.t(`chat.toasts.historyCleared`))):($.error(`Store: clearAllSessions failed:`,e),a.error(N.t(`chat.toasts.historyClearFailed`)),t({loading:!1}))}catch(e){$.error(`Store: clearAllSessions error:`,e);let n=F(e,N.t(`chat.toasts.historyClearFailed`));a.error(n),t({loading:!1})}},clearAllState:()=>{t({sessions:[],currentSession:null,models:[],hiddenModels:[],modelMetadata:{},selectedModel:``,selectedProviderType:null,selectedProviderId:null,systemMessage:``,loading:!1,error:null})},applySessionTitle:(e,n,r=Date.now())=>{t(t=>({sessions:t.sessions.map(t=>t.id===e?{...t,title:n,updatedAt:r}:t),currentSession:t.currentSession?.id===e?{...t.currentSession,title:n,updatedAt:r}:t.currentSession}))},updateSessionTitle:async(e,t)=>{try{let r=await c.updateSession(e,{title:t});if(r.success&&r.data){let t=r.data.title,i=r.data.updatedAt??Date.now();n().applySessionTitle(e,t,i),a.success(N.t(`chat.toasts.titleUpdated`))}}catch(e){let t=F(e,N.t(`chat.toasts.updateFailed`));a.error(t)}},addMessage:(e,r)=>{let i=n(),o=I(i,e);if(!Ee(i,e)){a.error(N.t(`chat.toasts.noValidSession`)),$.error(`addMessage blocked: currentSession is not valid`,i.currentSession?.id);return}if(!o&&!L(i,e)){a.error(N.t(`chat.toasts.sessionNotFound`)),$.error(`addMessage blocked: sessionId not found in sessions`,e);return}let s=Te(r);t(t=>De(t,e,s))},updateMessage:(e,n,r)=>{t(t=>Oe(t,e,n,r))},removeMessage:(e,n)=>{let r=e=>{let t=e.find(e=>e.id===n),r=e.filter(e=>e.id!==n);if(!t?.parentId)return r;let i=r.filter(e=>e.id===t.parentId||e.parentId===t.parentId),a=i.reduce((e,t)=>!e||(t.branchIndex??0)>(e.branchIndex??0)?t:e,void 0);return r.map(e=>i.some(t=>t.id===e.id)?{...e,isActive:e.id===a?.id,siblingCount:i.length}:e)};t(t=>({sessions:t.sessions.map(t=>t.id===e?{...t,messages:r(t.messages),updatedAt:Date.now()}:t),currentSession:t.currentSession?.id===e?{...t.currentSession,messages:r(t.currentSession.messages),updatedAt:Date.now()}:t.currentSession}))},updateMessageWithStatistics:(e,n,r,i,a,o)=>{t(t=>ke(t,e,n,r,i,a,o))},rateMessage:async(e,r,i)=>{let a=e=>e.map(e=>e.id===r?{...e,rating:i}:e),o=n().currentSession?.isPrivate;if(t(t=>({sessions:t.sessions.map(t=>t.id===e?{...t,messages:a(t.messages)}:t),currentSession:t.currentSession?.id===e?{...t.currentSession,messages:a(t.currentSession.messages)}:t.currentSession})),!o)try{await c.updateMessage(e,r,{rating:i??null})}catch(e){$.error(`Failed to save message rating:`,e)}},folders:[],loadFolders:async()=>{try{let e=await c.getFolders();e.success&&e.data&&t({folders:e.data})}catch(e){$.error(`Failed to load folders:`,e)}},createFolder:async e=>{try{let n=await c.createFolder(e);if(n.success&&n.data){let e=n.data;return t(t=>({folders:[...t.folders,e].sort((e,t)=>e.name.localeCompare(t.name))})),e}}catch(e){$.error(`Failed to create folder:`,e)}},renameFolder:async(e,n)=>{try{let r=await c.renameFolder(e,n);if(r.success&&r.data){let n=r.data;t(t=>({folders:t.folders.map(t=>t.id===e?n:t).sort((e,t)=>e.name.localeCompare(t.name))}))}}catch(e){$.error(`Failed to rename folder:`,e)}},deleteFolder:async e=>{try{(await c.deleteFolder(e)).success&&t(t=>({folders:t.folders.filter(t=>t.id!==e),sessions:t.sessions.map(t=>t.folderId===e?{...t,folderId:null}:t),currentSession:t.currentSession?.folderId===e?{...t.currentSession,folderId:null}:t.currentSession}))}catch(e){$.error(`Failed to delete folder:`,e)}},moveSessionToFolder:async(e,n)=>{t(t=>({sessions:t.sessions.map(t=>t.id===e?{...t,folderId:n}:t),currentSession:t.currentSession?.id===e?{...t.currentSession,folderId:n}:t.currentSession}));try{await c.updateSession(e,{folderId:n})}catch(e){$.error(`Failed to move session to folder:`,e)}},setSessionArchived:async(e,n)=>{t(t=>({sessions:t.sessions.map(t=>t.id===e?{...t,archived:n}:t),currentSession:t.currentSession?.id===e?{...t.currentSession,archived:n}:t.currentSession}));try{await c.updateSession(e,{archived:n})}catch(r){$.error(`Failed to update session archive state:`,r),t(t=>({sessions:t.sessions.map(t=>t.id===e?{...t,archived:!n}:t)}))}},setSessionPinned:async(e,n)=>{t(t=>({sessions:t.sessions.map(t=>t.id===e?{...t,pinned:n}:t),currentSession:t.currentSession?.id===e?{...t.currentSession,pinned:n}:t.currentSession}));try{await c.updateSession(e,{pinned:n})}catch(r){$.error(`Failed to update session pin state:`,r),t(t=>({sessions:t.sessions.map(t=>t.id===e?{...t,pinned:!n}:t)}))}},truncateMessagesFrom:(e,n)=>{let r=e=>{let t=e.findIndex(e=>e.id===n);return t===-1?e:e.slice(0,t)};t(t=>({sessions:t.sessions.map(t=>t.id===e?{...t,messages:r(t.messages),updatedAt:Date.now()}:t),currentSession:t.currentSession?.id===e?{...t.currentSession,messages:r(t.currentSession.messages),updatedAt:Date.now()}:t.currentSession}))},models:[],hiddenModels:[],setHiddenModels:e=>t({hiddenModels:e}),modelMetadata:{},ollamaConnected:!1,loadModels:async r=>{let i=r?.quiet===!0;try{i||t({loading:!0,error:null}),$.debug(`Loading models from API...`);let r=[],o;try{let e=await d.getModels();e.success&&e.data?(r=[...e.data],$.debug(`Ollama models loaded:`,e.data.length)):o=Error(e.error||e.message||`Ollama models are unavailable.`)}catch(e){o=e,$.warn(`Ollama models are unavailable; continuing with plugin models:`,e)}try{let e=await ee.getAllPlugins();if(e.success&&e.data){let t=e.data.filter(e=>e.active&&e.type!==`tts`&&e.type!==`image`);$.debug(`🔌 Active plugins found:`,t.map(e=>e.name));let n=je(t);r.push(...n),$.debug(`Plugin models added:`,n.length)}}catch(e){$.error(`❌ Failed to load plugin models:`,e),e instanceof Error&&$.error(`❌ Plugin error details:`,{message:e.message,response:e.response?.data,status:e.response?.status,url:e.config?.url})}try{let{agentCliApi:t}=await e(async()=>{let{agentCliApi:e}=await import(`./api-D7Ff5M2Q.js`).then(e=>e.t);return{agentCliApi:e}},__vite__mapDeps([0,1,2,3,4,5,6,7])),n=await t.getModels();if(n.success&&n.data){let e=n.data.map(e=>({name:e.id,model:e.id,size:0,digest:``,modified_at:``,details:{},isAgent:!0,agentName:e.name,agentId:e.agentId}));r.push(...e),$.debug(`Agent CLI models added:`,e.length)}}catch(e){$.warn(`Agent CLI models unavailable:`,e)}let s=r.length;try{let{personaApi:n}=await e(async()=>{let{personaApi:e}=await import(`./api-D7Ff5M2Q.js`).then(e=>e.t);return{personaApi:e}},__vite__mapDeps([0,1,2,3,4,5,6,7])),i=await n.getPersonas();if(i.success&&i.data){let e=R(i.data),n=Ae(i.data);r.push(...n),t(t=>({...t,personas:e}))}}catch(e){$.error(`❌ Failed to load personas:`,e)}let c=[],u=[],f={};try{let e=await d.getModelVisibility();e.success&&e.data&&(c=e.data.hidden??[],u=e.data.order??[],f=e.data.metadata??{})}catch(e){$.warn(`Model visibility unavailable; showing all models:`,e)}try{let{useAuthStore:t}=await e(async()=>{let{useAuthStore:e}=await import(`./authStore-BYW8-kP6.js`).then(e=>e.t);return{useAuthStore:e}},__vite__mapDeps([8,1,5,6,7,2,4,3,0,9])),n=t.getState();if(!(n.isAdmin()||n.systemInfo?.requiresAuth===!1)&&c.length>0){let e=new Set(c);r=r.filter(t=>!e.has(Y(t)))}}catch(e){$.warn(`Could not resolve viewer role for model list:`,e)}if(u.length>0){let e=new Map(u.map((e,t)=>[e,t]));r=[...r].sort((t,n)=>(e.get(Y(t))??2**53-1)-(e.get(Y(n))??2**53-1))}t({hiddenModels:c,modelMetadata:f}),$.debug(`Total models loaded:`,r.length);let p=s===0&&o?F(o,N.t(`chat.toasts.noModelProvider`)):null,m=n(),h=m.selectedModel,g={model:h,providerType:m.selectedProviderType,providerId:m.selectedProviderId},_=!!J(r,g),v=m.selectedProviderType===`ollama`||m.selectedProviderType===`plugin`;if(h&&!_&&v){let e=m.selectedProviderType===`plugin`?m.selectedProviderId||`plugin`:`Ollama`,n=N.t(`chat.toasts.modelUnavailable`,{model:h,provider:e});t({models:r,ollamaConnected:!o,loading:!1,error:n}),i||a.error(n);return}if(h&&!_&&r.length>0){let e=G(r[0]);$.debug(`⚠️ Legacy selected model "${h}" no longer available, falling back to "${e.model}"`),t({models:r,ollamaConnected:!o,loading:!1,selectedModel:e.model,selectedProviderType:e.providerType||null,selectedProviderId:e.providerId||null,error:p}),l.setDefaultModel(e.model,e.providerType,e.providerId).catch(e=>{$.warn(`Failed to save fallback default model:`,e)}),a.success(N.t(`chat.toasts.modelSwitched`,{model:e.model}))}else t({models:r,ollamaConnected:!o,loading:!1,error:p});p&&!i&&a.error(p)}catch(e){$.error(`Error loading models:`,e);let n=F(e,N.t(`chat.toasts.modelsLoadFailed`));t({ollamaConnected:!1,error:n,loading:!1}),i||a.error(n)}},contextWindowMessages:10,loadPreferences:async()=>{c.getContextPolicy().then(e=>{e.success&&e.data?.windowMessages&&t({contextWindowMessages:e.data.windowMessages})}).catch(()=>{});try{let e=await l.getPreferences();if(e.success&&e.data){let{defaultModel:n,defaultProviderType:r,defaultProviderId:i,systemMessage:a}=e.data;n&&(t({selectedModel:n,selectedProviderType:r||null,selectedProviderId:r===`plugin`&&i||null}),$.debug(`✅ Loaded default model from backend:`,n)),a!==void 0&&(t({systemMessage:a}),$.debug(`✅ Loaded system message from backend`))}}catch(e){$.warn(`❌ Failed to load preferences from backend:`,e)}},selectedModel:``,selectedProviderType:null,selectedProviderId:null,pendingComparisons:[],addPendingComparison:e=>t(t=>({pendingComparisons:[...t.pendingComparisons,e]})),removePendingComparison:e=>t(t=>({pendingComparisons:t.pendingComparisons.filter(t=>t.assistantMessageId!==e)})),setSelectedModel:(e,n=null,r=null)=>{let i=(n===`plugin`||n===`agent`)&&r||null;t({selectedModel:e,selectedProviderType:n,selectedProviderId:i}),l.setDefaultModel(e,n,i).catch(e=>{$.warn(`Failed to save default model to backend:`,e)})},updateCurrentSessionModel:async(e,r=null,i=null)=>{let o=n();if(!o.currentSession)throw Error(`No current session to update`);e.startsWith(`persona:`)&&(r=null,i=null);try{let n=await c.updateSession(o.currentSession.id,{model:e,providerType:r,providerId:r===`plugin`||r===`agent`?i:null});n.success&&n.data&&(t(t=>({sessions:t.sessions.map(e=>e.id===t.currentSession?.id?n.data:e),currentSession:n.data,selectedModel:e,selectedProviderType:r,selectedProviderId:(r===`plugin`||r===`agent`)&&i||null})),a.success(N.t(`chat.toasts.modelUpdated`)))}catch(e){let t=F(e,N.t(`chat.toasts.modelUpdateFailed`));throw a.error(t),e}},personas:{},loadPersonas:async()=>{try{t({loading:!0,error:null});let e=await u.getPersonas();if(e.success&&e.data){let n=e.data;t({personas:R(n),loading:!1}),$.debug(`✅ Personas loaded:`,n.length)}}catch(e){let n=F(e,`Failed to load personas`);t({error:n,loading:!1}),$.error(`❌ Failed to load personas:`,n)}},getCurrentPersona:()=>{let e=n();if(!e.currentSession||!e.currentSession.model?.startsWith(`persona:`))return null;let t=e.currentSession.model.replace(`persona:`,``);return e.personas[t]||null},systemMessage:``,setSystemMessage:e=>{let r=n();if(t({systemMessage:e}),l.setSystemMessage(e).catch(e=>{$.warn(`Failed to save system message to backend:`,e)}),r.currentSession){let n=r.currentSession.messages.findIndex(e=>e.role===`system`&&!Z(e.content));if(n!==-1){t(t=>{let r=t.sessions.map(r=>{if(r.id===t.currentSession?.id){let t=r.messages.map((t,r)=>r===n&&t.role===`system`?{...t,content:e,timestamp:Date.now()}:t);return{...r,messages:t,updatedAt:Date.now()}}return r});return{sessions:r,currentSession:t.currentSession?r.find(e=>e.id===t.currentSession.id)||t.currentSession:null}});let i=r.currentSession.messages[n];c.updateMessage(r.currentSession.id,i.id,{content:e}).catch(e=>{$.warn(`Failed to sync system message update to backend:`,e)}),$.debug(`✅ Updated system message in current session`)}}},loading:!1,error:null,setError:e=>t({error:e}),generatingTitleForSession:null,setGeneratingTitleForSession:e=>t({generatingTitleForSession:e}),...typeof window<`u`&&{testPluginApi:async()=>{try{$.debug(`🧪 Testing plugin API...`);let e=await ee.getAllPlugins();return $.debug(`✅ Plugin API test result:`,e),e}catch(e){return $.error(`❌ Plugin API test failed:`,e),{error:e}}}}}));export{ge as C,O as E,he as S,A as T,F as _,Z as a,be as b,q as c,K as d,Ne as f,Le as g,Ie as h,qe as i,Pe as l,Fe as m,X as n,Ue as o,J as p,Ke as r,Y as s,Je as t,G as u,P as v,j as w,M as x,we as y};
@@ -1 +1 @@
1
- import{n as e,t}from"./logger-DSXjF4ye.js";var n=t(`config`),r=window.location.protocol===`file:`?`http://localhost:3001/api`:`${window.location.origin}/api`,i=e(),a=()=>{i&&(n.debug(`API_BASE_URL configured as:`,r),n.debug(`Window location:`,window.location),n.debug(`Environment variables:`,{BASE_URL:`/`,DEV:!1,MODE:`production`,PROD:!0,SSR:!1,VITE_APP_VERSION:`0.25.0`}))};export{a as n,r as t};
1
+ import{n as e,t}from"./logger-DSXjF4ye.js";var n=t(`config`),r=window.location.protocol===`file:`?`http://localhost:3001/api`:`${window.location.origin}/api`,i=e(),a=()=>{i&&(n.debug(`API_BASE_URL configured as:`,r),n.debug(`Window location:`,window.location),n.debug(`Environment variables:`,{BASE_URL:`/`,DEV:!1,MODE:`production`,PROD:!0,SSR:!1,VITE_APP_VERSION:`0.27.0`}))};export{a as n,r as t};