@8wave/ai-elements 0.111.0-beta.3 → 0.111.0-beta.7

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 (150) hide show
  1. package/dist/_chunks/{Agent-Su_LDF9_.js → Agent-tE7ZJPxG.js} +80 -78
  2. package/dist/_chunks/Agent-tE7ZJPxG.js.map +1 -0
  3. package/dist/_chunks/{Document-DecVclEe.js → Document-Bmx6774B.js} +33 -21
  4. package/dist/_chunks/Document-Bmx6774B.js.map +1 -0
  5. package/dist/_chunks/Media-Cft7Pwrh.js +108 -0
  6. package/dist/_chunks/Media-Cft7Pwrh.js.map +1 -0
  7. package/dist/_chunks/{PkStreamingMarkdown-CwqsJnJJ.js → PkStreamingMarkdown-DgBS4Ebc.js} +69 -59
  8. package/dist/_chunks/PkStreamingMarkdown-DgBS4Ebc.js.map +1 -0
  9. package/dist/_chunks/{PkToolRequestGeolocation-OokLeTf1.js → PkToolRequestGeolocation-pVys3x9M.js} +2 -2
  10. package/dist/_chunks/{PkToolRequestGeolocation-OokLeTf1.js.map → PkToolRequestGeolocation-pVys3x9M.js.map} +1 -1
  11. package/dist/_chunks/{PkToolRequestOAuthConnection-CtqKG6Yb.js → PkToolRequestOAuthConnection-BGChb_eC.js} +2 -2
  12. package/dist/_chunks/{PkToolRequestOAuthConnection-CtqKG6Yb.js.map → PkToolRequestOAuthConnection-BGChb_eC.js.map} +1 -1
  13. package/dist/_chunks/{PkToolShowArtifact-M6jlSmyJ.js → PkToolShowArtifact-CkTBIdQd.js} +2 -2
  14. package/dist/_chunks/{PkToolShowArtifact-M6jlSmyJ.js.map → PkToolShowArtifact-CkTBIdQd.js.map} +1 -1
  15. package/dist/_chunks/{PkToolShowContactForm-D_dW59Dl.js → PkToolShowContactForm-Du7jX7K5.js} +2 -2
  16. package/dist/_chunks/{PkToolShowContactForm-D_dW59Dl.js.map → PkToolShowContactForm-Du7jX7K5.js.map} +1 -1
  17. package/dist/_chunks/PkToolShowDiagram-BdmG9gm8.js.map +1 -1
  18. package/dist/_chunks/{PkToolShowForm-DbJHMDbt.js → PkToolShowForm-Du2nk7pq.js} +3 -3
  19. package/dist/_chunks/PkToolShowForm-Du2nk7pq.js.map +1 -0
  20. package/dist/_chunks/{PkToolShowSources-Dot-W0Mj.js → PkToolShowSources-CsHLUF4L.js} +3 -3
  21. package/dist/_chunks/{PkToolShowSources-Dot-W0Mj.js.map → PkToolShowSources-CsHLUF4L.js.map} +1 -1
  22. package/dist/_chunks/{PkToolShowSuggestedReply-CKxSH0Y9.js → PkToolShowSuggestedReply-D7g_qymH.js} +2 -2
  23. package/dist/_chunks/{PkToolShowSuggestedReply-CKxSH0Y9.js.map → PkToolShowSuggestedReply-D7g_qymH.js.map} +1 -1
  24. package/dist/_chunks/PkToolShowWeather-LPd3tC77.js.map +1 -1
  25. package/dist/_chunks/PkUrl-BPbjZJ1A.js.map +1 -1
  26. package/dist/_chunks/{browser-NgY6LXg-.js → browser-B0Xnbqi7.js} +726 -751
  27. package/dist/_chunks/browser-B0Xnbqi7.js.map +1 -0
  28. package/dist/_chunks/text-DbSEK8si.js.map +1 -1
  29. package/dist/_chunks/utils-YJ0ZOLDG.js.map +1 -1
  30. package/dist/ai-elements.es.js +3010 -3052
  31. package/dist/ai-elements.es.js.map +1 -1
  32. package/dist-vue/PkChatbot.js +1 -1
  33. package/dist-vue/PkChatbotEmptyState.js +1 -1
  34. package/dist-vue/PkChatbotError.js +1 -1
  35. package/dist-vue/PkChatbotInput.js +1 -1
  36. package/dist-vue/PkChatbotMessages.js +1 -1
  37. package/dist-vue/PkChatbotSteps.js +1 -1
  38. package/dist-vue/PkChatbotViewChat.js +1 -1
  39. package/dist-vue/PkChatbotViewConversations.js +1 -1
  40. package/dist-vue/PkChatbotViewFiles.js +1 -1
  41. package/dist-vue/PkChatbotViewProfile.js +1 -1
  42. package/dist-vue/_chunks/{Agent-C8BsTAxk.js → Agent-De2gFNjR.js} +165 -176
  43. package/dist-vue/_chunks/Agent-De2gFNjR.js.map +1 -0
  44. package/dist-vue/_chunks/{Document-CaUfI_SZ.js → Document-8umjeTVS.js} +84 -72
  45. package/dist-vue/_chunks/Document-8umjeTVS.js.map +1 -0
  46. package/dist-vue/_chunks/Media-_HfFLHGD.js.map +1 -1
  47. package/dist-vue/_chunks/{PkChatbot-BPKSPIeC.js → PkChatbot-Di7R2CWN.js} +7 -7
  48. package/dist-vue/_chunks/PkChatbot-Di7R2CWN.js.map +1 -0
  49. package/dist-vue/_chunks/{PkChatbotEmptyState-BvaeBxhx.js → PkChatbotEmptyState-C_ITdvH7.js} +2 -2
  50. package/dist-vue/_chunks/{PkChatbotEmptyState-BvaeBxhx.js.map → PkChatbotEmptyState-C_ITdvH7.js.map} +1 -1
  51. package/dist-vue/_chunks/{PkChatbotError-CBP2mf-n.js → PkChatbotError-gvDpRcEz.js} +21 -19
  52. package/dist-vue/_chunks/PkChatbotError-gvDpRcEz.js.map +1 -0
  53. package/dist-vue/_chunks/{PkChatbotInput-JnHaRlfk.js → PkChatbotInput-pEl3D2O-.js} +139 -124
  54. package/dist-vue/_chunks/PkChatbotInput-pEl3D2O-.js.map +1 -0
  55. package/dist-vue/_chunks/{PkChatbotMessages-DAlkoMkY.js → PkChatbotMessages-CGALOKwe.js} +17 -17
  56. package/dist-vue/_chunks/PkChatbotMessages-CGALOKwe.js.map +1 -0
  57. package/dist-vue/_chunks/{PkChatbotSteps-rommD48p.js → PkChatbotSteps-BhFupvbz.js} +2 -2
  58. package/dist-vue/_chunks/{PkChatbotSteps-rommD48p.js.map → PkChatbotSteps-BhFupvbz.js.map} +1 -1
  59. package/dist-vue/_chunks/{PkChatbotViewChat-CEqzF1G9.js → PkChatbotViewChat-DT-rAU_r.js} +6 -6
  60. package/dist-vue/_chunks/{PkChatbotViewChat-CEqzF1G9.js.map → PkChatbotViewChat-DT-rAU_r.js.map} +1 -1
  61. package/dist-vue/_chunks/{PkChatbotViewConversations-C787v5ll.js → PkChatbotViewConversations-3LaZPFyw.js} +2 -2
  62. package/dist-vue/_chunks/{PkChatbotViewConversations-C787v5ll.js.map → PkChatbotViewConversations-3LaZPFyw.js.map} +1 -1
  63. package/dist-vue/_chunks/{PkChatbotViewFiles-CNFLt8YO.js → PkChatbotViewFiles-CTqnbsCj.js} +3 -3
  64. package/dist-vue/_chunks/{PkChatbotViewFiles-CNFLt8YO.js.map → PkChatbotViewFiles-CTqnbsCj.js.map} +1 -1
  65. package/dist-vue/_chunks/{PkChatbotViewProfile-7p0ci3qm.js → PkChatbotViewProfile-B-Mp1jGQ.js} +2 -2
  66. package/dist-vue/_chunks/{PkChatbotViewProfile-7p0ci3qm.js.map → PkChatbotViewProfile-B-Mp1jGQ.js.map} +1 -1
  67. package/dist-vue/_chunks/PkRelativeTime--1cIphlA.js.map +1 -1
  68. package/dist-vue/_chunks/{PkStreamingMarkdown-D8_LwZMR.js → PkStreamingMarkdown-DIaZEedG.js} +406 -396
  69. package/dist-vue/_chunks/PkStreamingMarkdown-DIaZEedG.js.map +1 -0
  70. package/dist-vue/_chunks/PkSvgViewer-D-0M5bqg.js.map +1 -1
  71. package/dist-vue/_chunks/{PkToolRequestGeolocation-Bxqz9oSo.js → PkToolRequestGeolocation-Q3N3jlO8.js} +2 -2
  72. package/dist-vue/_chunks/{PkToolRequestGeolocation-Bxqz9oSo.js.map → PkToolRequestGeolocation-Q3N3jlO8.js.map} +1 -1
  73. package/dist-vue/_chunks/{PkToolRequestOAuthConnection-C6rXgb0s.js → PkToolRequestOAuthConnection-C0LW5Evp.js} +2 -2
  74. package/dist-vue/_chunks/{PkToolRequestOAuthConnection-C6rXgb0s.js.map → PkToolRequestOAuthConnection-C0LW5Evp.js.map} +1 -1
  75. package/dist-vue/_chunks/{PkToolShowArtifact-CEXdfOGG.js → PkToolShowArtifact-BCCUucVQ.js} +2 -2
  76. package/dist-vue/_chunks/{PkToolShowArtifact-CEXdfOGG.js.map → PkToolShowArtifact-BCCUucVQ.js.map} +1 -1
  77. package/dist-vue/_chunks/{PkToolShowContactForm-DHmzAIVF.js → PkToolShowContactForm-BXGxWSc2.js} +2 -2
  78. package/dist-vue/_chunks/{PkToolShowContactForm-DHmzAIVF.js.map → PkToolShowContactForm-BXGxWSc2.js.map} +1 -1
  79. package/dist-vue/_chunks/{PkToolShowDiagram-dwCVZ1up.js → PkToolShowDiagram-CZgrWvBr.js} +2 -2
  80. package/dist-vue/_chunks/PkToolShowDiagram-CZgrWvBr.js.map +1 -0
  81. package/dist-vue/_chunks/{PkToolShowEmail-CavhsPvi.js → PkToolShowEmail-DpC517Vn.js} +2 -2
  82. package/dist-vue/_chunks/{PkToolShowEmail-CavhsPvi.js.map → PkToolShowEmail-DpC517Vn.js.map} +1 -1
  83. package/dist-vue/_chunks/{PkToolShowForm-CO5A_j9L.js → PkToolShowForm-CIZpfAGK.js} +3 -3
  84. package/dist-vue/_chunks/PkToolShowForm-CIZpfAGK.js.map +1 -0
  85. package/dist-vue/_chunks/{PkToolShowMessage-DQojxDiV.js → PkToolShowMessage-B7flxVCU.js} +2 -2
  86. package/dist-vue/_chunks/{PkToolShowMessage-DQojxDiV.js.map → PkToolShowMessage-B7flxVCU.js.map} +1 -1
  87. package/dist-vue/_chunks/{PkToolShowProductList-Cn0yewM3.js → PkToolShowProductList-B6fRtIpx.js} +2 -2
  88. package/dist-vue/_chunks/{PkToolShowProductList-Cn0yewM3.js.map → PkToolShowProductList-B6fRtIpx.js.map} +1 -1
  89. package/dist-vue/_chunks/{PkToolShowSources-7Q5Iogxi.js → PkToolShowSources-DDZokZow.js} +4 -4
  90. package/dist-vue/_chunks/{PkToolShowSources-7Q5Iogxi.js.map → PkToolShowSources-DDZokZow.js.map} +1 -1
  91. package/dist-vue/_chunks/{PkToolShowSuggestedReply-DQFOVonE.js → PkToolShowSuggestedReply-DWLkUh2L.js} +2 -2
  92. package/dist-vue/_chunks/{PkToolShowSuggestedReply-DQFOVonE.js.map → PkToolShowSuggestedReply-DWLkUh2L.js.map} +1 -1
  93. package/dist-vue/_chunks/PkToolShowWeather-Bzqalzh8.js.map +1 -1
  94. package/dist-vue/_chunks/{PkToolShowWebPages-Bzkkn9GV.js → PkToolShowWebPages-DY48ee6V.js} +2 -2
  95. package/dist-vue/_chunks/{PkToolShowWebPages-Bzkkn9GV.js.map → PkToolShowWebPages-DY48ee6V.js.map} +1 -1
  96. package/dist-vue/_chunks/{PkUrl-xUBKVJCv.js → PkUrl-DSGxrEM7.js} +2 -2
  97. package/dist-vue/_chunks/PkUrl-DSGxrEM7.js.map +1 -0
  98. package/dist-vue/_chunks/{createChatbotApiClient-D9f69brW.js → createChatbotApiClient-MkaPbGWB.js} +2 -2
  99. package/dist-vue/_chunks/createChatbotApiClient-MkaPbGWB.js.map +1 -0
  100. package/dist-vue/_chunks/{useChatbotStore-9Cw_oR6J.js → useChatbotStore-BzfqjiYz.js} +6 -3
  101. package/dist-vue/_chunks/useChatbotStore-BzfqjiYz.js.map +1 -0
  102. package/dist-vue/_chunks/useDialogConfirm-KWz0ohCQ.js.map +1 -1
  103. package/dist-vue/_chunks/utils-Coqik0XI.js.map +1 -1
  104. package/dist-vue/api.js +1 -1
  105. package/dist-vue/composables.js +2 -2
  106. package/dist-vue/index.js +3858 -3490
  107. package/dist-vue/index.js.map +1 -1
  108. package/dist-vue/locales.js +36 -8
  109. package/dist-vue/packages/components/src/chat/PkAgentSettingsPanel.d.ts +20 -3
  110. package/dist-vue/packages/components/src/chat/PkChatButton.d.ts +3 -2
  111. package/dist-vue/packages/components/src/chat/PkLanguageModel.d.ts +26 -2
  112. package/dist-vue/packages/components/src/chat/PkLanguageModelCombobox.d.ts +53 -1
  113. package/dist-vue/packages/components/src/chat/PkModelOption.d.ts +19 -0
  114. package/dist-vue/packages/components/src/chat/PkReasoningSettings.d.ts +6 -0
  115. package/dist-vue/packages/components/src/chat/constants.d.ts +5 -18
  116. package/dist-vue/packages/components/src/chat/index.d.ts +3 -1
  117. package/dist-vue/packages/components/src/chat/modelCatalog.d.ts +46 -0
  118. package/dist-vue/packages/components/src/table/PkTableSortable.d.ts +5 -1
  119. package/dist-vue/packages/composable/src/chatbot/useChatbotStore.d.ts +18 -0
  120. package/dist-vue/packages/composable/src/useChatbotError.d.ts +2 -0
  121. package/dist-vue/packages/models/src/schema/Agent.d.ts +70 -10
  122. package/dist-vue/packages/models/src/schema/Chat.d.ts +10 -0
  123. package/dist-vue/packages/models/src/schema/ModelProvider.d.ts +316 -0
  124. package/dist-vue/packages/models/src/schema/Organization.d.ts +142 -2
  125. package/dist-vue/packages/models/src/schema/ReasoningChat.d.ts +20 -0
  126. package/dist-vue/packages/models/src/schema/SubAgent.d.ts +20 -0
  127. package/dist-vue/packages/models/src/schema/UserOverview.d.ts +41 -0
  128. package/dist-vue/packages/models/src/schema/constants.d.ts +56 -91
  129. package/dist-vue/packages/models/src/schema/index.d.ts +1 -0
  130. package/dist-vue/style.css +1 -1
  131. package/package.json +1 -1
  132. package/dist/_chunks/Agent-Su_LDF9_.js.map +0 -1
  133. package/dist/_chunks/Document-DecVclEe.js.map +0 -1
  134. package/dist/_chunks/Media-C6SOQfJZ.js +0 -122
  135. package/dist/_chunks/Media-C6SOQfJZ.js.map +0 -1
  136. package/dist/_chunks/PkStreamingMarkdown-CwqsJnJJ.js.map +0 -1
  137. package/dist/_chunks/PkToolShowForm-DbJHMDbt.js.map +0 -1
  138. package/dist/_chunks/browser-NgY6LXg-.js.map +0 -1
  139. package/dist-vue/_chunks/Agent-C8BsTAxk.js.map +0 -1
  140. package/dist-vue/_chunks/Document-CaUfI_SZ.js.map +0 -1
  141. package/dist-vue/_chunks/PkChatbot-BPKSPIeC.js.map +0 -1
  142. package/dist-vue/_chunks/PkChatbotError-CBP2mf-n.js.map +0 -1
  143. package/dist-vue/_chunks/PkChatbotInput-JnHaRlfk.js.map +0 -1
  144. package/dist-vue/_chunks/PkChatbotMessages-DAlkoMkY.js.map +0 -1
  145. package/dist-vue/_chunks/PkStreamingMarkdown-D8_LwZMR.js.map +0 -1
  146. package/dist-vue/_chunks/PkToolShowDiagram-dwCVZ1up.js.map +0 -1
  147. package/dist-vue/_chunks/PkToolShowForm-CO5A_j9L.js.map +0 -1
  148. package/dist-vue/_chunks/PkUrl-xUBKVJCv.js.map +0 -1
  149. package/dist-vue/_chunks/createChatbotApiClient-D9f69brW.js.map +0 -1
  150. package/dist-vue/_chunks/useChatbotStore-9Cw_oR6J.js.map +0 -1
@@ -1,19 +1,31 @@
1
1
  import { C as e, S as t, _ as n, a as r, b as i, f as a, g as o, h as s, l as c, n as l, o as u, t as d, v as f, x as p, y as m } from "./zod-BTUfq5ZI.js";
2
- import { i as h, l as g, n as _, o as v, r as y, s as b } from "./Media-C6SOQfJZ.js";
2
+ import { a as h, n as g, r as _ } from "./Media-Cft7Pwrh.js";
3
3
  //#region ../../packages/utils/src/markdown.ts
4
- var x = (e) => {
4
+ var v = (e) => {
5
5
  if (e) return e.replace(/!\[.*?\]\(.*?\)/g, "").replace(/\[([^\]]+)\]\(.*?\)/g, "$1").replace(/`{1,3}[^`]*`{1,3}/g, "").replace(/#{1,6}\s/g, "").replace(/(\*{1,3}|_{1,3})(.*?)\1/g, "$2").replace(/~~(.*?)~~/g, "$1").replace(/^\s*[-*+>]\s+/gm, "").replace(/\n+/g, " ").trim();
6
- }, S = o({
6
+ };
7
+ (/* @__PURE__ */ (function(e) {
8
+ return e.textEmbedding3Small = "openai/text-embedding-3-small", e.geminiEmbedding2 = "google/gemini-embedding-2", e;
9
+ })({})).geminiEmbedding2;
10
+ var y = /* @__PURE__ */ function(e) {
11
+ return e.it = "it", e.en = "en", e.es = "es", e.fr = "fr", e.de = "de", e;
12
+ }({});
13
+ y.it, y.en, y.es, y.fr, y.de;
14
+ var b = /* @__PURE__ */ function(e) {
15
+ return e.READABILITY = "readability", e.AI = "ai", e;
16
+ }({}), x = /* @__PURE__ */ function(e) {
17
+ return e.FETCH = "fetch", e.PUPPETEER = "puppeteer", e.REMOTE = "remote", e;
18
+ }({}), S = o({
7
19
  key: m().optional(),
8
20
  value: m().optional()
9
- }), C = b(r(S), r(o({
21
+ }), C = _(r(S), r(o({
10
22
  key: m(),
11
23
  value: m()
12
24
  })), (e) => e?.filter((e) => e.key?.trim() && e.value?.trim())), w = /* @__PURE__ */ function(e) {
13
25
  return e.Pending = "pending", e.Processing = "processing", e.Success = "success", e.Failed = "failed", e;
14
26
  }({}), T = o({
15
- extractionStrategy: l(h).optional(),
16
- browserEngine: l(y).optional().default(y.FETCH),
27
+ extractionStrategy: l(b).optional(),
28
+ browserEngine: l(x).optional().default(x.FETCH),
17
29
  headers: C.nullish(),
18
30
  aiDescriptionModel: m().optional(),
19
31
  aiDescriptionPrompt: m().max(5e3).optional(),
@@ -56,7 +68,7 @@ var k = o({
56
68
  lastSyncedAt: m(),
57
69
  lastModified: m().optional(),
58
70
  candidate: o({
59
- media: _,
71
+ media: g,
60
72
  fingerprint: m(),
61
73
  name: m(),
62
74
  webUrl: m(),
@@ -79,7 +91,7 @@ var k = o({
79
91
  P
80
92
  ])), I = o({
81
93
  source: F.optional(),
82
- media: _.optional(),
94
+ media: g.optional(),
83
95
  title: m().optional(),
84
96
  author: m().optional(),
85
97
  description: m().optional(),
@@ -90,7 +102,7 @@ var k = o({
90
102
  producer: m().optional(),
91
103
  creationDate: m().optional(),
92
104
  modificationDate: m().optional(),
93
- pageCount: b(i([s(), r(p())]), s(), (e) => Array.isArray(e) ? e.length : e).optional(),
105
+ pageCount: _(i([s(), r(p())]), s(), (e) => Array.isArray(e) ? e.length : e).optional(),
94
106
  encrypted: u().optional(),
95
107
  characterCount: s().optional(),
96
108
  lineCount: s().optional(),
@@ -154,21 +166,21 @@ o({
154
166
  folderId: m().nullable().optional(),
155
167
  folderPath: m().nullable().optional()
156
168
  }), o({
157
- ...g.pagination(),
158
- ...g.sort([
169
+ ...h.pagination(),
170
+ ...h.sort([
159
171
  "id",
160
172
  "updatedAt",
161
173
  "createdAt",
162
174
  "name"
163
175
  ]),
164
- ...g.filters([
176
+ ...h.filters([
165
177
  "type",
166
178
  "language",
167
179
  "agentId",
168
180
  "indexStatus"
169
181
  ]),
170
- ...g.fullText(),
171
- ...g.ids(),
182
+ ...h.fullText(),
183
+ ...h.ids(),
172
184
  "filter[similarity]": m().optional(),
173
185
  "filter[folderId]": m().optional(),
174
186
  "filter[hasRedundantChunks]": m().optional(),
@@ -177,16 +189,16 @@ o({
177
189
  }), o({
178
190
  type: l(L).default(L.File),
179
191
  name: m().min(1).max(255).optional(),
180
- language: l(v).optional(),
192
+ language: l(y).optional(),
181
193
  organizationId: m(),
182
194
  agentIds: r(m()).min(1, "At least one agent is required"),
183
195
  folderId: e().nullable().optional(),
184
- media: _.optional(),
196
+ media: g.optional(),
185
197
  url: t().optional(),
186
198
  content: m().optional(),
187
199
  metadata: f(m(), p()).optional(),
188
- extractionStrategy: l(h).optional(),
189
- browserEngine: l(y).optional(),
200
+ extractionStrategy: l(b).optional(),
201
+ browserEngine: l(x).optional(),
190
202
  headers: C.nullish().default([]),
191
203
  aiDescriptionModel: m().optional(),
192
204
  aiDescriptionPrompt: m().max(5e3).optional(),
@@ -225,7 +237,7 @@ o({
225
237
  organizationId: m(),
226
238
  content: m().optional(),
227
239
  name: m().min(1).max(255).optional(),
228
- language: l(v).optional(),
240
+ language: l(y).optional(),
229
241
  priority: s().int().min(1).max(5).optional(),
230
242
  agentIds: r(m()).min(1).optional(),
231
243
  metadata: f(m(), p()).optional(),
@@ -286,6 +298,6 @@ var R = (e) => {
286
298
  };
287
299
  }, H = (e) => V(e).icon;
288
300
  //#endregion
289
- export { x as a, B as i, R as n, z as r, H as t };
301
+ export { v as a, B as i, R as n, z as r, H as t };
290
302
 
291
- //# sourceMappingURL=Document-DecVclEe.js.map
303
+ //# sourceMappingURL=Document-Bmx6774B.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Document-Bmx6774B.js","names":[],"sources":["../../../../packages/utils/src/markdown.ts","../../../../packages/models/src/schema/constants.ts","../../../../packages/models/src/schema/Header.ts","../../../../packages/models/src/schema/Document.ts"],"sourcesContent":["export const stripMarkdown = (text?: string | null) => {\n if (!text) {\n return undefined\n }\n return text\n .replace(/!\\[.*?\\]\\(.*?\\)/g, '') // images\n .replace(/\\[([^\\]]+)\\]\\(.*?\\)/g, '$1') // links\n .replace(/`{1,3}[^`]*`{1,3}/g, '') // inline code / code blocks\n .replace(/#{1,6}\\s/g, '') // headings\n .replace(/(\\*{1,3}|_{1,3})(.*?)\\1/g, '$2') // bold / italic\n .replace(/~~(.*?)~~/g, '$1') // strikethrough\n .replace(/^\\s*[-*+>]\\s+/gm, '') // lists and blockquotes\n .replace(/\\n+/g, ' ') // newlines\n .trim()\n}\n","/**\n * The models an agent of this platform may be pointed at.\n *\n * The gateway listing DESCRIBES what exists, this list PERMITS. They are two\n * different questions, and conflating them broke production once: on\n * 2026-07-23 two models entered the catalog before the installed\n * `@ai-sdk/gateway` knew them, and their tool calls failed under the generic\n * handling. Exposing every model the day the listing shows it would reproduce\n * that by construction.\n *\n * Adding one is a line here, after the checklist in\n * `docs/agents/llm-integration.md`: it must be `type: language` in the\n * listing, produce text and carry the `tool-use` tag. Everything else about\n * it, the commercial name, the price, the context window, the two privacy\n * flags, comes from the listing and is never written down twice.\n *\n * A test checks every id against a saved copy of the listing, which is what\n * replaces the by-hand verification that missed a model on 2026-09-18.\n */\nexport const GATEWAY_MODELS = [\n // OpenAI\n 'openai/gpt-5-nano',\n 'openai/gpt-5-mini',\n 'openai/gpt-5.1-thinking',\n 'openai/gpt-5.2',\n 'openai/gpt-5.4-nano',\n 'openai/gpt-5.4-mini',\n 'openai/gpt-5.4',\n 'openai/gpt-5.4-pro',\n 'openai/gpt-5.5',\n 'openai/gpt-5.5-pro',\n 'openai/gpt-5.6-luna',\n 'openai/gpt-5.6-terra',\n 'openai/gpt-5.6-sol',\n 'openai/gpt-5.6-luna-fast',\n 'openai/gpt-5.6-terra-fast',\n 'openai/gpt-5.6-sol-fast',\n 'openai/gpt-6-astra',\n 'openai/gpt-6-astra-fast',\n 'openai/gpt-6-sol',\n 'openai/gpt-6-sol-fast',\n 'openai/gpt-6-luna',\n 'openai/gpt-6-luna-fast',\n // Google Gemini\n 'google/gemini-2.5-flash-lite',\n 'google/gemini-2.5-flash',\n 'google/gemini-2.5-pro',\n 'google/gemini-3-flash',\n 'google/gemini-3.1-pro-preview',\n 'google/gemini-3.1-flash-lite',\n 'google/gemini-3.5-flash',\n 'google/gemini-3.5-flash-lite',\n 'google/gemini-3.6-flash',\n 'google/gemini-3.7-flash',\n 'google/gemini-3.8-flash',\n // Anthropic Claude\n 'anthropic/claude-haiku-4.5',\n 'anthropic/claude-sonnet-4.6',\n 'anthropic/claude-sonnet-5',\n 'anthropic/claude-opus-4.6',\n 'anthropic/claude-opus-4.7',\n 'anthropic/claude-opus-4.8',\n 'anthropic/claude-opus-5',\n 'anthropic/claude-opus-5-fast',\n 'anthropic/claude-opus-5.5',\n 'anthropic/claude-opus-5.5-fast',\n 'anthropic/claude-fable-5',\n 'anthropic/claude-fable-5.1',\n // Deepseek\n 'deepseek/deepseek-v3.2',\n 'deepseek/deepseek-v4-flash-0731',\n 'deepseek/deepseek-v4.1-flash',\n 'deepseek/deepseek-v4-pro-0813',\n // Alibaba\n 'alibaba/qwen3.6-plus',\n 'alibaba/qwen3.7-max',\n 'alibaba/qwen3.7-plus',\n 'alibaba/qwen3.7-flash',\n 'alibaba/qwen3.8-flash',\n 'alibaba/qwen3.8-max',\n 'alibaba/qwen3.8-27b',\n 'alibaba/qwen3.8-max-0902',\n 'alibaba/qwen3.8-omni-flash',\n // SpaceXAI\n 'spacexai/grok-4.3',\n 'spacexai/grok-4.6',\n 'spacexai/grok-4.7',\n // z.ai\n 'zai/glm-5.2',\n 'zai/glm-5.2-fast',\n 'zai/glm-5.3',\n 'zai/glm-5.3-flash',\n 'zai/glm-5.3-fast',\n 'zai/glm-5.3-flashx',\n // Meta\n 'meta/muse-spark-1.1',\n 'meta/muse-spark-1.2',\n 'meta/muse-spark-1.3',\n // Moonshot AI\n 'moonshotai/kimi-k3',\n 'moonshotai/kimi-k3-fast',\n // Mistral\n 'mistral/ministral-14b',\n 'mistral/mistral-small',\n 'mistral/mistral-medium-3.5',\n 'mistral/mistral-large-3',\n // Xiaomi\n 'xiaomi/mimo-v2.6-flash',\n 'xiaomi/mimo-v2.6-pro',\n 'xiaomi/mimo-v2.6-pro-ultraspeed',\n] as const satisfies readonly string[]\n\n/**\n * A model id: an entry of {@link GATEWAY_MODELS}, or a `byok/` id served by an\n * organization's own endpoint. A plain string on purpose, because the second\n * half cannot be enumerated.\n */\nexport type ModelId = string\n\n/**\n * Prices are stored per token, the unit the gateway listing publishes, and\n * shown per million, the unit every price page uses. One copy, so the page,\n * its dialogs and the picker never disagree on the factor.\n */\nexport const PER_MILLION_TOKENS = 1_000_000\n\n/**\n * The models the platform falls back to when an organization has expressed no\n * preference. The only model ids written in the code besides the curated list.\n */\nexport const PLATFORM_MODEL_DEFAULTS = {\n /** New agents, and the runtime fallback of an agent with no model. */\n agentModel: 'openai/gpt-5.6-terra',\n /** Question reformulation, JSON to schema, memory reconciliation. */\n utilityModel: 'google/gemini-3-flash',\n} as const\n\n/**\n * Models used to vectorize text, never to answer. Kept apart from\n * {@link GATEWAY_MODELS} so an embedding id cannot reach the chat plumbing,\n * and out of the catalog for the same reason: they are not selectable.\n */\nexport enum EmbeddingModel {\n textEmbedding3Small = 'openai/text-embedding-3-small',\n geminiEmbedding2 = 'google/gemini-embedding-2',\n}\n\nexport const EMBED_MODEL = EmbeddingModel.geminiEmbedding2\n\n/**\n * Supported languages for documents and revised answers\n */\nexport enum SupportedLanguage {\n it = 'it',\n en = 'en',\n es = 'es',\n fr = 'fr',\n de = 'de',\n}\n\n/**\n * Language display names (i18n keys)\n */\nexport const LANGUAGE_NAMES: Record<SupportedLanguage, string> = {\n [SupportedLanguage.it]: 'language.italian',\n [SupportedLanguage.en]: 'language.english',\n [SupportedLanguage.es]: 'language.spanish',\n [SupportedLanguage.fr]: 'language.french',\n [SupportedLanguage.de]: 'language.german',\n}\n\n/**\n * Content extraction strategies for URL scraping\n */\nexport enum ExtractionStrategy {\n /** Use Mozilla Readability for content extraction (fast, free, no API calls) */\n READABILITY = 'readability',\n /** Use AI-based extraction (better for complex layouts, requires API calls) */\n AI = 'ai',\n}\n\n/**\n * Browser engine options for URL scraping\n */\nexport enum BrowserEngine {\n /** Use simple HTTP fetch (fast, lightweight, no JavaScript support) */\n FETCH = 'fetch',\n /** Use Puppeteer with headless Chrome (full browser, JavaScript support) */\n PUPPETEER = 'puppeteer',\n /** Delegate browser rendering to an external pdf-image-generator service */\n REMOTE = 'remote',\n}\n\n/**\n * Which report family has to account for a credit charge.\n *\n * The hourly reconciliation trusts `cost_reports` (the gateway's own billing,\n * copied in house) as the source of truth for what an organization spent. A\n * charge whose supplier is not the gateway has no counterpart there, so it must\n * be told apart or the reconciliation forgives it: that is what happened to the\n * voice minutes until 2026-08-31.\n *\n * Declared here, written on the ledger row at charge time, never inferred from\n * `source` downstream: the next non-gateway supplier must be a compile-time\n * decision, not a string nobody remembered to add to a list.\n */\nexport enum BillingSource {\n /** Billed by the AI gateway, so it lands in `cost_reports`. */\n GATEWAY = 'gateway',\n /** Billed by another supplier (voice minutes, OCR): the ledger is the only record. */\n INTERNAL = 'internal',\n}\n\n/**\n * Kinds of row on the credit ledger.\n *\n * It used to be a free string with exactly one value ever written, `debit`.\n * Adding a second one is not free: the hourly reconciliation sums debits to\n * rebuild the real-time estimate, and the analytics endpoint sums the ledger to\n * chart spend, so a new type that nobody filters out is a number silently\n * doubled.\n */\nexport enum CreditTransactionType {\n /** A charge for something consumed, written in real time. */\n DEBIT = 'debit',\n /** The hourly settlement against the gateway report: the audit trail of a balance move. */\n RECONCILIATION = 'reconciliation',\n}\n\n/**\n * Prefix that marks a model served by the organization's own OpenAI compatible\n * endpoint rather than by the gateway.\n *\n * It is not a gateway brand, which is the point: every switch on the provider\n * (reasoning options, the Google thought signature repair, the per-provider\n * timeouts, the native web search tools) falls into its default branch without\n * any of them having to learn about BYOK.\n */\nexport const BYOK_MODEL_PREFIX = 'byok/'\n\nexport const isByokModel = (id?: string | null): boolean =>\n Boolean(id?.startsWith(BYOK_MODEL_PREFIX))\n\n/**\n * The id as the endpoint wants it, with the prefix removed. The remainder may\n * itself contain slashes (`byok/meta-llama/Llama-3.3-70B`), so this cuts the\n * prefix and does not split.\n */\nexport const byokModelId = (id: string): string =>\n id.startsWith(BYOK_MODEL_PREFIX) ? id.slice(BYOK_MODEL_PREFIX.length) : id\n","import * as z from 'zod'\nimport { decodeOnly } from '../utils'\n\nexport const HeaderSchema = z.object({\n key: z.string().optional(),\n value: z.string().optional(),\n})\n\nexport const HeadesSchema = decodeOnly(\n z.array(HeaderSchema),\n z.array(z.object({ key: z.string(), value: z.string() })),\n (headers) =>\n headers?.filter(\n (header) => header.key?.trim() && header.value?.trim(),\n ) as Array<{ key: string; value: string }>,\n)\n\nexport type Header = z.infer<typeof HeaderSchema>\nexport type Headers = z.infer<typeof HeadesSchema>\n","import * as z from 'zod'\nimport { zodQs, decodeOnly } from '../utils'\nimport {\n SupportedLanguage,\n ExtractionStrategy,\n BrowserEngine,\n} from './constants'\nimport { MediaSchema } from './Media'\nimport { HeadesSchema } from './Header'\n\n/**\n * Processing status for document indexing and embedding generation\n */\nexport enum IndexStatus {\n Pending = 'pending',\n Processing = 'processing',\n Success = 'success',\n Failed = 'failed',\n}\n\n// ===== Document Source Types =====\n\n/**\n * Conversion options for document processing\n * Used when creating or reprocessing documents\n */\nexport const ConversionOptionsSchema = z.object({\n extractionStrategy: z.enum(ExtractionStrategy).optional(),\n browserEngine: z\n .enum(BrowserEngine)\n .optional()\n .default(BrowserEngine.FETCH),\n headers: HeadesSchema.nullish(),\n aiDescriptionModel: z.string().optional(),\n aiDescriptionPrompt: z.string().max(5000).optional(),\n language: z.string().optional(),\n forceOcr: z.boolean().default(false),\n pages: z\n .string()\n .max(100)\n .regex(/^\\d+(\\s*-\\s*\\d+)?(\\s*,\\s*\\d+(\\s*-\\s*\\d+)?)*$/)\n .optional(),\n})\n\nexport type ConversionOptions = z.infer<typeof ConversionOptionsSchema>\n\n// ===== Document Source (metadata.source) =====\n\n/**\n * Who keeps a document's content up to date.\n *\n * `web` is a page the platform re-reads on its own; the others are cloud\n * document sources. Distinct from `documents.source_provider`, which carries\n * only the providers that OWN their documents (the cloud ones) and is null for\n * everything else: a web page discovered by a source stays editable.\n */\nexport enum DocumentSourceProvider {\n Web = 'web',\n SharePoint = 'sharepoint',\n GoogleDrive = 'google-drive',\n}\n\n/**\n * Outcome of the last pass over a document's source.\n *\n * `unchanged` is the one that pays for the whole mechanism: the source was read\n * and produced the same text, so no chunk was rewritten and no embedding was\n * charged. `shrunk` is a refusal, not a failure: the page answered but with far\n * less content than before, so the good version was kept.\n */\nexport enum DocumentRefreshResult {\n Updated = 'updated',\n Unchanged = 'unchanged',\n Failed = 'failed',\n Shrunk = 'shrunk',\n Gone = 'gone',\n}\n\n/**\n * How often a document re-reads its source on its own.\n *\n * `null` is the fourth value and the default: manual, which is what every\n * document is today and what every type other than `url` can ever be.\n */\nexport enum DocumentRefreshInterval {\n Daily = 'daily',\n Weekly = 'weekly',\n Monthly = 'monthly',\n}\n\n/**\n * The Postgres interval each trigger advances by.\n *\n * One table, read by the two places that move a deadline: the service, when\n * somebody sets or changes the trigger, and the timer, when a due document has\n * been queued. Written as literals rather than composed at the call site\n * because they end up inside SQL.\n */\nexport const REFRESH_INTERVAL_SQL: Record<DocumentRefreshInterval, string> = {\n [DocumentRefreshInterval.Daily]: '1 day',\n [DocumentRefreshInterval.Weekly]: '7 days',\n [DocumentRefreshInterval.Monthly]: '1 month',\n}\n\n/**\n * Hours after which a document left `processing` is treated as abandoned.\n *\n * A killed worker leaves that status behind, and nothing else moves it: the row\n * would drop out of the refresh timer's selection for good, because the timer\n * only claims documents that are `success` or `failed`. Past this window the\n * timer takes it anyway, and a manual refresh stops being refused.\n *\n * Generous on purpose: a scrape is bounded by the Functions host timeout, so\n * anything still `processing` after six hours is not running.\n */\nexport const STALE_PROCESSING_HOURS = 6\n\nexport const DocumentLastRefreshSchema = z.object({\n at: z.string(),\n result: z.enum(DocumentRefreshResult),\n httpStatus: z.number().optional(),\n error: z.string().optional(),\n /** Reset by the first good outcome; the notification threshold reads it. */\n consecutiveFailures: z.number().optional(),\n /**\n * Words before and after, written by the shrink guard. They are kept rather\n * than only compared because the guard's thresholds are a starting point:\n * after a month of real pages one can tell whether they cut too much.\n */\n previousWordCount: z.number().optional(),\n newWordCount: z.number().optional(),\n})\n\nexport type DocumentLastRefresh = z.infer<typeof DocumentLastRefreshSchema>\n\n/** Fields every source branch shares, whatever keeps the document up to date. */\nconst commonSourceFields = {\n /**\n * Hash of the text that actually reaches the chunks, so an unchanged source\n * costs no chunking and no embedding. Written by the processor on every\n * pass, which is what lets a document imported before this existed start\n * comparing from its second pass on.\n */\n contentHash: z.string().optional(),\n lastRefresh: DocumentLastRefreshSchema.optional(),\n}\n\nconst WebDocumentSourceSchema = z.object({\n provider: z.literal(DocumentSourceProvider.Web),\n url: z.string(),\n // Written by a successful conversion, and only then: at insert time the\n // page has not been read yet, so a value here would attest a scrape that\n // never happened.\n lastScrapedAt: z.string().optional(),\n /**\n * Hash of the deterministic text handed to the extraction step, before the\n * model. With `extractionStrategy: 'ai'` the model's output differs on every\n * call, so comparing the final markdown would always say \"changed\" and\n * every interval would pay conversion, chunking and embedding. This is what\n * the AI path compares, and it decides whether to call the model at all.\n */\n extractionInputHash: z.string().optional(),\n /**\n * Where the last successful pass actually landed after redirects.\n *\n * The shrink guard compares this with the new final URL, and not with `url`\n * on purpose: plenty of sites always redirect (a locale prefix, a trailing\n * slash, http to https), so comparing against the stored URL would refuse\n * every update of those pages forever. What says a page is gone is its\n * destination changing from the one it has been landing on.\n */\n finalUrl: z.string().optional(),\n /**\n * The web source that discovered this page. It says who found it, not who\n * governs it: the page stays editable like any other.\n */\n sourceId: z.uuid().optional(),\n ...commonSourceFields,\n})\n\n/** Coordinates a cloud adapter needs to find the item again, plus its content fingerprint. */\nconst cloudSourceFields = {\n /** The `document_sync_sources` row that owns this document. */\n sourceId: z.uuid(),\n remoteId: z.string(),\n webUrl: z.string(),\n path: z.string(),\n /**\n * The provider's own content fingerprint, compared for equality only and\n * never interpreted. It is what lets a sync skip the download entirely.\n */\n fingerprint: z.string(),\n /** Marks the document as seen by a run: the reconciliation after a resync reads it. */\n lastSyncedAt: z.string(),\n /** When the provider says the item last changed. Shown, never compared: the fingerprint decides. */\n lastModified: z.string().optional(),\n /**\n * A newly downloaded blob waiting to be converted. It sits here instead of\n * replacing `metadata.media` so that a conversion failure cannot destroy the\n * version that works: the processor promotes it only on success.\n */\n candidate: z\n .object({\n media: MediaSchema,\n fingerprint: z.string(),\n name: z.string(),\n webUrl: z.string(),\n path: z.string(),\n lastModified: z.string().optional(),\n })\n .optional(),\n ...commonSourceFields,\n}\n\nconst SharePointDocumentSourceSchema = z.object({\n provider: z.literal(DocumentSourceProvider.SharePoint),\n ...cloudSourceFields,\n})\n\nconst GoogleDriveDocumentSourceSchema = z.object({\n provider: z.literal(DocumentSourceProvider.GoogleDrive),\n ...cloudSourceFields,\n})\n\n/**\n * `metadata.source`, discriminated on `provider`.\n *\n * One object cannot hold both shapes: a web page has a URL and a scrape date, a\n * cloud file has remote coordinates and a fingerprint, and making every field\n * optional to fit both is the same as having no schema. Rows written before the\n * discriminator existed carry no `provider`, so they are normalized to the web\n * branch before routing: that is the only shape that could have been written.\n *\n * The normalization runs on parse, and responses are serialized by the\n * parse-based compiler (see `apps/backend/src/utils/responseSerializer.ts`), so\n * a legacy row still comes out of the API intact.\n */\nexport const DocumentSourceSchema = z.preprocess(\n (value) => {\n if (\n value &&\n typeof value === 'object' &&\n !Array.isArray(value) &&\n !('provider' in value)\n ) {\n return { provider: DocumentSourceProvider.Web, ...value }\n }\n return value\n },\n z.discriminatedUnion('provider', [\n WebDocumentSourceSchema,\n SharePointDocumentSourceSchema,\n GoogleDriveDocumentSourceSchema,\n ]),\n)\n\nexport type DocumentSource = z.infer<typeof DocumentSourceSchema>\nexport type WebDocumentSource = z.infer<typeof WebDocumentSourceSchema>\n\n/**\n * The page URL of a document's source, when its source is a web page.\n *\n * One place to narrow the union, so the views that show \"where this came from\"\n * do not each grow their own check, and a cloud-synced document returns nothing\n * here instead of a broken link: its address is `webUrl` on the remote item,\n * which is a different thing to show and to say.\n */\nexport function documentSourceUrl(source?: DocumentSource): string | undefined {\n return source && 'url' in source ? source.url : undefined\n}\n\n// ===== Processing queue contract =====\n\n/**\n * Why a document is being processed again. Absent means the ingestion of a new\n * document, which is the only case whose natural key is the document id alone.\n */\nexport type DocumentProcessingKind = 'refresh' | 'reprocess' | 'reindex'\n\n/**\n * The `document-processing` queue message.\n *\n * Lives here because two processes read it: the backend publishes it and the\n * Azure Function consumes it. It used to be declared in each, and the copy in\n * the function app was already a field behind.\n */\nexport interface DocumentProcessingJob {\n documentId: string\n conversionOptions?: ConversionOptions\n /**\n * Set by every caller that processes a document which already exists. It\n * shapes the message id (see `publishProcessingJob`) and, for `refresh`,\n * turns on the refresh mode of the processor.\n */\n kind?: DocumentProcessingKind\n /**\n * Only a scheduled refresh enforces the shrink guard. A person who clicked\n * \"refresh now\" is looking at the result and may well be refreshing a page\n * that really did get shorter, so the guard would only stand in their way.\n */\n guarded?: boolean\n}\n\n/**\n * Metadata structure for document.metadata column\n * Consolidates all metadata from converters and source info\n */\nexport const DocumentMetadataSchema = z\n .object({\n // === Source Info (URL and synced documents) ===\n source: DocumentSourceSchema.optional(),\n\n // === Media Info (File documents only) ===\n media: MediaSchema.optional(),\n\n // === Common Fields (all document types) ===\n title: z.string().optional(),\n author: z.string().optional(),\n description: z.string().optional(),\n summary: z.string().optional(),\n keywords: z.array(z.string()).optional(),\n\n // === PDF Specific ===\n subject: z.string().optional(),\n creator: z.string().optional(), // Original application\n producer: z.string().optional(), // PDF generator software\n creationDate: z.string().optional(),\n modificationDate: z.string().optional(),\n pageCount: decodeOnly(\n z.union([z.number(), z.array(z.unknown())]),\n z.number(),\n (val) => (Array.isArray(val) ? val.length : val),\n ).optional(),\n encrypted: z.boolean().optional(),\n\n // === DOCX Specific ===\n characterCount: z.number().optional(),\n lineCount: z.number().optional(),\n\n // === URL Specific ===\n siteName: z.string().optional(),\n canonicalUrl: z.url().optional(),\n imageUrl: z.url().optional(),\n favicon: z.url().optional(),\n type: z.string().optional(), // og:type (article, website, etc.)\n locale: z.string().optional(),\n tags: z.array(z.string()).optional(),\n publishedTime: z.string().optional(),\n modifiedTime: z.string().optional(),\n\n // === Metrics (all document types) ===\n wordCount: z.number().optional(),\n paragraphCount: z.number().optional(),\n readingTime: z.number().optional(), // in minutes\n\n // === OCR (PDF documents) ===\n ocrUsed: z.boolean().optional(),\n ocrProvider: z.string().optional(),\n ocrModel: z.string().optional(),\n ocrPages: z.string().optional(),\n ocrCost: z.number().optional(),\n ocrError: z.string().optional(),\n\n // === RAG / Duplicates / Sync Info ===\n chunksCount: z.number().optional(),\n redundantChunksCount: z.number().optional(),\n hasRedundantChunks: z.boolean().optional(),\n qdrantSynced: z.boolean().optional(),\n\n // === Conversion Options (for reprocessing) ===\n conversionOptions: ConversionOptionsSchema.optional(),\n })\n .loose() // Allow additional custom fields\n\nexport type DocumentMetadata = z.infer<typeof DocumentMetadataSchema>\n\n/**\n * Document type enum\n *\n * - 'file': Document created from uploaded file (PDF, DOCX)\n * - 'url': Document created from web scraping\n * - 'revised-answer': Document created from revised AI answer\n * - 'plain-text': Document created from plain text input\n */\nexport enum DocumentType {\n File = 'file',\n Url = 'url',\n RevisedAnswer = 'revised-answer',\n PlainText = 'plain-text',\n}\n\n// ===== Schemas =====\n\n/**\n * Full document schema from database\n * Extended with computed field chunksCount\n */\nconst BaseDocumentSchema = z.object({\n id: z.string(),\n externalId: z.string().nullable(),\n name: z.string(),\n content: z.string(),\n type: z.string(),\n language: z.string(),\n metadata: z.record(z.string(), z.unknown()),\n indexStatus: z.string(),\n processedAt: z.coerce.date().nullable(),\n createdAt: z.coerce.date(),\n createdBy: z.string(),\n updatedAt: z.coerce.date(),\n updatedBy: z.string(),\n deleted: z.boolean(),\n deletedAt: z.coerce.date().nullable(),\n deletedBy: z.string().nullable(),\n organizationId: z.string(),\n priority: z.number().int().min(1).max(5).default(3),\n /** The automatic refresh trigger; null is manual, and only `url` can have one. */\n refreshInterval: z.enum(DocumentRefreshInterval).nullable().optional(),\n /**\n * When the trigger next comes due. Null with an interval set means paused:\n * the source answered that the page is gone for good.\n */\n nextRefreshAt: z.coerce.date().nullable().optional(),\n /**\n * Which sync source owns this document, when one does.\n *\n * Null is the ordinary case. A non-null value means a job keeps the\n * document up to date, which is what makes it read only: editing it, moving\n * it or deleting it by hand would be undone at the next run, silently.\n * Written only by providers that own their documents, never by a crawl that\n * merely discovered a page.\n */\n sourceProvider: z.enum(DocumentSourceProvider).nullable().optional(),\n})\n\nexport const DocumentSchema = BaseDocumentSchema.extend({\n type: z.enum(DocumentType),\n indexStatus: z.enum(IndexStatus),\n metadata: DocumentMetadataSchema,\n // Add computed field for chunks count (populated by service layer)\n chunksCount: z.number().optional(),\n // Computed fields for redundancy tracking\n redundantChunksCount: z.number().optional(),\n hasRedundantChunks: z.boolean().optional(),\n // Qdrant sync status\n qdrantSynced: z.boolean().optional(),\n // Agent IDs associated with this document (populated in single-item reads)\n agentIds: z.array(z.string()).optional(),\n // Folder ID for this document within an agent context (populated in agent-scoped reads)\n folderId: z.string().nullable().optional(),\n // Full folder path string e.g. \"Parent / Child\" (populated in list reads when agentId is set)\n folderPath: z.string().nullable().optional(),\n})\n\n/**\n * Query parameters for listing documents with pagination, sorting, and filters\n */\nexport const DocumentQuerystringSchema = z.object({\n ...zodQs.pagination(),\n ...zodQs.sort(['id', 'updatedAt', 'createdAt', 'name']),\n ...zodQs.filters(['type', 'language', 'agentId', 'indexStatus']),\n ...zodQs.fullText(),\n ...zodQs.ids(),\n 'filter[similarity]': z.string().optional(),\n // UUID = documents in that folder; 'null' = documents at root (no folder); absent = all documents\n 'filter[folderId]': z.string().optional(),\n 'filter[hasRedundantChunks]': z.string().optional(),\n // One of the intervals, 'null' for the documents left on manual, 'auto' for\n // any of the three. Same convention as `filter[folderId]`, and handled\n // outside `getFilters` for the same reason: `inArray` cannot say IS NULL.\n 'filter[refreshInterval]': z.string().optional(),\n // A provider, 'null' for the documents nobody syncs, 'any' for the ones a\n // source owns whoever it is. Same convention and the same reason as above.\n 'filter[sourceProvider]': z.string().optional(),\n})\n\n/**\n * Document creation schema for POST /documents endpoint\n *\n * Supports three types:\n * - 'file': Requires media object with uploaded file info\n * - 'url': Requires url string for web scraping\n * - 'revised-answer': Requires content (created from revisedAnswer service)\n */\nexport const DocumentCreateDtoSchema = z\n .object({\n type: z.enum(DocumentType).default(DocumentType.File),\n name: z.string().min(1).max(255).optional(),\n language: z.enum(SupportedLanguage).optional(),\n organizationId: z.string(),\n agentIds: z.array(z.string()).min(1, 'At least one agent is required'),\n folderId: z.uuid().nullable().optional(),\n media: MediaSchema.optional(),\n url: z.url().optional(),\n content: z.string().optional(),\n metadata: z.record(z.string(), z.unknown()).optional(),\n extractionStrategy: z.enum(ExtractionStrategy).optional(),\n browserEngine: z.enum(BrowserEngine).optional(),\n headers: HeadesSchema.nullish().default([]),\n aiDescriptionModel: z.string().optional(),\n aiDescriptionPrompt: z.string().max(5000).optional(),\n forceOcr: z.boolean().default(false),\n pages: z\n .string()\n .max(100)\n .regex(/^\\d+(\\s*-\\s*\\d+)?(\\s*,\\s*\\d+(\\s*-\\s*\\d+)?)*$/)\n .optional(),\n priority: z.number().int().min(1).max(5).default(3).optional(),\n refreshInterval: z.enum(DocumentRefreshInterval).nullable().optional(),\n })\n .superRefine((data, ctx) => {\n if (data.type === DocumentType.File && !data.media) {\n ctx.addIssue({\n code: 'custom',\n params: {\n i18n: 'errors.required',\n },\n path: ['media'],\n })\n return\n }\n if (data.type === DocumentType.Url && !data.url) {\n ctx.addIssue({\n code: 'custom',\n params: {\n i18n: 'errors.required',\n },\n path: ['url'],\n })\n }\n // The database has the same CHECK, but a 400 saying which field is\n // wrong beats a constraint violation surfacing as a 500.\n if (data.refreshInterval && data.type !== DocumentType.Url) {\n ctx.addIssue({\n code: 'custom',\n params: {\n i18n: 'errors.refreshIntervalUrlOnly',\n },\n path: ['refreshInterval'],\n })\n }\n if (\n data.type === DocumentType.PlainText &&\n !(data.name || data.language)\n ) {\n if (!data.name) {\n ctx.addIssue({\n code: 'custom',\n params: {\n i18n: 'errors.required',\n },\n path: ['name'],\n })\n }\n if (!data.language) {\n ctx.addIssue({\n code: 'custom',\n params: {\n i18n: 'errors.required',\n },\n path: ['language'],\n })\n }\n }\n })\n\n/**\n * Document update schema for PUT /documents/:id endpoint\n *\n * All fields are optional, but at least one must be provided\n */\nexport const DocumentUpdateDtoSchema = z.object({\n id: z.string(),\n organizationId: z.string(),\n content: z.string().optional(),\n name: z.string().min(1).max(255).optional(),\n language: z.enum(SupportedLanguage).optional(),\n priority: z.number().int().min(1).max(5).optional(),\n agentIds: z.array(z.string()).min(1).optional(),\n metadata: z.record(z.string(), z.unknown()).optional(),\n refreshInterval: z.enum(DocumentRefreshInterval).nullable().optional(),\n})\n\n/** Body of `PATCH /documents/:id/refresh-interval`, twin of the priority route. */\nexport const DocumentRefreshIntervalDtoSchema = z.object({\n refreshInterval: z.enum(DocumentRefreshInterval).nullable(),\n})\n\n/** Body of `POST /documents/bulk-refresh-interval`. */\nexport const DocumentBulkRefreshIntervalDtoSchema = z.object({\n ids: z.array(z.uuid()).min(1).max(100),\n refreshInterval: z.enum(DocumentRefreshInterval).nullable(),\n})\n\n/** Body of `POST /documents/bulk-refresh`, twin of `bulk-reprocess`. */\nexport const DocumentBulkRefreshDtoSchema = z.object({\n ids: z.array(z.uuid()).min(1).max(100),\n})\n\n// ===== Type Exports =====\n\nexport type Document = z.infer<typeof DocumentSchema>\nexport type DocumentQuerystring = z.infer<typeof DocumentQuerystringSchema>\nexport type DocumentCreateDto = z.infer<typeof DocumentCreateDtoSchema>\nexport type DocumentUpdateDto = z.infer<typeof DocumentUpdateDtoSchema>\nexport type DocumentRefreshIntervalDto = z.infer<\n typeof DocumentRefreshIntervalDtoSchema\n>\nexport type DocumentBulkRefreshIntervalDto = z.infer<\n typeof DocumentBulkRefreshIntervalDtoSchema\n>\nexport type DocumentBulkRefreshDto = z.infer<\n typeof DocumentBulkRefreshDtoSchema\n>\n\n// ===== Helper Functions =====\n\nexport const getStatusColor = (status: IndexStatus) => {\n switch (status) {\n case IndexStatus.Success:\n return 'success'\n case IndexStatus.Failed:\n return 'danger'\n case IndexStatus.Processing:\n return 'warning'\n default:\n return 'info'\n }\n}\n\nexport const getStatusIcon = (status: IndexStatus) => {\n switch (status) {\n case IndexStatus.Success:\n return 'ri:check-line'\n case IndexStatus.Failed:\n return 'ri:error-warning-line'\n case IndexStatus.Processing:\n return 'ri:hourglass-line'\n default:\n return 'ri:time-line'\n }\n}\n\nexport const getTypeIcon = (type: DocumentType) => {\n switch (type) {\n case DocumentType.File:\n return 'ri:file-line'\n case DocumentType.Url:\n return 'ri:link'\n case DocumentType.RevisedAnswer:\n return 'ri:feedback-line'\n default:\n return 'ri:input-method-line'\n }\n}\n\nexport const getFileIcon = (extension: string) => {\n const ext = (\n extension.startsWith('.') ? extension.slice(1) : extension\n ).toLowerCase()\n switch (ext) {\n case 'pdf':\n return 'ri:file-pdf-2-line'\n case 'doc':\n case 'docx':\n return 'ri:file-word-line'\n case 'xls':\n case 'xlsx':\n return 'ri:file-excel-line'\n case 'ppt':\n case 'pptx':\n return 'ri:file-ppt-line'\n case 'txt':\n return 'ri:file-text-line'\n case 'mp3':\n case 'wav':\n case 'ogg':\n return 'ri:file-music-line'\n case 'mp4':\n case 'avi':\n case 'mkv':\n return 'ri:file-video-line'\n case 'jpg':\n case 'jpeg':\n case 'png':\n case 'gif':\n case 'bmp':\n case 'svg':\n return 'ri:file-image-line'\n case 'zip':\n case 'rar':\n case '7z':\n return 'ri:file-zip-line'\n default:\n return 'ri:file-line'\n }\n}\n\n/** Whether a MIME type is an image. */\nexport const isImageMime = (mimeType?: string | null): boolean =>\n (mimeType ?? '').startsWith('image/')\n\n/** Whether a file MIME type can be previewed inline in the browser (image or\n * PDF) instead of being forced as a download. Shared by every file-list surface\n * so the preview/download decision stays consistent. */\nexport const isInlineViewable = (mimeType?: string | null): boolean =>\n isImageMime(mimeType) || mimeType === 'application/pdf'\n\n/** File-type identity for list rows and previews: icon, accent color\n * (CSS value driving glyph and tile tint) and a short human kind label. */\nexport interface FileKind {\n icon: string\n accent: string\n label: string\n}\n\n/** File-type identity derived from a MIME type. Accents match the chat\n * attachment cards (PkChatbotFilePreview) so files read the same everywhere. */\nexport const fileKindForMime = (mimeType?: string | null): FileKind => {\n const mime = mimeType ?? ''\n if (isImageMime(mime)) {\n return { icon: 'ri:image-line', accent: '#ec4899', label: 'Image' }\n }\n if (mime === 'application/pdf') {\n return { icon: 'ri:file-pdf-2-line', accent: '#e2483d', label: 'PDF' }\n }\n if (mime === 'application/msword' || mime.includes('wordprocessingml')) {\n return { icon: 'ri:file-word-line', accent: '#2b7de9', label: 'Word' }\n }\n if (mime === 'application/vnd.ms-excel' || mime.includes('spreadsheetml')) {\n return {\n icon: 'ri:file-excel-line',\n accent: '#1f9d57',\n label: 'Spreadsheet',\n }\n }\n if (\n mime === 'application/vnd.ms-powerpoint' ||\n mime.includes('presentationml')\n ) {\n return {\n icon: 'ri:file-ppt-line',\n accent: '#d98324',\n label: 'Presentation',\n }\n }\n if (mime.startsWith('audio/')) {\n return { icon: 'ri:file-music-line', accent: '#8b5cf6', label: 'Audio' }\n }\n if (mime.startsWith('video/')) {\n return { icon: 'ri:file-video-line', accent: '#6366f1', label: 'Video' }\n }\n if (\n mime === 'application/zip' ||\n mime === 'application/x-rar-compressed' ||\n mime === 'application/x-7z-compressed'\n ) {\n return { icon: 'ri:file-zip-line', accent: '#c08a1e', label: 'Archive' }\n }\n if (mime.startsWith('text/')) {\n return { icon: 'ri:file-text-line', accent: '#64748b', label: 'Text' }\n }\n return { icon: 'ri:file-line', accent: '#64748b', label: 'File' }\n}\n\n/** Icon for a file-list row, derived from its MIME type. */\nexport const fileIconForMime = (mimeType?: string | null): string =>\n fileKindForMime(mimeType).icon\n"],"mappings":"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"}
@@ -0,0 +1,108 @@
1
+ import { C as e, S as t, a as n, b as r, c as i, f as a, g as o, h as s, l as c, n as l, o as u, s as d, v as f, x as p, y as m } from "./zod-BTUfq5ZI.js";
2
+ //#region ../../packages/models/src/utils.ts
3
+ var h = (e, t, n) => d(e, t, {
4
+ encode: (e) => e,
5
+ decode: n
6
+ }), g = 51200, _ = f(m(), p()).refine((e) => JSON.stringify(e).length <= g, { message: `Schema must not exceed ${g / 1024} KB` });
7
+ e();
8
+ var v = (e) => [`${e}`, `-${e}`], y = (e) => e.flatMap((e) => v(e)), b = {
9
+ pagination: (e = 1, t = 10) => ({
10
+ "page[number]": s().or(m()).transform((e) => Number(e)).default(e),
11
+ "page[size]": s().or(m()).transform((e) => Number(e)).default(t)
12
+ }),
13
+ filter: (e) => ({ [`filter[${e}]`]: m().optional() }),
14
+ include: (e) => ({ [`include[${e}]`]: m().optional() }),
15
+ range: (e) => ({
16
+ [`from[${e}]`]: m().optional(),
17
+ [`to[${e}]`]: m().optional()
18
+ }),
19
+ has: (e) => ({ [`has[${e}]`]: u().optional() }),
20
+ fullText: () => ({ "filter[fullText]": m().optional() }),
21
+ ids: () => ({ ids: r([m(), n(m())]).optional() }),
22
+ deleted: () => ({ "filter[isDeleted]": u().default(!1) }),
23
+ filters: (e) => e.map((e) => b.filter(e)).reduce((e, t) => ({
24
+ ...e,
25
+ ...t
26
+ })),
27
+ sort: (e) => {
28
+ let t = y(e);
29
+ return { sort: l(t).optional().default(t[0]) };
30
+ }
31
+ }, x = /^[a-z]+\/[a-z0-9\-+.]+$/i, S = /* @__PURE__ */ function(e) {
32
+ return e.DEFAULT = "default", e.COLD = "cold", e.HOT = "hot", e.ARCHIVE = "archive", e;
33
+ }({}), C = o({
34
+ type: a("azure-blob"),
35
+ blobUri: t(),
36
+ containerName: m().min(1),
37
+ pathRelativeToContainer: m().min(1)
38
+ }), w = o({
39
+ type: a("s3"),
40
+ bucket: m().min(1),
41
+ key: m().min(1),
42
+ region: m().min(1)
43
+ }), T = c("type", [C, w]), E = o({
44
+ type: m().min(1),
45
+ name: m().min(1),
46
+ mimeType: m().regex(x),
47
+ bytesCount: s().positive(),
48
+ extension: m().regex(/^\.[a-zA-Z0-9]+$/).overwrite((e) => e.toLowerCase()),
49
+ storedFileName: m().optional(),
50
+ metadata: f(m(), m()).default({}),
51
+ tags: f(m(), m()).default({})
52
+ }).extend({
53
+ storageHandle: T,
54
+ storagePolicy: l(S),
55
+ signData: m().optional(),
56
+ storedFileName: m().min(1)
57
+ }), D = o({
58
+ name: m().min(1),
59
+ src: E,
60
+ srcSet: n(E).default([]),
61
+ rawOptions: i().optional()
62
+ });
63
+ o({
64
+ src: E,
65
+ uploadHandle: o({
66
+ uploadSasuri: t(),
67
+ metadata: f(m(), m()).default({}),
68
+ tags: f(m(), m()).default({})
69
+ })
70
+ }), o({
71
+ src: E,
72
+ downloadHandle: o({
73
+ downloadSasuri: t(),
74
+ viewSasuri: t(),
75
+ previewSasuri: t().optional(),
76
+ expiresOn: m().datetime(),
77
+ type: m()
78
+ })
79
+ });
80
+ var O = /* @__PURE__ */ function(e) {
81
+ return e.picture = "picture", e.video = "video", e.audio = "audio", e.office = "office", e.archive = "archive", e.binary = "binary", e.executable = "executable", e;
82
+ }({}), k = o({
83
+ type: a(O.picture),
84
+ width: s().positive(),
85
+ height: s().positive(),
86
+ blurhash: m().optional()
87
+ }), A = o({
88
+ type: a(O.video),
89
+ width: s().positive(),
90
+ height: s().positive(),
91
+ duration: s().nonnegative()
92
+ }), j = o({
93
+ type: a(O.audio),
94
+ duration: s().nonnegative()
95
+ }), M = o({ type: a(O.office) }), N = o({ type: a(O.archive) }), P = o({ type: a(O.binary) }), F = o({ type: a(O.executable) });
96
+ c("type", [
97
+ k,
98
+ A,
99
+ j,
100
+ M,
101
+ N,
102
+ P,
103
+ F
104
+ ]);
105
+ //#endregion
106
+ export { b as a, _ as i, D as n, h as r, x as t };
107
+
108
+ //# sourceMappingURL=Media-Cft7Pwrh.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Media-Cft7Pwrh.js","names":[],"sources":["../../../../packages/models/src/utils.ts","../../../../packages/models/src/schema/Media.ts"],"sourcesContent":["import * as z from 'zod'\n\n/**\n * Bidirectional wrapper for decode-time normalizations.\n *\n * Response serialization must never hit a unidirectional transform\n * (z.preprocess/.transform throw ZodEncodeError under zod encode), so\n * normalizing schemas are expressed as codecs: `decode` runs the\n * normalization (output validity is enforced by the output schema at\n * runtime), while `encode` is the identity for already-normalized data.\n */\nexport const decodeOnly = <Input extends z.ZodType, Output extends z.ZodType>(\n input: Input,\n output: Output,\n decode: (value: z.output<Input>) => z.input<Output>,\n) =>\n z.codec(input, output, {\n // Identity: already-normalized data is serialized unchanged. The\n // input schema re-validates at runtime, so the cast is type-only.\n encode: (value) => value as z.output<Input>,\n decode,\n })\n\nconst MAX_SCHEMA_SIZE_BYTES = 50 * 1024 // 50 KB\n\n/** Reusable Zod field for JSON Schema objects with a 50 KB size limit. */\nexport const jsonSchemaField = z\n .record(z.string(), z.unknown())\n .refine((val) => JSON.stringify(val).length <= MAX_SCHEMA_SIZE_BYTES, {\n message: `Schema must not exceed ${MAX_SCHEMA_SIZE_BYTES / 1024} KB`,\n })\n\n/**\n * Reusable UUID schema, built once.\n *\n * `z.uuid()` inside a loop or a hot function rebuilds the schema on every call,\n * which costs more than the check itself. Pair it with `.validate()` when only\n * the boolean is needed: `safeParse` builds a ZodError nobody reads.\n */\nexport const UuidSchema = z.uuid()\n\nexport type QueryStringFilter<T extends string = string> = `filter[${T}]`\nexport type Querystring = {\n 'page[number]'?: number | string\n 'page[size]'?: number | string\n sort?: string[] | string\n [filterKeys: QueryStringFilter]: unknown\n [otherKeys: string]: unknown\n}\n\nexport const makeSortEnum = <const T extends string>(input: T) => {\n return [`${input}`, `-${input}`] as [T, `-${T}`]\n}\n\nexport const makeSortEnums = <const T extends string>(input: readonly T[]) => {\n return input.flatMap((i) => makeSortEnum(i))\n}\n\nexport const zodQs = {\n pagination: (defaultNumber = 1, defaultSize = 10) => {\n return {\n 'page[number]': z\n .number()\n .or(z.string())\n .transform((v) => Number(v))\n .default(defaultNumber),\n 'page[size]': z\n .number()\n .or(z.string())\n .transform((v) => Number(v))\n .default(defaultSize),\n }\n },\n filter: <const T extends string>(input: T) => {\n return { [`filter[${input}]`]: z.string().optional() } as Record<\n `filter[${T}]`,\n z.ZodOptional<z.ZodString | z.ZodArray<z.ZodString>>\n >\n },\n include: <const T extends string>(input: T) => {\n return { [`include[${input}]`]: z.string().optional() } as Record<\n `include[${T}]`,\n z.ZodOptional<z.ZodArray<z.ZodString> | z.ZodString>\n >\n },\n range: <const T extends string>(input: T) => {\n return {\n [`from[${input}]`]: z.string().optional(),\n [`to[${input}]`]: z.string().optional(),\n } as Record<`from[${T}]` | `to[${T}]`, z.ZodOptional<z.ZodString>>\n },\n has: <const T extends string>(input: T) => {\n return { [`has[${input}]`]: z.boolean().optional() } as Record<\n `has[${T}]`,\n z.ZodOptional<z.ZodBoolean>\n >\n },\n fullText: () => {\n return { [`filter[fullText]`]: z.string().optional() }\n },\n ids: () => {\n return { ids: z.union([z.string(), z.array(z.string())]).optional() }\n },\n deleted: () => {\n return { 'filter[isDeleted]': z.boolean().default(false) }\n },\n filters: <const T extends string>(input: readonly T[]) => {\n return input\n .map((i) => zodQs.filter(i))\n .reduce((a, b) => ({ ...a, ...b }))\n },\n sort: <const S extends string>(sort: S[]) => {\n const sortEnums = makeSortEnums(sort) as [S, ...`-${S}`[]]\n return {\n // @ts-expect-error: zod does not support tuple types\n sort: z.enum(sortEnums).optional().default(sortEnums[0]),\n }\n },\n}\n","import { z } from 'zod'\n\n// ===== Constants =====\n\nexport const MAX_FILE_SIZE = 100 * 1024 * 1024 // 100MB\n\nexport const MIME_TYPE_REGEX = /^[a-z]+\\/[a-z0-9\\-+.]+$/i\n\nexport const SUPPORTED_IMAGE_TYPES = [\n 'image/jpeg',\n 'image/png',\n 'image/gif',\n 'image/webp',\n 'image/svg+xml',\n] as const\n\nexport const SUPPORTED_DOCUMENT_TYPES = [\n 'application/pdf',\n 'application/msword',\n 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',\n 'application/vnd.ms-excel',\n 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',\n 'text/plain',\n 'text/markdown',\n] as const\n\nexport const SUPPORTED_VIDEO_TYPES = [\n 'video/mp4',\n 'video/webm',\n 'video/ogg',\n] as const\n\nexport const SUPPORTED_AUDIO_TYPES = [\n 'audio/mpeg',\n 'audio/wav',\n 'audio/ogg',\n] as const\n\n// ===== Enums =====\n\nexport enum StoragePolicy {\n DEFAULT = 'default',\n COLD = 'cold',\n HOT = 'hot',\n ARCHIVE = 'archive',\n}\n\nexport enum PreviewStatus {\n Pending = 'pending',\n Done = 'done',\n Failed = 'failed',\n}\n\n// ===== Storage Handle Schemas =====\n\nconst AzureBlobStorageHandleSchema = z.object({\n type: z.literal('azure-blob'),\n blobUri: z.url(),\n containerName: z.string().min(1),\n pathRelativeToContainer: z.string().min(1),\n})\n\nconst S3StorageHandleSchema = z.object({\n type: z.literal('s3'),\n bucket: z.string().min(1),\n key: z.string().min(1),\n region: z.string().min(1),\n})\n\nconst StorageHandleSchema = z.discriminatedUnion('type', [\n AzureBlobStorageHandleSchema,\n S3StorageHandleSchema,\n])\n\n// ===== Media Upload Schema =====\n\n/**\n * Media upload information for preparing a file upload\n */\nexport const MediaUploadSchema = z.object({\n /** Media type category (picture, video, audio, etc.) */\n type: z.string().min(1),\n /** Original filename */\n name: z.string().min(1),\n /** MIME type (e.g., 'image/jpeg') */\n mimeType: z.string().regex(MIME_TYPE_REGEX),\n /** File size in bytes (must be positive) */\n bytesCount: z.number().positive(),\n /** File extension with dot (e.g., '.jpg') */\n extension: z\n .string()\n .regex(/^\\.[a-zA-Z0-9]+$/)\n .overwrite((ext) => ext.toLowerCase()),\n /** Optional custom stored filename */\n storedFileName: z.string().optional(),\n /** Additional metadata key-value pairs */\n metadata: z.record(z.string(), z.string()).default({}),\n /** Storage tags for categorization */\n tags: z.record(z.string(), z.string()).default({}),\n})\nexport type MediaUpload = z.infer<typeof MediaUploadSchema>\n\n// ===== Media Source Schema =====\n\n/**\n * Complete media source information including storage details\n */\nexport const MediaSourceSchema = MediaUploadSchema.extend({\n /** Storage backend configuration */\n storageHandle: StorageHandleSchema,\n /** Storage tier/policy */\n storagePolicy: z.enum(StoragePolicy),\n /** Optional signature data for verification */\n signData: z.string().optional(),\n /** Actual stored filename (required) */\n storedFileName: z.string().min(1),\n})\nexport type MediaSource = z.infer<typeof MediaSourceSchema>\n\n// ===== Media Schema =====\n\n/**\n * Complete media object with source and optional variants\n */\nexport const MediaSchema = z.object({\n /** Display name for the media */\n name: z.string().min(1),\n /** Primary media source */\n src: MediaSourceSchema,\n /** Optional additional sources (e.g., different resolutions) */\n srcSet: z.array(MediaSourceSchema).default([]),\n /** Type-specific metadata (dimensions, duration, etc.) */\n rawOptions: z.custom<RawOptions>().optional(),\n})\nexport type Media = z.infer<typeof MediaSchema>\n\n// ===== Upload Handle Schema =====\n\n/**\n * Upload handle containing SAS URI and metadata for client-side upload\n */\nexport const MediaUploadHandleSchema = z.object({\n /** Media source information */\n src: MediaSourceSchema,\n /** Upload credentials and metadata */\n uploadHandle: z.object({\n /** Shared Access Signature URI for upload */\n uploadSasuri: z.url(),\n /** Metadata to attach to the blob */\n metadata: z.record(z.string(), z.string()).default({}),\n /** Tags to attach to the blob */\n tags: z.record(z.string(), z.string()).default({}),\n }),\n})\nexport type MediaUploadHandle = z.infer<typeof MediaUploadHandleSchema>\n\n// ===== Download Handle Schema =====\n\n/**\n * Download handle containing SAS URIs for different access patterns\n */\nexport const MediaDownloadHandleSchema = z.object({\n /** Media source information */\n src: MediaSourceSchema,\n /** Download credentials and URIs */\n downloadHandle: z.object({\n /** SAS URI for file download */\n downloadSasuri: z.url(),\n /** SAS URI for inline viewing */\n viewSasuri: z.url(),\n /** Optional SAS URI for preview thumbnail */\n previewSasuri: z.url().optional(),\n /** Expiration timestamp for the SAS URIs */\n expiresOn: z.string().datetime(),\n /** Storage backend type */\n type: z.string(),\n }),\n})\nexport type MediaDownloadHandle = z.infer<typeof MediaDownloadHandleSchema>\n\n// ===== Media Types =====\n\nexport enum MediaType {\n picture = 'picture',\n video = 'video',\n audio = 'audio',\n office = 'office',\n archive = 'archive',\n binary = 'binary',\n executable = 'executable',\n}\n\n// ===== Raw Options Schemas =====\n\nconst PictureRawOptionsSchema = z.object({\n type: z.literal(MediaType.picture),\n width: z.number().positive(),\n height: z.number().positive(),\n blurhash: z.string().optional(),\n})\n\nconst VideoRawOptionsSchema = z.object({\n type: z.literal(MediaType.video),\n width: z.number().positive(),\n height: z.number().positive(),\n duration: z.number().nonnegative(),\n})\n\nconst AudioRawOptionsSchema = z.object({\n type: z.literal(MediaType.audio),\n duration: z.number().nonnegative(),\n})\n\nconst OfficeRawOptionsSchema = z.object({\n type: z.literal(MediaType.office),\n})\n\nconst ArchiveRawOptionsSchema = z.object({\n type: z.literal(MediaType.archive),\n})\n\nconst BinaryRawOptionsSchema = z.object({\n type: z.literal(MediaType.binary),\n})\n\nconst ExecutableRawOptionsSchema = z.object({\n type: z.literal(MediaType.executable),\n})\n\nexport const RawOptionsSchema = z.discriminatedUnion('type', [\n PictureRawOptionsSchema,\n VideoRawOptionsSchema,\n AudioRawOptionsSchema,\n OfficeRawOptionsSchema,\n ArchiveRawOptionsSchema,\n BinaryRawOptionsSchema,\n ExecutableRawOptionsSchema,\n])\n\n// ===== Raw Options Types =====\n\n// ===== Raw Options Types =====\n\nexport type PictureRawOptions = z.infer<typeof PictureRawOptionsSchema>\nexport type VideoRawOptions = z.infer<typeof VideoRawOptionsSchema>\nexport type AudioRawOptions = z.infer<typeof AudioRawOptionsSchema>\nexport type OfficeRawOptions = z.infer<typeof OfficeRawOptionsSchema>\nexport type ArchiveRawOptions = z.infer<typeof ArchiveRawOptionsSchema>\nexport type BinaryRawOptions = z.infer<typeof BinaryRawOptionsSchema>\nexport type ExecutableRawOptions = z.infer<typeof ExecutableRawOptionsSchema>\n\nexport type RawOptions = z.infer<typeof RawOptionsSchema>\n\n// ===== Uploaded File Type =====\n\nexport type UploadedFile<Source = undefined> = Source extends undefined\n ? {\n name: string\n size: number\n type: string\n url: string\n lastModified?: number\n }\n : {\n name: string\n size: number\n type: string\n url: string\n lastModified?: number\n source: Source\n }\n\n// ===== Helper Functions =====\n\n/**\n * Check if a MIME type is a supported image format\n */\nexport const isSupportedImageType = (mimeType: string): boolean => {\n return mimeType.startsWith('image/')\n}\n\n/**\n * Check if a MIME type supports preview generation\n */\nexport const isSupportedPreviewType = (mimeType: string): boolean => {\n return mimeType.startsWith('image/') || mimeType === 'application/pdf'\n}\n\n/**\n * Determine MediaType from MIME type\n */\nexport const getMediaTypeFromMime = (mimeType: string): MediaType => {\n if (mimeType.startsWith('image/')) {\n return MediaType.picture\n }\n if (mimeType.startsWith('video/')) {\n return MediaType.video\n }\n if (mimeType.startsWith('audio/')) {\n return MediaType.audio\n }\n if (\n mimeType.startsWith('application/pdf') ||\n mimeType.startsWith('application/msword') ||\n mimeType.startsWith('application/vnd.openxmlformats') ||\n mimeType.startsWith('application/vnd.ms-')\n ) {\n return MediaType.office\n }\n if (\n mimeType === 'application/zip' ||\n mimeType === 'application/x-rar-compressed' ||\n mimeType === 'application/x-7z-compressed'\n ) {\n return MediaType.archive\n }\n if (\n mimeType.startsWith('application/x-') &&\n mimeType.includes('executable')\n ) {\n return MediaType.executable\n }\n return MediaType.binary\n}\n\n/**\n * Extract file extension from filename\n */\nexport const getExtensionFromFilename = (filename: string): string => {\n const lastDot = filename.lastIndexOf('.')\n return lastDot === -1 ? '' : filename.slice(lastDot).toLowerCase()\n}\n\n/**\n * Format bytes to human-readable string\n */\nexport const formatBytes = (bytes: number, decimals = 2): string => {\n if (bytes === 0) {\n return '0 Bytes'\n }\n const k = 1024\n const dm = decimals < 0 ? 0 : decimals\n const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB']\n const i = Math.floor(Math.log(bytes) / Math.log(k))\n return `${parseFloat((bytes / Math.pow(k, i)).toFixed(dm))} ${sizes[i]}`\n}\n\n// ===== Type Guards =====\n\nexport const isPictureOptions = (\n options: RawOptions,\n): options is PictureRawOptions => {\n return options.type === MediaType.picture\n}\n\nexport const isVideoOptions = (\n options: RawOptions,\n): options is VideoRawOptions => {\n return options.type === MediaType.video\n}\n\nexport const isAudioOptions = (\n options: RawOptions,\n): options is AudioRawOptions => {\n return options.type === MediaType.audio\n}\n\nexport const isOfficeOptions = (\n options: RawOptions,\n): options is OfficeRawOptions => {\n return options.type === MediaType.office\n}\n\nexport const isArchiveOptions = (\n options: RawOptions,\n): options is ArchiveRawOptions => {\n return options.type === MediaType.archive\n}\n\nexport const isBinaryOptions = (\n options: RawOptions,\n): options is BinaryRawOptions => {\n return options.type === MediaType.binary\n}\n\nexport const isExecutableOptions = (\n options: RawOptions,\n): options is ExecutableRawOptions => {\n return options.type === MediaType.executable\n}\n"],"mappings":";;AAWA,IAAa,KACT,GACA,GACA,MAEA,EAAQ,GAAO,GAAQ;CAGnB,SAAS,MAAU;CACnB;AACJ,CAAC,GAEC,IAAwB,OAGjB,IAAkB,EACnB,EAAS,GAAG,EAAU,CAAC,CAAC,CAC/B,QAAQ,MAAQ,KAAK,UAAU,CAAG,CAAC,CAAC,UAAU,GAAuB,EAClE,SAAS,0BAA0B,IAAwB,KAAK,KACpE,CAAC;AASqB,EAAO;AAWjC,IAAa,KAAwC,MAC1C,CAAC,GAAG,KAAS,IAAI,GAAO,GAGtB,KAAyC,MAC3C,EAAM,SAAS,MAAM,EAAa,CAAC,CAAC,GAGlC,IAAQ;CACjB,aAAa,IAAgB,GAAG,IAAc,QACnC;EACH,gBAAgB,EACJ,CAAC,CACR,GAAG,EAAS,CAAC,CAAC,CACd,WAAW,MAAM,OAAO,CAAC,CAAC,CAAC,CAC3B,QAAQ,CAAa;EAC1B,cAAc,EACF,CAAC,CACR,GAAG,EAAS,CAAC,CAAC,CACd,WAAW,MAAM,OAAO,CAAC,CAAC,CAAC,CAC3B,QAAQ,CAAW;CAC5B;CAEJ,SAAiC,OACtB,GAAG,UAAU,EAAM,KAAK,EAAS,CAAC,CAAC,SAAS,EAAE;CAKzD,UAAkC,OACvB,GAAG,WAAW,EAAM,KAAK,EAAS,CAAC,CAAC,SAAS,EAAE;CAK1D,QAAgC,OACrB;GACF,QAAQ,EAAM,KAAK,EAAS,CAAC,CAAC,SAAS;GACvC,MAAM,EAAM,KAAK,EAAS,CAAC,CAAC,SAAS;CAC1C;CAEJ,MAA8B,OACnB,GAAG,OAAO,EAAM,KAAK,EAAU,CAAC,CAAC,SAAS,EAAE;CAKvD,iBACW,EAAG,oBAAqB,EAAS,CAAC,CAAC,SAAS,EAAE;CAEzD,YACW,EAAE,KAAK,EAAQ,CAAC,EAAS,GAAG,EAAQ,EAAS,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE;CAExE,gBACW,EAAE,qBAAqB,EAAU,CAAC,CAAC,QAAQ,EAAK,EAAE;CAE7D,UAAkC,MACvB,EACF,KAAK,MAAM,EAAM,OAAO,CAAC,CAAC,CAAC,CAC3B,QAAQ,GAAG,OAAO;EAAE,GAAG;EAAG,GAAG;CAAE,EAAE;CAE1C,OAA+B,MAAc;EACzC,IAAM,IAAY,EAAc,CAAI;EACpC,OAAO,EAEH,MAAM,EAAO,CAAS,CAAC,CAAC,SAAS,CAAC,CAAC,QAAQ,EAAU,EAAE,EAC3D;CACJ;AACJ,GChHa,IAAkB,4BAkCnB,IAAL,yBAAA,GAAA;QACH,EAAA,UAAA,WACA,EAAA,OAAA,QACA,EAAA,MAAA,OACA,EAAA,UAAA;AACJ,EAAA,CAAA,CAAA,GAUM,IAA+B,EAAS;CAC1C,MAAM,EAAU,YAAY;CAC5B,SAAS,EAAM;CACf,eAAe,EAAS,CAAC,CAAC,IAAI,CAAC;CAC/B,yBAAyB,EAAS,CAAC,CAAC,IAAI,CAAC;AAC7C,CAAC,GAEK,IAAwB,EAAS;CACnC,MAAM,EAAU,IAAI;CACpB,QAAQ,EAAS,CAAC,CAAC,IAAI,CAAC;CACxB,KAAK,EAAS,CAAC,CAAC,IAAI,CAAC;CACrB,QAAQ,EAAS,CAAC,CAAC,IAAI,CAAC;AAC5B,CAAC,GAEK,IAAsB,EAAqB,QAAQ,CACrD,GACA,CACJ,CAAC,GAmCY,IA5BoB,EAAS;CAEtC,MAAM,EAAS,CAAC,CAAC,IAAI,CAAC;CAEtB,MAAM,EAAS,CAAC,CAAC,IAAI,CAAC;CAEtB,UAAU,EAAS,CAAC,CAAC,MAAM,CAAe;CAE1C,YAAY,EAAS,CAAC,CAAC,SAAS;CAEhC,WAAW,EACC,CAAC,CACR,MAAM,kBAAkB,CAAC,CACzB,WAAW,MAAQ,EAAI,YAAY,CAAC;CAEzC,gBAAgB,EAAS,CAAC,CAAC,SAAS;CAEpC,UAAU,EAAS,EAAS,GAAG,EAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;CAErD,MAAM,EAAS,EAAS,GAAG,EAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;AACrD,CAQiC,CAAA,CAAkB,OAAO;CAEtD,eAAe;CAEf,eAAe,EAAO,CAAa;CAEnC,UAAU,EAAS,CAAC,CAAC,SAAS;CAE9B,gBAAgB,EAAS,CAAC,CAAC,IAAI,CAAC;AACpC,CAAC,GAQY,IAAc,EAAS;CAEhC,MAAM,EAAS,CAAC,CAAC,IAAI,CAAC;CAEtB,KAAK;CAEL,QAAQ,EAAQ,CAAiB,CAAC,CAAC,QAAQ,CAAC,CAAC;CAE7C,YAAY,EAAqB,CAAC,CAAC,SAAS;AAChD,CAAC;AAQsC,EAAS;CAE5C,KAAK;CAEL,cAAc,EAAS;EAEnB,cAAc,EAAM;EAEpB,UAAU,EAAS,EAAS,GAAG,EAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;EAErD,MAAM,EAAS,EAAS,GAAG,EAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;CACrD,CAAC;AACL,CAAC,GAQwC,EAAS;CAE9C,KAAK;CAEL,gBAAgB,EAAS;EAErB,gBAAgB,EAAM;EAEtB,YAAY,EAAM;EAElB,eAAe,EAAM,CAAC,CAAC,SAAS;EAEhC,WAAW,EAAS,CAAC,CAAC,SAAS;EAE/B,MAAM,EAAS;CACnB,CAAC;AACL,CAAC;AAKD,IAAY,IAAL,yBAAA,GAAA;QACH,EAAA,UAAA,WACA,EAAA,QAAA,SACA,EAAA,QAAA,SACA,EAAA,SAAA,UACA,EAAA,UAAA,WACA,EAAA,SAAA,UACA,EAAA,aAAA;AACJ,EAAA,CAAA,CAAA,GAIM,IAA0B,EAAS;CACrC,MAAM,EAAU,EAAU,OAAO;CACjC,OAAO,EAAS,CAAC,CAAC,SAAS;CAC3B,QAAQ,EAAS,CAAC,CAAC,SAAS;CAC5B,UAAU,EAAS,CAAC,CAAC,SAAS;AAClC,CAAC,GAEK,IAAwB,EAAS;CACnC,MAAM,EAAU,EAAU,KAAK;CAC/B,OAAO,EAAS,CAAC,CAAC,SAAS;CAC3B,QAAQ,EAAS,CAAC,CAAC,SAAS;CAC5B,UAAU,EAAS,CAAC,CAAC,YAAY;AACrC,CAAC,GAEK,IAAwB,EAAS;CACnC,MAAM,EAAU,EAAU,KAAK;CAC/B,UAAU,EAAS,CAAC,CAAC,YAAY;AACrC,CAAC,GAEK,IAAyB,EAAS,EACpC,MAAM,EAAU,EAAU,MAAM,EACpC,CAAC,GAEK,IAA0B,EAAS,EACrC,MAAM,EAAU,EAAU,OAAO,EACrC,CAAC,GAEK,IAAyB,EAAS,EACpC,MAAM,EAAU,EAAU,MAAM,EACpC,CAAC,GAEK,IAA6B,EAAS,EACxC,MAAM,EAAU,EAAU,UAAU,EACxC,CAAC;AAE+B,EAAqB,QAAQ;CACzD;CACA;CACA;CACA;CACA;CACA;CACA;AACJ,CAAC"}