@arbidocs/blocks 0.4.142 → 0.4.143

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 (209) hide show
  1. package/dist/agents/index.cjs +438 -435
  2. package/dist/agents/index.js +10 -7
  3. package/dist/chat/index.cjs +139 -138
  4. package/dist/chat/index.js +4 -3
  5. package/dist/{chunk-S24XEVPS.cjs → chunk-464YPRAE.cjs} +33 -2
  6. package/dist/chunk-464YPRAE.cjs.map +1 -0
  7. package/dist/{chunk-7YLJHTDC.cjs → chunk-5A2QQAF5.cjs} +11 -11
  8. package/dist/{chunk-7YLJHTDC.cjs.map → chunk-5A2QQAF5.cjs.map} +1 -1
  9. package/dist/{chunk-ON3TKY5Y.js → chunk-5YHEHEJT.js} +242 -4
  10. package/dist/chunk-5YHEHEJT.js.map +1 -0
  11. package/dist/chunk-76L6LOP3.cjs +308 -0
  12. package/dist/chunk-76L6LOP3.cjs.map +1 -0
  13. package/dist/chunk-AOSUHWIL.js +98 -0
  14. package/dist/chunk-AOSUHWIL.js.map +1 -0
  15. package/dist/{chunk-PROK33G6.js → chunk-C44TDH54.js} +13 -1598
  16. package/dist/chunk-C44TDH54.js.map +1 -0
  17. package/dist/{chunk-YFY3TQ6Q.cjs → chunk-COCGRJLA.cjs} +7 -7
  18. package/dist/{chunk-YFY3TQ6Q.cjs.map → chunk-COCGRJLA.cjs.map} +1 -1
  19. package/dist/chunk-CQCC7LE7.js +210 -0
  20. package/dist/chunk-CQCC7LE7.js.map +1 -0
  21. package/dist/{chunk-UGCKUXRV.js → chunk-CSI2B2H5.js} +3 -3
  22. package/dist/{chunk-UGCKUXRV.js.map → chunk-CSI2B2H5.js.map} +1 -1
  23. package/dist/{chunk-R26BK7YL.cjs → chunk-DTROMMDX.cjs} +4 -4
  24. package/dist/{chunk-R26BK7YL.cjs.map → chunk-DTROMMDX.cjs.map} +1 -1
  25. package/dist/{chunk-65THHQVB.cjs → chunk-ECW2R2KF.cjs} +27 -27
  26. package/dist/{chunk-65THHQVB.cjs.map → chunk-ECW2R2KF.cjs.map} +1 -1
  27. package/dist/{chunk-RI6DZA5X.js → chunk-EF4ZLKRM.js} +3 -3
  28. package/dist/{chunk-RI6DZA5X.js.map → chunk-EF4ZLKRM.js.map} +1 -1
  29. package/dist/{chunk-WS5EX7DN.cjs → chunk-EYKISBDO.cjs} +5 -5
  30. package/dist/{chunk-WS5EX7DN.cjs.map → chunk-EYKISBDO.cjs.map} +1 -1
  31. package/dist/chunk-FJETR2AS.js +561 -0
  32. package/dist/chunk-FJETR2AS.js.map +1 -0
  33. package/dist/{chunk-JO3EMZ4X.js → chunk-GWSGIZQ5.js} +3 -3
  34. package/dist/{chunk-JO3EMZ4X.js.map → chunk-GWSGIZQ5.js.map} +1 -1
  35. package/dist/{chunk-I7WG3JRD.js → chunk-H4D7WKDY.js} +3 -3
  36. package/dist/{chunk-I7WG3JRD.js.map → chunk-H4D7WKDY.js.map} +1 -1
  37. package/dist/{chunk-GBS6QVGS.cjs → chunk-HAOKT4LC.cjs} +5 -5
  38. package/dist/{chunk-GBS6QVGS.cjs.map → chunk-HAOKT4LC.cjs.map} +1 -1
  39. package/dist/{chunk-N5X37J3D.js → chunk-IJST4EBM.js} +11 -8
  40. package/dist/chunk-IJST4EBM.js.map +1 -0
  41. package/dist/{chunk-3RJN2VTL.js → chunk-IXWJGOM2.js} +3 -3
  42. package/dist/{chunk-3RJN2VTL.js.map → chunk-IXWJGOM2.js.map} +1 -1
  43. package/dist/{chunk-CYNF5PZI.js → chunk-J5CWKFSC.js} +3 -3
  44. package/dist/{chunk-CYNF5PZI.js.map → chunk-J5CWKFSC.js.map} +1 -1
  45. package/dist/{chunk-OWCEQKAR.cjs → chunk-JSTKEZBS.cjs} +21 -318
  46. package/dist/chunk-JSTKEZBS.cjs.map +1 -0
  47. package/dist/{chunk-TP6PLDNM.cjs → chunk-KMZWKSKO.cjs} +8 -8
  48. package/dist/{chunk-TP6PLDNM.cjs.map → chunk-KMZWKSKO.cjs.map} +1 -1
  49. package/dist/{chunk-C4WSHRR6.cjs → chunk-KPZZ5FHE.cjs} +32 -12
  50. package/dist/chunk-KPZZ5FHE.cjs.map +1 -0
  51. package/dist/{chunk-CKCBBYTA.js → chunk-KSHKTOY2.js} +5 -205
  52. package/dist/chunk-KSHKTOY2.js.map +1 -0
  53. package/dist/chunk-LJJJ6CYH.cjs +62 -0
  54. package/dist/chunk-LJJJ6CYH.cjs.map +1 -0
  55. package/dist/chunk-LPYEUD2D.cjs +1627 -0
  56. package/dist/chunk-LPYEUD2D.cjs.map +1 -0
  57. package/dist/chunk-MHFF5N65.cjs +101 -0
  58. package/dist/chunk-MHFF5N65.cjs.map +1 -0
  59. package/dist/{chunk-GYAUJ4KT.js → chunk-MTSKK3BN.js} +32 -3
  60. package/dist/chunk-MTSKK3BN.js.map +1 -0
  61. package/dist/chunk-NHZK64TQ.js +75 -0
  62. package/dist/chunk-NHZK64TQ.js.map +1 -0
  63. package/dist/{chunk-BPBSSMRB.js → chunk-NRFAWUVD.js} +3 -3
  64. package/dist/{chunk-BPBSSMRB.js.map → chunk-NRFAWUVD.js.map} +1 -1
  65. package/dist/chunk-NWNVWO6L.cjs +80 -0
  66. package/dist/chunk-NWNVWO6L.cjs.map +1 -0
  67. package/dist/{chunk-HIJUXAWS.cjs → chunk-O2GW5IY6.cjs} +86 -83
  68. package/dist/chunk-O2GW5IY6.cjs.map +1 -0
  69. package/dist/{chunk-3BFGL2JL.cjs → chunk-ODRHHWHY.cjs} +4 -4
  70. package/dist/{chunk-3BFGL2JL.cjs.map → chunk-ODRHHWHY.cjs.map} +1 -1
  71. package/dist/{chunk-Y3KA6X7B.js → chunk-OVR3XMYL.js} +4 -4
  72. package/dist/{chunk-Y3KA6X7B.js.map → chunk-OVR3XMYL.js.map} +1 -1
  73. package/dist/{chunk-Y5KTM3V5.js → chunk-PDKM27DF.js} +17 -295
  74. package/dist/chunk-PDKM27DF.js.map +1 -0
  75. package/dist/{chunk-OAL3B2ZU.cjs → chunk-PLJ7PHWU.cjs} +5 -5
  76. package/dist/{chunk-OAL3B2ZU.cjs.map → chunk-PLJ7PHWU.cjs.map} +1 -1
  77. package/dist/{chunk-DPGFEMVT.cjs → chunk-RB7GX2VT.cjs} +57 -1665
  78. package/dist/chunk-RB7GX2VT.cjs.map +1 -0
  79. package/dist/chunk-RFIBUWLF.cjs +232 -0
  80. package/dist/chunk-RFIBUWLF.cjs.map +1 -0
  81. package/dist/{chunk-MIDXCYZB.cjs → chunk-RQ2Y7USX.cjs} +15 -235
  82. package/dist/chunk-RQ2Y7USX.cjs.map +1 -0
  83. package/dist/chunk-SV65E4QW.js +58 -0
  84. package/dist/chunk-SV65E4QW.js.map +1 -0
  85. package/dist/{chunk-LYUO3E6V.js → chunk-SZOFGU7W.js} +3 -3
  86. package/dist/{chunk-LYUO3E6V.js.map → chunk-SZOFGU7W.js.map} +1 -1
  87. package/dist/chunk-T5B7FM7S.js +1602 -0
  88. package/dist/chunk-T5B7FM7S.js.map +1 -0
  89. package/dist/{chunk-YNIBUKV5.js → chunk-TBEVGWY3.js} +32 -14
  90. package/dist/chunk-TBEVGWY3.js.map +1 -0
  91. package/dist/{chunk-MJCCBMM5.cjs → chunk-TC3RQNEX.cjs} +6 -80
  92. package/dist/chunk-TC3RQNEX.cjs.map +1 -0
  93. package/dist/chunk-TZGBRLPK.js +288 -0
  94. package/dist/chunk-TZGBRLPK.js.map +1 -0
  95. package/dist/chunk-U6YVZDOV.cjs +574 -0
  96. package/dist/chunk-U6YVZDOV.cjs.map +1 -0
  97. package/dist/{chunk-QIMVTGKS.cjs → chunk-U73KPFYH.cjs} +255 -2
  98. package/dist/chunk-U73KPFYH.cjs.map +1 -0
  99. package/dist/{chunk-HFGXA5CL.cjs → chunk-UTTTJSQU.cjs} +4 -4
  100. package/dist/{chunk-HFGXA5CL.cjs.map → chunk-UTTTJSQU.cjs.map} +1 -1
  101. package/dist/{chunk-DLBUFHLY.js → chunk-VTTZZ4FN.js} +4 -74
  102. package/dist/chunk-VTTZZ4FN.js.map +1 -0
  103. package/dist/{chunk-5FTIHRZH.cjs → chunk-XVUOMWMD.cjs} +4 -4
  104. package/dist/{chunk-5FTIHRZH.cjs.map → chunk-XVUOMWMD.cjs.map} +1 -1
  105. package/dist/{chunk-FXG7TFAG.js → chunk-Y4ATWQGV.js} +3 -3
  106. package/dist/{chunk-FXG7TFAG.js.map → chunk-Y4ATWQGV.js.map} +1 -1
  107. package/dist/{chunk-444XKG46.js → chunk-YKQ2DPIP.js} +3 -3
  108. package/dist/{chunk-444XKG46.js.map → chunk-YKQ2DPIP.js.map} +1 -1
  109. package/dist/{chunk-HEMU73OP.cjs → chunk-YSHIC4NJ.cjs} +4 -4
  110. package/dist/{chunk-HEMU73OP.cjs.map → chunk-YSHIC4NJ.cjs.map} +1 -1
  111. package/dist/{chunk-5BXEYYH6.js → chunk-ZM26YEOT.js} +3 -3
  112. package/dist/{chunk-5BXEYYH6.js.map → chunk-ZM26YEOT.js.map} +1 -1
  113. package/dist/citations/index.cjs +12 -12
  114. package/dist/citations/index.js +3 -3
  115. package/dist/connect/docx.cjs +36 -7
  116. package/dist/connect/docx.cjs.map +1 -1
  117. package/dist/connect/docx.d.ts +9 -2
  118. package/dist/connect/docx.js +30 -6
  119. package/dist/connect/docx.js.map +1 -1
  120. package/dist/connect/index.cjs +802 -628
  121. package/dist/connect/index.cjs.map +1 -1
  122. package/dist/connect/index.d.ts +2 -0
  123. package/dist/connect/index.js +636 -507
  124. package/dist/connect/index.js.map +1 -1
  125. package/dist/connection/ConnectedSettings.d.ts +3 -2
  126. package/dist/connection/docx/ConnectedNativeDocxComparison.d.ts +5 -0
  127. package/dist/connection/docx/ConnectedNativeDocxEditor.d.ts +16 -0
  128. package/dist/connection/{ConnectedStreamedWordArtifact.d.ts → docx/ConnectedStreamedWordArtifact.d.ts} +1 -1
  129. package/dist/connection/docx/support.d.ts +27 -0
  130. package/dist/connection/docx/useConnectedDocxReferences.d.ts +2 -0
  131. package/dist/connection/docx/useConnectedHouseTemplate.d.ts +2 -0
  132. package/dist/connection/settings-page/ConnectedAccountSettings.d.ts +35 -0
  133. package/dist/connection/settings-page/ConnectedMailSettings.d.ts +13 -0
  134. package/dist/connection/settings-page/ConnectedPremiumModels.d.ts +1 -0
  135. package/dist/connection/settings-page/ConnectedPrivacySettings.d.ts +12 -0
  136. package/dist/connection/settings-page/ConnectedSettingsPage.d.ts +29 -0
  137. package/dist/connection/settings-page/SessionStatusIcon.d.ts +7 -0
  138. package/dist/connection/settings-page/index.d.ts +6 -0
  139. package/dist/docx/index.cjs +17 -63
  140. package/dist/docx/index.cjs.map +1 -1
  141. package/dist/docx/index.d.ts +1 -0
  142. package/dist/docx/index.js +2 -64
  143. package/dist/docx/index.js.map +1 -1
  144. package/dist/docx/template/candidates.d.ts +16 -0
  145. package/dist/facts/index.cjs +3 -3
  146. package/dist/facts/index.js +2 -2
  147. package/dist/files/index.cjs +3 -3
  148. package/dist/files/index.js +2 -2
  149. package/dist/home/index.cjs +20 -20
  150. package/dist/home/index.js +4 -4
  151. package/dist/index.cjs +766 -741
  152. package/dist/index.cjs.map +1 -1
  153. package/dist/index.d.ts +2 -0
  154. package/dist/index.js +23 -18
  155. package/dist/index.js.map +1 -1
  156. package/dist/lib/deep-link.d.ts +46 -0
  157. package/dist/provider/BlocksProvider.d.ts +5 -1
  158. package/dist/provider/settings-section.d.ts +9 -0
  159. package/dist/retrieval/index.cjs +4 -4
  160. package/dist/retrieval/index.js +2 -2
  161. package/dist/settings/AppearanceSettings.d.ts +18 -0
  162. package/dist/settings/ServerConnectionControls.d.ts +16 -0
  163. package/dist/settings/SettingsPage.d.ts +31 -0
  164. package/dist/settings/index.cjs +188 -250
  165. package/dist/settings/index.cjs.map +1 -1
  166. package/dist/settings/index.d.ts +3 -1
  167. package/dist/settings/index.js +88 -199
  168. package/dist/settings/index.js.map +1 -1
  169. package/dist/shell/index.cjs +44 -44
  170. package/dist/shell/index.js +3 -3
  171. package/dist/site/index.cjs +74 -73
  172. package/dist/site/index.js +3 -2
  173. package/dist/studio/index.cjs +80 -78
  174. package/dist/studio/index.cjs.map +1 -1
  175. package/dist/studio/index.js +10 -8
  176. package/dist/studio/index.js.map +1 -1
  177. package/dist/workflow-canvas/index.cjs +62 -59
  178. package/dist/workflow-canvas/index.cjs.map +1 -1
  179. package/dist/workflow-canvas/index.js +10 -7
  180. package/dist/workflow-canvas/index.js.map +1 -1
  181. package/dist/workspaces/index.cjs +3 -3
  182. package/dist/workspaces/index.js +2 -2
  183. package/node_modules/@arbidocs/coedit/package.json +1 -1
  184. package/package.json +4 -4
  185. package/dist/chunk-4TR5QCCX.cjs +0 -43
  186. package/dist/chunk-4TR5QCCX.cjs.map +0 -1
  187. package/dist/chunk-7NDW4KF4.cjs +0 -112
  188. package/dist/chunk-7NDW4KF4.cjs.map +0 -1
  189. package/dist/chunk-C4WSHRR6.cjs.map +0 -1
  190. package/dist/chunk-CKCBBYTA.js.map +0 -1
  191. package/dist/chunk-DLBUFHLY.js.map +0 -1
  192. package/dist/chunk-DPGFEMVT.cjs.map +0 -1
  193. package/dist/chunk-ETXYVO6E.js +0 -109
  194. package/dist/chunk-ETXYVO6E.js.map +0 -1
  195. package/dist/chunk-GYAUJ4KT.js.map +0 -1
  196. package/dist/chunk-HIJUXAWS.cjs.map +0 -1
  197. package/dist/chunk-MCKOZACC.js +0 -41
  198. package/dist/chunk-MCKOZACC.js.map +0 -1
  199. package/dist/chunk-MIDXCYZB.cjs.map +0 -1
  200. package/dist/chunk-MJCCBMM5.cjs.map +0 -1
  201. package/dist/chunk-N5X37J3D.js.map +0 -1
  202. package/dist/chunk-ON3TKY5Y.js.map +0 -1
  203. package/dist/chunk-OWCEQKAR.cjs.map +0 -1
  204. package/dist/chunk-PROK33G6.js.map +0 -1
  205. package/dist/chunk-QIMVTGKS.cjs.map +0 -1
  206. package/dist/chunk-S24XEVPS.cjs.map +0 -1
  207. package/dist/chunk-Y5KTM3V5.js.map +0 -1
  208. package/dist/chunk-YNIBUKV5.js.map +0 -1
  209. package/dist/connection/ConnectedNativeDocxEditor.d.ts +0 -6
@@ -1,28 +1,31 @@
1
1
  "use client";
2
- import { DraggableHeader, SettingsSection, ProfileCard, AvatarPicker, IdentityVerificationCard, IdentityVerificationDialog, RequireVerified, PasswordChangeDialog, SettingsCard, SettingsActionRow, EMAIL_NOTIFICATION_KEYS, EMAIL_NOTIFICATION_CATEGORIES, NotificationCategoryList, toNotificationCategories, toActiveSessionViews, SettingsRow, ActiveSessionsDialog, LogoutDialog, toLogoutSessionViews, SettingsDangerZone, DeleteAccountDialog, toDeleteBlockerViews } from '../chunk-ON3TKY5Y.js';
3
- export { ConnectedAssistantDock, redlineStats, textToArtifact, toRedlineMarkdown, useConnectedAiTask, useConnectedChat, useSemanticSearch, useWorkspaceDocs } from '../chunk-UGCKUXRV.js';
4
- import { useConnectedConversations, useConnectedDocuments, useConnectedTags } from '../chunk-45LRMW54.js';
2
+ import { DraggableHeader, SettingsSection, ProfileCard, AvatarPicker, IdentityVerificationCard, IdentityVerificationDialog, RequireVerified, PasswordChangeDialog, SettingsCard, SettingsActionRow, EMAIL_NOTIFICATION_KEYS, EMAIL_NOTIFICATION_CATEGORIES, NotificationCategoryList, toNotificationCategories, toActiveSessionViews, SettingsRow, ActiveSessionsDialog, LogoutDialog, toLogoutSessionViews, SettingsDangerZone, DeleteAccountDialog, toDeleteBlockerViews, SettingsPanel, PremiumModelsFrame, SettingsPage, serverConnectionView, ServerConnectionButton, ModelProviderLabel } from '../chunk-5YHEHEJT.js';
3
+ export { ConnectedAssistantDock, redlineStats, textToArtifact, toRedlineMarkdown, useConnectedAiTask, useConnectedChat, useSemanticSearch, useWorkspaceDocs } from '../chunk-CSI2B2H5.js';
4
+ import { useConnectedWorkspaceRole, ConnectedNativeDocxEditor } from '../chunk-FJETR2AS.js';
5
+ export { ConnectedWorkflowDocumentsField, ConnectedWorkflowLauncher, ConnectedWorkflowsTable, DEFAULT_CONNECTED_WORKFLOWS_TABLE_LABELS, NativeDocxSupportProvider, toWorkflowFieldDocument, useConnectedAgentOptions, useConnectedWorkflowScopeSource, useConnectedWorkspaceRole, useNativeDocxSupport } from '../chunk-FJETR2AS.js';
5
6
  export { ConnectedWorkspaceDataProvider, useConnectedConversations, useConnectedDocuments, useConnectedTags } from '../chunk-45LRMW54.js';
6
- import { ConnectedNativeDocxEditor } from '../chunk-ETXYVO6E.js';
7
7
  import { ConnectionProvider, useConnection, useConnectedWorkspace } from '../chunk-US3S4DCB.js';
8
8
  export { ConnectionProvider, SESSION_EXPIRED_MESSAGE, isAuthenticated, useConnectedWorkspace, useConnection } from '../chunk-US3S4DCB.js';
9
9
  import { SignDocumentDialog } from '../chunk-2YOVK524.js';
10
- import '../chunk-GYAUJ4KT.js';
10
+ import '../chunk-MTSKK3BN.js';
11
11
  import '../chunk-2FL7QJKJ.js';
12
12
  import '../chunk-HFZ45FD3.js';
13
13
  import { FilesFilterBar, FolderFilterButton, FolderPickerRow } from '../chunk-7RJTEWYM.js';
14
- import { WorkspaceActivityList, WorkspaceNotificationMenu, ThreadFollowMenuItem, ThreadFollowButton, TagTable, tagTableDocx } from '../chunk-FXG7TFAG.js';
14
+ import { WorkspaceActivityList, WorkspaceNotificationMenu, ThreadFollowMenuItem, ThreadFollowButton, TagTable, tagTableDocx } from '../chunk-Y4ATWQGV.js';
15
15
  import { workspaceKindColor } from '../chunk-A3XPS2EU.js';
16
16
  import { PlainMailBodyEditor, draftMailCompose, replyMailCompose, emptyMailCompose, MailGrid, MailMessageView, MailDocumentPicker, parseMailRecipients } from '../chunk-6HCJ3ZEU.js';
17
+ import '../chunk-SV65E4QW.js';
17
18
  import { DOCX_MIME_TYPE } from '../chunk-QXMR5YHC.js';
18
19
  import '../chunk-AF6RDAJF.js';
19
- import { WorkflowsTable, workflowTriggerType, buildWorkflowScopeSource, documentScopeLabels, WorkflowDocumentsField, WorkflowLauncher, buildLibrarySkills, filterLibrarySkills, SKILL_SOURCE_LABELS, SKILL_TYPE_LABELS, SkillViewToggle, SkillFilterChips, SkillTile, SkillGenerateForm, SkillLibraryDetail, parseSkillFrontmatter, SKILL_MAIN_FILENAME, SkillEditForm, DEFAULT_AGENT_CAPABILITIES, stripPersonaPreamble, AgentCreator, DEFAULT_AGENT_TYPES, DEFAULT_AGENT_TEMPLATES, AgentAvatarField, isValidAgentName, AgentConnectInstructions, TaskRunsDialog, PersonPill, TaskActivityDialog, WorkflowStepBar, composePersona, importSkillFile, importSkillFromUrl, WorkflowRunner, skillSlug, serializeSkill, fromPlanSteps, toPlanSteps, useWorkflowView, workflowToSkillMarkdown } from '../chunk-PROK33G6.js';
20
- import '../chunk-3RJN2VTL.js';
20
+ import { buildLibrarySkills, filterLibrarySkills, SKILL_SOURCE_LABELS, SKILL_TYPE_LABELS, SkillViewToggle, SkillFilterChips, SkillTile, SkillGenerateForm, SkillLibraryDetail, parseSkillFrontmatter, SKILL_MAIN_FILENAME, SkillEditForm, DEFAULT_AGENT_CAPABILITIES, stripPersonaPreamble, AgentCreator, DEFAULT_AGENT_TYPES, DEFAULT_AGENT_TEMPLATES, AgentAvatarField, isValidAgentName, AgentConnectInstructions, TaskRunsDialog, TaskActivityDialog, WorkflowStepBar, composePersona, importSkillFile, importSkillFromUrl, WorkflowRunner, skillSlug, serializeSkill, fromPlanSteps, toPlanSteps, useWorkflowView, workflowToSkillMarkdown } from '../chunk-C44TDH54.js';
21
+ import { MultiSelect } from '../chunk-CQCC7LE7.js';
22
+ import { PersonPill } from '../chunk-T5B7FM7S.js';
23
+ import '../chunk-IXWJGOM2.js';
21
24
  import '../chunk-RLWIUUQ5.js';
22
- import { TriStateFilterMenu, MultiSelect } from '../chunk-CKCBBYTA.js';
25
+ import { TriStateFilterMenu } from '../chunk-KSHKTOY2.js';
23
26
  import '../chunk-P6GHJSLR.js';
24
27
  import '../chunk-EVUEIBNU.js';
25
- import '../chunk-444XKG46.js';
28
+ import '../chunk-YKQ2DPIP.js';
26
29
  import { SelectionBar, SelectionBarAction } from '../chunk-NUNKSZKU.js';
27
30
  import { FilterInput } from '../chunk-YU2KUMGE.js';
28
31
  import { GridView } from '../chunk-N5YEF3LC.js';
@@ -32,27 +35,28 @@ import { upcomingOf, conferenceUrl, isWebinarConference, canJoinEvent, calendarT
32
35
  import { detectTimeZone, utcToDate, formatPlainDate, formatInZone, safeZone, todayInZone, addDays, wallToUtc } from '../chunk-GTCC2VAR.js';
33
36
  import { ConfirmDialog } from '../chunk-VHJHY7TT.js';
34
37
  import { TabHeader } from '../chunk-4WWM3GQ5.js';
35
- import { ChatPage } from '../chunk-JO3EMZ4X.js';
38
+ import { ChatPage } from '../chunk-GWSGIZQ5.js';
36
39
  import '../chunk-7XF5SFJ2.js';
37
40
  import { takeOpenDocumentForTurn, useRegisterOpenDocument } from '../chunk-YBLIKTJK.js';
38
- import { splitDocRef, stepLevels, stepDocuments, stepKindOf, initialRunInputs, workflowSteps, stepStatesFromActivity, runThreadTitle, stepFields } from '../chunk-Y5KTM3V5.js';
41
+ import { splitDocRef, stepLevels, stepDocuments, stepKindOf, initialRunInputs, workflowSteps, stepStatesFromActivity, runThreadTitle, stepFields } from '../chunk-PDKM27DF.js';
42
+ import '../chunk-TZGBRLPK.js';
39
43
  import '../chunk-AA3PT6KR.js';
40
44
  import '../chunk-AUS3KBHJ.js';
41
45
  import '../chunk-SLSBJRWW.js';
42
46
  import '../chunk-NPLYHR2E.js';
43
47
  import '../chunk-7F6CBP3Z.js';
44
- import { useCopyText } from '../chunk-CYNF5PZI.js';
45
- import { useBlocksEnvironment } from '../chunk-YNIBUKV5.js';
48
+ import { useCopyText } from '../chunk-J5CWKFSC.js';
49
+ import { useBlocksEnvironment, useRequestedSettingsSection } from '../chunk-TBEVGWY3.js';
46
50
  import { ModalScaffold } from '../chunk-TX2ZICS7.js';
47
51
  import { fmtDate, initials } from '../chunk-OXF2IFXG.js';
48
52
  import '../chunk-VUNV25KB.js';
49
53
  import { lazy, useState, useMemo, useEffect, useCallback, useRef, Suspense, useSyncExternalStore, useLayoutEffect } from 'react';
50
54
  import { QueryClient, QueryClientProvider, useQueryClient, useQuery } from '@tanstack/react-query';
51
- import { ArbiProvider, useConversations, useRunConversation, useWorkspaceActivity, useWorkspaceUsers, isWorkspaceNotificationType, useArbi, useNotifications, useDeleteNotifications, useMarkNotificationsRead, useWorkspaces, useWorkspaceNotificationLevel, useFollowThread, useWorkflows, useAgents, useUpdateWorkflow, useDeleteWorkflow, useRunWorkflow, useThumbnails, useUploadSkillFiles, useSkills, useSetSkillVisibility, useDeleteSkill, useSkillSource, useAgentModels, useMcpTools, useAgentConfig, useAgentWorkspaces, useCreateAgent, useSaveAgentConfig, useGrantAgentAccess, useRevokeAgentAccess, useGenerateAgentAvatar, useWorkflowRuns, useConversationActivity, ArtifactCanvas, useArbiChat, useDocuments, useTagKindSchema, useTags, useSetTagValues, useUpdateTagKindSchema, useInvalidateTagData, useShellWorkspaces, useProfile, useUpdateProfile, useRequestEmailChange, useConfirmEmailChange, useNameEditor, useAvatarCrop, useEmailChange, ImageCropModal, useIdentityVerification, usePasswordChange, usePasswordChangeForm, useNotificationPreferences, useSessions, useCurrentSessionId, useTerminateSession, useSignOut, useDeleteAccount, useDeleteAccountFlow, useArbiWebSocket, useWorkNotifications, mailDraftIdFromContent, useMailClient, defaultMailAlias, useClaimNativeAlias, useMailOnline, useConnectMailAccount, useDisconnectMailAccount, useMailPolicy, useMailAccounts, useMailUnlock, useMailFolders, useMailMessages, useMailDraftCompose, useMailMessage, useMailCache, MailOfflineUnavailableError, accountPath, useCalendarEvents, useCalendars, useFetchCalendarEvent, useCalendarSettings, useCalendarOverlays, useCalendarOutbox, useCalendarAccounts, useSyncAccountsOnOpen, useResumeCalendarAccountConnect, useCreateEvent, useUpdateEvent, useDeleteEvent, useMoveEvent, useRespondToEvent, useCreateCalendar, useUpdateCalendar, useDeleteCalendar, useImportCalendar, useSaveCalendarSettings, useRefreshCalendar, useCalendarEvent, useMailAttachmentText, useCalendarEventByUid, getPublicBookingPage, bookPublicSlot, PublicBookingError, useAgentSession, useStartAgentSession, useCloseAgentSession, isQueuedCalendarWrite, isAliasTakenError, nextAliasSuggestion, aliasTakenMessage, mailJson, ArbiWebSocketProvider, isDeploymentUserNotification, getWorkspaceActionText, getWorkspaceSentPhrase, describeServerNotification, BOX_SEAT_REFUSED, BOX_SEAT_REFUSED_TITLE, documentActivityPhrase, isSignatureNotificationType, inputRequestTitle, WORK_NOTIFICATION_LABELS, useArbiSessionState, documentDisplayName, getWorkspaceKind, formatRelativeTime, useCreateWork, useActOnStep, useConversationThreads, fileAttachment, useMailProjects, useSaveMailDraft, useSendMail, useMailDraftReplaced, useCalendarInvitations, useDecideCounter, useSearchContacts, usePublishCalendar, useCalendarShares, useShareCalendar, useUnshareCalendar, useSubscribeCalendar, useHolidayCountries, useAddHolidayCalendar, cancelPublicBooking, AiAnswer, signatureNotificationPhrase, signatureRequestMeta, getNotificationTypeMeta, useMailDraftEditor, useFreeBusy, useRooms, useFindTime, useCalendarSupport, useStartCalendarAccountOAuth, useConnectOAuthAccount, useAppPasswords, splitAppPasswords, useBookingPages, useDeleteBookingPage, useSyncCalendarAccount, useUpdateCalendarAccount, useDisconnectCalendarAccount, ACCOUNT_VENDOR, useCalDavProfiles, useConnectCalDavAccount, useCreateAppPassword, useCreateFeed, useSaveBookingPage, useCreateRoom, useRevokeAppPassword } from '@arbidocs/react';
55
+ import { ArbiProvider, useConversations, useRunConversation, useWorkspaceActivity, useWorkspaceUsers, isWorkspaceNotificationType, useArbi, useNotifications, useDeleteNotifications, useMarkNotificationsRead, useWorkspaces, useWorkspaceNotificationLevel, useFollowThread, useUploadSkillFiles, useSkills, useSetSkillVisibility, useDeleteSkill, useSkillSource, useAgentModels, useMcpTools, useAgentConfig, useAgentWorkspaces, useCreateAgent, useSaveAgentConfig, useGrantAgentAccess, useRevokeAgentAccess, useGenerateAgentAvatar, useWorkflowRuns, useConversationActivity, useAgents, ArtifactCanvas, useArbiChat, useDocuments, useTagKindSchema, useTags, useSetTagValues, useUpdateTagKindSchema, useInvalidateTagData, useShellWorkspaces, ArbiBotHeadIcon, useProfile, useUpdateProfile, useRequestEmailChange, useConfirmEmailChange, useNameEditor, useAvatarCrop, useEmailChange, ImageCropModal, useIdentityVerification, usePasswordChange, usePasswordChangeForm, useNotificationPreferences, useSessions, useCurrentSessionId, useTerminateSession, useSignOut, useDeleteAccount, useDeleteAccountFlow, useMailClient, defaultMailAlias, useClaimNativeAlias, useMailOnline, useConnectMailAccount, useDisconnectMailAccount, useMailPolicy, useMailAccounts, useUserSettings, useUpdateUserSettings, useAvailableModels, useArbiWebSocket, useWorkNotifications, mailDraftIdFromContent, useMailUnlock, useMailFolders, useMailMessages, useMailDraftCompose, useMailMessage, useMailCache, MailOfflineUnavailableError, accountPath, useCalendarEvents, useCalendars, useFetchCalendarEvent, useCalendarSettings, useCalendarOverlays, useCalendarOutbox, useCalendarAccounts, useSyncAccountsOnOpen, useResumeCalendarAccountConnect, useCreateEvent, useUpdateEvent, useDeleteEvent, useMoveEvent, useRespondToEvent, useCreateCalendar, useUpdateCalendar, useDeleteCalendar, useImportCalendar, useSaveCalendarSettings, useRefreshCalendar, useCalendarEvent, useMailAttachmentText, useCalendarEventByUid, getPublicBookingPage, bookPublicSlot, PublicBookingError, useAgentSession, useStartAgentSession, useCloseAgentSession, isQueuedCalendarWrite, isAliasTakenError, nextAliasSuggestion, aliasTakenMessage, mailJson, ArbiWebSocketProvider, isDeploymentUserNotification, getWorkspaceActionText, getWorkspaceSentPhrase, describeServerNotification, BOX_SEAT_REFUSED, BOX_SEAT_REFUSED_TITLE, documentActivityPhrase, isSignatureNotificationType, inputRequestTitle, WORK_NOTIFICATION_LABELS, useArbiSessionState, documentDisplayName, getWorkspaceKind, formatRelativeTime, useCreateWork, useActOnStep, useConversationThreads, ProviderIcon, formatGbpPerMillionTokens, fileAttachment, useMailProjects, useSaveMailDraft, useSendMail, useMailDraftReplaced, useCalendarInvitations, useDecideCounter, useSearchContacts, usePublishCalendar, useCalendarShares, useShareCalendar, useUnshareCalendar, useSubscribeCalendar, useHolidayCountries, useAddHolidayCalendar, cancelPublicBooking, AiAnswer, signatureNotificationPhrase, signatureRequestMeta, getNotificationTypeMeta, useMailDraftEditor, useFreeBusy, useRooms, useFindTime, useCalendarSupport, useStartCalendarAccountOAuth, useConnectOAuthAccount, useAppPasswords, splitAppPasswords, useBookingPages, useDeleteBookingPage, useSyncCalendarAccount, useUpdateCalendarAccount, useDisconnectCalendarAccount, ACCOUNT_VENDOR, useCalDavProfiles, useConnectCalDavAccount, useCreateAppPassword, useCreateFeed, useSaveBookingPage, useCreateRoom, useRevokeAppPassword } from '@arbidocs/react';
52
56
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
53
- import { Button, Label, Input, cn, Textarea, Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, DocumentEntity, EntityPill, ShieldIcon, EntityIcon, Tooltip, TooltipTrigger, TooltipContent, Popover, PopoverTrigger, PopoverContent, Tabs, TabsList, TabsTrigger, TabsContent, DialogFooter, UserEntity, Switch } from '@arbidocs/react/ui';
57
+ import { Button, Label, Input, cn, Textarea, Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, Switch, DocumentEntity, EntityPill, ShieldIcon, EntityIcon, Tooltip, TooltipTrigger, TooltipContent, Popover, PopoverTrigger, PopoverContent, Tabs, TabsList, TabsTrigger, TabsContent, DialogFooter, UserEntity } from '@arbidocs/react/ui';
54
58
  import { useNotify } from '@arbidocs/react/shell';
55
- import { Bell, Activity, Info, UserCheck, Trash2, Loader2, Upload, Link2, Search, Plus, ArrowLeft, ExternalLink, UserCircle, KeyRound, Radio, Mail, Settings, Video, Printer, CalendarDays, Clock, MapPin, Globe, X, Paperclip, Send, Inbox, CalendarX, CalendarCheck, MessageSquare, CalendarSearch, Pencil, DoorOpen, RefreshCw, CheckCircle2, AlertTriangle, Check, Copy } from 'lucide-react';
59
+ import { Bell, Activity, Info, UserCheck, Trash2, Loader2, Upload, Link2, Search, Plus, ArrowLeft, ExternalLink, Monitor, UserCircle, KeyRound, Radio, LogOut, Wifi, RotateCcw, User, Mail, HatGlasses, MessageSquare, Settings, Video, Printer, CalendarDays, Clock, MapPin, Globe, X, Paperclip, Send, Inbox, CalendarX, CalendarCheck, CalendarSearch, Pencil, DoorOpen, RefreshCw, CheckCircle2, AlertTriangle, Check, Copy } from 'lucide-react';
56
60
  import { useIsOnline, downloadBlob, useOptionalDocumentTools, fetchDocumentPdf, DocumentToolsProvider } from '@arbidocs/react/document-tools';
57
61
  import { useStreamedArtifact } from '@arbidocs/react/artifacts';
58
62
  import { bytesToBase64 } from '@arbidocs/client';
@@ -839,255 +843,6 @@ function ConnectedThreadFollow({
839
843
  }
840
844
  );
841
845
  }
842
- function useConnectedWorkspaceRole() {
843
- const { workspaceId, live, userId, ensureWorkspaceOpen } = useConnectedWorkspace();
844
- const { data: members = [] } = useWorkspaceUsers(workspaceId ?? void 0, {
845
- enabled: live && !!workspaceId,
846
- beforeFetch: ensureWorkspaceOpen
847
- });
848
- const role = members.find((m) => m.user.external_id === userId)?.role;
849
- return {
850
- members,
851
- role,
852
- /** An owner or a collaborator edits, pauses, resumes and runs what is shared with the workspace. */
853
- canEditShared: role === "owner" || role === "collaborator",
854
- /** With an item's creator, the only one who deletes it. */
855
- isWorkspaceOwner: role === "owner"
856
- };
857
- }
858
- var DEFAULT_CONNECTED_WORKFLOWS_TABLE_LABELS = {
859
- updateFailed: "Could not update the workflow",
860
- deleteTitle: "Delete workflow",
861
- deleteOne: (name) => `Delete \u201C${name}\u201D? Threads it already created stay.`,
862
- deleteMany: (count) => `Delete ${count} workflows? Threads they already created stay.`,
863
- runFailed: "The workflow failed. You can send an error report from its history.",
864
- noThread: "The workflow did not create a thread.",
865
- documentAction: (workflow) => workflow.action?.type === "email_documents" ? "Preparing your document email" : "Reviewing documents",
866
- untitledTask: "Untitled thread"
867
- };
868
- var messageOf = (error) => error instanceof Error ? error.message : "";
869
- function ConnectedWorkflowsTable({
870
- filter,
871
- describeTrigger = (w) => workflowTriggerType(w).replaceAll("_", " "),
872
- formatDate: formatDate2 = fmtDate,
873
- onViewRuns,
874
- connectedLabels,
875
- ...tableProps
876
- }) {
877
- const l = { ...DEFAULT_CONNECTED_WORKFLOWS_TABLE_LABELS, ...connectedLabels };
878
- const { notify, confirm, openConversation } = useBlocksEnvironment();
879
- const { canEditShared, isWorkspaceOwner } = useConnectedWorkspaceRole();
880
- const { data: saved = [], isLoading } = useWorkflows({ live: true });
881
- const { data: conversations, refetch } = useConnectedConversations({ live: true });
882
- const { data: agents = [] } = useAgents();
883
- const update = useUpdateWorkflow();
884
- const remove = useDeleteWorkflow();
885
- const run = useRunWorkflow();
886
- const [busyId, setBusyId] = useState(null);
887
- const workflows = useMemo(() => filter ? saved.filter(filter) : saved, [saved, filter]);
888
- const firingStamp = saved.map((w) => `${w.external_id}:${w.last_fired_at ?? ""}`).join("|");
889
- useEffect(() => {
890
- void refetch?.();
891
- }, [firingStamp, refetch]);
892
- const lastRuns = useMemo(() => {
893
- const out = {};
894
- for (const c of conversations) {
895
- const id = c.workflow_ext_id;
896
- if (id && (!out[id] || Date.parse(c.created_at) > Date.parse(out[id].at)))
897
- out[id] = { conversationId: c.external_id, at: c.created_at, threadStatus: c.status };
898
- }
899
- return out;
900
- }, [conversations]);
901
- const agentNames = useMemo(
902
- () => Object.fromEntries(agents.map((a) => [a.external_id, a.given_name || a.email])),
903
- [agents]
904
- );
905
- const taskNames = useMemo(
906
- () => Object.fromEntries(
907
- conversations.filter((c) => c.status != null).map((c) => [c.external_id, c.title || l.untitledTask])
908
- ),
909
- [conversations, l.untitledTask]
910
- );
911
- const act = async (workflow, action) => {
912
- setBusyId(workflow.external_id);
913
- try {
914
- await action();
915
- } catch (error) {
916
- notify(messageOf(error) || l.updateFailed, "error");
917
- } finally {
918
- setBusyId(null);
919
- }
920
- };
921
- const setActive = (workflow, active) => act(workflow, () => update.mutateAsync({ workflowId: workflow.external_id, patch: { active } }));
922
- const deleteAll = async (items) => {
923
- if (!items.length) return;
924
- const ok = await confirm({
925
- title: l.deleteTitle,
926
- message: items.length === 1 ? l.deleteOne(items[0].name) : l.deleteMany(items.length)
927
- });
928
- if (!ok) return;
929
- for (const workflow of items)
930
- await act(workflow, () => remove.mutateAsync(workflow.external_id));
931
- };
932
- return /* @__PURE__ */ jsx(
933
- WorkflowsTable,
934
- {
935
- ...tableProps,
936
- workflows,
937
- isLoading,
938
- busyId,
939
- describeTrigger,
940
- formatDate: formatDate2,
941
- agentNames,
942
- taskNames,
943
- lastRuns,
944
- canEditShared,
945
- isWorkspaceOwner,
946
- onOpenThread: (conversationId) => openConversation(conversationId),
947
- onViewRuns,
948
- onToggleActive: (workflow, active) => void setActive(workflow, active),
949
- onToggleActiveMany: (items, active) => {
950
- void (async () => {
951
- for (const workflow of items) await setActive(workflow, active);
952
- })();
953
- },
954
- onToggleShared: (workflow, shared) => void act(
955
- workflow,
956
- () => update.mutateAsync({ workflowId: workflow.external_id, patch: { shared } })
957
- ),
958
- onDelete: (workflow) => void deleteAll([workflow]),
959
- onDeleteMany: (items) => void deleteAll(items),
960
- onRun: (workflow) => void act(workflow, async () => {
961
- const result = await run.mutateAsync(workflow.external_id);
962
- if (result.conversation_ext_id) openConversation(result.conversation_ext_id);
963
- if (result.error) {
964
- onViewRuns?.(workflow);
965
- notify(l.runFailed, "error");
966
- return;
967
- }
968
- if (result.execution_id && !result.conversation_ext_id) {
969
- onViewRuns?.(workflow);
970
- notify(l.documentAction(workflow), "success");
971
- return;
972
- }
973
- if (!result.conversation_ext_id) throw new Error(l.noThread);
974
- })
975
- }
976
- );
977
- }
978
- var IMAGE_FILE_TYPES = /* @__PURE__ */ new Set(["png", "jpg", "jpeg", "gif", "bmp", "tiff", "webp"]);
979
- function toWorkflowFieldDocument(doc) {
980
- const isImage = IMAGE_FILE_TYPES.has((doc.file_type ?? "").toLowerCase());
981
- return {
982
- id: doc.external_id,
983
- title: doc.doc_metadata?.title || doc.file_name || doc.external_id,
984
- fileName: doc.file_name,
985
- pages: isImage ? null : doc.n_pages ?? null,
986
- tokens: isImage ? null : doc.tokens ?? null,
987
- status: doc.status,
988
- isImage
989
- };
990
- }
991
- function useConnectedWorkflowScopeSource() {
992
- const { data: docs } = useConnectedDocuments();
993
- const { data: tags } = useConnectedTags();
994
- return useMemo(() => buildWorkflowScopeSource(docs, documentScopeLabels(tags)), [docs, tags]);
995
- }
996
- function useConnectedAgentOptions() {
997
- const { data: agents } = useAgents();
998
- return useMemo(
999
- () => (agents ?? []).map((a) => ({ id: a.external_id, label: a.given_name || a.email })),
1000
- [agents]
1001
- );
1002
- }
1003
- function ConnectedWorkflowDocumentsField({
1004
- field,
1005
- value,
1006
- onChange,
1007
- onAddFiles,
1008
- labels
1009
- }) {
1010
- const arbi = useArbi();
1011
- const { notify } = useBlocksEnvironment();
1012
- const { ensureWorkspaceOpen } = useConnectedWorkspace();
1013
- const { data: docs, loaded, refetch } = useConnectedDocuments();
1014
- const documents = useMemo(() => docs.map(toWorkflowFieldDocument), [docs]);
1015
- const chosen = value.documents ?? [];
1016
- const { data: thumbnails } = useThumbnails(chosen, { enabled: (field.max ?? 1) > 1 });
1017
- const input = useRef(null);
1018
- const [adding, setAdding] = useState(false);
1019
- const upload = useCallback(
1020
- async (files) => {
1021
- setAdding(true);
1022
- try {
1023
- await ensureWorkspaceOpen();
1024
- for (const file of files) await arbi.documents.uploadFile(file, file.name);
1025
- } catch (error) {
1026
- notify(error instanceof Error && error.message ? error.message : String(error), "error");
1027
- } finally {
1028
- setAdding(false);
1029
- await refetch?.();
1030
- }
1031
- },
1032
- [arbi, ensureWorkspaceOpen, notify, refetch]
1033
- );
1034
- return /* @__PURE__ */ jsxs(Fragment, { children: [
1035
- !onAddFiles && /* @__PURE__ */ jsx(
1036
- "input",
1037
- {
1038
- ref: input,
1039
- type: "file",
1040
- multiple: true,
1041
- className: "hidden",
1042
- "aria-label": "Add files",
1043
- "data-testid": "workflow-add-files-input",
1044
- onChange: (e) => {
1045
- const files = Array.from(e.target.files ?? []);
1046
- e.target.value = "";
1047
- if (files.length) void upload(files);
1048
- }
1049
- }
1050
- ),
1051
- /* @__PURE__ */ jsx(
1052
- WorkflowDocumentsField,
1053
- {
1054
- field,
1055
- value,
1056
- onChange,
1057
- documents,
1058
- loaded,
1059
- thumbnailOf: (id) => thumbnails?.[id],
1060
- onAddFiles: onAddFiles ?? ((files) => files?.length ? void upload(files) : input.current?.click()),
1061
- adding,
1062
- labels
1063
- }
1064
- )
1065
- ] });
1066
- }
1067
- function ConnectedWorkflowLauncher({
1068
- onAddFiles,
1069
- ...props
1070
- }) {
1071
- const scopeSource = useConnectedWorkflowScopeSource();
1072
- const agents = useConnectedAgentOptions();
1073
- return /* @__PURE__ */ jsx(
1074
- WorkflowLauncher,
1075
- {
1076
- ...props,
1077
- scopeSource,
1078
- agents,
1079
- renderDocuments: (field, value, onChange) => /* @__PURE__ */ jsx(
1080
- ConnectedWorkflowDocumentsField,
1081
- {
1082
- field,
1083
- value,
1084
- onChange,
1085
- onAddFiles
1086
- }
1087
- )
1088
- }
1089
- );
1090
- }
1091
846
  var DEFAULT_CONNECTED_SKILL_UPLOAD_LABELS = {
1092
847
  title: "Add a skill",
1093
848
  description: "Bring in a skill someone sent you, from a file or a link.",
@@ -2988,6 +2743,11 @@ function useConnectedShellWorkspaces(options = {}) {
2988
2743
  select: (workspace) => setWorkspace(workspace.id)
2989
2744
  });
2990
2745
  }
2746
+ function SessionStatusIcon({ status, className }) {
2747
+ if (status === "agent") return /* @__PURE__ */ jsx(ArbiBotHeadIcon, { className: className ?? "w-4 h-4" });
2748
+ return /* @__PURE__ */ jsx(Monitor, { className: className ?? "w-4 h-4 text-muted-foreground" });
2749
+ }
2750
+ var renderSessionStatusIcon = (status) => /* @__PURE__ */ jsx(SessionStatusIcon, { status });
2991
2751
  function errorText2(error, fallback) {
2992
2752
  const body = error?.apiError;
2993
2753
  return typeof body?.detail === "string" ? body.detail : fallback;
@@ -3225,7 +2985,9 @@ function ConnectedNotificationPreferences({
3225
2985
  }
3226
2986
  ) }) });
3227
2987
  }
3228
- function ConnectedSessionsRow({ renderSessionIcon }) {
2988
+ function ConnectedSessionsRow({
2989
+ renderSessionIcon = renderSessionStatusIcon
2990
+ }) {
3229
2991
  const { notify, confirm } = useBlocksEnvironment();
3230
2992
  const [open, setOpen] = useState(false);
3231
2993
  const sessions = useSessions({ enabled: open });
@@ -3291,7 +3053,7 @@ function ConnectedLogoutDialog({
3291
3053
  onClose,
3292
3054
  canLogoutAll = true,
3293
3055
  confirmSignOut,
3294
- renderSessionIcon
3056
+ renderSessionIcon = renderSessionStatusIcon
3295
3057
  }) {
3296
3058
  const sessions = useSessions({ enabled: open });
3297
3059
  const signOut = useSignOut();
@@ -3369,251 +3131,120 @@ function ConnectedDangerZone({ renderSubscriptionLink }) {
3369
3131
  )
3370
3132
  ] });
3371
3133
  }
3372
- function useConnectedDocxNotifications(onOpen) {
3373
- const arbi = useArbi();
3374
- const { status, user, apiUrl } = useConnection();
3375
- const { notify } = useBlocksEnvironment();
3376
- const queries = useQueryClient();
3377
- const source = `docx-mentions:${apiUrl}:${user?.externalId || ""}`;
3378
- const queryKey = ["docx-mentions", apiUrl, user?.externalId];
3379
- const { data = [] } = useQuery({
3380
- queryKey,
3381
- queryFn: () => arbi.notifications.list({ type: "docx_mention" }),
3382
- enabled: status === "authenticated",
3383
- refetchInterval: 3e4
3384
- });
3385
- useArbiWebSocket((message) => {
3386
- if (message.type === "docx_mention") void queries.invalidateQueries({ queryKey });
3387
- });
3388
- useEffect(() => {
3389
- const items = [];
3390
- if (status === "authenticated")
3391
- for (const note of data) {
3392
- if (note.recipient.external_id !== user?.externalId || !note.workspace_ext_id) continue;
3393
- try {
3394
- const target = JSON.parse(note.content || "{}");
3395
- if (!target.document_id?.startsWith("doc-") || !target.comment_id) continue;
3396
- const documentId = target.document_id, commentId = target.comment_id, workspaceId = note.workspace_ext_id;
3397
- items.push({
3398
- id: `docx:${note.external_id}`,
3399
- title: "Mentioned you in a document comment",
3400
- description: [note.sender.given_name, note.sender.family_name].filter(Boolean).join(" "),
3401
- variant: "info",
3402
- ts: Date.parse(note.created_at),
3403
- read: note.read,
3404
- source,
3405
- onSelect: () => {
3406
- void Promise.resolve(onOpen({ documentId, commentId, workspaceId })).catch(
3407
- (error) => notify(
3408
- error instanceof Error ? error.message : "Could not open the document.",
3409
- "error"
3410
- )
3411
- );
3412
- }
3413
- });
3414
- } catch {
3415
- }
3416
- }
3417
- useNotify.getState().syncSource(source, items);
3418
- return () => useNotify.getState().syncSource(source, []);
3419
- }, [data, status, user?.externalId, source, onOpen, notify]);
3420
- const markRead = async (ids) => {
3134
+ function ServerConnectionRow({ onRefresh, ...status }) {
3135
+ const { runtimeConfig } = useBlocksEnvironment();
3136
+ const [isRefreshing, setIsRefreshing] = useState(false);
3137
+ const view = serverConnectionView(status, runtimeConfig.deploymentDomain || "server");
3138
+ const refresh = async () => {
3139
+ setIsRefreshing(true);
3421
3140
  try {
3422
- await arbi.notifications.markRead(ids);
3423
- await queries.invalidateQueries({ queryKey });
3424
- } catch {
3425
- notify("Could not mark document mentions read.", "error");
3141
+ await onRefresh();
3142
+ } finally {
3143
+ setIsRefreshing(false);
3426
3144
  }
3427
3145
  };
3428
- return {
3429
- onMarkRead: (id) => {
3430
- if (id.startsWith("docx:")) void markRead([id.slice(5)]);
3431
- },
3432
- onMarkAllRead: () => {
3433
- void markRead(
3434
- data.filter((note) => !note.read && note.recipient.external_id === user?.externalId).map((note) => note.external_id)
3435
- );
3146
+ return /* @__PURE__ */ jsx(SettingsRow, { label: "Server connection", description: view.description, children: /* @__PURE__ */ jsx(
3147
+ ServerConnectionButton,
3148
+ {
3149
+ state: view.state,
3150
+ label: view.label,
3151
+ isRefreshing,
3152
+ onRefresh: () => void refresh()
3436
3153
  }
3437
- };
3154
+ ) });
3438
3155
  }
3439
- function useConnectedWorkNotifications(onOpen) {
3440
- const { status, user, apiUrl } = useConnection();
3441
- const { notify } = useBlocksEnvironment();
3442
- const source = `work-notifications:${apiUrl}:${user?.externalId || ""}`;
3443
- const { data = [], markRead: persistRead } = useWorkNotifications({
3444
- apiUrl,
3445
- userId: user?.externalId,
3446
- enabled: status === "authenticated"
3447
- });
3448
- useEffect(() => {
3449
- const items = [];
3450
- if (status === "authenticated")
3451
- for (const note of data) {
3452
- if (note.recipient.external_id !== user?.externalId) continue;
3453
- const mapped = mapWorkNotification(note);
3454
- if (!mapped) continue;
3455
- items.push({
3456
- id: `work:${note.external_id}`,
3457
- title: mapped.title,
3458
- variant: note.type === "workflow_failed" ? "error" : note.type === "conversation_done" ? "success" : "info",
3459
- ts: Date.parse(note.created_at),
3460
- read: note.read,
3461
- source,
3462
- onSelect: () => {
3463
- void Promise.resolve().then(() => onOpen(mapped.target)).catch(
3464
- (error) => notify(
3465
- error instanceof Error ? error.message : "Could not open this notification.",
3466
- "error"
3467
- )
3468
- );
3469
- }
3470
- });
3156
+ function ConnectedAccountSettings({
3157
+ avatarClassName,
3158
+ onManageBilling,
3159
+ formatIdentityPrice,
3160
+ afterProfile,
3161
+ getUnmetPasswordRequirement,
3162
+ securityRows,
3163
+ connection,
3164
+ onLogout,
3165
+ renderSessionIcon,
3166
+ renderSubscriptionLink
3167
+ }) {
3168
+ const [logoutOpen, setLogoutOpen] = useState(false);
3169
+ return /* @__PURE__ */ jsxs(SettingsPanel, { className: "max-w-2xl", children: [
3170
+ /* @__PURE__ */ jsx(ConnectedProfileCard, { avatarClassName, children: /* @__PURE__ */ jsx(
3171
+ ConnectedIdentityVerification,
3172
+ {
3173
+ onManageBilling,
3174
+ formatPrice: formatIdentityPrice
3471
3175
  }
3472
- useNotify.getState().syncSource(source, items);
3473
- return () => useNotify.getState().syncSource(source, []);
3474
- }, [data, status, user?.externalId, source, onOpen, notify]);
3475
- const markRead = async (ids) => {
3476
- if (!ids.length) return;
3176
+ ) }),
3177
+ afterProfile,
3178
+ /* @__PURE__ */ jsx(ConnectedSecuritySection, { getUnmetRequirement: getUnmetPasswordRequirement, children: securityRows }),
3179
+ /* @__PURE__ */ jsx(SettingsSection, { icon: /* @__PURE__ */ jsx(Wifi, {}), title: "Session", children: /* @__PURE__ */ jsxs(SettingsCard, { children: [
3180
+ connection && /* @__PURE__ */ jsx(ServerConnectionRow, { ...connection }),
3181
+ /* @__PURE__ */ jsx(ConnectedSessionsRow, { renderSessionIcon }),
3182
+ /* @__PURE__ */ jsx(SettingsRow, { label: "Logout", description: "Sign out of your account on this device.", children: /* @__PURE__ */ jsxs(
3183
+ Button,
3184
+ {
3185
+ type: "button",
3186
+ variant: "secondary",
3187
+ size: "sm",
3188
+ onClick: onLogout ?? (() => setLogoutOpen(true)),
3189
+ className: "flex items-center gap-2",
3190
+ "data-testid": "logout-button",
3191
+ children: [
3192
+ /* @__PURE__ */ jsx(LogOut, { className: "w-4 h-4" }),
3193
+ "Logout"
3194
+ ]
3195
+ }
3196
+ ) })
3197
+ ] }) }),
3198
+ /* @__PURE__ */ jsx(ConnectedDangerZone, { renderSubscriptionLink }),
3199
+ !onLogout && /* @__PURE__ */ jsx(
3200
+ ConnectedLogoutDialog,
3201
+ {
3202
+ open: logoutOpen,
3203
+ onClose: () => setLogoutOpen(false),
3204
+ renderSessionIcon
3205
+ }
3206
+ )
3207
+ ] });
3208
+ }
3209
+ function ConnectedMailAccounts({
3210
+ policy,
3211
+ accounts,
3212
+ onClose,
3213
+ embedded = false,
3214
+ user,
3215
+ oauthReturnPath,
3216
+ settings
3217
+ }) {
3218
+ const { client } = useMailClient();
3219
+ const [profileId, setProfileId] = useState(policy.server_profiles[0]?.id ?? "");
3220
+ const [email, setEmail] = useState("");
3221
+ const [username, setUsername] = useState("");
3222
+ const [password, setPassword] = useState("");
3223
+ const [error, setError] = useState("");
3224
+ const [alias, setAlias] = useState(() => defaultMailAlias(user));
3225
+ const native = useClaimNativeAlias(onClose);
3226
+ const isOnline = useMailOnline();
3227
+ const offline = !isOnline;
3228
+ const onNativeError = (err) => {
3229
+ if (!isAliasTakenError(err)) return setError(err.message);
3230
+ const suggestion = nextAliasSuggestion(alias);
3231
+ setAlias(suggestion);
3232
+ setError(aliasTakenMessage(alias, suggestion, policy.native_domain));
3233
+ };
3234
+ const connect = useConnectMailAccount();
3235
+ const disconnect = useDisconnectMailAccount();
3236
+ const authorizeOAuth = client.authorizeOAuth;
3237
+ const oauth = async (vendor) => {
3238
+ if (!authorizeOAuth) return;
3477
3239
  try {
3478
- await persistRead(ids);
3479
- } catch {
3480
- notify("Could not mark work notifications read.", "error");
3481
- }
3482
- };
3483
- return {
3484
- onMarkRead: (id) => {
3485
- if (data.some(
3486
- (note) => `work:${note.external_id}` === id && note.recipient.external_id === user?.externalId && mapWorkNotification(note)
3487
- ))
3488
- void markRead([id.slice(5)]);
3489
- },
3490
- onMarkAllRead: () => {
3491
- void markRead(
3492
- data.filter(
3493
- (note) => !note.read && note.recipient.external_id === user?.externalId && mapWorkNotification(note)
3494
- ).map((note) => note.external_id)
3495
- );
3496
- }
3497
- };
3498
- }
3499
- function mapWorkNotification(note) {
3500
- const sender = [note.sender.given_name, note.sender.family_name].filter(Boolean).join(" ") || note.sender.email;
3501
- if (note.type === "workflow_failed") {
3502
- try {
3503
- const payload = JSON.parse(note.content || "{}");
3504
- if (!payload.workflow_ext_id?.match(/^wfl-[a-zA-Z0-9]+$/)) return null;
3505
- if (note.workspace_ext_id?.match(/^wrk-[a-zA-Z0-9]+$/) && note.conversation_ext_id?.match(/^con-[a-zA-Z0-9]+$/)) {
3506
- return {
3507
- title: "A workflow failed to run",
3508
- target: {
3509
- kind: "conversation",
3510
- workspaceId: note.workspace_ext_id,
3511
- conversationId: note.conversation_ext_id
3512
- }
3513
- };
3514
- }
3515
- return {
3516
- title: "A workflow failed to run",
3517
- target: {
3518
- kind: "workflow",
3519
- workflowId: payload.workflow_ext_id,
3520
- workspaceId: note.workspace_ext_id || void 0
3521
- }
3522
- };
3523
- } catch {
3524
- return null;
3525
- }
3526
- }
3527
- if (note.type === "mail_draft_ready") {
3528
- const draftId = mailDraftIdFromContent(note.content);
3529
- if (!draftId) return null;
3530
- return {
3531
- title: `${sender} left a draft email for you to review`,
3532
- target: { kind: "mail_draft", draftId, mailbox: "native" }
3533
- };
3534
- }
3535
- const titles = {
3536
- mention: `${sender} mentioned you in a conversation`,
3537
- workspace_access_request: `${sender} needs workspace access to run a thread`,
3538
- conversation_ready: note.sender.external_id === note.recipient.external_id ? "Your thread is ready" : `${sender}\u2019s thread is ready`,
3539
- conversation_done: `${sender} marked a thread done`
3540
- };
3541
- const title = titles[note.type];
3542
- if (!title || !note.workspace_ext_id || !note.conversation_ext_id?.match(/^con-[a-zA-Z0-9]+$/))
3543
- return null;
3544
- return {
3545
- title,
3546
- target: {
3547
- kind: "conversation",
3548
- workspaceId: note.workspace_ext_id,
3549
- conversationId: note.conversation_ext_id,
3550
- ...note.message_ext_id ? { messageId: note.message_ext_id } : {}
3551
- }
3552
- };
3553
- }
3554
- function attachmentPath(accountId, messageId, attachmentId) {
3555
- return `${accountPath(accountId)}/messages/${encodeURIComponent(messageId)}/attachments/${encodeURIComponent(attachmentId)}`;
3556
- }
3557
- function saveFile(blob, name) {
3558
- const url = URL.createObjectURL(blob);
3559
- const link = document.createElement("a");
3560
- link.href = url;
3561
- link.download = name;
3562
- link.click();
3563
- setTimeout(() => URL.revokeObjectURL(url), 1e3);
3564
- }
3565
- function hydrateMailAttachments(client, account, messageId, attachments, { isOnline, offline }) {
3566
- return Promise.all(
3567
- attachments.map(async (a) => {
3568
- if (a.content_base64 != null) return a;
3569
- if (!isOnline) {
3570
- const file = await offline?.loadAttachment(account.id, messageId, a);
3571
- return file ? { ...a, content_base64: bytesToBase64(new Uint8Array(await file.arrayBuffer())) } : { ...a, content_base64: null };
3572
- }
3573
- const response = await client.fetch(attachmentPath(account.id, messageId, a.id));
3574
- return fileAttachment(new File([await response.blob()], a.name, { type: a.content_type }));
3575
- })
3576
- );
3577
- }
3578
- function ConnectedMailAccounts({
3579
- policy,
3580
- accounts,
3581
- onClose,
3582
- embedded = false,
3583
- user,
3584
- oauthReturnPath,
3585
- settings
3586
- }) {
3587
- const { client } = useMailClient();
3588
- const [profileId, setProfileId] = useState(policy.server_profiles[0]?.id ?? "");
3589
- const [email, setEmail] = useState("");
3590
- const [username, setUsername] = useState("");
3591
- const [password, setPassword] = useState("");
3592
- const [error, setError] = useState("");
3593
- const [alias, setAlias] = useState(() => defaultMailAlias(user));
3594
- const native = useClaimNativeAlias(onClose);
3595
- const isOnline = useMailOnline();
3596
- const offline = !isOnline;
3597
- const onNativeError = (err) => {
3598
- if (!isAliasTakenError(err)) return setError(err.message);
3599
- const suggestion = nextAliasSuggestion(alias);
3600
- setAlias(suggestion);
3601
- setError(aliasTakenMessage(alias, suggestion, policy.native_domain));
3602
- };
3603
- const connect = useConnectMailAccount();
3604
- const disconnect = useDisconnectMailAccount();
3605
- const authorizeOAuth = client.authorizeOAuth;
3606
- const oauth = async (vendor) => {
3607
- if (!authorizeOAuth) return;
3608
- try {
3609
- window.location.assign(
3610
- await authorizeOAuth(
3611
- vendor,
3612
- oauthReturnPath ?? `${window.location.pathname}${window.location.search}`
3613
- )
3614
- );
3615
- } catch (err) {
3616
- setError(err instanceof Error ? err.message : "Could not connect account");
3240
+ window.location.assign(
3241
+ await authorizeOAuth(
3242
+ vendor,
3243
+ oauthReturnPath ?? `${window.location.pathname}${window.location.search}`
3244
+ )
3245
+ );
3246
+ } catch (err) {
3247
+ setError(err instanceof Error ? err.message : "Could not connect account");
3617
3248
  }
3618
3249
  };
3619
3250
  const content = /* @__PURE__ */ jsxs(Fragment, { children: [
@@ -3798,6 +3429,504 @@ function ConnectedMailAccounts({
3798
3429
  }
3799
3430
  );
3800
3431
  }
3432
+ var noop = () => {
3433
+ };
3434
+ function ConnectedMailSettings({ oauthReturnPath, settings }) {
3435
+ const { data: policy } = useMailPolicy();
3436
+ const accounts = useMailAccounts({ enabled: !!policy?.enabled });
3437
+ const { data: profile } = useProfile();
3438
+ if (accounts.isError) {
3439
+ return /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: accounts.error.message });
3440
+ }
3441
+ if (!policy || !accounts.isSuccess) return /* @__PURE__ */ jsx("p", { children: "Loading mail accounts\u2026" });
3442
+ return /* @__PURE__ */ jsx(
3443
+ ConnectedMailAccounts,
3444
+ {
3445
+ embedded: true,
3446
+ policy,
3447
+ accounts: accounts.data,
3448
+ user: profile && { given_name: profile.givenName, family_name: profile.familyName },
3449
+ oauthReturnPath,
3450
+ settings,
3451
+ onClose: noop
3452
+ },
3453
+ profile ? "named" : "unnamed"
3454
+ );
3455
+ }
3456
+ function ConnectedPrivacySettings({
3457
+ rows,
3458
+ showTipsReset = false
3459
+ }) {
3460
+ const { data: settings } = useUserSettings();
3461
+ const update = useUpdateUserSettings();
3462
+ const hideOnlineStatus = settings?.hide_online_status ?? false;
3463
+ const dismissedTips = settings?.dismissed_tips ?? [];
3464
+ return /* @__PURE__ */ jsxs(SettingsPanel, { className: "max-w-2xl", children: [
3465
+ /* @__PURE__ */ jsx(SettingsSection, { title: "Privacy and tips", children: /* @__PURE__ */ jsxs(SettingsCard, { children: [
3466
+ /* @__PURE__ */ jsx(
3467
+ SettingsRow,
3468
+ {
3469
+ label: "Show Online Status",
3470
+ labelFor: "showOnlineStatus",
3471
+ description: "When on, other users can see when you're online",
3472
+ children: /* @__PURE__ */ jsx(
3473
+ Switch,
3474
+ {
3475
+ id: "showOnlineStatus",
3476
+ checked: !hideOnlineStatus,
3477
+ onCheckedChange: (value) => update.mutate({ hide_online_status: !value }),
3478
+ "data-testid": "toggle-show-online-status"
3479
+ }
3480
+ )
3481
+ }
3482
+ ),
3483
+ rows,
3484
+ showTipsReset && /* @__PURE__ */ jsx(
3485
+ SettingsRow,
3486
+ {
3487
+ label: "Hidden tips",
3488
+ description: "Restore any Smart Tips you\u2019ve hidden with \u201Cdon\u2019t show again\u201D.",
3489
+ children: /* @__PURE__ */ jsxs(
3490
+ Button,
3491
+ {
3492
+ type: "button",
3493
+ variant: "outline",
3494
+ size: "sm",
3495
+ onClick: () => update.mutate({ dismissed_tips: [] }),
3496
+ disabled: dismissedTips.length === 0,
3497
+ className: "gap-1.5",
3498
+ "data-testid": "reset-tips-button",
3499
+ children: [
3500
+ /* @__PURE__ */ jsx(RotateCcw, { className: "h-4 w-4" }),
3501
+ "Reset tips"
3502
+ ]
3503
+ }
3504
+ )
3505
+ }
3506
+ )
3507
+ ] }) }),
3508
+ /* @__PURE__ */ jsx(ConnectedNotificationPreferences, {})
3509
+ ] });
3510
+ }
3511
+ var PROVIDER_NAMES = {
3512
+ openai: "OpenAI",
3513
+ fireworks_ai: "Fireworks AI",
3514
+ "vertex_ai-language-models": "Google",
3515
+ vertex_ai: "Google",
3516
+ gemini: "Google",
3517
+ anthropic: "Anthropic"
3518
+ };
3519
+ var isStandard = (model) => !!model?.tags?.includes("Standard");
3520
+ function PremiumCostHeader() {
3521
+ return /* @__PURE__ */ jsx("span", { className: "flex items-center gap-0.5", children: "\xA3/MT in-out" });
3522
+ }
3523
+ function cheapest(models) {
3524
+ return [...models].sort((a, b) => {
3525
+ const ao = a.output_cost_per_token;
3526
+ const bo = b.output_cost_per_token;
3527
+ if (ao == null && bo == null) return 0;
3528
+ if (ao == null) return 1;
3529
+ if (bo == null) return -1;
3530
+ return ao - bo;
3531
+ })[0];
3532
+ }
3533
+ var COLUMNS = [
3534
+ {
3535
+ colId: "model_name",
3536
+ headerName: "Model",
3537
+ field: "model_name",
3538
+ flex: 2,
3539
+ minWidth: 130,
3540
+ tooltipField: "model_name"
3541
+ },
3542
+ {
3543
+ colId: "provider",
3544
+ headerName: "Provider",
3545
+ field: "provider",
3546
+ flex: 1,
3547
+ minWidth: 120,
3548
+ cellRenderer: (params) => isStandard(params.data) ? /* @__PURE__ */ jsx(
3549
+ ModelProviderLabel,
3550
+ {
3551
+ logo: /* @__PURE__ */ jsx("img", { src: "/favicon.svg", alt: "ARBI", className: "size-3.5 flex-shrink-0 rounded-sm" }),
3552
+ children: "ARBI CITY"
3553
+ }
3554
+ ) : /* @__PURE__ */ jsx(
3555
+ ModelProviderLabel,
3556
+ {
3557
+ logo: /* @__PURE__ */ jsx(ProviderIcon, { modelName: params.data?.model_name, provider: params.value, size: 14 }),
3558
+ children: PROVIDER_NAMES[params.value ?? ""] || params.value || "\u2014"
3559
+ }
3560
+ )
3561
+ },
3562
+ {
3563
+ // Input and output cost in one column so the table fits the panel; sorted by output cost.
3564
+ colId: "cost",
3565
+ headerName: "Cost / MTok",
3566
+ headerComponentParams: { innerHeaderComponent: PremiumCostHeader },
3567
+ headerTooltip: "\xA3 per million tokens \u2014 input then output",
3568
+ field: "output_cost_per_token",
3569
+ flex: 1,
3570
+ minWidth: 120,
3571
+ type: "rightAligned",
3572
+ cellRenderer: (params) => /* @__PURE__ */ jsxs("span", { className: "tabular-nums", children: [
3573
+ formatGbpPerMillionTokens(params.data?.input_cost_per_token) ?? "\xA30",
3574
+ "-",
3575
+ formatGbpPerMillionTokens(params.data?.output_cost_per_token) ?? "\xA30"
3576
+ ] })
3577
+ }
3578
+ ];
3579
+ function ConnectedPremiumModels() {
3580
+ const { notify } = useBlocksEnvironment();
3581
+ const { data: settings } = useUserSettings();
3582
+ const update = useUpdateUserSettings();
3583
+ const { data: available } = useAvailableModels();
3584
+ const isDeveloper = settings?.developer === true;
3585
+ const premiumModel = settings?.premium_model;
3586
+ const premiumModels = useMemo(
3587
+ () => (available?.models ?? []).filter(
3588
+ (m) => m.tags?.includes("Premium") && (isDeveloper || !m.model_name.includes("@"))
3589
+ ),
3590
+ [available, isDeveloper]
3591
+ );
3592
+ const rows = useMemo(() => {
3593
+ const standards = (available?.models ?? []).filter(isStandard);
3594
+ if (standards.length === 0) return premiumModels;
3595
+ const reference = {
3596
+ ...standards[0],
3597
+ model_name: `Standard (${standards.map((m) => m.model_name).join(", ")})`
3598
+ };
3599
+ return [reference, ...premiumModels];
3600
+ }, [available, premiumModels]);
3601
+ const current = premiumModel ?? available?.premium_default ?? "";
3602
+ const save = useCallback(
3603
+ (model) => update.mutate(
3604
+ { premium_model: model },
3605
+ {
3606
+ onError: (err) => notify(`Failed to update Premium setting: ${String(err)}`, "error")
3607
+ }
3608
+ ),
3609
+ [update, notify]
3610
+ );
3611
+ const currentRef = useRef(current);
3612
+ currentRef.current = current;
3613
+ const [selected, setSelected] = useState([]);
3614
+ useEffect(() => {
3615
+ const match = premiumModels.filter((m) => m.model_name === current);
3616
+ setSelected(
3617
+ (prev) => prev.length === match.length && prev[0]?.model_name === match[0]?.model_name ? prev : match
3618
+ );
3619
+ }, [current, premiumModels]);
3620
+ const onSelectionChange = useCallback(
3621
+ (items) => {
3622
+ const picked = items.filter((m) => !isStandard(m));
3623
+ const next = picked[0]?.model_name;
3624
+ if (!next || next === currentRef.current) return;
3625
+ setSelected(picked);
3626
+ save(next);
3627
+ },
3628
+ [save]
3629
+ );
3630
+ if (premiumModels.length === 0) return null;
3631
+ return /* @__PURE__ */ jsx(SettingsPanel, { className: "max-w-2xl space-y-4", children: /* @__PURE__ */ jsx(SettingsSection, { title: "Premium models", children: /* @__PURE__ */ jsx(SettingsCard, { className: "space-y-0", children: /* @__PURE__ */ jsx(
3632
+ PremiumModelsFrame,
3633
+ {
3634
+ enabled: premiumModel !== "",
3635
+ onEnabledChange: (enabled) => {
3636
+ const target = enabled ? cheapest(premiumModels)?.model_name : "";
3637
+ if (target !== void 0) save(target);
3638
+ },
3639
+ children: /* @__PURE__ */ jsx(
3640
+ GridView,
3641
+ {
3642
+ items: rows,
3643
+ columnDefs: COLUMNS,
3644
+ getItemId: (m) => m.model_name,
3645
+ selection: { mode: "single", selected, onSelectionChange },
3646
+ gridOptions: {
3647
+ rowClassRules: { "opacity-60 italic": (p) => isStandard(p.data) }
3648
+ },
3649
+ height: Math.min(rows.length * 40 + 48, 320),
3650
+ testId: "premium-model-grid"
3651
+ }
3652
+ )
3653
+ }
3654
+ ) }) }) });
3655
+ }
3656
+ var SETTINGS_SECTION_IDS = {
3657
+ account: "account",
3658
+ mail: "mail",
3659
+ privacy: "privacy",
3660
+ chat: "chat"
3661
+ };
3662
+ function accountSettingsSection(props) {
3663
+ return {
3664
+ id: SETTINGS_SECTION_IDS.account,
3665
+ label: "Account",
3666
+ icon: /* @__PURE__ */ jsx(User, { className: "w-6 h-6" }),
3667
+ render: () => /* @__PURE__ */ jsx(ConnectedAccountSettings, { ...props })
3668
+ };
3669
+ }
3670
+ function mailSettingsSection(props) {
3671
+ return {
3672
+ id: SETTINGS_SECTION_IDS.mail,
3673
+ label: "Mail",
3674
+ icon: /* @__PURE__ */ jsx(Mail, { className: "w-6 h-6" }),
3675
+ render: () => /* @__PURE__ */ jsx(ConnectedMailSettings, { ...props })
3676
+ };
3677
+ }
3678
+ function privacySettingsSection(props) {
3679
+ return {
3680
+ id: SETTINGS_SECTION_IDS.privacy,
3681
+ label: "Privacy",
3682
+ icon: /* @__PURE__ */ jsx(HatGlasses, { className: "w-6 h-6" }),
3683
+ render: () => /* @__PURE__ */ jsx(ConnectedPrivacySettings, { ...props })
3684
+ };
3685
+ }
3686
+ function chatSettingsSection() {
3687
+ return {
3688
+ id: SETTINGS_SECTION_IDS.chat,
3689
+ label: "Chat",
3690
+ icon: /* @__PURE__ */ jsx(MessageSquare, { className: "w-6 h-6" }),
3691
+ render: () => /* @__PURE__ */ jsx(ConnectedPremiumModels, {})
3692
+ };
3693
+ }
3694
+ var DEFAULT_SETTINGS_SECTIONS = [
3695
+ accountSettingsSection(),
3696
+ privacySettingsSection(),
3697
+ chatSettingsSection()
3698
+ ];
3699
+ function ConnectedSettingsPage({
3700
+ sections = DEFAULT_SETTINGS_SECTIONS,
3701
+ section,
3702
+ onSectionChange,
3703
+ ...page
3704
+ }) {
3705
+ const requested = useRequestedSettingsSection();
3706
+ const [local, setLocal] = useState(requested?.section);
3707
+ useEffect(() => {
3708
+ if (requested) setLocal(requested.section);
3709
+ }, [requested]);
3710
+ const controlled = section !== void 0;
3711
+ return /* @__PURE__ */ jsx(
3712
+ SettingsPage,
3713
+ {
3714
+ ...page,
3715
+ sections,
3716
+ activeSectionId: controlled ? section : local,
3717
+ onSectionChange: (id) => {
3718
+ if (!controlled) setLocal(id);
3719
+ onSectionChange?.(id);
3720
+ }
3721
+ }
3722
+ );
3723
+ }
3724
+ function useConnectedDocxNotifications(onOpen) {
3725
+ const arbi = useArbi();
3726
+ const { status, user, apiUrl } = useConnection();
3727
+ const { notify } = useBlocksEnvironment();
3728
+ const queries = useQueryClient();
3729
+ const source = `docx-mentions:${apiUrl}:${user?.externalId || ""}`;
3730
+ const queryKey = ["docx-mentions", apiUrl, user?.externalId];
3731
+ const { data = [] } = useQuery({
3732
+ queryKey,
3733
+ queryFn: () => arbi.notifications.list({ type: "docx_mention" }),
3734
+ enabled: status === "authenticated",
3735
+ refetchInterval: 3e4
3736
+ });
3737
+ useArbiWebSocket((message) => {
3738
+ if (message.type === "docx_mention") void queries.invalidateQueries({ queryKey });
3739
+ });
3740
+ useEffect(() => {
3741
+ const items = [];
3742
+ if (status === "authenticated")
3743
+ for (const note of data) {
3744
+ if (note.recipient.external_id !== user?.externalId || !note.workspace_ext_id) continue;
3745
+ try {
3746
+ const target = JSON.parse(note.content || "{}");
3747
+ if (!target.document_id?.startsWith("doc-") || !target.comment_id) continue;
3748
+ const documentId = target.document_id, commentId = target.comment_id, workspaceId = note.workspace_ext_id;
3749
+ items.push({
3750
+ id: `docx:${note.external_id}`,
3751
+ title: "Mentioned you in a document comment",
3752
+ description: [note.sender.given_name, note.sender.family_name].filter(Boolean).join(" "),
3753
+ variant: "info",
3754
+ ts: Date.parse(note.created_at),
3755
+ read: note.read,
3756
+ source,
3757
+ onSelect: () => {
3758
+ void Promise.resolve(onOpen({ documentId, commentId, workspaceId })).catch(
3759
+ (error) => notify(
3760
+ error instanceof Error ? error.message : "Could not open the document.",
3761
+ "error"
3762
+ )
3763
+ );
3764
+ }
3765
+ });
3766
+ } catch {
3767
+ }
3768
+ }
3769
+ useNotify.getState().syncSource(source, items);
3770
+ return () => useNotify.getState().syncSource(source, []);
3771
+ }, [data, status, user?.externalId, source, onOpen, notify]);
3772
+ const markRead = async (ids) => {
3773
+ try {
3774
+ await arbi.notifications.markRead(ids);
3775
+ await queries.invalidateQueries({ queryKey });
3776
+ } catch {
3777
+ notify("Could not mark document mentions read.", "error");
3778
+ }
3779
+ };
3780
+ return {
3781
+ onMarkRead: (id) => {
3782
+ if (id.startsWith("docx:")) void markRead([id.slice(5)]);
3783
+ },
3784
+ onMarkAllRead: () => {
3785
+ void markRead(
3786
+ data.filter((note) => !note.read && note.recipient.external_id === user?.externalId).map((note) => note.external_id)
3787
+ );
3788
+ }
3789
+ };
3790
+ }
3791
+ function useConnectedWorkNotifications(onOpen) {
3792
+ const { status, user, apiUrl } = useConnection();
3793
+ const { notify } = useBlocksEnvironment();
3794
+ const source = `work-notifications:${apiUrl}:${user?.externalId || ""}`;
3795
+ const { data = [], markRead: persistRead } = useWorkNotifications({
3796
+ apiUrl,
3797
+ userId: user?.externalId,
3798
+ enabled: status === "authenticated"
3799
+ });
3800
+ useEffect(() => {
3801
+ const items = [];
3802
+ if (status === "authenticated")
3803
+ for (const note of data) {
3804
+ if (note.recipient.external_id !== user?.externalId) continue;
3805
+ const mapped = mapWorkNotification(note);
3806
+ if (!mapped) continue;
3807
+ items.push({
3808
+ id: `work:${note.external_id}`,
3809
+ title: mapped.title,
3810
+ variant: note.type === "workflow_failed" ? "error" : note.type === "conversation_done" ? "success" : "info",
3811
+ ts: Date.parse(note.created_at),
3812
+ read: note.read,
3813
+ source,
3814
+ onSelect: () => {
3815
+ void Promise.resolve().then(() => onOpen(mapped.target)).catch(
3816
+ (error) => notify(
3817
+ error instanceof Error ? error.message : "Could not open this notification.",
3818
+ "error"
3819
+ )
3820
+ );
3821
+ }
3822
+ });
3823
+ }
3824
+ useNotify.getState().syncSource(source, items);
3825
+ return () => useNotify.getState().syncSource(source, []);
3826
+ }, [data, status, user?.externalId, source, onOpen, notify]);
3827
+ const markRead = async (ids) => {
3828
+ if (!ids.length) return;
3829
+ try {
3830
+ await persistRead(ids);
3831
+ } catch {
3832
+ notify("Could not mark work notifications read.", "error");
3833
+ }
3834
+ };
3835
+ return {
3836
+ onMarkRead: (id) => {
3837
+ if (data.some(
3838
+ (note) => `work:${note.external_id}` === id && note.recipient.external_id === user?.externalId && mapWorkNotification(note)
3839
+ ))
3840
+ void markRead([id.slice(5)]);
3841
+ },
3842
+ onMarkAllRead: () => {
3843
+ void markRead(
3844
+ data.filter(
3845
+ (note) => !note.read && note.recipient.external_id === user?.externalId && mapWorkNotification(note)
3846
+ ).map((note) => note.external_id)
3847
+ );
3848
+ }
3849
+ };
3850
+ }
3851
+ function mapWorkNotification(note) {
3852
+ const sender = [note.sender.given_name, note.sender.family_name].filter(Boolean).join(" ") || note.sender.email;
3853
+ if (note.type === "workflow_failed") {
3854
+ try {
3855
+ const payload = JSON.parse(note.content || "{}");
3856
+ if (!payload.workflow_ext_id?.match(/^wfl-[a-zA-Z0-9]+$/)) return null;
3857
+ if (note.workspace_ext_id?.match(/^wrk-[a-zA-Z0-9]+$/) && note.conversation_ext_id?.match(/^con-[a-zA-Z0-9]+$/)) {
3858
+ return {
3859
+ title: "A workflow failed to run",
3860
+ target: {
3861
+ kind: "conversation",
3862
+ workspaceId: note.workspace_ext_id,
3863
+ conversationId: note.conversation_ext_id
3864
+ }
3865
+ };
3866
+ }
3867
+ return {
3868
+ title: "A workflow failed to run",
3869
+ target: {
3870
+ kind: "workflow",
3871
+ workflowId: payload.workflow_ext_id,
3872
+ workspaceId: note.workspace_ext_id || void 0
3873
+ }
3874
+ };
3875
+ } catch {
3876
+ return null;
3877
+ }
3878
+ }
3879
+ if (note.type === "mail_draft_ready") {
3880
+ const draftId = mailDraftIdFromContent(note.content);
3881
+ if (!draftId) return null;
3882
+ return {
3883
+ title: `${sender} left a draft email for you to review`,
3884
+ target: { kind: "mail_draft", draftId, mailbox: "native" }
3885
+ };
3886
+ }
3887
+ const titles = {
3888
+ mention: `${sender} mentioned you in a conversation`,
3889
+ workspace_access_request: `${sender} needs workspace access to run a thread`,
3890
+ conversation_ready: note.sender.external_id === note.recipient.external_id ? "Your thread is ready" : `${sender}\u2019s thread is ready`,
3891
+ conversation_done: `${sender} marked a thread done`
3892
+ };
3893
+ const title = titles[note.type];
3894
+ if (!title || !note.workspace_ext_id || !note.conversation_ext_id?.match(/^con-[a-zA-Z0-9]+$/))
3895
+ return null;
3896
+ return {
3897
+ title,
3898
+ target: {
3899
+ kind: "conversation",
3900
+ workspaceId: note.workspace_ext_id,
3901
+ conversationId: note.conversation_ext_id,
3902
+ ...note.message_ext_id ? { messageId: note.message_ext_id } : {}
3903
+ }
3904
+ };
3905
+ }
3906
+ function attachmentPath(accountId, messageId, attachmentId) {
3907
+ return `${accountPath(accountId)}/messages/${encodeURIComponent(messageId)}/attachments/${encodeURIComponent(attachmentId)}`;
3908
+ }
3909
+ function saveFile(blob, name) {
3910
+ const url = URL.createObjectURL(blob);
3911
+ const link = document.createElement("a");
3912
+ link.href = url;
3913
+ link.download = name;
3914
+ link.click();
3915
+ setTimeout(() => URL.revokeObjectURL(url), 1e3);
3916
+ }
3917
+ function hydrateMailAttachments(client, account, messageId, attachments, { isOnline, offline }) {
3918
+ return Promise.all(
3919
+ attachments.map(async (a) => {
3920
+ if (a.content_base64 != null) return a;
3921
+ if (!isOnline) {
3922
+ const file = await offline?.loadAttachment(account.id, messageId, a);
3923
+ return file ? { ...a, content_base64: bytesToBase64(new Uint8Array(await file.arrayBuffer())) } : { ...a, content_base64: null };
3924
+ }
3925
+ const response = await client.fetch(attachmentPath(account.id, messageId, a.id));
3926
+ return fileAttachment(new File([await response.blob()], a.name, { type: a.content_type }));
3927
+ })
3928
+ );
3929
+ }
3801
3930
  var sessionRooms = /* @__PURE__ */ new Map();
3802
3931
  function useWordBody({
3803
3932
  word,
@@ -9138,6 +9267,6 @@ function ConnectedAgentChatPanel({
9138
9267
  ] });
9139
9268
  }
9140
9269
 
9141
- export { ArbiAppProvider, ConnectedAgentChatPanel, ConnectedAgentCreator, ConnectedCalendar, ConnectedDangerZone, ConnectedIdentityVerification, ConnectedLogoutDialog, ConnectedMailAccounts, ConnectedMailComposer, ConnectedMailInviteCard, ConnectedMailMessage, ConnectedMailSetup, ConnectedMailbox, ConnectedNotificationCenter, ConnectedNotificationPreferences, ConnectedPasswordChangeDialog, ConnectedProfileCard, ConnectedPublicBooking, ConnectedRequireVerified, ConnectedSecuritySection, ConnectedSessionsRow, ConnectedSkillUpload, ConnectedSkillsLibrary, ConnectedTagTable, ConnectedTaskAccessRequest, ConnectedTaskActivityDialog, ConnectedThreadFollow, ConnectedUpcomingEvents, ConnectedWorkflowDocumentsField, ConnectedWorkflowHistory, ConnectedWorkflowLauncher, ConnectedWorkflowRunner, ConnectedWorkflowsTable, ConnectedWorkspaceActivity, ConnectedWorkspaceNotificationMenu, DEFAULT_CONNECTED_SKILL_UPLOAD_LABELS, DEFAULT_CONNECTED_WORKFLOWS_TABLE_LABELS, DEFAULT_CONNECTED_WORKFLOW_RUNNER_LABELS, NotificationCenter, NotificationEvent, StreamedArtifact, WorkflowRunThread, bookingCancelLink, buildNotificationCenterItems, countNotificationTypes, defaultUnmetPasswordRequirement, filterNotificationCenterItems, openMeetingLink, requestCalendarComposer, requestCalendarEvent, resolveMailbox, toWorkflowFieldDocument, useCalendarViewStore, useConnectedAgentOptions, useConnectedDocxNotifications, useConnectedShellWorkspaces, useConnectedWorkNotifications, useConnectedWorkflowScopeSource, useConnectedWorkspaceRole, workflowRunView };
9270
+ export { ArbiAppProvider, ConnectedAccountSettings, ConnectedAgentChatPanel, ConnectedAgentCreator, ConnectedCalendar, ConnectedDangerZone, ConnectedIdentityVerification, ConnectedLogoutDialog, ConnectedMailAccounts, ConnectedMailComposer, ConnectedMailInviteCard, ConnectedMailMessage, ConnectedMailSettings, ConnectedMailSetup, ConnectedMailbox, ConnectedNotificationCenter, ConnectedNotificationPreferences, ConnectedPasswordChangeDialog, ConnectedPremiumModels, ConnectedPrivacySettings, ConnectedProfileCard, ConnectedPublicBooking, ConnectedRequireVerified, ConnectedSecuritySection, ConnectedSessionsRow, ConnectedSettingsPage, ConnectedSkillUpload, ConnectedSkillsLibrary, ConnectedTagTable, ConnectedTaskAccessRequest, ConnectedTaskActivityDialog, ConnectedThreadFollow, ConnectedUpcomingEvents, ConnectedWorkflowHistory, ConnectedWorkflowRunner, ConnectedWorkspaceActivity, ConnectedWorkspaceNotificationMenu, DEFAULT_CONNECTED_SKILL_UPLOAD_LABELS, DEFAULT_CONNECTED_WORKFLOW_RUNNER_LABELS, DEFAULT_SETTINGS_SECTIONS, NotificationCenter, NotificationEvent, SETTINGS_SECTION_IDS, SessionStatusIcon, StreamedArtifact, WorkflowRunThread, accountSettingsSection, bookingCancelLink, buildNotificationCenterItems, chatSettingsSection, countNotificationTypes, defaultUnmetPasswordRequirement, filterNotificationCenterItems, mailSettingsSection, openMeetingLink, privacySettingsSection, renderSessionStatusIcon, requestCalendarComposer, requestCalendarEvent, resolveMailbox, useCalendarViewStore, useConnectedDocxNotifications, useConnectedShellWorkspaces, useConnectedWorkNotifications, workflowRunView };
9142
9271
  //# sourceMappingURL=index.js.map
9143
9272
  //# sourceMappingURL=index.js.map