@datalayer/core 1.1.59 → 1.1.66

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 (366) hide show
  1. package/README.md +2 -2
  2. package/lib/api/DatalayerApi.d.ts +42 -1
  3. package/lib/api/DatalayerApi.js +90 -3
  4. package/lib/api/constants.d.ts +18 -0
  5. package/lib/api/constants.js +18 -0
  6. package/lib/api/contents/attachments.d.ts +9 -0
  7. package/lib/api/contents/attachments.js +43 -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 +15 -0
  17. package/lib/api/contents/datasets.js +45 -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 +53 -0
  32. package/lib/api/contents/sandboxUid.js +78 -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/iam/connectedAgents.d.ts +39 -0
  40. package/lib/api/iam/connectedAgents.js +52 -0
  41. package/lib/api/iam/index.d.ts +2 -1
  42. package/lib/api/iam/index.js +2 -1
  43. package/lib/api/iam/mcpAlertRules.d.ts +51 -0
  44. package/lib/api/iam/mcpAlertRules.js +198 -0
  45. package/lib/api/iam/mcpAuditSettings.d.ts +46 -0
  46. package/lib/api/iam/mcpAuditSettings.js +120 -0
  47. package/lib/api/iam/mcpPolicy.d.ts +80 -0
  48. package/lib/api/iam/mcpPolicy.js +132 -0
  49. package/lib/api/iam/organizationTeams.d.ts +13 -0
  50. package/lib/api/iam/organizationTeams.js +43 -0
  51. package/lib/api/iam/serviceAgents.d.ts +68 -0
  52. package/lib/api/iam/serviceAgents.js +119 -0
  53. package/lib/api/index.d.ts +4 -1
  54. package/lib/api/index.js +3 -1
  55. package/lib/api/mcp/activity.d.ts +37 -0
  56. package/lib/api/mcp/activity.js +26 -0
  57. package/lib/api/mcp/alerts.d.ts +25 -0
  58. package/lib/api/mcp/alerts.js +51 -0
  59. package/lib/api/mcp/audit.d.ts +29 -0
  60. package/lib/api/mcp/audit.js +55 -0
  61. package/lib/api/mcp/bindings.d.ts +18 -0
  62. package/lib/api/mcp/bindings.js +42 -0
  63. package/lib/api/mcp/forwarding.d.ts +25 -0
  64. package/lib/api/mcp/forwarding.js +46 -0
  65. package/lib/api/mcp/gateway.d.ts +16 -0
  66. package/lib/api/mcp/gateway.js +70 -0
  67. package/lib/api/mcp/generated.d.ts +22 -0
  68. package/lib/api/mcp/generated.js +213 -0
  69. package/lib/api/mcp/index.d.ts +17 -0
  70. package/lib/api/mcp/index.js +25 -0
  71. package/lib/api/mcp/observability.d.ts +125 -0
  72. package/lib/api/mcp/observability.js +254 -0
  73. package/lib/api/mcp/operations.d.ts +83 -0
  74. package/lib/api/mcp/operations.js +50 -0
  75. package/lib/api/mcp/organizations.d.ts +102 -0
  76. package/lib/api/mcp/organizations.js +46 -0
  77. package/lib/api/mcp/policy.d.ts +9 -0
  78. package/lib/api/mcp/policy.js +23 -0
  79. package/lib/api/mcp/tasks.d.ts +49 -0
  80. package/lib/api/mcp/tasks.js +147 -0
  81. package/lib/api/utils/validation.d.ts +1 -1
  82. package/lib/api/utils/validation.js +1 -1
  83. package/lib/client/auth/index.js +0 -5
  84. package/lib/client/auth/storage.js +0 -5
  85. package/lib/client/auth/strategies.js +0 -5
  86. package/lib/client/base.d.ts +6 -0
  87. package/lib/client/base.js +8 -0
  88. package/lib/client/index.d.ts +0 -10
  89. package/lib/client/index.js +2 -2
  90. package/lib/client/mixins/ContentsMixin.d.ts +71 -0
  91. package/lib/client/mixins/ContentsMixin.js +157 -0
  92. package/lib/client/mixins/IAMMixin.d.ts +0 -31
  93. package/lib/client/mixins/IAMMixin.js +0 -58
  94. package/lib/components/animation/AnimatedText.d.ts +1 -0
  95. package/lib/components/animation/AnimatedText.js +0 -4
  96. package/lib/components/auth/SigInAPIKey.d.ts +1 -0
  97. package/lib/components/auth/SigInAPIKey.js +0 -6
  98. package/lib/components/auth/SignIn.d.ts +1 -0
  99. package/lib/components/auth/SignIn.js +0 -4
  100. package/lib/components/auth/SignIn.stories.d.ts +2 -2
  101. package/lib/components/avatars/BoringAvatar.d.ts +1 -1
  102. package/lib/components/avatars/BoringAvatar.stories.d.ts +1 -1
  103. package/lib/components/avatars/DLAvatar.d.ts +1 -1
  104. package/lib/components/avatars/DLAvatar.js +0 -4
  105. package/lib/components/avatars/UserAvatar.d.ts +18 -1
  106. package/lib/components/avatars/UserAvatar.js +14 -14
  107. package/lib/components/avatars/UserProfileAvatar.d.ts +1 -1
  108. package/lib/components/banners/NoAutomationBanner.d.ts +1 -1
  109. package/lib/components/billing/BillingEntitySelect.d.ts +10 -0
  110. package/lib/components/billing/BillingEntitySelect.js +0 -17
  111. package/lib/components/billing/index.js +0 -4
  112. package/lib/components/buttons/DownloadCSVButton.d.ts +1 -1
  113. package/lib/components/buttons/DownloadJsonButton.d.ts +1 -1
  114. package/lib/components/buttons/LongActionButton.d.ts +1 -0
  115. package/lib/components/buttons/LongActionButton.js +0 -4
  116. package/lib/components/buttons/UploadButton.d.ts +1 -0
  117. package/lib/components/buttons/UploadButton.js +0 -4
  118. package/lib/components/checkout/StripeCheckout.d.ts +1 -1
  119. package/lib/components/collaboration/LiveEditorCollaborators.d.ts +31 -0
  120. package/lib/components/collaboration/LiveEditorCollaborators.js +98 -53
  121. package/lib/components/collaboration/index.js +0 -4
  122. package/lib/components/confetti/ConfettiSuccess.d.ts +1 -1
  123. package/lib/components/contents/ContentSourceCard.d.ts +8 -0
  124. package/lib/components/contents/ContentSourceCard.js +23 -0
  125. package/lib/components/contents/HomeFolderObjectsBrowser.d.ts +10 -0
  126. package/lib/components/contents/HomeFolderObjectsBrowser.js +148 -0
  127. package/lib/components/contents/index.d.ts +2 -0
  128. package/lib/components/contents/index.js +6 -0
  129. package/lib/components/context/OrganizationSelect.d.ts +1 -1
  130. package/lib/components/display/AvatarSkeleton.d.ts +1 -1
  131. package/lib/components/display/BusyDots.d.ts +1 -1
  132. package/lib/components/display/CenteredSpinner.d.ts +1 -1
  133. package/lib/components/display/CodePreview.d.ts +1 -1
  134. package/lib/components/display/DatalayerBox.d.ts +7 -2
  135. package/lib/components/display/DatalayerBox.js +6 -6
  136. package/lib/components/display/HorizontalCenter.d.ts +1 -1
  137. package/lib/components/display/JupyterDialog.d.ts +1 -0
  138. package/lib/components/display/JupyterDialog.js +1 -7
  139. package/lib/components/display/Markdown.d.ts +1 -0
  140. package/lib/components/display/NotebookSkeleton.d.ts +1 -1
  141. package/lib/components/display/Placeholder.d.ts +1 -1
  142. package/lib/components/display/ToTopBranded.d.ts +1 -1
  143. package/lib/components/echarts/EChartsReact.d.ts +1 -1
  144. package/lib/components/flashes/FlashClosable.d.ts +1 -0
  145. package/lib/components/flashes/FlashClosable.js +0 -4
  146. package/lib/components/flashes/FlashGuest.d.ts +1 -1
  147. package/lib/components/flashes/FlashSurveys.d.ts +1 -1
  148. package/lib/components/flashes/FlashUnauthorized.d.ts +1 -0
  149. package/lib/components/flashes/FlashUnauthorized.js +0 -6
  150. package/lib/components/flashes/surveys/Survey2025_1.d.ts +1 -1
  151. package/lib/components/iam/ExternalTokenSilentLogin.d.ts +1 -1
  152. package/lib/components/index.d.ts +2 -0
  153. package/lib/components/index.js +2 -0
  154. package/lib/components/labels/StatusLabels.d.ts +10 -0
  155. package/lib/components/labels/StatusLabels.js +30 -1
  156. package/lib/components/labels/VisibilityLabel.d.ts +1 -1
  157. package/lib/components/landings/StepBlock.d.ts +1 -1
  158. package/lib/components/mcp/ClientBadge.d.ts +41 -0
  159. package/lib/components/mcp/ClientBadge.js +33 -0
  160. package/lib/components/mcp/McpErrorBlankslate.d.ts +21 -0
  161. package/lib/components/mcp/McpErrorBlankslate.js +17 -0
  162. package/lib/components/mcp/ScopeList.d.ts +28 -0
  163. package/lib/components/mcp/ScopeList.js +14 -0
  164. package/lib/components/mcp/index.d.ts +10 -0
  165. package/lib/components/mcp/index.js +18 -0
  166. package/lib/components/navbar/NavigationVisbilityObserver.d.ts +2 -1
  167. package/lib/components/navbar/SubdomainNavBar.d.ts +10 -5
  168. package/lib/components/navbar/SubdomainNavBar.js +2 -1
  169. package/lib/components/notebooks/JupyterNotebook.d.ts +1 -1
  170. package/lib/components/notebooks/JupyterNotebookToolbar.d.ts +1 -1
  171. package/lib/components/principal/PrincipalAppearance.d.ts +1 -0
  172. package/lib/components/principal/PrincipalAppearance.js +0 -8
  173. package/lib/components/principal/PrincipalAvatar.d.ts +9 -1
  174. package/lib/components/principal/PrincipalAvatar.js +25 -10
  175. package/lib/components/principal/PrincipalBadge.d.ts +1 -1
  176. package/lib/components/principal/PrincipalBanner.d.ts +1 -1
  177. package/lib/components/principal/PrincipalDetailsOverlay.d.ts +31 -1
  178. package/lib/components/principal/PrincipalDetailsOverlay.js +64 -33
  179. package/lib/components/principal/PrincipalHoverCard.d.ts +31 -0
  180. package/lib/components/principal/PrincipalHoverCard.js +52 -0
  181. package/lib/components/principal/PrincipalSwitcherMenu.d.ts +1 -0
  182. package/lib/components/principal/PrincipalSwitcherMenu.js +7 -15
  183. package/lib/components/principal/index.d.ts +2 -1
  184. package/lib/components/principal/index.js +2 -1
  185. package/lib/components/progress/ConsumptionBar.d.ts +1 -0
  186. package/lib/components/progress/ConsumptionBar.js +0 -4
  187. package/lib/components/progress/ProgressRing.d.ts +1 -0
  188. package/lib/components/progress/SpinnerBar.d.ts +1 -1
  189. package/lib/components/progress/Timer.d.ts +1 -0
  190. package/lib/components/progress/Timer.js +0 -4
  191. package/lib/components/screencapture/ScreencaptureButton.d.ts +1 -1
  192. package/lib/components/sharing/ShareAccessComponent.d.ts +15 -1
  193. package/lib/components/sharing/ShareAccessComponent.js +36 -23
  194. package/lib/components/sharing/SharingEditor.d.ts +17 -0
  195. package/lib/components/sharing/SharingEditor.js +0 -24
  196. package/lib/components/sparklines/Sparklines.js +3 -4
  197. package/lib/components/sparklines/index.js +0 -4
  198. package/lib/components/storage/ContentsBrowser.d.ts +25 -1
  199. package/lib/components/storage/ContentsBrowser.js +145 -52
  200. package/lib/components/storage/ContentsBrowserMock.d.ts +3 -0
  201. package/lib/components/storage/ContentsBrowserMock.js +75 -0
  202. package/lib/components/storage/ContentsItems.d.ts +2 -1
  203. package/lib/components/storage/ContentsItems.js +0 -4
  204. package/lib/components/storage/ContentsTable.d.ts +50 -0
  205. package/lib/components/storage/ContentsTable.js +134 -0
  206. package/lib/components/storage/HomeFolderDrive.d.ts +71 -0
  207. package/lib/components/storage/HomeFolderDrive.js +248 -0
  208. package/lib/components/storage/index.d.ts +2 -0
  209. package/lib/components/storage/index.js +2 -0
  210. package/lib/components/students/StudentItemStatus.d.ts +1 -1
  211. package/lib/components/students/StudentResultCircle.d.ts +1 -1
  212. package/lib/components/subnav/SubNav.d.ts +5 -5
  213. package/lib/components/subnav/SubNav.js +11 -9
  214. package/lib/components/tables/DataTable.d.ts +1 -1
  215. package/lib/components/text-reveal/TextRevealAnimation.d.ts +2 -2
  216. package/lib/components/text-reveal/useTextRevealAnimationLines.d.ts +1 -1
  217. package/lib/components/time/LiveRelativeTime.d.ts +1 -0
  218. package/lib/components/time/LiveRelativeTime.js +0 -8
  219. package/lib/components/time/index.js +0 -4
  220. package/lib/components/timeline/Timeline.d.ts +1 -1
  221. package/lib/components/timeline/index.js +0 -4
  222. package/lib/components/users/PeerIndicator.d.ts +1 -0
  223. package/lib/components/users/PeerIndicator.js +0 -4
  224. package/lib/config/Configuration.d.ts +15 -17
  225. package/lib/config/Configuration.js +7 -0
  226. package/lib/hooks/index.d.ts +2 -0
  227. package/lib/hooks/index.js +2 -0
  228. package/lib/hooks/layouts/LayoutBackdrop.d.ts +1 -1
  229. package/lib/hooks/layouts/LayoutScreencapture.d.ts +1 -1
  230. package/lib/hooks/useBackdrop.d.ts +1 -1
  231. package/lib/hooks/useBackdropJupyterLab.d.ts +3 -2
  232. package/lib/hooks/useBackdropJupyterLab.js +0 -4
  233. package/lib/hooks/useCache.d.ts +310 -105
  234. package/lib/hooks/useCache.js +142 -355
  235. package/lib/hooks/useContainsFocus.d.ts +1 -1
  236. package/lib/hooks/useContents.d.ts +313 -0
  237. package/lib/hooks/useContents.js +964 -0
  238. package/lib/hooks/useFocusTrap.d.ts +4 -4
  239. package/lib/hooks/useFocusTrap.js +1 -1
  240. package/lib/hooks/useMcp.d.ts +229 -0
  241. package/lib/hooks/useMcp.js +656 -0
  242. package/lib/hooks/useMobile.js +0 -5
  243. package/lib/hooks/useProjectStore.d.ts +3 -3
  244. package/lib/hooks/useProjectStore.js +4 -4
  245. package/lib/hooks/useRef.d.ts +1 -1
  246. package/lib/hooks/useRef.js +3 -0
  247. package/lib/hooks/useScreencapture.d.ts +2 -1
  248. package/lib/hooks/useScreencapture.js +0 -4
  249. package/lib/hooks/useToast.js +0 -4
  250. package/lib/hooks/useUser.js +42 -0
  251. package/lib/hooks/useVisibilityObserver.d.ts +1 -1
  252. package/lib/index.d.ts +4 -1
  253. package/lib/index.js +3 -1
  254. package/lib/mocks/components/FlashMock.d.ts +1 -1
  255. package/lib/mocks/views/ActionMenuMock.d.ts +1 -1
  256. package/lib/mocks/views/ChartMock.d.ts +1 -1
  257. package/lib/mocks/views/DashboardMock.d.ts +1 -1
  258. package/lib/mocks/views/FormMock.d.ts +1 -1
  259. package/lib/mocks/views/TableMock.d.ts +1 -1
  260. package/lib/mocks/views/WipMock.d.ts +1 -1
  261. package/lib/models/Credits.d.ts +16 -0
  262. package/lib/models/Credits.js +22 -0
  263. package/lib/models/McpAuditEvent.d.ts +52 -0
  264. package/lib/models/McpAuditEvent.js +5 -0
  265. package/lib/models/McpBinding.d.ts +51 -0
  266. package/lib/models/McpBinding.js +5 -0
  267. package/lib/models/McpPolicy.d.ts +77 -0
  268. package/lib/models/McpPolicy.js +5 -0
  269. package/lib/models/McpTask.d.ts +94 -0
  270. package/lib/models/McpTask.js +7 -0
  271. package/lib/models/StartedBy.d.ts +57 -0
  272. package/lib/models/StartedBy.js +81 -0
  273. package/lib/models/UserDTO.js +4 -2
  274. package/lib/models/contents/__fixtures__/solr-codec.json +57 -0
  275. package/lib/models/contents/__fixtures__/v1-contracts.json +66 -0
  276. package/lib/models/contents/fieldCase.d.ts +8 -0
  277. package/lib/models/contents/fieldCase.js +37 -0
  278. package/lib/models/contents/index.d.ts +2 -0
  279. package/lib/models/contents/index.js +6 -0
  280. package/lib/models/contents/permissions.d.ts +16 -0
  281. package/lib/models/contents/permissions.js +34 -0
  282. package/lib/models/index.d.ts +5 -1
  283. package/lib/models/index.js +5 -1
  284. package/lib/state/substates/CoreState.d.ts +15 -7
  285. package/lib/state/substates/CoreState.js +18 -14
  286. package/lib/state/substates/IAMState.d.ts +1 -1
  287. package/lib/state/substates/IAMState.js +5 -5
  288. package/lib/state/substates/ProfileState.js +0 -4
  289. package/lib/state/substates/index.d.ts +0 -1
  290. package/lib/state/substates/index.js +0 -1
  291. package/lib/utils/Jwt.d.ts +26 -0
  292. package/lib/utils/Jwt.js +37 -0
  293. package/lib/utils/WithSuspense.d.ts +1 -1
  294. package/lib/views/api-keys/APIKeyEdit.d.ts +1 -1
  295. package/lib/views/api-keys/APIKeyNew.d.ts +1 -1
  296. package/lib/views/api-keys/APIKeys.d.ts +1 -1
  297. package/lib/views/api-keys/APIKeys.js +30 -4
  298. package/lib/views/api-keys/APIKeysStandalone.d.ts +5 -1
  299. package/lib/views/api-keys/APIKeysStandalone.js +2 -2
  300. package/lib/views/datasources/DatasourceDetail.d.ts +12 -5
  301. package/lib/views/datasources/DatasourceDetail.js +80 -110
  302. package/lib/views/datasources/DatasourceNew.d.ts +14 -8
  303. package/lib/views/datasources/DatasourceNew.js +129 -118
  304. package/lib/views/datasources/Datasources.d.ts +39 -7
  305. package/lib/views/datasources/Datasources.js +95 -40
  306. package/lib/views/datasources/DatasourcesMock.d.ts +3 -0
  307. package/lib/views/datasources/DatasourcesMock.js +57 -0
  308. package/lib/views/iam/SignInSimple.d.ts +12 -0
  309. package/lib/views/iam/SignInSimple.js +4 -4
  310. package/lib/views/index.d.ts +1 -0
  311. package/lib/views/index.js +1 -0
  312. package/lib/views/mcp/AlertDestinations.d.ts +34 -0
  313. package/lib/views/mcp/AlertDestinations.js +75 -0
  314. package/lib/views/mcp/AlertRules.d.ts +32 -0
  315. package/lib/views/mcp/AlertRules.js +245 -0
  316. package/lib/views/mcp/AuditLog.d.ts +42 -0
  317. package/lib/views/mcp/AuditLog.js +144 -0
  318. package/lib/views/mcp/ConnectedAgents.d.ts +34 -0
  319. package/lib/views/mcp/ConnectedAgents.js +100 -0
  320. package/lib/views/mcp/EnterpriseConsole.d.ts +74 -0
  321. package/lib/views/mcp/EnterpriseConsole.js +173 -0
  322. package/lib/views/mcp/McpDashboard.d.ts +50 -0
  323. package/lib/views/mcp/McpDashboard.js +347 -0
  324. package/lib/views/mcp/McpHome.d.ts +92 -0
  325. package/lib/views/mcp/McpHome.js +153 -0
  326. package/lib/views/mcp/McpObservability.d.ts +50 -0
  327. package/lib/views/mcp/McpObservability.js +150 -0
  328. package/lib/views/mcp/OrganizationPolicy.d.ts +45 -0
  329. package/lib/views/mcp/OrganizationPolicy.js +107 -0
  330. package/lib/views/mcp/OrganizationUsage.d.ts +69 -0
  331. package/lib/views/mcp/OrganizationUsage.js +113 -0
  332. package/lib/views/mcp/PersonalPolicy.d.ts +54 -0
  333. package/lib/views/mcp/PersonalPolicy.js +125 -0
  334. package/lib/views/mcp/Policies.d.ts +53 -0
  335. package/lib/views/mcp/Policies.js +210 -0
  336. package/lib/views/mcp/PolicyForm.d.ts +67 -0
  337. package/lib/views/mcp/PolicyForm.js +91 -0
  338. package/lib/views/mcp/PolicyHistory.d.ts +45 -0
  339. package/lib/views/mcp/PolicyHistory.js +62 -0
  340. package/lib/views/mcp/ServiceAgents.d.ts +46 -0
  341. package/lib/views/mcp/ServiceAgents.js +194 -0
  342. package/lib/views/mcp/TeamPolicies.d.ts +33 -0
  343. package/lib/views/mcp/TeamPolicies.js +98 -0
  344. package/lib/views/mcp/format.d.ts +25 -0
  345. package/lib/views/mcp/format.js +77 -0
  346. package/lib/views/mcp/index.d.ts +29 -0
  347. package/lib/views/mcp/index.js +37 -0
  348. package/lib/views/mcp/types.d.ts +66 -0
  349. package/lib/views/mcp/types.js +5 -0
  350. package/lib/views/secrets/SecretEdit.d.ts +5 -1
  351. package/lib/views/secrets/SecretEdit.js +2 -2
  352. package/lib/views/secrets/SecretNew.d.ts +11 -1
  353. package/lib/views/secrets/SecretNew.js +2 -2
  354. package/lib/views/secrets/Secrets.d.ts +12 -1
  355. package/lib/views/secrets/Secrets.js +2 -2
  356. package/package.json +28 -24
  357. package/scripts/generate-contents-types.py +169 -0
  358. package/scripts/generate-mcp-types.py +233 -0
  359. package/lib/api/iam/datasources.d.ts +0 -86
  360. package/lib/api/iam/datasources.js +0 -185
  361. package/lib/components/toolbars/index.d.ts +0 -1
  362. package/lib/models/Datasource.d.ts +0 -181
  363. package/lib/models/Datasource.js +0 -154
  364. package/lib/state/substates/DatasourceState.d.ts +0 -11
  365. package/lib/state/substates/DatasourceState.js +0 -16
  366. /package/lib/{components/toolbars/index.js → api/contents/generated.js} +0 -0
@@ -0,0 +1,150 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { useState } from 'react';
3
+ import { Button, Heading, Label, SegmentedControl, Spinner, Text, TextInput, } from '@primer/react';
4
+ import { Blankslate } from '@primer/react/experimental';
5
+ import { Box } from '@datalayer/primer-addons';
6
+ import { SearchIcon, TelescopeIcon } from '@primer/octicons-react';
7
+ import { McpErrorBlankslate } from '../../components/mcp/index.js';
8
+ import { useMcpMetrics, useMcpTrace, useRunTrace } from '../../hooks/useMcp.js';
9
+ import { useNavigate } from '../../hooks/index.js';
10
+ import { MCP_METRIC_CATALOG } from '../../api/mcp/index.js';
11
+ import { durationLabel } from './format.js';
12
+ /** The gateway's own spans, so the tree can call out what each stage cost. */
13
+ const STAGE = (name) => {
14
+ if (name.startsWith('mcp.policy')) {
15
+ return 'Policy';
16
+ }
17
+ if (name.startsWith('mcp.request')) {
18
+ return 'Gateway';
19
+ }
20
+ if (name.startsWith('sandbox.')) {
21
+ return 'Sandbox';
22
+ }
23
+ if (name.startsWith('durable.')) {
24
+ return 'Workflow';
25
+ }
26
+ return '';
27
+ };
28
+ const SpanRow = ({ node, depth, }) => {
29
+ const stage = STAGE(node.span.span_name);
30
+ const failed = (node.span.status_code ?? '').toUpperCase() === 'ERROR';
31
+ return (_jsxs(_Fragment, { children: [_jsxs(Box, { sx: {
32
+ display: 'flex',
33
+ alignItems: 'center',
34
+ gap: 2,
35
+ py: 1,
36
+ pl: depth * 3,
37
+ borderBottom: '1px solid',
38
+ borderColor: 'border.muted',
39
+ minWidth: 0,
40
+ }, children: [_jsx(Text, { sx: {
41
+ fontSize: 0,
42
+ fontFamily: 'mono',
43
+ flex: 1,
44
+ minWidth: 0,
45
+ overflow: 'hidden',
46
+ textOverflow: 'ellipsis',
47
+ whiteSpace: 'nowrap',
48
+ color: failed ? 'danger.fg' : 'fg.default',
49
+ }, children: node.span.span_name }), stage && (_jsx(Label, { size: "small", variant: "secondary", children: stage })), _jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: node.span.service_name }), _jsx(Text, { sx: {
50
+ fontSize: 0,
51
+ fontWeight: 'semibold',
52
+ minWidth: 60,
53
+ textAlign: 'right',
54
+ }, children: durationLabel(node.span.duration_ms) })] }), node.children.map(child => (_jsx(SpanRow, { node: child, depth: depth + 1 }, child.span.span_id)))] }));
55
+ };
56
+ /** A number the reader can act on, or a plain statement that it is not measured. */
57
+ const Sli = ({ label, value, note, }) => (_jsxs(Box, { sx: {
58
+ p: 3,
59
+ border: '1px solid',
60
+ borderColor: 'border.default',
61
+ borderRadius: 2,
62
+ minWidth: 0,
63
+ }, children: [_jsx(Text, { sx: { display: 'block', fontSize: 3, fontWeight: 'bold' }, children: value }), _jsx(Text, { sx: { display: 'block', fontSize: 0, color: 'fg.muted' }, children: label }), note && (_jsx(Text, { sx: { display: 'block', fontSize: 0, color: 'fg.subtle' }, children: note }))] }));
64
+ const percentLabel = (value) => value === null || value === undefined
65
+ ? 'Not measured'
66
+ : `${(value * 100).toFixed(1)}%`;
67
+ export const McpObservability = ({ errorState, routes, pane, onPaneChange, taskUid, traceId, onSelect, agent, org, showTitle = true, }) => {
68
+ const navigate = useNavigate();
69
+ const [find, setFind] = useState(taskUid ?? traceId ?? '');
70
+ // One of the two, never both: a task names its own trace, and a trace
71
+ // names itself.
72
+ const byTask = useRunTrace(taskUid, { enabled: Boolean(taskUid) });
73
+ const byTrace = useMcpTrace(traceId, {
74
+ enabled: Boolean(traceId) && !taskUid,
75
+ });
76
+ const run = taskUid ? byTask : byTrace;
77
+ const metrics = useMcpMetrics({ agent, org });
78
+ const telemetryNotice = (_jsxs(Text, { sx: { fontSize: 0, color: 'fg.subtle' }, children: ["This is telemetry: spans and metrics are sampled, kept for a short time and meant for understanding how a call ran. It is not the record of what was allowed \u2014", ' ', _jsx(Text, { as: "span", sx: { color: 'accent.fg', cursor: 'pointer' }, onClick: () => navigate(routes.audit), children: "the audit log" }), ' ', "is, and it is kept per plan and never changed."] }));
79
+ return (_jsxs(Box, { sx: { display: 'grid', gap: 3, minWidth: 0 }, children: [showTitle && (_jsxs(Box, { children: [_jsx(Heading, { as: "h2", sx: { fontSize: 3, mb: 1 }, children: "Observability" }), _jsx(Text, { as: "p", sx: { color: 'fg.muted', fontSize: 1, m: 0 }, children: "How the calls of your agents ran: where the time went, and how the service is behaving." })] })), _jsxs(SegmentedControl, { "aria-label": "Observability panes", size: "small", children: [_jsx(SegmentedControl.Button, { selected: pane === 'runs', onClick: () => onPaneChange('runs'), children: "Runs" }), _jsx(SegmentedControl.Button, { selected: pane === 'metrics', onClick: () => onPaneChange('metrics'), children: "Metrics" })] }), telemetryNotice, pane === 'runs' && (_jsxs(Box, { sx: { display: 'grid', gap: 3 }, children: [_jsxs(Box, { sx: {
80
+ display: 'flex',
81
+ gap: 2,
82
+ alignItems: 'center',
83
+ flexWrap: 'wrap',
84
+ }, children: [_jsx(TextInput, { size: "small", leadingVisual: SearchIcon, "aria-label": "Task or trace id", placeholder: "Task uid or trace id", value: find, sx: { minWidth: 320 }, onChange: event => setFind(event.currentTarget.value) }), _jsx(Button, { size: "small", onClick: () => {
85
+ const value = find.trim();
86
+ if (!value) {
87
+ onSelect({});
88
+ return;
89
+ }
90
+ // A trace id is 32 hexadecimal characters; anything else is a
91
+ // task uid, and the gateway tells us which by answering.
92
+ onSelect(/^[0-9a-f]{32}$/i.test(value)
93
+ ? { trace: value }
94
+ : { task: value });
95
+ }, children: "Show the run" })] }), !taskUid && !traceId ? (_jsxs(Blankslate, { border: true, spacious: true, children: [_jsx(Blankslate.Visual, { children: _jsx(TelescopeIcon, { size: "medium" }) }), _jsx(Blankslate.Heading, { children: "Pick a run" }), _jsx(Blankslate.Description, { children: _jsx(Text, { sx: { textAlign: 'center' }, children: "Open a call from the audit log or the dashboard, or paste its task uid or trace id here, and its spans across the gateway, the policy check and the worker appear with the time each took." }) }), _jsx(Button, { size: "small", onClick: () => navigate(routes.audit), children: "Open the audit log" })] })) : run.isError ? (_jsx(McpErrorBlankslate, { state: errorState(run.error, 'This run'), onRetry: () => run.refetch() })) : run.isPending ? (_jsx(Box, { sx: { display: 'flex', justifyContent: 'center', py: 5 }, children: _jsx(Spinner, {}) })) : (run.data?.spans.length ?? 0) === 0 ? (_jsxs(Blankslate, { border: true, spacious: true, children: [_jsx(Blankslate.Visual, { children: _jsx(TelescopeIcon, { size: "medium" }) }), _jsx(Blankslate.Heading, { children: "No span for this call" }), _jsx(Blankslate.Description, { children: _jsx(Text, { sx: { textAlign: 'center' }, children: "Spans reach the collector a few seconds after the call and are kept for a short time. A call older than the retention window has an audit row but no trace." }) })] })) : (_jsxs(Box, { sx: { display: 'grid', gap: 2 }, children: [_jsxs(Box, { sx: {
96
+ display: 'flex',
97
+ gap: 3,
98
+ alignItems: 'center',
99
+ flexWrap: 'wrap',
100
+ }, children: [_jsx(Text, { sx: { fontSize: 0, color: 'fg.muted', fontFamily: 'mono' }, children: run.data?.traceId }), _jsxs(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: [run.data?.spans.length, " spans"] }), _jsx(Button, { size: "small", onClick: () => navigate(`${routes.audit}?trace=${encodeURIComponent(run.data?.traceId ?? '')}`), children: "The audit row" })] }), _jsx(Box, { sx: {
101
+ border: '1px solid',
102
+ borderColor: 'border.default',
103
+ borderRadius: 2,
104
+ overflowX: 'auto',
105
+ }, children: (run.data?.tree ?? []).map(node => (_jsx(SpanRow, { node: node, depth: 0 }, node.span.span_id))) }), _jsx(Text, { sx: { fontSize: 0, color: 'fg.subtle' }, children: "The workflow steps and the sandbox launch of a durable task join this tree with milestone 2, and so does the live stream of calls as they land." })] }))] })), pane === 'metrics' && (_jsx(Box, { sx: { display: 'grid', gap: 3 }, children: metrics.isError ? (_jsx(McpErrorBlankslate, { state: errorState(metrics.error, 'Metrics'), onRetry: () => metrics.refetch() })) : metrics.isPending && !metrics.data ? (_jsx(Box, { sx: { display: 'flex', justifyContent: 'center', py: 5 }, children: _jsx(Spinner, {}) })) : (_jsxs(_Fragment, { children: [_jsxs(Box, { sx: {
106
+ display: 'grid',
107
+ gap: 3,
108
+ gridTemplateColumns: [
109
+ '1fr',
110
+ 'repeat(2, 1fr)',
111
+ 'repeat(4, 1fr)',
112
+ ],
113
+ }, children: [_jsx(Sli, { label: "Availability", value: percentLabel(metrics.data?.slis.availability), note: `${metrics.data?.slis.samples.calls ?? 0} calls` }), _jsx(Sli, { label: "Call latency, p95", value: metrics.data?.slis.p95CallDurationMs === null ||
114
+ metrics.data?.slis.p95CallDurationMs === undefined
115
+ ? 'Not measured'
116
+ : durationLabel(metrics.data.slis.p95CallDurationMs) }), _jsx(Sli, { label: "Task success", value: percentLabel(metrics.data?.slis.taskSuccessRate), note: `${metrics.data?.slis.samples.tasks ?? 0} tasks` }), _jsx(Sli, { label: "Sandbox launch, p95", value: Object.keys(metrics.data?.slis.p95SandboxLaunchSeconds ?? {}).length === 0
117
+ ? 'Not measured'
118
+ : Object.entries(metrics.data?.slis.p95SandboxLaunchSeconds ?? {})
119
+ .map(([provider, seconds]) => `${provider} ${seconds.toFixed(1)}s`)
120
+ .join(' · '), note: `${metrics.data?.slis.samples.launches ?? 0} launches` })] }), _jsx(Box, { sx: {
121
+ border: '1px solid',
122
+ borderColor: 'border.default',
123
+ borderRadius: 2,
124
+ overflowX: 'auto',
125
+ }, children: MCP_METRIC_CATALOG.map(name => {
126
+ const points = metrics.data?.metrics[name] ?? [];
127
+ const last = points[points.length - 1];
128
+ return (_jsxs(Box, { sx: {
129
+ display: 'flex',
130
+ alignItems: 'center',
131
+ gap: 3,
132
+ py: 1,
133
+ px: 2,
134
+ borderBottom: '1px solid',
135
+ borderColor: 'border.muted',
136
+ }, children: [_jsx(Text, { sx: { fontSize: 0, fontFamily: 'mono', flex: 1 }, children: name }), _jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: points.length === 0
137
+ ? 'no point'
138
+ : `${points.length} points` }), _jsx(Text, { sx: {
139
+ fontSize: 0,
140
+ fontWeight: 'semibold',
141
+ minWidth: 80,
142
+ textAlign: 'right',
143
+ }, children: last
144
+ ? `${last.value}${last.unit ? ` ${last.unit}` : ''}`
145
+ : '—' })] }, name));
146
+ }) }), _jsxs(Text, { sx: { fontSize: 0, color: 'fg.subtle' }, children: ["Metrics carry no user, agent or organization label by design, so a per-agent reading is computed from the request spans, which do.", metrics.data?.spans.length
147
+ ? ` ${metrics.data.spans.length} spans read.`
148
+ : ''] })] })) }))] }));
149
+ };
150
+ export default McpObservability;
@@ -0,0 +1,45 @@
1
+ /**
2
+ * What an organization narrows for its agents, and the form that writes it.
3
+ *
4
+ * The sibling `Policies` view is the *read*: every layer intersected, with
5
+ * the layer that decided each rule. This is the *write*, and only one
6
+ * layer's — an organization owner cannot edit the platform's defaults or
7
+ * somebody's personal rules, and would not want to.
8
+ *
9
+ * Three things this page owes the person filling it in:
10
+ *
11
+ * **Only rules the gateway enforces.** IAM refuses anything else, so a form
12
+ * offering more would collect a setting that is thrown away at the write —
13
+ * and `toolDenyList` would read as a working denylist rather than a typo.
14
+ * The fields come from `MCP_POLICY_RULES` so the form cannot drift.
15
+ *
16
+ * **An empty allowlist is not an allowlist.** Leaving the field blank means
17
+ * "I have not set one", not "nothing is permitted" — the second would stop
18
+ * every agent in the organization, and the first conclusion anybody draws
19
+ * from that is that the platform is down. The captions say so where
20
+ * somebody is about to make that mistake.
21
+ *
22
+ * **A limit of zero is refused rather than stored.** The gateway reads a
23
+ * non-positive cap as *no cap*, so a zero written to stop an organization's
24
+ * agents lifts its limit instead — the one value whose stored meaning is the
25
+ * opposite of its plain reading.
26
+ *
27
+ * @module views/mcp/OrganizationPolicy
28
+ */
29
+ import type { JSX } from 'react';
30
+ import type { McpErrorStateFn } from './types';
31
+ export interface OrganizationPolicyProps {
32
+ /** The application's words for a failed request. */
33
+ errorState: McpErrorStateFn;
34
+ /** The organization whose layer this is. */
35
+ orgUid: string;
36
+ /**
37
+ * Read-only for anybody who is not an owner. IAM refuses their writes
38
+ * either way; this keeps the page from offering an action that would be
39
+ * refused.
40
+ */
41
+ readOnly?: boolean;
42
+ showTitle?: boolean;
43
+ }
44
+ export declare const OrganizationPolicy: ({ errorState, orgUid, readOnly, showTitle, }: OrganizationPolicyProps) => JSX.Element;
45
+ export default OrganizationPolicy;
@@ -0,0 +1,107 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useEffect, useMemo, useState } from 'react';
3
+ import { Button, Flash, Heading, Spinner, Text } from '@primer/react';
4
+ import { Dialog } from '@primer/react/experimental';
5
+ import { Box } from '@datalayer/primer-addons';
6
+ import { McpErrorBlankslate } from '../../components/mcp/index.js';
7
+ import { useDeleteMcpPolicyLayer, useMcpPolicyLayer, useSetMcpPolicyLayer, } from '../../hooks/useMcp.js';
8
+ import { useToast } from '../../hooks/index.js';
9
+ import { McpPolicyConflict } from '../../api/iam/mcpPolicy.js';
10
+ import { PolicyHistory } from './PolicyHistory.js';
11
+ import { EMPTY_POLICY_DRAFT, PolicyForm, draftOf, policyChanged, rulesFrom, } from './PolicyForm.js';
12
+ export const OrganizationPolicy = ({ errorState, orgUid, readOnly = false, showTitle = true, }) => {
13
+ const { enqueueToast } = useToast();
14
+ const layer = useMcpPolicyLayer('organization', orgUid);
15
+ const save = useSetMcpPolicyLayer('organization', orgUid);
16
+ const remove = useDeleteMcpPolicyLayer('organization', orgUid);
17
+ const [draft, setDraft] = useState(EMPTY_POLICY_DRAFT);
18
+ const [removing, setRemoving] = useState(false);
19
+ const [conflict, setConflict] = useState('');
20
+ const [refusal, setRefusal] = useState('');
21
+ /**
22
+ * The version that was read, sent back with the write.
23
+ *
24
+ * `undefined` when nobody has written this layer: inventing a version
25
+ * would make the first write of every policy a conflict.
26
+ */
27
+ const version = layer.data?.version;
28
+ const stored = useMemo(() => draftOf(layer.data), [layer.data]);
29
+ // The form follows what was read, including after a conflict has been
30
+ // resolved by re-reading: an editor still showing the losing draft is how
31
+ // somebody reapplies the change that was already refused.
32
+ useEffect(() => setDraft(stored), [stored]);
33
+ const changed = useMemo(() => policyChanged(draft, stored), [draft, stored]);
34
+ const set = (key, value) => setDraft(current => ({ ...current, [key]: value }));
35
+ const apply = () => {
36
+ const rules = rulesFrom(draft);
37
+ if (typeof rules === 'string') {
38
+ setRefusal(rules);
39
+ return;
40
+ }
41
+ setRefusal('');
42
+ setConflict('');
43
+ save.mutate({ rules, expectedVersion: version }, {
44
+ onSuccess: () => {
45
+ enqueueToast('Policy saved. It applies to the next call.', {
46
+ variant: 'success',
47
+ });
48
+ },
49
+ onError: error => {
50
+ if (error instanceof McpPolicyConflict) {
51
+ // Not a toast. A toast disappears, and this needs an action —
52
+ // the draft in front of them is the one that lost.
53
+ setConflict(error.message);
54
+ return;
55
+ }
56
+ enqueueToast(`Could not save: ${error.message}`, {
57
+ variant: 'error',
58
+ });
59
+ },
60
+ });
61
+ };
62
+ const confirmRemove = () => {
63
+ remove.mutate(undefined, {
64
+ onSuccess: () => {
65
+ setRemoving(false);
66
+ enqueueToast('Policy removed. This layer narrows nothing.', {
67
+ variant: 'success',
68
+ });
69
+ },
70
+ onError: error => {
71
+ setRemoving(false);
72
+ enqueueToast(`Could not remove: ${error.message}`, {
73
+ variant: 'error',
74
+ });
75
+ },
76
+ });
77
+ };
78
+ if (layer.isError) {
79
+ return (_jsx(McpErrorBlankslate, { state: errorState(layer.error, "The organization's MCP policy"), onRetry: () => layer.refetch() }));
80
+ }
81
+ if (layer.isPending && layer.data === undefined) {
82
+ return (_jsx(Box, { sx: { display: 'flex', justifyContent: 'center', py: 5 }, children: _jsx(Spinner, {}) }));
83
+ }
84
+ return (_jsxs(Box, { sx: { display: 'grid', gap: 3, minWidth: 0, maxWidth: '52rem' }, children: [showTitle && (_jsxs(Box, { children: [_jsx(Heading, { as: "h2", sx: { fontSize: 3, mb: 1 }, children: "Organization Policy" }), _jsx(Text, { as: "p", sx: { color: 'fg.muted', fontSize: 1, m: 0 }, children: "What this organization narrows for every agent acting in it. Each layer only narrows \u2014 a team, or a person, can be stricter than this and never looser." })] })), conflict && (_jsxs(Flash, { variant: "warning", children: [_jsx(Text, { sx: { fontSize: 1 }, children: conflict }), _jsx(Box, { sx: { mt: 2 }, children: _jsx(Button, { size: "small", onClick: () => {
85
+ setConflict('');
86
+ layer.refetch();
87
+ }, children: "Read it again" }) })] })), refusal && (_jsx(Flash, { variant: "danger", children: _jsx(Text, { sx: { fontSize: 1 }, children: refusal }) })), _jsx(PolicyForm, { draft: draft, onChange: set, disabled: readOnly }), !readOnly && (_jsxs(Box, { sx: { display: 'flex', gap: 2, alignItems: 'center' }, children: [_jsx(Button, { variant: "primary", onClick: apply, disabled: !changed || save.isPending, children: "Save policy" }), changed && (_jsx(Button, { variant: "invisible", onClick: () => setDraft(stored), children: "Discard changes" })), layer.data && (_jsx(Box, { sx: { marginLeft: 'auto' }, children: _jsx(Button, { variant: "danger", onClick: () => setRemoving(true), children: "Remove policy" }) }))] })), _jsxs(Box, { sx: {
88
+ borderTop: '1px solid',
89
+ borderColor: 'border.muted',
90
+ pt: 3,
91
+ display: 'grid',
92
+ gap: 2,
93
+ }, children: [_jsx(Text, { as: "h3", sx: { fontSize: 1, fontWeight: 'semibold', m: 0 }, children: "History" }), _jsx(PolicyHistory, { orgUid: orgUid, subjectUid: orgUid })] }), _jsx(Text, { sx: { fontSize: 0, color: 'fg.subtle' }, children: "Only these rules can be stored. A rule the gateway does not enforce is refused rather than kept, so this page cannot promise something that never happens." }), removing && (_jsx(Dialog, { title: "Remove this policy?", onClose: () => setRemoving(false), footerButtons: [
94
+ {
95
+ buttonType: 'default',
96
+ content: 'Keep it',
97
+ onClick: () => setRemoving(false),
98
+ },
99
+ {
100
+ buttonType: 'danger',
101
+ content: 'Remove',
102
+ onClick: confirmRemove,
103
+ disabled: remove.isPending,
104
+ },
105
+ ], children: _jsxs(Text, { sx: { fontSize: 1 }, children: ["This organization stops narrowing anything. Its agents fall back to the platform defaults and to whatever each team and person has set \u2014 which may be ", _jsx("strong", { children: "wider" }), " than what you have now. Nothing already done is undone."] }) }))] }));
106
+ };
107
+ export default OrganizationPolicy;
@@ -0,0 +1,69 @@
1
+ /**
2
+ * What the organization used, against what it may — and which agent used it.
3
+ *
4
+ * The console had a role called `organization_usage_reviewer` and no page of
5
+ * usage: the reviewer was sent to the Overview, which counts runs and
6
+ * refusals and says nothing about a limit. A budget with no spend against it
7
+ * is a number somebody set once.
8
+ *
9
+ * The breakdown underneath is the half that decides anything. A quota bar at
10
+ * ninety percent tells an administrator to act; it does not say what to turn
11
+ * off. The rows name the agents, biggest spender first, because that is the
12
+ * order the question is asked in.
13
+ *
14
+ * **Unreadable is not zero.** A figure the gateway could not read is drawn
15
+ * as "not available" with the reason, never as a blank or a 0 — they look
16
+ * the same in a dashboard and mean opposite things. For the same reason the
17
+ * breakdown is hidden entirely when the total could not be read: the parts
18
+ * under an unreadable whole make every agent look cheap, and a reader
19
+ * concludes the budget is fine.
20
+ *
21
+ * Limits are **changed in IAM**, not here. The page says where.
22
+ *
23
+ * @module views/mcp/OrganizationUsage
24
+ */
25
+ import type { JSX } from 'react';
26
+ import type { McpAgentSpend, McpOrganizationUsage } from '../../api/mcp/organizations';
27
+ import { type McpErrorStateFn } from './types';
28
+ export interface OrganizationUsageProps {
29
+ /** The application's words for a failed request. */
30
+ errorState: McpErrorStateFn;
31
+ /** The organization whose use this is. */
32
+ orgUid: string;
33
+ /** One team of it, rather than all of them. */
34
+ teamUid?: string;
35
+ /** Drawn without its heading, when the page around it carries one. */
36
+ showTitle?: boolean;
37
+ }
38
+ export type SpendRow = McpAgentSpend & {
39
+ id: string;
40
+ };
41
+ /** Two decimals for credits, none for counts. */
42
+ export declare const amount: (value: number) => string;
43
+ /**
44
+ * How close to the limit, said in colour.
45
+ *
46
+ * Three bands rather than a gradient: a reader acts at "nearly there" and
47
+ * not at eighty-one percent, and a bar that reddens smoothly gives them no
48
+ * moment to act on.
49
+ */
50
+ export declare const quotaTone: (fraction: number) => "success" | "attention" | "danger";
51
+ /**
52
+ * What the breakdown should show: the rows, nothing, or a refusal to guess.
53
+ *
54
+ * `unreadable` is not `empty`. The gateway sends no rows in both cases —
55
+ * because nobody spent anything, or because it could not read the ledger —
56
+ * and drawing them the same way tells a reader "your agents were quiet"
57
+ * when the truth is "we cannot tell you". They act on that differently.
58
+ */
59
+ export declare const breakdownState: (usage: McpOrganizationUsage | undefined) => "unreadable" | "empty" | "rows";
60
+ /**
61
+ * The rows, keyed the way the gateway grouped them.
62
+ *
63
+ * The agent uid first: service agents reach Runtimes through the gateway and
64
+ * carry *its* client id, so keying on that would collapse an organization's
65
+ * pipelines into one row costing the sum of several.
66
+ */
67
+ export declare const spendRowsOf: (byAgent: McpAgentSpend[]) => SpendRow[];
68
+ export declare const OrganizationUsage: ({ errorState, orgUid, teamUid, showTitle, }: OrganizationUsageProps) => JSX.Element;
69
+ export default OrganizationUsage;
@@ -0,0 +1,113 @@
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useMemo } from 'react';
3
+ import { Heading, Label, ProgressBar, Spinner, Text } from '@primer/react';
4
+ import { Blankslate, DataTable, Table } from '@primer/react/experimental';
5
+ import { Box } from '@datalayer/primer-addons';
6
+ import { GraphIcon } from '@primer/octicons-react';
7
+ import { ClientBadge, McpErrorBlankslate } from '../../components/mcp/index.js';
8
+ import { useOrgMcpUsage } from '../../hooks/useMcp.js';
9
+ /** The quotas, in the order they are read. */
10
+ const QUOTAS = [
11
+ {
12
+ key: 'creditsPerDay',
13
+ label: 'Credits today',
14
+ // Named so the reader knows the window without reading the number: a
15
+ // daily budget and a monthly one differ by thirty, and the mistake is
16
+ // silent.
17
+ hint: 'Against the daily budget',
18
+ },
19
+ {
20
+ key: 'concurrentSandboxes',
21
+ label: 'Sandboxes running',
22
+ hint: 'Against the concurrency limit',
23
+ },
24
+ {
25
+ key: 'callsPerMinute',
26
+ label: 'Calls per minute',
27
+ // The gateway reports this limit without a use, and says why: the
28
+ // windows are per subject, so an organization's "calls this minute" is
29
+ // a sum over subjects that changes while it is being read.
30
+ hint: 'The cap; refusals are where you meet it',
31
+ },
32
+ ];
33
+ /** Two decimals for credits, none for counts. */
34
+ export const amount = (value) => Number.isInteger(value) ? String(value) : value.toFixed(2);
35
+ /**
36
+ * How close to the limit, said in colour.
37
+ *
38
+ * Three bands rather than a gradient: a reader acts at "nearly there" and
39
+ * not at eighty-one percent, and a bar that reddens smoothly gives them no
40
+ * moment to act on.
41
+ */
42
+ export const quotaTone = (fraction) => fraction >= 0.9 ? 'danger' : fraction >= 0.75 ? 'attention' : 'success';
43
+ /**
44
+ * What the breakdown should show: the rows, nothing, or a refusal to guess.
45
+ *
46
+ * `unreadable` is not `empty`. The gateway sends no rows in both cases —
47
+ * because nobody spent anything, or because it could not read the ledger —
48
+ * and drawing them the same way tells a reader "your agents were quiet"
49
+ * when the truth is "we cannot tell you". They act on that differently.
50
+ */
51
+ export const breakdownState = (usage) => {
52
+ if (!usage || usage.quotas?.creditsPerDay?.unknown) {
53
+ return 'unreadable';
54
+ }
55
+ return (usage.byAgent ?? []).length > 0 ? 'rows' : 'empty';
56
+ };
57
+ /**
58
+ * The rows, keyed the way the gateway grouped them.
59
+ *
60
+ * The agent uid first: service agents reach Runtimes through the gateway and
61
+ * carry *its* client id, so keying on that would collapse an organization's
62
+ * pipelines into one row costing the sum of several.
63
+ */
64
+ export const spendRowsOf = (byAgent) => byAgent.map((entry, index) => ({
65
+ ...entry,
66
+ id: entry.agentUid || entry.clientId || String(index),
67
+ }));
68
+ const QuotaCard = ({ label, hint, quota, }) => {
69
+ const limit = quota?.limit;
70
+ const used = quota?.used;
71
+ const fraction = quota?.fraction;
72
+ return (_jsxs(Box, { sx: {
73
+ border: '1px solid',
74
+ borderColor: 'border.default',
75
+ borderRadius: 2,
76
+ p: 3,
77
+ flex: '1 1 220px',
78
+ minWidth: 0,
79
+ }, children: [_jsx(Text, { sx: { fontWeight: 'bold', fontSize: 1 }, children: label }), _jsx(Box, { sx: { mt: 2, display: 'flex', alignItems: 'baseline', gap: 2 }, children: quota?.unknown ? (_jsx(Text, { sx: { fontSize: 2, color: 'fg.muted' }, children: "Not available" })) : (_jsxs(_Fragment, { children: [_jsx(Text, { sx: { fontSize: 4, fontWeight: 'bold' }, children: typeof used === 'number' ? amount(used) : '—' }), _jsx(Text, { sx: { fontSize: 1, color: 'fg.muted' }, children: typeof limit === 'number'
80
+ ? `of ${amount(limit)}`
81
+ : 'no limit set' })] })) }), typeof fraction === 'number' && (_jsx(Box, { sx: { mt: 2 }, children: _jsx(ProgressBar, { progress: Math.min(100, fraction * 100), barSize: "small", bg: `${quotaTone(fraction)}.emphasis`, "aria-label": `${label}: ${Math.round(fraction * 100)}% of the limit` }) })), _jsx(Text, { as: "p", sx: { mt: 2, mb: 0, fontSize: 0, color: 'fg.muted' }, children: quota?.unknown ? quota.unknown : hint })] }));
82
+ };
83
+ export const OrganizationUsage = ({ errorState, orgUid, teamUid, showTitle = true, }) => {
84
+ const usage = useOrgMcpUsage(orgUid, teamUid ? { team: teamUid } : {});
85
+ const rows = useMemo(() => spendRowsOf(usage.data?.byAgent ?? []), [usage.data]);
86
+ if (usage.isLoading) {
87
+ return (_jsx(Box, { sx: { display: 'flex', justifyContent: 'center', p: 6 }, children: _jsx(Spinner, {}) }));
88
+ }
89
+ if (usage.isError) {
90
+ return (_jsx(McpErrorBlankslate, { state: errorState(usage.error, 'The usage'), onRetry: () => void usage.refetch() }));
91
+ }
92
+ const quotas = usage.data?.quotas ?? {};
93
+ const breakdown = breakdownState(usage.data);
94
+ return (_jsxs(Box, { children: [showTitle && (_jsx(Heading, { as: "h2", sx: { fontSize: 3, mb: 1 }, children: "Usage" })), _jsx(Text, { as: "p", sx: { color: 'fg.muted', mt: 0, mb: 3 }, children: "What this organization's agents used over the last day, against what they may use. Limits are set in the organization's MCP policy, not here." }), _jsx(Box, { sx: { display: 'flex', flexWrap: 'wrap', gap: 3 }, children: QUOTAS.map(quota => (_jsx(QuotaCard, { label: quota.label, hint: quota.hint, quota: quotas[quota.key] }, quota.key))) }), _jsx(Heading, { as: "h3", sx: { fontSize: 2, mt: 4, mb: 2 }, children: "Credits by agent" }), breakdown === 'unreadable' ? (_jsxs(Blankslate, { border: true, children: [_jsx(Blankslate.Visual, { children: _jsx(GraphIcon, { size: "medium" }) }), _jsx(Blankslate.Heading, { children: "The day's spend could not be read" }), _jsx(Blankslate.Description, { children: _jsx(Text, { as: "p", sx: { textAlign: 'center' }, children: "A breakdown of a total nobody could read would make every agent look cheap. Try again in a moment." }) })] })) : breakdown === 'empty' ? (_jsxs(Blankslate, { border: true, children: [_jsx(Blankslate.Visual, { children: _jsx(GraphIcon, { size: "medium" }) }), _jsx(Blankslate.Heading, { children: "No agent spent credits today" }), _jsx(Blankslate.Description, { children: _jsx(Text, { as: "p", sx: { textAlign: 'center' }, children: "Work a person ran themselves is in the total above, and is not an agent's." }) })] })) : (_jsx(Table.Container, { children: _jsx(DataTable, { "aria-labelledby": "usage-by-agent", data: rows, columns: [
95
+ {
96
+ header: 'Agent',
97
+ field: 'clientId',
98
+ rowHeader: true,
99
+ renderCell: row => row.clientId ? (_jsx(ClientBadge, { clientId: row.clientId })) : (_jsx(Label, { variant: "secondary", children: row.agentUid })),
100
+ },
101
+ {
102
+ header: 'Credits',
103
+ field: 'credits',
104
+ renderCell: row => amount(row.credits),
105
+ },
106
+ {
107
+ header: 'Records',
108
+ field: 'records',
109
+ renderCell: row => String(row.records),
110
+ },
111
+ ] }) }))] }));
112
+ };
113
+ export default OrganizationUsage;
@@ -0,0 +1,54 @@
1
+ /**
2
+ * The rules a person sets for their own agents.
3
+ *
4
+ * The same six rules as an organization's layer, over the same
5
+ * `PolicyForm` — but they mean something narrower here, and the difference
6
+ * is the whole reason this page needs saying anything at all.
7
+ *
8
+ * **A personal layer only narrows.** Every layer intersects: the platform's
9
+ * defaults, then the organization's, then the team's, then this. Denying a
10
+ * tool here denies it. *Permitting* one an organization denies does nothing
11
+ * — the denial unions across layers and cannot be lifted from below. A cap
12
+ * of 60 under an organization's 30 leaves the effective cap at 30.
13
+ *
14
+ * So the page compares what is typed against the organizations the person
15
+ * belongs to and says, **beside the field while their hands are on it**,
16
+ * where a value will have no effect and why.
17
+ *
18
+ * It does not *refuse* those values, and that is deliberate. The same
19
+ * personal layer applies to personal-scope work, where no organization
20
+ * narrows anything — a rule that is wider than one employer's is still the
21
+ * rule that governs an agent acting for the person alone. Refusing it would
22
+ * make somebody's own policy unwritable because of a place they happen to
23
+ * work.
24
+ *
25
+ * @module views/mcp/PersonalPolicy
26
+ */
27
+ import type { JSX } from 'react';
28
+ import { type McpPolicyRules } from '../../api/iam/mcpPolicy';
29
+ import type { McpErrorStateFn } from './types';
30
+ /** One organization the person belongs to, and what it narrows. */
31
+ export interface NarrowingOrganization {
32
+ uid: string;
33
+ name: string;
34
+ rules: McpPolicyRules | null;
35
+ }
36
+ export interface PersonalPolicyProps {
37
+ errorState: McpErrorStateFn;
38
+ /** The person whose layer this is. */
39
+ userUid: string;
40
+ /**
41
+ * The organizations they belong to, with each one's layer.
42
+ *
43
+ * Empty is the ordinary case for somebody with no organization, and the
44
+ * page simply says nothing about narrowing.
45
+ */
46
+ organizations?: NarrowingOrganization[];
47
+ showTitle?: boolean;
48
+ }
49
+ /** A list rule already denied elsewhere, as a sentence naming who. */
50
+ export declare const deniedElsewhere: (typed: string, organizations: NarrowingOrganization[]) => string[];
51
+ /** A number rule already capped lower elsewhere. */
52
+ export declare const cappedLower: (typed: string, organizations: NarrowingOrganization[], rule: "maxCallsPerMinute" | "maxCreditsPerDay" | "maxConcurrentSandboxes") => string[];
53
+ export declare const PersonalPolicy: ({ errorState, userUid, organizations, showTitle, }: PersonalPolicyProps) => JSX.Element;
54
+ export default PersonalPolicy;