@datalayer/core 1.1.60 → 1.2.10

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 (496) hide show
  1. package/README.md +41 -18
  2. package/lib/api/DatalayerApi.d.ts +42 -1
  3. package/lib/api/DatalayerApi.js +90 -3
  4. package/lib/api/constants.d.ts +19 -1
  5. package/lib/api/constants.js +19 -1
  6. package/lib/api/contents/attachments.d.ts +9 -0
  7. package/lib/api/contents/attachments.js +39 -0
  8. package/lib/api/contents/bridges.d.ts +22 -0
  9. package/lib/api/contents/bridges.js +79 -0
  10. package/lib/api/contents/capabilities.d.ts +11 -0
  11. package/lib/api/contents/capabilities.js +21 -0
  12. package/lib/api/contents/cloudStorage.d.ts +31 -0
  13. package/lib/api/contents/cloudStorage.js +89 -0
  14. package/lib/api/contents/dataservers.d.ts +37 -0
  15. package/lib/api/contents/dataservers.js +121 -0
  16. package/lib/api/contents/datasets.d.ts +63 -0
  17. package/lib/api/contents/datasets.js +82 -0
  18. package/lib/api/contents/datasources.d.ts +70 -0
  19. package/lib/api/contents/datasources.js +149 -0
  20. package/lib/api/contents/generated.d.ts +1070 -0
  21. package/lib/api/contents/index.d.ts +16 -0
  22. package/lib/api/contents/index.js +20 -0
  23. package/lib/api/contents/mcp.d.ts +46 -0
  24. package/lib/api/contents/mcp.js +157 -0
  25. package/lib/api/contents/objects.d.ts +31 -0
  26. package/lib/api/contents/objects.js +88 -0
  27. package/lib/api/contents/operations.d.ts +3 -0
  28. package/lib/api/contents/operations.js +19 -0
  29. package/lib/api/contents/runtimeMounts.d.ts +40 -0
  30. package/lib/api/contents/runtimeMounts.js +59 -0
  31. package/lib/api/contents/sandboxUid.d.ts +21 -0
  32. package/lib/api/contents/sandboxUid.js +27 -0
  33. package/lib/api/contents/sources.d.ts +19 -0
  34. package/lib/api/contents/sources.js +119 -0
  35. package/lib/api/contents/sync.d.ts +18 -0
  36. package/lib/api/contents/sync.js +69 -0
  37. package/lib/api/contents/transfers.d.ts +38 -0
  38. package/lib/api/contents/transfers.js +123 -0
  39. package/lib/api/evals/client.d.ts +402 -0
  40. package/lib/api/evals/client.js +359 -0
  41. package/lib/api/evals/index.d.ts +10 -0
  42. package/lib/api/evals/index.js +18 -0
  43. package/lib/api/evals/request.d.ts +43 -0
  44. package/lib/api/evals/request.js +67 -0
  45. package/lib/api/evals/status.d.ts +27 -0
  46. package/lib/api/evals/status.js +122 -0
  47. package/lib/api/evals/types.d.ts +1335 -0
  48. package/lib/api/evals/types.js +5 -0
  49. package/lib/api/iam/connectedAgents.d.ts +68 -0
  50. package/lib/api/iam/connectedAgents.js +87 -0
  51. package/lib/api/iam/identityProviders.d.ts +76 -0
  52. package/lib/api/iam/identityProviders.js +187 -0
  53. package/lib/api/iam/index.d.ts +3 -1
  54. package/lib/api/iam/index.js +3 -1
  55. package/lib/api/iam/mcpAlertRules.d.ts +51 -0
  56. package/lib/api/iam/mcpAlertRules.js +198 -0
  57. package/lib/api/iam/mcpAuditSettings.d.ts +46 -0
  58. package/lib/api/iam/mcpAuditSettings.js +120 -0
  59. package/lib/api/iam/mcpPolicy.d.ts +181 -0
  60. package/lib/api/iam/mcpPolicy.js +168 -0
  61. package/lib/api/iam/organizationTeams.d.ts +13 -0
  62. package/lib/api/iam/organizationTeams.js +43 -0
  63. package/lib/api/iam/profile.d.ts +17 -1
  64. package/lib/api/iam/profile.js +27 -0
  65. package/lib/api/iam/scimTokens.d.ts +79 -0
  66. package/lib/api/iam/scimTokens.js +141 -0
  67. package/lib/api/iam/secrets.js +9 -21
  68. package/lib/api/iam/serviceAgents.d.ts +68 -0
  69. package/lib/api/iam/serviceAgents.js +119 -0
  70. package/lib/api/iam/trials.d.ts +38 -0
  71. package/lib/api/iam/trials.js +66 -0
  72. package/lib/api/index.d.ts +8 -1
  73. package/lib/api/index.js +7 -1
  74. package/lib/api/mcp/activity.d.ts +37 -0
  75. package/lib/api/mcp/activity.js +26 -0
  76. package/lib/api/mcp/alerts.d.ts +25 -0
  77. package/lib/api/mcp/alerts.js +51 -0
  78. package/lib/api/mcp/audit.d.ts +29 -0
  79. package/lib/api/mcp/audit.js +55 -0
  80. package/lib/api/mcp/bindings.d.ts +18 -0
  81. package/lib/api/mcp/bindings.js +42 -0
  82. package/lib/api/mcp/forwarding.d.ts +25 -0
  83. package/lib/api/mcp/forwarding.js +46 -0
  84. package/lib/api/mcp/gateway.d.ts +16 -0
  85. package/lib/api/mcp/gateway.js +70 -0
  86. package/lib/api/mcp/generated.d.ts +22 -0
  87. package/lib/api/mcp/generated.js +213 -0
  88. package/lib/api/mcp/index.d.ts +17 -0
  89. package/lib/api/mcp/index.js +25 -0
  90. package/lib/api/mcp/observability.d.ts +141 -0
  91. package/lib/api/mcp/observability.js +267 -0
  92. package/lib/api/mcp/operations.d.ts +83 -0
  93. package/lib/api/mcp/operations.js +50 -0
  94. package/lib/api/mcp/organizations.d.ts +102 -0
  95. package/lib/api/mcp/organizations.js +46 -0
  96. package/lib/api/mcp/policy.d.ts +9 -0
  97. package/lib/api/mcp/policy.js +23 -0
  98. package/lib/api/mcp/tasks.d.ts +49 -0
  99. package/lib/api/mcp/tasks.js +147 -0
  100. package/lib/api/orchestration/client.d.ts +53 -0
  101. package/lib/api/orchestration/client.js +105 -0
  102. package/lib/api/orchestration/events.d.ts +88 -0
  103. package/lib/api/orchestration/events.js +245 -0
  104. package/lib/api/orchestration/generated.d.ts +693 -0
  105. package/lib/api/orchestration/generated.js +687 -0
  106. package/lib/api/orchestration/index.d.ts +30 -0
  107. package/lib/api/orchestration/index.js +34 -0
  108. package/lib/api/orchestration/lifecycle.d.ts +39 -0
  109. package/lib/api/orchestration/lifecycle.js +57 -0
  110. package/lib/api/orchestration/measures.d.ts +55 -0
  111. package/lib/api/orchestration/measures.js +99 -0
  112. package/lib/api/otel/dashboards.d.ts +56 -0
  113. package/lib/api/otel/dashboards.js +50 -0
  114. package/lib/api/otel/index.d.ts +1 -0
  115. package/lib/api/otel/index.js +1 -0
  116. package/lib/api/otel/metrics.d.ts +16 -0
  117. package/lib/api/otel/metrics.js +15 -0
  118. package/lib/api/scheduler/client.d.ts +32 -0
  119. package/lib/api/scheduler/client.js +42 -0
  120. package/lib/api/scheduler/index.d.ts +8 -0
  121. package/lib/api/scheduler/index.js +16 -0
  122. package/lib/api/scheduler/request.d.ts +28 -0
  123. package/lib/api/scheduler/request.js +50 -0
  124. package/lib/api/scheduler/types.d.ts +88 -0
  125. package/lib/api/scheduler/types.js +5 -0
  126. package/lib/api/spacer/comments.d.ts +97 -0
  127. package/lib/api/spacer/comments.js +45 -0
  128. package/lib/api/spacer/index.d.ts +9 -0
  129. package/lib/api/spacer/index.js +17 -0
  130. package/lib/api/spacer/notebooks.d.ts +33 -0
  131. package/lib/api/spacer/notebooks.js +39 -0
  132. package/lib/api/spacer/request.d.ts +25 -0
  133. package/lib/api/spacer/request.js +46 -0
  134. package/lib/api/spacer/spaces.d.ts +68 -0
  135. package/lib/api/spacer/spaces.js +45 -0
  136. package/lib/api/utils/validation.d.ts +4 -4
  137. package/lib/api/utils/validation.js +10 -7
  138. package/lib/client/auth/index.js +0 -5
  139. package/lib/client/auth/storage.js +0 -5
  140. package/lib/client/auth/strategies.js +0 -5
  141. package/lib/client/base.d.ts +6 -0
  142. package/lib/client/base.js +8 -0
  143. package/lib/client/constants.d.ts +1 -0
  144. package/lib/client/constants.js +1 -0
  145. package/lib/client/index.d.ts +0 -10
  146. package/lib/client/index.js +2 -2
  147. package/lib/client/mixins/ContentsMixin.d.ts +71 -0
  148. package/lib/client/mixins/ContentsMixin.js +157 -0
  149. package/lib/client/mixins/IAMMixin.d.ts +0 -31
  150. package/lib/client/mixins/IAMMixin.js +0 -58
  151. package/lib/components/animation/AnimatedText.d.ts +2 -44
  152. package/lib/components/animation/AnimatedText.js +6 -126
  153. package/lib/components/anonymous/AnonymousKeyExpired.d.ts +56 -0
  154. package/lib/components/anonymous/AnonymousKeyExpired.js +96 -0
  155. package/lib/components/anonymous/AnonymousKeyTimer.d.ts +63 -0
  156. package/lib/components/anonymous/AnonymousKeyTimer.js +140 -0
  157. package/lib/components/anonymous/index.d.ts +7 -0
  158. package/lib/components/anonymous/index.js +15 -0
  159. package/lib/components/auth/SigInAPIKey.d.ts +1 -0
  160. package/lib/components/auth/SigInAPIKey.js +0 -6
  161. package/lib/components/auth/SignIn.d.ts +1 -0
  162. package/lib/components/auth/SignIn.js +0 -4
  163. package/lib/components/auth/SignIn.stories.d.ts +2 -2
  164. package/lib/components/avatars/BoringAvatar.d.ts +1 -1
  165. package/lib/components/avatars/BoringAvatar.stories.d.ts +1 -1
  166. package/lib/components/avatars/DLAvatar.d.ts +1 -1
  167. package/lib/components/avatars/DLAvatar.js +0 -4
  168. package/lib/components/avatars/UserAvatar.d.ts +16 -1
  169. package/lib/components/avatars/UserAvatar.js +15 -13
  170. package/lib/components/avatars/UserProfileAvatar.d.ts +1 -1
  171. package/lib/components/banners/NoAutomationBanner.d.ts +1 -1
  172. package/lib/components/billing/BillingEntitySelect.d.ts +16 -0
  173. package/lib/components/billing/BillingEntitySelect.js +49 -27
  174. package/lib/components/billing/eligibility.d.ts +22 -0
  175. package/lib/components/billing/eligibility.js +27 -0
  176. package/lib/components/billing/index.d.ts +1 -0
  177. package/lib/components/billing/index.js +1 -4
  178. package/lib/components/buttons/DownloadCSVButton.d.ts +1 -1
  179. package/lib/components/buttons/DownloadJsonButton.d.ts +1 -1
  180. package/lib/components/buttons/LongActionButton.d.ts +1 -0
  181. package/lib/components/buttons/LongActionButton.js +0 -4
  182. package/lib/components/buttons/UploadButton.d.ts +1 -0
  183. package/lib/components/buttons/UploadButton.js +0 -4
  184. package/lib/components/checkout/StripeCheckout.d.ts +1 -1
  185. package/lib/components/collaboration/LiveEditorCollaborators.d.ts +36 -0
  186. package/lib/components/collaboration/LiveEditorCollaborators.js +88 -53
  187. package/lib/components/collaboration/index.js +0 -4
  188. package/lib/components/confetti/ConfettiSuccess.d.ts +1 -1
  189. package/lib/components/contents/ContentSourceCard.d.ts +8 -0
  190. package/lib/components/contents/ContentSourceCard.js +23 -0
  191. package/lib/components/contents/HomeFolderObjectsBrowser.d.ts +10 -0
  192. package/lib/components/contents/HomeFolderObjectsBrowser.js +148 -0
  193. package/lib/components/contents/index.d.ts +2 -0
  194. package/lib/components/contents/index.js +6 -0
  195. package/lib/components/context/OrganizationSelect.d.ts +1 -1
  196. package/lib/components/display/AvatarSkeleton.d.ts +1 -1
  197. package/lib/components/display/BusyDots.d.ts +1 -1
  198. package/lib/components/display/CenteredSpinner.d.ts +1 -1
  199. package/lib/components/display/CodePreview.d.ts +1 -1
  200. package/lib/components/display/DatalayerBox.d.ts +7 -3
  201. package/lib/components/display/DatalayerBox.js +7 -7
  202. package/lib/components/display/HorizontalCenter.d.ts +1 -1
  203. package/lib/components/display/JupyterDialog.d.ts +1 -0
  204. package/lib/components/display/JupyterDialog.js +1 -7
  205. package/lib/components/display/Markdown.d.ts +1 -0
  206. package/lib/components/display/NavLink.js +3 -2
  207. package/lib/components/display/NotebookSkeleton.d.ts +1 -1
  208. package/lib/components/display/Placeholder.d.ts +1 -1
  209. package/lib/components/display/ToTopBranded.d.ts +1 -1
  210. package/lib/components/echarts/EChartsReact.d.ts +1 -1
  211. package/lib/components/flashes/FlashClosable.d.ts +1 -0
  212. package/lib/components/flashes/FlashClosable.js +0 -4
  213. package/lib/components/flashes/FlashGuest.d.ts +1 -1
  214. package/lib/components/flashes/FlashSurveys.d.ts +1 -1
  215. package/lib/components/flashes/FlashUnauthorized.d.ts +1 -0
  216. package/lib/components/flashes/FlashUnauthorized.js +0 -6
  217. package/lib/components/flashes/surveys/Survey2025_1.d.ts +1 -1
  218. package/lib/components/iam/ExternalTokenSilentLogin.d.ts +1 -1
  219. package/lib/components/index.d.ts +2 -0
  220. package/lib/components/index.js +2 -0
  221. package/lib/components/labels/StatusLabels.d.ts +2 -9
  222. package/lib/components/labels/StatusLabels.js +2 -26
  223. package/lib/components/labels/VisibilityLabel.d.ts +1 -1
  224. package/lib/components/landings/StepBlock.d.ts +1 -1
  225. package/lib/components/mcp/ClientBadge.d.ts +41 -0
  226. package/lib/components/mcp/ClientBadge.js +33 -0
  227. package/lib/components/mcp/McpErrorBlankslate.d.ts +21 -0
  228. package/lib/components/mcp/McpErrorBlankslate.js +17 -0
  229. package/lib/components/mcp/ScopeList.d.ts +28 -0
  230. package/lib/components/mcp/ScopeList.js +14 -0
  231. package/lib/components/mcp/index.d.ts +10 -0
  232. package/lib/components/mcp/index.js +18 -0
  233. package/lib/components/navbar/NavigationVisbilityObserver.d.ts +2 -1
  234. package/lib/components/navbar/SubdomainNavBar.d.ts +10 -5
  235. package/lib/components/navbar/SubdomainNavBar.js +2 -1
  236. package/lib/components/notebooks/JupyterNotebook.d.ts +1 -1
  237. package/lib/components/notebooks/JupyterNotebookToolbar.d.ts +1 -1
  238. package/lib/components/principal/PrincipalAppearance.d.ts +22 -42
  239. package/lib/components/principal/PrincipalAppearance.js +232 -182
  240. package/lib/components/principal/PrincipalAvatar.d.ts +9 -1
  241. package/lib/components/principal/PrincipalAvatar.js +18 -10
  242. package/lib/components/principal/PrincipalBadge.d.ts +1 -1
  243. package/lib/components/principal/PrincipalBanner.d.ts +1 -1
  244. package/lib/components/principal/PrincipalDetailsOverlay.d.ts +38 -1
  245. package/lib/components/principal/PrincipalDetailsOverlay.js +64 -33
  246. package/lib/components/principal/PrincipalHoverCard.d.ts +31 -0
  247. package/lib/components/principal/PrincipalHoverCard.js +52 -0
  248. package/lib/components/principal/PrincipalSwitcherMenu.d.ts +1 -0
  249. package/lib/components/principal/PrincipalSwitcherMenu.js +5 -14
  250. package/lib/components/principal/index.d.ts +2 -1
  251. package/lib/components/principal/index.js +2 -1
  252. package/lib/components/progress/ConsumptionBar.d.ts +1 -0
  253. package/lib/components/progress/ConsumptionBar.js +0 -4
  254. package/lib/components/progress/ProgressRing.d.ts +1 -0
  255. package/lib/components/progress/SpinnerBar.d.ts +1 -1
  256. package/lib/components/progress/Timer.d.ts +1 -0
  257. package/lib/components/progress/Timer.js +0 -4
  258. package/lib/components/screencapture/Screencapture.js +46 -3
  259. package/lib/components/screencapture/ScreencaptureButton.d.ts +1 -1
  260. package/lib/components/sharing/ShareAccessComponent.d.ts +58 -3
  261. package/lib/components/sharing/ShareAccessComponent.js +143 -98
  262. package/lib/components/sharing/SharingEditor.d.ts +21 -0
  263. package/lib/components/sharing/SharingEditor.js +9 -28
  264. package/lib/components/sharing/index.d.ts +1 -0
  265. package/lib/components/sharing/index.js +1 -0
  266. package/lib/components/sharing/sandboxSharing.d.ts +26 -0
  267. package/lib/components/sharing/sandboxSharing.js +41 -0
  268. package/lib/components/spaces/SpaceDetailsOverlay.d.ts +39 -0
  269. package/lib/components/spaces/SpaceDetailsOverlay.js +80 -0
  270. package/lib/components/spaces/SpaceDisplay.d.ts +38 -0
  271. package/lib/components/spaces/SpaceDisplay.js +92 -0
  272. package/lib/components/spaces/index.d.ts +4 -0
  273. package/lib/components/spaces/index.js +7 -0
  274. package/lib/components/spaces/spaceDisplayModel.d.ts +93 -0
  275. package/lib/components/spaces/spaceDisplayModel.js +170 -0
  276. package/lib/components/sparklines/Sparklines.js +3 -4
  277. package/lib/components/sparklines/index.js +0 -4
  278. package/lib/components/storage/ContentsBrowser.d.ts +25 -1
  279. package/lib/components/storage/ContentsBrowser.js +145 -52
  280. package/lib/components/storage/ContentsBrowserMock.d.ts +3 -0
  281. package/lib/components/storage/ContentsBrowserMock.js +75 -0
  282. package/lib/components/storage/ContentsItems.d.ts +2 -1
  283. package/lib/components/storage/ContentsItems.js +0 -4
  284. package/lib/components/storage/ContentsTable.d.ts +50 -0
  285. package/lib/components/storage/ContentsTable.js +134 -0
  286. package/lib/components/storage/HomeFolderDrive.d.ts +71 -0
  287. package/lib/components/storage/HomeFolderDrive.js +248 -0
  288. package/lib/components/storage/index.d.ts +2 -0
  289. package/lib/components/storage/index.js +2 -0
  290. package/lib/components/students/StudentItemStatus.d.ts +1 -1
  291. package/lib/components/students/StudentResultCircle.d.ts +1 -1
  292. package/lib/components/subnav/SubNav.d.ts +5 -5
  293. package/lib/components/subnav/SubNav.js +11 -9
  294. package/lib/components/tables/DataTable.d.ts +1 -1
  295. package/lib/components/text-reveal/TextRevealAnimation.d.ts +2 -2
  296. package/lib/components/text-reveal/useTextRevealAnimationLines.d.ts +1 -1
  297. package/lib/components/time/LiveRelativeTime.d.ts +1 -0
  298. package/lib/components/time/LiveRelativeTime.js +0 -8
  299. package/lib/components/time/index.js +0 -4
  300. package/lib/components/timeline/Timeline.d.ts +1 -1
  301. package/lib/components/timeline/index.js +0 -4
  302. package/lib/components/users/PeerIndicator.d.ts +1 -0
  303. package/lib/components/users/PeerIndicator.js +0 -4
  304. package/lib/config/Configuration.d.ts +15 -17
  305. package/lib/config/Configuration.js +7 -0
  306. package/lib/hooks/cacheConverters.d.ts +0 -7
  307. package/lib/hooks/cacheConverters.js +0 -25
  308. package/lib/hooks/index.d.ts +3 -0
  309. package/lib/hooks/index.js +3 -0
  310. package/lib/hooks/layouts/LayoutBackdrop.d.ts +1 -1
  311. package/lib/hooks/layouts/LayoutScreencapture.d.ts +1 -1
  312. package/lib/hooks/useBackdrop.d.ts +1 -1
  313. package/lib/hooks/useBackdropJupyterLab.d.ts +3 -2
  314. package/lib/hooks/useBackdropJupyterLab.js +0 -4
  315. package/lib/hooks/useBillingEntityStore.js +3 -0
  316. package/lib/hooks/useCache.d.ts +478 -130
  317. package/lib/hooks/useCache.js +1580 -676
  318. package/lib/hooks/useContainsFocus.d.ts +1 -1
  319. package/lib/hooks/useContents.d.ts +334 -0
  320. package/lib/hooks/useContents.js +1033 -0
  321. package/lib/hooks/useFocusTrap.d.ts +4 -4
  322. package/lib/hooks/useFocusTrap.js +1 -1
  323. package/lib/hooks/useMcp.d.ts +315 -0
  324. package/lib/hooks/useMcp.js +891 -0
  325. package/lib/hooks/useMobile.js +0 -5
  326. package/lib/hooks/useNavigate.d.ts +41 -3
  327. package/lib/hooks/useNavigate.js +106 -52
  328. package/lib/hooks/usePrincipalCacheStore.js +3 -0
  329. package/lib/hooks/usePrincipalStore.js +3 -0
  330. package/lib/hooks/useProjectStore.d.ts +3 -3
  331. package/lib/hooks/useProjectStore.js +4 -4
  332. package/lib/hooks/useRef.d.ts +1 -1
  333. package/lib/hooks/useRef.js +3 -0
  334. package/lib/hooks/useScreencapture.d.ts +2 -1
  335. package/lib/hooks/useScreencapture.js +0 -4
  336. package/lib/hooks/useSpaceCacheStore.d.ts +50 -0
  337. package/lib/hooks/useSpaceCacheStore.js +85 -0
  338. package/lib/hooks/useToast.js +0 -4
  339. package/lib/hooks/useVisibilityObserver.d.ts +1 -1
  340. package/lib/index.d.ts +4 -1
  341. package/lib/index.js +3 -1
  342. package/lib/mocks/components/FlashMock.d.ts +1 -1
  343. package/lib/mocks/views/ActionMenuMock.d.ts +1 -1
  344. package/lib/mocks/views/ChartMock.d.ts +1 -1
  345. package/lib/mocks/views/DashboardMock.d.ts +1 -1
  346. package/lib/mocks/views/FormMock.d.ts +1 -1
  347. package/lib/mocks/views/TableMock.d.ts +1 -1
  348. package/lib/mocks/views/WipMock.d.ts +1 -1
  349. package/lib/models/Credits.d.ts +16 -0
  350. package/lib/models/Credits.js +22 -0
  351. package/lib/models/CreditsDTO.d.ts +6 -5
  352. package/lib/models/CreditsDTO.js +7 -5
  353. package/lib/models/McpAuditEvent.d.ts +52 -0
  354. package/lib/models/McpAuditEvent.js +5 -0
  355. package/lib/models/McpBinding.d.ts +57 -0
  356. package/lib/models/McpBinding.js +5 -0
  357. package/lib/models/McpPolicy.d.ts +77 -0
  358. package/lib/models/McpPolicy.js +5 -0
  359. package/lib/models/McpTask.d.ts +94 -0
  360. package/lib/models/McpTask.js +7 -0
  361. package/lib/models/Organization.d.ts +69 -0
  362. package/lib/models/Organization.js +96 -0
  363. package/lib/models/Secret.d.ts +1 -2
  364. package/lib/models/Secret.js +2 -18
  365. package/lib/models/StartedBy.d.ts +91 -0
  366. package/lib/models/StartedBy.js +117 -0
  367. package/lib/models/Team.d.ts +2 -0
  368. package/lib/models/Team.js +2 -0
  369. package/lib/models/User.d.ts +4 -0
  370. package/lib/models/User.js +3 -0
  371. package/lib/models/UserDTO.js +4 -2
  372. package/lib/models/UserSettings.d.ts +13 -0
  373. package/lib/models/UserSettings.js +9 -0
  374. package/lib/models/contents/__fixtures__/solr-codec.json +57 -0
  375. package/lib/models/contents/__fixtures__/v1-contracts.json +194 -0
  376. package/lib/models/contents/fieldCase.d.ts +8 -0
  377. package/lib/models/contents/fieldCase.js +37 -0
  378. package/lib/models/contents/index.d.ts +2 -0
  379. package/lib/models/contents/index.js +6 -0
  380. package/lib/models/contents/permissions.d.ts +16 -0
  381. package/lib/models/contents/permissions.js +34 -0
  382. package/lib/models/index.d.ts +5 -1
  383. package/lib/models/index.js +5 -1
  384. package/lib/navigation/components.js +2 -3
  385. package/lib/routes/publicPaths.js +4 -0
  386. package/lib/state/index.d.ts +1 -0
  387. package/lib/state/index.js +1 -0
  388. package/lib/state/sessionEnd.d.ts +55 -0
  389. package/lib/state/sessionEnd.js +162 -0
  390. package/lib/state/substates/CoreState.d.ts +15 -7
  391. package/lib/state/substates/CoreState.js +21 -17
  392. package/lib/state/substates/IAMState.d.ts +1 -1
  393. package/lib/state/substates/IAMState.js +12 -5
  394. package/lib/state/substates/LayoutState.js +12 -0
  395. package/lib/state/substates/ProfileState.d.ts +1 -0
  396. package/lib/state/substates/ProfileState.js +1 -4
  397. package/lib/state/substates/index.d.ts +0 -1
  398. package/lib/state/substates/index.js +0 -1
  399. package/lib/utils/Jwt.d.ts +26 -0
  400. package/lib/utils/Jwt.js +37 -0
  401. package/lib/utils/Lazy.d.ts +20 -0
  402. package/lib/utils/Lazy.js +32 -6
  403. package/lib/utils/Screencapture.js +3 -0
  404. package/lib/utils/WithSuspense.d.ts +11 -1
  405. package/lib/utils/WithSuspense.js +11 -1
  406. package/lib/views/api-keys/APIKeyEdit.d.ts +1 -1
  407. package/lib/views/api-keys/APIKeyNew.d.ts +1 -1
  408. package/lib/views/api-keys/APIKeys.d.ts +1 -1
  409. package/lib/views/api-keys/APIKeys.js +30 -4
  410. package/lib/views/api-keys/APIKeysStandalone.d.ts +5 -1
  411. package/lib/views/api-keys/APIKeysStandalone.js +2 -2
  412. package/lib/views/datasources/DatasourceDetail.d.ts +12 -5
  413. package/lib/views/datasources/DatasourceDetail.js +80 -110
  414. package/lib/views/datasources/DatasourceNew.d.ts +14 -8
  415. package/lib/views/datasources/DatasourceNew.js +129 -118
  416. package/lib/views/datasources/Datasources.d.ts +39 -7
  417. package/lib/views/datasources/Datasources.js +95 -40
  418. package/lib/views/datasources/DatasourcesMock.d.ts +3 -0
  419. package/lib/views/datasources/DatasourcesMock.js +57 -0
  420. package/lib/views/iam/SignInSimple.d.ts +12 -0
  421. package/lib/views/iam/SignInSimple.js +4 -4
  422. package/lib/views/index.d.ts +1 -0
  423. package/lib/views/index.js +1 -0
  424. package/lib/views/mcp/AdmittedClients.d.ts +44 -0
  425. package/lib/views/mcp/AdmittedClients.js +59 -0
  426. package/lib/views/mcp/AlertDestinations.d.ts +34 -0
  427. package/lib/views/mcp/AlertDestinations.js +75 -0
  428. package/lib/views/mcp/AlertRules.d.ts +32 -0
  429. package/lib/views/mcp/AlertRules.js +245 -0
  430. package/lib/views/mcp/ApprovalQueue.d.ts +66 -0
  431. package/lib/views/mcp/ApprovalQueue.js +95 -0
  432. package/lib/views/mcp/AuditLog.d.ts +42 -0
  433. package/lib/views/mcp/AuditLog.js +144 -0
  434. package/lib/views/mcp/ConnectedAgents.d.ts +34 -0
  435. package/lib/views/mcp/ConnectedAgents.js +135 -0
  436. package/lib/views/mcp/EnterpriseConsole.d.ts +74 -0
  437. package/lib/views/mcp/EnterpriseConsole.js +195 -0
  438. package/lib/views/mcp/IdentityProviders.d.ts +33 -0
  439. package/lib/views/mcp/IdentityProviders.js +299 -0
  440. package/lib/views/mcp/McpDashboard.d.ts +50 -0
  441. package/lib/views/mcp/McpDashboard.js +430 -0
  442. package/lib/views/mcp/McpHome.d.ts +92 -0
  443. package/lib/views/mcp/McpHome.js +153 -0
  444. package/lib/views/mcp/McpObservability.d.ts +79 -0
  445. package/lib/views/mcp/McpObservability.js +236 -0
  446. package/lib/views/mcp/NotebookRuns.d.ts +39 -0
  447. package/lib/views/mcp/NotebookRuns.js +44 -0
  448. package/lib/views/mcp/OrganizationPolicy.d.ts +45 -0
  449. package/lib/views/mcp/OrganizationPolicy.js +108 -0
  450. package/lib/views/mcp/OrganizationUsage.d.ts +69 -0
  451. package/lib/views/mcp/OrganizationUsage.js +113 -0
  452. package/lib/views/mcp/PersonalPolicy.d.ts +54 -0
  453. package/lib/views/mcp/PersonalPolicy.js +126 -0
  454. package/lib/views/mcp/Policies.d.ts +53 -0
  455. package/lib/views/mcp/Policies.js +210 -0
  456. package/lib/views/mcp/PolicyForm.d.ts +83 -0
  457. package/lib/views/mcp/PolicyForm.js +113 -0
  458. package/lib/views/mcp/PolicyHistory.d.ts +58 -0
  459. package/lib/views/mcp/PolicyHistory.js +75 -0
  460. package/lib/views/mcp/RunDetail.d.ts +87 -0
  461. package/lib/views/mcp/RunDetail.js +186 -0
  462. package/lib/views/mcp/ScimProvisioning.d.ts +54 -0
  463. package/lib/views/mcp/ScimProvisioning.js +173 -0
  464. package/lib/views/mcp/ServiceAgents.d.ts +46 -0
  465. package/lib/views/mcp/ServiceAgents.js +194 -0
  466. package/lib/views/mcp/TeamPolicies.d.ts +33 -0
  467. package/lib/views/mcp/TeamPolicies.js +159 -0
  468. package/lib/views/mcp/ToolAccess.d.ts +60 -0
  469. package/lib/views/mcp/ToolAccess.js +101 -0
  470. package/lib/views/mcp/TraceTimeline.d.ts +81 -0
  471. package/lib/views/mcp/TraceTimeline.js +132 -0
  472. package/lib/views/mcp/format.d.ts +25 -0
  473. package/lib/views/mcp/format.js +77 -0
  474. package/lib/views/mcp/index.d.ts +34 -0
  475. package/lib/views/mcp/index.js +42 -0
  476. package/lib/views/mcp/types.d.ts +66 -0
  477. package/lib/views/mcp/types.js +5 -0
  478. package/lib/views/otel/simpleAuthStore.js +3 -0
  479. package/lib/views/secrets/SecretEdit.d.ts +5 -1
  480. package/lib/views/secrets/SecretEdit.js +5 -4
  481. package/lib/views/secrets/SecretNew.d.ts +11 -1
  482. package/lib/views/secrets/SecretNew.js +7 -3
  483. package/lib/views/secrets/Secrets.d.ts +12 -1
  484. package/lib/views/secrets/Secrets.js +2 -2
  485. package/package.json +269 -260
  486. package/scripts/generate-contents-types.py +169 -0
  487. package/scripts/generate-mcp-types.py +233 -0
  488. package/scripts/generate-orchestration-types.py +920 -0
  489. package/lib/api/iam/datasources.d.ts +0 -86
  490. package/lib/api/iam/datasources.js +0 -185
  491. package/lib/components/toolbars/index.d.ts +0 -1
  492. package/lib/models/Datasource.d.ts +0 -181
  493. package/lib/models/Datasource.js +0 -154
  494. package/lib/state/substates/DatasourceState.d.ts +0 -11
  495. package/lib/state/substates/DatasourceState.js +0 -16
  496. /package/lib/{components/toolbars/index.js → api/contents/generated.js} +0 -0
@@ -0,0 +1,891 @@
1
+ /*
2
+ * Copyright (c) 2023-2025 Datalayer, Inc.
3
+ * Distributed under the terms of the Modified BSD License.
4
+ */
5
+ /*
6
+ * Copyright (c) 2023-2026 Datalayer, Inc.
7
+ * Distributed under the terms of the Modified BSD License.
8
+ */
9
+ /**
10
+ * Hooks over the Jupyter MCP Server, IAM's connected agents and the OTEL
11
+ * service, in the `useContents.ts` shape: `enabled` on token and URL,
12
+ * `staleTime` per resource, filters in the query key, mutations that
13
+ * `setQueryData` and invalidate.
14
+ *
15
+ * Polling by predicate: a task refetches every two seconds while it is not
16
+ * terminal and stops when it is; the activity answer every ten seconds as
17
+ * the fallback under the websocket; audit and policy on demand. An open
18
+ * Runs panel subscribes to the task's server-sent events instead.
19
+ *
20
+ * @module hooks/useMcp
21
+ */
22
+ import { useEffect } from 'react';
23
+ import { useMutation, useQueries, useQuery, useQueryClient, } from '@tanstack/react-query';
24
+ import { answerTask, cancelTask, exportAuditEvents, fetchMcpLogs, fetchMcpMetrics, fetchRunTrace, fetchTraceSpans, getEffectivePolicy, getGatewayVersion, getMcpActivity, getOrganizationMcpOverview, getOrganizationMcpUsage, getTask, getWorkflowsHealth, isMcpTaskTerminal, listAuditEvents, listBindings, listNotebookTasks, listTasks, listWorkers, subscribeTaskEvents, terminateBinding, } from '../api/mcp/index.js';
25
+ import { disconnectAgent, disconnectEveryAgent, disconnectEveryAgentInTeam, listConnectedAgents, } from '../api/iam/connectedAgents.js';
26
+ import { listOrganizationTeams, } from '../api/iam/organizationTeams.js';
27
+ import { getAuditSettings, setAuditSettings, } from '../api/iam/mcpAuditSettings.js';
28
+ import { getMcpForwarding } from '../api/mcp/forwarding.js';
29
+ import { testAlertRule } from '../api/mcp/alerts.js';
30
+ import { createAlertRule, deleteAlertRule, listAlertRules, updateAlertRule, } from '../api/iam/mcpAlertRules.js';
31
+ import { createIdentityProvider, deleteIdentityProvider, disableIdentityProvider, enableIdentityProvider, getDomainVerification, listIdentityProviders, updateIdentityProvider, verifyDomain, } from '../api/iam/identityProviders.js';
32
+ import { createScimToken, listScimTokens, revokeScimToken, rotateScimToken, } from '../api/iam/scimTokens.js';
33
+ import { deleteMcpPolicy, getAdmittedClients, getMcpPolicy, setMcpPolicy, } from '../api/iam/mcpPolicy.js';
34
+ import { createServiceAgent, listServiceAgents, revokeServiceAgent, rotateServiceAgentKey, } from '../api/iam/serviceAgents.js';
35
+ import { useCoreStore, useIAMStore } from '../state/index.js';
36
+ import { queryKeys } from './useCache.js';
37
+ const useMcpServerUrl = () => useCoreStore(state => state.configuration.jupyterMcpServerUrl);
38
+ const useIamUrl = () => useCoreStore(state => state.configuration.iamUrl);
39
+ const useOtelUrl = () => useCoreStore(state => state.configuration.otelUrl);
40
+ // -- Tasks -----------------------------------------------------------------
41
+ export const useTasks = (filters = {}, options = {}) => {
42
+ const token = useIAMStore(state => state.token);
43
+ const mcpUrl = useMcpServerUrl();
44
+ return useQuery({
45
+ queryKey: queryKeys.mcp.taskList(filters),
46
+ queryFn: () => listTasks(token ?? '', filters, mcpUrl),
47
+ enabled: Boolean(token && mcpUrl) && (options.enabled ?? true),
48
+ staleTime: 5_000,
49
+ refetchInterval: filters.status && !isMcpTaskTerminal(filters.status) ? 5_000 : false,
50
+ });
51
+ };
52
+ /** One task, polled every two seconds until it is terminal. */
53
+ export const useTask = (taskUid) => {
54
+ const token = useIAMStore(state => state.token);
55
+ const mcpUrl = useMcpServerUrl();
56
+ return useQuery({
57
+ queryKey: queryKeys.mcp.task(taskUid ?? ''),
58
+ queryFn: () => getTask(token ?? '', taskUid, mcpUrl),
59
+ enabled: Boolean(token && mcpUrl && taskUid),
60
+ refetchInterval: query => query.state.data && isMcpTaskTerminal(query.state.data.status)
61
+ ? false
62
+ : 2_000,
63
+ });
64
+ };
65
+ export const useNotebookTasks = (notebookUid, filters = {}) => {
66
+ const token = useIAMStore(state => state.token);
67
+ const mcpUrl = useMcpServerUrl();
68
+ return useQuery({
69
+ queryKey: queryKeys.mcp.notebookTasks(notebookUid ?? '', filters),
70
+ queryFn: () => listNotebookTasks(token ?? '', notebookUid, filters, mcpUrl),
71
+ enabled: Boolean(token && mcpUrl && notebookUid),
72
+ staleTime: 5_000,
73
+ });
74
+ };
75
+ /**
76
+ * The task's server-sent events, patched into the task's cache entry so
77
+ * every `useTask` of it updates without polling. Ends by itself when the
78
+ * task is terminal; the subscription closes with the component.
79
+ */
80
+ export const useTaskEvents = (taskUid, options = {}) => {
81
+ const queryClient = useQueryClient();
82
+ const token = useIAMStore(state => state.token);
83
+ const mcpUrl = useMcpServerUrl();
84
+ const enabled = Boolean(token && mcpUrl && taskUid) && (options.enabled ?? true);
85
+ const { onEvent } = options;
86
+ useEffect(() => {
87
+ if (!enabled) {
88
+ return undefined;
89
+ }
90
+ const close = subscribeTaskEvents(token ?? '', taskUid, {
91
+ onEvent: event => {
92
+ queryClient.setQueryData(queryKeys.mcp.task(taskUid), current => {
93
+ if (event.task) {
94
+ return event.task;
95
+ }
96
+ if (!current) {
97
+ return current;
98
+ }
99
+ return {
100
+ ...current,
101
+ status: event.status ?? current.status,
102
+ statusMessage: event.statusMessage ?? current.statusMessage,
103
+ lastUpdatedAt: event.at ?? current.lastUpdatedAt,
104
+ outputs: event.output
105
+ ? [...(current.outputs ?? []), event.output]
106
+ : current.outputs,
107
+ };
108
+ });
109
+ onEvent?.(event);
110
+ },
111
+ onClose: () => {
112
+ queryClient.invalidateQueries({
113
+ queryKey: queryKeys.mcp.task(taskUid),
114
+ });
115
+ queryClient.invalidateQueries({ queryKey: queryKeys.mcp.tasks() });
116
+ },
117
+ }, mcpUrl);
118
+ return close;
119
+ }, [enabled, token, taskUid, mcpUrl, queryClient, onEvent]);
120
+ };
121
+ export const useCancelTask = () => {
122
+ const queryClient = useQueryClient();
123
+ const token = useIAMStore(state => state.token);
124
+ const mcpUrl = useMcpServerUrl();
125
+ return useMutation({
126
+ mutationFn: taskUid => cancelTask(token ?? '', taskUid, mcpUrl),
127
+ onSuccess: task => {
128
+ queryClient.setQueryData(queryKeys.mcp.task(task.uid), task);
129
+ queryClient.invalidateQueries({ queryKey: queryKeys.mcp.tasks() });
130
+ queryClient.invalidateQueries({ queryKey: queryKeys.mcp.activity() });
131
+ },
132
+ });
133
+ };
134
+ export const useAnswerTask = () => {
135
+ const queryClient = useQueryClient();
136
+ const token = useIAMStore(state => state.token);
137
+ const mcpUrl = useMcpServerUrl();
138
+ return useMutation({
139
+ mutationFn: ({ taskUid, input }) => answerTask(token ?? '', taskUid, { input }, crypto.randomUUID(), mcpUrl),
140
+ onSuccess: task => {
141
+ queryClient.setQueryData(queryKeys.mcp.task(task.uid), task);
142
+ queryClient.invalidateQueries({ queryKey: queryKeys.mcp.tasks() });
143
+ },
144
+ });
145
+ };
146
+ // -- Bindings --------------------------------------------------------------
147
+ export const useBindings = (filters = {}, options = {}) => {
148
+ const token = useIAMStore(state => state.token);
149
+ const mcpUrl = useMcpServerUrl();
150
+ return useQuery({
151
+ queryKey: queryKeys.mcp.bindingList(filters),
152
+ queryFn: () => listBindings(token ?? '', filters, mcpUrl),
153
+ enabled: Boolean(token && mcpUrl) && (options.enabled ?? true),
154
+ staleTime: 10_000,
155
+ });
156
+ };
157
+ export const useTerminateBinding = () => {
158
+ const queryClient = useQueryClient();
159
+ const token = useIAMStore(state => state.token);
160
+ const mcpUrl = useMcpServerUrl();
161
+ return useMutation({
162
+ mutationFn: bindingUid => terminateBinding(token ?? '', bindingUid, mcpUrl),
163
+ onSuccess: () => {
164
+ queryClient.invalidateQueries({ queryKey: queryKeys.mcp.bindings() });
165
+ queryClient.invalidateQueries({ queryKey: queryKeys.mcp.activity() });
166
+ },
167
+ });
168
+ };
169
+ // -- Activity --------------------------------------------------------------
170
+ /**
171
+ * What is going on for the caller, refetched every ten seconds as the
172
+ * fallback under the ai-agents websocket, which patches the same entry.
173
+ */
174
+ export const useMcpActivity = (filters = {}, options = {}) => {
175
+ const token = useIAMStore(state => state.token);
176
+ const mcpUrl = useMcpServerUrl();
177
+ return useQuery({
178
+ queryKey: queryKeys.mcp.activity(filters),
179
+ queryFn: () => getMcpActivity(token ?? '', filters, mcpUrl),
180
+ enabled: Boolean(token && mcpUrl) && (options.enabled ?? true),
181
+ staleTime: 5_000,
182
+ /*
183
+ * A poll that cannot succeed stops polling.
184
+ *
185
+ * `refetchInterval` as a plain number re-arms after *every* settle,
186
+ * failures included — so an endpoint the browser refuses outright (no
187
+ * CORS header, a dead host, a revoked token) turned this into a tight
188
+ * loop: fetch, fail, re-arm, fetch. Each failure is a query state change,
189
+ * and every observer re-rendered on each one, which read as a page
190
+ * repainting on a timer with nothing behind it.
191
+ *
192
+ * As a function it can decline. One error is enough to stand down; a
193
+ * remount, a refocus or a token change starts it again, which is when
194
+ * the answer could genuinely have changed.
195
+ */
196
+ refetchInterval: query => query.state.status === 'error'
197
+ ? false
198
+ : (options.pollIntervalMs ?? 10_000),
199
+ refetchIntervalInBackground: false,
200
+ // One retry, not the default three. The failures worth retrying here are
201
+ // transient; a refused origin is not, and three attempts only make the
202
+ // loop above three times as loud.
203
+ retry: 1,
204
+ /*
205
+ * Re-render for the answer, not for the asking.
206
+ *
207
+ * This polls for as long as the page is open, and by default a query
208
+ * notifies on every observed field — so `isFetching` going true and back
209
+ * again re-rendered every consumer twice a poll, whether or not a single
210
+ * byte had changed. On a dashboard that reads only the data, that is a
211
+ * repaint on a timer with nothing behind it.
212
+ *
213
+ * Structural sharing already keeps `data` referentially stable when the
214
+ * payload is unchanged, so with this the quiet polls cost nothing.
215
+ */
216
+ /*
217
+ * Re-render for the answer, not for the asking.
218
+ *
219
+ * `error` is deliberately absent: this is a background poll, and a
220
+ * consumer that redraws every time it fails is redrawing for something it
221
+ * does not show. `isPending` covers the one transition that matters —
222
+ * nothing yet, then something.
223
+ */
224
+ notifyOnChangeProps: ['data', 'isPending'],
225
+ });
226
+ };
227
+ // -- Audit -----------------------------------------------------------------
228
+ /** One page of the audit log; the cursor is one of the filters, as the URL keeps it. */
229
+ export const useAuditEvents = (filters = {}, options = {}) => {
230
+ const token = useIAMStore(state => state.token);
231
+ const mcpUrl = useMcpServerUrl();
232
+ return useQuery({
233
+ queryKey: queryKeys.mcp.auditList(filters),
234
+ queryFn: () => listAuditEvents(token ?? '', filters, mcpUrl),
235
+ enabled: Boolean(token && mcpUrl) && (options.enabled ?? true),
236
+ staleTime: 30_000,
237
+ placeholderData: previous => previous,
238
+ });
239
+ };
240
+ /** The whole selection as one JSONL or CSV document, on demand. */
241
+ export const useAuditExport = () => {
242
+ const token = useIAMStore(state => state.token);
243
+ const mcpUrl = useMcpServerUrl();
244
+ return useMutation({
245
+ mutationFn: ({ filters = {}, format = 'jsonl' }) => exportAuditEvents(token ?? '', filters, format, mcpUrl),
246
+ });
247
+ };
248
+ // -- Policy ----------------------------------------------------------------
249
+ /** The effective policy for the caller, or previewed as one agent. */
250
+ export const useEffectivePolicy = (agent, filters = {}, options = {}) => {
251
+ const token = useIAMStore(state => state.token);
252
+ const mcpUrl = useMcpServerUrl();
253
+ const policyFilters = { agent, ...filters };
254
+ return useQuery({
255
+ queryKey: queryKeys.mcp.policy(policyFilters),
256
+ queryFn: () => getEffectivePolicy(token ?? '', policyFilters, mcpUrl),
257
+ enabled: Boolean(token && mcpUrl) && (options.enabled ?? true),
258
+ staleTime: 60_000,
259
+ });
260
+ };
261
+ // -- Organizations (the Enterprise console) --------------------------------
262
+ /**
263
+ * The organization's MCP overview, for the console's first page.
264
+ *
265
+ * Read on demand and kept for a minute: an administrator reads it, acts, and
266
+ * comes back — it is not a live pane, and a page that re-asked every ten
267
+ * seconds would cost the gateway three bounded queries for nothing.
268
+ */
269
+ export const useOrgMcpOverview = (orgUid, filters = {}, options = {}) => {
270
+ const token = useIAMStore(state => state.token);
271
+ const mcpUrl = useMcpServerUrl();
272
+ return useQuery({
273
+ queryKey: queryKeys.mcp.orgOverview(orgUid ?? '', filters),
274
+ queryFn: () => getOrganizationMcpOverview(token ?? '', orgUid, filters, mcpUrl),
275
+ enabled: Boolean(token && mcpUrl && orgUid) && (options.enabled ?? true),
276
+ staleTime: 60_000,
277
+ });
278
+ };
279
+ /**
280
+ * The organization's use against its quotas, and which agents spent it.
281
+ *
282
+ * Kept for a minute like the overview, and for the same reason: an
283
+ * administrator reads it, acts, and comes back. A budget that re-asked every
284
+ * ten seconds would cost IAM a ledger query for a number that moves in
285
+ * credits, not in milliseconds.
286
+ */
287
+ export const useOrgMcpUsage = (orgUid, filters = {}, options = {}) => {
288
+ const token = useIAMStore(state => state.token);
289
+ const mcpUrl = useMcpServerUrl();
290
+ return useQuery({
291
+ queryKey: queryKeys.mcp.orgUsage(orgUid ?? '', filters),
292
+ queryFn: () => getOrganizationMcpUsage(token ?? '', orgUid, filters, mcpUrl),
293
+ enabled: Boolean(token && mcpUrl && orgUid) && (options.enabled ?? true),
294
+ staleTime: 60_000,
295
+ });
296
+ };
297
+ // -- Connected agents (IAM) ------------------------------------------------
298
+ export const useConnectedAgents = (options = {}) => {
299
+ const token = useIAMStore(state => state.token);
300
+ const iamUrl = useIamUrl();
301
+ return useQuery({
302
+ queryKey: queryKeys.mcp.connectedAgents(),
303
+ queryFn: () => listConnectedAgents(token ?? '', iamUrl),
304
+ enabled: Boolean(token && iamUrl) && (options.enabled ?? true),
305
+ staleTime: 30_000,
306
+ });
307
+ };
308
+ /** Revoke a grant; the list and the activity are refreshed, never guessed. */
309
+ export const useDisconnectAgent = () => {
310
+ const queryClient = useQueryClient();
311
+ const token = useIAMStore(state => state.token);
312
+ const iamUrl = useIamUrl();
313
+ return useMutation({
314
+ mutationFn: grantUid => disconnectAgent(token ?? '', grantUid, iamUrl),
315
+ onSuccess: () => {
316
+ queryClient.invalidateQueries({
317
+ queryKey: queryKeys.mcp.connectedAgents(),
318
+ });
319
+ queryClient.invalidateQueries({ queryKey: queryKeys.mcp.activity() });
320
+ },
321
+ });
322
+ };
323
+ /**
324
+ * Disconnect every agent of this person — and so force the next
325
+ * authorization through the consent screen.
326
+ *
327
+ * The grant *is* the consent, so there is no separate "ask again" to keep in
328
+ * step: ending them all is what forcing re-consent means.
329
+ */
330
+ export const useDisconnectEveryAgent = () => {
331
+ const queryClient = useQueryClient();
332
+ const token = useIAMStore(state => state.token);
333
+ const iamUrl = useIamUrl();
334
+ return useMutation({
335
+ mutationFn: () => disconnectEveryAgent(token ?? '', iamUrl),
336
+ onSuccess: () => {
337
+ queryClient.invalidateQueries({
338
+ queryKey: queryKeys.mcp.connectedAgents(),
339
+ });
340
+ queryClient.invalidateQueries({ queryKey: queryKeys.mcp.activity() });
341
+ },
342
+ });
343
+ };
344
+ /** The same for one team's agents, for whoever may manage that team. */
345
+ export const useDisconnectEveryAgentInTeam = () => {
346
+ const queryClient = useQueryClient();
347
+ const token = useIAMStore(state => state.token);
348
+ const iamUrl = useIamUrl();
349
+ return useMutation({
350
+ mutationFn: teamUid => disconnectEveryAgentInTeam(token ?? '', teamUid, iamUrl),
351
+ onSuccess: () => {
352
+ queryClient.invalidateQueries({
353
+ queryKey: queryKeys.mcp.connectedAgents(),
354
+ });
355
+ queryClient.invalidateQueries({ queryKey: queryKeys.mcp.activity() });
356
+ },
357
+ });
358
+ };
359
+ // -- Teams (IAM) ------------------------------------------------------------
360
+ /** One organization's teams, for the console's team policy page. */
361
+ export const useOrganizationTeams = (orgUid, options = {}) => {
362
+ const token = useIAMStore(state => state.token);
363
+ const iamUrl = useIamUrl();
364
+ return useQuery({
365
+ queryKey: queryKeys.mcp.organizationTeams(orgUid),
366
+ queryFn: () => listOrganizationTeams(token ?? '', orgUid, iamUrl),
367
+ enabled: Boolean(token && iamUrl && orgUid) && (options.enabled ?? true),
368
+ staleTime: 60_000,
369
+ });
370
+ };
371
+ /**
372
+ * Whether the audit is reaching the organization's own system of record.
373
+ *
374
+ * Polled rather than read once: a destination that stops answering does so
375
+ * while somebody is looking at the page, and the point of the panel is to
376
+ * say when that happens.
377
+ */
378
+ export const useMcpForwarding = (org = '', options = {}) => {
379
+ const token = useIAMStore(state => state.token);
380
+ const mcpUrl = useMcpServerUrl();
381
+ return useQuery({
382
+ queryKey: queryKeys.mcp.forwarding(org),
383
+ queryFn: () => getMcpForwarding(token ?? '', org, mcpUrl),
384
+ enabled: Boolean(token && mcpUrl) && (options.enabled ?? true),
385
+ staleTime: 30_000,
386
+ refetchInterval: 60_000,
387
+ });
388
+ };
389
+ // -- Audit settings: retention, forwarding, alert destinations (IAM) --------
390
+ /** One organization's settings, or `null` where it has decided nothing. */
391
+ export const useAuditSettings = (orgUid, options = {}) => {
392
+ const token = useIAMStore(state => state.token);
393
+ const iamUrl = useIamUrl();
394
+ return useQuery({
395
+ queryKey: queryKeys.mcp.auditSettings(orgUid),
396
+ queryFn: () => getAuditSettings(token ?? '', orgUid, iamUrl),
397
+ enabled: Boolean(token && iamUrl && orgUid) && (options.enabled ?? true),
398
+ staleTime: 30_000,
399
+ });
400
+ };
401
+ /**
402
+ * Change some of them. Only what is passed is sent, because IAM merges: a
403
+ * page editing the alert destinations must not clear a retention it never
404
+ * showed.
405
+ */
406
+ export const useSetAuditSettings = (orgUid) => {
407
+ const queryClient = useQueryClient();
408
+ const token = useIAMStore(state => state.token);
409
+ const iamUrl = useIamUrl();
410
+ return useMutation({
411
+ mutationFn: ({ settings, expectedVersion }) => setAuditSettings(token ?? '', orgUid, settings, { expectedVersion }, iamUrl),
412
+ onSuccess: () => {
413
+ queryClient.invalidateQueries({
414
+ queryKey: queryKeys.mcp.auditSettings(orgUid),
415
+ });
416
+ },
417
+ });
418
+ };
419
+ /**
420
+ * Try a rule against current values.
421
+ *
422
+ * A mutation rather than a query: it is something somebody asks for, once,
423
+ * by pressing a button — and caching "what does this see now" would answer
424
+ * the second press with the first press's numbers.
425
+ */
426
+ export const useTestAlertRule = () => {
427
+ const token = useIAMStore(state => state.token);
428
+ const mcpUrl = useMcpServerUrl();
429
+ return useMutation({
430
+ mutationFn: rule => testAlertRule(token ?? '', rule, mcpUrl),
431
+ });
432
+ };
433
+ // -- Alert rules (IAM) ------------------------------------------------------
434
+ /** One organization's alert rules, disabled ones included. */
435
+ export const useAlertRules = (orgUid, options = {}) => {
436
+ const token = useIAMStore(state => state.token);
437
+ const iamUrl = useIamUrl();
438
+ return useQuery({
439
+ queryKey: queryKeys.mcp.alertRules(orgUid),
440
+ queryFn: () => listAlertRules(token ?? '', orgUid, iamUrl),
441
+ enabled: Boolean(token && iamUrl && orgUid) && (options.enabled ?? true),
442
+ staleTime: 30_000,
443
+ });
444
+ };
445
+ export const useCreateAlertRule = (orgUid) => {
446
+ const queryClient = useQueryClient();
447
+ const token = useIAMStore(state => state.token);
448
+ const iamUrl = useIamUrl();
449
+ return useMutation({
450
+ mutationFn: rule => createAlertRule(token ?? '', orgUid, rule, iamUrl),
451
+ onSuccess: () => {
452
+ queryClient.invalidateQueries({
453
+ queryKey: queryKeys.mcp.alertRules(orgUid),
454
+ });
455
+ },
456
+ });
457
+ };
458
+ export const useUpdateAlertRule = (orgUid) => {
459
+ const queryClient = useQueryClient();
460
+ const token = useIAMStore(state => state.token);
461
+ const iamUrl = useIamUrl();
462
+ return useMutation({
463
+ mutationFn: ({ uid, rule }) => updateAlertRule(token ?? '', orgUid, uid, rule, iamUrl),
464
+ onSuccess: () => {
465
+ queryClient.invalidateQueries({
466
+ queryKey: queryKeys.mcp.alertRules(orgUid),
467
+ });
468
+ },
469
+ });
470
+ };
471
+ export const useDeleteAlertRule = (orgUid) => {
472
+ const queryClient = useQueryClient();
473
+ const token = useIAMStore(state => state.token);
474
+ const iamUrl = useIamUrl();
475
+ return useMutation({
476
+ mutationFn: uid => deleteAlertRule(token ?? '', orgUid, uid, iamUrl),
477
+ onSuccess: () => {
478
+ queryClient.invalidateQueries({
479
+ queryKey: queryKeys.mcp.alertRules(orgUid),
480
+ });
481
+ },
482
+ });
483
+ };
484
+ // -- Identity providers (IAM) -----------------------------------------------
485
+ /** One organization's identity providers, disabled ones included. */
486
+ export const useIdentityProviders = (orgUid, options = {}) => {
487
+ const token = useIAMStore(state => state.token);
488
+ const iamUrl = useIamUrl();
489
+ return useQuery({
490
+ queryKey: queryKeys.mcp.identityProviders(orgUid),
491
+ queryFn: () => listIdentityProviders(token ?? '', orgUid, iamUrl),
492
+ enabled: Boolean(token && iamUrl && orgUid) && (options.enabled ?? true),
493
+ staleTime: 30_000,
494
+ });
495
+ };
496
+ export const useCreateIdentityProvider = (orgUid) => {
497
+ const queryClient = useQueryClient();
498
+ const token = useIAMStore(state => state.token);
499
+ const iamUrl = useIamUrl();
500
+ return useMutation({
501
+ mutationFn: provider => createIdentityProvider(token ?? '', orgUid, provider, iamUrl),
502
+ onSuccess: () => {
503
+ queryClient.invalidateQueries({
504
+ queryKey: queryKeys.mcp.identityProviders(orgUid),
505
+ });
506
+ },
507
+ });
508
+ };
509
+ export const useUpdateIdentityProvider = (orgUid) => {
510
+ const queryClient = useQueryClient();
511
+ const token = useIAMStore(state => state.token);
512
+ const iamUrl = useIamUrl();
513
+ return useMutation({
514
+ mutationFn: ({ uid, provider }) => updateIdentityProvider(token ?? '', orgUid, uid, provider, iamUrl),
515
+ onSuccess: () => {
516
+ queryClient.invalidateQueries({
517
+ queryKey: queryKeys.mcp.identityProviders(orgUid),
518
+ });
519
+ },
520
+ });
521
+ };
522
+ export const useSetIdentityProviderEnabled = (orgUid) => {
523
+ const queryClient = useQueryClient();
524
+ const token = useIAMStore(state => state.token);
525
+ const iamUrl = useIamUrl();
526
+ return useMutation({
527
+ mutationFn: ({ uid, enabled }) => enabled
528
+ ? enableIdentityProvider(token ?? '', orgUid, uid, iamUrl)
529
+ : disableIdentityProvider(token ?? '', orgUid, uid, iamUrl),
530
+ onSuccess: () => {
531
+ queryClient.invalidateQueries({
532
+ queryKey: queryKeys.mcp.identityProviders(orgUid),
533
+ });
534
+ },
535
+ });
536
+ };
537
+ /**
538
+ * What one layer's `allowedClients` entries actually name.
539
+ *
540
+ * Deliberately *not* folded into `useMcpPolicyLayer`. That query is read
541
+ * whenever a policy form mounts; this one may make the server fetch a client
542
+ * document per entry, and an editor typing in a textarea must not set that
543
+ * off on every keystroke — so it is fetched from what is **stored**, and goes
544
+ * stale until the draft is saved.
545
+ */
546
+ export const useAdmittedClients = (scope, subjectUid, options = {}) => {
547
+ const token = useIAMStore(state => state.token);
548
+ const iamUrl = useIamUrl();
549
+ return useQuery({
550
+ queryKey: queryKeys.mcp.admittedClients(scope, subjectUid),
551
+ queryFn: () => getAdmittedClients(token ?? '', scope, subjectUid, iamUrl),
552
+ enabled: Boolean(token && iamUrl && subjectUid) && (options.enabled ?? true),
553
+ // Longer than the policy layer's: a client document is cached by the
554
+ // server for as long as its own headers say, and re-asking on every
555
+ // focus would make a console page a source of outbound traffic.
556
+ staleTime: 300_000,
557
+ });
558
+ };
559
+ // -- SCIM provisioning credentials (IAM) ------------------------------------
560
+ /**
561
+ * One organization's SCIM tokens, revoked ones included.
562
+ *
563
+ * Revoked ones are *not* filtered out here. A console that hid them would
564
+ * make an organization whose every token is revoked look identical to one
565
+ * that never had any — and those are different problems with different
566
+ * fixes, only one of which is "nobody is being deprovisioned right now".
567
+ */
568
+ export const useScimTokens = (orgUid, options = {}) => {
569
+ const token = useIAMStore(state => state.token);
570
+ const iamUrl = useIamUrl();
571
+ return useQuery({
572
+ queryKey: queryKeys.mcp.scimTokens(orgUid),
573
+ queryFn: () => listScimTokens(token ?? '', orgUid, iamUrl),
574
+ enabled: Boolean(token && iamUrl && orgUid) && (options.enabled ?? true),
575
+ staleTime: 30_000,
576
+ });
577
+ };
578
+ /**
579
+ * Mint one. The secret is in the result and nowhere else, ever again.
580
+ *
581
+ * The mutation result is deliberately not written into the query cache: a
582
+ * secret that lived in a cache would be re-rendered on every refetch of the
583
+ * list, and outlive the dialog it was shown in.
584
+ */
585
+ export const useCreateScimToken = (orgUid) => {
586
+ const queryClient = useQueryClient();
587
+ const token = useIAMStore(state => state.token);
588
+ const iamUrl = useIamUrl();
589
+ return useMutation({
590
+ mutationFn: name => createScimToken(token ?? '', orgUid, name, iamUrl),
591
+ onSuccess: () => {
592
+ queryClient.invalidateQueries({
593
+ queryKey: queryKeys.mcp.scimTokens(orgUid),
594
+ });
595
+ },
596
+ });
597
+ };
598
+ export const useRotateScimToken = (orgUid) => {
599
+ const queryClient = useQueryClient();
600
+ const token = useIAMStore(state => state.token);
601
+ const iamUrl = useIamUrl();
602
+ return useMutation({
603
+ mutationFn: uid => rotateScimToken(token ?? '', orgUid, uid, iamUrl),
604
+ onSuccess: () => {
605
+ queryClient.invalidateQueries({
606
+ queryKey: queryKeys.mcp.scimTokens(orgUid),
607
+ });
608
+ },
609
+ });
610
+ };
611
+ export const useRevokeScimToken = (orgUid) => {
612
+ const queryClient = useQueryClient();
613
+ const token = useIAMStore(state => state.token);
614
+ const iamUrl = useIamUrl();
615
+ return useMutation({
616
+ mutationFn: uid => revokeScimToken(token ?? '', orgUid, uid, iamUrl),
617
+ onSuccess: () => {
618
+ queryClient.invalidateQueries({
619
+ queryKey: queryKeys.mcp.scimTokens(orgUid),
620
+ });
621
+ },
622
+ });
623
+ };
624
+ export const useDeleteIdentityProvider = (orgUid) => {
625
+ const queryClient = useQueryClient();
626
+ const token = useIAMStore(state => state.token);
627
+ const iamUrl = useIamUrl();
628
+ return useMutation({
629
+ mutationFn: uid => deleteIdentityProvider(token ?? '', orgUid, uid, iamUrl),
630
+ onSuccess: () => {
631
+ queryClient.invalidateQueries({
632
+ queryKey: queryKeys.mcp.identityProviders(orgUid),
633
+ });
634
+ },
635
+ });
636
+ };
637
+ /**
638
+ * What to publish in DNS, fetched on demand rather than kept fresh.
639
+ *
640
+ * A mutation, not a query with a `refetch`: this is asked for once when
641
+ * somebody opens the verification panel, and the value never changes for a
642
+ * given provider and domain — what changes is `verified`, which the
643
+ * `verify` call below answers directly from the provider it returns.
644
+ */
645
+ export const useDomainVerification = (orgUid) => {
646
+ const token = useIAMStore(state => state.token);
647
+ const iamUrl = useIamUrl();
648
+ return useMutation({
649
+ mutationFn: ({ uid, domain }) => getDomainVerification(token ?? '', orgUid, uid, domain, iamUrl),
650
+ });
651
+ };
652
+ export const useVerifyDomain = (orgUid) => {
653
+ const queryClient = useQueryClient();
654
+ const token = useIAMStore(state => state.token);
655
+ const iamUrl = useIamUrl();
656
+ return useMutation({
657
+ mutationFn: ({ uid, domain }) => verifyDomain(token ?? '', orgUid, uid, domain, iamUrl),
658
+ onSuccess: () => {
659
+ queryClient.invalidateQueries({
660
+ queryKey: queryKeys.mcp.identityProviders(orgUid),
661
+ });
662
+ },
663
+ });
664
+ };
665
+ // -- The policy layer IAM stores (IAM) -------------------------------------
666
+ /**
667
+ * One layer's rules, or `null` where nobody has written one.
668
+ *
669
+ * `null` is a real answer and not an error: most organizations have never
670
+ * written a policy, and a form needs to tell "narrows nothing" from "does
671
+ * not exist" — only the second has nothing to remove.
672
+ */
673
+ export const useMcpPolicyLayer = (scope, subjectUid, options = {}) => {
674
+ const token = useIAMStore(state => state.token);
675
+ const iamUrl = useIamUrl();
676
+ return useQuery({
677
+ queryKey: queryKeys.mcp.policyLayer(scope, subjectUid),
678
+ queryFn: () => getMcpPolicy(token ?? '', scope, subjectUid, iamUrl),
679
+ enabled: Boolean(token && iamUrl && subjectUid) && (options.enabled ?? true),
680
+ staleTime: 30_000,
681
+ });
682
+ };
683
+ /**
684
+ * Several layers at once, for a page that has to compare against them all.
685
+ *
686
+ * The personal policy page needs every organization a person belongs to in
687
+ * order to say which of their values will have no effect. One hook per
688
+ * organization is not something a component can do — the count changes — so
689
+ * they are fetched together and answered in the order asked.
690
+ *
691
+ * A layer that could not be read comes back `null`, the same as one nobody
692
+ * has written. That is the safe direction here: the page would rather say
693
+ * nothing about narrowing than invent a cap somebody does not have.
694
+ */
695
+ export const useMcpPolicyLayers = (scope, subjectUids) => {
696
+ const token = useIAMStore(state => state.token);
697
+ const iamUrl = useIamUrl();
698
+ return useQueries({
699
+ queries: subjectUids.map(subjectUid => ({
700
+ queryKey: queryKeys.mcp.policyLayer(scope, subjectUid),
701
+ queryFn: () => getMcpPolicy(token ?? '', scope, subjectUid, iamUrl),
702
+ enabled: Boolean(token && iamUrl && subjectUid),
703
+ staleTime: 30_000,
704
+ })),
705
+ });
706
+ };
707
+ /**
708
+ * Replace one layer's rules.
709
+ *
710
+ * The **effective** policy is invalidated alongside the layer: the two are
711
+ * the same fact read two ways, and a page still showing the old effective
712
+ * policy after a write is a page saying the change did not take.
713
+ */
714
+ export const useSetMcpPolicyLayer = (scope, subjectUid) => {
715
+ const queryClient = useQueryClient();
716
+ const token = useIAMStore(state => state.token);
717
+ const iamUrl = useIamUrl();
718
+ return useMutation({
719
+ mutationFn: ({ rules, expectedVersion }) => setMcpPolicy(token ?? '', scope, subjectUid, rules, { expectedVersion }, iamUrl),
720
+ onSuccess: () => {
721
+ queryClient.invalidateQueries({
722
+ queryKey: queryKeys.mcp.policyLayer(scope, subjectUid),
723
+ });
724
+ queryClient.invalidateQueries({ queryKey: queryKeys.mcp.policy() });
725
+ },
726
+ });
727
+ };
728
+ /** Remove one layer, so it narrows nothing again. */
729
+ export const useDeleteMcpPolicyLayer = (scope, subjectUid) => {
730
+ const queryClient = useQueryClient();
731
+ const token = useIAMStore(state => state.token);
732
+ const iamUrl = useIamUrl();
733
+ return useMutation({
734
+ mutationFn: () => deleteMcpPolicy(token ?? '', scope, subjectUid, iamUrl),
735
+ onSuccess: () => {
736
+ queryClient.invalidateQueries({
737
+ queryKey: queryKeys.mcp.policyLayer(scope, subjectUid),
738
+ });
739
+ queryClient.invalidateQueries({ queryKey: queryKeys.mcp.policy() });
740
+ },
741
+ });
742
+ };
743
+ // -- Service agents (IAM) --------------------------------------------------
744
+ /**
745
+ * One organization's service agents, revoked ones included.
746
+ *
747
+ * Keyed by the organization: two organizations' lists must never share a
748
+ * cache entry, or an owner of both would see one under the other's name.
749
+ */
750
+ export const useServiceAgents = (orgUid, options = {}) => {
751
+ const token = useIAMStore(state => state.token);
752
+ const iamUrl = useIamUrl();
753
+ return useQuery({
754
+ queryKey: queryKeys.mcp.serviceAgents(orgUid),
755
+ queryFn: () => listServiceAgents(token ?? '', orgUid, iamUrl),
756
+ enabled: Boolean(token && iamUrl && orgUid) && (options.enabled ?? true),
757
+ staleTime: 30_000,
758
+ });
759
+ };
760
+ /**
761
+ * Create one. The answer carries the key, and it is the only place it
762
+ * exists — so the caller must render it before doing anything else with it.
763
+ */
764
+ export const useCreateServiceAgent = (orgUid) => {
765
+ const queryClient = useQueryClient();
766
+ const token = useIAMStore(state => state.token);
767
+ const iamUrl = useIamUrl();
768
+ return useMutation({
769
+ mutationFn: agent => createServiceAgent(token ?? '', orgUid, agent, iamUrl),
770
+ onSuccess: () => {
771
+ queryClient.invalidateQueries({
772
+ queryKey: queryKeys.mcp.serviceAgents(orgUid),
773
+ });
774
+ },
775
+ });
776
+ };
777
+ /** Replace an agent's key; the old one stops working with the call. */
778
+ export const useRotateServiceAgentKey = (orgUid) => {
779
+ const queryClient = useQueryClient();
780
+ const token = useIAMStore(state => state.token);
781
+ const iamUrl = useIamUrl();
782
+ return useMutation({
783
+ mutationFn: agentUid => rotateServiceAgentKey(token ?? '', orgUid, agentUid, iamUrl),
784
+ onSuccess: () => {
785
+ queryClient.invalidateQueries({
786
+ queryKey: queryKeys.mcp.serviceAgents(orgUid),
787
+ });
788
+ },
789
+ });
790
+ };
791
+ /** Stop an agent. The list is refetched rather than edited in place. */
792
+ export const useRevokeServiceAgent = (orgUid) => {
793
+ const queryClient = useQueryClient();
794
+ const token = useIAMStore(state => state.token);
795
+ const iamUrl = useIamUrl();
796
+ return useMutation({
797
+ mutationFn: agentUid => revokeServiceAgent(token ?? '', orgUid, agentUid, iamUrl),
798
+ onSuccess: () => {
799
+ queryClient.invalidateQueries({
800
+ queryKey: queryKeys.mcp.serviceAgents(orgUid),
801
+ });
802
+ },
803
+ });
804
+ };
805
+ // -- Observability (OTEL) --------------------------------------------------
806
+ /** The spans of a run, from the task's trace id; asked again while the task runs. */
807
+ export const useRunTrace = (taskUid, options = {}) => {
808
+ const token = useIAMStore(state => state.token);
809
+ const otelUrl = useOtelUrl();
810
+ const task = useTask(taskUid);
811
+ return useQuery({
812
+ queryKey: queryKeys.mcp.trace(taskUid ?? ''),
813
+ queryFn: () => fetchRunTrace(token ?? '', task.data, otelUrl),
814
+ enabled: Boolean(token && otelUrl && task.data) && (options.enabled ?? true),
815
+ staleTime: 15_000,
816
+ refetchInterval: task.data && !isMcpTaskTerminal(task.data.status) ? 5_000 : false,
817
+ });
818
+ };
819
+ /**
820
+ * The spans of one trace, for a call that finished inside its own request.
821
+ *
822
+ * Read once and kept: a finished trace does not change, and the pane that
823
+ * shows it is opened from an audit row rather than watched.
824
+ */
825
+ export const useMcpTrace = (traceId, options = {}) => {
826
+ const token = useIAMStore(state => state.token);
827
+ const otelUrl = useOtelUrl();
828
+ return useQuery({
829
+ queryKey: queryKeys.mcp.traceById(traceId ?? ''),
830
+ queryFn: () => fetchTraceSpans(token ?? '', traceId, otelUrl),
831
+ enabled: Boolean(token && otelUrl && traceId) && (options.enabled ?? true),
832
+ staleTime: 60_000,
833
+ });
834
+ };
835
+ /** The four SLIs and the catalog, platform-wide or for one agent or organization. */
836
+ export const useMcpMetrics = (filters = {}, options = {}) => {
837
+ const token = useIAMStore(state => state.token);
838
+ const otelUrl = useOtelUrl();
839
+ return useQuery({
840
+ queryKey: queryKeys.mcp.metrics(filters),
841
+ queryFn: () => fetchMcpMetrics(token ?? '', filters, otelUrl),
842
+ enabled: Boolean(token && otelUrl) && (options.enabled ?? true),
843
+ staleTime: 30_000,
844
+ });
845
+ };
846
+ /** The log lines of a run, gateway and worker alike, by its trace. */
847
+ export const useMcpLogs = (taskUid, options = {}) => {
848
+ const token = useIAMStore(state => state.token);
849
+ const otelUrl = useOtelUrl();
850
+ const task = useTask(taskUid);
851
+ return useQuery({
852
+ queryKey: queryKeys.mcp.logs(taskUid ?? ''),
853
+ queryFn: () => fetchMcpLogs(token ?? '', task.data, { limit: options.limit, severity: options.severity }, otelUrl),
854
+ enabled: Boolean(token && otelUrl && task.data) && (options.enabled ?? true),
855
+ staleTime: 15_000,
856
+ refetchInterval: task.data && !isMcpTaskTerminal(task.data.status) ? 5_000 : false,
857
+ });
858
+ };
859
+ // -- Operations (platform administrators) ----------------------------------
860
+ export const useMcpWorkers = (options = {}) => {
861
+ const token = useIAMStore(state => state.token);
862
+ const mcpUrl = useMcpServerUrl();
863
+ return useQuery({
864
+ queryKey: queryKeys.mcp.workers(),
865
+ queryFn: () => listWorkers(token ?? '', mcpUrl),
866
+ enabled: Boolean(token && mcpUrl) && (options.enabled ?? true),
867
+ staleTime: 5_000,
868
+ refetchInterval: 10_000,
869
+ });
870
+ };
871
+ export const useMcpWorkflowsHealth = (options = {}) => {
872
+ const token = useIAMStore(state => state.token);
873
+ const mcpUrl = useMcpServerUrl();
874
+ return useQuery({
875
+ queryKey: queryKeys.mcp.workflows(),
876
+ queryFn: () => getWorkflowsHealth(token ?? '', mcpUrl),
877
+ enabled: Boolean(token && mcpUrl) && (options.enabled ?? true),
878
+ staleTime: 10_000,
879
+ refetchInterval: 30_000,
880
+ });
881
+ };
882
+ /** The gateway's version and resource; no token needed. */
883
+ export const useMcpGatewayVersion = () => {
884
+ const mcpUrl = useMcpServerUrl();
885
+ return useQuery({
886
+ queryKey: queryKeys.mcp.gatewayVersion(),
887
+ queryFn: () => getGatewayVersion(mcpUrl),
888
+ enabled: Boolean(mcpUrl),
889
+ staleTime: 300_000,
890
+ });
891
+ };