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
@@ -1 +1 @@
1
- {"version":3,"file":"documentService.d.ts","sourceRoot":"","sources":["../../src/services/documentService.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"documentService.d.ts","sourceRoot":"","sources":["../../src/services/documentService.ts"],"names":[],"mappings":"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"}
@@ -18,6 +18,10 @@ import crypto from 'node:crypto';
18
18
  import { Readable } from 'node:stream';
19
19
  import { v4 as uuidv4 } from 'uuid';
20
20
  import storageService from '../storage.js';
21
+ import { getPersistence } from '../persistence/index.js';
22
+ import { encryptionService } from './encryptionService.js';
23
+ import { listGrantsForActor } from './resourceGrantService.js';
24
+ import { grantedResourceIdsFor, sharedMetaFor, } from './sharedResourceAccess.js';
21
25
  import { configurePlatformStorageRuntime, getPlatformStorageRuntime, } from '../platform/storage/index.js';
22
26
  import { MAX_VECTOR_RECORDS_PER_UPSERT, MAX_VECTOR_RESOURCE_INDEX_ENTRIES, } from '../platform/storage/vectorStore.js';
23
27
  import { aggregateDocumentIndexRevision, createDocumentIndexMetadata, DOCUMENT_CHUNKER_VERSION, DOCUMENT_INDEX_METADATA_KEY, DOCUMENT_VECTOR_NAMESPACE, DOCUMENT_VECTOR_VERSION, documentChunkSourceRevision as sourceRevision, documentEmbeddingDimensions as embeddingDimensions, documentIndexMatchesSpec, embeddedDocumentChunks as embeddedChunks, readDocumentIndexMetadata as readDocumentIndexMetadataValue, } from '../platform/storage/documentVectorIndex.js';
@@ -29,6 +33,8 @@ import { transactionalResourceDeletionEnqueuer } from '../platform/jobs/resource
29
33
  import preferencesService from './preferencesService.js';
30
34
  import { createLogger } from '../utils/logger.js';
31
35
  import { throwIfChatGenerationCancelled } from '../utils/chatCancellation.js';
36
+ import { reciprocalRankFusion, scoreCandidatesBm25, } from '../utils/hybridRetrieval.js';
37
+ import { DocumentExtractionError, detectImageMimeType, extractDocumentContentByType, extractPdfEmbeddedJpegs, readDocumentSegments, resolveDocumentFileType, resolveSegmentLabel, } from '../utils/documentExtraction.js';
32
38
  const logger = createLogger('documents');
33
39
  const DOCUMENT_BLOB_PURPOSE = 'document.source';
34
40
  const DOCUMENT_POST_VECTOR_FAULT_MARKER = 'LIBRE_DOCUMENT_POST_VECTOR_KILL';
@@ -248,31 +254,62 @@ const getPdfjsLib = async () => {
248
254
  }
249
255
  return pdfjsLib;
250
256
  };
251
- const extractDocumentContent = async (fileBuffer, mimeType, signal) => {
257
+ /**
258
+ * Segment maps above this length would bloat the encrypted metadata column;
259
+ * a source under the extraction size cap never legitimately reaches it.
260
+ */
261
+ const MAX_DOCUMENT_SEGMENTS = 5000;
262
+ const extractDocumentContent = async (fileName, fileBuffer, mimeType, signal, userId) => {
252
263
  if (signal?.aborted)
253
264
  throw signal.reason;
254
- if (mimeType === 'text/plain') {
255
- return { content: fileBuffer.toString('utf8'), fileType: 'txt' };
256
- }
257
- if (mimeType !== 'application/pdf') {
265
+ const fileType = resolveDocumentFileType(fileName, mimeType);
266
+ if (!fileType) {
258
267
  throw new Error(`Unsupported file type: ${mimeType}`);
259
268
  }
260
- const pdfLib = await getPdfjsLib();
261
- const pdfDocument = await pdfLib.getDocument({
262
- data: new Uint8Array(fileBuffer),
263
- }).promise;
264
- let textContent = '';
265
- for (let pageNum = 1; pageNum <= pdfDocument.numPages; pageNum += 1) {
266
- if (signal?.aborted)
267
- throw signal.reason;
268
- const page = await pdfDocument.getPage(pageNum);
269
- const pageText = await page.getTextContent();
270
- textContent += `${pageText.items
271
- .map(item => ('str' in item ? item.str : ''))
272
- .join(' ')}\n\n`;
269
+ // Images and audio extract through model calls (vision OCR / provider
270
+ // STT), which need the owner's identity, providers, and permissions.
271
+ if (fileType === 'image' || fileType === 'audio') {
272
+ if (!userId) {
273
+ throw new DocumentExtractionError('Image and audio extraction require an owning user');
274
+ }
275
+ const media = await import('./documentMediaExtractionService.js');
276
+ if (fileType === 'image') {
277
+ const mime = detectImageMimeType(fileBuffer);
278
+ const extracted = await media.extractImagesToText([{ data: fileBuffer, mime, label: 'Image' }], userId, signal);
279
+ return { ...extracted, fileType };
280
+ }
281
+ const extracted = await media.extractAudioToText({ buffer: fileBuffer, mimetype: mimeType, originalname: fileName }, userId, signal);
282
+ return { ...extracted, fileType };
283
+ }
284
+ const extracted = await extractDocumentContentByType(fileBuffer, fileType, {
285
+ signal,
286
+ ...(fileType === 'pdf' ? { pdfLib: await getPdfjsLib() } : {}),
287
+ });
288
+ // A PDF with no text layer is almost always a scan: recover the embedded
289
+ // JPEG page images and OCR them through the owner's vision model.
290
+ if (fileType === 'pdf' && !extracted.content.trim() && userId) {
291
+ const scans = extractPdfEmbeddedJpegs(fileBuffer);
292
+ if (scans.length > 0) {
293
+ const media = await import('./documentMediaExtractionService.js');
294
+ const ocr = await media.extractImagesToText(scans.map((data, index) => ({
295
+ data,
296
+ mime: 'image/jpeg',
297
+ label: `Page ${index + 1}`,
298
+ })), userId, signal);
299
+ return {
300
+ content: ocr.content,
301
+ fileType,
302
+ segments: ocr.segments.slice(0, MAX_DOCUMENT_SEGMENTS),
303
+ };
304
+ }
273
305
  }
274
- return { content: textContent.trim(), fileType: 'pdf' };
306
+ return {
307
+ content: extracted.content,
308
+ fileType,
309
+ segments: extracted.segments.slice(0, MAX_DOCUMENT_SEGMENTS),
310
+ };
275
311
  };
312
+ const documentContentSha256 = (fileBuffer) => crypto.createHash('sha256').update(fileBuffer).digest('hex');
276
313
  export class DocumentService {
277
314
  async captureEmbeddingExecutionSpec(userId) {
278
315
  const settings = (await preferencesService.getPreferences(userId))
@@ -333,23 +370,36 @@ export class DocumentService {
333
370
  * if the SQL transaction cannot commit.
334
371
  */
335
372
  async queueDocumentProcessing(fileName, fileBuffer, mimeType, userId, sessionId, signal) {
336
- if (mimeType !== 'text/plain' && mimeType !== 'application/pdf') {
373
+ const resolvedType = resolveDocumentFileType(fileName, mimeType);
374
+ if (!resolvedType) {
337
375
  throw new Error(`Unsupported file type: ${mimeType}`);
338
376
  }
339
377
  if (signal?.aborted)
340
378
  throw signal.reason;
379
+ const contentSha256 = documentContentSha256(fileBuffer);
380
+ const duplicate = await this.findDuplicateDocument(userId, sessionId, contentSha256);
381
+ if (duplicate) {
382
+ const existingJob = await getDurableJobRuntime().service.getByIdempotency(userId, DOCUMENT_INGEST_IDEMPOTENCY_SCOPE, duplicate.id);
383
+ if (existingJob) {
384
+ return {
385
+ document: duplicate,
386
+ jobId: existingJob.id,
387
+ deduplicated: true,
388
+ };
389
+ }
390
+ }
341
391
  const documentId = uuidv4();
342
392
  const now = Date.now();
343
393
  const document = {
344
394
  id: documentId,
345
395
  filename: fileName,
346
396
  content: '',
347
- fileType: mimeType === 'application/pdf' ? 'pdf' : 'txt',
397
+ fileType: resolvedType,
348
398
  size: fileBuffer.length,
349
399
  ...(sessionId ? { sessionId } : {}),
350
400
  uploadedAt: now,
351
401
  createdAt: now,
352
- metadata: { processingStatus: 'queued' },
402
+ metadata: { processingStatus: 'queued', contentSha256 },
353
403
  };
354
404
  const platform = getPlatformStorageRuntime();
355
405
  const sourceBlob = await platform.blobStore.put({
@@ -417,7 +467,7 @@ export class DocumentService {
417
467
  async processDocument(fileName, fileBuffer, mimeType, userId, sessionId) {
418
468
  const documentId = uuidv4();
419
469
  try {
420
- const { content, fileType } = await extractDocumentContent(fileBuffer, mimeType);
470
+ const { content, fileType, segments } = await extractDocumentContent(fileName, fileBuffer, mimeType, undefined, userId);
421
471
  let document = {
422
472
  id: documentId,
423
473
  filename: fileName,
@@ -426,6 +476,10 @@ export class DocumentService {
426
476
  size: fileBuffer.length,
427
477
  sessionId,
428
478
  uploadedAt: Date.now(),
479
+ metadata: {
480
+ contentSha256: documentContentSha256(fileBuffer),
481
+ ...(segments.length > 0 ? { segments } : {}),
482
+ },
429
483
  };
430
484
  const spec = await this.captureEmbeddingExecutionSpec(userId);
431
485
  // Process the document into chunks under one immutable execution spec.
@@ -771,6 +825,27 @@ export class DocumentService {
771
825
  return result;
772
826
  }
773
827
  /** Durable extraction/embedding handler entrypoint for an existing source. */
828
+ /**
829
+ * Record a terminal extraction failure on the document row so the owner
830
+ * can see why the upload never became searchable. Best effort: the
831
+ * durable job remains the operational record.
832
+ */
833
+ async markProcessingFailed(documentId, userId, message) {
834
+ const current = await this.getDocument(documentId, userId);
835
+ if (!current)
836
+ return false;
837
+ const document = {
838
+ ...current,
839
+ metadata: {
840
+ ...(current.metadata ?? {}),
841
+ processingStatus: 'failed',
842
+ processingError: message.slice(0, 500),
843
+ processedAt: Date.now(),
844
+ },
845
+ };
846
+ await getPlatformStorageRuntime().domains.documents.upsert(document, userId);
847
+ return true;
848
+ }
774
849
  async reprocessDocument(documentId, userId, signal, assertSideEffectAllowed, attemptCount = 1) {
775
850
  const spec = await this.captureEmbeddingExecutionSpec(userId);
776
851
  const current = await this.getDocument(documentId, userId);
@@ -791,7 +866,8 @@ export class DocumentService {
791
866
  }
792
867
  buffers.push(buffer);
793
868
  }
794
- const extracted = await extractDocumentContent(Buffer.concat(buffers, size), source.descriptor.contentType, signal);
869
+ const sourceBuffer = Buffer.concat(buffers, size);
870
+ const extracted = await extractDocumentContent(source.descriptor.originalFilename ?? current.filename, sourceBuffer, source.descriptor.contentType, signal, userId);
795
871
  let document = {
796
872
  ...current,
797
873
  content: extracted.content,
@@ -804,6 +880,10 @@ export class DocumentService {
804
880
  ...(document.metadata ?? {}),
805
881
  processingStatus: 'completed',
806
882
  processedAt: Date.now(),
883
+ contentSha256: documentContentSha256(sourceBuffer),
884
+ ...(extracted.segments.length > 0
885
+ ? { segments: extracted.segments }
886
+ : {}),
807
887
  };
808
888
  document = withDocumentIndexMetadata(document, embedded, spec);
809
889
  await assertSideEffectAllowed?.();
@@ -837,6 +917,31 @@ export class DocumentService {
837
917
  async getDocument(documentId, userId) {
838
918
  return storageService.getDocument(documentId, userId);
839
919
  }
920
+ /**
921
+ * Finds an existing live document with identical source bytes in the same
922
+ * scope (the same session, or both standing). Upload deduplication only —
923
+ * a match in another scope is not a duplicate because deleting one scope's
924
+ * copy must never remove another's.
925
+ */
926
+ async findDuplicateDocument(userId, sessionId, contentSha256) {
927
+ const scope = sessionId ?? null;
928
+ const platform = getPlatformStorageRuntime();
929
+ const documents = await storageService.getAllDocuments(userId);
930
+ for (const candidate of documents) {
931
+ if ((candidate.sessionId ?? null) !== scope)
932
+ continue;
933
+ if (candidate.metadata?.contentSha256 !== contentSha256)
934
+ continue;
935
+ const reserved = await platform.domains.resourceDeletions.isReserved('document', candidate.id);
936
+ if (!reserved)
937
+ return candidate;
938
+ }
939
+ return undefined;
940
+ }
941
+ /** Documents in a chat's searchable scope: session uploads, selected collections, and standing uploads. */
942
+ async getDocumentsInScope(userId, sessionId, collectionIds) {
943
+ return (await storageService.getAllDocuments(userId)).filter(document => this.documentInScope(document, sessionId, collectionIds));
944
+ }
840
945
  async getDocuments(userId, sessionId) {
841
946
  const allDocs = await storageService.getAllDocuments(userId);
842
947
  if (sessionId) {
@@ -892,6 +997,147 @@ export class DocumentService {
892
997
  document.collectionId &&
893
998
  collectionIds.includes(document.collectionId));
894
999
  }
1000
+ /**
1001
+ * Principals that may retrieve this document's vectors: everyone granted
1002
+ * the document directly plus everyone granted its collection. Grants ride
1003
+ * the ACL table, so revocation applies on the very next query without
1004
+ * re-embedding anything.
1005
+ */
1006
+ async vectorGrantsForDocument(document) {
1007
+ const security = getPersistence(encryptionService).repositories.security;
1008
+ const rows = [
1009
+ ...(await security.grants.listForResource('document', document.id)),
1010
+ ];
1011
+ if (document.collectionId) {
1012
+ rows.push(...(await security.grants.listForResource('knowledge-collection', document.collectionId)));
1013
+ }
1014
+ const unique = new Map();
1015
+ for (const row of rows) {
1016
+ if (row.principal_type !== 'user' && row.principal_type !== 'group') {
1017
+ continue;
1018
+ }
1019
+ unique.set(`${row.principal_type}${row.principal_id}`, {
1020
+ type: row.principal_type,
1021
+ id: row.principal_id,
1022
+ });
1023
+ }
1024
+ return [...unique.values()];
1025
+ }
1026
+ /**
1027
+ * Re-publishes the vector ACL for every document a share change affects.
1028
+ * Called after a grant on a document or knowledge collection is created
1029
+ * or revoked.
1030
+ */
1031
+ async syncShareGrants(resourceType, resourceId, ownerUserId) {
1032
+ const platform = getPlatformStorageRuntime();
1033
+ const documents = resourceType === 'document'
1034
+ ? await storageService
1035
+ .getDocument(resourceId, ownerUserId)
1036
+ .then(document => (document ? [document] : []))
1037
+ : (await storageService.getAllDocuments(ownerUserId)).filter(document => document.collectionId === resourceId);
1038
+ for (const document of documents) {
1039
+ const grants = await this.vectorGrantsForDocument(document);
1040
+ await platform.vectorStore.replaceResourceGrants({
1041
+ actor: { userId: ownerUserId },
1042
+ namespace: DOCUMENT_VECTOR_NAMESPACE,
1043
+ resourceIds: [document.id],
1044
+ grants,
1045
+ });
1046
+ }
1047
+ }
1048
+ /**
1049
+ * Documents living in knowledge collections shared with the actor. The
1050
+ * grant rows themselves are the authorization: they are resolved fresh
1051
+ * (including group membership) on every call.
1052
+ */
1053
+ async loadSharedScopeDocuments(userId, collectionIds) {
1054
+ const grants = await listGrantsForActor({ userId });
1055
+ const shared = [];
1056
+ const seenCollections = new Set();
1057
+ const seenDocuments = new Set();
1058
+ for (const grant of grants) {
1059
+ if (grant.resource_type !== 'knowledge-collection')
1060
+ continue;
1061
+ const collectionId = grant.resource_id;
1062
+ if (seenCollections.has(collectionId))
1063
+ continue;
1064
+ seenCollections.add(collectionId);
1065
+ if (grant.owner_user_id === userId)
1066
+ continue;
1067
+ if (collectionIds &&
1068
+ collectionIds.length > 0 &&
1069
+ !collectionIds.includes(collectionId)) {
1070
+ continue;
1071
+ }
1072
+ const documents = (await storageService.getAllDocuments(grant.owner_user_id)).filter(document => document.collectionId === collectionId);
1073
+ for (const document of documents) {
1074
+ if (seenDocuments.has(document.id))
1075
+ continue;
1076
+ seenDocuments.add(document.id);
1077
+ shared.push({ document, ownerUserId: grant.owner_user_id });
1078
+ }
1079
+ }
1080
+ return shared;
1081
+ }
1082
+ /**
1083
+ * Loads a document the actor may read: their own, or one reachable
1084
+ * through a document or collection grant. Shared results are read-only.
1085
+ */
1086
+ async getDocumentShared(documentId, actor) {
1087
+ const own = await storageService.getDocument(documentId, actor.userId);
1088
+ if (own)
1089
+ return { document: own, ownerUserId: actor.userId };
1090
+ const ownerUserId = await getPersistence(encryptionService).repositories.resources.archive.ownerOf('document', documentId);
1091
+ if (!ownerUserId || ownerUserId === actor.userId)
1092
+ return undefined;
1093
+ const document = await storageService.getDocument(documentId, ownerUserId);
1094
+ if (!document)
1095
+ return undefined;
1096
+ let shared = await sharedMetaFor(actor, 'document', documentId, ownerUserId);
1097
+ if (!shared && document.collectionId) {
1098
+ shared = await sharedMetaFor(actor, 'knowledge-collection', document.collectionId, ownerUserId);
1099
+ }
1100
+ if (!shared)
1101
+ return undefined;
1102
+ return { document, ownerUserId, shared };
1103
+ }
1104
+ /** Documents shared with the actor through collection grants. */
1105
+ async listSharedDocuments(actor) {
1106
+ const entries = await this.loadSharedScopeDocuments(actor.userId);
1107
+ const result = [];
1108
+ for (const { document, ownerUserId } of entries) {
1109
+ if (!document.collectionId)
1110
+ continue;
1111
+ const meta = await sharedMetaFor(actor, 'knowledge-collection', document.collectionId, ownerUserId);
1112
+ if (meta)
1113
+ result.push({ document, shared: meta });
1114
+ }
1115
+ return result;
1116
+ }
1117
+ /**
1118
+ * The actor's own collections followed by collections shared with them.
1119
+ */
1120
+ async listCollectionsWithShared(actor) {
1121
+ const own = await storageService.getKnowledgeCollections(actor.userId);
1122
+ const sharedIds = await grantedResourceIdsFor(actor, 'knowledge-collection', new Set(own.map(collection => collection.id)));
1123
+ const shared = [];
1124
+ for (const collectionId of sharedIds) {
1125
+ const collection = await storageService.getKnowledgeCollectionById(collectionId);
1126
+ if (!collection || collection.ownerUserId === actor.userId)
1127
+ continue;
1128
+ const meta = await sharedMetaFor(actor, 'knowledge-collection', collectionId, collection.ownerUserId);
1129
+ if (!meta)
1130
+ continue;
1131
+ shared.push({
1132
+ id: collection.id,
1133
+ name: collection.name,
1134
+ createdAt: collection.createdAt,
1135
+ updatedAt: collection.updatedAt,
1136
+ shared: meta,
1137
+ });
1138
+ }
1139
+ return [...own, ...shared];
1140
+ }
895
1141
  async indexDocumentChunks(document, chunks, userId, spec, attemptCount = 1, signal, assertSideEffectAllowed) {
896
1142
  const executionSpec = spec ?? (await this.captureEmbeddingExecutionSpec(userId));
897
1143
  const embedded = embeddedChunks(chunks);
@@ -924,6 +1170,7 @@ export class DocumentService {
924
1170
  mutated = true;
925
1171
  await assertSideEffectAllowed?.();
926
1172
  await this.assertDocumentIndexAuthoritative(document.id, userId, expectedRevision, expectedSource);
1173
+ const shareGrants = await this.vectorGrantsForDocument(document);
927
1174
  for (let offset = 0; offset < embedded.length; offset += MAX_VECTOR_RECORDS_PER_UPSERT) {
928
1175
  await assertSideEffectAllowed?.();
929
1176
  await this.assertDocumentIndexAuthoritative(document.id, userId, expectedRevision, expectedSource);
@@ -947,6 +1194,7 @@ export class DocumentService {
947
1194
  ? { collectionId: document.collectionId }
948
1195
  : {}),
949
1196
  },
1197
+ ...(shareGrants.length > 0 ? { grants: shareGrants } : {}),
950
1198
  })),
951
1199
  });
952
1200
  await assertSideEffectAllowed?.();
@@ -992,9 +1240,19 @@ export class DocumentService {
992
1240
  return this.keywordSearchDocuments(query, userId, sessionId, limit, collectionIds, signal);
993
1241
  }
994
1242
  const documents = (await storageService.getAllDocuments(userId)).filter(document => this.documentInScope(document, sessionId, collectionIds));
1243
+ // Shared-collection documents join the corpus read-only: their chunks
1244
+ // feed the lexical ranking directly, and their vector hits pass the
1245
+ // store's ACL predicate through the grants published at share time.
1246
+ const sharedDocuments = await this.loadSharedScopeDocuments(userId, collectionIds);
995
1247
  const platform = getPlatformStorageRuntime();
996
1248
  const chunksById = new Map();
997
- const unembedded = [];
1249
+ for (const { document } of sharedDocuments) {
1250
+ throwIfChatGenerationCancelled(signal);
1251
+ const documentChunks = await this.loadDocumentChunks(document.id);
1252
+ for (const chunk of documentChunks) {
1253
+ chunksById.set(chunk.id, { chunk, document });
1254
+ }
1255
+ }
998
1256
  for (const document of documents) {
999
1257
  throwIfChatGenerationCancelled(signal);
1000
1258
  let searchableDocument = document;
@@ -1026,7 +1284,6 @@ export class DocumentService {
1026
1284
  // and deletion cleanup through the shared document resource lease.
1027
1285
  // PostgreSQL/team reads never mutate PGVector.
1028
1286
  const publishedIndex = readDocumentIndexMetadata(searchableDocument);
1029
- const canProveCurrentEmbeddingModel = documentIndexMatchesSpec(publishedIndex, executionSpec);
1030
1287
  const localIndexProbe = platform.dialect === 'sqlite'
1031
1288
  ? exactLocalDocumentIndexProbe(searchableDocument, documentChunks, userId, executionSpec)
1032
1289
  : undefined;
@@ -1069,24 +1326,20 @@ export class DocumentService {
1069
1326
  for (const chunk of documentChunks) {
1070
1327
  // PostgreSQL deliberately keeps embeddings only in PGVector, so a
1071
1328
  // relational chunk without an `embedding` property can still be the
1072
- // authoritative content for a vector hit. Always make every current
1073
- // relational chunk available for hit hydration. Metadata tells us
1074
- // whether an absent inline embedding means "stored externally" or
1075
- // whether this chunk genuinely needs keyword fallback.
1329
+ // authoritative content for a vector hit. Every current relational
1330
+ // chunk joins the candidate set: vector hits hydrate from it and
1331
+ // the BM25 side of the hybrid ranking scores it, so chunks without
1332
+ // a current embedding stay reachable.
1076
1333
  chunksById.set(chunk.id, {
1077
1334
  chunk,
1078
1335
  document: searchableDocument,
1079
1336
  });
1080
- const indexedForSemanticQuery = canProveCurrentEmbeddingModel &&
1081
- publishedIndex !== undefined &&
1082
- publishedIndex.dimensions !== null &&
1083
- (platform.dialect === 'postgres' || localIndexReady);
1084
- if (!indexedForSemanticQuery) {
1085
- unembedded.push({ chunk, document: searchableDocument });
1086
- }
1087
1337
  }
1088
1338
  }
1089
- const resourceIds = documents.map(document => document.id);
1339
+ const resourceIds = [
1340
+ ...documents.map(document => document.id),
1341
+ ...sharedDocuments.map(entry => entry.document.id),
1342
+ ];
1090
1343
  const hits = [];
1091
1344
  for (let offset = 0; offset < resourceIds.length; offset += MAX_VECTOR_RESOURCE_FILTERS) {
1092
1345
  throwIfChatGenerationCancelled(signal);
@@ -1106,37 +1359,39 @@ export class DocumentService {
1106
1359
  hits.sort((left, right) => right.score - left.score ||
1107
1360
  left.ownerUserId.localeCompare(right.ownerUserId) ||
1108
1361
  left.id.localeCompare(right.id));
1109
- const top = [];
1110
- const selectedChunkIds = new Set();
1362
+ // Hybrid assembly: fuse the vector ranking with an in-process BM25
1363
+ // ranking over every in-scope chunk. The lexical side keeps chunks
1364
+ // without current embeddings reachable and lets an exact term match
1365
+ // outrank a semantically weak neighbor; fusion means neither ranking
1366
+ // silently dominates the other.
1367
+ const semanticRanked = [];
1368
+ const semanticScores = new Map();
1111
1369
  for (const hit of hits) {
1112
- if (top.length >= limit)
1113
- break;
1114
1370
  const match = chunksById.get(hit.id);
1115
1371
  if (!match ||
1116
1372
  match.document.id !== hit.resourceId ||
1117
1373
  sourceRevision(match.chunk) !== hit.sourceRevision ||
1118
- selectedChunkIds.has(match.chunk.id)) {
1374
+ semanticScores.has(match.chunk.id)) {
1119
1375
  continue;
1120
1376
  }
1121
- top.push({
1122
- ...match.chunk,
1123
- filename: match.document.filename,
1124
- });
1125
- selectedChunkIds.add(match.chunk.id);
1377
+ semanticRanked.push(match.chunk.id);
1378
+ semanticScores.set(match.chunk.id, hit.score);
1126
1379
  }
1127
- if (top.length < limit && unembedded.length > 0) {
1128
- const scored = this.scoreChunksByKeywords(query, unembedded);
1129
- for (const entry of scored) {
1130
- if (top.length >= limit)
1131
- break;
1132
- if (selectedChunkIds.has(entry.chunk.id))
1133
- continue;
1134
- top.push({
1135
- ...entry.chunk,
1136
- filename: entry.document.filename,
1137
- });
1138
- selectedChunkIds.add(entry.chunk.id);
1139
- }
1380
+ const lexicalScored = this.scoreChunksByKeywords(query, [
1381
+ ...chunksById.values(),
1382
+ ]);
1383
+ const fused = reciprocalRankFusion([
1384
+ semanticRanked,
1385
+ lexicalScored.map(entry => entry.chunk.id),
1386
+ ]);
1387
+ const top = [];
1388
+ for (const { id, score } of fused) {
1389
+ if (top.length >= limit)
1390
+ break;
1391
+ const match = chunksById.get(id);
1392
+ if (!match)
1393
+ continue;
1394
+ top.push(this.hydrateRetrievedChunk(match.chunk, match.document, score));
1140
1395
  }
1141
1396
  if (top.length > 0)
1142
1397
  return top;
@@ -1151,25 +1406,13 @@ export class DocumentService {
1151
1406
  return this.keywordSearchDocuments(query, userId, sessionId, limit, collectionIds, signal);
1152
1407
  }
1153
1408
  }
1154
- /** Term-frequency scores for a set of chunks, best first. */
1409
+ /** BM25 scores for a set of chunks, best first. */
1155
1410
  scoreChunksByKeywords(query, entries) {
1156
- const searchTerms = query
1157
- .toLowerCase()
1158
- .split(/\s+/)
1159
- .filter(term => term.length > 2);
1160
- const scored = [];
1161
- for (const { chunk, document } of entries) {
1162
- const chunkText = chunk.content.toLowerCase();
1163
- let score = 0;
1164
- for (const term of searchTerms) {
1165
- // Escape special regex characters to prevent injection
1166
- const escapedTerm = term.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
1167
- score += (chunkText.match(new RegExp(escapedTerm, 'gi')) || []).length;
1168
- }
1169
- if (score > 0)
1170
- scored.push({ chunk, score, document });
1171
- }
1172
- return scored.sort((a, b) => b.score - a.score);
1411
+ const byId = new Map(entries.map(entry => [entry.chunk.id, entry]));
1412
+ return scoreCandidatesBm25(query, entries.map(entry => ({ id: entry.chunk.id, text: entry.chunk.content })), { requireQueryWordMatch: true }).map(({ id, score }) => {
1413
+ const entry = byId.get(id);
1414
+ return { chunk: entry.chunk, score, document: entry.document };
1415
+ });
1173
1416
  }
1174
1417
  async keywordSearchDocuments(query, userId, sessionId, limit = 5, collectionIds, signal) {
1175
1418
  const candidates = [];
@@ -1184,12 +1427,28 @@ export class DocumentService {
1184
1427
  candidates.push({ chunk, document });
1185
1428
  }
1186
1429
  }
1430
+ for (const { document } of await this.loadSharedScopeDocuments(userId, collectionIds)) {
1431
+ throwIfChatGenerationCancelled(signal);
1432
+ const documentChunks = await this.loadDocumentChunks(document.id);
1433
+ for (const chunk of documentChunks) {
1434
+ candidates.push({ chunk, document });
1435
+ }
1436
+ }
1187
1437
  throwIfChatGenerationCancelled(signal);
1188
1438
  const results = this.scoreChunksByKeywords(query, candidates);
1189
- return results.slice(0, limit).map(result => ({
1190
- ...result.chunk,
1191
- filename: result.document.filename, // Add filename for context
1192
- }));
1439
+ return results
1440
+ .slice(0, limit)
1441
+ .map(result => this.hydrateRetrievedChunk(result.chunk, result.document, result.score));
1442
+ }
1443
+ /** Attaches filename, score, and source location to a retrieval result. */
1444
+ hydrateRetrievedChunk(chunk, document, score) {
1445
+ const location = resolveSegmentLabel(readDocumentSegments(document.metadata), chunk.startChar, chunk.endChar);
1446
+ return {
1447
+ ...chunk,
1448
+ filename: document.filename,
1449
+ ...(score !== undefined ? { score } : {}),
1450
+ ...(location ? { location } : {}),
1451
+ };
1193
1452
  }
1194
1453
  // Get relevant context for RAG
1195
1454
  async getRelevantContext(query, userId, sessionId) {