@vertesia/ui 1.5.0-dev.20260714.072725Z → 1.5.0-dev.20260722.120446Z

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 (393) hide show
  1. package/lib/core/components/SidePanel.js +1 -1
  2. package/lib/core/components/SidePanel.js.map +1 -1
  3. package/lib/core/components/shadcn/button.d.ts +10 -3
  4. package/lib/core/components/shadcn/button.d.ts.map +1 -1
  5. package/lib/core/components/shadcn/button.js +41 -9
  6. package/lib/core/components/shadcn/button.js.map +1 -1
  7. package/lib/core/components/shadcn/modal/dialog.js +1 -1
  8. package/lib/core/components/shadcn/modal/dialog.js.map +1 -1
  9. package/lib/core/components/shadcn/theme/ThemeSwitcher.js +1 -1
  10. package/lib/core/components/shadcn/theme/ThemeSwitcher.js.map +1 -1
  11. package/lib/env/index.d.ts +19 -0
  12. package/lib/env/index.d.ts.map +1 -1
  13. package/lib/env/index.js +6 -0
  14. package/lib/env/index.js.map +1 -1
  15. package/lib/features/agent/chat/AgentChatPlaybackControls.d.ts.map +1 -1
  16. package/lib/features/agent/chat/AgentChatPlaybackControls.js +2 -2
  17. package/lib/features/agent/chat/AgentChatPlaybackControls.js.map +1 -1
  18. package/lib/features/agent/chat/AgentRequestInputOverlay.d.ts.map +1 -1
  19. package/lib/features/agent/chat/AgentRequestInputOverlay.js +2 -2
  20. package/lib/features/agent/chat/AgentRequestInputOverlay.js.map +1 -1
  21. package/lib/features/agent/chat/ArtifactsTab.d.ts.map +1 -1
  22. package/lib/features/agent/chat/ArtifactsTab.js +68 -11
  23. package/lib/features/agent/chat/ArtifactsTab.js.map +1 -1
  24. package/lib/features/agent/chat/ImageLightbox.d.ts.map +1 -1
  25. package/lib/features/agent/chat/ImageLightbox.js +1 -1
  26. package/lib/features/agent/chat/ImageLightbox.js.map +1 -1
  27. package/lib/features/agent/chat/ModernAgentConversation.js +52 -49
  28. package/lib/features/agent/chat/ModernAgentConversation.js.map +1 -1
  29. package/lib/features/agent/chat/ModernAgentOutput/AllMessagesMixed.d.ts.map +1 -1
  30. package/lib/features/agent/chat/ModernAgentOutput/AllMessagesMixed.js +5 -5
  31. package/lib/features/agent/chat/ModernAgentOutput/AllMessagesMixed.js.map +1 -1
  32. package/lib/features/agent/chat/ModernAgentOutput/Header.d.ts.map +1 -1
  33. package/lib/features/agent/chat/ModernAgentOutput/Header.js +4 -2
  34. package/lib/features/agent/chat/ModernAgentOutput/Header.js.map +1 -1
  35. package/lib/features/agent/chat/ModernAgentOutput/MessageInput.d.ts.map +1 -1
  36. package/lib/features/agent/chat/ModernAgentOutput/MessageInput.js +2 -2
  37. package/lib/features/agent/chat/ModernAgentOutput/MessageInput.js.map +1 -1
  38. package/lib/features/agent/chat/ModernAgentOutput/MessageItem.d.ts.map +1 -1
  39. package/lib/features/agent/chat/ModernAgentOutput/MessageItem.js +2 -1
  40. package/lib/features/agent/chat/ModernAgentOutput/MessageItem.js.map +1 -1
  41. package/lib/features/agent/chat/ModernAgentOutput/requestInputMessages.d.ts +6 -0
  42. package/lib/features/agent/chat/ModernAgentOutput/requestInputMessages.d.ts.map +1 -1
  43. package/lib/features/agent/chat/ModernAgentOutput/requestInputMessages.js +15 -1
  44. package/lib/features/agent/chat/ModernAgentOutput/requestInputMessages.js.map +1 -1
  45. package/lib/features/agent/chat/hooks/useArtifacts.d.ts +8 -1
  46. package/lib/features/agent/chat/hooks/useArtifacts.d.ts.map +1 -1
  47. package/lib/features/agent/chat/hooks/useArtifacts.js +28 -10
  48. package/lib/features/agent/chat/hooks/useArtifacts.js.map +1 -1
  49. package/lib/features/document-viewer/UniversalDocumentViewer.d.ts +73 -0
  50. package/lib/features/document-viewer/UniversalDocumentViewer.d.ts.map +1 -0
  51. package/lib/features/document-viewer/UniversalDocumentViewer.js +415 -0
  52. package/lib/features/document-viewer/UniversalDocumentViewer.js.map +1 -0
  53. package/lib/features/document-viewer/index.d.ts +2 -0
  54. package/lib/features/document-viewer/index.d.ts.map +1 -0
  55. package/lib/features/document-viewer/index.js +2 -0
  56. package/lib/features/document-viewer/index.js.map +1 -0
  57. package/lib/features/environment/SelectEnvironment.d.ts +28 -0
  58. package/lib/features/environment/SelectEnvironment.d.ts.map +1 -0
  59. package/lib/features/environment/SelectEnvironment.js +97 -0
  60. package/lib/features/environment/SelectEnvironment.js.map +1 -0
  61. package/lib/features/environment/index.d.ts +2 -0
  62. package/lib/features/environment/index.d.ts.map +1 -0
  63. package/lib/features/environment/index.js +2 -0
  64. package/lib/features/environment/index.js.map +1 -0
  65. package/lib/features/index.d.ts +3 -0
  66. package/lib/features/index.d.ts.map +1 -1
  67. package/lib/features/index.js +3 -0
  68. package/lib/features/index.js.map +1 -1
  69. package/lib/features/magic-pdf/AnnotatedImageSlider.js +12 -12
  70. package/lib/features/magic-pdf/AnnotatedImageSlider.js.map +1 -1
  71. package/lib/features/magic-pdf/DownloadPopover.d.ts.map +1 -1
  72. package/lib/features/magic-pdf/DownloadPopover.js +3 -17
  73. package/lib/features/magic-pdf/DownloadPopover.js.map +1 -1
  74. package/lib/features/magic-pdf/ExtractedContentView.js +2 -6
  75. package/lib/features/magic-pdf/ExtractedContentView.js.map +1 -1
  76. package/lib/features/magic-pdf/GroundedExtractionAssistantPanel.d.ts +25 -0
  77. package/lib/features/magic-pdf/GroundedExtractionAssistantPanel.d.ts.map +1 -0
  78. package/lib/features/magic-pdf/GroundedExtractionAssistantPanel.js +42 -0
  79. package/lib/features/magic-pdf/GroundedExtractionAssistantPanel.js.map +1 -0
  80. package/lib/features/magic-pdf/GroundedExtractionView.d.ts +27 -0
  81. package/lib/features/magic-pdf/GroundedExtractionView.d.ts.map +1 -0
  82. package/lib/features/magic-pdf/GroundedExtractionView.js +377 -0
  83. package/lib/features/magic-pdf/GroundedExtractionView.js.map +1 -0
  84. package/lib/features/magic-pdf/MagicPdfProvider.d.ts +0 -2
  85. package/lib/features/magic-pdf/MagicPdfProvider.d.ts.map +1 -1
  86. package/lib/features/magic-pdf/MagicPdfProvider.js +15 -42
  87. package/lib/features/magic-pdf/MagicPdfProvider.js.map +1 -1
  88. package/lib/features/magic-pdf/MagicPdfView.d.ts.map +1 -1
  89. package/lib/features/magic-pdf/MagicPdfView.js +2 -19
  90. package/lib/features/magic-pdf/MagicPdfView.js.map +1 -1
  91. package/lib/features/magic-pdf/index.d.ts +1 -0
  92. package/lib/features/magic-pdf/index.d.ts.map +1 -1
  93. package/lib/features/magic-pdf/index.js +1 -0
  94. package/lib/features/magic-pdf/index.js.map +1 -1
  95. package/lib/features/magic-pdf/types.d.ts +1 -1
  96. package/lib/features/magic-pdf/types.d.ts.map +1 -1
  97. package/lib/features/oauth/McpConnectionsButton.d.ts.map +1 -1
  98. package/lib/features/oauth/McpConnectionsButton.js +2 -2
  99. package/lib/features/oauth/McpConnectionsButton.js.map +1 -1
  100. package/lib/features/oauth/McpConnectionsDialog.d.ts.map +1 -1
  101. package/lib/features/oauth/McpConnectionsDialog.js +1 -1
  102. package/lib/features/oauth/McpConnectionsDialog.js.map +1 -1
  103. package/lib/features/oauth/RemoteMcpConnectionButton.d.ts.map +1 -1
  104. package/lib/features/oauth/RemoteMcpConnectionButton.js +1 -1
  105. package/lib/features/oauth/RemoteMcpConnectionButton.js.map +1 -1
  106. package/lib/features/pdf-viewer/PdfPageSlider.js +2 -2
  107. package/lib/features/pdf-viewer/PdfPageSlider.js.map +1 -1
  108. package/lib/features/pdf-viewer/SimplePdfViewer.d.ts.map +1 -1
  109. package/lib/features/pdf-viewer/SimplePdfViewer.js +3 -3
  110. package/lib/features/pdf-viewer/SimplePdfViewer.js.map +1 -1
  111. package/lib/features/permissions/UserPermissionsProvider.d.ts +2 -3
  112. package/lib/features/permissions/UserPermissionsProvider.d.ts.map +1 -1
  113. package/lib/features/permissions/UserPermissionsProvider.js +31 -38
  114. package/lib/features/permissions/UserPermissionsProvider.js.map +1 -1
  115. package/lib/features/store/objects/DocumentQuickFilter.d.ts.map +1 -1
  116. package/lib/features/store/objects/DocumentQuickFilter.js +5 -5
  117. package/lib/features/store/objects/DocumentQuickFilter.js.map +1 -1
  118. package/lib/features/store/objects/DocumentSearchResults.d.ts.map +1 -1
  119. package/lib/features/store/objects/DocumentSearchResults.js +2 -2
  120. package/lib/features/store/objects/DocumentSearchResults.js.map +1 -1
  121. package/lib/features/store/objects/components/ContentDispositionButton.d.ts.map +1 -1
  122. package/lib/features/store/objects/components/ContentDispositionButton.js +1 -1
  123. package/lib/features/store/objects/components/ContentDispositionButton.js.map +1 -1
  124. package/lib/features/store/objects/components/ContentOverview.d.ts.map +1 -1
  125. package/lib/features/store/objects/components/ContentOverview.js +148 -31
  126. package/lib/features/store/objects/components/ContentOverview.js.map +1 -1
  127. package/lib/features/store/objects/components/DocumentIcon.js +1 -1
  128. package/lib/features/store/objects/components/VectorSearchWidget.js +1 -1
  129. package/lib/features/store/objects/components/VectorSearchWidget.js.map +1 -1
  130. package/lib/features/store/objects/components/useContentPanelHooks.d.ts +1 -2
  131. package/lib/features/store/objects/components/useContentPanelHooks.d.ts.map +1 -1
  132. package/lib/features/store/objects/components/useContentPanelHooks.js +4 -8
  133. package/lib/features/store/objects/components/useContentPanelHooks.js.map +1 -1
  134. package/lib/features/store/objects/layout/renderers.d.ts.map +1 -1
  135. package/lib/features/store/objects/layout/renderers.js +2 -2
  136. package/lib/features/store/objects/layout/renderers.js.map +1 -1
  137. package/lib/features/store/objects/selection/SelectionActions.js +1 -1
  138. package/lib/features/store/objects/selection/SelectionActions.js.map +1 -1
  139. package/lib/features/store/types/ContentObjectTypesTable.d.ts.map +1 -1
  140. package/lib/features/store/types/ContentObjectTypesTable.js +4 -4
  141. package/lib/features/store/types/ContentObjectTypesTable.js.map +1 -1
  142. package/lib/features/store/types/IntakePolicyEditor.d.ts +15 -0
  143. package/lib/features/store/types/IntakePolicyEditor.d.ts.map +1 -0
  144. package/lib/features/store/types/IntakePolicyEditor.js +455 -0
  145. package/lib/features/store/types/IntakePolicyEditor.js.map +1 -0
  146. package/lib/features/store/types/IntakePolicyForm.d.ts +11 -0
  147. package/lib/features/store/types/IntakePolicyForm.d.ts.map +1 -0
  148. package/lib/features/store/types/IntakePolicyForm.js +91 -0
  149. package/lib/features/store/types/IntakePolicyForm.js.map +1 -0
  150. package/lib/features/store/types/SelectContentTypeModal.js +1 -1
  151. package/lib/features/store/types/SelectContentTypeModal.js.map +1 -1
  152. package/lib/features/store/types/index.d.ts +2 -0
  153. package/lib/features/store/types/index.d.ts.map +1 -1
  154. package/lib/features/store/types/index.js +2 -0
  155. package/lib/features/store/types/index.js.map +1 -1
  156. package/lib/features/store/types/intake-policy-editor.logic.d.ts +7 -0
  157. package/lib/features/store/types/intake-policy-editor.logic.d.ts.map +1 -0
  158. package/lib/features/store/types/intake-policy-editor.logic.js +60 -0
  159. package/lib/features/store/types/intake-policy-editor.logic.js.map +1 -0
  160. package/lib/features/store/types/typeCatalogCache.d.ts +5 -0
  161. package/lib/features/store/types/typeCatalogCache.d.ts.map +1 -0
  162. package/lib/features/store/types/typeCatalogCache.js +40 -0
  163. package/lib/features/store/types/typeCatalogCache.js.map +1 -0
  164. package/lib/features/user/UserInfo.js +7 -3
  165. package/lib/features/user/UserInfo.js.map +1 -1
  166. package/lib/features/views/ViewExperience.d.ts +20 -0
  167. package/lib/features/views/ViewExperience.d.ts.map +1 -0
  168. package/lib/features/views/ViewExperience.js +188 -0
  169. package/lib/features/views/ViewExperience.js.map +1 -0
  170. package/lib/features/views/ViewNavigation.d.ts +3 -0
  171. package/lib/features/views/ViewNavigation.d.ts.map +1 -0
  172. package/lib/features/views/ViewNavigation.js +36 -0
  173. package/lib/features/views/ViewNavigation.js.map +1 -0
  174. package/lib/features/views/ViewResults.d.ts +9 -0
  175. package/lib/features/views/ViewResults.d.ts.map +1 -0
  176. package/lib/features/views/ViewResults.js +229 -0
  177. package/lib/features/views/ViewResults.js.map +1 -0
  178. package/lib/features/views/ViewSearch.d.ts +3 -0
  179. package/lib/features/views/ViewSearch.d.ts.map +1 -0
  180. package/lib/features/views/ViewSearch.js +74 -0
  181. package/lib/features/views/ViewSearch.js.map +1 -0
  182. package/lib/features/views/index.d.ts +7 -0
  183. package/lib/features/views/index.d.ts.map +1 -0
  184. package/lib/features/views/index.js +7 -0
  185. package/lib/features/views/index.js.map +1 -0
  186. package/lib/features/views/types.d.ts +39 -0
  187. package/lib/features/views/types.d.ts.map +1 -0
  188. package/lib/features/views/types.js +2 -0
  189. package/lib/features/views/types.js.map +1 -0
  190. package/lib/features/views/viewState.d.ts +14 -0
  191. package/lib/features/views/viewState.d.ts.map +1 -0
  192. package/lib/features/views/viewState.js +117 -0
  193. package/lib/features/views/viewState.js.map +1 -0
  194. package/lib/i18n/locales/ar.json +18 -0
  195. package/lib/i18n/locales/de.json +14 -0
  196. package/lib/i18n/locales/en.json +246 -32
  197. package/lib/i18n/locales/es.json +15 -0
  198. package/lib/i18n/locales/fr.json +15 -0
  199. package/lib/i18n/locales/it.json +15 -0
  200. package/lib/i18n/locales/ja.json +13 -0
  201. package/lib/i18n/locales/ko.json +13 -0
  202. package/lib/i18n/locales/pt.json +15 -0
  203. package/lib/i18n/locales/ru.json +16 -0
  204. package/lib/i18n/locales/tr.json +14 -0
  205. package/lib/i18n/locales/zh-TW.json +13 -0
  206. package/lib/i18n/locales/zh.json +13 -0
  207. package/lib/router/HistoryNavigator.d.ts.map +1 -1
  208. package/lib/router/HistoryNavigator.js +27 -14
  209. package/lib/router/HistoryNavigator.js.map +1 -1
  210. package/lib/router/Nav.d.ts.map +1 -1
  211. package/lib/router/Nav.js +21 -6
  212. package/lib/router/Nav.js.map +1 -1
  213. package/lib/router/Router.d.ts.map +1 -1
  214. package/lib/router/Router.js +19 -4
  215. package/lib/router/Router.js.map +1 -1
  216. package/lib/router/path.d.ts +15 -0
  217. package/lib/router/path.d.ts.map +1 -1
  218. package/lib/router/path.js +43 -0
  219. package/lib/router/path.js.map +1 -1
  220. package/lib/session/UserSession.d.ts +6 -0
  221. package/lib/session/UserSession.d.ts.map +1 -1
  222. package/lib/session/UserSession.js +36 -12
  223. package/lib/session/UserSession.js.map +1 -1
  224. package/lib/session/UserSessionProvider.d.ts.map +1 -1
  225. package/lib/session/UserSessionProvider.js +111 -49
  226. package/lib/session/UserSessionProvider.js.map +1 -1
  227. package/lib/session/auth/composable.d.ts.map +1 -1
  228. package/lib/session/auth/composable.js +52 -3
  229. package/lib/session/auth/composable.js.map +1 -1
  230. package/lib/session/auth/domainRouting.d.ts +25 -0
  231. package/lib/session/auth/domainRouting.d.ts.map +1 -1
  232. package/lib/session/auth/domainRouting.js +36 -0
  233. package/lib/session/auth/domainRouting.js.map +1 -1
  234. package/lib/shell/login/SignInRestrictedEnvStep.d.ts +1 -1
  235. package/lib/shell/login/SignInRestrictedEnvStep.js +1 -1
  236. package/lib/shell/login/SigninScreen.js +9 -1
  237. package/lib/shell/login/SigninScreen.js.map +1 -1
  238. package/lib/shell/login/productionUrl.d.ts +0 -14
  239. package/lib/shell/login/productionUrl.d.ts.map +1 -1
  240. package/lib/shell/login/productionUrl.js +14 -5
  241. package/lib/shell/login/productionUrl.js.map +1 -1
  242. package/lib/vertesia-ui-core.js +4 -4
  243. package/lib/vertesia-ui-core.js.map +1 -1
  244. package/lib/vertesia-ui-env.js +1 -1
  245. package/lib/vertesia-ui-env.js.map +1 -1
  246. package/lib/vertesia-ui-features.js +35 -28
  247. package/lib/vertesia-ui-features.js.map +1 -1
  248. package/lib/vertesia-ui-i18n.js +15 -15
  249. package/lib/vertesia-ui-i18n.js.map +1 -1
  250. package/lib/vertesia-ui-router.js +1 -1
  251. package/lib/vertesia-ui-router.js.map +1 -1
  252. package/lib/vertesia-ui-session.js +1 -1
  253. package/lib/vertesia-ui-session.js.map +1 -1
  254. package/lib/vertesia-ui-shell.js +1 -1
  255. package/lib/vertesia-ui-shell.js.map +1 -1
  256. package/lib/vertesia-ui-widgets.js +7 -7
  257. package/lib/vertesia-ui-widgets.js.map +1 -1
  258. package/lib/widgets/form/Form.js +1 -1
  259. package/lib/widgets/form/Form.js.map +1 -1
  260. package/lib/widgets/json-view/JSONSwitcher.js +1 -1
  261. package/lib/widgets/json-view/JSONSwitcher.js.map +1 -1
  262. package/lib/widgets/json-view/JSONView.js +6 -6
  263. package/lib/widgets/json-view/JSONView.js.map +1 -1
  264. package/lib/widgets/monacoEditor/MonacoEditor.d.ts.map +1 -1
  265. package/lib/widgets/monacoEditor/MonacoEditor.js +29 -0
  266. package/lib/widgets/monacoEditor/MonacoEditor.js.map +1 -1
  267. package/lib/widgets/schema-editor/ManagedSchema.d.ts +8 -0
  268. package/lib/widgets/schema-editor/ManagedSchema.d.ts.map +1 -1
  269. package/lib/widgets/schema-editor/ManagedSchema.js +16 -0
  270. package/lib/widgets/schema-editor/ManagedSchema.js.map +1 -1
  271. package/lib/widgets/schema-editor/editor/EditableSchemaProperty.d.ts +2 -0
  272. package/lib/widgets/schema-editor/editor/EditableSchemaProperty.d.ts.map +1 -1
  273. package/lib/widgets/schema-editor/editor/EditableSchemaProperty.js +1 -0
  274. package/lib/widgets/schema-editor/editor/EditableSchemaProperty.js.map +1 -1
  275. package/lib/widgets/schema-editor/editor/PropertyViewer.d.ts.map +1 -1
  276. package/lib/widgets/schema-editor/editor/PropertyViewer.js +4 -1
  277. package/lib/widgets/schema-editor/editor/PropertyViewer.js.map +1 -1
  278. package/lib/widgets/schema-editor/editor/SchemaEditor.d.ts.map +1 -1
  279. package/lib/widgets/schema-editor/editor/SchemaEditor.js +22 -11
  280. package/lib/widgets/schema-editor/editor/SchemaEditor.js.map +1 -1
  281. package/llms.txt +70 -70
  282. package/package.json +33 -32
  283. package/src/__tests__/a11y.test.tsx +73 -0
  284. package/src/core/components/SidePanel.tsx +1 -1
  285. package/src/core/components/shadcn/button.tsx +67 -12
  286. package/src/core/components/shadcn/modal/dialog.tsx +1 -1
  287. package/src/core/components/shadcn/theme/ThemeSwitcher.tsx +1 -1
  288. package/src/env/index.ts +24 -0
  289. package/src/features/agent/chat/AgentChatPlaybackControls.tsx +0 -5
  290. package/src/features/agent/chat/AgentRequestInputOverlay.test.tsx +31 -0
  291. package/src/features/agent/chat/AgentRequestInputOverlay.tsx +6 -2
  292. package/src/features/agent/chat/ArtifactsTab.tsx +165 -21
  293. package/src/features/agent/chat/ImageLightbox.tsx +0 -1
  294. package/src/features/agent/chat/ModernAgentConversation.test.tsx +48 -0
  295. package/src/features/agent/chat/ModernAgentConversation.tsx +53 -51
  296. package/src/features/agent/chat/ModernAgentOutput/AllMessagesMixed.test.tsx +6 -1
  297. package/src/features/agent/chat/ModernAgentOutput/AllMessagesMixed.tsx +21 -15
  298. package/src/features/agent/chat/ModernAgentOutput/Header.tsx +3 -3
  299. package/src/features/agent/chat/ModernAgentOutput/MessageInput.tsx +0 -2
  300. package/src/features/agent/chat/ModernAgentOutput/MessageItem.tsx +4 -1
  301. package/src/features/agent/chat/ModernAgentOutput/requestInputMessages.test.ts +80 -0
  302. package/src/features/agent/chat/ModernAgentOutput/requestInputMessages.ts +21 -1
  303. package/src/features/agent/chat/hooks/useArtifacts.ts +44 -11
  304. package/src/features/document-viewer/UniversalDocumentViewer.test.tsx +123 -0
  305. package/src/features/document-viewer/UniversalDocumentViewer.tsx +746 -0
  306. package/src/features/document-viewer/index.ts +1 -0
  307. package/src/features/environment/SelectEnvironment.tsx +186 -0
  308. package/src/features/environment/index.ts +1 -0
  309. package/src/features/index.ts +3 -0
  310. package/src/features/magic-pdf/AnnotatedImageSlider.tsx +62 -66
  311. package/src/features/magic-pdf/DownloadPopover.tsx +5 -48
  312. package/src/features/magic-pdf/ExtractedContentView.tsx +2 -14
  313. package/src/features/magic-pdf/GroundedExtractionAssistantPanel.tsx +86 -0
  314. package/src/features/magic-pdf/GroundedExtractionView.test.tsx +65 -0
  315. package/src/features/magic-pdf/GroundedExtractionView.tsx +1055 -0
  316. package/src/features/magic-pdf/MagicPdfProvider.tsx +17 -47
  317. package/src/features/magic-pdf/MagicPdfView.tsx +3 -51
  318. package/src/features/magic-pdf/index.ts +1 -0
  319. package/src/features/magic-pdf/types.ts +1 -1
  320. package/src/features/oauth/McpConnectionsButton.tsx +0 -2
  321. package/src/features/oauth/McpConnectionsDialog.tsx +0 -1
  322. package/src/features/oauth/RemoteMcpConnectionButton.tsx +0 -1
  323. package/src/features/pdf-viewer/PdfPageSlider.tsx +5 -5
  324. package/src/features/pdf-viewer/SimplePdfViewer.tsx +11 -12
  325. package/src/features/permissions/UserPermissionsProvider.tsx +36 -39
  326. package/src/features/store/objects/DocumentQuickFilter.tsx +13 -15
  327. package/src/features/store/objects/DocumentSearchResults.tsx +3 -6
  328. package/src/features/store/objects/components/ContentDispositionButton.tsx +5 -1
  329. package/src/features/store/objects/components/ContentOverview.tsx +240 -67
  330. package/src/features/store/objects/components/DocumentIcon.tsx +1 -1
  331. package/src/features/store/objects/components/VectorSearchWidget.tsx +2 -2
  332. package/src/features/store/objects/components/useContentPanelHooks.ts +3 -15
  333. package/src/features/store/objects/layout/renderers.tsx +1 -2
  334. package/src/features/store/objects/selection/SelectionActions.tsx +1 -1
  335. package/src/features/store/types/ContentObjectTypesTable.tsx +12 -14
  336. package/src/features/store/types/IntakePolicyEditor.tsx +679 -0
  337. package/src/features/store/types/IntakePolicyForm.tsx +838 -0
  338. package/src/features/store/types/SelectContentTypeModal.tsx +2 -2
  339. package/src/features/store/types/index.ts +2 -0
  340. package/src/features/store/types/intake-policy-editor.logic.test.ts +109 -0
  341. package/src/features/store/types/intake-policy-editor.logic.ts +87 -0
  342. package/src/features/store/types/typeCatalogCache.ts +45 -0
  343. package/src/features/user/UserInfo.tsx +7 -7
  344. package/src/features/views/ViewExperience.test.tsx +273 -0
  345. package/src/features/views/ViewExperience.tsx +408 -0
  346. package/src/features/views/ViewNavigation.test.tsx +86 -0
  347. package/src/features/views/ViewNavigation.tsx +187 -0
  348. package/src/features/views/ViewResults.test.ts +82 -0
  349. package/src/features/views/ViewResults.tsx +609 -0
  350. package/src/features/views/ViewSearch.test.tsx +147 -0
  351. package/src/features/views/ViewSearch.tsx +205 -0
  352. package/src/features/views/index.ts +6 -0
  353. package/src/features/views/types.ts +57 -0
  354. package/src/features/views/viewState.test.ts +111 -0
  355. package/src/features/views/viewState.ts +132 -0
  356. package/src/i18n/locales/ar.json +18 -0
  357. package/src/i18n/locales/de.json +14 -0
  358. package/src/i18n/locales/en.json +965 -751
  359. package/src/i18n/locales/es.json +15 -0
  360. package/src/i18n/locales/fr.json +15 -0
  361. package/src/i18n/locales/it.json +15 -0
  362. package/src/i18n/locales/ja.json +13 -0
  363. package/src/i18n/locales/ko.json +13 -0
  364. package/src/i18n/locales/pt.json +15 -0
  365. package/src/i18n/locales/ru.json +16 -0
  366. package/src/i18n/locales/tr.json +14 -0
  367. package/src/i18n/locales/zh-TW.json +13 -0
  368. package/src/i18n/locales/zh.json +13 -0
  369. package/src/router/HistoryNavigator.test.ts +48 -0
  370. package/src/router/HistoryNavigator.ts +28 -14
  371. package/src/router/Nav.tsx +24 -8
  372. package/src/router/Router.tsx +18 -4
  373. package/src/router/path.test.ts +87 -0
  374. package/src/router/path.ts +38 -0
  375. package/src/session/UserSession.test.ts +39 -0
  376. package/src/session/UserSession.ts +37 -12
  377. package/src/session/UserSessionProvider.tsx +138 -62
  378. package/src/session/auth/composable.test.ts +111 -0
  379. package/src/session/auth/composable.ts +58 -3
  380. package/src/session/auth/domainRouting.test.ts +28 -1
  381. package/src/session/auth/domainRouting.ts +38 -0
  382. package/src/shell/login/SignInRestrictedEnvStep.tsx +1 -1
  383. package/src/shell/login/SigninScreen.tsx +9 -1
  384. package/src/shell/login/productionUrl.test.ts +8 -5
  385. package/src/shell/login/productionUrl.ts +15 -5
  386. package/src/widgets/form/Form.tsx +1 -1
  387. package/src/widgets/json-view/JSONSwitcher.tsx +2 -2
  388. package/src/widgets/json-view/JSONView.tsx +7 -7
  389. package/src/widgets/monacoEditor/MonacoEditor.tsx +29 -0
  390. package/src/widgets/schema-editor/ManagedSchema.ts +22 -0
  391. package/src/widgets/schema-editor/editor/EditableSchemaProperty.tsx +3 -0
  392. package/src/widgets/schema-editor/editor/PropertyViewer.tsx +14 -3
  393. package/src/widgets/schema-editor/editor/SchemaEditor.tsx +80 -29
@@ -17,7 +17,7 @@ export function ModeOption({ option, current, setTheme, icon, alt }: ModeOptionP
17
17
  variant={current === option ? 'secondary' : 'outline'}
18
18
  size="sm"
19
19
  onClick={() => setTheme(option)}
20
- alt={alt}
20
+ title={alt}
21
21
  >
22
22
  {icon}
23
23
  </Button>
package/src/env/index.ts CHANGED
@@ -15,6 +15,7 @@ export interface EnvProps {
15
15
  zeno: string;
16
16
  studio: string;
17
17
  sts: string; // Security Token Service endpoint
18
+ git?: string; // Smart HTTP app source git endpoint
18
19
  mcp?: string;
19
20
  };
20
21
  firebase?: {
@@ -27,6 +28,21 @@ export interface EnvProps {
27
28
  region?: string;
28
29
  datadogRum?: boolean;
29
30
  datadogLogs?: boolean;
31
+ /**
32
+ * Development-only Vertesia auth token.
33
+ *
34
+ * This is intended for sandbox/dev previews where the host process already
35
+ * has a short-lived Vertesia token. Production apps must not set this.
36
+ */
37
+ devAuthToken?: string;
38
+ /**
39
+ * Optional host-provided Vertesia auth token bootstrap.
40
+ *
41
+ * Published generated apps use this to ask their same-origin app gateway for
42
+ * the token backing the gateway session cookie, allowing UserSession to
43
+ * initialize without redirecting through Central Auth.
44
+ */
45
+ authTokenProvider?: () => Promise<string | undefined>;
30
46
  logger?: {
31
47
  info: (msg: string, ...args: unknown[]) => void;
32
48
  warn: (msg: string, ...args: unknown[]) => void;
@@ -116,6 +132,14 @@ export class VertesiaEnvironment implements Readonly<EnvProps> {
116
132
  return this._props?.datadogLogs ?? false;
117
133
  }
118
134
 
135
+ get devAuthToken() {
136
+ return this._props?.devAuthToken;
137
+ }
138
+
139
+ get authTokenProvider() {
140
+ return this._props?.authTokenProvider;
141
+ }
142
+
119
143
  get logger() {
120
144
  return this._props?.logger ?? console;
121
145
  }
@@ -108,7 +108,6 @@ export function AgentChatPlaybackControls({
108
108
  type="button"
109
109
  variant="ghost"
110
110
  size="icon"
111
- aria-label={t('agent.rewind.jumpToStart')}
112
111
  title={t('agent.rewind.jumpToStart')}
113
112
  disabled={!canJumpToStart}
114
113
  onClick={jumpToStart}
@@ -120,7 +119,6 @@ export function AgentChatPlaybackControls({
120
119
  type="button"
121
120
  variant="ghost"
122
121
  size="icon"
123
- aria-label={t('agent.rewind.previousMessage')}
124
122
  title={t('agent.rewind.previousMessage')}
125
123
  disabled={!canStepPrevious}
126
124
  onClick={setPreviousMessage}
@@ -165,7 +163,6 @@ export function AgentChatPlaybackControls({
165
163
  type="button"
166
164
  variant="ghost"
167
165
  size="icon"
168
- aria-label={t('agent.rewind.nextMessage')}
169
166
  title={t('agent.rewind.nextMessage')}
170
167
  disabled={!canStepNext}
171
168
  onClick={setNextMessage}
@@ -177,7 +174,6 @@ export function AgentChatPlaybackControls({
177
174
  type="button"
178
175
  variant="ghost"
179
176
  size="icon"
180
- aria-label={t('agent.rewind.jumpToLatest')}
181
177
  title={t('agent.rewind.jumpToLatest')}
182
178
  disabled={!canJumpToLatest}
183
179
  onClick={jumpToLatest}
@@ -189,7 +185,6 @@ export function AgentChatPlaybackControls({
189
185
  type="button"
190
186
  variant={isLive ? 'secondary' : 'ghost'}
191
187
  size="icon"
192
- aria-label={t('agent.rewind.jumpToLive')}
193
188
  title={t('agent.rewind.jumpToLive')}
194
189
  disabled={isLive}
195
190
  onClick={() => onChangeCursor('live')}
@@ -110,6 +110,37 @@ describe('AgentRequestInputOverlay', () => {
110
110
  });
111
111
  });
112
112
 
113
+ it('sends a tool approval option with structured metadata', () => {
114
+ const onSendMessage = vi.fn();
115
+
116
+ renderWithProviders(
117
+ <AgentRequestInputOverlay message={createToolApprovalRequestMessage()} onSendMessage={onSendMessage} />,
118
+ );
119
+
120
+ fireEvent.click(screen.getByRole('button', { name: 'Allow this action for this run' }));
121
+
122
+ expect(onSendMessage).toHaveBeenCalledTimes(1);
123
+ expect(onSendMessage).toHaveBeenCalledWith('allow_for_run', {
124
+ tool_approval_response: {
125
+ decision: 'allow_for_run',
126
+ approval_key: 'write_artifact:name:quotes.md',
127
+ },
128
+ });
129
+ });
130
+
131
+ it('sends a bare option id for prompts that are not tool approvals', () => {
132
+ const onSendMessage = vi.fn();
133
+ const message = createToolApprovalRequestMessage();
134
+ delete (message.details as Record<string, unknown>).tool_approval;
135
+
136
+ renderWithProviders(<AgentRequestInputOverlay message={message} onSendMessage={onSendMessage} />);
137
+
138
+ fireEvent.click(screen.getByRole('button', { name: 'Allow once' }));
139
+
140
+ expect(onSendMessage).toHaveBeenCalledTimes(1);
141
+ expect(onSendMessage).toHaveBeenCalledWith('allow_once');
142
+ });
143
+
113
144
  it('renders legacy field-prefixed tool approval prompts with a friendly target', () => {
114
145
  const message = createToolApprovalRequestMessage();
115
146
  message.message = 'Approve Write Artifact: name quotes.md?';
@@ -5,7 +5,11 @@ import { useUserSession } from '@vertesia/ui/session';
5
5
  import { XIcon } from 'lucide-react';
6
6
  import { RemoteMcpConnectionButton } from '../../oauth/RemoteMcpConnectionButton.js';
7
7
  import { AskUserWidget } from './AskUserWidget';
8
- import { getRequestInputDisplayText, type RequestInputMessageWithUx } from './ModernAgentOutput/requestInputMessages';
8
+ import {
9
+ getRequestInputDisplayText,
10
+ getToolApprovalResponseMetadata,
11
+ type RequestInputMessageWithUx,
12
+ } from './ModernAgentOutput/requestInputMessages';
9
13
 
10
14
  export interface AgentRequestInputOverlayProps {
11
15
  message?: RequestInputMessageWithUx;
@@ -118,7 +122,7 @@ export function AgentRequestInputOverlay({
118
122
  allowFreeResponse={options.length === 0 || !!freeResponse}
119
123
  placeholder={freeResponse?.placeholder}
120
124
  submitLabel={freeResponse?.submit_label}
121
- onSelect={send}
125
+ onSelect={(optionId) => send(optionId, getToolApprovalResponseMetadata(message, optionId))}
122
126
  onMultiSelect={(optionIds) => send(optionIds.join(', '))}
123
127
  onSubmit={(value) => send(value, freeResponse?.metadata)}
124
128
  hideBorder
@@ -1,9 +1,11 @@
1
- import { Button, Center, ErrorBox, Input } from '@vertesia/ui/core';
1
+ import { Button, Center, ErrorBox, Input, Modal, ModalBody, ModalTitle, Switch } from '@vertesia/ui/core';
2
2
  import { useUITranslation } from '@vertesia/ui/i18n';
3
3
  import { useUserSession } from '@vertesia/ui/session';
4
4
  import {
5
5
  ChevronDownIcon,
6
6
  ChevronRightIcon,
7
+ DownloadIcon,
8
+ EyeIcon,
7
9
  FileIcon,
8
10
  FolderIcon,
9
11
  FolderOpenIcon,
@@ -12,8 +14,14 @@ import {
12
14
  RefreshCwIcon,
13
15
  } from 'lucide-react';
14
16
  import React, { useCallback, useId, useMemo, useState } from 'react';
17
+ import type { UniversalDocumentSource } from '../../document-viewer/UniversalDocumentViewer.js';
15
18
  import { type ArtifactTreeNode, useArtifacts } from './hooks/useArtifacts.js';
16
19
 
20
+ const UniversalDocumentViewer = React.lazy(async () => {
21
+ const module = await import('../../document-viewer/UniversalDocumentViewer.js');
22
+ return { default: module.UniversalDocumentViewer };
23
+ });
24
+
17
25
  // ---------------------------------------------------------------------------
18
26
  // Tree node component
19
27
  // ---------------------------------------------------------------------------
@@ -22,16 +30,26 @@ interface TreeNodeProps {
22
30
  node: ArtifactTreeNode;
23
31
  depth: number;
24
32
  runId: string;
33
+ onPreview: (relativePath: string) => void;
25
34
  onDownload: (relativePath: string) => void;
26
35
  downloadingPath: string | null;
27
36
  forceExpanded?: boolean;
28
37
  }
38
+
29
39
  //** Convert a raw directory segment (e.g. "out_files") into a readable label ("Out Files"). */
30
40
  function formatDirectoryLabel(name: string): string {
31
41
  return name.replace(/[_-]/g, ' ').replace(/\b\w/g, (c) => c.toUpperCase());
32
42
  }
33
43
 
34
- function TreeNode({ node, depth, runId, onDownload, downloadingPath, forceExpanded = false }: TreeNodeProps) {
44
+ function TreeNode({
45
+ node,
46
+ depth,
47
+ runId,
48
+ onPreview,
49
+ onDownload,
50
+ downloadingPath,
51
+ forceExpanded = false,
52
+ }: TreeNodeProps) {
35
53
  const [expanded, setExpanded] = useState(false);
36
54
  const isExpanded = forceExpanded || expanded;
37
55
 
@@ -66,6 +84,7 @@ function TreeNode({ node, depth, runId, onDownload, downloadingPath, forceExpand
66
84
  node={child}
67
85
  depth={depth + 1}
68
86
  runId={runId}
87
+ onPreview={onPreview}
69
88
  onDownload={onDownload}
70
89
  downloadingPath={downloadingPath}
71
90
  forceExpanded={forceExpanded}
@@ -78,23 +97,45 @@ function TreeNode({ node, depth, runId, onDownload, downloadingPath, forceExpand
78
97
  const isDownloading = downloadingPath === node.path;
79
98
 
80
99
  return (
81
- <div className="min-w-0">
100
+ <div
101
+ className="group flex min-w-0 items-center gap-1.5 rounded text-sm hover:bg-muted/30"
102
+ style={{ paddingInlineStart: `${depth * 14 + 4}px` }}
103
+ >
82
104
  <Button
83
105
  variant="unstyled"
84
- className="flex w-full max-w-full items-center justify-start gap-1.5 rounded px-1 py-1 text-start text-sm hover:bg-muted/30"
85
- style={{ paddingInlineStart: `${depth * 14 + 4}px` }}
86
- onClick={() => onDownload(node.path)}
87
- disabled={isDownloading}
106
+ className="flex min-w-0 flex-1 items-center justify-start gap-1.5 px-1 py-1 text-start"
107
+ onClick={() => onPreview(node.path)}
88
108
  title={node.path}
89
109
  >
90
- {isDownloading ? (
91
- <Loader2Icon className="size-3.5 shrink-0 animate-spin text-info" />
92
- ) : (
93
- <span className="size-3.5 shrink-0" />
94
- )}
110
+ <span className="size-3.5 shrink-0" />
95
111
  <FileIcon className="size-4 shrink-0 text-muted" />
96
112
  <span className="min-w-0 truncate">{node.name}</span>
97
113
  </Button>
114
+ <div className="flex shrink-0 items-center pe-1 opacity-0 transition-opacity group-hover:opacity-100 focus-within:opacity-100">
115
+ <Button
116
+ variant="ghost"
117
+ size="xs"
118
+ className="h-6 w-6 p-0"
119
+ onClick={() => onPreview(node.path)}
120
+ aria-label="Preview artifact"
121
+ >
122
+ <EyeIcon className="size-3.5" />
123
+ </Button>
124
+ <Button
125
+ variant="ghost"
126
+ size="xs"
127
+ className="h-6 w-6 p-0"
128
+ onClick={() => onDownload(node.path)}
129
+ disabled={isDownloading}
130
+ aria-label="Download artifact"
131
+ >
132
+ {isDownloading ? (
133
+ <Loader2Icon className="size-3.5 animate-spin text-info" />
134
+ ) : (
135
+ <DownloadIcon className="size-3.5" />
136
+ )}
137
+ </Button>
138
+ </div>
98
139
  </div>
99
140
  );
100
141
  }
@@ -142,6 +183,42 @@ function downloadUrl(url: string, filename: string) {
142
183
  anchor.remove();
143
184
  }
144
185
 
186
+ function getArtifactContentType(path: string): string | undefined {
187
+ const ext = path.split('.').pop()?.toLowerCase();
188
+ switch (ext) {
189
+ case 'css':
190
+ return 'text/css';
191
+ case 'gif':
192
+ return 'image/gif';
193
+ case 'htm':
194
+ case 'html':
195
+ return 'text/html';
196
+ case 'jpeg':
197
+ case 'jpg':
198
+ return 'image/jpeg';
199
+ case 'json':
200
+ return 'application/json';
201
+ case 'md':
202
+ case 'markdown':
203
+ return 'text/markdown';
204
+ case 'pdf':
205
+ return 'application/pdf';
206
+ case 'png':
207
+ return 'image/png';
208
+ case 'svg':
209
+ return 'image/svg+xml';
210
+ case 'ts':
211
+ case 'tsx':
212
+ return 'text/typescript';
213
+ case 'txt':
214
+ return 'text/plain';
215
+ case 'webp':
216
+ return 'image/webp';
217
+ default:
218
+ return undefined;
219
+ }
220
+ }
221
+
145
222
  // ---------------------------------------------------------------------------
146
223
  // Main tab component
147
224
  // ---------------------------------------------------------------------------
@@ -172,8 +249,15 @@ function ArtifactEmptyState({
172
249
  function ArtifactsTabComponent({ runId, refreshKey = 0 }: ArtifactsTabProps) {
173
250
  const { t } = useUITranslation();
174
251
  const { client } = useUserSession();
175
- const { tree, flatFiles, isLoading, error, refresh } = useArtifacts(client, runId, refreshKey);
252
+ const [showSystem, setShowSystem] = useState(false);
253
+ const { tree, flatFiles, totalCount, systemHiddenCount, isLoading, error, refresh } = useArtifacts(
254
+ client,
255
+ runId,
256
+ refreshKey,
257
+ showSystem,
258
+ );
176
259
  const [downloadingPath, setDownloadingPath] = useState<string | null>(null);
260
+ const [previewPath, setPreviewPath] = useState<string | null>(null);
177
261
  const [filterValue, setFilterValue] = useState('');
178
262
  const normalizedFilterValue = filterValue.trim();
179
263
  const filteredTree = useMemo(() => filterArtifactTree(tree, normalizedFilterValue), [tree, normalizedFilterValue]);
@@ -196,11 +280,28 @@ function ArtifactsTabComponent({ runId, refreshKey = 0 }: ArtifactsTabProps) {
196
280
  [client, runId],
197
281
  );
198
282
 
283
+ const handlePreview = useCallback((relativePath: string) => {
284
+ setPreviewPath(relativePath);
285
+ }, []);
286
+
287
+ const previewSource: UniversalDocumentSource | null =
288
+ runId && previewPath
289
+ ? {
290
+ title: previewPath.split('/').pop() || previewPath,
291
+ fileName: previewPath.split('/').pop() || previewPath,
292
+ contentType: getArtifactContentType(previewPath),
293
+ artifact: {
294
+ runId,
295
+ path: previewPath,
296
+ },
297
+ }
298
+ : null;
299
+
199
300
  if (!runId) {
200
301
  return <ArtifactEmptyState icon={<PackageIcon className="mb-2 size-8" />}>No run selected</ArtifactEmptyState>;
201
302
  }
202
303
 
203
- if (isLoading && flatFiles.length === 0) {
304
+ if (isLoading && totalCount === 0) {
204
305
  return (
205
306
  <ArtifactEmptyState icon={<Loader2Icon className="mb-2 size-6 animate-spin" />}>
206
307
  {t('agent.loadingArtifacts')}
@@ -228,7 +329,7 @@ function ArtifactsTabComponent({ runId, refreshKey = 0 }: ArtifactsTabProps) {
228
329
  );
229
330
  }
230
331
 
231
- if (flatFiles.length === 0) {
332
+ if (totalCount === 0) {
232
333
  return (
233
334
  <ArtifactEmptyState
234
335
  icon={<PackageIcon className="mb-2 size-8" />}
@@ -247,16 +348,28 @@ function ArtifactsTabComponent({ runId, refreshKey = 0 }: ArtifactsTabProps) {
247
348
  return (
248
349
  <div className="flex flex-col h-full">
249
350
  {/* Top bar */}
250
- <div className="flex shrink-0 flex-col gap-2 px-3 py-2">
351
+ <div className="flex shrink-0 flex-col gap-2 border-b px-3 py-2">
251
352
  <div className="flex items-center justify-between gap-2 text-xs text-muted">
252
353
  <span>
253
354
  {normalizedFilterValue
254
355
  ? `${visibleFileCount} of ${flatFiles.length} file${flatFiles.length !== 1 ? 's' : ''}`
255
356
  : `${flatFiles.length} file${flatFiles.length !== 1 ? 's' : ''}`}
357
+ {!showSystem && systemHiddenCount > 0 ? ` · ${systemHiddenCount} hidden` : ''}
256
358
  </span>
257
- <Button variant="ghost" size="sm" onClick={refresh} disabled={isLoading} className="h-6 w-6 p-0">
258
- <RefreshCwIcon className={`size-3.5 ${isLoading ? 'animate-spin' : ''}`} />
259
- </Button>
359
+ <div className="flex items-center gap-1">
360
+ <Switch size="sm" value={showSystem} onChange={setShowSystem}>
361
+ <span className="text-xs text-muted">{t('agent.showSystemArtifacts')}</span>
362
+ </Switch>
363
+ <Button
364
+ variant="ghost"
365
+ size="sm"
366
+ onClick={refresh}
367
+ disabled={isLoading}
368
+ className="h-6 w-6 p-0"
369
+ >
370
+ <RefreshCwIcon className={`size-3.5 ${isLoading ? 'animate-spin' : ''}`} />
371
+ </Button>
372
+ </div>
260
373
  </div>
261
374
  <label htmlFor={filterInputId} className="sr-only">
262
375
  {t('form.filter')}
@@ -274,7 +387,7 @@ function ArtifactsTabComponent({ runId, refreshKey = 0 }: ArtifactsTabProps) {
274
387
  </div>
275
388
 
276
389
  {/* Tree */}
277
- <div className="flex-1 overflow-y-auto px-3 pb-2">
390
+ <div className="flex-1 overflow-y-auto px-3 py-2">
278
391
  {filteredTree.length > 0 ? (
279
392
  <div className="min-w-0">
280
393
  {filteredTree.map((node) => (
@@ -283,6 +396,7 @@ function ArtifactsTabComponent({ runId, refreshKey = 0 }: ArtifactsTabProps) {
283
396
  node={node}
284
397
  depth={0}
285
398
  runId={runId}
399
+ onPreview={handlePreview}
286
400
  onDownload={handleDownload}
287
401
  downloadingPath={downloadingPath}
288
402
  forceExpanded={!!normalizedFilterValue}
@@ -290,9 +404,39 @@ function ArtifactsTabComponent({ runId, refreshKey = 0 }: ArtifactsTabProps) {
290
404
  ))}
291
405
  </div>
292
406
  ) : (
293
- <div className="px-1 py-6 text-sm text-muted">{t('agent.noContentAvailable')}</div>
407
+ <div className="px-1 py-6 text-sm text-muted">
408
+ {!showSystem && systemHiddenCount > 0
409
+ ? t('agent.onlySystemArtifacts')
410
+ : t('agent.noContentAvailable')}
411
+ </div>
294
412
  )}
295
413
  </div>
414
+ {previewSource && (
415
+ <Modal
416
+ isOpen={!!previewPath}
417
+ onClose={() => setPreviewPath(null)}
418
+ size="xl"
419
+ className="h-[90vh] p-0"
420
+ description="Artifact preview"
421
+ >
422
+ <ModalTitle show={false}>{previewSource.fileName}</ModalTitle>
423
+ <ModalBody className="h-full max-h-none p-0">
424
+ <React.Suspense
425
+ fallback={
426
+ <Center className="h-full">
427
+ <Loader2Icon className="size-6 animate-spin text-muted" />
428
+ </Center>
429
+ }
430
+ >
431
+ <UniversalDocumentViewer
432
+ source={previewSource}
433
+ className="h-full"
434
+ onDownload={() => previewPath && void handleDownload(previewPath)}
435
+ />
436
+ </React.Suspense>
437
+ </ModalBody>
438
+ </Modal>
439
+ )}
296
440
  </div>
297
441
  );
298
442
  }
@@ -64,7 +64,6 @@ export function ImageLightboxProvider({ children }: ImageLightboxProviderProps)
64
64
  className="absolute top-2 end-2 text-white bg-black/50 rounded-full p-2 hover:bg-black/70 transition-colors"
65
65
  onClick={closeImage}
66
66
  title={t('agent.close')}
67
- aria-label={t('agent.close')}
68
67
  >
69
68
  <X className="size-6" />
70
69
  </Button>
@@ -1400,6 +1400,54 @@ describe('ModernAgentConversation send handling', () => {
1400
1400
  );
1401
1401
  });
1402
1402
 
1403
+ it('passes approval option metadata through the request overlay signal', async () => {
1404
+ mockStreamState({
1405
+ messages: [
1406
+ {
1407
+ ...createMessage(AgentMessageType.REQUEST_INPUT, 'Approve Write Artifact: quotes.md?'),
1408
+ details: {
1409
+ tool_approval: {
1410
+ tool_name: 'write_artifact',
1411
+ approval_key: 'write_artifact:name:quotes.md',
1412
+ },
1413
+ ux: {
1414
+ options: [
1415
+ { id: 'allow_once', label: 'Allow once' },
1416
+ { id: 'allow_for_run', label: 'Allow this action for this run' },
1417
+ { id: 'deny', label: 'Deny' },
1418
+ ],
1419
+ },
1420
+ },
1421
+ },
1422
+ ],
1423
+ isCompleted: false,
1424
+ agentRunStatus: 'RUNNING',
1425
+ });
1426
+
1427
+ renderConversation();
1428
+
1429
+ fireEvent.click(screen.getByRole('button', { name: 'Allow this action for this run' }));
1430
+
1431
+ await waitFor(() => {
1432
+ expect(mocks.sendSignal).toHaveBeenCalledTimes(1);
1433
+ });
1434
+ expect(mocks.sendSignal).toHaveBeenCalledWith(
1435
+ 'agent-run-1',
1436
+ 'UserInput',
1437
+ expect.objectContaining({
1438
+ message: 'allow_for_run',
1439
+ metadata: expect.objectContaining({
1440
+ tool_approval_response: {
1441
+ decision: 'allow_for_run',
1442
+ approval_key: 'write_artifact:name:quotes.md',
1443
+ },
1444
+ id: expect.any(String),
1445
+ _messageId: expect.any(String),
1446
+ }),
1447
+ }),
1448
+ );
1449
+ });
1450
+
1403
1451
  it('sends directly without restart while the run is active', async () => {
1404
1452
  mockStreamState({
1405
1453
  messages: [createMessage(AgentMessageType.ANSWER, 'still running')],
@@ -925,64 +925,68 @@ function StartWorkflowView({
925
925
  ].join('\n');
926
926
  }
927
927
 
928
+ const newRun = await startWorkflow(messageContent, { tool_approval_mode: toolApprovalMode });
929
+ if (!newRun) {
930
+ setPendingStartMessage(null);
931
+ setPendingStartTimestamp(null);
932
+ return;
933
+ }
934
+
928
935
  setPendingStartMessage(messageContent);
929
936
  setPendingStartTimestamp(Date.now());
930
937
 
931
- const newRun = await startWorkflow(messageContent, { tool_approval_mode: toolApprovalMode });
932
- if (newRun) {
933
- const agentId = newRun.agent_run_id;
934
-
935
- // Upload staged files to the new run's artifact space and signal agent
936
- const uploadedFiles: string[] = [];
937
- if (canStageFiles && stagedFiles.length > 0) {
938
- for (const file of stagedFiles) {
939
- try {
940
- const artifactPath = `files/${file.name}`;
941
- await client.agents.uploadArtifact(agentId, artifactPath, file);
942
-
943
- // Signal agent that file was uploaded
944
- await client.agents.sendSignal(agentId, 'FileUploaded', {
945
- id: `file-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
946
- name: file.name,
947
- content_type: file.type || 'application/octet-stream',
948
- reference: `artifact:${artifactPath}`,
949
- artifact_path: artifactPath,
950
- } as ConversationFileRef);
951
- uploadedFiles.push(file.name);
952
- } catch (uploadErr) {
953
- console.error(`Failed to upload staged file ${file.name}:`, uploadErr);
954
- // Continue with other files
955
- }
956
- }
938
+ const agentId = newRun.agent_run_id;
957
939
 
958
- // Send a follow-up message to notify the agent that all files are ready
959
- if (uploadedFiles.length > 0) {
960
- try {
961
- await client.agents.sendSignal(agentId, 'UserInput', {
962
- message: `[Files Ready] All ${uploadedFiles.length} file(s) have been uploaded and are now available: ${uploadedFiles.join(', ')}. You can now process them.`,
963
- metadata: {
964
- type: 'files_ready',
965
- files: uploadedFiles,
966
- },
967
- } as UserInputSignal);
968
- } catch (signalErr) {
969
- console.error('Failed to send files ready signal:', signalErr);
970
- }
940
+ // Upload staged files to the new run's artifact space and signal agent
941
+ const uploadedFiles: string[] = [];
942
+ if (canStageFiles && stagedFiles.length > 0) {
943
+ for (const file of stagedFiles) {
944
+ try {
945
+ const artifactPath = `files/${file.name}`;
946
+ await client.agents.uploadArtifact(agentId, artifactPath, file);
947
+
948
+ // Signal agent that file was uploaded
949
+ await client.agents.sendSignal(agentId, 'FileUploaded', {
950
+ id: `file-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
951
+ name: file.name,
952
+ content_type: file.type || 'application/octet-stream',
953
+ reference: `artifact:${artifactPath}`,
954
+ artifact_path: artifactPath,
955
+ } as ConversationFileRef);
956
+ uploadedFiles.push(file.name);
957
+ } catch (uploadErr) {
958
+ console.error(`Failed to upload staged file ${file.name}:`, uploadErr);
959
+ // Continue with other files
971
960
  }
961
+ }
972
962
 
973
- setStagedFiles([]);
963
+ // Send a follow-up message to notify the agent that all files are ready
964
+ if (uploadedFiles.length > 0) {
965
+ try {
966
+ await client.agents.sendSignal(agentId, 'UserInput', {
967
+ message: `[Files Ready] All ${uploadedFiles.length} file(s) have been uploaded and are now available: ${uploadedFiles.join(', ')}. You can now process them.`,
968
+ metadata: {
969
+ type: 'files_ready',
970
+ files: uploadedFiles,
971
+ },
972
+ } as UserInputSignal);
973
+ } catch (signalErr) {
974
+ console.error('Failed to send files ready signal:', signalErr);
975
+ }
974
976
  }
975
977
 
976
- // Clear attachments after successful start
977
- onAttachmentsSent?.();
978
- setStartedAgentRunId(agentId);
979
- setInputValue('');
980
- toast({
981
- title: t('agent.agentStarted'),
982
- status: 'success',
983
- duration: 3000,
984
- });
978
+ setStagedFiles([]);
985
979
  }
980
+
981
+ // Clear attachments after successful start
982
+ onAttachmentsSent?.();
983
+ setStartedAgentRunId(agentId);
984
+ setInputValue('');
985
+ toast({
986
+ title: t('agent.agentStarted'),
987
+ status: 'success',
988
+ duration: 3000,
989
+ });
986
990
  } catch (err: unknown) {
987
991
  setPendingStartMessage(null);
988
992
  setPendingStartTimestamp(null);
@@ -1106,7 +1110,6 @@ function StartWorkflowView({
1106
1110
  size="xs"
1107
1111
  variant="ghost"
1108
1112
  onClick={onClose}
1109
- aria-label={t('agent.close')}
1110
1113
  title={t('agent.close')}
1111
1114
  className="text-muted hover:text-foreground"
1112
1115
  >
@@ -1212,7 +1215,6 @@ function StartWorkflowView({
1212
1215
  'disabled:bg-mixer-muted/25 disabled:text-muted disabled:opacity-100',
1213
1216
  )}
1214
1217
  title={resolvedStartButtonText}
1215
- aria-label={resolvedStartButtonText}
1216
1218
  >
1217
1219
  {isSending ? <Spinner size="sm" /> : <ArrowUpIcon className="size-4" />}
1218
1220
  </Button>