@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
@@ -0,0 +1,838 @@
1
+ import type {
2
+ ContentTypeIntakePolicy,
3
+ IntakePageRanges,
4
+ IntakeVisionDetail,
5
+ InteractionExecutionConfiguration,
6
+ } from '@vertesia/common';
7
+ import { Button, FormItem, Input, NumberInput, SelectBox, TagsInput, Textarea, VTooltip } from '@vertesia/ui/core';
8
+ import { useUITranslation } from '@vertesia/ui/i18n';
9
+ import { Plus, Trash2 } from 'lucide-react';
10
+ import type { ReactNode } from 'react';
11
+ import { SelectEnvironment, SelectModel } from '../../environment/SelectEnvironment.js';
12
+ import {
13
+ type IntakePolicyPath,
14
+ replaceIntakeRange,
15
+ updateExecutionEnvironment,
16
+ updateExecutionModel,
17
+ updateIntakePolicy,
18
+ } from './intake-policy-editor.logic.js';
19
+
20
+ export type IntakePolicyFormSection = 'overview' | 'conversion' | 'extraction' | 'grounding' | 'output';
21
+
22
+ interface IntakePolicyFormProps {
23
+ policy: ContentTypeIntakePolicy;
24
+ section: IntakePolicyFormSection;
25
+ onChange: (policy: ContentTypeIntakePolicy) => void;
26
+ readonly?: boolean;
27
+ }
28
+
29
+ interface SelectOption<T extends string | number> {
30
+ value: T;
31
+ label: string;
32
+ }
33
+
34
+ export function IntakePolicyForm({ policy, section, onChange, readonly = false }: IntakePolicyFormProps) {
35
+ const { t } = useUITranslation();
36
+ const setValue = (path: IntakePolicyPath, value: unknown) => onChange(updateIntakePolicy(policy, path, value));
37
+
38
+ if (section === 'overview') {
39
+ return (
40
+ <FormSurface>
41
+ <FormSection title={t('intakePolicy.section.classification')}>
42
+ <div className="grid gap-4 md:grid-cols-2">
43
+ <SelectField
44
+ label={t('intakePolicy.field.mode')}
45
+ description={t('intakePolicy.help.mode')}
46
+ value={policy.mode}
47
+ options={options(t, ['programmatic', 'agentic'])}
48
+ onChange={(value) => setValue(['mode'], value)}
49
+ readonly={readonly}
50
+ />
51
+ <SelectField
52
+ label={t('intakePolicy.field.defaultView')}
53
+ value={policy.default_view}
54
+ options={options(t, ['auto', 'text', 'pdf', 'image', 'properties'])}
55
+ onChange={(value) => setValue(['default_view'], value)}
56
+ readonly={readonly}
57
+ />
58
+ </div>
59
+ <TextAreaField
60
+ label={t('intakePolicy.field.identificationGuidance')}
61
+ description={t('intakePolicy.help.identificationGuidance')}
62
+ value={policy.identification?.guidance}
63
+ onChange={(value) => setValue(['identification', 'guidance'], value)}
64
+ readonly={readonly}
65
+ />
66
+ <TextAreaField
67
+ label={t('intakePolicy.field.distinguishFrom')}
68
+ value={policy.identification?.distinguish_from}
69
+ onChange={(value) => setValue(['identification', 'distinguish_from'], value)}
70
+ readonly={readonly}
71
+ />
72
+ <FormItem label={t('intakePolicy.field.examples')} description={t('intakePolicy.help.examples')}>
73
+ <TagsInput
74
+ options={policy.identification?.examples ?? []}
75
+ value={policy.identification?.examples ?? []}
76
+ onChange={(value) =>
77
+ setValue(['identification', 'examples'], value.length ? value : undefined)
78
+ }
79
+ onOptionsChange={(value) =>
80
+ setValue(['identification', 'examples'], value.length ? value : undefined)
81
+ }
82
+ creatable
83
+ disabled={readonly}
84
+ placeholder={t('intakePolicy.placeholder.objectId')}
85
+ />
86
+ </FormItem>
87
+ </FormSection>
88
+
89
+ <FormSection title={t('intakePolicy.section.locate')} last>
90
+ <TextAreaField
91
+ label={t('intakePolicy.field.locateInstructions')}
92
+ description={t('intakePolicy.help.locateInstructions')}
93
+ value={policy.locate?.instructions}
94
+ onChange={(value) =>
95
+ setValue(['locate'], value ? { ...policy.locate, instructions: value } : undefined)
96
+ }
97
+ readonly={readonly}
98
+ />
99
+ <div className="grid gap-4 md:grid-cols-2">
100
+ <SelectField
101
+ label={t('intakePolicy.field.contactSheetDetail')}
102
+ value={policy.locate?.detail}
103
+ options={[
104
+ { value: 8, label: t('intakePolicy.option.pagesPerSheet', { count: 8 }) },
105
+ { value: 16, label: t('intakePolicy.option.pagesPerSheet', { count: 16 }) },
106
+ ]}
107
+ onChange={(value) => setValue(['locate', 'detail'], value)}
108
+ readonly={readonly || !policy.locate}
109
+ />
110
+ <NumberField
111
+ label={t('intakePolicy.field.locateMinPages')}
112
+ value={policy.locate?.min_pages}
113
+ min={0}
114
+ onChange={(value) => setValue(['locate', 'min_pages'], value)}
115
+ readonly={readonly || !policy.locate}
116
+ />
117
+ </div>
118
+ </FormSection>
119
+ </FormSurface>
120
+ );
121
+ }
122
+
123
+ if (section === 'conversion') {
124
+ return (
125
+ <FormSurface>
126
+ <FormSection title={t('intakePolicy.section.conversion')}>
127
+ <div className="grid gap-4 md:grid-cols-2 xl:grid-cols-4">
128
+ <TriStateField
129
+ label={t('intakePolicy.field.enabled')}
130
+ value={policy.text_conversion?.enabled}
131
+ onChange={(value) => setValue(['text_conversion', 'enabled'], value)}
132
+ readonly={readonly}
133
+ />
134
+ <SelectField
135
+ label={t('intakePolicy.field.method')}
136
+ value={policy.text_conversion?.method}
137
+ options={options(t, ['auto', 'basic', 'llm', 'custom'])}
138
+ onChange={(value) => setValue(['text_conversion', 'method'], value)}
139
+ readonly={readonly}
140
+ />
141
+ <SelectField
142
+ label={t('intakePolicy.field.outputFormat')}
143
+ value={policy.text_conversion?.output_format}
144
+ options={options(t, ['markdown', 'text'])}
145
+ onChange={(value) => setValue(['text_conversion', 'output_format'], value)}
146
+ readonly={readonly}
147
+ />
148
+ <SelectField
149
+ label={t('intakePolicy.field.pageScope')}
150
+ value={policy.text_conversion?.scope}
151
+ options={options(t, ['all', 'located'])}
152
+ onChange={(value) => setValue(['text_conversion', 'scope'], value)}
153
+ readonly={readonly}
154
+ />
155
+ </div>
156
+ <TextAreaField
157
+ label={t('intakePolicy.field.instructions')}
158
+ value={policy.text_conversion?.instructions}
159
+ onChange={(value) => setValue(['text_conversion', 'instructions'], value)}
160
+ readonly={readonly}
161
+ />
162
+ </FormSection>
163
+
164
+ {policy.text_conversion?.method === 'custom' && (
165
+ <FormSection title={t('intakePolicy.section.customConversion')}>
166
+ <div className="grid gap-4 md:grid-cols-2">
167
+ <InputField
168
+ label={t('intakePolicy.field.interaction')}
169
+ value={policy.text_conversion.custom?.interaction}
170
+ onChange={(value) => setValue(['text_conversion', 'custom', 'interaction'], value)}
171
+ readonly={readonly}
172
+ />
173
+ <InputField
174
+ label={t('intakePolicy.field.agent')}
175
+ value={policy.text_conversion.custom?.agent}
176
+ onChange={(value) => setValue(['text_conversion', 'custom', 'agent'], value)}
177
+ readonly={readonly}
178
+ />
179
+ </div>
180
+ </FormSection>
181
+ )}
182
+
183
+ <FormSection title={t('intakePolicy.section.pageRanges')} last>
184
+ <PageRangesField
185
+ value={policy.text_conversion?.page_ranges}
186
+ onChange={(value) => setValue(['text_conversion', 'page_ranges'], value)}
187
+ readonly={readonly}
188
+ />
189
+ </FormSection>
190
+ </FormSurface>
191
+ );
192
+ }
193
+
194
+ if (section === 'extraction') {
195
+ return (
196
+ <FormSurface>
197
+ <FormSection title={t('intakePolicy.section.extraction')}>
198
+ <div className="grid gap-4 md:grid-cols-2 xl:grid-cols-4">
199
+ <TriStateField
200
+ label={t('intakePolicy.field.enabled')}
201
+ value={policy.extraction?.enabled}
202
+ onChange={(value) => setValue(['extraction', 'enabled'], value)}
203
+ readonly={readonly}
204
+ />
205
+ <SelectField
206
+ label={t('intakePolicy.field.source')}
207
+ value={policy.extraction?.source}
208
+ options={options(t, ['auto', 'text', 'vision', 'mixed'])}
209
+ onChange={(value) => setValue(['extraction', 'source'], value)}
210
+ readonly={readonly}
211
+ />
212
+ <SelectField
213
+ label={t('intakePolicy.field.pageScope')}
214
+ value={policy.extraction?.scope}
215
+ options={options(t, ['all', 'located'])}
216
+ onChange={(value) => setValue(['extraction', 'scope'], value)}
217
+ readonly={readonly}
218
+ />
219
+ <NumberField
220
+ label={t('intakePolicy.field.maxPages')}
221
+ value={policy.extraction?.max_pages}
222
+ min={1}
223
+ onChange={(value) => setValue(['extraction', 'max_pages'], value)}
224
+ readonly={readonly}
225
+ />
226
+ </div>
227
+ <InputField
228
+ label={t('intakePolicy.field.interaction')}
229
+ value={policy.extraction?.interaction}
230
+ onChange={(value) => setValue(['extraction', 'interaction'], value)}
231
+ readonly={readonly}
232
+ />
233
+ <TextAreaField
234
+ label={t('intakePolicy.field.instructions')}
235
+ value={policy.extraction?.instructions}
236
+ onChange={(value) => setValue(['extraction', 'instructions'], value)}
237
+ readonly={readonly}
238
+ />
239
+ <PageRangesField
240
+ value={policy.extraction?.page_ranges}
241
+ onChange={(value) => setValue(['extraction', 'page_ranges'], value)}
242
+ readonly={readonly}
243
+ />
244
+ </FormSection>
245
+
246
+ <FormSection title={t('intakePolicy.section.visionBudget')}>
247
+ <div className="grid gap-4 md:grid-cols-2 xl:grid-cols-3">
248
+ <SelectField
249
+ label={t('intakePolicy.field.defaultDetail')}
250
+ value={policy.extraction?.vision?.default_detail}
251
+ options={options(t, ['low', 'standard', 'high'])}
252
+ onChange={(value) => setValue(['extraction', 'vision', 'default_detail'], value)}
253
+ readonly={readonly}
254
+ />
255
+ <VisionDetailsField
256
+ value={policy.extraction?.vision?.allowed_details}
257
+ onChange={(value) => setValue(['extraction', 'vision', 'allowed_details'], value)}
258
+ readonly={readonly}
259
+ />
260
+ <NumberField
261
+ label={t('intakePolicy.field.maxImageTokens')}
262
+ value={policy.extraction?.vision?.max_image_tokens}
263
+ min={1}
264
+ onChange={(value) => setValue(['extraction', 'vision', 'max_image_tokens'], value)}
265
+ readonly={readonly}
266
+ />
267
+ <NumberField
268
+ label={t('intakePolicy.field.maxPayloadMb')}
269
+ value={policy.extraction?.vision?.max_payload_mb}
270
+ min={1}
271
+ onChange={(value) => setValue(['extraction', 'vision', 'max_payload_mb'], value)}
272
+ readonly={readonly}
273
+ />
274
+ <NumberField
275
+ label={t('intakePolicy.field.maxPagesPerCall')}
276
+ value={policy.extraction?.vision?.max_pages_per_call}
277
+ min={1}
278
+ onChange={(value) => setValue(['extraction', 'vision', 'max_pages_per_call'], value)}
279
+ readonly={readonly}
280
+ />
281
+ </div>
282
+ </FormSection>
283
+
284
+ <FormSection title={t('intakePolicy.section.verification')} last>
285
+ <div className="grid gap-4 md:grid-cols-2 xl:grid-cols-3">
286
+ <TriStateField
287
+ label={t('intakePolicy.field.enabled')}
288
+ value={policy.extraction?.verification?.enabled}
289
+ onChange={(value) => setValue(['extraction', 'verification', 'enabled'], value)}
290
+ readonly={readonly}
291
+ />
292
+ <InputField
293
+ label={t('intakePolicy.field.model')}
294
+ value={policy.extraction?.verification?.model}
295
+ onChange={(value) => setValue(['extraction', 'verification', 'model'], value)}
296
+ readonly={readonly}
297
+ />
298
+ <InputField
299
+ label={t('intakePolicy.field.environment')}
300
+ value={policy.extraction?.verification?.environment}
301
+ onChange={(value) => setValue(['extraction', 'verification', 'environment'], value)}
302
+ readonly={readonly}
303
+ />
304
+ <NumberField
305
+ label={t('intakePolicy.field.threshold')}
306
+ value={policy.extraction?.verification?.threshold}
307
+ min={0}
308
+ max={1}
309
+ step={0.05}
310
+ onChange={(value) => setValue(['extraction', 'verification', 'threshold'], value)}
311
+ readonly={readonly}
312
+ />
313
+ <NumberField
314
+ label={t('intakePolicy.field.maxRetries')}
315
+ value={policy.extraction?.verification?.max_retries}
316
+ min={0}
317
+ onChange={(value) => setValue(['extraction', 'verification', 'max_retries'], value)}
318
+ readonly={readonly}
319
+ />
320
+ <SelectField
321
+ label={t('intakePolicy.field.onFailure')}
322
+ value={policy.extraction?.verification?.on_fail}
323
+ options={options(t, ['flag', 'block'])}
324
+ onChange={(value) => setValue(['extraction', 'verification', 'on_fail'], value)}
325
+ readonly={readonly}
326
+ />
327
+ </div>
328
+ <TextAreaField
329
+ label={t('intakePolicy.field.materiality')}
330
+ value={policy.extraction?.verification?.materiality}
331
+ onChange={(value) => setValue(['extraction', 'verification', 'materiality'], value)}
332
+ readonly={readonly}
333
+ />
334
+ </FormSection>
335
+ </FormSurface>
336
+ );
337
+ }
338
+
339
+ if (section === 'grounding') {
340
+ const grounding = policy.extraction?.grounding;
341
+ const review = grounding?.review;
342
+ return (
343
+ <FormSurface>
344
+ <FormSection title={t('intakePolicy.section.grounding')}>
345
+ <div className="grid gap-4 md:grid-cols-2 xl:grid-cols-4">
346
+ <TriStateField
347
+ label={t('intakePolicy.field.enabled')}
348
+ value={grounding?.enabled}
349
+ onChange={(value) => setValue(['extraction', 'grounding', 'enabled'], value)}
350
+ readonly={readonly}
351
+ />
352
+ <NumberField
353
+ label={t('intakePolicy.field.maxPages')}
354
+ value={grounding?.max_pages}
355
+ min={1}
356
+ onChange={(value) => setValue(['extraction', 'grounding', 'max_pages'], value)}
357
+ readonly={readonly}
358
+ />
359
+ <NumberField
360
+ label={t('intakePolicy.field.windowPages')}
361
+ value={grounding?.window_pages}
362
+ min={1}
363
+ onChange={(value) => setValue(['extraction', 'grounding', 'window_pages'], value)}
364
+ readonly={readonly}
365
+ />
366
+ <InputField
367
+ label={t('intakePolicy.field.interaction')}
368
+ value={grounding?.interaction}
369
+ onChange={(value) => setValue(['extraction', 'grounding', 'interaction'], value)}
370
+ readonly={readonly}
371
+ />
372
+ </div>
373
+ <div className="grid gap-4 md:grid-cols-2 xl:grid-cols-3">
374
+ <TriStateField
375
+ label={t('intakePolicy.field.useVision')}
376
+ value={grounding?.use_vision}
377
+ onChange={(value) => setValue(['extraction', 'grounding', 'use_vision'], value)}
378
+ readonly={readonly}
379
+ />
380
+ <TriStateField
381
+ label={t('intakePolicy.field.forceOcr')}
382
+ value={grounding?.force_ocr}
383
+ onChange={(value) => setValue(['extraction', 'grounding', 'force_ocr'], value)}
384
+ readonly={readonly}
385
+ />
386
+ <TriStateField
387
+ label={t('intakePolicy.field.refreshOcr')}
388
+ value={grounding?.refresh_ocr}
389
+ onChange={(value) => setValue(['extraction', 'grounding', 'refresh_ocr'], value)}
390
+ readonly={readonly}
391
+ />
392
+ <TriStateField
393
+ label={t('intakePolicy.field.omitBlockBoxes')}
394
+ value={grounding?.omit_block_boxes}
395
+ onChange={(value) => setValue(['extraction', 'grounding', 'omit_block_boxes'], value)}
396
+ readonly={readonly}
397
+ />
398
+ <TriStateField
399
+ label={t('intakePolicy.field.updateProperties')}
400
+ value={grounding?.update_properties}
401
+ onChange={(value) => setValue(['extraction', 'grounding', 'update_properties'], value)}
402
+ readonly={readonly}
403
+ />
404
+ </div>
405
+ </FormSection>
406
+
407
+ <FormSection title={t('intakePolicy.section.models')}>
408
+ <ModelConfigFields
409
+ title={t('intakePolicy.field.primaryModel')}
410
+ config={grounding?.config}
411
+ onChange={(value) => setValue(['extraction', 'grounding', 'config'], value)}
412
+ readonly={readonly}
413
+ />
414
+ <ModelConfigFields
415
+ title={t('intakePolicy.field.hardModel')}
416
+ config={grounding?.hard_config}
417
+ onChange={(value) => setValue(['extraction', 'grounding', 'hard_config'], value)}
418
+ readonly={readonly}
419
+ />
420
+ <div className="grid gap-4 md:grid-cols-2">
421
+ <NumberField
422
+ label={t('intakePolicy.field.hardnessThreshold')}
423
+ value={grounding?.hardness_threshold}
424
+ min={0}
425
+ max={1}
426
+ step={0.05}
427
+ onChange={(value) => setValue(['extraction', 'grounding', 'hardness_threshold'], value)}
428
+ readonly={readonly}
429
+ />
430
+ <NumberField
431
+ label={t('intakePolicy.field.minCitationDensity')}
432
+ value={grounding?.min_citation_density}
433
+ min={0}
434
+ max={1}
435
+ step={0.05}
436
+ onChange={(value) => setValue(['extraction', 'grounding', 'min_citation_density'], value)}
437
+ readonly={readonly}
438
+ />
439
+ </div>
440
+ </FormSection>
441
+
442
+ <FormSection title={t('intakePolicy.section.review')} last>
443
+ <div className="grid gap-4 md:grid-cols-2 xl:grid-cols-4">
444
+ <TriStateField
445
+ label={t('intakePolicy.field.enabled')}
446
+ value={review?.enabled}
447
+ onChange={(value) => setValue(['extraction', 'grounding', 'review', 'enabled'], value)}
448
+ readonly={readonly}
449
+ />
450
+ <TriStateField
451
+ label={t('intakePolicy.field.forceReview')}
452
+ value={review?.force}
453
+ onChange={(value) => setValue(['extraction', 'grounding', 'review', 'force'], value)}
454
+ readonly={readonly}
455
+ />
456
+ <NumberField
457
+ label={t('intakePolicy.field.reviewThreshold')}
458
+ value={review?.threshold}
459
+ min={0}
460
+ max={1}
461
+ step={0.05}
462
+ onChange={(value) => setValue(['extraction', 'grounding', 'review', 'threshold'], value)}
463
+ readonly={readonly}
464
+ />
465
+ <NumberField
466
+ label={t('intakePolicy.field.coverageThreshold')}
467
+ value={review?.coverage_threshold}
468
+ min={0}
469
+ max={1}
470
+ step={0.05}
471
+ onChange={(value) =>
472
+ setValue(['extraction', 'grounding', 'review', 'coverage_threshold'], value)
473
+ }
474
+ readonly={readonly}
475
+ />
476
+ </div>
477
+ <ModelConfigFields
478
+ title={t('intakePolicy.field.reviewModel')}
479
+ config={review?.config}
480
+ onChange={(value) => setValue(['extraction', 'grounding', 'review', 'config'], value)}
481
+ readonly={readonly}
482
+ />
483
+ </FormSection>
484
+ </FormSurface>
485
+ );
486
+ }
487
+
488
+ return (
489
+ <FormSurface>
490
+ <FormSection title={t('intakePolicy.section.rendering')}>
491
+ <TextAreaField
492
+ label={t('intakePolicy.field.renderingTemplate')}
493
+ description={t('intakePolicy.help.renderingTemplate')}
494
+ value={policy.rendering_template}
495
+ onChange={(value) => setValue(['rendering_template'], value)}
496
+ readonly={readonly}
497
+ monospace
498
+ minLines={8}
499
+ />
500
+ </FormSection>
501
+ <FormSection title={t('intakePolicy.section.embeddings')} last>
502
+ <div className="grid gap-4 md:grid-cols-2 xl:grid-cols-4">
503
+ <TriStateField
504
+ label={t('intakePolicy.field.textEmbedding')}
505
+ value={policy.embeddings?.text}
506
+ onChange={(value) => setValue(['embeddings', 'text'], value)}
507
+ readonly={readonly}
508
+ />
509
+ <TriStateField
510
+ label={t('intakePolicy.field.imageEmbedding')}
511
+ value={policy.embeddings?.image}
512
+ onChange={(value) => setValue(['embeddings', 'image'], value)}
513
+ readonly={readonly}
514
+ />
515
+ <TriStateField
516
+ label={t('intakePolicy.field.propertiesEmbedding')}
517
+ value={policy.embeddings?.properties}
518
+ onChange={(value) => setValue(['embeddings', 'properties'], value)}
519
+ readonly={readonly}
520
+ />
521
+ <TriStateField
522
+ label={t('intakePolicy.field.generateToc')}
523
+ value={policy.generate_toc}
524
+ onChange={(value) => setValue(['generate_toc'], value)}
525
+ readonly={readonly}
526
+ />
527
+ </div>
528
+ </FormSection>
529
+ </FormSurface>
530
+ );
531
+ }
532
+
533
+ function FormSurface({ children }: { children: ReactNode }) {
534
+ return <div className="mx-auto w-full max-w-6xl px-1 py-4">{children}</div>;
535
+ }
536
+
537
+ function FormSection({ title, children, last = false }: { title: string; children: ReactNode; last?: boolean }) {
538
+ return (
539
+ <section className={last ? 'pb-3' : 'mb-6 border-b pb-6'}>
540
+ <h3 className="mb-4 text-sm font-semibold">{title}</h3>
541
+ <div className="space-y-4">{children}</div>
542
+ </section>
543
+ );
544
+ }
545
+
546
+ function InputField({
547
+ label,
548
+ value,
549
+ onChange,
550
+ readonly,
551
+ description,
552
+ }: {
553
+ label: string;
554
+ value?: string;
555
+ onChange: (value: string | undefined) => void;
556
+ readonly: boolean;
557
+ description?: string;
558
+ }) {
559
+ return (
560
+ <FormItem label={label} description={description}>
561
+ <Input value={value ?? ''} onChange={(value) => onChange(value || undefined)} disabled={readonly} />
562
+ </FormItem>
563
+ );
564
+ }
565
+
566
+ function TextAreaField({
567
+ label,
568
+ value,
569
+ onChange,
570
+ readonly,
571
+ description,
572
+ minLines = 3,
573
+ monospace = false,
574
+ }: {
575
+ label: string;
576
+ value?: string;
577
+ onChange: (value: string | undefined) => void;
578
+ readonly: boolean;
579
+ description?: string;
580
+ minLines?: number;
581
+ monospace?: boolean;
582
+ }) {
583
+ return (
584
+ <FormItem label={label} description={description}>
585
+ <Textarea
586
+ value={value ?? ''}
587
+ onChange={(event) => onChange(event.target.value || undefined)}
588
+ disabled={readonly}
589
+ minLines={minLines}
590
+ maxLines={14}
591
+ className={monospace ? 'font-mono' : undefined}
592
+ />
593
+ </FormItem>
594
+ );
595
+ }
596
+
597
+ function NumberField({
598
+ label,
599
+ value,
600
+ onChange,
601
+ readonly,
602
+ min,
603
+ max,
604
+ step,
605
+ }: {
606
+ label: string;
607
+ value?: number;
608
+ onChange: (value: number | undefined) => void;
609
+ readonly: boolean;
610
+ min?: number;
611
+ max?: number;
612
+ step?: number;
613
+ }) {
614
+ return (
615
+ <FormItem label={label}>
616
+ <NumberInput
617
+ value={value}
618
+ onChange={(value) => onChange(value === undefined || Number.isFinite(value) ? value : undefined)}
619
+ disabled={readonly}
620
+ min={min}
621
+ max={max}
622
+ step={step ?? 1}
623
+ noScroll
624
+ />
625
+ </FormItem>
626
+ );
627
+ }
628
+
629
+ function SelectField<T extends string | number>({
630
+ label,
631
+ description,
632
+ value,
633
+ options,
634
+ onChange,
635
+ readonly,
636
+ }: {
637
+ label: string;
638
+ description?: string;
639
+ value?: T;
640
+ options: SelectOption<T>[];
641
+ onChange: (value: T | undefined) => void;
642
+ readonly: boolean;
643
+ }) {
644
+ const { t } = useUITranslation();
645
+ const choices: SelectOption<T | '__inherit__'>[] = [
646
+ { value: '__inherit__', label: t('intakePolicy.option.inherit') },
647
+ ...options,
648
+ ];
649
+ const selected = choices.find((option) => option.value === value) ?? choices[0];
650
+ return (
651
+ <FormItem label={label} description={description}>
652
+ <SelectBox
653
+ options={choices}
654
+ value={selected}
655
+ by="value"
656
+ optionLabel={(option) => option.label}
657
+ onChange={(option) => onChange(option.value === '__inherit__' ? undefined : option.value)}
658
+ disabled={readonly}
659
+ />
660
+ </FormItem>
661
+ );
662
+ }
663
+
664
+ function TriStateField({
665
+ label,
666
+ value,
667
+ onChange,
668
+ readonly,
669
+ }: {
670
+ label: string;
671
+ value?: boolean;
672
+ onChange: (value: boolean | undefined) => void;
673
+ readonly: boolean;
674
+ }) {
675
+ const { t } = useUITranslation();
676
+ const choices = [
677
+ { value: 'inherit', label: t('intakePolicy.option.inherit') },
678
+ { value: 'enabled', label: t('intakePolicy.option.enabled') },
679
+ { value: 'disabled', label: t('intakePolicy.option.disabled') },
680
+ ] as const;
681
+ const selectedValue = value === undefined ? 'inherit' : value ? 'enabled' : 'disabled';
682
+ return (
683
+ <FormItem label={label}>
684
+ <SelectBox
685
+ options={[...choices]}
686
+ value={choices.find((option) => option.value === selectedValue)}
687
+ by="value"
688
+ optionLabel={(option) => option.label}
689
+ onChange={(option) => onChange(option.value === 'inherit' ? undefined : option.value === 'enabled')}
690
+ disabled={readonly}
691
+ />
692
+ </FormItem>
693
+ );
694
+ }
695
+
696
+ function VisionDetailsField({
697
+ value,
698
+ onChange,
699
+ readonly,
700
+ }: {
701
+ value?: IntakeVisionDetail[];
702
+ onChange: (value: IntakeVisionDetail[] | undefined) => void;
703
+ readonly: boolean;
704
+ }) {
705
+ const { t } = useUITranslation();
706
+ const choices = options(t, ['low', 'standard', 'high'] as const);
707
+ return (
708
+ <FormItem label={t('intakePolicy.field.allowedDetails')}>
709
+ <SelectBox<SelectOption<IntakeVisionDetail>>
710
+ multiple
711
+ options={choices}
712
+ value={choices.filter((option) => value?.includes(option.value))}
713
+ by="value"
714
+ optionLabel={(option) => option.label}
715
+ onChange={(selected) => onChange(selected.length ? selected.map((option) => option.value) : undefined)}
716
+ disabled={readonly}
717
+ />
718
+ </FormItem>
719
+ );
720
+ }
721
+
722
+ function PageRangesField({
723
+ value,
724
+ onChange,
725
+ readonly,
726
+ }: {
727
+ value?: IntakePageRanges;
728
+ onChange: (value: IntakePageRanges | undefined) => void;
729
+ readonly: boolean;
730
+ }) {
731
+ const { t } = useUITranslation();
732
+ const remove = (index: number) => {
733
+ const next = value?.filter((_, rangeIndex) => rangeIndex !== index);
734
+ onChange(next?.length ? next : undefined);
735
+ };
736
+ return (
737
+ <FormItem label={t('intakePolicy.field.pageRanges')} description={t('intakePolicy.help.pageRanges')}>
738
+ <div className="space-y-2">
739
+ {value?.map((range, index) => (
740
+ <div className="grid grid-cols-[minmax(0,1fr)_minmax(0,1fr)_2.25rem] gap-2" key={`${index}`}>
741
+ <NumberInput
742
+ aria-label={t('intakePolicy.field.rangeStart')}
743
+ value={range[0]}
744
+ onChange={(next) => {
745
+ if (next !== undefined && Number.isFinite(next)) {
746
+ onChange(replaceIntakeRange(value, index, 0, next));
747
+ }
748
+ }}
749
+ disabled={readonly}
750
+ step={1}
751
+ noScroll
752
+ />
753
+ <NumberInput
754
+ aria-label={t('intakePolicy.field.rangeEnd')}
755
+ value={range[1]}
756
+ onChange={(next) => {
757
+ if (next !== undefined && Number.isFinite(next)) {
758
+ onChange(replaceIntakeRange(value, index, 1, next));
759
+ }
760
+ }}
761
+ disabled={readonly}
762
+ step={1}
763
+ noScroll
764
+ />
765
+ <VTooltip description={t('intakePolicy.action.removeRange')}>
766
+ <Button
767
+ type="button"
768
+ variant="ghost"
769
+ size="icon"
770
+ aria-label={t('intakePolicy.action.removeRange')}
771
+ onClick={() => remove(index)}
772
+ disabled={readonly}
773
+ >
774
+ <Trash2 className="size-4" />
775
+ </Button>
776
+ </VTooltip>
777
+ </div>
778
+ ))}
779
+ <Button
780
+ type="button"
781
+ variant="outline"
782
+ size="sm"
783
+ onClick={() => onChange([...(value ?? []), [1, 1]])}
784
+ disabled={readonly}
785
+ >
786
+ <Plus className="size-4" />
787
+ {t('intakePolicy.action.addRange')}
788
+ </Button>
789
+ </div>
790
+ </FormItem>
791
+ );
792
+ }
793
+
794
+ function ModelConfigFields({
795
+ title,
796
+ config,
797
+ onChange,
798
+ readonly,
799
+ }: {
800
+ title: string;
801
+ config?: InteractionExecutionConfiguration;
802
+ onChange: (value: InteractionExecutionConfiguration | undefined) => void;
803
+ readonly: boolean;
804
+ }) {
805
+ const { t } = useUITranslation();
806
+
807
+ return (
808
+ <div>
809
+ <div className="mb-2 text-xs font-medium text-muted">{title}</div>
810
+ <div className="grid gap-4 md:grid-cols-2">
811
+ <FormItem label={t('intakePolicy.field.environment')}>
812
+ <SelectEnvironment
813
+ selectedEnvId={config?.environment}
814
+ onChange={(environment) => onChange(updateExecutionEnvironment(config, environment?.id))}
815
+ isClearable
816
+ disabled={readonly}
817
+ />
818
+ </FormItem>
819
+ <FormItem label={t('intakePolicy.field.model')}>
820
+ <SelectModel
821
+ envId={config?.environment}
822
+ selectedModelId={config?.model}
823
+ onChange={(model) => onChange(updateExecutionModel(config, model?.id))}
824
+ isClearable
825
+ disabled={readonly || !config?.environment}
826
+ />
827
+ </FormItem>
828
+ </div>
829
+ </div>
830
+ );
831
+ }
832
+
833
+ function options<T extends string>(
834
+ t: (key: string, values?: Record<string, unknown>) => string,
835
+ values: readonly T[],
836
+ ): SelectOption<T>[] {
837
+ return values.map((value) => ({ value, label: t(`intakePolicy.option.${value}`) }));
838
+ }