@arbidocs/blocks 0.4.141 → 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 (222) hide show
  1. package/dist/agents/index.cjs +440 -436
  2. package/dist/agents/index.js +12 -8
  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-AHDJXIUB.cjs +25 -0
  14. package/dist/chunk-AHDJXIUB.cjs.map +1 -0
  15. package/dist/chunk-AOSUHWIL.js +98 -0
  16. package/dist/chunk-AOSUHWIL.js.map +1 -0
  17. package/dist/{chunk-YFF3GTJQ.js → chunk-C44TDH54.js} +14 -1613
  18. package/dist/chunk-C44TDH54.js.map +1 -0
  19. package/dist/{chunk-GFRQG36Y.cjs → chunk-COCGRJLA.cjs} +213 -57
  20. package/dist/chunk-COCGRJLA.cjs.map +1 -0
  21. package/dist/chunk-CQCC7LE7.js +210 -0
  22. package/dist/chunk-CQCC7LE7.js.map +1 -0
  23. package/dist/{chunk-UGCKUXRV.js → chunk-CSI2B2H5.js} +3 -3
  24. package/dist/{chunk-UGCKUXRV.js.map → chunk-CSI2B2H5.js.map} +1 -1
  25. package/dist/{chunk-R26BK7YL.cjs → chunk-DTROMMDX.cjs} +4 -4
  26. package/dist/{chunk-R26BK7YL.cjs.map → chunk-DTROMMDX.cjs.map} +1 -1
  27. package/dist/{chunk-65THHQVB.cjs → chunk-ECW2R2KF.cjs} +27 -27
  28. package/dist/{chunk-65THHQVB.cjs.map → chunk-ECW2R2KF.cjs.map} +1 -1
  29. package/dist/{chunk-RI6DZA5X.js → chunk-EF4ZLKRM.js} +3 -3
  30. package/dist/{chunk-RI6DZA5X.js.map → chunk-EF4ZLKRM.js.map} +1 -1
  31. package/dist/{chunk-WS5EX7DN.cjs → chunk-EYKISBDO.cjs} +5 -5
  32. package/dist/{chunk-WS5EX7DN.cjs.map → chunk-EYKISBDO.cjs.map} +1 -1
  33. package/dist/chunk-FJETR2AS.js +561 -0
  34. package/dist/chunk-FJETR2AS.js.map +1 -0
  35. package/dist/{chunk-JO3EMZ4X.js → chunk-GWSGIZQ5.js} +3 -3
  36. package/dist/{chunk-JO3EMZ4X.js.map → chunk-GWSGIZQ5.js.map} +1 -1
  37. package/dist/{chunk-O6W6RW3B.js → chunk-H4D7WKDY.js} +207 -54
  38. package/dist/chunk-H4D7WKDY.js.map +1 -0
  39. package/dist/{chunk-OAQEUTNJ.cjs → chunk-HAOKT4LC.cjs} +5 -5
  40. package/dist/{chunk-OAQEUTNJ.cjs.map → chunk-HAOKT4LC.cjs.map} +1 -1
  41. package/dist/{chunk-YWY2KIX2.js → chunk-IJST4EBM.js} +13 -9
  42. package/dist/chunk-IJST4EBM.js.map +1 -0
  43. package/dist/{chunk-3RJN2VTL.js → chunk-IXWJGOM2.js} +3 -3
  44. package/dist/{chunk-3RJN2VTL.js.map → chunk-IXWJGOM2.js.map} +1 -1
  45. package/dist/{chunk-CYNF5PZI.js → chunk-J5CWKFSC.js} +3 -3
  46. package/dist/{chunk-CYNF5PZI.js.map → chunk-J5CWKFSC.js.map} +1 -1
  47. package/dist/{chunk-OWCEQKAR.cjs → chunk-JSTKEZBS.cjs} +21 -318
  48. package/dist/chunk-JSTKEZBS.cjs.map +1 -0
  49. package/dist/{chunk-TP6PLDNM.cjs → chunk-KMZWKSKO.cjs} +8 -8
  50. package/dist/{chunk-TP6PLDNM.cjs.map → chunk-KMZWKSKO.cjs.map} +1 -1
  51. package/dist/{chunk-C4WSHRR6.cjs → chunk-KPZZ5FHE.cjs} +32 -12
  52. package/dist/chunk-KPZZ5FHE.cjs.map +1 -0
  53. package/dist/{chunk-CKCBBYTA.js → chunk-KSHKTOY2.js} +5 -205
  54. package/dist/chunk-KSHKTOY2.js.map +1 -0
  55. package/dist/chunk-LJJJ6CYH.cjs +62 -0
  56. package/dist/chunk-LJJJ6CYH.cjs.map +1 -0
  57. package/dist/chunk-LPYEUD2D.cjs +1627 -0
  58. package/dist/chunk-LPYEUD2D.cjs.map +1 -0
  59. package/dist/chunk-MHFF5N65.cjs +101 -0
  60. package/dist/chunk-MHFF5N65.cjs.map +1 -0
  61. package/dist/{chunk-GYAUJ4KT.js → chunk-MTSKK3BN.js} +32 -3
  62. package/dist/chunk-MTSKK3BN.js.map +1 -0
  63. package/dist/chunk-NHZK64TQ.js +75 -0
  64. package/dist/chunk-NHZK64TQ.js.map +1 -0
  65. package/dist/{chunk-BPBSSMRB.js → chunk-NRFAWUVD.js} +3 -3
  66. package/dist/{chunk-BPBSSMRB.js.map → chunk-NRFAWUVD.js.map} +1 -1
  67. package/dist/chunk-NWNVWO6L.cjs +80 -0
  68. package/dist/chunk-NWNVWO6L.cjs.map +1 -0
  69. package/dist/{chunk-CQ4MFKFC.cjs → chunk-O2GW5IY6.cjs} +90 -86
  70. package/dist/chunk-O2GW5IY6.cjs.map +1 -0
  71. package/dist/{chunk-3BFGL2JL.cjs → chunk-ODRHHWHY.cjs} +4 -4
  72. package/dist/{chunk-3BFGL2JL.cjs.map → chunk-ODRHHWHY.cjs.map} +1 -1
  73. package/dist/{chunk-Y3KA6X7B.js → chunk-OVR3XMYL.js} +4 -4
  74. package/dist/{chunk-Y3KA6X7B.js.map → chunk-OVR3XMYL.js.map} +1 -1
  75. package/dist/{chunk-Y5KTM3V5.js → chunk-PDKM27DF.js} +17 -295
  76. package/dist/chunk-PDKM27DF.js.map +1 -0
  77. package/dist/{chunk-OAL3B2ZU.cjs → chunk-PLJ7PHWU.cjs} +5 -5
  78. package/dist/{chunk-OAL3B2ZU.cjs.map → chunk-PLJ7PHWU.cjs.map} +1 -1
  79. package/dist/{chunk-2UUNSHDI.cjs → chunk-RB7GX2VT.cjs} +59 -1682
  80. package/dist/chunk-RB7GX2VT.cjs.map +1 -0
  81. package/dist/chunk-RFIBUWLF.cjs +232 -0
  82. package/dist/chunk-RFIBUWLF.cjs.map +1 -0
  83. package/dist/chunk-RLWIUUQ5.js +23 -0
  84. package/dist/chunk-RLWIUUQ5.js.map +1 -0
  85. package/dist/{chunk-MIDXCYZB.cjs → chunk-RQ2Y7USX.cjs} +15 -235
  86. package/dist/chunk-RQ2Y7USX.cjs.map +1 -0
  87. package/dist/chunk-SV65E4QW.js +58 -0
  88. package/dist/chunk-SV65E4QW.js.map +1 -0
  89. package/dist/{chunk-LYUO3E6V.js → chunk-SZOFGU7W.js} +3 -3
  90. package/dist/{chunk-LYUO3E6V.js.map → chunk-SZOFGU7W.js.map} +1 -1
  91. package/dist/chunk-T5B7FM7S.js +1602 -0
  92. package/dist/chunk-T5B7FM7S.js.map +1 -0
  93. package/dist/{chunk-YNIBUKV5.js → chunk-TBEVGWY3.js} +32 -14
  94. package/dist/chunk-TBEVGWY3.js.map +1 -0
  95. package/dist/{chunk-MJCCBMM5.cjs → chunk-TC3RQNEX.cjs} +6 -80
  96. package/dist/chunk-TC3RQNEX.cjs.map +1 -0
  97. package/dist/chunk-TZGBRLPK.js +288 -0
  98. package/dist/chunk-TZGBRLPK.js.map +1 -0
  99. package/dist/chunk-U6YVZDOV.cjs +574 -0
  100. package/dist/chunk-U6YVZDOV.cjs.map +1 -0
  101. package/dist/{chunk-QIMVTGKS.cjs → chunk-U73KPFYH.cjs} +255 -2
  102. package/dist/chunk-U73KPFYH.cjs.map +1 -0
  103. package/dist/{chunk-HFGXA5CL.cjs → chunk-UTTTJSQU.cjs} +4 -4
  104. package/dist/{chunk-HFGXA5CL.cjs.map → chunk-UTTTJSQU.cjs.map} +1 -1
  105. package/dist/{chunk-DLBUFHLY.js → chunk-VTTZZ4FN.js} +4 -74
  106. package/dist/chunk-VTTZZ4FN.js.map +1 -0
  107. package/dist/{chunk-5FTIHRZH.cjs → chunk-XVUOMWMD.cjs} +4 -4
  108. package/dist/{chunk-5FTIHRZH.cjs.map → chunk-XVUOMWMD.cjs.map} +1 -1
  109. package/dist/{chunk-3ZYOASAX.js → chunk-Y4ATWQGV.js} +3 -3
  110. package/dist/{chunk-3ZYOASAX.js.map → chunk-Y4ATWQGV.js.map} +1 -1
  111. package/dist/{chunk-444XKG46.js → chunk-YKQ2DPIP.js} +3 -3
  112. package/dist/{chunk-444XKG46.js.map → chunk-YKQ2DPIP.js.map} +1 -1
  113. package/dist/{chunk-HEMU73OP.cjs → chunk-YSHIC4NJ.cjs} +4 -4
  114. package/dist/{chunk-HEMU73OP.cjs.map → chunk-YSHIC4NJ.cjs.map} +1 -1
  115. package/dist/{chunk-5BXEYYH6.js → chunk-ZM26YEOT.js} +3 -3
  116. package/dist/{chunk-5BXEYYH6.js.map → chunk-ZM26YEOT.js.map} +1 -1
  117. package/dist/citations/index.cjs +12 -12
  118. package/dist/citations/index.js +3 -3
  119. package/dist/connect/docx.cjs +36 -7
  120. package/dist/connect/docx.cjs.map +1 -1
  121. package/dist/connect/docx.d.ts +9 -2
  122. package/dist/connect/docx.js +30 -6
  123. package/dist/connect/docx.js.map +1 -1
  124. package/dist/connect/index.cjs +805 -630
  125. package/dist/connect/index.cjs.map +1 -1
  126. package/dist/connect/index.d.ts +2 -0
  127. package/dist/connect/index.js +639 -509
  128. package/dist/connect/index.js.map +1 -1
  129. package/dist/connection/ConnectedSettings.d.ts +3 -2
  130. package/dist/connection/docx/ConnectedNativeDocxComparison.d.ts +5 -0
  131. package/dist/connection/docx/ConnectedNativeDocxEditor.d.ts +16 -0
  132. package/dist/connection/{ConnectedStreamedWordArtifact.d.ts → docx/ConnectedStreamedWordArtifact.d.ts} +1 -1
  133. package/dist/connection/docx/support.d.ts +27 -0
  134. package/dist/connection/docx/useConnectedDocxReferences.d.ts +2 -0
  135. package/dist/connection/docx/useConnectedHouseTemplate.d.ts +2 -0
  136. package/dist/connection/settings-page/ConnectedAccountSettings.d.ts +35 -0
  137. package/dist/connection/settings-page/ConnectedMailSettings.d.ts +13 -0
  138. package/dist/connection/settings-page/ConnectedPremiumModels.d.ts +1 -0
  139. package/dist/connection/settings-page/ConnectedPrivacySettings.d.ts +12 -0
  140. package/dist/connection/settings-page/ConnectedSettingsPage.d.ts +29 -0
  141. package/dist/connection/settings-page/SessionStatusIcon.d.ts +7 -0
  142. package/dist/connection/settings-page/index.d.ts +6 -0
  143. package/dist/docx/index.cjs +17 -63
  144. package/dist/docx/index.cjs.map +1 -1
  145. package/dist/docx/index.d.ts +1 -0
  146. package/dist/docx/index.js +2 -64
  147. package/dist/docx/index.js.map +1 -1
  148. package/dist/docx/template/candidates.d.ts +16 -0
  149. package/dist/facts/index.cjs +4 -4
  150. package/dist/facts/index.js +3 -3
  151. package/dist/files/index.cjs +3 -3
  152. package/dist/files/index.js +2 -2
  153. package/dist/home/index.cjs +20 -20
  154. package/dist/home/index.js +4 -4
  155. package/dist/index.cjs +793 -755
  156. package/dist/index.cjs.map +1 -1
  157. package/dist/index.d.ts +2 -0
  158. package/dist/index.js +25 -19
  159. package/dist/index.js.map +1 -1
  160. package/dist/lib/deep-link.d.ts +46 -0
  161. package/dist/lib/sidebar-mode.d.ts +1 -3
  162. package/dist/lib/use-close-on-escape.d.ts +6 -0
  163. package/dist/provider/BlocksProvider.d.ts +5 -1
  164. package/dist/provider/settings-section.d.ts +9 -0
  165. package/dist/retrieval/index.cjs +4 -4
  166. package/dist/retrieval/index.js +2 -2
  167. package/dist/settings/AppearanceSettings.d.ts +18 -0
  168. package/dist/settings/ServerConnectionControls.d.ts +16 -0
  169. package/dist/settings/SettingsPage.d.ts +31 -0
  170. package/dist/settings/index.cjs +189 -251
  171. package/dist/settings/index.cjs.map +1 -1
  172. package/dist/settings/index.d.ts +3 -1
  173. package/dist/settings/index.js +89 -200
  174. package/dist/settings/index.js.map +1 -1
  175. package/dist/shell/ShellSidebar.d.ts +37 -0
  176. package/dist/shell/Sidebar.d.ts +6 -6
  177. package/dist/shell/index.cjs +63 -50
  178. package/dist/shell/index.d.ts +4 -1
  179. package/dist/shell/index.js +5 -4
  180. package/dist/shell/types.d.ts +18 -0
  181. package/dist/shell/use-sidebar-controller.d.ts +59 -0
  182. package/dist/site/index.cjs +74 -73
  183. package/dist/site/index.js +3 -2
  184. package/dist/studio/index.cjs +80 -78
  185. package/dist/studio/index.cjs.map +1 -1
  186. package/dist/studio/index.js +10 -8
  187. package/dist/studio/index.js.map +1 -1
  188. package/dist/workflow-canvas/index.cjs +64 -60
  189. package/dist/workflow-canvas/index.cjs.map +1 -1
  190. package/dist/workflow-canvas/index.js +12 -8
  191. package/dist/workflow-canvas/index.js.map +1 -1
  192. package/dist/workspaces/index.cjs +3 -3
  193. package/dist/workspaces/index.js +2 -2
  194. package/node_modules/@arbidocs/coedit/package.json +1 -1
  195. package/package.json +4 -4
  196. package/dist/chunk-2UUNSHDI.cjs.map +0 -1
  197. package/dist/chunk-4TR5QCCX.cjs +0 -43
  198. package/dist/chunk-4TR5QCCX.cjs.map +0 -1
  199. package/dist/chunk-7NDW4KF4.cjs +0 -112
  200. package/dist/chunk-7NDW4KF4.cjs.map +0 -1
  201. package/dist/chunk-C4WSHRR6.cjs.map +0 -1
  202. package/dist/chunk-CKCBBYTA.js.map +0 -1
  203. package/dist/chunk-CQ4MFKFC.cjs.map +0 -1
  204. package/dist/chunk-DLBUFHLY.js.map +0 -1
  205. package/dist/chunk-ETXYVO6E.js +0 -109
  206. package/dist/chunk-ETXYVO6E.js.map +0 -1
  207. package/dist/chunk-GFRQG36Y.cjs.map +0 -1
  208. package/dist/chunk-GYAUJ4KT.js.map +0 -1
  209. package/dist/chunk-MCKOZACC.js +0 -41
  210. package/dist/chunk-MCKOZACC.js.map +0 -1
  211. package/dist/chunk-MIDXCYZB.cjs.map +0 -1
  212. package/dist/chunk-MJCCBMM5.cjs.map +0 -1
  213. package/dist/chunk-O6W6RW3B.js.map +0 -1
  214. package/dist/chunk-ON3TKY5Y.js.map +0 -1
  215. package/dist/chunk-OWCEQKAR.cjs.map +0 -1
  216. package/dist/chunk-QIMVTGKS.cjs.map +0 -1
  217. package/dist/chunk-S24XEVPS.cjs.map +0 -1
  218. package/dist/chunk-Y5KTM3V5.js.map +0 -1
  219. package/dist/chunk-YFF3GTJQ.js.map +0 -1
  220. package/dist/chunk-YNIBUKV5.js.map +0 -1
  221. package/dist/chunk-YWY2KIX2.js.map +0 -1
  222. package/dist/connection/ConnectedNativeDocxEditor.d.ts +0 -6
@@ -1,27 +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-3ZYOASAX.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-YFF3GTJQ.js';
20
- import '../chunk-3RJN2VTL.js';
21
- import { TriStateFilterMenu, MultiSelect } from '../chunk-CKCBBYTA.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';
24
+ import '../chunk-RLWIUUQ5.js';
25
+ import { TriStateFilterMenu } from '../chunk-KSHKTOY2.js';
22
26
  import '../chunk-P6GHJSLR.js';
23
27
  import '../chunk-EVUEIBNU.js';
24
- import '../chunk-444XKG46.js';
28
+ import '../chunk-YKQ2DPIP.js';
25
29
  import { SelectionBar, SelectionBarAction } from '../chunk-NUNKSZKU.js';
26
30
  import { FilterInput } from '../chunk-YU2KUMGE.js';
27
31
  import { GridView } from '../chunk-N5YEF3LC.js';
@@ -29,29 +33,30 @@ import { StreamedArtifactFrame } from '../chunk-LOJVUGBJ.js';
29
33
  import '../chunk-VILAPTCB.js';
30
34
  import { upcomingOf, conferenceUrl, isWebinarConference, canJoinEvent, calendarToListItem, buildGridEvents, pendingCreateToGrid, newEventDraft, MiniMonth, CalendarList, CalendarGrid, printCalendar, EventDetails, ScopeDialog, CalendarFormDialog, ProposeTimeDialog, isCalendarAttachment, parseIcsInvite, formatEventWhen, groupSlotsByDay, publicBookingMessage, formatSlotRange, zoneOptions, buildTimeChangeRequest, eventToDraft, needsScope, validateDraft, CALENDAR_DEFAULT_LABELS, buildCreateBody, attendeeKey, buildDeleteTarget, EventEditor, toSettingsValue, CalendarSettingsForm, describeCalendarError, normalizeFeedUrl, parseOverlayLink, isAllDayDraft, draftRangeUtc, freeBusyToRows, SchedulingAssistant, applySuggestion, toSuggestionViews, RoomFinder, bookingLink, defaultRoomWindow, bookingToForm, emptyBookingForm, slugify, WeeklyHoursEditor, validateBookingForm, formToBookingBody, WEEKDAY_NAMES, formatBusy, setupSteps, buildEditRequest } from '../chunk-B3AHCIV5.js';
31
35
  import { detectTimeZone, utcToDate, formatPlainDate, formatInZone, safeZone, todayInZone, addDays, wallToUtc } from '../chunk-GTCC2VAR.js';
32
- import { ChatPage } from '../chunk-JO3EMZ4X.js';
36
+ import { ConfirmDialog } from '../chunk-VHJHY7TT.js';
37
+ import { TabHeader } from '../chunk-4WWM3GQ5.js';
38
+ import { ChatPage } from '../chunk-GWSGIZQ5.js';
33
39
  import '../chunk-7XF5SFJ2.js';
34
40
  import { takeOpenDocumentForTurn, useRegisterOpenDocument } from '../chunk-YBLIKTJK.js';
35
- 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';
36
43
  import '../chunk-AA3PT6KR.js';
37
44
  import '../chunk-AUS3KBHJ.js';
38
45
  import '../chunk-SLSBJRWW.js';
39
- import { ConfirmDialog } from '../chunk-VHJHY7TT.js';
40
- import { TabHeader } from '../chunk-4WWM3GQ5.js';
41
46
  import '../chunk-NPLYHR2E.js';
42
47
  import '../chunk-7F6CBP3Z.js';
43
- import { useCopyText } from '../chunk-CYNF5PZI.js';
44
- import { useBlocksEnvironment } from '../chunk-YNIBUKV5.js';
48
+ import { useCopyText } from '../chunk-J5CWKFSC.js';
49
+ import { useBlocksEnvironment, useRequestedSettingsSection } from '../chunk-TBEVGWY3.js';
45
50
  import { ModalScaffold } from '../chunk-TX2ZICS7.js';
46
51
  import { fmtDate, initials } from '../chunk-OXF2IFXG.js';
47
52
  import '../chunk-VUNV25KB.js';
48
53
  import { lazy, useState, useMemo, useEffect, useCallback, useRef, Suspense, useSyncExternalStore, useLayoutEffect } from 'react';
49
54
  import { QueryClient, QueryClientProvider, useQueryClient, useQuery } from '@tanstack/react-query';
50
- 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';
51
56
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
52
- 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';
53
58
  import { useNotify } from '@arbidocs/react/shell';
54
- 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';
55
60
  import { useIsOnline, downloadBlob, useOptionalDocumentTools, fetchDocumentPdf, DocumentToolsProvider } from '@arbidocs/react/document-tools';
56
61
  import { useStreamedArtifact } from '@arbidocs/react/artifacts';
57
62
  import { bytesToBase64 } from '@arbidocs/client';
@@ -838,255 +843,6 @@ function ConnectedThreadFollow({
838
843
  }
839
844
  );
840
845
  }
841
- function useConnectedWorkspaceRole() {
842
- const { workspaceId, live, userId, ensureWorkspaceOpen } = useConnectedWorkspace();
843
- const { data: members = [] } = useWorkspaceUsers(workspaceId ?? void 0, {
844
- enabled: live && !!workspaceId,
845
- beforeFetch: ensureWorkspaceOpen
846
- });
847
- const role = members.find((m) => m.user.external_id === userId)?.role;
848
- return {
849
- members,
850
- role,
851
- /** An owner or a collaborator edits, pauses, resumes and runs what is shared with the workspace. */
852
- canEditShared: role === "owner" || role === "collaborator",
853
- /** With an item's creator, the only one who deletes it. */
854
- isWorkspaceOwner: role === "owner"
855
- };
856
- }
857
- var DEFAULT_CONNECTED_WORKFLOWS_TABLE_LABELS = {
858
- updateFailed: "Could not update the workflow",
859
- deleteTitle: "Delete workflow",
860
- deleteOne: (name) => `Delete \u201C${name}\u201D? Threads it already created stay.`,
861
- deleteMany: (count) => `Delete ${count} workflows? Threads they already created stay.`,
862
- runFailed: "The workflow failed. You can send an error report from its history.",
863
- noThread: "The workflow did not create a thread.",
864
- documentAction: (workflow) => workflow.action?.type === "email_documents" ? "Preparing your document email" : "Reviewing documents",
865
- untitledTask: "Untitled thread"
866
- };
867
- var messageOf = (error) => error instanceof Error ? error.message : "";
868
- function ConnectedWorkflowsTable({
869
- filter,
870
- describeTrigger = (w) => workflowTriggerType(w).replaceAll("_", " "),
871
- formatDate: formatDate2 = fmtDate,
872
- onViewRuns,
873
- connectedLabels,
874
- ...tableProps
875
- }) {
876
- const l = { ...DEFAULT_CONNECTED_WORKFLOWS_TABLE_LABELS, ...connectedLabels };
877
- const { notify, confirm, openConversation } = useBlocksEnvironment();
878
- const { canEditShared, isWorkspaceOwner } = useConnectedWorkspaceRole();
879
- const { data: saved = [], isLoading } = useWorkflows({ live: true });
880
- const { data: conversations, refetch } = useConnectedConversations({ live: true });
881
- const { data: agents = [] } = useAgents();
882
- const update = useUpdateWorkflow();
883
- const remove = useDeleteWorkflow();
884
- const run = useRunWorkflow();
885
- const [busyId, setBusyId] = useState(null);
886
- const workflows = useMemo(() => filter ? saved.filter(filter) : saved, [saved, filter]);
887
- const firingStamp = saved.map((w) => `${w.external_id}:${w.last_fired_at ?? ""}`).join("|");
888
- useEffect(() => {
889
- void refetch?.();
890
- }, [firingStamp, refetch]);
891
- const lastRuns = useMemo(() => {
892
- const out = {};
893
- for (const c of conversations) {
894
- const id = c.workflow_ext_id;
895
- if (id && (!out[id] || Date.parse(c.created_at) > Date.parse(out[id].at)))
896
- out[id] = { conversationId: c.external_id, at: c.created_at, threadStatus: c.status };
897
- }
898
- return out;
899
- }, [conversations]);
900
- const agentNames = useMemo(
901
- () => Object.fromEntries(agents.map((a) => [a.external_id, a.given_name || a.email])),
902
- [agents]
903
- );
904
- const taskNames = useMemo(
905
- () => Object.fromEntries(
906
- conversations.filter((c) => c.status != null).map((c) => [c.external_id, c.title || l.untitledTask])
907
- ),
908
- [conversations, l.untitledTask]
909
- );
910
- const act = async (workflow, action) => {
911
- setBusyId(workflow.external_id);
912
- try {
913
- await action();
914
- } catch (error) {
915
- notify(messageOf(error) || l.updateFailed, "error");
916
- } finally {
917
- setBusyId(null);
918
- }
919
- };
920
- const setActive = (workflow, active) => act(workflow, () => update.mutateAsync({ workflowId: workflow.external_id, patch: { active } }));
921
- const deleteAll = async (items) => {
922
- if (!items.length) return;
923
- const ok = await confirm({
924
- title: l.deleteTitle,
925
- message: items.length === 1 ? l.deleteOne(items[0].name) : l.deleteMany(items.length)
926
- });
927
- if (!ok) return;
928
- for (const workflow of items)
929
- await act(workflow, () => remove.mutateAsync(workflow.external_id));
930
- };
931
- return /* @__PURE__ */ jsx(
932
- WorkflowsTable,
933
- {
934
- ...tableProps,
935
- workflows,
936
- isLoading,
937
- busyId,
938
- describeTrigger,
939
- formatDate: formatDate2,
940
- agentNames,
941
- taskNames,
942
- lastRuns,
943
- canEditShared,
944
- isWorkspaceOwner,
945
- onOpenThread: (conversationId) => openConversation(conversationId),
946
- onViewRuns,
947
- onToggleActive: (workflow, active) => void setActive(workflow, active),
948
- onToggleActiveMany: (items, active) => {
949
- void (async () => {
950
- for (const workflow of items) await setActive(workflow, active);
951
- })();
952
- },
953
- onToggleShared: (workflow, shared) => void act(
954
- workflow,
955
- () => update.mutateAsync({ workflowId: workflow.external_id, patch: { shared } })
956
- ),
957
- onDelete: (workflow) => void deleteAll([workflow]),
958
- onDeleteMany: (items) => void deleteAll(items),
959
- onRun: (workflow) => void act(workflow, async () => {
960
- const result = await run.mutateAsync(workflow.external_id);
961
- if (result.conversation_ext_id) openConversation(result.conversation_ext_id);
962
- if (result.error) {
963
- onViewRuns?.(workflow);
964
- notify(l.runFailed, "error");
965
- return;
966
- }
967
- if (result.execution_id && !result.conversation_ext_id) {
968
- onViewRuns?.(workflow);
969
- notify(l.documentAction(workflow), "success");
970
- return;
971
- }
972
- if (!result.conversation_ext_id) throw new Error(l.noThread);
973
- })
974
- }
975
- );
976
- }
977
- var IMAGE_FILE_TYPES = /* @__PURE__ */ new Set(["png", "jpg", "jpeg", "gif", "bmp", "tiff", "webp"]);
978
- function toWorkflowFieldDocument(doc) {
979
- const isImage = IMAGE_FILE_TYPES.has((doc.file_type ?? "").toLowerCase());
980
- return {
981
- id: doc.external_id,
982
- title: doc.doc_metadata?.title || doc.file_name || doc.external_id,
983
- fileName: doc.file_name,
984
- pages: isImage ? null : doc.n_pages ?? null,
985
- tokens: isImage ? null : doc.tokens ?? null,
986
- status: doc.status,
987
- isImage
988
- };
989
- }
990
- function useConnectedWorkflowScopeSource() {
991
- const { data: docs } = useConnectedDocuments();
992
- const { data: tags } = useConnectedTags();
993
- return useMemo(() => buildWorkflowScopeSource(docs, documentScopeLabels(tags)), [docs, tags]);
994
- }
995
- function useConnectedAgentOptions() {
996
- const { data: agents } = useAgents();
997
- return useMemo(
998
- () => (agents ?? []).map((a) => ({ id: a.external_id, label: a.given_name || a.email })),
999
- [agents]
1000
- );
1001
- }
1002
- function ConnectedWorkflowDocumentsField({
1003
- field,
1004
- value,
1005
- onChange,
1006
- onAddFiles,
1007
- labels
1008
- }) {
1009
- const arbi = useArbi();
1010
- const { notify } = useBlocksEnvironment();
1011
- const { ensureWorkspaceOpen } = useConnectedWorkspace();
1012
- const { data: docs, loaded, refetch } = useConnectedDocuments();
1013
- const documents = useMemo(() => docs.map(toWorkflowFieldDocument), [docs]);
1014
- const chosen = value.documents ?? [];
1015
- const { data: thumbnails } = useThumbnails(chosen, { enabled: (field.max ?? 1) > 1 });
1016
- const input = useRef(null);
1017
- const [adding, setAdding] = useState(false);
1018
- const upload = useCallback(
1019
- async (files) => {
1020
- setAdding(true);
1021
- try {
1022
- await ensureWorkspaceOpen();
1023
- for (const file of files) await arbi.documents.uploadFile(file, file.name);
1024
- } catch (error) {
1025
- notify(error instanceof Error && error.message ? error.message : String(error), "error");
1026
- } finally {
1027
- setAdding(false);
1028
- await refetch?.();
1029
- }
1030
- },
1031
- [arbi, ensureWorkspaceOpen, notify, refetch]
1032
- );
1033
- return /* @__PURE__ */ jsxs(Fragment, { children: [
1034
- !onAddFiles && /* @__PURE__ */ jsx(
1035
- "input",
1036
- {
1037
- ref: input,
1038
- type: "file",
1039
- multiple: true,
1040
- className: "hidden",
1041
- "aria-label": "Add files",
1042
- "data-testid": "workflow-add-files-input",
1043
- onChange: (e) => {
1044
- const files = Array.from(e.target.files ?? []);
1045
- e.target.value = "";
1046
- if (files.length) void upload(files);
1047
- }
1048
- }
1049
- ),
1050
- /* @__PURE__ */ jsx(
1051
- WorkflowDocumentsField,
1052
- {
1053
- field,
1054
- value,
1055
- onChange,
1056
- documents,
1057
- loaded,
1058
- thumbnailOf: (id) => thumbnails?.[id],
1059
- onAddFiles: onAddFiles ?? ((files) => files?.length ? void upload(files) : input.current?.click()),
1060
- adding,
1061
- labels
1062
- }
1063
- )
1064
- ] });
1065
- }
1066
- function ConnectedWorkflowLauncher({
1067
- onAddFiles,
1068
- ...props
1069
- }) {
1070
- const scopeSource = useConnectedWorkflowScopeSource();
1071
- const agents = useConnectedAgentOptions();
1072
- return /* @__PURE__ */ jsx(
1073
- WorkflowLauncher,
1074
- {
1075
- ...props,
1076
- scopeSource,
1077
- agents,
1078
- renderDocuments: (field, value, onChange) => /* @__PURE__ */ jsx(
1079
- ConnectedWorkflowDocumentsField,
1080
- {
1081
- field,
1082
- value,
1083
- onChange,
1084
- onAddFiles
1085
- }
1086
- )
1087
- }
1088
- );
1089
- }
1090
846
  var DEFAULT_CONNECTED_SKILL_UPLOAD_LABELS = {
1091
847
  title: "Add a skill",
1092
848
  description: "Bring in a skill someone sent you, from a file or a link.",
@@ -2987,6 +2743,11 @@ function useConnectedShellWorkspaces(options = {}) {
2987
2743
  select: (workspace) => setWorkspace(workspace.id)
2988
2744
  });
2989
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 });
2990
2751
  function errorText2(error, fallback) {
2991
2752
  const body = error?.apiError;
2992
2753
  return typeof body?.detail === "string" ? body.detail : fallback;
@@ -3224,7 +2985,9 @@ function ConnectedNotificationPreferences({
3224
2985
  }
3225
2986
  ) }) });
3226
2987
  }
3227
- function ConnectedSessionsRow({ renderSessionIcon }) {
2988
+ function ConnectedSessionsRow({
2989
+ renderSessionIcon = renderSessionStatusIcon
2990
+ }) {
3228
2991
  const { notify, confirm } = useBlocksEnvironment();
3229
2992
  const [open, setOpen] = useState(false);
3230
2993
  const sessions = useSessions({ enabled: open });
@@ -3290,7 +3053,7 @@ function ConnectedLogoutDialog({
3290
3053
  onClose,
3291
3054
  canLogoutAll = true,
3292
3055
  confirmSignOut,
3293
- renderSessionIcon
3056
+ renderSessionIcon = renderSessionStatusIcon
3294
3057
  }) {
3295
3058
  const sessions = useSessions({ enabled: open });
3296
3059
  const signOut = useSignOut();
@@ -3368,251 +3131,120 @@ function ConnectedDangerZone({ renderSubscriptionLink }) {
3368
3131
  )
3369
3132
  ] });
3370
3133
  }
3371
- function useConnectedDocxNotifications(onOpen) {
3372
- const arbi = useArbi();
3373
- const { status, user, apiUrl } = useConnection();
3374
- const { notify } = useBlocksEnvironment();
3375
- const queries = useQueryClient();
3376
- const source = `docx-mentions:${apiUrl}:${user?.externalId || ""}`;
3377
- const queryKey = ["docx-mentions", apiUrl, user?.externalId];
3378
- const { data = [] } = useQuery({
3379
- queryKey,
3380
- queryFn: () => arbi.notifications.list({ type: "docx_mention" }),
3381
- enabled: status === "authenticated",
3382
- refetchInterval: 3e4
3383
- });
3384
- useArbiWebSocket((message) => {
3385
- if (message.type === "docx_mention") void queries.invalidateQueries({ queryKey });
3386
- });
3387
- useEffect(() => {
3388
- const items = [];
3389
- if (status === "authenticated")
3390
- for (const note of data) {
3391
- if (note.recipient.external_id !== user?.externalId || !note.workspace_ext_id) continue;
3392
- try {
3393
- const target = JSON.parse(note.content || "{}");
3394
- if (!target.document_id?.startsWith("doc-") || !target.comment_id) continue;
3395
- const documentId = target.document_id, commentId = target.comment_id, workspaceId = note.workspace_ext_id;
3396
- items.push({
3397
- id: `docx:${note.external_id}`,
3398
- title: "Mentioned you in a document comment",
3399
- description: [note.sender.given_name, note.sender.family_name].filter(Boolean).join(" "),
3400
- variant: "info",
3401
- ts: Date.parse(note.created_at),
3402
- read: note.read,
3403
- source,
3404
- onSelect: () => {
3405
- void Promise.resolve(onOpen({ documentId, commentId, workspaceId })).catch(
3406
- (error) => notify(
3407
- error instanceof Error ? error.message : "Could not open the document.",
3408
- "error"
3409
- )
3410
- );
3411
- }
3412
- });
3413
- } catch {
3414
- }
3415
- }
3416
- useNotify.getState().syncSource(source, items);
3417
- return () => useNotify.getState().syncSource(source, []);
3418
- }, [data, status, user?.externalId, source, onOpen, notify]);
3419
- 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);
3420
3140
  try {
3421
- await arbi.notifications.markRead(ids);
3422
- await queries.invalidateQueries({ queryKey });
3423
- } catch {
3424
- notify("Could not mark document mentions read.", "error");
3141
+ await onRefresh();
3142
+ } finally {
3143
+ setIsRefreshing(false);
3425
3144
  }
3426
3145
  };
3427
- return {
3428
- onMarkRead: (id) => {
3429
- if (id.startsWith("docx:")) void markRead([id.slice(5)]);
3430
- },
3431
- onMarkAllRead: () => {
3432
- void markRead(
3433
- data.filter((note) => !note.read && note.recipient.external_id === user?.externalId).map((note) => note.external_id)
3434
- );
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()
3435
3153
  }
3436
- };
3154
+ ) });
3437
3155
  }
3438
- function useConnectedWorkNotifications(onOpen) {
3439
- const { status, user, apiUrl } = useConnection();
3440
- const { notify } = useBlocksEnvironment();
3441
- const source = `work-notifications:${apiUrl}:${user?.externalId || ""}`;
3442
- const { data = [], markRead: persistRead } = useWorkNotifications({
3443
- apiUrl,
3444
- userId: user?.externalId,
3445
- enabled: status === "authenticated"
3446
- });
3447
- useEffect(() => {
3448
- const items = [];
3449
- if (status === "authenticated")
3450
- for (const note of data) {
3451
- if (note.recipient.external_id !== user?.externalId) continue;
3452
- const mapped = mapWorkNotification(note);
3453
- if (!mapped) continue;
3454
- items.push({
3455
- id: `work:${note.external_id}`,
3456
- title: mapped.title,
3457
- variant: note.type === "workflow_failed" ? "error" : note.type === "conversation_done" ? "success" : "info",
3458
- ts: Date.parse(note.created_at),
3459
- read: note.read,
3460
- source,
3461
- onSelect: () => {
3462
- void Promise.resolve().then(() => onOpen(mapped.target)).catch(
3463
- (error) => notify(
3464
- error instanceof Error ? error.message : "Could not open this notification.",
3465
- "error"
3466
- )
3467
- );
3468
- }
3469
- });
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
3470
3175
  }
3471
- useNotify.getState().syncSource(source, items);
3472
- return () => useNotify.getState().syncSource(source, []);
3473
- }, [data, status, user?.externalId, source, onOpen, notify]);
3474
- const markRead = async (ids) => {
3475
- 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;
3476
3239
  try {
3477
- await persistRead(ids);
3478
- } catch {
3479
- notify("Could not mark work notifications read.", "error");
3480
- }
3481
- };
3482
- return {
3483
- onMarkRead: (id) => {
3484
- if (data.some(
3485
- (note) => `work:${note.external_id}` === id && note.recipient.external_id === user?.externalId && mapWorkNotification(note)
3486
- ))
3487
- void markRead([id.slice(5)]);
3488
- },
3489
- onMarkAllRead: () => {
3490
- void markRead(
3491
- data.filter(
3492
- (note) => !note.read && note.recipient.external_id === user?.externalId && mapWorkNotification(note)
3493
- ).map((note) => note.external_id)
3494
- );
3495
- }
3496
- };
3497
- }
3498
- function mapWorkNotification(note) {
3499
- const sender = [note.sender.given_name, note.sender.family_name].filter(Boolean).join(" ") || note.sender.email;
3500
- if (note.type === "workflow_failed") {
3501
- try {
3502
- const payload = JSON.parse(note.content || "{}");
3503
- if (!payload.workflow_ext_id?.match(/^wfl-[a-zA-Z0-9]+$/)) return null;
3504
- if (note.workspace_ext_id?.match(/^wrk-[a-zA-Z0-9]+$/) && note.conversation_ext_id?.match(/^con-[a-zA-Z0-9]+$/)) {
3505
- return {
3506
- title: "A workflow failed to run",
3507
- target: {
3508
- kind: "conversation",
3509
- workspaceId: note.workspace_ext_id,
3510
- conversationId: note.conversation_ext_id
3511
- }
3512
- };
3513
- }
3514
- return {
3515
- title: "A workflow failed to run",
3516
- target: {
3517
- kind: "workflow",
3518
- workflowId: payload.workflow_ext_id,
3519
- workspaceId: note.workspace_ext_id || void 0
3520
- }
3521
- };
3522
- } catch {
3523
- return null;
3524
- }
3525
- }
3526
- if (note.type === "mail_draft_ready") {
3527
- const draftId = mailDraftIdFromContent(note.content);
3528
- if (!draftId) return null;
3529
- return {
3530
- title: `${sender} left a draft email for you to review`,
3531
- target: { kind: "mail_draft", draftId, mailbox: "native" }
3532
- };
3533
- }
3534
- const titles = {
3535
- mention: `${sender} mentioned you in a conversation`,
3536
- workspace_access_request: `${sender} needs workspace access to run a thread`,
3537
- conversation_ready: note.sender.external_id === note.recipient.external_id ? "Your thread is ready" : `${sender}\u2019s thread is ready`,
3538
- conversation_done: `${sender} marked a thread done`
3539
- };
3540
- const title = titles[note.type];
3541
- if (!title || !note.workspace_ext_id || !note.conversation_ext_id?.match(/^con-[a-zA-Z0-9]+$/))
3542
- return null;
3543
- return {
3544
- title,
3545
- target: {
3546
- kind: "conversation",
3547
- workspaceId: note.workspace_ext_id,
3548
- conversationId: note.conversation_ext_id,
3549
- ...note.message_ext_id ? { messageId: note.message_ext_id } : {}
3550
- }
3551
- };
3552
- }
3553
- function attachmentPath(accountId, messageId, attachmentId) {
3554
- return `${accountPath(accountId)}/messages/${encodeURIComponent(messageId)}/attachments/${encodeURIComponent(attachmentId)}`;
3555
- }
3556
- function saveFile(blob, name) {
3557
- const url = URL.createObjectURL(blob);
3558
- const link = document.createElement("a");
3559
- link.href = url;
3560
- link.download = name;
3561
- link.click();
3562
- setTimeout(() => URL.revokeObjectURL(url), 1e3);
3563
- }
3564
- function hydrateMailAttachments(client, account, messageId, attachments, { isOnline, offline }) {
3565
- return Promise.all(
3566
- attachments.map(async (a) => {
3567
- if (a.content_base64 != null) return a;
3568
- if (!isOnline) {
3569
- const file = await offline?.loadAttachment(account.id, messageId, a);
3570
- return file ? { ...a, content_base64: bytesToBase64(new Uint8Array(await file.arrayBuffer())) } : { ...a, content_base64: null };
3571
- }
3572
- const response = await client.fetch(attachmentPath(account.id, messageId, a.id));
3573
- return fileAttachment(new File([await response.blob()], a.name, { type: a.content_type }));
3574
- })
3575
- );
3576
- }
3577
- function ConnectedMailAccounts({
3578
- policy,
3579
- accounts,
3580
- onClose,
3581
- embedded = false,
3582
- user,
3583
- oauthReturnPath,
3584
- settings
3585
- }) {
3586
- const { client } = useMailClient();
3587
- const [profileId, setProfileId] = useState(policy.server_profiles[0]?.id ?? "");
3588
- const [email, setEmail] = useState("");
3589
- const [username, setUsername] = useState("");
3590
- const [password, setPassword] = useState("");
3591
- const [error, setError] = useState("");
3592
- const [alias, setAlias] = useState(() => defaultMailAlias(user));
3593
- const native = useClaimNativeAlias(onClose);
3594
- const isOnline = useMailOnline();
3595
- const offline = !isOnline;
3596
- const onNativeError = (err) => {
3597
- if (!isAliasTakenError(err)) return setError(err.message);
3598
- const suggestion = nextAliasSuggestion(alias);
3599
- setAlias(suggestion);
3600
- setError(aliasTakenMessage(alias, suggestion, policy.native_domain));
3601
- };
3602
- const connect = useConnectMailAccount();
3603
- const disconnect = useDisconnectMailAccount();
3604
- const authorizeOAuth = client.authorizeOAuth;
3605
- const oauth = async (vendor) => {
3606
- if (!authorizeOAuth) return;
3607
- try {
3608
- window.location.assign(
3609
- await authorizeOAuth(
3610
- vendor,
3611
- oauthReturnPath ?? `${window.location.pathname}${window.location.search}`
3612
- )
3613
- );
3614
- } catch (err) {
3615
- 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");
3616
3248
  }
3617
3249
  };
3618
3250
  const content = /* @__PURE__ */ jsxs(Fragment, { children: [
@@ -3797,6 +3429,504 @@ function ConnectedMailAccounts({
3797
3429
  }
3798
3430
  );
3799
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
+ }
3800
3930
  var sessionRooms = /* @__PURE__ */ new Map();
3801
3931
  function useWordBody({
3802
3932
  word,
@@ -9137,6 +9267,6 @@ function ConnectedAgentChatPanel({
9137
9267
  ] });
9138
9268
  }
9139
9269
 
9140
- 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 };
9141
9271
  //# sourceMappingURL=index.js.map
9142
9272
  //# sourceMappingURL=index.js.map