@burdenoff/microfe-botmanor 2026.1108.1 → 2026.1109.2

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 (335) hide show
  1. package/dist/botlit/BotlitRoutes.d.ts +2 -0
  2. package/dist/botlit/BotlitRoutes.js +40 -52
  3. package/dist/botlit/BotlitRoutes.js.map +1 -1
  4. package/dist/botlit/BotmanorRoot.d.ts +3 -0
  5. package/dist/botlit/BotmanorRoot.js +1 -2
  6. package/dist/botlit/BotmanorRoot.js.map +1 -1
  7. package/dist/botlit/BotmanorRootInner.d.ts +3 -0
  8. package/dist/botlit/BotmanorRootInner.js +9 -10
  9. package/dist/botlit/BotmanorRootInner.js.map +1 -1
  10. package/dist/botlit/components/AgentApprovalPanel.d.ts +20 -0
  11. package/dist/botlit/components/AgentApprovalPanel.js +49 -50
  12. package/dist/botlit/components/AgentApprovalPanel.js.map +1 -1
  13. package/dist/botlit/components/AiOperationsPanel.d.ts +14 -0
  14. package/dist/botlit/components/AiOperationsPanel.js +54 -55
  15. package/dist/botlit/components/AiOperationsPanel.js.map +1 -1
  16. package/dist/botlit/components/AssistantChannelPanel.d.ts +3 -0
  17. package/dist/botlit/components/AssistantChannelPanel.js +12 -13
  18. package/dist/botlit/components/AssistantChannelPanel.js.map +1 -1
  19. package/dist/botlit/components/AssistantRuntimeSetupPanel.d.ts +4 -0
  20. package/dist/botlit/components/AssistantRuntimeSetupPanel.js +14 -14
  21. package/dist/botlit/components/AssistantRuntimeSetupPanel.js.map +1 -1
  22. package/dist/botlit/components/AssistantWebsitePanel.d.ts +5 -0
  23. package/dist/botlit/components/AssistantWebsitePanel.js +15 -16
  24. package/dist/botlit/components/AssistantWebsitePanel.js.map +1 -1
  25. package/dist/botlit/components/Badge.d.ts +9 -0
  26. package/dist/botlit/components/Badge.js +1 -2
  27. package/dist/botlit/components/Badge.js.map +1 -1
  28. package/dist/botlit/components/Button.d.ts +10 -0
  29. package/dist/botlit/components/Button.js +1 -2
  30. package/dist/botlit/components/Button.js.map +1 -1
  31. package/dist/botlit/components/Card.d.ts +16 -0
  32. package/dist/botlit/components/Card.js +1 -2
  33. package/dist/botlit/components/Card.js.map +1 -1
  34. package/dist/botlit/components/ChannelSelectorSheet.d.ts +23 -0
  35. package/dist/botlit/components/ChannelSelectorSheet.js +1 -2
  36. package/dist/botlit/components/ChannelSelectorSheet.js.map +1 -1
  37. package/dist/botlit/components/EmptyState.d.ts +12 -0
  38. package/dist/botlit/components/EmptyState.js +1 -2
  39. package/dist/botlit/components/EmptyState.js.map +1 -1
  40. package/dist/botlit/components/ErrorState.d.ts +10 -0
  41. package/dist/botlit/components/ErrorState.js +5 -6
  42. package/dist/botlit/components/ErrorState.js.map +1 -1
  43. package/dist/botlit/components/Input.d.ts +27 -0
  44. package/dist/botlit/components/Input.js +1 -2
  45. package/dist/botlit/components/Input.js.map +1 -1
  46. package/dist/botlit/components/KnowledgeSourceImportPanel.d.ts +3 -0
  47. package/dist/botlit/components/KnowledgeSourceImportPanel.js +12 -13
  48. package/dist/botlit/components/KnowledgeSourceImportPanel.js.map +1 -1
  49. package/dist/botlit/components/ModelRegistrationPanel.d.ts +5 -0
  50. package/dist/botlit/components/ModelRegistrationPanel.js +1 -2
  51. package/dist/botlit/components/ModelRegistrationPanel.js.map +1 -1
  52. package/dist/botlit/components/PageLayout.d.ts +12 -0
  53. package/dist/botlit/components/PageLayout.js +1 -2
  54. package/dist/botlit/components/PageLayout.js.map +1 -1
  55. package/dist/botlit/components/QuotaExhaustedDialog.d.ts +9 -0
  56. package/dist/botlit/components/QuotaExhaustedDialog.js +1 -2
  57. package/dist/botlit/components/QuotaExhaustedDialog.js.map +1 -1
  58. package/dist/botlit/components/RetentionStatusPanel.d.ts +2 -0
  59. package/dist/botlit/components/RetentionStatusPanel.js +18 -19
  60. package/dist/botlit/components/RetentionStatusPanel.js.map +1 -1
  61. package/dist/botlit/components/RouteLoader.d.ts +23 -0
  62. package/dist/botlit/components/RouteLoader.js +1 -2
  63. package/dist/botlit/components/RouteLoader.js.map +1 -1
  64. package/dist/botlit/components/VersionHistoryPanel.d.ts +12 -0
  65. package/dist/botlit/components/VersionHistoryPanel.js +23 -24
  66. package/dist/botlit/components/VersionHistoryPanel.js.map +1 -1
  67. package/dist/botlit/components/WorkspaceRequired.d.ts +18 -0
  68. package/dist/botlit/components/WorkspaceRequired.js +1 -2
  69. package/dist/botlit/components/WorkspaceRequired.js.map +1 -1
  70. package/dist/botlit/components/index.d.ts +14 -0
  71. package/dist/botlit/hooks/index.d.ts +35 -0
  72. package/dist/botlit/hooks/index.js +16 -16
  73. package/dist/botlit/hooks/internal/mutationInput.d.ts +56 -0
  74. package/dist/botlit/hooks/internal/mutationInput.js +1 -2
  75. package/dist/botlit/hooks/internal/mutationInput.js.map +1 -1
  76. package/dist/botlit/hooks/internal/workspaceGateway.d.ts +54 -0
  77. package/dist/botlit/hooks/internal/workspaceGateway.js +17 -19
  78. package/dist/botlit/hooks/internal/workspaceGateway.js.map +1 -1
  79. package/dist/botlit/hooks/useA2A.d.ts +104 -0
  80. package/dist/botlit/hooks/useA2A.js +45 -45
  81. package/dist/botlit/hooks/useA2A.js.map +1 -1
  82. package/dist/botlit/hooks/useAgentApprovals.d.ts +62 -0
  83. package/dist/botlit/hooks/useAgentApprovals.js +38 -39
  84. package/dist/botlit/hooks/useAgentApprovals.js.map +1 -1
  85. package/dist/botlit/hooks/useAgents.d.ts +105 -0
  86. package/dist/botlit/hooks/useAgents.js +53 -54
  87. package/dist/botlit/hooks/useAgents.js.map +1 -1
  88. package/dist/botlit/hooks/useAiOperations.d.ts +95 -0
  89. package/dist/botlit/hooks/useAiOperations.js +20 -19
  90. package/dist/botlit/hooks/useAiOperations.js.map +1 -1
  91. package/dist/botlit/hooks/useAssistantChannels.d.ts +16 -0
  92. package/dist/botlit/hooks/useAssistantChannels.js +1 -2
  93. package/dist/botlit/hooks/useAssistantChannels.js.map +1 -1
  94. package/dist/botlit/hooks/useAssistantRuntimeSetup.d.ts +17 -0
  95. package/dist/botlit/hooks/useAssistantRuntimeSetup.js +1 -2
  96. package/dist/botlit/hooks/useAssistantRuntimeSetup.js.map +1 -1
  97. package/dist/botlit/hooks/useAssistantWebsites.d.ts +18 -0
  98. package/dist/botlit/hooks/useAssistantWebsites.js +1 -2
  99. package/dist/botlit/hooks/useAssistantWebsites.js.map +1 -1
  100. package/dist/botlit/hooks/useBotWorkflow.d.ts +22 -0
  101. package/dist/botlit/hooks/useBotWorkflow.js +1 -2
  102. package/dist/botlit/hooks/useBotWorkflow.js.map +1 -1
  103. package/dist/botlit/hooks/useBots.d.ts +68 -0
  104. package/dist/botlit/hooks/useBots.js +32 -33
  105. package/dist/botlit/hooks/useBots.js.map +1 -1
  106. package/dist/botlit/hooks/useBuckets.d.ts +62 -0
  107. package/dist/botlit/hooks/useBuckets.js +91 -58
  108. package/dist/botlit/hooks/useBuckets.js.map +1 -1
  109. package/dist/botlit/hooks/useChannels.d.ts +87 -0
  110. package/dist/botlit/hooks/useChannels.js +73 -73
  111. package/dist/botlit/hooks/useChannels.js.map +1 -1
  112. package/dist/botlit/hooks/useExecutions.d.ts +87 -0
  113. package/dist/botlit/hooks/useExecutions.js +37 -37
  114. package/dist/botlit/hooks/useExecutions.js.map +1 -1
  115. package/dist/botlit/hooks/useKnowledgeBases.d.ts +79 -0
  116. package/dist/botlit/hooks/useKnowledgeBases.js +40 -39
  117. package/dist/botlit/hooks/useKnowledgeBases.js.map +1 -1
  118. package/dist/botlit/hooks/useKnowledgeSourceImports.d.ts +21 -0
  119. package/dist/botlit/hooks/useKnowledgeSourceImports.js +1 -2
  120. package/dist/botlit/hooks/useKnowledgeSourceImports.js.map +1 -1
  121. package/dist/botlit/hooks/useLLMProviders.d.ts +66 -0
  122. package/dist/botlit/hooks/useLLMProviders.js +25 -26
  123. package/dist/botlit/hooks/useLLMProviders.js.map +1 -1
  124. package/dist/botlit/hooks/useMCPServers.d.ts +71 -0
  125. package/dist/botlit/hooks/useMCPServers.js +40 -38
  126. package/dist/botlit/hooks/useMCPServers.js.map +1 -1
  127. package/dist/botlit/hooks/usePolicies.d.ts +60 -0
  128. package/dist/botlit/hooks/usePolicies.js +49 -49
  129. package/dist/botlit/hooks/usePolicies.js.map +1 -1
  130. package/dist/botlit/hooks/usePromptTemplates.d.ts +88 -0
  131. package/dist/botlit/hooks/usePromptTemplates.js +57 -57
  132. package/dist/botlit/hooks/usePromptTemplates.js.map +1 -1
  133. package/dist/botlit/hooks/useRetention.d.ts +26 -0
  134. package/dist/botlit/hooks/useRetention.js +3 -3
  135. package/dist/botlit/hooks/useRetention.js.map +1 -1
  136. package/dist/botlit/hooks/useRetrievalProfiles.d.ts +75 -0
  137. package/dist/botlit/hooks/useRetrievalProfiles.js +47 -47
  138. package/dist/botlit/hooks/useRetrievalProfiles.js.map +1 -1
  139. package/dist/botlit/hooks/useSkills.d.ts +64 -0
  140. package/dist/botlit/hooks/useSkills.js +53 -53
  141. package/dist/botlit/hooks/useSkills.js.map +1 -1
  142. package/dist/botlit/hooks/useStore.d.ts +112 -0
  143. package/dist/botlit/hooks/useStore.js +55 -55
  144. package/dist/botlit/hooks/useStore.js.map +1 -1
  145. package/dist/botlit/hooks/useUserPlatformConnection.d.ts +80 -0
  146. package/dist/botlit/hooks/useUserPlatformConnection.js +19 -19
  147. package/dist/botlit/hooks/useUserPlatformConnection.js.map +1 -1
  148. package/dist/botlit/index.d.ts +15 -0
  149. package/dist/botlit/index.js +11 -11
  150. package/dist/botlit/pages/A2AAgentDetailPage.d.ts +6 -0
  151. package/dist/botlit/pages/A2AAgentDetailPage.js +171 -178
  152. package/dist/botlit/pages/A2AAgentDetailPage.js.map +1 -1
  153. package/dist/botlit/pages/A2ARegistryPage.d.ts +2 -0
  154. package/dist/botlit/pages/A2ARegistryPage.js +25 -26
  155. package/dist/botlit/pages/A2ARegistryPage.js.map +1 -1
  156. package/dist/botlit/pages/AgentApprovalsPage.d.ts +2 -0
  157. package/dist/botlit/pages/AgentApprovalsPage.js +32 -33
  158. package/dist/botlit/pages/AgentApprovalsPage.js.map +1 -1
  159. package/dist/botlit/pages/AgentBuilderPage.d.ts +2 -0
  160. package/dist/botlit/pages/AgentBuilderPage.js +59 -60
  161. package/dist/botlit/pages/AgentBuilderPage.js.map +1 -1
  162. package/dist/botlit/pages/AgentDetailPage.d.ts +2 -0
  163. package/dist/botlit/pages/AgentDetailPage.js +83 -84
  164. package/dist/botlit/pages/AgentDetailPage.js.map +1 -1
  165. package/dist/botlit/pages/AgentsListPage.d.ts +2 -0
  166. package/dist/botlit/pages/AgentsListPage.js +71 -72
  167. package/dist/botlit/pages/AgentsListPage.js.map +1 -1
  168. package/dist/botlit/pages/AiOperationsPage.d.ts +2 -0
  169. package/dist/botlit/pages/AiOperationsPage.js +52 -53
  170. package/dist/botlit/pages/AiOperationsPage.js.map +1 -1
  171. package/dist/botlit/pages/BotChannelsTab.d.ts +7 -0
  172. package/dist/botlit/pages/BotChannelsTab.js +120 -122
  173. package/dist/botlit/pages/BotChannelsTab.js.map +1 -1
  174. package/dist/botlit/pages/BotDetailPage.d.ts +7 -0
  175. package/dist/botlit/pages/BotDetailPage.js +353 -358
  176. package/dist/botlit/pages/BotDetailPage.js.map +1 -1
  177. package/dist/botlit/pages/BotWorkflowTab.d.ts +11 -0
  178. package/dist/botlit/pages/BotWorkflowTab.js +20 -21
  179. package/dist/botlit/pages/BotWorkflowTab.js.map +1 -1
  180. package/dist/botlit/pages/BotsListPage.d.ts +2 -0
  181. package/dist/botlit/pages/BotsListPage.js +52 -53
  182. package/dist/botlit/pages/BotsListPage.js.map +1 -1
  183. package/dist/botlit/pages/BucketDetailPage.d.ts +2 -0
  184. package/dist/botlit/pages/BucketDetailPage.js +251 -0
  185. package/dist/botlit/pages/BucketDetailPage.js.map +1 -0
  186. package/dist/botlit/pages/BucketsPage.d.ts +2 -0
  187. package/dist/botlit/pages/BucketsPage.js +260 -261
  188. package/dist/botlit/pages/BucketsPage.js.map +1 -1
  189. package/dist/botlit/pages/ChannelDetailPage.d.ts +6 -0
  190. package/dist/botlit/pages/ChannelDetailPage.js +97 -96
  191. package/dist/botlit/pages/ChannelDetailPage.js.map +1 -1
  192. package/dist/botlit/pages/ChannelRoutesPage.d.ts +2 -0
  193. package/dist/botlit/pages/ChannelRoutesPage.js +23 -24
  194. package/dist/botlit/pages/ChannelRoutesPage.js.map +1 -1
  195. package/dist/botlit/pages/ChannelsPage.d.ts +2 -0
  196. package/dist/botlit/pages/ChannelsPage.js +44 -45
  197. package/dist/botlit/pages/ChannelsPage.js.map +1 -1
  198. package/dist/botlit/pages/ChatPage.d.ts +1 -0
  199. package/dist/botlit/pages/ChatPage.js +10 -11
  200. package/dist/botlit/pages/ChatPage.js.map +1 -1
  201. package/dist/botlit/pages/DashboardPage.d.ts +2 -0
  202. package/dist/botlit/pages/DashboardPage.js +37 -38
  203. package/dist/botlit/pages/DashboardPage.js.map +1 -1
  204. package/dist/botlit/pages/ExecutionDetailPage.d.ts +2 -0
  205. package/dist/botlit/pages/ExecutionDetailPage.js +47 -48
  206. package/dist/botlit/pages/ExecutionDetailPage.js.map +1 -1
  207. package/dist/botlit/pages/ExecutionsPage.d.ts +2 -0
  208. package/dist/botlit/pages/ExecutionsPage.js +72 -70
  209. package/dist/botlit/pages/ExecutionsPage.js.map +1 -1
  210. package/dist/botlit/pages/InstalledPackagesPage.d.ts +2 -0
  211. package/dist/botlit/pages/InstalledPackagesPage.js +77 -78
  212. package/dist/botlit/pages/InstalledPackagesPage.js.map +1 -1
  213. package/dist/botlit/pages/KnowledgeBaseDetailPage.d.ts +6 -0
  214. package/dist/botlit/pages/KnowledgeBaseDetailPage.js +171 -181
  215. package/dist/botlit/pages/KnowledgeBaseDetailPage.js.map +1 -1
  216. package/dist/botlit/pages/KnowledgeBasesPage.d.ts +2 -0
  217. package/dist/botlit/pages/KnowledgeBasesPage.js +30 -31
  218. package/dist/botlit/pages/KnowledgeBasesPage.js.map +1 -1
  219. package/dist/botlit/pages/MCPServerDetailPage.d.ts +6 -0
  220. package/dist/botlit/pages/MCPServerDetailPage.js +82 -83
  221. package/dist/botlit/pages/MCPServerDetailPage.js.map +1 -1
  222. package/dist/botlit/pages/MCPServersPage.d.ts +2 -0
  223. package/dist/botlit/pages/MCPServersPage.js +54 -55
  224. package/dist/botlit/pages/MCPServersPage.js.map +1 -1
  225. package/dist/botlit/pages/PoliciesPage.d.ts +2 -0
  226. package/dist/botlit/pages/PoliciesPage.js +25 -26
  227. package/dist/botlit/pages/PoliciesPage.js.map +1 -1
  228. package/dist/botlit/pages/PolicyDetailPage.d.ts +6 -0
  229. package/dist/botlit/pages/PolicyDetailPage.js +257 -259
  230. package/dist/botlit/pages/PolicyDetailPage.js.map +1 -1
  231. package/dist/botlit/pages/PromptStudioPage.d.ts +2 -0
  232. package/dist/botlit/pages/PromptStudioPage.js +35 -35
  233. package/dist/botlit/pages/PromptStudioPage.js.map +1 -1
  234. package/dist/botlit/pages/PromptTemplateDetailPage.d.ts +6 -0
  235. package/dist/botlit/pages/PromptTemplateDetailPage.js +363 -362
  236. package/dist/botlit/pages/PromptTemplateDetailPage.js.map +1 -1
  237. package/dist/botlit/pages/PromptTemplatesPage.d.ts +2 -0
  238. package/dist/botlit/pages/PromptTemplatesPage.js +26 -27
  239. package/dist/botlit/pages/PromptTemplatesPage.js.map +1 -1
  240. package/dist/botlit/pages/RetrievalProfileDetailPage.d.ts +6 -0
  241. package/dist/botlit/pages/RetrievalProfileDetailPage.js +150 -158
  242. package/dist/botlit/pages/RetrievalProfileDetailPage.js.map +1 -1
  243. package/dist/botlit/pages/RetrievalProfilesPage.d.ts +2 -0
  244. package/dist/botlit/pages/RetrievalProfilesPage.js +24 -25
  245. package/dist/botlit/pages/RetrievalProfilesPage.js.map +1 -1
  246. package/dist/botlit/pages/SettingsPage.d.ts +2 -0
  247. package/dist/botlit/pages/SettingsPage.js +124 -125
  248. package/dist/botlit/pages/SettingsPage.js.map +1 -1
  249. package/dist/botlit/pages/SkillDetailPage.d.ts +6 -0
  250. package/dist/botlit/pages/SkillDetailPage.js +216 -217
  251. package/dist/botlit/pages/SkillDetailPage.js.map +1 -1
  252. package/dist/botlit/pages/SkillsPage.d.ts +2 -0
  253. package/dist/botlit/pages/SkillsPage.js +24 -25
  254. package/dist/botlit/pages/SkillsPage.js.map +1 -1
  255. package/dist/botlit/pages/StorePackageDetailPage.d.ts +2 -0
  256. package/dist/botlit/pages/StorePackageDetailPage.js +38 -39
  257. package/dist/botlit/pages/StorePackageDetailPage.js.map +1 -1
  258. package/dist/botlit/pages/StorePage.d.ts +2 -0
  259. package/dist/botlit/pages/StorePage.js +135 -136
  260. package/dist/botlit/pages/StorePage.js.map +1 -1
  261. package/dist/botlit/pages/index.d.ts +38 -0
  262. package/dist/botlit/permissions/PermissionRequired.d.ts +20 -0
  263. package/dist/botlit/permissions/PermissionRequired.js +10 -11
  264. package/dist/botlit/permissions/PermissionRequired.js.map +1 -1
  265. package/dist/botlit/permissions/botmanorPermissions.d.ts +82 -0
  266. package/dist/botlit/permissions/botmanorPermissions.js +1 -2
  267. package/dist/botlit/permissions/botmanorPermissions.js.map +1 -1
  268. package/dist/botlit/permissions/index.d.ts +7 -0
  269. package/dist/botlit/permissions/index.js +4 -3
  270. package/dist/botlit/permissions/useBotmanorPermissions.d.ts +41 -0
  271. package/dist/botlit/permissions/useBotmanorPermissions.js +1 -2
  272. package/dist/botlit/permissions/useBotmanorPermissions.js.map +1 -1
  273. package/dist/botlit/providers/BotlitProvider.d.ts +14 -0
  274. package/dist/botlit/providers/BotlitProvider.js +3 -3
  275. package/dist/botlit/providers/BotlitProvider.js.map +1 -1
  276. package/dist/botlit/store/botlitStore.d.ts +85 -0
  277. package/dist/botlit/store/botlitStore.js +1 -2
  278. package/dist/botlit/store/botlitStore.js.map +1 -1
  279. package/dist/botlit/store/renamedKeyStorage.d.ts +13 -0
  280. package/dist/botlit/store/renamedKeyStorage.js +1 -2
  281. package/dist/botlit/store/renamedKeyStorage.js.map +1 -1
  282. package/dist/botlit/types/index.d.ts +1008 -0
  283. package/dist/botlit/utils/cn.d.ts +2 -0
  284. package/dist/botlit/utils/cn.js +1 -2
  285. package/dist/botlit/utils/cn.js.map +1 -1
  286. package/dist/botlit/utils/embedding-models.d.ts +9 -0
  287. package/dist/botlit/utils/embedding-models.js +1 -2
  288. package/dist/botlit/utils/embedding-models.js.map +1 -1
  289. package/dist/botlit/utils/errors.d.ts +19 -0
  290. package/dist/botlit/utils/errors.js +1 -2
  291. package/dist/botlit/utils/errors.js.map +1 -1
  292. package/dist/botlit/utils/formatters.d.ts +38 -0
  293. package/dist/botlit/utils/formatters.js +0 -1
  294. package/dist/botlit/utils/formatters.js.map +1 -1
  295. package/dist/botlit/utils/navigation.d.ts +19 -0
  296. package/dist/botlit/utils/navigation.js +1 -2
  297. package/dist/botlit/utils/navigation.js.map +1 -1
  298. package/dist/botlit/utils/policyConfig.d.ts +68 -0
  299. package/dist/botlit/utils/policyConfig.js +2 -3
  300. package/dist/botlit/utils/policyConfig.js.map +1 -1
  301. package/dist/botlit/utils/unions.d.ts +25 -0
  302. package/dist/botlit/utils/unions.js +1 -2
  303. package/dist/botlit/utils/unions.js.map +1 -1
  304. package/dist/dev/App.d.ts +2 -0
  305. package/dist/dev/main.d.ts +0 -0
  306. package/dist/generated/global-operations.d.ts +197 -0
  307. package/dist/generated/global-operations.js +1 -2
  308. package/dist/generated/global-operations.js.map +1 -1
  309. package/dist/generated/global-types.d.ts +27678 -0
  310. package/dist/generated/global-types.js +1 -2
  311. package/dist/generated/global-types.js.map +1 -1
  312. package/dist/generated/wspace-operations.d.ts +5489 -0
  313. package/dist/generated/wspace-operations.js +88 -84
  314. package/dist/generated/wspace-operations.js.map +1 -1
  315. package/dist/generated/wspace-types.d.ts +152017 -0
  316. package/dist/generated/wspace-types.js +1 -2
  317. package/dist/generated/wspace-types.js.map +1 -1
  318. package/dist/index.d.ts +5 -0
  319. package/dist/index.js +5 -6
  320. package/dist/shared/hooks/useTr.d.ts +16 -0
  321. package/dist/shared/hooks/useTr.js +1 -2
  322. package/dist/shared/hooks/useTr.js.map +1 -1
  323. package/dist/stories/Badge.stories.d.ts +11 -0
  324. package/dist/stories/Button.stories.d.ts +13 -0
  325. package/dist/stories/EmptyState.stories.d.ts +8 -0
  326. package/dist/stories/StatusBadge.stories.d.ts +9 -0
  327. package/dist/test/fixtures.d.ts +39 -0
  328. package/dist/test/happydom.d.ts +1 -0
  329. package/dist/test/renderPage.d.ts +18 -0
  330. package/dist/test/setup.d.ts +9 -0
  331. package/dist/utils/nativeBridge.d.ts +2 -0
  332. package/dist/utils/nativeBridge.js +1 -2
  333. package/package.json +87 -60
  334. package/dist/botlit/hooks/useConversations.js +0 -64
  335. package/dist/botlit/hooks/useConversations.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"AiOperationsPanel.js","names":[],"sources":["../../../src/botlit/components/AiOperationsPanel.tsx"],"sourcesContent":["/**\n * AI Operations Panel (BOFF-3839)\n * @module botlit/components\n *\n * The decision-card list at the heart of the supervisor feed. Rendered by the\n * workspace-wide /botmanor/ai page and, narrowed with `filter`, as a slice on\n * the agent and bot detail pages. Accept always confirms first and then\n * applies the recommendation through the existing mutation for the finding\n * type (rebuild index, pause agent) before marking the finding ACCEPTED;\n * findings without a safe one-click action are acknowledged with a deep link\n * to the subject. Dismiss records the signal and suppresses same-day\n * re-fires (fingerprint bucket, enforced server-side).\n */\n\nimport type { FC, ReactNode } from 'react';\nimport { useCallback, useMemo, useState } from 'react';\nimport { useNavigate } from 'react-router';\nimport {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n} from '@burdenoff/fe-libs/ui';\nimport { Check, ShieldAlert, X } from 'lucide-react';\nimport {\n PauseBotmanorAgentForSupervisorDocument,\n RebuildKnowledgeBaseIndexForSupervisorDocument,\n type PauseBotmanorAgentForSupervisorMutation,\n type RebuildKnowledgeBaseIndexForSupervisorMutation,\n} from '../../generated/wspace-operations';\nimport { AiPredictionStatus } from '../../generated/wspace-types';\nimport { useTr } from '../../shared/hooks/useTr';\nimport { cn } from '../utils/cn';\nimport { formatRelativeTime } from '../utils/formatters';\nimport { Badge } from './Badge';\nimport { Button } from './Button';\nimport { Card, CardContent } from './Card';\nimport { EmptyState } from './EmptyState';\nimport { ErrorState } from './ErrorState';\nimport { useWorkspaceClient } from '../hooks/internal/workspaceGateway';\nimport {\n predictionSeverity,\n predictionSubjectName,\n useAiPredictions,\n useSetAiPredictionStatus,\n type AiPredictionRecord,\n type AiPredictionsFilter,\n} from '../hooks/useAiOperations';\n\nconst SEVERITY_VARIANTS: Record<\n string,\n 'default' | 'secondary' | 'warning' | 'destructive' | 'outline'\n> = {\n CRITICAL: 'destructive',\n WARNING: 'warning',\n INFO: 'secondary',\n};\n\nconst SEVERITY_LABEL_KEYS: Record<string, string> = {\n CRITICAL: 'botlit.aiOperations.severity.critical',\n WARNING: 'botlit.aiOperations.severity.warning',\n INFO: 'botlit.aiOperations.severity.info',\n};\n\nconst TYPE_LABEL_KEYS: Record<string, string> = {\n failure_rate_regression: 'botlit.aiOperations.type.failureRateRegression',\n grounding_decay: 'botlit.aiOperations.type.groundingDecay',\n cost_anomaly: 'botlit.aiOperations.type.costAnomaly',\n latency_drift: 'botlit.aiOperations.type.latencyDrift',\n stalled_index: 'botlit.aiOperations.type.stalledIndex',\n idle_agent: 'botlit.aiOperations.type.idleAgent',\n stale_knowledge: 'botlit.aiOperations.type.staleKnowledge',\n};\n\ninterface AcceptAction {\n /** Existing mutation that applies the recommendation. */\n kind: 'rebuild-index' | 'pause-agent';\n /** Dynamic confirmation copy. */\n confirmTitle: string;\n confirmBody: string;\n /** Fallback deep-link target when there is no one-click action. */\n acknowledgeOnly?: false;\n}\n\n/** Maps a finding to its Accept action, or null when Accept is not offered. */\nfunction acceptActionFor(\n record: AiPredictionRecord,\n t: ReturnType<typeof useTr>\n): AcceptAction | null {\n switch (record.predictionType) {\n case 'stalled_index':\n if (record.subjectType !== 'KNOWLEDGE_BASE' || !record.subjectId) return null;\n return {\n kind: 'rebuild-index',\n confirmTitle: t(\n 'botlit.aiOperations.confirm.rebuildTitle',\n 'Rebuild the knowledge base index?'\n ),\n confirmBody: t(\n 'botlit.aiOperations.confirm.rebuildBody',\n 'This rebuilds the index for this knowledge base so agents can retrieve from it again. The finding is marked accepted afterwards.'\n ),\n };\n case 'failure_rate_regression':\n case 'idle_agent':\n if (record.subjectType !== 'AGENT' || !record.subjectId) return null;\n return {\n kind: 'pause-agent',\n confirmTitle: t('botlit.aiOperations.confirm.pauseTitle', 'Pause this agent?'),\n confirmBody: t(\n 'botlit.aiOperations.confirm.pauseBody',\n 'The agent stops answering until a workspace member reactivates it. The finding is marked accepted afterwards.'\n ),\n };\n default:\n return null;\n }\n}\n\n/** Deep link to the subject for findings Accept cannot apply automatically. */\nfunction subjectLinkFor(record: AiPredictionRecord): string | null {\n if (!record.subjectId) return null;\n switch (record.subjectType) {\n case 'AGENT':\n return `/agents/${record.subjectId}`;\n case 'APP':\n return `/bots/${record.subjectId}`;\n case 'KNOWLEDGE_BASE':\n return `/knowledge/${record.subjectId}`;\n default:\n return null;\n }\n}\n\nfunction evidenceSummary(record: AiPredictionRecord): Array<[string, string]> {\n const features = record.features ?? {};\n const entries: Array<[string, string]> = [];\n const push = (key: string, value: unknown): void => {\n if (typeof value === 'number')\n entries.push([key, Number.isInteger(value) ? String(value) : value.toFixed(4)]);\n else if (typeof value === 'string' && value.length > 0 && value.length < 80)\n entries.push([key, value]);\n };\n for (const [key, value] of Object.entries(features).slice(0, 6)) {\n if (key.endsWith('At') || key === 'knowledgeBaseIds' || key === 'agentIds') continue;\n push(key, value);\n }\n return entries.slice(0, 4);\n}\n\ninterface DecisionCardProps {\n record: AiPredictionRecord;\n busy: boolean;\n onAccept: (record: AiPredictionRecord) => void;\n onDismiss: (record: AiPredictionRecord) => void;\n}\n\nconst DecisionCard: FC<DecisionCardProps> = ({ record, busy, onAccept, onDismiss }) => {\n const t = useTr();\n const navigate = useNavigate();\n const severity = predictionSeverity(record);\n const subjectName = predictionSubjectName(record);\n const action = record.status === 'GENERATED' ? acceptActionFor(record, t) : null;\n const subjectLink = subjectLinkFor(record);\n const evidence = evidenceSummary(record);\n const isOpen = record.status === 'GENERATED';\n\n return (\n <Card className={cn('p-5', severity === 'CRITICAL' && 'glow')} data-testid=\"ai-operations-card\">\n <div className=\"flex items-start justify-between gap-3\">\n <div className=\"flex items-center gap-2 flex-wrap\">\n <Badge variant={SEVERITY_VARIANTS[severity] ?? 'secondary'}>\n {t(SEVERITY_LABEL_KEYS[severity] ?? SEVERITY_LABEL_KEYS.INFO, severity.toLowerCase())}\n </Badge>\n <Badge variant=\"outline\">\n {t(\n TYPE_LABEL_KEYS[record.predictionType] ?? 'botlit.aiOperations.type.unknown',\n record.predictionType.replace(/_/g, ' ')\n )}\n </Badge>\n <span className=\"text-sm text-text-secondary\">\n {t('botlit.aiOperations.onSubject', 'on {{name}}', { name: subjectName })}\n </span>\n </div>\n <span className=\"text-xs text-text-tertiary whitespace-nowrap\">\n {formatRelativeTime(record.generatedAt)}\n </span>\n </div>\n\n <p className=\"mt-3 text-sm text-text-primary\">{record.recommendation}</p>\n\n {evidence.length > 0 && (\n <dl className=\"mt-3 grid grid-cols-2 gap-x-4 gap-y-1 sm:grid-cols-4\">\n {evidence.map(([key, value]) => (\n <div key={key}>\n <dt className=\"text-xs text-text-tertiary\">{key}</dt>\n <dd className=\"text-sm text-text-secondary\">{value}</dd>\n </div>\n ))}\n </dl>\n )}\n\n {isOpen && (\n <div className=\"mt-4 flex items-center gap-2\">\n {action ? (\n <Button size=\"sm\" onClick={() => onAccept(record)} disabled={busy}>\n <Check className=\"h-4 w-4\" />\n {t('botlit.aiOperations.actions.accept', 'Accept')}\n </Button>\n ) : (\n subjectLink && (\n <Button\n size=\"sm\"\n variant=\"outline\"\n onClick={() => navigate(subjectLink)}\n disabled={busy}\n >\n <Check className=\"h-4 w-4\" />\n {t('botlit.aiOperations.actions.reviewSubject', 'Review subject')}\n </Button>\n )\n )}\n <Button size=\"sm\" variant=\"outline\" onClick={() => onDismiss(record)} disabled={busy}>\n <X className=\"h-4 w-4\" />\n {t('botlit.aiOperations.actions.dismiss', 'Dismiss')}\n </Button>\n </div>\n )}\n {!isOpen && (\n <div className=\"mt-4\">\n <Badge variant={record.status === 'ACCEPTED' ? 'success' : 'outline'}>\n {record.status}\n </Badge>\n </div>\n )}\n </Card>\n );\n};\n\nexport interface AiOperationsPanelProps {\n /** Narrow the feed to one subject (agent detail / bot detail slices). */\n filter?: AiPredictionsFilter;\n title?: string;\n description?: string;\n className?: string;\n}\n\n/**\n * The decision-card feed. Pure presentation over `useAiPredictions` — the\n * owning page composes it with config and run controls.\n */\nexport const AiOperationsPanel: FC<AiOperationsPanelProps> = ({\n filter,\n title,\n description,\n className,\n}) => {\n const t = useTr();\n const client = useWorkspaceClient();\n const { data: records, loading, error, refetch } = useAiPredictions(filter);\n const [setStatus, setStatusState] = useSetAiPredictionStatus();\n const [pendingAccept, setPendingAccept] = useState<AiPredictionRecord | null>(null);\n const [actionError, setActionError] = useState<string | null>(null);\n const busy = setStatusState.loading;\n\n const onDismiss = useCallback(\n async (record: AiPredictionRecord) => {\n setActionError(null);\n try {\n await setStatus({ id: record.id, status: AiPredictionStatus.Dismissed });\n await refetch();\n } catch (dismissError) {\n setActionError(dismissError instanceof Error ? dismissError.message : String(dismissError));\n }\n },\n [setStatus, refetch]\n );\n\n const applyAccept = useCallback(async () => {\n const record = pendingAccept;\n if (!record) return;\n setPendingAccept(null);\n setActionError(null);\n const action = acceptActionFor(record, t);\n try {\n if (action?.kind === 'rebuild-index' && record.subjectId) {\n await client.mutate<RebuildKnowledgeBaseIndexForSupervisorMutation>({\n mutation: RebuildKnowledgeBaseIndexForSupervisorDocument,\n variables: { knowledgeBaseId: record.subjectId },\n });\n } else if (action?.kind === 'pause-agent' && record.subjectId) {\n await client.mutate<PauseBotmanorAgentForSupervisorMutation>({\n mutation: PauseBotmanorAgentForSupervisorDocument,\n variables: { id: record.subjectId, input: { status: 'PAUSED' } },\n });\n }\n await setStatus({ id: record.id, status: AiPredictionStatus.Accepted });\n await refetch();\n } catch (acceptError) {\n setActionError(acceptError instanceof Error ? acceptError.message : String(acceptError));\n }\n }, [pendingAccept, client, setStatus, refetch, t]);\n\n const pendingAction = pendingAccept ? acceptActionFor(pendingAccept, t) : null;\n\n const content: ReactNode = useMemo(() => {\n if (error) {\n return (\n <ErrorState\n resource={t('botlit.aiOperations.errorTitle', 'AI operations findings')}\n error={error}\n onRetry={() => void refetch()}\n />\n );\n }\n if (loading && records.length === 0) {\n return (\n <div className=\"space-y-3\" aria-busy=\"true\">\n {[0, 1, 2].map((index) => (\n <Card key={index} className=\"p-5 h-28 animate-pulse bg-bg-subtle\">\n <span className=\"sr-only\">\n {t('botlit.aiOperations.loading', 'Loading findings')}\n </span>\n </Card>\n ))}\n </div>\n );\n }\n if (records.length === 0) {\n return (\n <EmptyState\n icon={<ShieldAlert className=\"h-8 w-8\" />}\n title={t('botlit.aiOperations.emptyTitle', 'No findings')}\n description={t(\n 'botlit.aiOperations.emptyDescription',\n 'The supervisor has not flagged anything. Enable the scheduled review to keep it that way.'\n )}\n />\n );\n }\n return (\n <div className=\"space-y-3\" data-testid=\"ai-operations-feed\">\n {records.map((record) => (\n <DecisionCard\n key={record.id}\n record={record}\n busy={busy}\n onAccept={(target) => setPendingAccept(target)}\n onDismiss={(target) => void onDismiss(target)}\n />\n ))}\n </div>\n );\n }, [error, loading, records, busy, onDismiss, refetch, t]);\n\n return (\n <section className={className} data-testid=\"ai-operations-panel\">\n {(title || description) && (\n <header className=\"mb-4\">\n {title && <h2 className=\"text-lg font-semibold text-text-primary\">{title}</h2>}\n {description && <p className=\"text-sm text-text-secondary\">{description}</p>}\n </header>\n )}\n {actionError && (\n <p className=\"mb-3 text-sm text-status-error-text\" role=\"alert\">\n {actionError}\n </p>\n )}\n {content}\n\n <AlertDialog\n open={pendingAccept != null}\n onOpenChange={(open) => !open && setPendingAccept(null)}\n >\n <AlertDialogContent>\n <AlertDialogHeader>\n <AlertDialogTitle>{pendingAction?.confirmTitle}</AlertDialogTitle>\n <AlertDialogDescription>{pendingAction?.confirmBody}</AlertDialogDescription>\n </AlertDialogHeader>\n <AlertDialogFooter>\n <AlertDialogCancel>\n {t('botlit.aiOperations.actions.cancel', 'Cancel')}\n </AlertDialogCancel>\n <AlertDialogAction onClick={() => void applyAccept()}>\n {t('botlit.aiOperations.actions.confirmAccept', 'Confirm')}\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n </section>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"AiOperationsPanel.js","names":["SEVERITY_VARIANTS","SEVERITY_LABEL_KEYS","TYPE_LABEL_KEYS","acceptActionFor","record","subjectLinkFor","evidenceSummary","features","entries","push","value","key","DecisionCard","t","useTr","navigate","useNavigate","severity","predictionSeverity","subjectName","predictionSubjectName","action","subjectLink","evidence","isOpen","Card","cn","Badge","formatRelativeTime","Button","onAccept","busy","Check","onDismiss","X","AiOperationsPanel","client","useWorkspaceClient","records","useAiPredictions","filter","setStatus","setStatusState","useSetAiPredictionStatus","pendingAccept","setPendingAccept","useState","actionError","setActionError","useCallback","AiPredictionStatus","refetch","dismissError","applyAccept","RebuildKnowledgeBaseIndexForSupervisorDocument","PauseBotmanorAgentForSupervisorDocument","acceptError","pendingAction","content","useMemo","error","ErrorState","loading","index","EmptyState","ShieldAlert","target","title","description","AlertDialog","open","AlertDialogContent","AlertDialogHeader","AlertDialogTitle","AlertDialogDescription","AlertDialogFooter","AlertDialogCancel","AlertDialogAction"],"sources":["../../../src/botlit/components/AiOperationsPanel.tsx"],"sourcesContent":["/**\n * AI Operations Panel (BOFF-3839)\n * @module botlit/components\n *\n * The decision-card list at the heart of the supervisor feed. Rendered by the\n * workspace-wide /botmanor/ai page and, narrowed with `filter`, as a slice on\n * the agent and bot detail pages. Accept always confirms first and then\n * applies the recommendation through the existing mutation for the finding\n * type (rebuild index, pause agent) before marking the finding ACCEPTED;\n * findings without a safe one-click action are acknowledged with a deep link\n * to the subject. Dismiss records the signal and suppresses same-day\n * re-fires (fingerprint bucket, enforced server-side).\n */\n\nimport type { FC, ReactNode } from 'react';\nimport { useCallback, useMemo, useState } from 'react';\nimport { useNavigate } from 'react-router';\nimport {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n} from '@burdenoff/fe-libs/ui';\nimport { Check, ShieldAlert, X } from 'lucide-react';\nimport {\n PauseBotmanorAgentForSupervisorDocument,\n RebuildKnowledgeBaseIndexForSupervisorDocument,\n type PauseBotmanorAgentForSupervisorMutation,\n type RebuildKnowledgeBaseIndexForSupervisorMutation,\n} from '../../generated/wspace-operations';\nimport { AiPredictionStatus } from '../../generated/wspace-types';\nimport { useTr } from '../../shared/hooks/useTr';\nimport { cn } from '../utils/cn';\nimport { formatRelativeTime } from '../utils/formatters';\nimport { Badge } from './Badge';\nimport { Button } from './Button';\nimport { Card, CardContent } from './Card';\nimport { EmptyState } from './EmptyState';\nimport { ErrorState } from './ErrorState';\nimport { useWorkspaceClient } from '../hooks/internal/workspaceGateway';\nimport {\n predictionSeverity,\n predictionSubjectName,\n useAiPredictions,\n useSetAiPredictionStatus,\n type AiPredictionRecord,\n type AiPredictionsFilter,\n} from '../hooks/useAiOperations';\n\nconst SEVERITY_VARIANTS: Record<\n string,\n 'default' | 'secondary' | 'warning' | 'destructive' | 'outline'\n> = {\n CRITICAL: 'destructive',\n WARNING: 'warning',\n INFO: 'secondary',\n};\n\nconst SEVERITY_LABEL_KEYS: Record<string, string> = {\n CRITICAL: 'botlit.aiOperations.severity.critical',\n WARNING: 'botlit.aiOperations.severity.warning',\n INFO: 'botlit.aiOperations.severity.info',\n};\n\nconst TYPE_LABEL_KEYS: Record<string, string> = {\n failure_rate_regression: 'botlit.aiOperations.type.failureRateRegression',\n grounding_decay: 'botlit.aiOperations.type.groundingDecay',\n cost_anomaly: 'botlit.aiOperations.type.costAnomaly',\n latency_drift: 'botlit.aiOperations.type.latencyDrift',\n stalled_index: 'botlit.aiOperations.type.stalledIndex',\n idle_agent: 'botlit.aiOperations.type.idleAgent',\n stale_knowledge: 'botlit.aiOperations.type.staleKnowledge',\n};\n\ninterface AcceptAction {\n /** Existing mutation that applies the recommendation. */\n kind: 'rebuild-index' | 'pause-agent';\n /** Dynamic confirmation copy. */\n confirmTitle: string;\n confirmBody: string;\n /** Fallback deep-link target when there is no one-click action. */\n acknowledgeOnly?: false;\n}\n\n/** Maps a finding to its Accept action, or null when Accept is not offered. */\nfunction acceptActionFor(\n record: AiPredictionRecord,\n t: ReturnType<typeof useTr>\n): AcceptAction | null {\n switch (record.predictionType) {\n case 'stalled_index':\n if (record.subjectType !== 'KNOWLEDGE_BASE' || !record.subjectId) return null;\n return {\n kind: 'rebuild-index',\n confirmTitle: t(\n 'botlit.aiOperations.confirm.rebuildTitle',\n 'Rebuild the knowledge base index?'\n ),\n confirmBody: t(\n 'botlit.aiOperations.confirm.rebuildBody',\n 'This rebuilds the index for this knowledge base so agents can retrieve from it again. The finding is marked accepted afterwards.'\n ),\n };\n case 'failure_rate_regression':\n case 'idle_agent':\n if (record.subjectType !== 'AGENT' || !record.subjectId) return null;\n return {\n kind: 'pause-agent',\n confirmTitle: t('botlit.aiOperations.confirm.pauseTitle', 'Pause this agent?'),\n confirmBody: t(\n 'botlit.aiOperations.confirm.pauseBody',\n 'The agent stops answering until a workspace member reactivates it. The finding is marked accepted afterwards.'\n ),\n };\n default:\n return null;\n }\n}\n\n/** Deep link to the subject for findings Accept cannot apply automatically. */\nfunction subjectLinkFor(record: AiPredictionRecord): string | null {\n if (!record.subjectId) return null;\n switch (record.subjectType) {\n case 'AGENT':\n return `/agents/${record.subjectId}`;\n case 'APP':\n return `/bots/${record.subjectId}`;\n case 'KNOWLEDGE_BASE':\n return `/knowledge/${record.subjectId}`;\n default:\n return null;\n }\n}\n\nfunction evidenceSummary(record: AiPredictionRecord): Array<[string, string]> {\n const features = record.features ?? {};\n const entries: Array<[string, string]> = [];\n const push = (key: string, value: unknown): void => {\n if (typeof value === 'number')\n entries.push([key, Number.isInteger(value) ? String(value) : value.toFixed(4)]);\n else if (typeof value === 'string' && value.length > 0 && value.length < 80)\n entries.push([key, value]);\n };\n for (const [key, value] of Object.entries(features).slice(0, 6)) {\n if (key.endsWith('At') || key === 'knowledgeBaseIds' || key === 'agentIds') continue;\n push(key, value);\n }\n return entries.slice(0, 4);\n}\n\ninterface DecisionCardProps {\n record: AiPredictionRecord;\n busy: boolean;\n onAccept: (record: AiPredictionRecord) => void;\n onDismiss: (record: AiPredictionRecord) => void;\n}\n\nconst DecisionCard: FC<DecisionCardProps> = ({ record, busy, onAccept, onDismiss }) => {\n const t = useTr();\n const navigate = useNavigate();\n const severity = predictionSeverity(record);\n const subjectName = predictionSubjectName(record);\n const action = record.status === 'GENERATED' ? acceptActionFor(record, t) : null;\n const subjectLink = subjectLinkFor(record);\n const evidence = evidenceSummary(record);\n const isOpen = record.status === 'GENERATED';\n\n return (\n <Card className={cn('p-5', severity === 'CRITICAL' && 'glow')} data-testid=\"ai-operations-card\">\n <div className=\"flex items-start justify-between gap-3\">\n <div className=\"flex items-center gap-2 flex-wrap\">\n <Badge variant={SEVERITY_VARIANTS[severity] ?? 'secondary'}>\n {t(SEVERITY_LABEL_KEYS[severity] ?? SEVERITY_LABEL_KEYS.INFO, severity.toLowerCase())}\n </Badge>\n <Badge variant=\"outline\">\n {t(\n TYPE_LABEL_KEYS[record.predictionType] ?? 'botlit.aiOperations.type.unknown',\n record.predictionType.replace(/_/g, ' ')\n )}\n </Badge>\n <span className=\"text-sm text-text-secondary\">\n {t('botlit.aiOperations.onSubject', 'on {{name}}', { name: subjectName })}\n </span>\n </div>\n <span className=\"text-xs text-text-tertiary whitespace-nowrap\">\n {formatRelativeTime(record.generatedAt)}\n </span>\n </div>\n\n <p className=\"mt-3 text-sm text-text-primary\">{record.recommendation}</p>\n\n {evidence.length > 0 && (\n <dl className=\"mt-3 grid grid-cols-2 gap-x-4 gap-y-1 sm:grid-cols-4\">\n {evidence.map(([key, value]) => (\n <div key={key}>\n <dt className=\"text-xs text-text-tertiary\">{key}</dt>\n <dd className=\"text-sm text-text-secondary\">{value}</dd>\n </div>\n ))}\n </dl>\n )}\n\n {isOpen && (\n <div className=\"mt-4 flex items-center gap-2\">\n {action ? (\n <Button size=\"sm\" onClick={() => onAccept(record)} disabled={busy}>\n <Check className=\"h-4 w-4\" />\n {t('botlit.aiOperations.actions.accept', 'Accept')}\n </Button>\n ) : (\n subjectLink && (\n <Button\n size=\"sm\"\n variant=\"outline\"\n onClick={() => navigate(subjectLink)}\n disabled={busy}\n >\n <Check className=\"h-4 w-4\" />\n {t('botlit.aiOperations.actions.reviewSubject', 'Review subject')}\n </Button>\n )\n )}\n <Button size=\"sm\" variant=\"outline\" onClick={() => onDismiss(record)} disabled={busy}>\n <X className=\"h-4 w-4\" />\n {t('botlit.aiOperations.actions.dismiss', 'Dismiss')}\n </Button>\n </div>\n )}\n {!isOpen && (\n <div className=\"mt-4\">\n <Badge variant={record.status === 'ACCEPTED' ? 'success' : 'outline'}>\n {record.status}\n </Badge>\n </div>\n )}\n </Card>\n );\n};\n\nexport interface AiOperationsPanelProps {\n /** Narrow the feed to one subject (agent detail / bot detail slices). */\n filter?: AiPredictionsFilter;\n title?: string;\n description?: string;\n className?: string;\n}\n\n/**\n * The decision-card feed. Pure presentation over `useAiPredictions` — the\n * owning page composes it with config and run controls.\n */\nexport const AiOperationsPanel: FC<AiOperationsPanelProps> = ({\n filter,\n title,\n description,\n className,\n}) => {\n const t = useTr();\n const client = useWorkspaceClient();\n const { data: records, loading, error, refetch } = useAiPredictions(filter);\n const [setStatus, setStatusState] = useSetAiPredictionStatus();\n const [pendingAccept, setPendingAccept] = useState<AiPredictionRecord | null>(null);\n const [actionError, setActionError] = useState<string | null>(null);\n const busy = setStatusState.loading;\n\n const onDismiss = useCallback(\n async (record: AiPredictionRecord) => {\n setActionError(null);\n try {\n await setStatus({ id: record.id, status: AiPredictionStatus.Dismissed });\n await refetch();\n } catch (dismissError) {\n setActionError(dismissError instanceof Error ? dismissError.message : String(dismissError));\n }\n },\n [setStatus, refetch]\n );\n\n const applyAccept = useCallback(async () => {\n const record = pendingAccept;\n if (!record) return;\n setPendingAccept(null);\n setActionError(null);\n const action = acceptActionFor(record, t);\n try {\n if (action?.kind === 'rebuild-index' && record.subjectId) {\n await client.mutate<RebuildKnowledgeBaseIndexForSupervisorMutation>({\n mutation: RebuildKnowledgeBaseIndexForSupervisorDocument,\n variables: { knowledgeBaseId: record.subjectId },\n });\n } else if (action?.kind === 'pause-agent' && record.subjectId) {\n await client.mutate<PauseBotmanorAgentForSupervisorMutation>({\n mutation: PauseBotmanorAgentForSupervisorDocument,\n variables: { id: record.subjectId, input: { status: 'PAUSED' } },\n });\n }\n await setStatus({ id: record.id, status: AiPredictionStatus.Accepted });\n await refetch();\n } catch (acceptError) {\n setActionError(acceptError instanceof Error ? acceptError.message : String(acceptError));\n }\n }, [pendingAccept, client, setStatus, refetch, t]);\n\n const pendingAction = pendingAccept ? acceptActionFor(pendingAccept, t) : null;\n\n const content: ReactNode = useMemo(() => {\n if (error) {\n return (\n <ErrorState\n resource={t('botlit.aiOperations.errorTitle', 'AI operations findings')}\n error={error}\n onRetry={() => void refetch()}\n />\n );\n }\n if (loading && records.length === 0) {\n return (\n <div className=\"space-y-3\" aria-busy=\"true\">\n {[0, 1, 2].map((index) => (\n <Card key={index} className=\"p-5 h-28 animate-pulse bg-bg-subtle\">\n <span className=\"sr-only\">\n {t('botlit.aiOperations.loading', 'Loading findings')}\n </span>\n </Card>\n ))}\n </div>\n );\n }\n if (records.length === 0) {\n return (\n <EmptyState\n icon={<ShieldAlert className=\"h-8 w-8\" />}\n title={t('botlit.aiOperations.emptyTitle', 'No findings')}\n description={t(\n 'botlit.aiOperations.emptyDescription',\n 'The supervisor has not flagged anything. Enable the scheduled review to keep it that way.'\n )}\n />\n );\n }\n return (\n <div className=\"space-y-3\" data-testid=\"ai-operations-feed\">\n {records.map((record) => (\n <DecisionCard\n key={record.id}\n record={record}\n busy={busy}\n onAccept={(target) => setPendingAccept(target)}\n onDismiss={(target) => void onDismiss(target)}\n />\n ))}\n </div>\n );\n }, [error, loading, records, busy, onDismiss, refetch, t]);\n\n return (\n <section className={className} data-testid=\"ai-operations-panel\">\n {(title || description) && (\n <header className=\"mb-4\">\n {title && <h2 className=\"text-lg font-semibold text-text-primary\">{title}</h2>}\n {description && <p className=\"text-sm text-text-secondary\">{description}</p>}\n </header>\n )}\n {actionError && (\n <p className=\"mb-3 text-sm text-status-error-text\" role=\"alert\">\n {actionError}\n </p>\n )}\n {content}\n\n <AlertDialog\n open={pendingAccept != null}\n onOpenChange={(open) => !open && setPendingAccept(null)}\n >\n <AlertDialogContent>\n <AlertDialogHeader>\n <AlertDialogTitle>{pendingAction?.confirmTitle}</AlertDialogTitle>\n <AlertDialogDescription>{pendingAction?.confirmBody}</AlertDialogDescription>\n </AlertDialogHeader>\n <AlertDialogFooter>\n <AlertDialogCancel>\n {t('botlit.aiOperations.actions.cancel', 'Cancel')}\n </AlertDialogCancel>\n <AlertDialogAction onClick={() => void applyAccept()}>\n {t('botlit.aiOperations.actions.confirmAccept', 'Confirm')}\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n </section>\n );\n};\n"],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export declare function AssistantChannelPanel({ agentId }: {
2
+ agentId: string;
3
+ }): import('react').JSX.Element;
@@ -1,17 +1,17 @@
1
- import { useBotlit as e } from "../providers/BotlitProvider.js";
2
- import { Button as t } from "./Button.js";
1
+ import { useAssistantChannels as e } from "../hooks/useAssistantChannels.js";
2
+ import { useAssistantWebsites as t } from "../hooks/useAssistantWebsites.js";
3
3
  import { useChannelRoutes as n } from "../hooks/useChannels.js";
4
- import { useAssistantChannels as r } from "../hooks/useAssistantChannels.js";
5
- import { useAssistantWebsites as i } from "../hooks/useAssistantWebsites.js";
4
+ import { useBotlit as r } from "../providers/BotlitProvider.js";
5
+ import { Button as i } from "./Button.js";
6
6
  import { useState as a } from "react";
7
7
  import { jsx as o, jsxs as s } from "react/jsx-runtime";
8
- //#region src/botlit/components/AssistantChannelPanel.tsx
9
- function c({ agentId: t }) {
10
- let { workspaceId: n, currentUser: r } = e();
11
- return /* @__PURE__ */ o(l, { agentId: t }, `${n}:${r?.id}:${t}`);
8
+ // src/botlit/components/AssistantChannelPanel.tsx
9
+ function c({ agentId: e }) {
10
+ let { workspaceId: t, currentUser: n } = r();
11
+ return /* @__PURE__ */ o(l, { agentId: e }, `${t}:${n?.id}:${e}`);
12
12
  }
13
- function l({ agentId: e }) {
14
- let c = r(), l = i(e), u = n(), [d, f] = a(""), [p, m] = a(""), [h, g] = a(""), _ = l.installations.data?.filter((e) => e.enabled) ?? [], v = new Set(l.installations.data?.map((e) => e.id) ?? []);
13
+ function l({ agentId: r }) {
14
+ let c = e(), l = t(r), u = n(), [d, f] = a(""), [p, m] = a(""), [h, g] = a(""), _ = l.installations.data?.filter((e) => e.enabled) ?? [], v = new Set(l.installations.data?.map((e) => e.id) ?? []);
15
15
  return /* @__PURE__ */ s("section", {
16
16
  className: "space-y-4 rounded-lg border border-border-default p-5",
17
17
  children: [
@@ -61,7 +61,7 @@ function l({ agentId: e }) {
61
61
  }, e.id))]
62
62
  })]
63
63
  }),
64
- /* @__PURE__ */ o(t, {
64
+ /* @__PURE__ */ o(i, {
65
65
  disabled: !_.some((e) => e.id === p) || !u.data.some((e) => e.id === d) || !!u.error,
66
66
  isLoading: c.configure.isPending,
67
67
  onClick: async () => {
@@ -87,7 +87,7 @@ function l({ agentId: e }) {
87
87
  " ·",
88
88
  " ",
89
89
  e.enabled ? "Enabled" : "Disabled"
90
- ] }), e.enabled && /* @__PURE__ */ o(t, {
90
+ ] }), e.enabled && /* @__PURE__ */ o(i, {
91
91
  variant: "outline",
92
92
  isLoading: c.disable.isPending,
93
93
  onClick: async () => {
@@ -103,7 +103,6 @@ function l({ agentId: e }) {
103
103
  ]
104
104
  });
105
105
  }
106
- //#endregion
107
106
  export { c as AssistantChannelPanel };
108
107
 
109
108
  //# sourceMappingURL=AssistantChannelPanel.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"AssistantChannelPanel.js","names":[],"sources":["../../../src/botlit/components/AssistantChannelPanel.tsx"],"sourcesContent":["import { useState } from 'react';\nimport { useAssistantChannels } from '../hooks/useAssistantChannels';\nimport { useAssistantWebsites } from '../hooks/useAssistantWebsites';\nimport { useChannelRoutes } from '../hooks/useChannels';\nimport { useBotlit } from '../providers/BotlitProvider';\nimport { Button } from './Button';\n\nexport function AssistantChannelPanel({ agentId }: { agentId: string }) {\n const { workspaceId, currentUser } = useBotlit();\n return (\n <ScopedChannelPanel key={`${workspaceId}:${currentUser?.id}:${agentId}`} agentId={agentId} />\n );\n}\nfunction ScopedChannelPanel({ agentId }: { agentId: string }) {\n const channels = useAssistantChannels(),\n publications = useAssistantWebsites(agentId),\n routes = useChannelRoutes();\n const [routeId, setRouteId] = useState(''),\n [publicationId, setPublicationId] = useState(''),\n [message, setMessage] = useState('');\n const approved = publications.installations.data?.filter((row) => row.enabled) ?? [];\n const ownIds = new Set(publications.installations.data?.map((row) => row.id) ?? []);\n return (\n <section className=\"space-y-4 rounded-lg border border-border-default p-5\">\n <h2 className=\"text-lg font-semibold\">Channel assistant</h2>\n <p className=\"text-sm text-text-secondary\">\n Use an approved public assistant publication on an existing channel route. Messages run\n through Fluidgrids and replies use channel-svc. Private course teachers cannot be published.\n </p>\n {(routes.error || publications.installations.isError || channels.installations.isError) && (\n <p role=\"alert\">\n Channel setup could not be loaded. Check your publishing permission and reload.\n </p>\n )}\n <label className=\"grid gap-2 text-sm\">\n Approved public publication\n <select\n className=\"h-10 rounded-md border border-border-default bg-bg-surface px-3\"\n value={publicationId}\n onChange={(event) => setPublicationId(event.target.value)}\n >\n <option value=\"\">Select a reviewed publication</option>\n {approved.map((row) => (\n <option key={row.id} value={row.id}>\n {row.name}\n </option>\n ))}\n </select>\n </label>\n <label className=\"grid gap-2 text-sm\">\n Existing channel route\n <select\n className=\"h-10 rounded-md border border-border-default bg-bg-surface px-3\"\n value={routeId}\n onChange={(event) => setRouteId(event.target.value)}\n >\n <option value=\"\">Select a route</option>\n {routes.data.map((route) => (\n <option key={route.id} value={route.id}>\n {route.locationId} · {route.appId}\n </option>\n ))}\n </select>\n </label>\n <Button\n disabled={\n !approved.some((row) => row.id === publicationId) ||\n !routes.data.some((row) => row.id === routeId) ||\n Boolean(routes.error)\n }\n isLoading={channels.configure.isPending}\n onClick={async () => {\n try {\n await channels.configure.mutateAsync({ routeId, publicationId });\n setMessage('Channel assistant enabled.');\n } catch {\n setMessage(\n 'Channel publication failed. Check the public assistant configuration, channel ownership and publishing permission.'\n );\n }\n }}\n >\n Enable channel assistant\n </Button>\n {message && <p role=\"status\">{message}</p>}\n {channels.installations.data\n ?.filter((row) => ownIds.has(row.publicationId))\n .map((row) => (\n <div key={row.id} className=\"flex items-center justify-between gap-3 text-sm\">\n <span>\n {routes.data.find((route) => route.id === row.routeId)?.locationId ?? row.routeId} ·{' '}\n {row.enabled ? 'Enabled' : 'Disabled'}\n </span>\n {row.enabled && (\n <Button\n variant=\"outline\"\n isLoading={channels.disable.isPending}\n onClick={async () => {\n try {\n await channels.disable.mutateAsync(row.id);\n setMessage('Channel assistant disabled.');\n } catch {\n setMessage('Channel could not be disabled. Reload and try again.');\n }\n }}\n >\n Disable\n </Button>\n )}\n </div>\n ))}\n </section>\n );\n}\n"],"mappings":";;;;;;;;AAOA,SAAgB,EAAsB,EAAE,cAAgC;CACtE,IAAM,EAAE,gBAAa,mBAAgB,GAAW;AAChD,QACE,kBAAC,GAAD,EAAkF,YAAW,EAApE,GAAG,EAAY,GAAG,GAAa,GAAG,GAAG,IAA+B;;AAGjG,SAAS,EAAmB,EAAE,cAAgC;CAC5D,IAAM,IAAW,GAAsB,EACrC,IAAe,EAAqB,EAAQ,EAC5C,IAAS,GAAkB,EACvB,CAAC,GAAS,KAAc,EAAS,GAAG,EACxC,CAAC,GAAe,KAAoB,EAAS,GAAG,EAChD,CAAC,GAAS,KAAc,EAAS,GAAG,EAChC,IAAW,EAAa,cAAc,MAAM,QAAQ,MAAQ,EAAI,QAAQ,IAAI,EAAE,EAC9E,IAAS,IAAI,IAAI,EAAa,cAAc,MAAM,KAAK,MAAQ,EAAI,GAAG,IAAI,EAAE,CAAC;AACnF,QACE,kBAAC,WAAD;EAAS,WAAU;YAAnB;GACE,kBAAC,MAAD;IAAI,WAAU;cAAwB;IAAsB,CAAA;GAC5D,kBAAC,KAAD;IAAG,WAAU;cAA8B;IAGvC,CAAA;IACF,EAAO,SAAS,EAAa,cAAc,WAAW,EAAS,cAAc,YAC7E,kBAAC,KAAD;IAAG,MAAK;cAAQ;IAEZ,CAAA;GAEN,kBAAC,SAAD;IAAO,WAAU;cAAjB,CAAsC,+BAEpC,kBAAC,UAAD;KACE,WAAU;KACV,OAAO;KACP,WAAW,MAAU,EAAiB,EAAM,OAAO,MAAM;eAH3D,CAKE,kBAAC,UAAD;MAAQ,OAAM;gBAAG;MAAsC,CAAA,EACtD,EAAS,KAAK,MACb,kBAAC,UAAD;MAAqB,OAAO,EAAI;gBAC7B,EAAI;MACE,EAFI,EAAI,GAER,CACT,CACK;OACH;;GACR,kBAAC,SAAD;IAAO,WAAU;cAAjB,CAAsC,0BAEpC,kBAAC,UAAD;KACE,WAAU;KACV,OAAO;KACP,WAAW,MAAU,EAAW,EAAM,OAAO,MAAM;eAHrD,CAKE,kBAAC,UAAD;MAAQ,OAAM;gBAAG;MAAuB,CAAA,EACvC,EAAO,KAAK,KAAK,MAChB,kBAAC,UAAD;MAAuB,OAAO,EAAM;gBAApC;OACG,EAAM;OAAW;OAAI,EAAM;OACrB;QAFI,EAAM,GAEV,CACT,CACK;OACH;;GACR,kBAAC,GAAD;IACE,UACE,CAAC,EAAS,MAAM,MAAQ,EAAI,OAAO,EAAc,IACjD,CAAC,EAAO,KAAK,MAAM,MAAQ,EAAI,OAAO,EAAQ,IAC9C,EAAQ,EAAO;IAEjB,WAAW,EAAS,UAAU;IAC9B,SAAS,YAAY;AACnB,SAAI;AAEF,MADA,MAAM,EAAS,UAAU,YAAY;OAAE;OAAS;OAAe,CAAC,EAChE,EAAW,6BAA6B;aAClC;AACN,QACE,qHACD;;;cAGN;IAEQ,CAAA;GACR,KAAW,kBAAC,KAAD;IAAG,MAAK;cAAU;IAAY,CAAA;GACzC,EAAS,cAAc,MACpB,QAAQ,MAAQ,EAAO,IAAI,EAAI,cAAc,CAAC,CAC/C,KAAK,MACJ,kBAAC,OAAD;IAAkB,WAAU;cAA5B,CACE,kBAAC,QAAD,EAAA,UAAA;KACG,EAAO,KAAK,MAAM,MAAU,EAAM,OAAO,EAAI,QAAQ,EAAE,cAAc,EAAI;KAAQ;KAAG;KACpF,EAAI,UAAU,YAAY;KACtB,EAAA,CAAA,EACN,EAAI,WACH,kBAAC,GAAD;KACE,SAAQ;KACR,WAAW,EAAS,QAAQ;KAC5B,SAAS,YAAY;AACnB,UAAI;AAEF,OADA,MAAM,EAAS,QAAQ,YAAY,EAAI,GAAG,EAC1C,EAAW,8BAA8B;cACnC;AACN,SAAW,uDAAuD;;;eAGvE;KAEQ,CAAA,CAEP;MArBI,EAAI,GAqBR,CACN;GACI"}
1
+ {"version":3,"file":"AssistantChannelPanel.js","names":["AssistantChannelPanel","useBotlit","ScopedChannelPanel","workspaceId","currentUser","agentId","channels","useAssistantChannels","publications","useAssistantWebsites","routes","useChannelRoutes","routeId","setRouteId","useState","publicationId","setPublicationId","message","setMessage","approved","row","ownIds","event","route","Button"],"sources":["../../../src/botlit/components/AssistantChannelPanel.tsx"],"sourcesContent":["import { useState } from 'react';\nimport { useAssistantChannels } from '../hooks/useAssistantChannels';\nimport { useAssistantWebsites } from '../hooks/useAssistantWebsites';\nimport { useChannelRoutes } from '../hooks/useChannels';\nimport { useBotlit } from '../providers/BotlitProvider';\nimport { Button } from './Button';\n\nexport function AssistantChannelPanel({ agentId }: { agentId: string }) {\n const { workspaceId, currentUser } = useBotlit();\n return (\n <ScopedChannelPanel key={`${workspaceId}:${currentUser?.id}:${agentId}`} agentId={agentId} />\n );\n}\nfunction ScopedChannelPanel({ agentId }: { agentId: string }) {\n const channels = useAssistantChannels(),\n publications = useAssistantWebsites(agentId),\n routes = useChannelRoutes();\n const [routeId, setRouteId] = useState(''),\n [publicationId, setPublicationId] = useState(''),\n [message, setMessage] = useState('');\n const approved = publications.installations.data?.filter((row) => row.enabled) ?? [];\n const ownIds = new Set(publications.installations.data?.map((row) => row.id) ?? []);\n return (\n <section className=\"space-y-4 rounded-lg border border-border-default p-5\">\n <h2 className=\"text-lg font-semibold\">Channel assistant</h2>\n <p className=\"text-sm text-text-secondary\">\n Use an approved public assistant publication on an existing channel route. Messages run\n through Fluidgrids and replies use channel-svc. Private course teachers cannot be published.\n </p>\n {(routes.error || publications.installations.isError || channels.installations.isError) && (\n <p role=\"alert\">\n Channel setup could not be loaded. Check your publishing permission and reload.\n </p>\n )}\n <label className=\"grid gap-2 text-sm\">\n Approved public publication\n <select\n className=\"h-10 rounded-md border border-border-default bg-bg-surface px-3\"\n value={publicationId}\n onChange={(event) => setPublicationId(event.target.value)}\n >\n <option value=\"\">Select a reviewed publication</option>\n {approved.map((row) => (\n <option key={row.id} value={row.id}>\n {row.name}\n </option>\n ))}\n </select>\n </label>\n <label className=\"grid gap-2 text-sm\">\n Existing channel route\n <select\n className=\"h-10 rounded-md border border-border-default bg-bg-surface px-3\"\n value={routeId}\n onChange={(event) => setRouteId(event.target.value)}\n >\n <option value=\"\">Select a route</option>\n {routes.data.map((route) => (\n <option key={route.id} value={route.id}>\n {route.locationId} · {route.appId}\n </option>\n ))}\n </select>\n </label>\n <Button\n disabled={\n !approved.some((row) => row.id === publicationId) ||\n !routes.data.some((row) => row.id === routeId) ||\n Boolean(routes.error)\n }\n isLoading={channels.configure.isPending}\n onClick={async () => {\n try {\n await channels.configure.mutateAsync({ routeId, publicationId });\n setMessage('Channel assistant enabled.');\n } catch {\n setMessage(\n 'Channel publication failed. Check the public assistant configuration, channel ownership and publishing permission.'\n );\n }\n }}\n >\n Enable channel assistant\n </Button>\n {message && <p role=\"status\">{message}</p>}\n {channels.installations.data\n ?.filter((row) => ownIds.has(row.publicationId))\n .map((row) => (\n <div key={row.id} className=\"flex items-center justify-between gap-3 text-sm\">\n <span>\n {routes.data.find((route) => route.id === row.routeId)?.locationId ?? row.routeId} ·{' '}\n {row.enabled ? 'Enabled' : 'Disabled'}\n </span>\n {row.enabled && (\n <Button\n variant=\"outline\"\n isLoading={channels.disable.isPending}\n onClick={async () => {\n try {\n await channels.disable.mutateAsync(row.id);\n setMessage('Channel assistant disabled.');\n } catch {\n setMessage('Channel could not be disabled. Reload and try again.');\n }\n }}\n >\n Disable\n </Button>\n )}\n </div>\n ))}\n </section>\n );\n}\n"],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export declare function AssistantRuntimeSetupPanel({ agentId, onConfigured, }: {
2
+ agentId: string;
3
+ onConfigured: () => void;
4
+ }): import('react').JSX.Element;
@@ -1,18 +1,18 @@
1
- import { useBotlit as e } from "../providers/BotlitProvider.js";
2
- import { Button as t } from "./Button.js";
3
- import { useAssistantRuntimeSetup as n } from "../hooks/useAssistantRuntimeSetup.js";
1
+ import { useAssistantRuntimeSetup as e } from "../hooks/useAssistantRuntimeSetup.js";
2
+ import { useBotlit as t } from "../providers/BotlitProvider.js";
3
+ import { Button as n } from "./Button.js";
4
4
  import { useState as r } from "react";
5
5
  import { Fragment as i, jsx as a, jsxs as o } from "react/jsx-runtime";
6
- //#region src/botlit/components/AssistantRuntimeSetupPanel.tsx
7
- function s({ agentId: t, onConfigured: n }) {
8
- let { workspaceId: r, currentUser: i } = e();
6
+ // src/botlit/components/AssistantRuntimeSetupPanel.tsx
7
+ function s({ agentId: e, onConfigured: n }) {
8
+ let { workspaceId: r, currentUser: i } = t();
9
9
  return /* @__PURE__ */ a(c, {
10
- agentId: t,
10
+ agentId: e,
11
11
  onConfigured: n
12
- }, `${r}:${i?.id}:${t}`);
12
+ }, `${r}:${i?.id}:${e}`);
13
13
  }
14
- function c({ agentId: e, onConfigured: s }) {
15
- let { connections: c, configure: l } = n(e), [u, d] = r(""), [f, p] = r(""), [m, h] = r(!1);
14
+ function c({ agentId: t, onConfigured: s }) {
15
+ let { connections: c, configure: l } = e(t), [u, d] = r(""), [f, p] = r(""), [m, h] = r(!1);
16
16
  return /* @__PURE__ */ o("section", {
17
17
  className: "space-y-4 rounded-lg border border-border-default p-5",
18
18
  children: [
@@ -28,7 +28,7 @@ function c({ agentId: e, onConfigured: s }) {
28
28
  children: "Loading connections…"
29
29
  }) : c.isError ? /* @__PURE__ */ o("div", {
30
30
  role: "alert",
31
- children: [/* @__PURE__ */ a("p", { children: "Connections could not be loaded. Check your access and try again." }), /* @__PURE__ */ a(t, {
31
+ children: [/* @__PURE__ */ a("p", { children: "Connections could not be loaded. Check your access and try again." }), /* @__PURE__ */ a(n, {
32
32
  variant: "outline",
33
33
  onClick: () => void c.refetch(),
34
34
  children: "Reload connections"
@@ -50,13 +50,14 @@ function c({ agentId: e, onConfigured: s }) {
50
50
  children: e.name
51
51
  }, e.id))]
52
52
  })]
53
- }), /* @__PURE__ */ a(t, {
53
+ }), /* @__PURE__ */ a(n, {
54
54
  disabled: !u,
55
55
  isLoading: l.isPending,
56
56
  onClick: async () => {
57
57
  p(""), h(!1);
58
58
  try {
59
- p((await l.mutateAsync(u)).ready ? "Assistant configured and ready." : "Workflows configured. Activate the assistant and finish indexing its knowledge before using it."), s();
59
+ let e = await l.mutateAsync(u);
60
+ p(e.ready ? "Assistant configured and ready." : "Workflows configured. Activate the assistant and finish indexing its knowledge before using it."), s();
60
61
  } catch {
61
62
  h(!0), p("Setup could not be completed. Check the model, knowledge scope and your permissions, then try again.");
62
63
  }
@@ -70,7 +71,6 @@ function c({ agentId: e, onConfigured: s }) {
70
71
  ]
71
72
  });
72
73
  }
73
- //#endregion
74
74
  export { s as AssistantRuntimeSetupPanel };
75
75
 
76
76
  //# sourceMappingURL=AssistantRuntimeSetupPanel.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"AssistantRuntimeSetupPanel.js","names":[],"sources":["../../../src/botlit/components/AssistantRuntimeSetupPanel.tsx"],"sourcesContent":["import { useState } from 'react';\nimport { useAssistantRuntimeSetup } from '../hooks/useAssistantRuntimeSetup';\nimport { useBotlit } from '../providers/BotlitProvider';\nimport { Button } from './Button';\n\nexport function AssistantRuntimeSetupPanel({\n agentId,\n onConfigured,\n}: {\n agentId: string;\n onConfigured: () => void;\n}) {\n const { workspaceId, currentUser } = useBotlit();\n return (\n <ScopedSetupPanel\n key={`${workspaceId}:${currentUser?.id}:${agentId}`}\n agentId={agentId}\n onConfigured={onConfigured}\n />\n );\n}\n\nfunction ScopedSetupPanel({\n agentId,\n onConfigured,\n}: {\n agentId: string;\n onConfigured: () => void;\n}) {\n const { connections, configure } = useAssistantRuntimeSetup(agentId);\n const [selected, setSelected] = useState('');\n const [message, setMessage] = useState('');\n const [failed, setFailed] = useState(false);\n return (\n <section className=\"space-y-4 rounded-lg border border-border-default p-5\">\n <div>\n <h2 className=\"text-lg font-semibold\">Assistant setup</h2>\n <p className=\"text-sm text-text-secondary\">\n Connect this assistant to Fluidgrids for answers and recovery. Course teachers also\n receive content ingestion workflows.\n </p>\n </div>\n {connections.isPending ? (\n <p role=\"status\">Loading connections…</p>\n ) : connections.isError ? (\n <div role=\"alert\">\n <p>Connections could not be loaded. Check your access and try again.</p>\n <Button variant=\"outline\" onClick={() => void connections.refetch()}>\n Reload connections\n </Button>\n </div>\n ) : !connections.data?.length ? (\n <p>\n Create an active BotManor Assistant Runtime connection in Integrations, then reload this\n page.\n </p>\n ) : (\n <>\n <label className=\"grid gap-2 text-sm font-medium\">\n Workflow connection\n <select\n className=\"h-10 rounded-md border border-border-default bg-bg-surface px-3\"\n value={selected}\n disabled={configure.isPending}\n onChange={(event) => {\n setSelected(event.target.value);\n setMessage('');\n }}\n >\n <option value=\"\">Choose a connection</option>\n {connections.data.map((connection) => (\n <option key={connection.id} value={connection.id}>\n {connection.name}\n </option>\n ))}\n </select>\n </label>\n <Button\n disabled={!selected}\n isLoading={configure.isPending}\n onClick={async () => {\n setMessage('');\n setFailed(false);\n try {\n const result = await configure.mutateAsync(selected);\n setMessage(\n result.ready\n ? 'Assistant configured and ready.'\n : 'Workflows configured. Activate the assistant and finish indexing its knowledge before using it.'\n );\n onConfigured();\n } catch {\n setFailed(true);\n setMessage(\n 'Setup could not be completed. Check the model, knowledge scope and your permissions, then try again.'\n );\n }\n }}\n >\n Configure assistant\n </Button>\n </>\n )}\n {message && <p role={failed ? 'alert' : 'status'}>{message}</p>}\n </section>\n );\n}\n"],"mappings":";;;;;;AAKA,SAAgB,EAA2B,EACzC,YACA,mBAIC;CACD,IAAM,EAAE,gBAAa,mBAAgB,GAAW;AAChD,QACE,kBAAC,GAAD;EAEW;EACK;EACd,EAHK,GAAG,EAAY,GAAG,GAAa,GAAG,GAAG,IAG1C;;AAIN,SAAS,EAAiB,EACxB,YACA,mBAIC;CACD,IAAM,EAAE,gBAAa,iBAAc,EAAyB,EAAQ,EAC9D,CAAC,GAAU,KAAe,EAAS,GAAG,EACtC,CAAC,GAAS,KAAc,EAAS,GAAG,EACpC,CAAC,GAAQ,KAAa,EAAS,GAAM;AAC3C,QACE,kBAAC,WAAD;EAAS,WAAU;YAAnB;GACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,MAAD;IAAI,WAAU;cAAwB;IAAoB,CAAA,EAC1D,kBAAC,KAAD;IAAG,WAAU;cAA8B;IAGvC,CAAA,CACA,EAAA,CAAA;GACL,EAAY,YACX,kBAAC,KAAD;IAAG,MAAK;cAAS;IAAwB,CAAA,GACvC,EAAY,UACd,kBAAC,OAAD;IAAK,MAAK;cAAV,CACE,kBAAC,KAAD,EAAA,UAAG,qEAAqE,CAAA,EACxE,kBAAC,GAAD;KAAQ,SAAQ;KAAU,eAAe,KAAK,EAAY,SAAS;eAAE;KAE5D,CAAA,CACL;QACH,EAAY,MAAM,SAMrB,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,SAAD;IAAO,WAAU;cAAjB,CAAkD,uBAEhD,kBAAC,UAAD;KACE,WAAU;KACV,OAAO;KACP,UAAU,EAAU;KACpB,WAAW,MAAU;AAEnB,MADA,EAAY,EAAM,OAAO,MAAM,EAC/B,EAAW,GAAG;;eANlB,CASE,kBAAC,UAAD;MAAQ,OAAM;gBAAG;MAA4B,CAAA,EAC5C,EAAY,KAAK,KAAK,MACrB,kBAAC,UAAD;MAA4B,OAAO,EAAW;gBAC3C,EAAW;MACL,EAFI,EAAW,GAEf,CACT,CACK;OACH;OACR,kBAAC,GAAD;IACE,UAAU,CAAC;IACX,WAAW,EAAU;IACrB,SAAS,YAAY;AAEnB,KADA,EAAW,GAAG,EACd,EAAU,GAAM;AAChB,SAAI;AAOF,MALA,GADe,MAAM,EAAU,YAAY,EAAS,EAE3C,QACH,oCACA,kGACL,EACD,GAAc;aACR;AAEN,MADA,EAAU,GAAK,EACf,EACE,uGACD;;;cAGN;IAEQ,CAAA,CACR,EAAA,CAAA,GAjDH,kBAAC,KAAD,EAAA,UAAG,kGAGC,CAAA;GAgDL,KAAW,kBAAC,KAAD;IAAG,MAAM,IAAS,UAAU;cAAW;IAAY,CAAA;GACvD"}
1
+ {"version":3,"file":"AssistantRuntimeSetupPanel.js","names":["_Fragment","AssistantRuntimeSetupPanel","useBotlit","ScopedSetupPanel","workspaceId","currentUser","agentId","useAssistantRuntimeSetup","selected","setSelected","useState","message","setMessage","failed","setFailed","connections","Button","Fragment","configure","event","connection","result","onConfigured"],"sources":["../../../src/botlit/components/AssistantRuntimeSetupPanel.tsx"],"sourcesContent":["import { useState } from 'react';\nimport { useAssistantRuntimeSetup } from '../hooks/useAssistantRuntimeSetup';\nimport { useBotlit } from '../providers/BotlitProvider';\nimport { Button } from './Button';\n\nexport function AssistantRuntimeSetupPanel({\n agentId,\n onConfigured,\n}: {\n agentId: string;\n onConfigured: () => void;\n}) {\n const { workspaceId, currentUser } = useBotlit();\n return (\n <ScopedSetupPanel\n key={`${workspaceId}:${currentUser?.id}:${agentId}`}\n agentId={agentId}\n onConfigured={onConfigured}\n />\n );\n}\n\nfunction ScopedSetupPanel({\n agentId,\n onConfigured,\n}: {\n agentId: string;\n onConfigured: () => void;\n}) {\n const { connections, configure } = useAssistantRuntimeSetup(agentId);\n const [selected, setSelected] = useState('');\n const [message, setMessage] = useState('');\n const [failed, setFailed] = useState(false);\n return (\n <section className=\"space-y-4 rounded-lg border border-border-default p-5\">\n <div>\n <h2 className=\"text-lg font-semibold\">Assistant setup</h2>\n <p className=\"text-sm text-text-secondary\">\n Connect this assistant to Fluidgrids for answers and recovery. Course teachers also\n receive content ingestion workflows.\n </p>\n </div>\n {connections.isPending ? (\n <p role=\"status\">Loading connections…</p>\n ) : connections.isError ? (\n <div role=\"alert\">\n <p>Connections could not be loaded. Check your access and try again.</p>\n <Button variant=\"outline\" onClick={() => void connections.refetch()}>\n Reload connections\n </Button>\n </div>\n ) : !connections.data?.length ? (\n <p>\n Create an active BotManor Assistant Runtime connection in Integrations, then reload this\n page.\n </p>\n ) : (\n <>\n <label className=\"grid gap-2 text-sm font-medium\">\n Workflow connection\n <select\n className=\"h-10 rounded-md border border-border-default bg-bg-surface px-3\"\n value={selected}\n disabled={configure.isPending}\n onChange={(event) => {\n setSelected(event.target.value);\n setMessage('');\n }}\n >\n <option value=\"\">Choose a connection</option>\n {connections.data.map((connection) => (\n <option key={connection.id} value={connection.id}>\n {connection.name}\n </option>\n ))}\n </select>\n </label>\n <Button\n disabled={!selected}\n isLoading={configure.isPending}\n onClick={async () => {\n setMessage('');\n setFailed(false);\n try {\n const result = await configure.mutateAsync(selected);\n setMessage(\n result.ready\n ? 'Assistant configured and ready.'\n : 'Workflows configured. Activate the assistant and finish indexing its knowledge before using it.'\n );\n onConfigured();\n } catch {\n setFailed(true);\n setMessage(\n 'Setup could not be completed. Check the model, knowledge scope and your permissions, then try again.'\n );\n }\n }}\n >\n Configure assistant\n </Button>\n </>\n )}\n {message && <p role={failed ? 'alert' : 'status'}>{message}</p>}\n </section>\n );\n}\n"],"mappings":";;;;;;AAKA,SAAgBC,EAA2B,EACzC,YACA,mBAIC;CACD,IAAM,EAAE,gBAAa,mBAAgBC,EAAU;CAC/C,OACE,kBAACC,GAAD;EAEW;EACK;CACf,GAHM,GAAGC,EAAY,GAAGC,GAAa,GAAG,GAAGC,GAG3C;AAEL;AAEA,SAASH,EAAiB,EACxB,YACA,mBAIC;CACD,IAAM,EAAE,gBAAa,iBAAcI,EAAyBD,CAAO,GAC7D,CAACE,GAAUC,KAAeC,EAAS,EAAE,GACrC,CAACC,GAASC,KAAcF,EAAS,EAAE,GACnC,CAACG,GAAQC,KAAaJ,EAAS,EAAK;CAC1C,OACE,kBAAC,WAAD;EAAS,WAAU;EAAnB,UAAA;GACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,MAAD;IAAI,WAAU;IAAwB,UAAA;GAAmB,CAAA,GACzD,kBAAC,KAAD;IAAG,WAAU;IAA8B,UAAA;GAGxC,CAAA,CACA,EAAA,CAAA;GACJK,EAAY,YACX,kBAAC,KAAD;IAAG,MAAK;IAAS,UAAA;GAAuB,CAAA,IACtCA,EAAY,UACd,kBAAC,OAAD;IAAK,MAAK;IAAV,UAAA,CACE,kBAAC,KAAD,EAAA,UAAG,oEAAoE,CAAA,GACvE,kBAACC,GAAD;KAAQ,SAAQ;KAAU,eAAe,KAAKD,EAAY,QAAQ;KAAG,UAAA;IAE7D,CAAA,CACL;GACH,CAAA,IAACA,EAAY,MAAM,SAMrB,kBAAAf,GAAA,EAAA,UAAA,CACE,kBAAC,SAAD;IAAO,WAAU;IAAjB,UAAA,CAAkD,uBAEhD,kBAAC,UAAD;KACE,WAAU;KACV,OAAOQ;KACP,UAAUU,EAAU;KACpB,WAAW,MAAU;MAEnB,AADAT,EAAYU,EAAM,OAAO,KAAK,GAC9BP,EAAW,EAAE;KACf;KAPF,UAAA,CASE,kBAAC,UAAD;MAAQ,OAAM;MAAG,UAAA;KAA2B,CAAA,GAC3CG,EAAY,KAAK,KAAK,MACrB,kBAAC,UAAD;MAA4B,OAAOK,EAAW;MAC3C,UAAAA,EAAW;KACN,GAFKA,EAAW,EAEhB,CACT,CACK;IACH,CAAA,CAAA;GACP,CAAA,GAAA,kBAACJ,GAAD;IACE,UAAU,CAACR;IACX,WAAWU,EAAU;IACrB,SAAS,YAAY;KAEnB,AADAN,EAAW,EAAE,GACbE,EAAU,EAAK;KACf,IAAI;MACF,IAAMO,IAAS,MAAMH,EAAU,YAAYV,CAAQ;MAMnD,AALAI,EACES,EAAO,QACH,oCACA,iGACN,GACAC,EAAa;KACf,QAAQ;MAEN,AADAR,EAAU,EAAI,GACdF,EACE,sGACF;KACF;IACF;IACD,UAAA;GAEO,CAAA,CACR,EAAA,CAAA,IAjDF,kBAAC,KAAD,EAAA,UAAG,iGAGA,CAAA;GAgDJD,KAAW,kBAAC,KAAD;IAAG,MAAME,IAAS,UAAU;IAAW,UAAAF;GAAW,CAAA;EACvD;;AAEb"}
@@ -0,0 +1,5 @@
1
+ export declare function assistantWidgetSnippet(gateway: string, workspaceId: string, installationId: string): string;
2
+ export declare function AssistantWebsitePanel({ agentId, knowledgeBaseIds, }: {
3
+ agentId: string;
4
+ knowledgeBaseIds: string[];
5
+ }): import('react').JSX.Element;
@@ -1,24 +1,24 @@
1
- import { useBotlit as e } from "../providers/BotlitProvider.js";
1
+ import { useAssistantWebsites as e } from "../hooks/useAssistantWebsites.js";
2
2
  import { useKnowledgeBases as t } from "../hooks/useKnowledgeBases.js";
3
- import { Button as n } from "./Button.js";
4
- import { useAssistantWebsites as r } from "../hooks/useAssistantWebsites.js";
3
+ import { useBotlit as n } from "../providers/BotlitProvider.js";
4
+ import { Button as r } from "./Button.js";
5
5
  import { useState as i } from "react";
6
6
  import { Fragment as a, jsx as o, jsxs as s } from "react/jsx-runtime";
7
- //#region src/botlit/components/AssistantWebsitePanel.tsx
7
+ // src/botlit/components/AssistantWebsitePanel.tsx
8
8
  function c(e, t, n) {
9
9
  let r = new URL(e);
10
10
  if (r.protocol !== "https:" || r.username || r.password || r.search || r.hash || !/^[a-f0-9-]{36}$/i.test(t) || !/^[a-f0-9-]{36}$/i.test(n)) throw Error("Invalid website widget address");
11
11
  return `<script src="${r.origin}/api/assistant-web/widget.js" data-workspace="${t}" data-installation="${n}" defer><\/script>`;
12
12
  }
13
- function l({ agentId: t, knowledgeBaseIds: n }) {
14
- let { workspaceId: r, currentUser: i } = e();
13
+ function l({ agentId: e, knowledgeBaseIds: t }) {
14
+ let { workspaceId: r, currentUser: i } = n();
15
15
  return /* @__PURE__ */ o(u, {
16
- agentId: t,
17
- knowledgeBaseIds: n
18
- }, `${r}:${i?.id}:${t}:${n.join(",")}`);
16
+ agentId: e,
17
+ knowledgeBaseIds: t
18
+ }, `${r}:${i?.id}:${e}:${t.join(",")}`);
19
19
  }
20
20
  function u({ agentId: l, knowledgeBaseIds: u }) {
21
- let { apiGatewayUrl: d } = e(), f = r(l), p = t(), [m, h] = i("Website assistant"), [g, _] = i(""), [v, y] = i(!1), [b, x] = i(""), [S, C] = i(!1), w = d || (typeof window < "u" && window.location.hostname.startsWith("alpha") ? "https://alphagraphqlworkspaces.burdenoff.com" : "https://graphqlworkspaces.burdenoff.com"), T = u.map((e) => p.data?.find((t) => t.id === e)), E = (e, t = !1) => {
21
+ let { apiGatewayUrl: d } = n(), f = e(l), p = t(), [m, h] = i("Website assistant"), [g, _] = i(""), [v, y] = i(!1), [b, x] = i(""), [S, C] = i(!1), w = d || (typeof window < "u" && window.location.hostname.startsWith("alpha") ? "https://alphagraphqlworkspaces.burdenoff.com" : "https://graphqlworkspaces.burdenoff.com"), T = u.map((e) => p.data?.find((t) => t.id === e)), E = (e, t = !1) => {
22
22
  x(e), C(t);
23
23
  };
24
24
  return /* @__PURE__ */ s("section", {
@@ -86,7 +86,7 @@ function u({ agentId: l, knowledgeBaseIds: u }) {
86
86
  onChange: (e) => y(e.target.checked)
87
87
  }), "I approve the assistant’s prompt and every listed knowledge source for public website visitors."]
88
88
  }),
89
- /* @__PURE__ */ o(n, {
89
+ /* @__PURE__ */ o(r, {
90
90
  disabled: !v || !m.trim() || !g.trim() || u.length > 20,
91
91
  isLoading: f.publish.isPending,
92
92
  onClick: async () => {
@@ -124,7 +124,7 @@ function u({ agentId: l, knowledgeBaseIds: u }) {
124
124
  children: "Loading website publications…"
125
125
  }) : f.installations.isError ? /* @__PURE__ */ s("div", {
126
126
  role: "alert",
127
- children: [/* @__PURE__ */ o("p", { children: "Website publications could not be loaded. Publishing permission is required." }), /* @__PURE__ */ o(n, {
127
+ children: [/* @__PURE__ */ o("p", { children: "Website publications could not be loaded. Publishing permission is required." }), /* @__PURE__ */ o(r, {
128
128
  variant: "outline",
129
129
  onClick: () => void f.installations.refetch(),
130
130
  children: "Reload publications"
@@ -155,7 +155,7 @@ function u({ agentId: l, knowledgeBaseIds: u }) {
155
155
  value: t,
156
156
  rows: 3,
157
157
  className: "w-full rounded-md border border-border-default bg-bg-sunken p-2 font-mono text-xs"
158
- }), /* @__PURE__ */ o(n, {
158
+ }), /* @__PURE__ */ o(r, {
159
159
  variant: "outline",
160
160
  onClick: async () => {
161
161
  try {
@@ -168,7 +168,7 @@ function u({ agentId: l, knowledgeBaseIds: u }) {
168
168
  })] }) : /* @__PURE__ */ o("p", {
169
169
  role: "alert",
170
170
  children: "The website widget address is unavailable."
171
- }), /* @__PURE__ */ o(n, {
171
+ }), /* @__PURE__ */ o(r, {
172
172
  variant: "outline",
173
173
  isLoading: f.disable.isPending,
174
174
  onClick: async () => {
@@ -190,7 +190,6 @@ function u({ agentId: l, knowledgeBaseIds: u }) {
190
190
  ]
191
191
  });
192
192
  }
193
- //#endregion
194
- export { l as AssistantWebsitePanel };
193
+ export { l as AssistantWebsitePanel, c as assistantWidgetSnippet };
195
194
 
196
195
  //# sourceMappingURL=AssistantWebsitePanel.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"AssistantWebsitePanel.js","names":[],"sources":["../../../src/botlit/components/AssistantWebsitePanel.tsx"],"sourcesContent":["import { useState } from 'react';\nimport { useAssistantWebsites } from '../hooks/useAssistantWebsites';\nimport { useKnowledgeBases } from '../hooks/useKnowledgeBases';\nimport { useBotlit } from '../providers/BotlitProvider';\nimport { Button } from './Button';\n\nexport function assistantWidgetSnippet(\n gateway: string,\n workspaceId: string,\n installationId: string\n): string {\n const url = new URL(gateway);\n if (\n url.protocol !== 'https:' ||\n url.username ||\n url.password ||\n url.search ||\n url.hash ||\n !/^[a-f0-9-]{36}$/i.test(workspaceId) ||\n !/^[a-f0-9-]{36}$/i.test(installationId)\n )\n throw new Error('Invalid website widget address');\n return `<script src=\"${url.origin}/api/assistant-web/widget.js\" data-workspace=\"${workspaceId}\" data-installation=\"${installationId}\" defer></script>`;\n}\nexport function AssistantWebsitePanel({\n agentId,\n knowledgeBaseIds,\n}: {\n agentId: string;\n knowledgeBaseIds: string[];\n}) {\n const { workspaceId, currentUser } = useBotlit();\n return (\n <ScopedWebsitePanel\n key={`${workspaceId}:${currentUser?.id}:${agentId}:${knowledgeBaseIds.join(',')}`}\n agentId={agentId}\n knowledgeBaseIds={knowledgeBaseIds}\n />\n );\n}\nfunction ScopedWebsitePanel({\n agentId,\n knowledgeBaseIds,\n}: {\n agentId: string;\n knowledgeBaseIds: string[];\n}) {\n const { apiGatewayUrl } = useBotlit(),\n websites = useAssistantWebsites(agentId),\n bases = useKnowledgeBases();\n const [name, setName] = useState('Website assistant'),\n [origins, setOrigins] = useState(''),\n [approved, setApproved] = useState(false),\n [message, setMessage] = useState(''),\n [failed, setFailed] = useState(false);\n const gateway =\n apiGatewayUrl ||\n (typeof window !== 'undefined' && window.location.hostname.startsWith('alpha')\n ? 'https://alphagraphqlworkspaces.burdenoff.com'\n : 'https://graphqlworkspaces.burdenoff.com');\n const sources = knowledgeBaseIds.map((id) => bases.data?.find((base) => base.id === id));\n const showMessage = (value: string, error = false) => {\n setMessage(value);\n setFailed(error);\n };\n return (\n <section className=\"space-y-4 rounded-lg border border-border-default p-5\">\n <div>\n <h2 className=\"text-lg font-semibold\">Website assistant</h2>\n <p className=\"text-sm text-text-secondary\">\n Publish a general assistant on approved websites. Configure its Fluidgrids runtime first.\n Private course teachers cannot be published.\n </p>\n </div>\n <label className=\"grid gap-2 text-sm font-medium\">\n Display name\n <input\n className=\"h-10 rounded-md border border-border-default bg-bg-surface px-3\"\n maxLength={120}\n value={name}\n disabled={websites.publish.isPending}\n onChange={(event) => setName(event.target.value)}\n />\n </label>\n <label className=\"grid gap-2 text-sm font-medium\">\n Approved website origins\n <textarea\n className=\"rounded-md border border-border-default bg-bg-surface p-3\"\n rows={3}\n placeholder=\"https://www.example.com\"\n value={origins}\n disabled={websites.publish.isPending}\n onChange={(event) => {\n setOrigins(event.target.value);\n setApproved(false);\n }}\n />\n <span className=\"font-normal text-text-secondary\">\n One exact HTTPS origin per line, without a path or trailing slash.\n </span>\n </label>\n <div className=\"text-sm\">\n <p className=\"font-medium\">Knowledge made available to website visitors</p>\n {bases.loading ? (\n <p role=\"status\">Loading knowledge sources…</p>\n ) : sources.some((source) => !source) ? (\n <p role=\"alert\">\n Some sources could not be reviewed. Reload the assistant before publishing.\n </p>\n ) : knowledgeBaseIds.length ? (\n <ul className=\"list-disc pl-5\">\n {sources.map((source) => source && <li key={source.id}>{source.name}</li>)}\n </ul>\n ) : (\n <p>This assistant has no attached knowledge sources.</p>\n )}\n </div>\n <label className=\"flex gap-2 text-sm\">\n <input\n type=\"checkbox\"\n checked={approved}\n disabled={\n websites.publish.isPending || bases.loading || sources.some((source) => !source)\n }\n onChange={(event) => setApproved(event.target.checked)}\n />\n I approve the assistant’s prompt and every listed knowledge source for public website\n visitors.\n </label>\n <Button\n disabled={!approved || !name.trim() || !origins.trim() || knowledgeBaseIds.length > 20}\n isLoading={websites.publish.isPending}\n onClick={async () => {\n showMessage('');\n try {\n const allowedOrigins = origins\n .split('\\n')\n .map((origin) => origin.trim())\n .filter(Boolean);\n if (\n allowedOrigins.length > 20 ||\n allowedOrigins.some((origin) => {\n try {\n const url = new URL(origin);\n return (\n url.protocol !== 'https:' ||\n origin !== url.origin ||\n Boolean(url.username || url.password) ||\n url.hostname.includes('*')\n );\n } catch {\n return true;\n }\n })\n ) {\n showMessage('Use up to twenty exact HTTPS origins.', true);\n return;\n }\n await websites.publish.mutateAsync({\n name,\n allowedOrigins,\n approvedKnowledgeBaseIds: knowledgeBaseIds,\n });\n setApproved(false);\n showMessage('Website publication created. Add its snippet to an approved website.');\n } catch {\n showMessage(\n 'Publication failed. Check the assistant configuration, public knowledge approval and your publishing permission.',\n true\n );\n }\n }}\n >\n Publish website assistant\n </Button>\n {message && <p role={failed ? 'alert' : 'status'}>{message}</p>}\n {websites.installations.isPending ? (\n <p role=\"status\">Loading website publications…</p>\n ) : websites.installations.isError ? (\n <div role=\"alert\">\n <p>Website publications could not be loaded. Publishing permission is required.</p>\n <Button variant=\"outline\" onClick={() => void websites.installations.refetch()}>\n Reload publications\n </Button>\n </div>\n ) : (\n websites.installations.data?.map((installation) => {\n let snippet = '';\n try {\n snippet = assistantWidgetSnippet(gateway, installation.workspaceId, installation.id);\n } catch {\n /* An invalid host configuration cannot produce an unsafe embed. */\n }\n return (\n <div\n key={installation.id}\n className=\"space-y-2 rounded-md border border-border-default p-3\"\n >\n <p className=\"font-medium\">\n {installation.name} · {installation.enabled ? 'Enabled' : 'Disabled'}\n </p>\n <p className=\"text-sm text-text-secondary\">\n {installation.allowedOrigins.join(', ')}\n </p>\n {installation.enabled && (\n <>\n {snippet ? (\n <>\n <textarea\n aria-label={`Installation snippet for ${installation.name}`}\n readOnly\n value={snippet}\n rows={3}\n className=\"w-full rounded-md border border-border-default bg-bg-sunken p-2 font-mono text-xs\"\n />\n <Button\n variant=\"outline\"\n onClick={async () => {\n try {\n await navigator.clipboard.writeText(snippet);\n showMessage('Installation snippet copied.');\n } catch {\n showMessage(\n 'Copy unavailable. Select and copy the snippet above.',\n true\n );\n }\n }}\n >\n Copy snippet\n </Button>\n </>\n ) : (\n <p role=\"alert\">The website widget address is unavailable.</p>\n )}\n <Button\n variant=\"outline\"\n isLoading={websites.disable.isPending}\n onClick={async () => {\n try {\n await websites.disable.mutateAsync(installation.id);\n showMessage(\n 'Publication disabled. Existing visitors can no longer receive answers.'\n );\n } catch {\n showMessage('Disable failed. Reload publications and try again.', true);\n }\n }}\n >\n Disable publication\n </Button>\n </>\n )}\n </div>\n );\n })\n )}\n <p className=\"text-sm text-text-secondary\">\n Changes to the assistant or its models revoke existing website sessions. Create a new\n publication after reviewing the updated configuration.\n </p>\n </section>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"AssistantWebsitePanel.js","names":["_Fragment","assistantWidgetSnippet","url","gateway","workspaceId","installationId","AssistantWebsitePanel","useBotlit","ScopedWebsitePanel","currentUser","agentId","knowledgeBaseIds","websites","useAssistantWebsites","bases","useKnowledgeBases","name","setName","useState","origins","setOrigins","approved","setApproved","message","setMessage","failed","setFailed","apiGatewayUrl","sources","base","id","showMessage","value","error","event","source","Button","allowedOrigins","origin","snippet","installation","Fragment"],"sources":["../../../src/botlit/components/AssistantWebsitePanel.tsx"],"sourcesContent":["import { useState } from 'react';\nimport { useAssistantWebsites } from '../hooks/useAssistantWebsites';\nimport { useKnowledgeBases } from '../hooks/useKnowledgeBases';\nimport { useBotlit } from '../providers/BotlitProvider';\nimport { Button } from './Button';\n\nexport function assistantWidgetSnippet(\n gateway: string,\n workspaceId: string,\n installationId: string\n): string {\n const url = new URL(gateway);\n if (\n url.protocol !== 'https:' ||\n url.username ||\n url.password ||\n url.search ||\n url.hash ||\n !/^[a-f0-9-]{36}$/i.test(workspaceId) ||\n !/^[a-f0-9-]{36}$/i.test(installationId)\n )\n throw new Error('Invalid website widget address');\n return `<script src=\"${url.origin}/api/assistant-web/widget.js\" data-workspace=\"${workspaceId}\" data-installation=\"${installationId}\" defer></script>`;\n}\nexport function AssistantWebsitePanel({\n agentId,\n knowledgeBaseIds,\n}: {\n agentId: string;\n knowledgeBaseIds: string[];\n}) {\n const { workspaceId, currentUser } = useBotlit();\n return (\n <ScopedWebsitePanel\n key={`${workspaceId}:${currentUser?.id}:${agentId}:${knowledgeBaseIds.join(',')}`}\n agentId={agentId}\n knowledgeBaseIds={knowledgeBaseIds}\n />\n );\n}\nfunction ScopedWebsitePanel({\n agentId,\n knowledgeBaseIds,\n}: {\n agentId: string;\n knowledgeBaseIds: string[];\n}) {\n const { apiGatewayUrl } = useBotlit(),\n websites = useAssistantWebsites(agentId),\n bases = useKnowledgeBases();\n const [name, setName] = useState('Website assistant'),\n [origins, setOrigins] = useState(''),\n [approved, setApproved] = useState(false),\n [message, setMessage] = useState(''),\n [failed, setFailed] = useState(false);\n const gateway =\n apiGatewayUrl ||\n (typeof window !== 'undefined' && window.location.hostname.startsWith('alpha')\n ? 'https://alphagraphqlworkspaces.burdenoff.com'\n : 'https://graphqlworkspaces.burdenoff.com');\n const sources = knowledgeBaseIds.map((id) => bases.data?.find((base) => base.id === id));\n const showMessage = (value: string, error = false) => {\n setMessage(value);\n setFailed(error);\n };\n return (\n <section className=\"space-y-4 rounded-lg border border-border-default p-5\">\n <div>\n <h2 className=\"text-lg font-semibold\">Website assistant</h2>\n <p className=\"text-sm text-text-secondary\">\n Publish a general assistant on approved websites. Configure its Fluidgrids runtime first.\n Private course teachers cannot be published.\n </p>\n </div>\n <label className=\"grid gap-2 text-sm font-medium\">\n Display name\n <input\n className=\"h-10 rounded-md border border-border-default bg-bg-surface px-3\"\n maxLength={120}\n value={name}\n disabled={websites.publish.isPending}\n onChange={(event) => setName(event.target.value)}\n />\n </label>\n <label className=\"grid gap-2 text-sm font-medium\">\n Approved website origins\n <textarea\n className=\"rounded-md border border-border-default bg-bg-surface p-3\"\n rows={3}\n placeholder=\"https://www.example.com\"\n value={origins}\n disabled={websites.publish.isPending}\n onChange={(event) => {\n setOrigins(event.target.value);\n setApproved(false);\n }}\n />\n <span className=\"font-normal text-text-secondary\">\n One exact HTTPS origin per line, without a path or trailing slash.\n </span>\n </label>\n <div className=\"text-sm\">\n <p className=\"font-medium\">Knowledge made available to website visitors</p>\n {bases.loading ? (\n <p role=\"status\">Loading knowledge sources…</p>\n ) : sources.some((source) => !source) ? (\n <p role=\"alert\">\n Some sources could not be reviewed. Reload the assistant before publishing.\n </p>\n ) : knowledgeBaseIds.length ? (\n <ul className=\"list-disc pl-5\">\n {sources.map((source) => source && <li key={source.id}>{source.name}</li>)}\n </ul>\n ) : (\n <p>This assistant has no attached knowledge sources.</p>\n )}\n </div>\n <label className=\"flex gap-2 text-sm\">\n <input\n type=\"checkbox\"\n checked={approved}\n disabled={\n websites.publish.isPending || bases.loading || sources.some((source) => !source)\n }\n onChange={(event) => setApproved(event.target.checked)}\n />\n I approve the assistant’s prompt and every listed knowledge source for public website\n visitors.\n </label>\n <Button\n disabled={!approved || !name.trim() || !origins.trim() || knowledgeBaseIds.length > 20}\n isLoading={websites.publish.isPending}\n onClick={async () => {\n showMessage('');\n try {\n const allowedOrigins = origins\n .split('\\n')\n .map((origin) => origin.trim())\n .filter(Boolean);\n if (\n allowedOrigins.length > 20 ||\n allowedOrigins.some((origin) => {\n try {\n const url = new URL(origin);\n return (\n url.protocol !== 'https:' ||\n origin !== url.origin ||\n Boolean(url.username || url.password) ||\n url.hostname.includes('*')\n );\n } catch {\n return true;\n }\n })\n ) {\n showMessage('Use up to twenty exact HTTPS origins.', true);\n return;\n }\n await websites.publish.mutateAsync({\n name,\n allowedOrigins,\n approvedKnowledgeBaseIds: knowledgeBaseIds,\n });\n setApproved(false);\n showMessage('Website publication created. Add its snippet to an approved website.');\n } catch {\n showMessage(\n 'Publication failed. Check the assistant configuration, public knowledge approval and your publishing permission.',\n true\n );\n }\n }}\n >\n Publish website assistant\n </Button>\n {message && <p role={failed ? 'alert' : 'status'}>{message}</p>}\n {websites.installations.isPending ? (\n <p role=\"status\">Loading website publications…</p>\n ) : websites.installations.isError ? (\n <div role=\"alert\">\n <p>Website publications could not be loaded. Publishing permission is required.</p>\n <Button variant=\"outline\" onClick={() => void websites.installations.refetch()}>\n Reload publications\n </Button>\n </div>\n ) : (\n websites.installations.data?.map((installation) => {\n let snippet = '';\n try {\n snippet = assistantWidgetSnippet(gateway, installation.workspaceId, installation.id);\n } catch {\n /* An invalid host configuration cannot produce an unsafe embed. */\n }\n return (\n <div\n key={installation.id}\n className=\"space-y-2 rounded-md border border-border-default p-3\"\n >\n <p className=\"font-medium\">\n {installation.name} · {installation.enabled ? 'Enabled' : 'Disabled'}\n </p>\n <p className=\"text-sm text-text-secondary\">\n {installation.allowedOrigins.join(', ')}\n </p>\n {installation.enabled && (\n <>\n {snippet ? (\n <>\n <textarea\n aria-label={`Installation snippet for ${installation.name}`}\n readOnly\n value={snippet}\n rows={3}\n className=\"w-full rounded-md border border-border-default bg-bg-sunken p-2 font-mono text-xs\"\n />\n <Button\n variant=\"outline\"\n onClick={async () => {\n try {\n await navigator.clipboard.writeText(snippet);\n showMessage('Installation snippet copied.');\n } catch {\n showMessage(\n 'Copy unavailable. Select and copy the snippet above.',\n true\n );\n }\n }}\n >\n Copy snippet\n </Button>\n </>\n ) : (\n <p role=\"alert\">The website widget address is unavailable.</p>\n )}\n <Button\n variant=\"outline\"\n isLoading={websites.disable.isPending}\n onClick={async () => {\n try {\n await websites.disable.mutateAsync(installation.id);\n showMessage(\n 'Publication disabled. Existing visitors can no longer receive answers.'\n );\n } catch {\n showMessage('Disable failed. Reload publications and try again.', true);\n }\n }}\n >\n Disable publication\n </Button>\n </>\n )}\n </div>\n );\n })\n )}\n <p className=\"text-sm text-text-secondary\">\n Changes to the assistant or its models revoke existing website sessions. Create a new\n publication after reviewing the updated configuration.\n </p>\n </section>\n );\n}\n"],"mappings":";;;;;;;AAMA,SAAgBC,EACd,GACA,GACA,GACQ;CACR,IAAMC,IAAM,IAAI,IAAIC,CAAO;CAC3B,IACED,EAAI,aAAa,YACjBA,EAAI,YACJA,EAAI,YACJA,EAAI,UACJA,EAAI,QACJ,CAAC,mBAAmB,KAAKE,CAAW,KACpC,CAAC,mBAAmB,KAAKC,CAAc,GAEvC,MAAU,MAAM,gCAAgC;CAClD,OAAO,gBAAgBH,EAAI,OAAO,gDAAgDE,EAAY,uBAAuBC,EAAe;AACtI;AACA,SAAgBC,EAAsB,EACpC,YACA,uBAIC;CACD,IAAM,EAAE,gBAAa,mBAAgBC,EAAU;CAC/C,OACE,kBAACC,GAAD;EAEW;EACS;CACnB,GAHM,GAAGJ,EAAY,GAAGK,GAAa,GAAG,GAAGC,EAAQ,GAAGC,EAAiB,KAAK,GAAG,GAG/E;AAEL;AACA,SAASH,EAAmB,EAC1B,YACA,uBAIC;CACD,IAAM,EAAE,qBAAkBD,EAAU,GAClCK,IAAWC,EAAqBH,CAAO,GACvCI,IAAQC,EAAkB,GACtB,CAACC,GAAMC,KAAWC,EAAS,mBAAmB,GAClD,CAACC,GAASC,KAAcF,EAAS,EAAE,GACnC,CAACG,GAAUC,KAAeJ,EAAS,EAAK,GACxC,CAACK,GAASC,KAAcN,EAAS,EAAE,GACnC,CAACO,GAAQC,KAAaR,EAAS,EAAK,GAChCf,IACJwB,MACC,OAAO,SAAW,OAAe,OAAO,SAAS,SAAS,WAAW,OAAO,IACzE,iDACA,4CACAC,IAAUjB,EAAiB,KAAK,MAAOG,EAAM,MAAM,MAAM,MAASe,EAAK,OAAOC,CAAE,CAAC,GACjFC,KAAe,GAAe,IAAQ,OAAU;EAEpD,AADAP,EAAWQ,CAAK,GAChBN,EAAUO,CAAK;CACjB;CACA,OACE,kBAAC,WAAD;EAAS,WAAU;EAAnB,UAAA;GACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,MAAD;IAAI,WAAU;IAAwB,UAAA;GAAqB,CAAA,GAC3D,kBAAC,KAAD;IAAG,WAAU;IAA8B,UAAA;GAGxC,CAAA,CACA,EAAA,CAAA;GACL,kBAAC,SAAD;IAAO,WAAU;IAAjB,UAAA,CAAkD,gBAEhD,kBAAC,SAAD;KACE,WAAU;KACV,WAAW;KACX,OAAOjB;KACP,UAAUJ,EAAS,QAAQ;KAC3B,WAAW,MAAUK,EAAQiB,EAAM,OAAO,KAAK;IAChD,CAAA,CACI;;GACP,kBAAC,SAAD;IAAO,WAAU;IAAjB,UAAA;KAAkD;KAEhD,kBAAC,YAAD;MACE,WAAU;MACV,MAAM;MACN,aAAY;MACZ,OAAOf;MACP,UAAUP,EAAS,QAAQ;MAC3B,WAAW,MAAU;OAEnB,AADAQ,EAAWc,EAAM,OAAO,KAAK,GAC7BZ,EAAY,EAAK;MACnB;KACD,CAAA;KACD,kBAAC,QAAD;MAAM,WAAU;MAAkC,UAAA;KAE5C,CAAA;IACD;;GACP,kBAAC,OAAD;IAAK,WAAU;IAAf,UAAA,CACE,kBAAC,KAAD;KAAG,WAAU;KAAc,UAAA;IAA+C,CAAA,GACzER,EAAM,UACL,kBAAC,KAAD;KAAG,MAAK;KAAS,UAAA;IAA6B,CAAA,IAC5Cc,EAAQ,MAAM,MAAW,CAACO,CAAM,IAClC,kBAAC,KAAD;KAAG,MAAK;KAAQ,UAAA;IAEb,CAAA,IACDxB,EAAiB,SACnB,kBAAC,MAAD;KAAI,WAAU;KACX,UAAAiB,EAAQ,KAAK,MAAWO,KAAU,kBAAC,MAAD,EAAA,UAAqBA,EAAO,KAAS,GAA5BA,EAAO,EAAqB,CAAC;IACvE,CAAA,IAEJ,kBAAC,KAAD,EAAA,UAAG,oDAAoD,CAAA,CAEtD;;GACL,kBAAC,SAAD;IAAO,WAAU;IAAjB,UAAA,CACE,kBAAC,SAAD;KACE,MAAK;KACL,SAASd;KACT,UACET,EAAS,QAAQ,aAAaE,EAAM,WAAWc,EAAQ,MAAM,MAAW,CAACO,CAAM;KAEjF,WAAW,MAAUb,EAAYY,EAAM,OAAO,OAAO;IACtD,CAAA,GAAC,iGAGG;;GACP,kBAACE,GAAD;IACE,UAAU,CAACf,KAAY,CAACL,EAAK,KAAK,KAAK,CAACG,EAAQ,KAAK,KAAKR,EAAiB,SAAS;IACpF,WAAWC,EAAS,QAAQ;IAC5B,SAAS,YAAY;KACnB,EAAY,EAAE;KACd,IAAI;MACF,IAAMyB,IAAiBlB,EACpB,MAAM,IAAI,CAAC,CACX,KAAK,MAAWmB,EAAO,KAAK,CAAC,CAAC,CAC9B,OAAO,OAAO;MACjB,IACED,EAAe,SAAS,MACxBA,EAAe,MAAM,MAAW;OAC9B,IAAI;QACF,IAAMnC,IAAM,IAAI,IAAIoC,CAAM;QAC1B,OACEpC,EAAI,aAAa,YACjBoC,MAAWpC,EAAI,UACf,GAAQA,EAAI,YAAYA,EAAI,aAC5BA,EAAI,SAAS,SAAS,GAAG;OAE7B,QAAQ;QACN,OAAO;OACT;MACF,CAAC,GACD;OACA,EAAY,yCAAyC,EAAI;OACzD;MACF;MAOA,AANA,MAAMU,EAAS,QAAQ,YAAY;OACjC;OACA;OACA,0BAA0BD;MAC5B,CAAC,GACDW,EAAY,EAAK,GACjBS,EAAY,sEAAsE;KACpF,QAAQ;MACN,EACE,oHACA,EACF;KACF;IACF;IACD,UAAA;GAEO,CAAA;GACPR,KAAW,kBAAC,KAAD;IAAG,MAAME,IAAS,UAAU;IAAW,UAAAF;GAAW,CAAA;GAC7DX,EAAS,cAAc,YACtB,kBAAC,KAAD;IAAG,MAAK;IAAS,UAAA;GAAgC,CAAA,IAC/CA,EAAS,cAAc,UACzB,kBAAC,OAAD;IAAK,MAAK;IAAV,UAAA,CACE,kBAAC,KAAD,EAAA,UAAG,+EAA+E,CAAA,GAClF,kBAACwB,GAAD;KAAQ,SAAQ;KAAU,eAAe,KAAKxB,EAAS,cAAc,QAAQ;KAAG,UAAA;IAExE,CAAA,CACL;GAEL,CAAA,IAAAA,EAAS,cAAc,MAAM,KAAK,MAAiB;IACjD,IAAI2B,IAAU;IACd,IAAI;KACF,IAAUtC,EAAuBE,GAASqC,EAAa,aAAaA,EAAa,EAAE;IACrF,QAAQ,CAER;IACA,OACE,kBAAC,OAAD;KAEE,WAAU;KAFZ,UAAA;MAIE,kBAAC,KAAD;OAAG,WAAU;OAAb,UAAA;QACGA,EAAa;QAAK;QAAIA,EAAa,UAAU,YAAY;OACzD;;MACH,kBAAC,KAAD;OAAG,WAAU;OACV,UAAAA,EAAa,eAAe,KAAK,IAAI;MACrC,CAAA;MACFA,EAAa,WACZ,kBAAAxC,GAAA,EAAA,UAAA,CACGuC,IACC,kBAAAvC,GAAA,EAAA,UAAA,CACE,kBAAC,YAAD;OACE,cAAY,4BAA4BwC,EAAa;OACrD,UAAA;OACA,OAAOD;OACP,MAAM;OACN,WAAU;MACX,CAAA,GACD,kBAACH,GAAD;OACE,SAAQ;OACR,SAAS,YAAY;QACnB,IAAI;SAEF,AADA,MAAM,UAAU,UAAU,UAAUG,CAAO,GAC3CR,EAAY,8BAA8B;QAC5C,QAAQ;SACN,EACE,wDACA,EACF;QACF;OACF;OACD,UAAA;MAEO,CAAA,CACR,EAAA,CAAA,IAEF,kBAAC,KAAD;OAAG,MAAK;OAAQ,UAAA;MAA6C,CAAA,GAE/D,kBAACK,GAAD;OACE,SAAQ;OACR,WAAWxB,EAAS,QAAQ;OAC5B,SAAS,YAAY;QACnB,IAAI;SAEF,AADA,MAAMA,EAAS,QAAQ,YAAY4B,EAAa,EAAE,GAClDT,EACE,wEACF;QACF,QAAQ;SACN,EAAY,sDAAsD,EAAI;QACxE;OACF;OACD,UAAA;MAEO,CAAA,CACR,EAAA,CAAA;KAED;IA1DE,GAAAS,EAAa,EA0Df;GAET,CAAC;GAEH,kBAAC,KAAD;IAAG,WAAU;IAA8B,UAAA;GAGxC,CAAA;EACI;;AAEb"}
@@ -0,0 +1,9 @@
1
+ import { FC, HTMLAttributes } from 'react';
2
+ interface BadgeProps extends HTMLAttributes<HTMLSpanElement> {
3
+ variant?: 'default' | 'secondary' | 'success' | 'warning' | 'destructive' | 'outline';
4
+ }
5
+ export declare const Badge: FC<BadgeProps>;
6
+ export declare const StatusBadge: FC<{
7
+ status: string;
8
+ }>;
9
+ export {};
@@ -1,6 +1,6 @@
1
1
  import { cn as e } from "../utils/cn.js";
2
2
  import { jsx as t } from "react/jsx-runtime";
3
- //#region src/botlit/components/Badge.tsx
3
+ // src/botlit/components/Badge.tsx
4
4
  var n = {
5
5
  default: "bg-action-primary-bg text-action-primary-text",
6
6
  secondary: "bg-secondary text-secondary-foreground",
@@ -33,7 +33,6 @@ var n = {
33
33
  }[e.toLowerCase()] || "default",
34
34
  children: e
35
35
  });
36
- //#endregion
37
36
  export { r as Badge, i as StatusBadge };
38
37
 
39
38
  //# sourceMappingURL=Badge.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Badge.js","names":[],"sources":["../../../src/botlit/components/Badge.tsx"],"sourcesContent":["/**\n * Badge Component\n * @module botlit/components\n */\n\nimport type { FC, HTMLAttributes } from 'react';\nimport { cn } from '../utils/cn';\n\ninterface BadgeProps extends HTMLAttributes<HTMLSpanElement> {\n variant?: 'default' | 'secondary' | 'success' | 'warning' | 'destructive' | 'outline';\n}\n\nconst variantStyles = {\n default: 'bg-action-primary-bg text-action-primary-text',\n secondary: 'bg-secondary text-secondary-foreground',\n success: 'bg-green-500/20 text-green-600 dark:text-green-400',\n warning: 'bg-yellow-500/20 text-yellow-600 dark:text-yellow-400',\n destructive: 'bg-status-error-bg/20 text-status-error-text',\n outline: 'border border-border-subtle text-text-primary',\n};\n\nexport const Badge: FC<BadgeProps> = ({ className, variant = 'default', ...props }) => {\n return (\n <span\n className={cn(\n 'inline-flex items-center rounded-full px-2.5 py-0.5 text-xs font-medium',\n variantStyles[variant],\n className\n )}\n {...props}\n />\n );\n};\n\n// Status-specific badges\nexport const StatusBadge: FC<{ status: string }> = ({ status }) => {\n const variants: Record<string, BadgeProps['variant']> = {\n active: 'success',\n ready: 'success',\n connected: 'success',\n running: 'success',\n completed: 'success',\n draft: 'secondary',\n pending: 'secondary',\n paused: 'warning',\n training: 'warning',\n indexing: 'warning',\n processing: 'warning',\n connecting: 'warning',\n error: 'destructive',\n failed: 'destructive',\n disconnected: 'destructive',\n archived: 'outline',\n cancelled: 'outline',\n };\n\n return <Badge variant={variants[status.toLowerCase()] || 'default'}>{status}</Badge>;\n};\n"],"mappings":";;;AAYA,IAAM,IAAgB;CACpB,SAAS;CACT,WAAW;CACX,SAAS;CACT,SAAS;CACT,aAAa;CACb,SAAS;CACV,EAEY,KAAyB,EAAE,cAAW,aAAU,WAAW,GAAG,QAEvE,kBAAC,QAAD;CACE,WAAW,EACT,2EACA,EAAc,IACd,EACD;CACD,GAAI;CACJ,CAAA,EAKO,KAAuC,EAAE,gBAqB7C,kBAAC,GAAD;CAAO,SApB0C;EACtD,QAAQ;EACR,OAAO;EACP,WAAW;EACX,SAAS;EACT,WAAW;EACX,OAAO;EACP,SAAS;EACT,QAAQ;EACR,UAAU;EACV,UAAU;EACV,YAAY;EACZ,YAAY;EACZ,OAAO;EACP,QAAQ;EACR,cAAc;EACd,UAAU;EACV,WAAW;EACZ,CAE+B,EAAO,aAAa,KAAK;WAAY;CAAe,CAAA"}
1
+ {"version":3,"file":"Badge.js","names":["variantStyles","Badge","props","cn","variant","className","StatusBadge","status"],"sources":["../../../src/botlit/components/Badge.tsx"],"sourcesContent":["/**\n * Badge Component\n * @module botlit/components\n */\n\nimport type { FC, HTMLAttributes } from 'react';\nimport { cn } from '../utils/cn';\n\ninterface BadgeProps extends HTMLAttributes<HTMLSpanElement> {\n variant?: 'default' | 'secondary' | 'success' | 'warning' | 'destructive' | 'outline';\n}\n\nconst variantStyles = {\n default: 'bg-action-primary-bg text-action-primary-text',\n secondary: 'bg-secondary text-secondary-foreground',\n success: 'bg-green-500/20 text-green-600 dark:text-green-400',\n warning: 'bg-yellow-500/20 text-yellow-600 dark:text-yellow-400',\n destructive: 'bg-status-error-bg/20 text-status-error-text',\n outline: 'border border-border-subtle text-text-primary',\n};\n\nexport const Badge: FC<BadgeProps> = ({ className, variant = 'default', ...props }) => {\n return (\n <span\n className={cn(\n 'inline-flex items-center rounded-full px-2.5 py-0.5 text-xs font-medium',\n variantStyles[variant],\n className\n )}\n {...props}\n />\n );\n};\n\n// Status-specific badges\nexport const StatusBadge: FC<{ status: string }> = ({ status }) => {\n const variants: Record<string, BadgeProps['variant']> = {\n active: 'success',\n ready: 'success',\n connected: 'success',\n running: 'success',\n completed: 'success',\n draft: 'secondary',\n pending: 'secondary',\n paused: 'warning',\n training: 'warning',\n indexing: 'warning',\n processing: 'warning',\n connecting: 'warning',\n error: 'destructive',\n failed: 'destructive',\n disconnected: 'destructive',\n archived: 'outline',\n cancelled: 'outline',\n };\n\n return <Badge variant={variants[status.toLowerCase()] || 'default'}>{status}</Badge>;\n};\n"],"mappings":";;;AAYA,IAAMA,IAAgB;CACpB,SAAS;CACT,WAAW;CACX,SAAS;CACT,SAAS;CACT,aAAa;CACb,SAAS;AACX,GAEaC,KAAyB,EAAE,cAAW,aAAU,WAAW,GAAGC,QAEvE,kBAAC,QAAD;CACE,WAAWC,EACT,2EACAH,EAAcI,IACdC,CACF;CACA,GAAIH;AACL,CAAA,GAKQI,KAAuC,EAAE,gBAqB7C,kBAACL,GAAD;CAAO,SAAS;EAnBrB,QAAQ;EACR,OAAO;EACP,WAAW;EACX,SAAS;EACT,WAAW;EACX,OAAO;EACP,SAAS;EACT,QAAQ;EACR,UAAU;EACV,UAAU;EACV,YAAY;EACZ,YAAY;EACZ,OAAO;EACP,QAAQ;EACR,cAAc;EACd,UAAU;EACV,WAAW;CAGU,EAASM,EAAO,YAAY,MAAM;CAAY,UAAAA;AAAc,CAAA"}
@@ -0,0 +1,10 @@
1
+ import { FC, ButtonHTMLAttributes, ReactNode } from 'react';
2
+ interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
3
+ variant?: 'default' | 'primary' | 'secondary' | 'outline' | 'ghost' | 'destructive';
4
+ size?: 'sm' | 'md' | 'lg' | 'icon';
5
+ isLoading?: boolean;
6
+ leftIcon?: ReactNode;
7
+ rightIcon?: ReactNode;
8
+ }
9
+ export declare const Button: FC<ButtonProps>;
10
+ export {};
@@ -1,6 +1,6 @@
1
1
  import { cn as e } from "../utils/cn.js";
2
2
  import { jsx as t, jsxs as n } from "react/jsx-runtime";
3
- //#region src/botlit/components/Button.tsx
3
+ // src/botlit/components/Button.tsx
4
4
  var r = {
5
5
  default: "bg-action-primary-bg text-action-primary-text hover:bg-action-primary-bg/90",
6
6
  primary: "bg-action-primary-bg text-action-primary-text hover:bg-action-primary-bg/90",
@@ -40,7 +40,6 @@ var r = {
40
40
  u
41
41
  ]
42
42
  });
43
- //#endregion
44
43
  export { a as Button };
45
44
 
46
45
  //# sourceMappingURL=Button.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Button.js","names":[],"sources":["../../../src/botlit/components/Button.tsx"],"sourcesContent":["/**\n * Button Component\n * @module botlit/components\n */\n\nimport type { FC, ButtonHTMLAttributes, ReactNode } from 'react';\nimport { cn } from '../utils/cn';\n\ninterface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {\n variant?: 'default' | 'primary' | 'secondary' | 'outline' | 'ghost' | 'destructive';\n size?: 'sm' | 'md' | 'lg' | 'icon';\n isLoading?: boolean;\n leftIcon?: ReactNode;\n rightIcon?: ReactNode;\n}\n\nconst variantStyles = {\n default: 'bg-action-primary-bg text-action-primary-text hover:bg-action-primary-bg/90',\n primary: 'bg-action-primary-bg text-action-primary-text hover:bg-action-primary-bg/90',\n secondary: 'bg-secondary text-secondary-foreground hover:bg-secondary/80',\n outline: 'border border-border-default bg-bg-surface hover:bg-accent hover:text-text-primary',\n ghost: 'hover:bg-accent hover:text-text-primary',\n destructive: 'bg-status-error-bg text-status-error-text hover:bg-status-error-bg/90',\n};\n\nconst sizeStyles = {\n sm: 'h-8 px-3 text-xs',\n md: 'h-10 px-4 text-sm',\n lg: 'h-12 px-6 text-base',\n icon: 'h-10 w-10',\n};\n\nexport const Button: FC<ButtonProps> = ({\n className,\n variant = 'default',\n size = 'md',\n isLoading,\n leftIcon,\n rightIcon,\n disabled,\n children,\n ...props\n}) => {\n return (\n <button\n className={cn(\n 'inline-flex items-center justify-center gap-2 rounded-md font-medium transition-colors',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-focus-ring)] focus-visible:ring-offset-2',\n 'disabled:pointer-events-none disabled:opacity-50',\n variantStyles[variant],\n sizeStyles[size],\n className\n )}\n disabled={disabled || isLoading}\n {...props}\n >\n {isLoading ? (\n <svg\n className=\"h-4 w-4 animate-spin\"\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n >\n <circle\n className=\"opacity-25\"\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n strokeWidth=\"4\"\n />\n <path\n className=\"opacity-75\"\n fill=\"currentColor\"\n d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"\n />\n </svg>\n ) : (\n leftIcon\n )}\n {children}\n {rightIcon}\n </button>\n );\n};\n"],"mappings":";;;AAgBA,IAAM,IAAgB;CACpB,SAAS;CACT,SAAS;CACT,WAAW;CACX,SAAS;CACT,OAAO;CACP,aAAa;CACd,EAEK,IAAa;CACjB,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,MAAM;CACP,EAEY,KAA2B,EACtC,cACA,aAAU,WACV,UAAO,MACP,cACA,aACA,cACA,aACA,aACA,GAAG,QAGD,kBAAC,UAAD;CACE,WAAW,EACT,0FACA,4HACA,oDACA,EAAc,IACd,EAAW,IACX,EACD;CACD,UAAU,KAAY;CACtB,GAAI;WAVN;EAYG,IACC,kBAAC,OAAD;GACE,WAAU;GACV,OAAM;GACN,MAAK;GACL,SAAQ;aAJV,CAME,kBAAC,UAAD;IACE,WAAU;IACV,IAAG;IACH,IAAG;IACH,GAAE;IACF,QAAO;IACP,aAAY;IACZ,CAAA,EACF,kBAAC,QAAD;IACE,WAAU;IACV,MAAK;IACL,GAAE;IACF,CAAA,CACE;OAEN;EAED;EACA;EACM"}
1
+ {"version":3,"file":"Button.js","names":["variantStyles","sizeStyles","Button","props","cn","variant","size","className","disabled","isLoading","leftIcon","children","rightIcon"],"sources":["../../../src/botlit/components/Button.tsx"],"sourcesContent":["/**\n * Button Component\n * @module botlit/components\n */\n\nimport type { FC, ButtonHTMLAttributes, ReactNode } from 'react';\nimport { cn } from '../utils/cn';\n\ninterface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {\n variant?: 'default' | 'primary' | 'secondary' | 'outline' | 'ghost' | 'destructive';\n size?: 'sm' | 'md' | 'lg' | 'icon';\n isLoading?: boolean;\n leftIcon?: ReactNode;\n rightIcon?: ReactNode;\n}\n\nconst variantStyles = {\n default: 'bg-action-primary-bg text-action-primary-text hover:bg-action-primary-bg/90',\n primary: 'bg-action-primary-bg text-action-primary-text hover:bg-action-primary-bg/90',\n secondary: 'bg-secondary text-secondary-foreground hover:bg-secondary/80',\n outline: 'border border-border-default bg-bg-surface hover:bg-accent hover:text-text-primary',\n ghost: 'hover:bg-accent hover:text-text-primary',\n destructive: 'bg-status-error-bg text-status-error-text hover:bg-status-error-bg/90',\n};\n\nconst sizeStyles = {\n sm: 'h-8 px-3 text-xs',\n md: 'h-10 px-4 text-sm',\n lg: 'h-12 px-6 text-base',\n icon: 'h-10 w-10',\n};\n\nexport const Button: FC<ButtonProps> = ({\n className,\n variant = 'default',\n size = 'md',\n isLoading,\n leftIcon,\n rightIcon,\n disabled,\n children,\n ...props\n}) => {\n return (\n <button\n className={cn(\n 'inline-flex items-center justify-center gap-2 rounded-md font-medium transition-colors',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-focus-ring)] focus-visible:ring-offset-2',\n 'disabled:pointer-events-none disabled:opacity-50',\n variantStyles[variant],\n sizeStyles[size],\n className\n )}\n disabled={disabled || isLoading}\n {...props}\n >\n {isLoading ? (\n <svg\n className=\"h-4 w-4 animate-spin\"\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n >\n <circle\n className=\"opacity-25\"\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n strokeWidth=\"4\"\n />\n <path\n className=\"opacity-75\"\n fill=\"currentColor\"\n d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"\n />\n </svg>\n ) : (\n leftIcon\n )}\n {children}\n {rightIcon}\n </button>\n );\n};\n"],"mappings":";;;AAgBA,IAAMA,IAAgB;CACpB,SAAS;CACT,SAAS;CACT,WAAW;CACX,SAAS;CACT,OAAO;CACP,aAAa;AACf,GAEMC,IAAa;CACjB,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,MAAM;AACR,GAEaC,KAA2B,EACtC,cACA,aAAU,WACV,UAAO,MACP,cACA,aACA,cACA,aACA,aACA,GAAGC,QAGD,kBAAC,UAAD;CACE,WAAWC,EACT,0FACA,4HACA,oDACAJ,EAAcK,IACdJ,EAAWK,IACXC,CACF;CACA,UAAUC,KAAYC;CACtB,GAAIN;CAVN,UAAA;EAYGM,IACC,kBAAC,OAAD;GACE,WAAU;GACV,OAAM;GACN,MAAK;GACL,SAAQ;GAJV,UAAA,CAME,kBAAC,UAAD;IACE,WAAU;IACV,IAAG;IACH,IAAG;IACH,GAAE;IACF,QAAO;IACP,aAAY;GACb,CAAA,GACD,kBAAC,QAAD;IACE,WAAU;IACV,MAAK;IACL,GAAE;GACH,CAAA,CACE;EAEL,CAAA,IAAAC;EAEDC;EACAC;CACK"}
@@ -0,0 +1,16 @@
1
+ import { FC, ReactNode, HTMLAttributes } from 'react';
2
+ import { GlassCardProps } from '@burdenoff/fe-libs/ui';
3
+ interface CardProps extends HTMLAttributes<HTMLDivElement> {
4
+ children: ReactNode;
5
+ /** Boff UI 2.0 glass treatment. Defaults to `plain`. */
6
+ treatment?: GlassCardProps['treatment'];
7
+ /** Featured/active accent glow (no movement). */
8
+ glow?: boolean;
9
+ }
10
+ export declare const Card: FC<CardProps>;
11
+ export declare const CardHeader: FC<HTMLAttributes<HTMLDivElement>>;
12
+ export declare const CardTitle: FC<HTMLAttributes<HTMLHeadingElement>>;
13
+ export declare const CardDescription: FC<HTMLAttributes<HTMLParagraphElement>>;
14
+ export declare const CardContent: FC<HTMLAttributes<HTMLDivElement>>;
15
+ export declare const CardFooter: FC<HTMLAttributes<HTMLDivElement>>;
16
+ export {};