@vertesia/ui 1.4.0-dev.20260615.051508Z → 1.4.0-dev.20260629.130134Z
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.
- package/lib/core/components/shadcn/dropdown.d.ts.map +1 -1
- package/lib/core/components/shadcn/dropdown.js +6 -2
- package/lib/core/components/shadcn/dropdown.js.map +1 -1
- package/lib/core/components/shadcn/filters/filterBar.d.ts.map +1 -1
- package/lib/core/components/shadcn/filters/filterBar.js +9 -2
- package/lib/core/components/shadcn/filters/filterBar.js.map +1 -1
- package/lib/core/components/shadcn/modal/ConfirmModal.d.ts +16 -1
- package/lib/core/components/shadcn/modal/ConfirmModal.d.ts.map +1 -1
- package/lib/core/components/shadcn/modal/ConfirmModal.js +25 -3
- package/lib/core/components/shadcn/modal/ConfirmModal.js.map +1 -1
- package/lib/core/components/shadcn/modal/dialog.js +1 -1
- package/lib/core/components/shadcn/modal/dialog.js.map +1 -1
- package/lib/core/components/shadcn/popover.d.ts.map +1 -1
- package/lib/core/components/shadcn/popover.js +3 -1
- package/lib/core/components/shadcn/popover.js.map +1 -1
- package/lib/core/components/shadcn/switch.js +3 -3
- package/lib/core/components/shadcn/switch.js.map +1 -1
- package/lib/core/components/shadcn/tabs.js +1 -1
- package/lib/core/components/shadcn/tabs.js.map +1 -1
- package/lib/core/components/shadcn/tooltip.d.ts.map +1 -1
- package/lib/core/components/shadcn/tooltip.js +3 -1
- package/lib/core/components/shadcn/tooltip.js.map +1 -1
- package/lib/env/index.d.ts +0 -19
- package/lib/env/index.d.ts.map +1 -1
- package/lib/env/index.js +0 -6
- package/lib/env/index.js.map +1 -1
- package/lib/features/agent/PayloadBuilder.d.ts +4 -0
- package/lib/features/agent/PayloadBuilder.d.ts.map +1 -1
- package/lib/features/agent/PayloadBuilder.js +16 -0
- package/lib/features/agent/PayloadBuilder.js.map +1 -1
- package/lib/features/agent/chat/AgentApprovalModeSelector.d.ts +10 -0
- package/lib/features/agent/chat/AgentApprovalModeSelector.d.ts.map +1 -0
- package/lib/features/agent/chat/AgentApprovalModeSelector.js +50 -0
- package/lib/features/agent/chat/AgentApprovalModeSelector.js.map +1 -0
- package/lib/features/agent/chat/AgentChatFixtureReplay.d.ts +2 -1
- package/lib/features/agent/chat/AgentChatFixtureReplay.d.ts.map +1 -1
- package/lib/features/agent/chat/AgentChatFixtureReplay.js +3 -3
- package/lib/features/agent/chat/AgentChatFixtureReplay.js.map +1 -1
- package/lib/features/agent/chat/AgentRequestInputOverlay.d.ts +5 -2
- package/lib/features/agent/chat/AgentRequestInputOverlay.d.ts.map +1 -1
- package/lib/features/agent/chat/AgentRequestInputOverlay.js +41 -7
- package/lib/features/agent/chat/AgentRequestInputOverlay.js.map +1 -1
- package/lib/features/agent/chat/AgentRightPanel.d.ts.map +1 -1
- package/lib/features/agent/chat/AgentRightPanel.js +133 -12
- package/lib/features/agent/chat/AgentRightPanel.js.map +1 -1
- package/lib/features/agent/chat/AnimatedThinkingDots.js +1 -1
- package/lib/features/agent/chat/AnimatedThinkingDots.js.map +1 -1
- package/lib/features/agent/chat/ArtifactsTab.d.ts.map +1 -1
- package/lib/features/agent/chat/ArtifactsTab.js +11 -65
- package/lib/features/agent/chat/ArtifactsTab.js.map +1 -1
- package/lib/features/agent/chat/AskUserWidget.d.ts +3 -1
- package/lib/features/agent/chat/AskUserWidget.d.ts.map +1 -1
- package/lib/features/agent/chat/AskUserWidget.js +4 -3
- package/lib/features/agent/chat/AskUserWidget.js.map +1 -1
- package/lib/features/agent/chat/ModernAgentConversation.d.ts +10 -2
- package/lib/features/agent/chat/ModernAgentConversation.d.ts.map +1 -1
- package/lib/features/agent/chat/ModernAgentConversation.js +526 -117
- package/lib/features/agent/chat/ModernAgentConversation.js.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/ActiveWorkstreamsSummary.d.ts +8 -0
- package/lib/features/agent/chat/ModernAgentOutput/ActiveWorkstreamsSummary.d.ts.map +1 -0
- package/lib/features/agent/chat/ModernAgentOutput/ActiveWorkstreamsSummary.js +19 -0
- package/lib/features/agent/chat/ModernAgentOutput/ActiveWorkstreamsSummary.js.map +1 -0
- package/lib/features/agent/chat/ModernAgentOutput/AllMessagesMixed.d.ts +8 -2
- package/lib/features/agent/chat/ModernAgentOutput/AllMessagesMixed.d.ts.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/AllMessagesMixed.js +551 -92
- package/lib/features/agent/chat/ModernAgentOutput/AllMessagesMixed.js.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/AttachmentPreview.d.ts.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/AttachmentPreview.js +7 -6
- package/lib/features/agent/chat/ModernAgentOutput/AttachmentPreview.js.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/Header.js +2 -2
- package/lib/features/agent/chat/ModernAgentOutput/Header.js.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/MessageDeliveryStatus.d.ts +8 -0
- package/lib/features/agent/chat/ModernAgentOutput/MessageDeliveryStatus.d.ts.map +1 -0
- package/lib/features/agent/chat/ModernAgentOutput/MessageDeliveryStatus.js +61 -0
- package/lib/features/agent/chat/ModernAgentOutput/MessageDeliveryStatus.js.map +1 -0
- package/lib/features/agent/chat/ModernAgentOutput/MessageInput.d.ts +15 -2
- package/lib/features/agent/chat/ModernAgentOutput/MessageInput.d.ts.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/MessageInput.js +28 -38
- package/lib/features/agent/chat/ModernAgentOutput/MessageInput.js.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/MessageItem.d.ts +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/MessageItem.d.ts.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/MessageItem.js +3 -2
- package/lib/features/agent/chat/ModernAgentOutput/MessageItem.js.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/SlideInPanel.js +2 -1
- package/lib/features/agent/chat/ModernAgentOutput/SlideInPanel.js.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/SlidingMessages.js +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/SlidingMessages.js.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/SummaryConversation.d.ts +5 -0
- package/lib/features/agent/chat/ModernAgentOutput/SummaryConversation.d.ts.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/SummaryConversation.js +59 -4
- package/lib/features/agent/chat/ModernAgentOutput/SummaryConversation.js.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/WorkstreamTabs.js +2 -2
- package/lib/features/agent/chat/ModernAgentOutput/WorkstreamTabs.js.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/requestInputMessages.d.ts +9 -0
- package/lib/features/agent/chat/ModernAgentOutput/requestInputMessages.d.ts.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/requestInputMessages.js +180 -0
- package/lib/features/agent/chat/ModernAgentOutput/requestInputMessages.js.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/utils.d.ts +6 -0
- package/lib/features/agent/chat/ModernAgentOutput/utils.d.ts.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/utils.js +92 -2
- package/lib/features/agent/chat/ModernAgentOutput/utils.js.map +1 -1
- package/lib/features/agent/chat/clipboardFiles.d.ts +15 -0
- package/lib/features/agent/chat/clipboardFiles.d.ts.map +1 -0
- package/lib/features/agent/chat/clipboardFiles.js +35 -0
- package/lib/features/agent/chat/clipboardFiles.js.map +1 -0
- package/lib/features/agent/chat/hooks/useAgentStream.d.ts +6 -0
- package/lib/features/agent/chat/hooks/useAgentStream.d.ts.map +1 -1
- package/lib/features/agent/chat/hooks/useAgentStream.js +218 -37
- package/lib/features/agent/chat/hooks/useAgentStream.js.map +1 -1
- package/lib/features/agent/chat/hooks/useArtifacts.d.ts +1 -8
- package/lib/features/agent/chat/hooks/useArtifacts.d.ts.map +1 -1
- package/lib/features/agent/chat/hooks/useArtifacts.js +10 -28
- package/lib/features/agent/chat/hooks/useArtifacts.js.map +1 -1
- package/lib/features/agent/chat/index.d.ts +2 -1
- package/lib/features/agent/chat/index.d.ts.map +1 -1
- package/lib/features/agent/chat/index.js +2 -1
- package/lib/features/agent/chat/index.js.map +1 -1
- package/lib/features/agent/chat/workstreams.d.ts +1 -0
- package/lib/features/agent/chat/workstreams.d.ts.map +1 -1
- package/lib/features/agent/chat/workstreams.js +28 -0
- package/lib/features/agent/chat/workstreams.js.map +1 -1
- package/lib/features/facets/AgentRunnerFacetsNav.d.ts +10 -1
- package/lib/features/facets/AgentRunnerFacetsNav.d.ts.map +1 -1
- package/lib/features/facets/AgentRunnerFacetsNav.js +6 -3
- package/lib/features/facets/AgentRunnerFacetsNav.js.map +1 -1
- package/lib/features/facets/CollectionsFacetsNav.d.ts +10 -1
- package/lib/features/facets/CollectionsFacetsNav.d.ts.map +1 -1
- package/lib/features/facets/CollectionsFacetsNav.js +14 -5
- package/lib/features/facets/CollectionsFacetsNav.js.map +1 -1
- package/lib/features/facets/PromptsFacetsNav.d.ts +10 -1
- package/lib/features/facets/PromptsFacetsNav.d.ts.map +1 -1
- package/lib/features/facets/PromptsFacetsNav.js +14 -5
- package/lib/features/facets/PromptsFacetsNav.js.map +1 -1
- package/lib/features/facets/RunsFacetsNav.d.ts +10 -1
- package/lib/features/facets/RunsFacetsNav.d.ts.map +1 -1
- package/lib/features/facets/RunsFacetsNav.js +14 -5
- package/lib/features/facets/RunsFacetsNav.js.map +1 -1
- package/lib/features/index.d.ts +0 -1
- package/lib/features/index.d.ts.map +1 -1
- package/lib/features/index.js +0 -1
- package/lib/features/index.js.map +1 -1
- package/lib/features/oauth/McpConnectionsButton.d.ts +30 -0
- package/lib/features/oauth/McpConnectionsButton.d.ts.map +1 -0
- package/lib/features/oauth/McpConnectionsButton.js +70 -0
- package/lib/features/oauth/McpConnectionsButton.js.map +1 -0
- package/lib/features/oauth/McpConnectionsDialog.d.ts +25 -0
- package/lib/features/oauth/McpConnectionsDialog.d.ts.map +1 -0
- package/lib/features/oauth/McpConnectionsDialog.js +26 -0
- package/lib/features/oauth/McpConnectionsDialog.js.map +1 -0
- package/lib/features/oauth/RemoteMcpConnectionButton.d.ts.map +1 -1
- package/lib/features/oauth/RemoteMcpConnectionButton.js +14 -6
- package/lib/features/oauth/RemoteMcpConnectionButton.js.map +1 -1
- package/lib/features/oauth/index.d.ts +3 -0
- package/lib/features/oauth/index.d.ts.map +1 -1
- package/lib/features/oauth/index.js +3 -0
- package/lib/features/oauth/index.js.map +1 -1
- package/lib/features/oauth/useMcpConnections.d.ts +44 -0
- package/lib/features/oauth/useMcpConnections.d.ts.map +1 -0
- package/lib/features/oauth/useMcpConnections.js +168 -0
- package/lib/features/oauth/useMcpConnections.js.map +1 -0
- package/lib/features/permissions/UserPermissionsProvider.d.ts +4 -6
- package/lib/features/permissions/UserPermissionsProvider.d.ts.map +1 -1
- package/lib/features/permissions/UserPermissionsProvider.js +40 -42
- package/lib/features/permissions/UserPermissionsProvider.js.map +1 -1
- package/lib/features/store/objects/DocumentPreviewPanel.d.ts.map +1 -1
- package/lib/features/store/objects/DocumentPreviewPanel.js +2 -1
- package/lib/features/store/objects/DocumentPreviewPanel.js.map +1 -1
- package/lib/features/store/objects/DocumentQuickFilter.d.ts +23 -0
- package/lib/features/store/objects/DocumentQuickFilter.d.ts.map +1 -0
- package/lib/features/store/objects/DocumentQuickFilter.js +30 -0
- package/lib/features/store/objects/DocumentQuickFilter.js.map +1 -0
- package/lib/features/store/objects/DocumentSearchResults.d.ts.map +1 -1
- package/lib/features/store/objects/DocumentSearchResults.js +17 -1
- package/lib/features/store/objects/DocumentSearchResults.js.map +1 -1
- package/lib/features/store/objects/components/ContentOverview.d.ts.map +1 -1
- package/lib/features/store/objects/components/ContentOverview.js +17 -74
- package/lib/features/store/objects/components/ContentOverview.js.map +1 -1
- package/lib/features/store/objects/layout/DocumentTableColumn.d.ts +7 -1
- package/lib/features/store/objects/layout/DocumentTableColumn.d.ts.map +1 -1
- package/lib/features/store/objects/layout/DocumentTableColumn.js +27 -3
- package/lib/features/store/objects/layout/DocumentTableColumn.js.map +1 -1
- package/lib/features/store/objects/layout/documentLayout.js +1 -1
- package/lib/features/store/objects/layout/renderers.d.ts +2 -1
- package/lib/features/store/objects/layout/renderers.d.ts.map +1 -1
- package/lib/features/store/objects/layout/renderers.js +27 -20
- package/lib/features/store/objects/layout/renderers.js.map +1 -1
- package/lib/features/store/types/ContentObjectTypesSearch.d.ts.map +1 -1
- package/lib/features/store/types/ContentObjectTypesSearch.js +4 -1
- package/lib/features/store/types/ContentObjectTypesSearch.js.map +1 -1
- package/lib/features/store/types/ContentObjectTypesTable.d.ts +2 -1
- package/lib/features/store/types/ContentObjectTypesTable.d.ts.map +1 -1
- package/lib/features/store/types/ContentObjectTypesTable.js +8 -3
- package/lib/features/store/types/ContentObjectTypesTable.js.map +1 -1
- package/lib/i18n/instance.d.ts.map +1 -1
- package/lib/i18n/instance.js +1 -0
- package/lib/i18n/instance.js.map +1 -1
- package/lib/i18n/locales/ar.json +72 -45
- package/lib/i18n/locales/de.json +65 -34
- package/lib/i18n/locales/en.json +63 -47
- package/lib/i18n/locales/es.json +65 -35
- package/lib/i18n/locales/fr.json +65 -35
- package/lib/i18n/locales/it.json +72 -42
- package/lib/i18n/locales/ja.json +72 -41
- package/lib/i18n/locales/ko.json +72 -41
- package/lib/i18n/locales/pt.json +72 -42
- package/lib/i18n/locales/ru.json +72 -43
- package/lib/i18n/locales/tr.json +72 -41
- package/lib/i18n/locales/zh-TW.json +72 -41
- package/lib/i18n/locales/zh.json +72 -41
- package/lib/session/UserSession.d.ts +0 -6
- package/lib/session/UserSession.d.ts.map +1 -1
- package/lib/session/UserSession.js +0 -15
- package/lib/session/UserSession.js.map +1 -1
- package/lib/session/UserSessionProvider.d.ts.map +1 -1
- package/lib/session/UserSessionProvider.js +39 -98
- package/lib/session/UserSessionProvider.js.map +1 -1
- package/lib/session/auth/composable.d.ts.map +1 -1
- package/lib/session/auth/composable.js +3 -33
- package/lib/session/auth/composable.js.map +1 -1
- package/lib/shell/login/SignInPrimitives.d.ts.map +1 -1
- package/lib/shell/login/SignInPrimitives.js +3 -2
- package/lib/shell/login/SignInPrimitives.js.map +1 -1
- package/lib/vertesia-ui-core.js +1 -1
- package/lib/vertesia-ui-core.js.map +1 -1
- package/lib/vertesia-ui-env.js +1 -1
- package/lib/vertesia-ui-env.js.map +1 -1
- package/lib/vertesia-ui-features.js +1 -1
- package/lib/vertesia-ui-features.js.map +1 -1
- package/lib/vertesia-ui-i18n.js +1 -1
- package/lib/vertesia-ui-i18n.js.map +1 -1
- package/lib/vertesia-ui-session.js +1 -1
- package/lib/vertesia-ui-session.js.map +1 -1
- package/lib/vertesia-ui-shell.js +1 -1
- package/lib/vertesia-ui-shell.js.map +1 -1
- package/lib/vertesia-ui-widgets.js +1 -1
- package/lib/vertesia-ui-widgets.js.map +1 -1
- package/lib/widgets/schema-editor/editor/Editable.js +1 -1
- package/lib/widgets/schema-editor/editor/Editable.js.map +1 -1
- package/llms.txt +70 -70
- package/package.json +35 -32
- package/src/core/components/shadcn/dropdown.tsx +2 -0
- package/src/core/components/shadcn/filters/filterBar.tsx +9 -2
- package/src/core/components/shadcn/modal/ConfirmModal.tsx +65 -3
- package/src/core/components/shadcn/modal/dialog.tsx +1 -1
- package/src/core/components/shadcn/popover.tsx +1 -0
- package/src/core/components/shadcn/switch.tsx +4 -4
- package/src/core/components/shadcn/tabs.tsx +1 -1
- package/src/core/components/shadcn/tooltip.tsx +1 -0
- package/src/env/index.ts +0 -24
- package/src/features/agent/PayloadBuilder.tsx +18 -0
- package/src/features/agent/chat/AgentApprovalModeSelector.tsx +130 -0
- package/src/features/agent/chat/AgentChatFixtureReplay.test.tsx +22 -2
- package/src/features/agent/chat/AgentChatFixtureReplay.tsx +33 -27
- package/src/features/agent/chat/AgentRequestInputOverlay.test.tsx +122 -0
- package/src/features/agent/chat/AgentRequestInputOverlay.tsx +91 -17
- package/src/features/agent/chat/AgentRightPanel.tsx +238 -50
- package/src/features/agent/chat/AnimatedThinkingDots.tsx +1 -1
- package/src/features/agent/chat/ArtifactsTab.tsx +21 -155
- package/src/features/agent/chat/AskUserWidget.tsx +6 -2
- package/src/features/agent/chat/ModernAgentConversation.test.tsx +1157 -47
- package/src/features/agent/chat/ModernAgentConversation.tsx +703 -136
- package/src/features/agent/chat/ModernAgentOutput/ActiveWorkstreamsSummary.tsx +74 -0
- package/src/features/agent/chat/ModernAgentOutput/AllMessagesMixed.test.tsx +1420 -126
- package/src/features/agent/chat/ModernAgentOutput/AllMessagesMixed.tsx +934 -111
- package/src/features/agent/chat/ModernAgentOutput/AttachmentPreview.tsx +31 -40
- package/src/features/agent/chat/ModernAgentOutput/Header.tsx +28 -28
- package/src/features/agent/chat/ModernAgentOutput/MessageDeliveryStatus.tsx +83 -0
- package/src/features/agent/chat/ModernAgentOutput/MessageInput.test.tsx +38 -2
- package/src/features/agent/chat/ModernAgentOutput/MessageInput.tsx +121 -98
- package/src/features/agent/chat/ModernAgentOutput/MessageItem.tsx +7 -1
- package/src/features/agent/chat/ModernAgentOutput/SlideInPanel.tsx +3 -3
- package/src/features/agent/chat/ModernAgentOutput/SlidingMessages.tsx +1 -1
- package/src/features/agent/chat/ModernAgentOutput/SummaryConversation.ts +82 -2
- package/src/features/agent/chat/ModernAgentOutput/WorkstreamTabs.tsx +2 -2
- package/src/features/agent/chat/ModernAgentOutput/requestInputMessages.ts +216 -0
- package/src/features/agent/chat/ModernAgentOutput/utils.test.ts +149 -0
- package/src/features/agent/chat/ModernAgentOutput/utils.ts +103 -2
- package/src/features/agent/chat/clipboardFiles.ts +33 -0
- package/src/features/agent/chat/hooks/useAgentStream.test.tsx +355 -4
- package/src/features/agent/chat/hooks/useAgentStream.ts +270 -43
- package/src/features/agent/chat/hooks/useArtifacts.ts +11 -44
- package/src/features/agent/chat/index.ts +10 -1
- package/src/features/agent/chat/workstreams.ts +42 -0
- package/src/features/facets/AgentRunnerFacetsNav.tsx +23 -3
- package/src/features/facets/CollectionsFacetsNav.tsx +30 -5
- package/src/features/facets/PromptsFacetsNav.tsx +30 -5
- package/src/features/facets/RunsFacetsNav.tsx +32 -5
- package/src/features/index.ts +0 -1
- package/src/features/oauth/McpConnectionsButton.test.tsx +248 -0
- package/src/features/oauth/McpConnectionsButton.tsx +269 -0
- package/src/features/oauth/McpConnectionsDialog.tsx +142 -0
- package/src/features/oauth/RemoteMcpConnectionButton.tsx +37 -14
- package/src/features/oauth/index.ts +3 -0
- package/src/features/oauth/useMcpConnections.test.ts +94 -0
- package/src/features/oauth/useMcpConnections.ts +210 -0
- package/src/features/permissions/UserPermissionsProvider.tsx +41 -59
- package/src/features/store/objects/DocumentPreviewPanel.tsx +4 -2
- package/src/features/store/objects/DocumentQuickFilter.tsx +72 -0
- package/src/features/store/objects/DocumentSearchResults.tsx +30 -11
- package/src/features/store/objects/components/ContentOverview.tsx +30 -99
- package/src/features/store/objects/layout/DocumentTableColumn.tsx +29 -4
- package/src/features/store/objects/layout/documentLayout.tsx +1 -1
- package/src/features/store/objects/layout/renderers.tsx +80 -20
- package/src/features/store/types/ContentObjectTypesSearch.tsx +7 -1
- package/src/features/store/types/ContentObjectTypesTable.tsx +34 -4
- package/src/i18n/instance.ts +1 -0
- package/src/i18n/locales/ar.json +72 -45
- package/src/i18n/locales/de.json +65 -34
- package/src/i18n/locales/en.json +63 -47
- package/src/i18n/locales/es.json +65 -35
- package/src/i18n/locales/fr.json +65 -35
- package/src/i18n/locales/it.json +72 -42
- package/src/i18n/locales/ja.json +72 -41
- package/src/i18n/locales/ko.json +72 -41
- package/src/i18n/locales/pt.json +72 -42
- package/src/i18n/locales/ru.json +72 -43
- package/src/i18n/locales/tr.json +72 -41
- package/src/i18n/locales/zh-TW.json +72 -41
- package/src/i18n/locales/zh.json +72 -41
- package/src/i18n/rtl.test.ts +57 -1
- package/src/session/UserSession.ts +0 -16
- package/src/session/UserSessionProvider.tsx +51 -123
- package/src/session/auth/composable.ts +3 -34
- package/src/shell/login/SignInPrimitives.tsx +3 -2
- package/src/widgets/schema-editor/editor/Editable.tsx +1 -1
- package/lib/features/document-viewer/UniversalDocumentViewer.d.ts +0 -73
- package/lib/features/document-viewer/UniversalDocumentViewer.d.ts.map +0 -1
- package/lib/features/document-viewer/UniversalDocumentViewer.js +0 -415
- package/lib/features/document-viewer/UniversalDocumentViewer.js.map +0 -1
- package/lib/features/document-viewer/index.d.ts +0 -2
- package/lib/features/document-viewer/index.d.ts.map +0 -1
- package/lib/features/document-viewer/index.js +0 -2
- package/lib/features/document-viewer/index.js.map +0 -1
- package/src/features/document-viewer/UniversalDocumentViewer.test.tsx +0 -123
- package/src/features/document-viewer/UniversalDocumentViewer.tsx +0 -746
- package/src/features/document-viewer/index.ts +0 -1
- package/src/session/auth/composable.test.ts +0 -79
|
@@ -1,31 +1,35 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
-
import { AgentMessageType, } from '@vertesia/common';
|
|
2
|
+
import { AgentMessageType, normalizeAgentToolApprovalMode, } from '@vertesia/common';
|
|
3
3
|
import { FusionFragmentProvider } from '@vertesia/fusion-ux';
|
|
4
4
|
import { Button, cn, insertNewlineAtCursor, MessageBox, Modal, ModalBody, ModalFooter, ModalTitle, Spinner, Textarea, useToast, } from '@vertesia/ui/core';
|
|
5
5
|
import { useUITranslation } from '@vertesia/ui/i18n';
|
|
6
6
|
import { useUserSession } from '@vertesia/ui/session';
|
|
7
7
|
import { ArrowUpIcon, Bot, CheckCircle, Cpu, FileTextIcon, UploadIcon, XIcon } from 'lucide-react';
|
|
8
8
|
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
9
|
+
import { McpConnectionsActionMenu } from '../../oauth/McpConnectionsButton.js';
|
|
10
|
+
import { AgentApprovalModeSelector } from './AgentApprovalModeSelector';
|
|
9
11
|
import { AgentChatPlaybackControls } from './AgentChatPlaybackControls';
|
|
10
12
|
import { AgentRequestInputOverlay } from './AgentRequestInputOverlay';
|
|
11
13
|
import { AgentRightPanel } from './AgentRightPanel.js';
|
|
12
14
|
import { AnimatedThinkingDots, PulsatingCircle } from './AnimatedThinkingDots';
|
|
15
|
+
import { extractFilesFromClipboard } from './clipboardFiles.js';
|
|
13
16
|
import { useAgentPlans } from './hooks/useAgentPlans.js';
|
|
14
17
|
import { useAgentStream } from './hooks/useAgentStream.js';
|
|
15
18
|
import { useDocumentPanel } from './hooks/useDocumentPanel.js';
|
|
16
19
|
import { useFileProcessing } from './hooks/useFileProcessing.js';
|
|
17
20
|
import { ImageLightboxProvider } from './ImageLightbox';
|
|
21
|
+
import { ActiveWorkstreamsSummary } from './ModernAgentOutput/ActiveWorkstreamsSummary';
|
|
18
22
|
import AllMessagesMixed from './ModernAgentOutput/AllMessagesMixed';
|
|
19
23
|
import Header from './ModernAgentOutput/Header';
|
|
20
24
|
import MessageInput from './ModernAgentOutput/MessageInput';
|
|
21
25
|
import { getPendingRequestInputMessage } from './ModernAgentOutput/requestInputMessages';
|
|
22
|
-
import { getConversationUrl, getWorkstreamId, isInProgress } from './ModernAgentOutput/utils';
|
|
26
|
+
import { debugAgentChat, filterMessagesForActiveWorkstream, getConversationUrl, getWorkstreamId, isInProgress, } from './ModernAgentOutput/utils';
|
|
23
27
|
import { createPlaybackState, getPlaybackCursorIndex, isAgentChatPlaybackAvailable, isAgentChatPlaybackEnabled, } from './playback';
|
|
24
28
|
import { SkillWidgetProvider } from './SkillWidgetProvider';
|
|
25
29
|
import { ArtifactUrlCacheProvider } from './useArtifactUrlCache.js';
|
|
26
30
|
import { VegaLiteChart } from './VegaLiteChart';
|
|
27
31
|
import { ThinkingMessages } from './WaitingMessages';
|
|
28
|
-
import { getWorkstreamLaunchDetails, getWorkstreamLifecycleStatus, isWorkstreamInternalResultMessage,
|
|
32
|
+
import { getWorkstreamDisplayName, getWorkstreamLaunchDetails, getWorkstreamLifecycleStatus, isWorkstreamInternalResultMessage, } from './workstreams.js';
|
|
29
33
|
const EMPTY_STREAMING_MESSAGES = new Map();
|
|
30
34
|
function getTimestampMs(timestamp) {
|
|
31
35
|
if (typeof timestamp === 'number')
|
|
@@ -35,46 +39,216 @@ function getTimestampMs(timestamp) {
|
|
|
35
39
|
const parsed = new Date(timestamp).getTime();
|
|
36
40
|
return Number.isFinite(parsed) ? parsed : Date.now();
|
|
37
41
|
}
|
|
38
|
-
function
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
if (isWorkstreamInternalResultMessage(message))
|
|
42
|
+
function isActiveWorkstreamStatus(status) {
|
|
43
|
+
return status === 'running' || status === 'canceling';
|
|
44
|
+
}
|
|
45
|
+
function isTerminalWorkstreamStatus(status) {
|
|
46
|
+
return !isActiveWorkstreamStatus(status);
|
|
47
|
+
}
|
|
48
|
+
function getNumberDetail(value) {
|
|
49
|
+
return typeof value === 'number' && Number.isFinite(value) ? value : undefined;
|
|
50
|
+
}
|
|
51
|
+
function toContextWindowUsage(messages) {
|
|
52
|
+
for (let index = messages.length - 1; index >= 0; index--) {
|
|
53
|
+
const details = messages[index].details;
|
|
54
|
+
if (!details)
|
|
52
55
|
continue;
|
|
53
|
-
const
|
|
54
|
-
|
|
56
|
+
const tokenUsage = details.token_usage;
|
|
57
|
+
const usedTokens = getNumberDetail(tokenUsage?.total);
|
|
58
|
+
const checkpointTokens = getNumberDetail(details.checkpoint_threshold) ?? getNumberDetail(details.checkpoint_at);
|
|
59
|
+
if (typeof usedTokens !== 'number' || typeof checkpointTokens !== 'number' || checkpointTokens <= 0) {
|
|
55
60
|
continue;
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
return Array.from(latestByWorkstream.entries())
|
|
59
|
-
.filter(([, message]) => {
|
|
60
|
-
if ([AgentMessageType.COMPLETE, AgentMessageType.IDLE].includes(message.type))
|
|
61
|
-
return false;
|
|
62
|
-
return !isWorkstreamTerminalMessage(message);
|
|
63
|
-
})
|
|
64
|
-
.map(([workstreamId, message]) => {
|
|
65
|
-
const launch = launchesByWorkstream.get(workstreamId);
|
|
61
|
+
}
|
|
62
|
+
const usedPercent = Math.max(0, Math.min(100, Math.round((usedTokens / checkpointTokens) * 100)));
|
|
66
63
|
return {
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
deadline_ms: 0,
|
|
72
|
-
remaining_ms: 0,
|
|
73
|
-
status: getWorkstreamLifecycleStatus(message) ?? 'running',
|
|
74
|
-
child_workflow_id: launch?.child_workflow_id,
|
|
75
|
-
child_workflow_run_id: launch?.child_workflow_run_id,
|
|
64
|
+
usedTokens,
|
|
65
|
+
checkpointTokens,
|
|
66
|
+
usedPercent,
|
|
67
|
+
remainingPercent: Math.max(0, 100 - usedPercent),
|
|
76
68
|
};
|
|
69
|
+
}
|
|
70
|
+
return undefined;
|
|
71
|
+
}
|
|
72
|
+
function mergePreservingTerminalStatus(existing, next) {
|
|
73
|
+
if (!isTerminalWorkstreamStatus(existing.status) || !isActiveWorkstreamStatus(next.status)) {
|
|
74
|
+
return { ...existing, ...next };
|
|
75
|
+
}
|
|
76
|
+
return {
|
|
77
|
+
...existing,
|
|
78
|
+
interaction: existing.interaction ?? next.interaction,
|
|
79
|
+
elapsed_ms: Math.max(existing.elapsed_ms, next.elapsed_ms),
|
|
80
|
+
deadline_ms: Math.max(existing.deadline_ms, next.deadline_ms),
|
|
81
|
+
remaining_ms: 0,
|
|
82
|
+
phase: existing.phase ?? next.phase,
|
|
83
|
+
child_workflow_id: existing.child_workflow_id ?? next.child_workflow_id,
|
|
84
|
+
child_workflow_run_id: existing.child_workflow_run_id ?? next.child_workflow_run_id,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
function getWorkstreamMessageDetails(message) {
|
|
88
|
+
const details = message.details;
|
|
89
|
+
const workstreamId = typeof details?.workstream_id === 'string' && details.workstream_id.trim()
|
|
90
|
+
? details.workstream_id
|
|
91
|
+
: getWorkstreamId(message);
|
|
92
|
+
if (workstreamId === 'main' || workstreamId === 'all')
|
|
93
|
+
return null;
|
|
94
|
+
return {
|
|
95
|
+
workstreamId,
|
|
96
|
+
launchId: typeof details?.launch_id === 'string' ? details.launch_id : undefined,
|
|
97
|
+
interaction: typeof details?.interaction === 'string' ? details.interaction : undefined,
|
|
98
|
+
childWorkflowId: typeof details?.child_workflow_id === 'string' ? details.child_workflow_id : undefined,
|
|
99
|
+
childWorkflowRunId: typeof details?.child_workflow_run_id === 'string' ? details.child_workflow_run_id : undefined,
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
function isWorkstreamActivityFailureMessage(message) {
|
|
103
|
+
if (message.type !== AgentMessageType.ERROR)
|
|
104
|
+
return false;
|
|
105
|
+
const details = message.details;
|
|
106
|
+
if (details?.event_class !== 'activity')
|
|
107
|
+
return false;
|
|
108
|
+
if (details.workstream_event)
|
|
109
|
+
return false;
|
|
110
|
+
return !(details.tool ||
|
|
111
|
+
details.tool_status ||
|
|
112
|
+
details.tool_run_id ||
|
|
113
|
+
details.activity_group_id ||
|
|
114
|
+
details.tool_event);
|
|
115
|
+
}
|
|
116
|
+
function ensureWorkstreamRecord(records, latestKeyByWorkstream, workstreamId, launchId, timestamp, order) {
|
|
117
|
+
if (launchId) {
|
|
118
|
+
const previousKey = latestKeyByWorkstream.get(workstreamId);
|
|
119
|
+
if (previousKey?.startsWith('message-derived:')) {
|
|
120
|
+
const previous = records.get(previousKey);
|
|
121
|
+
if (previous) {
|
|
122
|
+
records.delete(previousKey);
|
|
123
|
+
records.set(launchId, {
|
|
124
|
+
...previous,
|
|
125
|
+
launch_id: launchId,
|
|
126
|
+
updated_at: Math.max(previous.updated_at, timestamp),
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
latestKeyByWorkstream.set(workstreamId, launchId);
|
|
131
|
+
}
|
|
132
|
+
const key = launchId ?? latestKeyByWorkstream.get(workstreamId) ?? `message-derived:${workstreamId}`;
|
|
133
|
+
const existing = records.get(key);
|
|
134
|
+
if (existing)
|
|
135
|
+
return existing;
|
|
136
|
+
const record = {
|
|
137
|
+
workstream_id: workstreamId,
|
|
138
|
+
launch_id: key,
|
|
139
|
+
elapsed_ms: 0,
|
|
140
|
+
deadline_ms: 0,
|
|
141
|
+
remaining_ms: 0,
|
|
142
|
+
status: 'running',
|
|
143
|
+
started_at: timestamp,
|
|
144
|
+
updated_at: timestamp,
|
|
145
|
+
order,
|
|
146
|
+
};
|
|
147
|
+
records.set(key, record);
|
|
148
|
+
if (!latestKeyByWorkstream.has(workstreamId))
|
|
149
|
+
latestKeyByWorkstream.set(workstreamId, key);
|
|
150
|
+
return record;
|
|
151
|
+
}
|
|
152
|
+
function deriveWorkstreamsFromMessages(messages) {
|
|
153
|
+
const records = new Map();
|
|
154
|
+
const latestKeyByWorkstream = new Map();
|
|
155
|
+
messages.forEach((message, order) => {
|
|
156
|
+
const timestamp = getTimestampMs(message.timestamp);
|
|
157
|
+
const details = getWorkstreamMessageDetails(message);
|
|
158
|
+
const launchDetails = getWorkstreamLaunchDetails(message);
|
|
159
|
+
const workstreamId = launchDetails?.workstreamId ?? details?.workstreamId;
|
|
160
|
+
if (!workstreamId)
|
|
161
|
+
return;
|
|
162
|
+
const launchId = launchDetails?.launchId ?? details?.launchId;
|
|
163
|
+
const isInternalResult = isWorkstreamInternalResultMessage(message);
|
|
164
|
+
if (!launchDetails && !launchId && isInternalResult && !latestKeyByWorkstream.has(workstreamId))
|
|
165
|
+
return;
|
|
166
|
+
const record = ensureWorkstreamRecord(records, latestKeyByWorkstream, workstreamId, launchId, timestamp, order);
|
|
167
|
+
if (launchDetails) {
|
|
168
|
+
record.interaction = launchDetails.interaction ?? record.interaction;
|
|
169
|
+
record.child_workflow_id = launchDetails.childWorkflowId ?? record.child_workflow_id;
|
|
170
|
+
record.child_workflow_run_id = launchDetails.childWorkflowRunId ?? record.child_workflow_run_id;
|
|
171
|
+
record.status = 'running';
|
|
172
|
+
}
|
|
173
|
+
else {
|
|
174
|
+
record.interaction = details?.interaction ?? record.interaction;
|
|
175
|
+
record.child_workflow_id = details?.childWorkflowId ?? record.child_workflow_id;
|
|
176
|
+
record.child_workflow_run_id = details?.childWorkflowRunId ?? record.child_workflow_run_id;
|
|
177
|
+
}
|
|
178
|
+
const lifecycleStatus = getWorkstreamLifecycleStatus(message);
|
|
179
|
+
if (lifecycleStatus) {
|
|
180
|
+
record.status = lifecycleStatus;
|
|
181
|
+
}
|
|
182
|
+
else if (!isInternalResult) {
|
|
183
|
+
if (isWorkstreamActivityFailureMessage(message)) {
|
|
184
|
+
record.status = 'failed';
|
|
185
|
+
}
|
|
186
|
+
else if (message.type === AgentMessageType.COMPLETE || message.type === AgentMessageType.IDLE) {
|
|
187
|
+
record.status = 'completed';
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
if (isInternalResult)
|
|
191
|
+
return;
|
|
192
|
+
record.updated_at = Math.max(record.updated_at, timestamp);
|
|
193
|
+
if (isActiveWorkstreamStatus(record.status)) {
|
|
194
|
+
record.elapsed_ms = Math.max(record.elapsed_ms, timestamp - record.started_at);
|
|
195
|
+
}
|
|
196
|
+
else {
|
|
197
|
+
record.elapsed_ms = Math.max(record.elapsed_ms, timestamp - record.started_at);
|
|
198
|
+
record.remaining_ms = 0;
|
|
199
|
+
}
|
|
77
200
|
});
|
|
201
|
+
return Array.from(records.values())
|
|
202
|
+
.sort((a, b) => {
|
|
203
|
+
const activeDelta = Number(!isActiveWorkstreamStatus(a.status)) - Number(!isActiveWorkstreamStatus(b.status));
|
|
204
|
+
if (activeDelta !== 0)
|
|
205
|
+
return activeDelta;
|
|
206
|
+
if (isActiveWorkstreamStatus(a.status))
|
|
207
|
+
return a.order - b.order;
|
|
208
|
+
return b.updated_at - a.updated_at || a.order - b.order;
|
|
209
|
+
})
|
|
210
|
+
.map(({ started_at, updated_at, order, ...workstream }) => workstream);
|
|
211
|
+
}
|
|
212
|
+
function activeWorkstreamEntryToInfo(ws) {
|
|
213
|
+
return {
|
|
214
|
+
workstream_id: ws.workstream_id,
|
|
215
|
+
launch_id: ws.launch_id,
|
|
216
|
+
interaction: ws.interaction,
|
|
217
|
+
elapsed_ms: ws.elapsed_ms,
|
|
218
|
+
deadline_ms: ws.deadline_ms,
|
|
219
|
+
remaining_ms: Math.max(0, ws.deadline_ms - ws.elapsed_ms),
|
|
220
|
+
status: ws.status,
|
|
221
|
+
phase: ws.latest_progress?.phase,
|
|
222
|
+
child_workflow_id: ws.child_workflow_id,
|
|
223
|
+
child_workflow_run_id: ws.child_workflow_run_id,
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
function completedWorkstreamEntryToInfo(ws) {
|
|
227
|
+
return {
|
|
228
|
+
workstream_id: ws.workstream_id,
|
|
229
|
+
launch_id: ws.launch_id,
|
|
230
|
+
interaction: ws.interaction,
|
|
231
|
+
elapsed_ms: ws.duration_ms ?? 0,
|
|
232
|
+
deadline_ms: 0,
|
|
233
|
+
remaining_ms: 0,
|
|
234
|
+
status: ws.status,
|
|
235
|
+
phase: ws.last_progress?.phase,
|
|
236
|
+
child_workflow_id: ws.child_workflow_id,
|
|
237
|
+
child_workflow_run_id: ws.child_workflow_run_id,
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
function mergeWorkstreamInfo(workstreams, next) {
|
|
241
|
+
const existingIndex = workstreams.findIndex((ws) => ws.launch_id === next.launch_id);
|
|
242
|
+
if (existingIndex >= 0) {
|
|
243
|
+
workstreams[existingIndex] = mergePreservingTerminalStatus(workstreams[existingIndex], next);
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
246
|
+
const fallbackIndex = workstreams.findIndex((ws) => ws.workstream_id === next.workstream_id && ws.launch_id.startsWith('message-derived:'));
|
|
247
|
+
if (fallbackIndex >= 0 && !next.launch_id.startsWith('message-derived:')) {
|
|
248
|
+
workstreams[fallbackIndex] = mergePreservingTerminalStatus(workstreams[fallbackIndex], next);
|
|
249
|
+
return;
|
|
250
|
+
}
|
|
251
|
+
workstreams.push(next);
|
|
78
252
|
}
|
|
79
253
|
function formatCompactDuration(seconds) {
|
|
80
254
|
if (seconds < 60)
|
|
@@ -197,12 +371,13 @@ function EmptyState() {
|
|
|
197
371
|
}
|
|
198
372
|
// Start workflow view - allows initiating a new agent conversation
|
|
199
373
|
// Files can be staged locally before workflow starts, then uploaded when the workflow is created
|
|
200
|
-
function StartWorkflowView({ initialMessage, startWorkflow, onClose, isModal = false, fullWidth = false, placeholder, startButtonText, title,
|
|
374
|
+
function StartWorkflowView({ initialMessage, interactive = true, startWorkflow, onClose, isModal = false, fullWidth = false, placeholder, startButtonText, title,
|
|
201
375
|
// Attachment callback - used to include existing document attachments in the first message
|
|
202
376
|
getAttachedDocs, onAttachmentsSent,
|
|
203
377
|
// File upload props
|
|
204
|
-
acceptedFileTypes, maxFiles = 5, hideHeader = false, hideFileUpload = false, hideObjectLinking, headerVariant, inputContainerClassName, inputClassName, className, allowWorkflowControl, }) {
|
|
378
|
+
acceptedFileTypes, maxFiles = 5, hideHeader = false, hideFileUpload = false, hideObjectLinking, headerVariant, inputContainerClassName, inputClassName, className, allowWorkflowControl, initialToolApprovalMode, }) {
|
|
205
379
|
const { t } = useUITranslation();
|
|
380
|
+
const canStageFiles = !hideFileUpload;
|
|
206
381
|
const resolvedPlaceholder = placeholder ?? t('agent.typeYourMessage');
|
|
207
382
|
const resolvedStartButtonText = startButtonText ?? t('agent.startAgent');
|
|
208
383
|
const resolvedTitle = title ?? t('agent.startNewConversation');
|
|
@@ -212,12 +387,12 @@ acceptedFileTypes, maxFiles = 5, hideHeader = false, hideFileUpload = false, hid
|
|
|
212
387
|
const [startedAgentRunId, setStartedAgentRunId] = useState(null);
|
|
213
388
|
const [pendingStartMessage, setPendingStartMessage] = useState(null);
|
|
214
389
|
const [pendingStartTimestamp, setPendingStartTimestamp] = useState(null);
|
|
390
|
+
const [toolApprovalMode, setToolApprovalMode] = useState(() => normalizeAgentToolApprovalMode(initialToolApprovalMode, interactive));
|
|
215
391
|
const toast = useToast();
|
|
216
392
|
const inputRef = useRef(null);
|
|
217
393
|
const fileInputRef = useRef(null);
|
|
218
394
|
// Staged files - stored locally until workflow starts
|
|
219
395
|
const [stagedFiles, setStagedFiles] = useState([]);
|
|
220
|
-
const canStageFiles = !hideFileUpload;
|
|
221
396
|
// Drag and drop state
|
|
222
397
|
const [isDragOver, setIsDragOver] = useState(false);
|
|
223
398
|
const dragCounterRef = useRef(0);
|
|
@@ -263,6 +438,17 @@ acceptedFileTypes, maxFiles = 5, hideHeader = false, hideFileUpload = false, hid
|
|
|
263
438
|
});
|
|
264
439
|
}
|
|
265
440
|
}, [maxFiles, canStageFiles]);
|
|
441
|
+
// Paste handler for files — mirrors MessageInput.handlePaste so the start
|
|
442
|
+
// screen and the live chat both accept pasted clipboard images/files. Files
|
|
443
|
+
// are staged locally here; they get uploaded when the workflow starts.
|
|
444
|
+
const handlePaste = useCallback((e) => {
|
|
445
|
+
if (!canStageFiles)
|
|
446
|
+
return;
|
|
447
|
+
const files = extractFilesFromClipboard(e.clipboardData?.items);
|
|
448
|
+
if (files.length > 0) {
|
|
449
|
+
setStagedFiles((prev) => [...prev, ...files].slice(0, maxFiles));
|
|
450
|
+
}
|
|
451
|
+
}, [canStageFiles, maxFiles]);
|
|
266
452
|
const handleFileInputChange = useCallback((e) => {
|
|
267
453
|
if (e.target.files && e.target.files.length > 0) {
|
|
268
454
|
const filesArray = Array.from(e.target.files);
|
|
@@ -320,7 +506,7 @@ acceptedFileTypes, maxFiles = 5, hideHeader = false, hideFileUpload = false, hid
|
|
|
320
506
|
}
|
|
321
507
|
setPendingStartMessage(messageContent);
|
|
322
508
|
setPendingStartTimestamp(Date.now());
|
|
323
|
-
const newRun = await startWorkflow(messageContent);
|
|
509
|
+
const newRun = await startWorkflow(messageContent, { tool_approval_mode: toolApprovalMode });
|
|
324
510
|
if (newRun) {
|
|
325
511
|
const agentId = newRun.agent_run_id;
|
|
326
512
|
// Upload staged files to the new run's artifact space and signal agent
|
|
@@ -429,11 +615,9 @@ acceptedFileTypes, maxFiles = 5, hideHeader = false, hideFileUpload = false, hid
|
|
|
429
615
|
inputContainerClassName,
|
|
430
616
|
inputClassName,
|
|
431
617
|
className,
|
|
432
|
-
allowWorkflowControl, agentRunId: startedAgentRunId, title: title, pendingStartMessage: pendingStartMessage ?? undefined, pendingStartTimestamp: pendingStartTimestamp ?? undefined }));
|
|
618
|
+
allowWorkflowControl, agentRunId: startedAgentRunId, title: title, pendingStartMessage: pendingStartMessage ?? undefined, pendingStartTimestamp: pendingStartTimestamp ?? undefined, initialToolApprovalMode: toolApprovalMode }));
|
|
433
619
|
}
|
|
434
|
-
return (_jsx("div", { className: cn('flex h-full flex-col items-center bg-background', className), children: _jsxs("div", { className: cn('relative flex h-full w-full flex-col overflow-hidden border-0', fullWidth ? '' : 'max-w-4xl'), onDragEnter: canStageFiles ? handleDragEnter : undefined, onDragOver: canStageFiles ? handleDragOver : undefined, onDragLeave: canStageFiles ? handleDragLeave : undefined, onDrop: canStageFiles ? handleDrop : undefined, children: [canStageFiles && isDragOver && (_jsx("div", { className: "absolute inset-0 flex items-center justify-center bg-info-background z-50 pointer-events-none rounded-lg", children: _jsxs("div", { className: "text-info font-medium flex items-center gap-2 text-lg", children: [_jsx(UploadIcon, { className: "size-6" }), "Drop files to stage for upload"] }) })), canStageFiles && (_jsx("input", { ref: fileInputRef, type: "file", multiple: true, accept: acceptedFileTypes, onChange: handleFileInputChange, className: "hidden" })), !hideHeader && (_jsxs("div", { className: "flex items-center justify-between border-b border-border/60 bg-background px-3 py-2", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("div", { className: "p-1", children: _jsx(Cpu, { className: "size-3.5 text-muted" }) }), _jsx("span", { className: "text-sm font-medium text-foreground", children: resolvedTitle })] }), onClose && !isModal && (_jsx(Button, { size: "xs", variant: "ghost", onClick: onClose, "aria-label": t('agent.close'), title: t('agent.close'), className: "text-muted hover:text-foreground", children: _jsx(XIcon, { className: "size-4" }) }))] })), _jsx("div", { className: "flex flex-1 flex-col items-center justify-end overflow-y-auto bg-background px-4", children: pendingStartMessage && pendingStartTimestamp ? (_jsx(PendingStartConversation, { message: pendingStartMessage, startedAt: pendingStartTimestamp })) : (_jsx("div", { className: "mx-auto flex min-h-full w-full max-w-3xl flex-col justify-end py-8", children: initialMessage && (_jsx("div", { className: "text-[15px] leading-relaxed text-foreground/80", children: initialMessage })) })) }),
|
|
435
|
-
? t('agent.filesStagedCount', { count: stagedFiles.length })
|
|
436
|
-
: t('agent.enterToSend') })] })] }) }));
|
|
620
|
+
return (_jsx("div", { className: cn('flex h-full flex-col items-center bg-background', className), children: _jsxs("div", { className: cn('relative flex h-full w-full flex-col overflow-hidden border-0', fullWidth ? '' : 'max-w-4xl'), onDragEnter: canStageFiles ? handleDragEnter : undefined, onDragOver: canStageFiles ? handleDragOver : undefined, onDragLeave: canStageFiles ? handleDragLeave : undefined, onDrop: canStageFiles ? handleDrop : undefined, children: [canStageFiles && isDragOver && (_jsx("div", { className: "absolute inset-0 flex items-center justify-center bg-info-background z-50 pointer-events-none rounded-lg", children: _jsxs("div", { className: "text-info font-medium flex items-center gap-2 text-lg", children: [_jsx(UploadIcon, { className: "size-6" }), "Drop files to stage for upload"] }) })), canStageFiles && (_jsx("input", { ref: fileInputRef, type: "file", multiple: true, accept: acceptedFileTypes, onChange: handleFileInputChange, className: "hidden" })), !hideHeader && (_jsxs("div", { className: "flex items-center justify-between border-b border-border/60 bg-background px-3 py-2", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("div", { className: "p-1", children: _jsx(Cpu, { className: "size-3.5 text-muted" }) }), _jsx("span", { className: "text-sm font-medium text-foreground", children: resolvedTitle })] }), onClose && !isModal && (_jsx(Button, { size: "xs", variant: "ghost", onClick: onClose, "aria-label": t('agent.close'), title: t('agent.close'), className: "text-muted hover:text-foreground", children: _jsx(XIcon, { className: "size-4" }) }))] })), _jsx("div", { className: "flex flex-1 flex-col items-center justify-end overflow-y-auto bg-background px-4", children: pendingStartMessage && pendingStartTimestamp ? (_jsx(PendingStartConversation, { message: pendingStartMessage, startedAt: pendingStartTimestamp })) : (_jsx("div", { className: "mx-auto flex min-h-full w-full max-w-3xl flex-col justify-end py-8", children: initialMessage && (_jsx("div", { className: "text-[15px] leading-relaxed text-foreground/80", children: initialMessage })) })) }), _jsx("div", { className: "shrink-0 bg-background px-4 pb-safe-area-4 pt-2", children: _jsxs("div", { className: cn('mx-auto flex max-w-3xl flex-col gap-3 rounded-2xl border border-border/70 bg-mixer-muted/15 p-3 shadow-lg shadow-black/5', inputContainerClassName), children: [canStageFiles && stagedFiles.length > 0 && (_jsx("div", { className: "flex flex-wrap gap-2", children: stagedFiles.map((file, index) => (_jsxs("div", { className: "flex items-center gap-1.5 rounded-md bg-attention/10 px-2 py-1 text-sm text-attention", title: t('agent.fileStagedTooltip'), children: [_jsx(FileTextIcon, { className: "size-3.5" }), _jsx("span", { className: "max-w-[120px] truncate", children: file.name }), _jsx("span", { className: "text-xs opacity-70", children: t('agent.staged') }), _jsx(Button, { variant: "unstyled", "aria-label": `Remove staged file ${file.name}`, onClick: () => removeStagedFile(index), className: "ms-1 rounded p-0.5 hover:bg-attention/20", children: _jsx(XIcon, { className: "size-3" }) })] }, `${file.name}-${file.size}-${file.lastModified}`))) })), _jsx(Textarea, { ref: inputRef, value: inputValue, onChange: (e) => setInputValue(e.target.value), onKeyDown: handleKeyDown, onPaste: handlePaste, placeholder: resolvedPlaceholder, disabled: isSending, rows: 2, className: cn('min-h-[72px] resize-none overflow-hidden border-0 bg-transparent px-0 py-0 text-sm leading-6 shadow-none focus-visible:ring-0', inputClassName), style: { minHeight: '72px', maxHeight: '200px' } }), _jsxs("div", { className: "flex items-center justify-between gap-3", children: [_jsxs("div", { className: "flex min-w-0 items-center gap-2", children: [canStageFiles && (_jsx(Button, { variant: "ghost", size: "icon", onClick: () => fileInputRef.current?.click(), disabled: isSending || stagedFiles.length >= maxFiles, "aria-label": t('agent.upload'), className: "rounded-full text-muted", title: t('agent.upload'), children: _jsx(UploadIcon, { className: "size-4" }) })), interactive && (_jsx(AgentApprovalModeSelector, { mode: toolApprovalMode, onChange: setToolApprovalMode, disabled: isSending }))] }), _jsx(Button, { onClick: startWorkflowWithMessage, disabled: !inputValue.trim() || isSending, variant: "ghost", size: "icon", className: cn('size-9 rounded-full border border-border/60 bg-foreground text-background shadow-sm', 'hover:bg-foreground/90 hover:text-background', 'disabled:bg-mixer-muted/25 disabled:text-muted disabled:opacity-100'), title: resolvedStartButtonText, "aria-label": resolvedStartButtonText, children: isSending ? _jsx(Spinner, { size: "sm" }) : _jsx(ArrowUpIcon, { className: "size-4" }) })] })] }) })] }) }));
|
|
437
621
|
}
|
|
438
622
|
// Inner component that handles the agent conversation - similar to ModernAgentOutput
|
|
439
623
|
function ModernAgentConversationInner({ agentRunId, title, interactive = true, onClose, isModal = false, fullWidth = false, placeholder, resetWorkflow, onRestart, onClone, onShowDetails, allowWorkflowControl = true,
|
|
@@ -472,14 +656,14 @@ streamingMessageClassNames,
|
|
|
472
656
|
// BatchProgressPanel className overrides
|
|
473
657
|
batchProgressPanelClassNames,
|
|
474
658
|
// AllMessagesMixed className overrides
|
|
475
|
-
workingIndicatorClassName, messageListClassName, StoreLinkComponent, CollectionLinkComponent, prependFriendlyMessage, initialRequestData, initialRequestSchema, initialRequestTitle, initialRequestTemplate, payloadContent, conversationContent, conversationTab = false, pendingStartMessage, pendingStartTimestamp, enablePlayback, showPlaybackToggle = true, }) {
|
|
659
|
+
workingIndicatorClassName, messageListClassName, StoreLinkComponent, CollectionLinkComponent, prependFriendlyMessage, initialRequestData, initialRequestSchema, initialRequestTitle, initialRequestTemplate, payloadContent, conversationContent, conversationTab = false, pendingStartMessage, pendingStartTimestamp, initialToolApprovalMode, enablePlayback, showPlaybackToggle = true, }) {
|
|
476
660
|
const { t } = useUITranslation();
|
|
477
661
|
const { client } = useUserSession();
|
|
478
662
|
const toast = useToast();
|
|
479
663
|
// ────────────────────────────────────────────
|
|
480
664
|
// Extracted hooks
|
|
481
665
|
// ────────────────────────────────────────────
|
|
482
|
-
const { messages, streamingMessages, isCompleted, debugChunkFlash, addOptimisticMessage,
|
|
666
|
+
const { messages, streamingMessages, isCompleted, initialHistoryStatus, debugChunkFlash, addOptimisticMessage, updateOptimisticMessageStatus, reconnect: reconnectStream, agentRunStatus, workflowRunId, serverFileUpdates, } = useAgentStream(client, agentRunId);
|
|
483
667
|
const { plans, activePlanIndex, setActivePlanIndex, workstreamStatusMap, showInput, showSlidingPanel, setShowSlidingPanel, } = useAgentPlans(messages, interactive, isModal);
|
|
484
668
|
const { openDocuments, activeDocumentId, isDocPanelOpen, docRefreshKey, closeDocPanel: handleCloseDocPanel, closeDocument: handleCloseDocument, selectDocument, openDocInPanel, updateDocumentTitle, } = useDocumentPanel(messages);
|
|
485
669
|
const { processingFiles, hasProcessingFiles, handleFileUpload, removeProcessingFile } = useFileProcessing(client, agentRunId, serverFileUpdates, toast);
|
|
@@ -494,6 +678,7 @@ workingIndicatorClassName, messageListClassName, StoreLinkComponent, CollectionL
|
|
|
494
678
|
const conversationRef = useRef(null);
|
|
495
679
|
const conversationLayoutRef = useRef(null);
|
|
496
680
|
const [isSending, setIsSending] = useState(false);
|
|
681
|
+
const [isCompactingContext, setIsCompactingContext] = useState(false);
|
|
497
682
|
const [internalViewMode, setInternalViewMode] = useState('sliding');
|
|
498
683
|
const viewMode = controlledViewMode ?? internalViewMode;
|
|
499
684
|
const handleViewModeChange = useCallback((mode) => {
|
|
@@ -506,14 +691,23 @@ workingIndicatorClassName, messageListClassName, StoreLinkComponent, CollectionL
|
|
|
506
691
|
}, [onViewModeChangeProp]);
|
|
507
692
|
const [isStopping, setIsStopping] = useState(false);
|
|
508
693
|
const [isDragOver, setIsDragOver] = useState(false);
|
|
694
|
+
const [activeWorkstream, setActiveWorkstream] = useState('all');
|
|
509
695
|
const [playbackCursor, setPlaybackCursor] = useState('live');
|
|
510
696
|
const [isPlaybackToggleEnabled, setIsPlaybackToggleEnabled] = useState(false);
|
|
511
697
|
const [playbackScrollRequestId, setPlaybackScrollRequestId] = useState(0);
|
|
512
|
-
const [
|
|
513
|
-
const [
|
|
698
|
+
const [queriedActiveWorkstreams, setQueriedActiveWorkstreams] = useState([]);
|
|
699
|
+
const [queriedCompletedWorkstreams, setQueriedCompletedWorkstreams] = useState([]);
|
|
700
|
+
const [isWorkstreamQueryUnavailable, setIsWorkstreamQueryUnavailable] = useState(false);
|
|
701
|
+
const initialResolvedToolApprovalMode = useMemo(() => initialToolApprovalMode === undefined && interactive
|
|
702
|
+
? undefined
|
|
703
|
+
: normalizeAgentToolApprovalMode(initialToolApprovalMode, interactive), [initialToolApprovalMode, interactive]);
|
|
704
|
+
const [toolApprovalMode, setToolApprovalMode] = useState(initialResolvedToolApprovalMode);
|
|
514
705
|
const workstreamFetchFailedRef = useRef(false);
|
|
515
706
|
const dragCounterRef = useRef(0);
|
|
516
707
|
const pendingPlaybackScrollRef = useRef(false);
|
|
708
|
+
useEffect(() => {
|
|
709
|
+
setToolApprovalMode(initialResolvedToolApprovalMode);
|
|
710
|
+
}, [initialResolvedToolApprovalMode]);
|
|
517
711
|
// PERFORMANCE: Refs for values used inside useCallback to avoid re-creating the callback
|
|
518
712
|
const isSendingRef = useRef(isSending);
|
|
519
713
|
isSendingRef.current = isSending;
|
|
@@ -572,63 +766,125 @@ workingIndicatorClassName, messageListClassName, StoreLinkComponent, CollectionL
|
|
|
572
766
|
workstreamStatus: currentWorkstreamStatus,
|
|
573
767
|
};
|
|
574
768
|
}, [plans, activePlanIndex, workstreamStatusMap]);
|
|
575
|
-
const
|
|
769
|
+
const messageDerivedWorkstreams = useMemo(() => deriveWorkstreamsFromMessages(messages), [messages]);
|
|
576
770
|
const panelWorkstreams = useMemo(() => {
|
|
577
|
-
const
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
771
|
+
const merged = [...messageDerivedWorkstreams];
|
|
772
|
+
for (const ws of queriedCompletedWorkstreams) {
|
|
773
|
+
mergeWorkstreamInfo(merged, completedWorkstreamEntryToInfo(ws));
|
|
774
|
+
}
|
|
775
|
+
for (const ws of queriedActiveWorkstreams) {
|
|
776
|
+
mergeWorkstreamInfo(merged, activeWorkstreamEntryToInfo(ws));
|
|
777
|
+
}
|
|
778
|
+
return merged
|
|
779
|
+
.map((workstream, index) => ({ workstream, index }))
|
|
780
|
+
.sort((a, b) => {
|
|
781
|
+
const activeDelta = Number(!isActiveWorkstreamStatus(a.workstream.status)) -
|
|
782
|
+
Number(!isActiveWorkstreamStatus(b.workstream.status));
|
|
783
|
+
return activeDelta || a.index - b.index;
|
|
784
|
+
})
|
|
785
|
+
.map(({ workstream }) => workstream);
|
|
786
|
+
}, [messageDerivedWorkstreams, queriedActiveWorkstreams, queriedCompletedWorkstreams]);
|
|
787
|
+
const composerActiveWorkstreams = useMemo(() => panelWorkstreams.filter((ws) => isActiveWorkstreamStatus(ws.status)), [panelWorkstreams]);
|
|
788
|
+
const activeTaskCount = useMemo(() => composerActiveWorkstreams.filter((ws) => ws.status === 'running').length, [composerActiveWorkstreams]);
|
|
789
|
+
const activeWorkstreamDisplayName = useMemo(() => {
|
|
790
|
+
if (activeWorkstream === 'all')
|
|
791
|
+
return undefined;
|
|
792
|
+
const workstream = panelWorkstreams.find((ws) => ws.workstream_id === activeWorkstream || ws.launch_id === activeWorkstream);
|
|
793
|
+
if (!workstream)
|
|
794
|
+
return getWorkstreamDisplayName(activeWorkstream);
|
|
795
|
+
return getWorkstreamDisplayName(workstream.workstream_id, workstream.interaction);
|
|
796
|
+
}, [activeWorkstream, panelWorkstreams]);
|
|
797
|
+
const composerPlaceholder = useMemo(() => {
|
|
798
|
+
if (placeholder)
|
|
799
|
+
return placeholder;
|
|
800
|
+
if (activeWorkstreamDisplayName) {
|
|
801
|
+
return t('agent.messageMainAgentWhileViewingWorkstream', { workstream: activeWorkstreamDisplayName });
|
|
802
|
+
}
|
|
803
|
+
return undefined;
|
|
804
|
+
}, [activeWorkstreamDisplayName, placeholder, t]);
|
|
605
805
|
const canShowPlaybackToggle = showPlaybackToggle && enablePlayback === undefined && isAgentChatPlaybackAvailable();
|
|
606
806
|
const isPlaybackEnabled = enablePlayback ?? (isAgentChatPlaybackEnabled() || isPlaybackToggleEnabled);
|
|
607
|
-
const
|
|
807
|
+
const playbackSourceMessages = useMemo(() => {
|
|
808
|
+
const visibleMessages = hiddenMessageTypes?.length
|
|
809
|
+
? messages.filter((message) => !hiddenMessageTypes.includes(message.type))
|
|
810
|
+
: messages;
|
|
811
|
+
return filterMessagesForActiveWorkstream(visibleMessages, activeWorkstream);
|
|
812
|
+
}, [activeWorkstream, hiddenMessageTypes, messages]);
|
|
813
|
+
const playbackState = useMemo(() => createPlaybackState(playbackSourceMessages, playbackCursor, isPlaybackEnabled), [isPlaybackEnabled, playbackCursor, playbackSourceMessages]);
|
|
608
814
|
const clampedPlaybackCursor = playbackState.cursor;
|
|
609
815
|
const isPlaybackLive = playbackState.isLive;
|
|
816
|
+
const isPlaybackAtLatest = isPlaybackEnabled && !isPlaybackLive && playbackState.cursorIndex === playbackSourceMessages.length - 1;
|
|
610
817
|
const displayedMessages = playbackState.displayedMessages;
|
|
611
818
|
const displayedStreamingMessages = isPlaybackLive ? streamingMessages : EMPTY_STREAMING_MESSAGES;
|
|
819
|
+
const playbackDerivedWorkstreams = useMemo(() => deriveWorkstreamsFromMessages(displayedMessages), [displayedMessages]);
|
|
820
|
+
const playbackActiveWorkstreams = useMemo(() => playbackDerivedWorkstreams.filter((ws) => isActiveWorkstreamStatus(ws.status)), [playbackDerivedWorkstreams]);
|
|
612
821
|
const effectiveIsCompleted = useMemo(() => isCompleted || !isInProgress(messages), [isCompleted, messages]);
|
|
613
|
-
const displayedIsCompleted = isPlaybackLive ? effectiveIsCompleted : false;
|
|
822
|
+
const displayedIsCompleted = isPlaybackLive || isPlaybackAtLatest ? effectiveIsCompleted : false;
|
|
614
823
|
const pendingRequestInputMessage = useMemo(() => getPendingRequestInputMessage(displayedMessages), [displayedMessages]);
|
|
615
824
|
const shouldShowRequestInputOverlay = Boolean(pendingRequestInputMessage) && !isFailed;
|
|
616
825
|
const isViewingPlaybackHistory = isPlaybackEnabled && !isPlaybackLive;
|
|
617
|
-
const shouldShowLiveRequestInputOverlay = shouldShowRequestInputOverlay && !isViewingPlaybackHistory;
|
|
618
826
|
const shouldRenderLiveMessageInputArea = shouldRenderMessageInputArea && !isViewingPlaybackHistory;
|
|
827
|
+
const contextWindowUsage = useMemo(() => toContextWindowUsage(messages), [messages]);
|
|
828
|
+
// The run is still "alive" while it waits for user input (idle on ask_user), so keep the
|
|
829
|
+
// context-usage indicator visible then — it's only truly hidden once the run terminates.
|
|
830
|
+
const canCompactContext = allowWorkflowControl && !isWorkflowTerminal && isPlaybackLive && Boolean(contextWindowUsage);
|
|
831
|
+
useEffect(() => {
|
|
832
|
+
debugAgentChat('conversation render state', {
|
|
833
|
+
agentRunId,
|
|
834
|
+
messageCount: messages.length,
|
|
835
|
+
playbackMessageCount: playbackSourceMessages.length,
|
|
836
|
+
displayedMessageCount: displayedMessages.length,
|
|
837
|
+
streamingCount: streamingMessages.size,
|
|
838
|
+
displayedStreamingCount: displayedStreamingMessages.size,
|
|
839
|
+
initialHistoryStatus,
|
|
840
|
+
isCompleted,
|
|
841
|
+
effectiveIsCompleted,
|
|
842
|
+
displayedIsCompleted,
|
|
843
|
+
agentRunStatus,
|
|
844
|
+
effectiveWorkflowStatus,
|
|
845
|
+
isWorkflowTerminal,
|
|
846
|
+
playbackCursor: clampedPlaybackCursor,
|
|
847
|
+
isPlaybackEnabled,
|
|
848
|
+
isPlaybackLive,
|
|
849
|
+
isPlaybackAtLatest,
|
|
850
|
+
activeWorkstream,
|
|
851
|
+
showInitialRequest: initialHistoryStatus === 'empty' && messages.length === 0,
|
|
852
|
+
pendingStartVisible: messages.length === 0 && !effectiveIsCompleted && Boolean(pendingStartMessage),
|
|
853
|
+
});
|
|
854
|
+
}, [
|
|
855
|
+
activeWorkstream,
|
|
856
|
+
agentRunId,
|
|
857
|
+
agentRunStatus,
|
|
858
|
+
clampedPlaybackCursor,
|
|
859
|
+
displayedIsCompleted,
|
|
860
|
+
displayedMessages.length,
|
|
861
|
+
displayedStreamingMessages.size,
|
|
862
|
+
effectiveIsCompleted,
|
|
863
|
+
effectiveWorkflowStatus,
|
|
864
|
+
initialHistoryStatus,
|
|
865
|
+
isCompleted,
|
|
866
|
+
isPlaybackAtLatest,
|
|
867
|
+
isPlaybackEnabled,
|
|
868
|
+
isPlaybackLive,
|
|
869
|
+
isWorkflowTerminal,
|
|
870
|
+
messages.length,
|
|
871
|
+
pendingStartMessage,
|
|
872
|
+
playbackSourceMessages.length,
|
|
873
|
+
streamingMessages.size,
|
|
874
|
+
]);
|
|
619
875
|
const handleTogglePlayback = useCallback(() => {
|
|
620
876
|
setIsPlaybackToggleEnabled((prev) => !prev);
|
|
621
877
|
}, []);
|
|
622
878
|
const handleChangePlaybackCursor = useCallback((nextCursor) => {
|
|
623
|
-
const currentIndex = getPlaybackCursorIndex(clampedPlaybackCursor,
|
|
624
|
-
const nextIndex = getPlaybackCursorIndex(nextCursor,
|
|
879
|
+
const currentIndex = getPlaybackCursorIndex(clampedPlaybackCursor, playbackSourceMessages.length);
|
|
880
|
+
const nextIndex = getPlaybackCursorIndex(nextCursor, playbackSourceMessages.length);
|
|
625
881
|
const returningToLive = nextCursor === 'live' && clampedPlaybackCursor !== 'live';
|
|
626
882
|
if (isPlaybackEnabled && (nextIndex > currentIndex || returningToLive)) {
|
|
627
883
|
pendingPlaybackScrollRef.current = true;
|
|
628
884
|
setPlaybackScrollRequestId((requestId) => requestId + 1);
|
|
629
885
|
}
|
|
630
886
|
setPlaybackCursor(nextCursor);
|
|
631
|
-
}, [clampedPlaybackCursor, isPlaybackEnabled,
|
|
887
|
+
}, [clampedPlaybackCursor, isPlaybackEnabled, playbackSourceMessages.length]);
|
|
632
888
|
useEffect(() => {
|
|
633
889
|
if (!isPlaybackEnabled) {
|
|
634
890
|
if (playbackCursor !== 'live')
|
|
@@ -742,39 +998,76 @@ workingIndicatorClassName, messageListClassName, StoreLinkComponent, CollectionL
|
|
|
742
998
|
useEffect(() => {
|
|
743
999
|
onWorkstreamStatusChange?.(workstreamStatusMap);
|
|
744
1000
|
}, [workstreamStatusMap, onWorkstreamStatusChange]);
|
|
745
|
-
// Poll active workstreams from backend query for right-panel visibility and details.
|
|
746
1001
|
useEffect(() => {
|
|
747
|
-
|
|
1002
|
+
void agentRunId;
|
|
1003
|
+
workstreamFetchFailedRef.current = false;
|
|
1004
|
+
setIsWorkstreamQueryUnavailable(false);
|
|
1005
|
+
setQueriedActiveWorkstreams([]);
|
|
1006
|
+
setQueriedCompletedWorkstreams([]);
|
|
1007
|
+
}, [agentRunId]);
|
|
1008
|
+
// Poll the backend query only as live enrichment. Persisted messages remain the
|
|
1009
|
+
// source of truth for the right-panel history once a workflow can no longer be queried.
|
|
1010
|
+
useEffect(() => {
|
|
1011
|
+
const shouldPoll = initialHistoryStatus !== 'loading' &&
|
|
1012
|
+
!effectiveIsCompleted &&
|
|
1013
|
+
!isWorkflowTerminal &&
|
|
1014
|
+
!isWorkstreamQueryUnavailable;
|
|
1015
|
+
debugAgentChat('active workstreams poll state', {
|
|
1016
|
+
agentRunId,
|
|
1017
|
+
shouldPoll,
|
|
1018
|
+
initialHistoryStatus,
|
|
1019
|
+
effectiveIsCompleted,
|
|
1020
|
+
isWorkflowTerminal,
|
|
1021
|
+
isWorkstreamQueryUnavailable,
|
|
1022
|
+
});
|
|
748
1023
|
if (!shouldPoll) {
|
|
749
|
-
|
|
1024
|
+
setQueriedActiveWorkstreams((prev) => (prev.length === 0 ? prev : []));
|
|
750
1025
|
return;
|
|
751
1026
|
}
|
|
752
1027
|
let isCancelled = false;
|
|
1028
|
+
let isFetchInFlight = false;
|
|
753
1029
|
const fetchActiveWorkstreams = async () => {
|
|
1030
|
+
if (isFetchInFlight) {
|
|
1031
|
+
debugAgentChat('active workstreams fetch skipped while previous request is pending', { agentRunId });
|
|
1032
|
+
return;
|
|
1033
|
+
}
|
|
1034
|
+
isFetchInFlight = true;
|
|
754
1035
|
try {
|
|
1036
|
+
debugAgentChat('active workstreams fetch start', { agentRunId });
|
|
755
1037
|
const result = await client.agents.getActiveWorkstreams(agentRunId);
|
|
756
1038
|
if (isCancelled)
|
|
757
1039
|
return;
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
1040
|
+
debugAgentChat('active workstreams fetch success', {
|
|
1041
|
+
agentRunId,
|
|
1042
|
+
runningCount: result.running?.length ?? 0,
|
|
1043
|
+
completedCount: result.completed?.length ?? 0,
|
|
1044
|
+
unavailable: result.unavailable === true,
|
|
1045
|
+
});
|
|
1046
|
+
setQueriedActiveWorkstreams(result.running ?? []);
|
|
1047
|
+
setQueriedCompletedWorkstreams(result.completed ?? []);
|
|
1048
|
+
if (result.unavailable) {
|
|
1049
|
+
setIsWorkstreamQueryUnavailable(true);
|
|
1050
|
+
return;
|
|
1051
|
+
}
|
|
767
1052
|
workstreamFetchFailedRef.current = false;
|
|
768
1053
|
}
|
|
769
1054
|
catch (error) {
|
|
770
1055
|
if (isCancelled)
|
|
771
1056
|
return;
|
|
772
|
-
|
|
1057
|
+
setQueriedActiveWorkstreams((prev) => (prev.length === 0 ? prev : []));
|
|
1058
|
+
setIsWorkstreamQueryUnavailable(true);
|
|
1059
|
+
debugAgentChat('active workstreams fetch failed', {
|
|
1060
|
+
agentRunId,
|
|
1061
|
+
error: error instanceof Error ? error.message : String(error),
|
|
1062
|
+
});
|
|
773
1063
|
if (!workstreamFetchFailedRef.current) {
|
|
774
1064
|
console.warn('Failed to fetch active workstreams:', error);
|
|
775
1065
|
workstreamFetchFailedRef.current = true;
|
|
776
1066
|
}
|
|
777
1067
|
}
|
|
1068
|
+
finally {
|
|
1069
|
+
isFetchInFlight = false;
|
|
1070
|
+
}
|
|
778
1071
|
};
|
|
779
1072
|
void fetchActiveWorkstreams();
|
|
780
1073
|
const pollHandle = window.setInterval(fetchActiveWorkstreams, 10000);
|
|
@@ -782,7 +1075,14 @@ workingIndicatorClassName, messageListClassName, StoreLinkComponent, CollectionL
|
|
|
782
1075
|
isCancelled = true;
|
|
783
1076
|
window.clearInterval(pollHandle);
|
|
784
1077
|
};
|
|
785
|
-
}, [
|
|
1078
|
+
}, [
|
|
1079
|
+
client.agents,
|
|
1080
|
+
agentRunId,
|
|
1081
|
+
effectiveIsCompleted,
|
|
1082
|
+
initialHistoryStatus,
|
|
1083
|
+
isWorkflowTerminal,
|
|
1084
|
+
isWorkstreamQueryUnavailable,
|
|
1085
|
+
]);
|
|
786
1086
|
// Notify parent when input availability is determined
|
|
787
1087
|
useEffect(() => {
|
|
788
1088
|
if (messages.length === 0)
|
|
@@ -807,7 +1107,7 @@ workingIndicatorClassName, messageListClassName, StoreLinkComponent, CollectionL
|
|
|
807
1107
|
// Handlers
|
|
808
1108
|
// ────────────────────────────────────────────
|
|
809
1109
|
// Send a message to the agent
|
|
810
|
-
const handleSendMessage = useCallback((message) => {
|
|
1110
|
+
const handleSendMessage = useCallback((message, inputMetadata) => {
|
|
811
1111
|
const trimmed = message.trim();
|
|
812
1112
|
if (!trimmed || isSendingRef.current)
|
|
813
1113
|
return;
|
|
@@ -841,18 +1141,25 @@ workingIndicatorClassName, messageListClassName, StoreLinkComponent, CollectionL
|
|
|
841
1141
|
type: AgentMessageType.QUESTION,
|
|
842
1142
|
message: messageContent,
|
|
843
1143
|
workstream_id: 'main',
|
|
844
|
-
details: { _optimistic: true, _messageId: messageId },
|
|
1144
|
+
details: { _optimistic: true, _messageId: messageId, _deliveryStatus: 'sending' },
|
|
845
1145
|
};
|
|
846
1146
|
addOptimisticMessage(optimisticMessage);
|
|
847
1147
|
const metadata = {
|
|
848
1148
|
...(attachedDocs.length > 0 ? { attached_docs: attachedDocs.map((d) => d.id) } : {}),
|
|
849
1149
|
...contextMetadata,
|
|
1150
|
+
...inputMetadata,
|
|
1151
|
+
id: messageId,
|
|
850
1152
|
_messageId: messageId,
|
|
851
1153
|
};
|
|
852
1154
|
const sendUserInput = () => client.agents.sendSignal(agentRunId, 'UserInput', {
|
|
853
1155
|
message: messageContent,
|
|
1156
|
+
client_message_id: messageId,
|
|
854
1157
|
metadata,
|
|
855
1158
|
});
|
|
1159
|
+
const markReceived = () => {
|
|
1160
|
+
updateOptimisticMessageStatus(messageId, 'received');
|
|
1161
|
+
onAttachmentsSent?.();
|
|
1162
|
+
};
|
|
856
1163
|
// When the workflow has already completed, restart it first so it resumes
|
|
857
1164
|
// from the existing conversation history, then deliver the message. Temporal
|
|
858
1165
|
// buffers the signal until the new run is ready to receive it. We reconnect
|
|
@@ -861,16 +1168,12 @@ workingIndicatorClassName, messageListClassName, StoreLinkComponent, CollectionL
|
|
|
861
1168
|
const deliver = isWorkflowTerminalRef.current
|
|
862
1169
|
? client.agents.restart(agentRunId).then(() => {
|
|
863
1170
|
reconnectStream();
|
|
864
|
-
return sendUserInput().then(
|
|
865
|
-
onAttachmentsSent?.();
|
|
866
|
-
});
|
|
1171
|
+
return sendUserInput().then(markReceived);
|
|
867
1172
|
})
|
|
868
|
-
: sendUserInput().then(
|
|
869
|
-
onAttachmentsSent?.();
|
|
870
|
-
});
|
|
1173
|
+
: sendUserInput().then(markReceived);
|
|
871
1174
|
deliver
|
|
872
1175
|
.catch((err) => {
|
|
873
|
-
|
|
1176
|
+
updateOptimisticMessageStatus(messageId, 'failed');
|
|
874
1177
|
toast({
|
|
875
1178
|
status: 'error',
|
|
876
1179
|
title: t('agent.failedToSend'),
|
|
@@ -890,9 +1193,77 @@ workingIndicatorClassName, messageListClassName, StoreLinkComponent, CollectionL
|
|
|
890
1193
|
onAttachmentsSent,
|
|
891
1194
|
reconnectStream,
|
|
892
1195
|
addOptimisticMessage,
|
|
893
|
-
|
|
1196
|
+
updateOptimisticMessageStatus,
|
|
894
1197
|
t,
|
|
895
1198
|
]);
|
|
1199
|
+
// After the user connects an MCP server requested via request_mcp_connection, flag the
|
|
1200
|
+
// conversation for tool re-discovery and resume it with a confirmation message so the agent
|
|
1201
|
+
// continues automatically with the newly-available tools.
|
|
1202
|
+
const handleMcpConnected = useCallback(async (cfg) => {
|
|
1203
|
+
// Await the dirty-flag signal BEFORE sending the follow-up message so Temporal records
|
|
1204
|
+
// McpConfigChanged ahead of the UserInput. Otherwise the resume turn could run before
|
|
1205
|
+
// the flag is set and use the stale tool catalog. An omitted disabled list preserves
|
|
1206
|
+
// the user's current deactivation set.
|
|
1207
|
+
try {
|
|
1208
|
+
await client.agents.sendSignal(agentRunId, 'McpConfigChanged', {});
|
|
1209
|
+
}
|
|
1210
|
+
catch (err) {
|
|
1211
|
+
console.error('Failed to signal MCP config change', err);
|
|
1212
|
+
}
|
|
1213
|
+
handleSendMessage(t('agent.mcpConnectedMessage', { name: cfg.name }));
|
|
1214
|
+
}, [client, agentRunId, handleSendMessage, t]);
|
|
1215
|
+
// Per-conversation MCP deactivation set, seeded from the run and updated live via the
|
|
1216
|
+
// MCP action menu in the composer toolbar. Changes are pushed to the running workflow
|
|
1217
|
+
// (which re-discovers tools at the next turn).
|
|
1218
|
+
const [mcpDisabled, setMcpDisabled] = useState(undefined);
|
|
1219
|
+
useEffect(() => {
|
|
1220
|
+
let cancelled = false;
|
|
1221
|
+
client.agents
|
|
1222
|
+
.retrieve(agentRunId)
|
|
1223
|
+
.then((run) => {
|
|
1224
|
+
if (!cancelled) {
|
|
1225
|
+
setMcpDisabled(run.disabled_mcp_collections);
|
|
1226
|
+
if (run.tool_approval_mode !== undefined || run.interactive !== undefined) {
|
|
1227
|
+
setToolApprovalMode(normalizeAgentToolApprovalMode(run.tool_approval_mode, run.interactive));
|
|
1228
|
+
}
|
|
1229
|
+
}
|
|
1230
|
+
})
|
|
1231
|
+
.catch(() => {
|
|
1232
|
+
/* best-effort: toggles default to all-active */
|
|
1233
|
+
});
|
|
1234
|
+
return () => {
|
|
1235
|
+
cancelled = true;
|
|
1236
|
+
};
|
|
1237
|
+
}, [client, agentRunId]);
|
|
1238
|
+
const handleMcpDisabledChange = useCallback((disabled) => {
|
|
1239
|
+
const next = disabled.length > 0 ? disabled : undefined;
|
|
1240
|
+
setMcpDisabled(next);
|
|
1241
|
+
client.agents
|
|
1242
|
+
.sendSignal(agentRunId, 'McpConfigChanged', { disabled_mcp_collections: disabled })
|
|
1243
|
+
.catch((err) => console.error('Failed to signal MCP config change', err));
|
|
1244
|
+
}, [client, agentRunId]);
|
|
1245
|
+
const handleMcpConnectionChange = useCallback(() => {
|
|
1246
|
+
// A connect/disconnect doesn't change the activation set — omit disabled_mcp_collections so
|
|
1247
|
+
// the workflow preserves the current denylist (rather than overwriting it with possibly
|
|
1248
|
+
// stale UI state) and just re-discovers tools.
|
|
1249
|
+
client.agents
|
|
1250
|
+
.sendSignal(agentRunId, 'McpConfigChanged', {})
|
|
1251
|
+
.catch((err) => console.error('Failed to signal MCP config change', err));
|
|
1252
|
+
}, [client, agentRunId]);
|
|
1253
|
+
const handleToolApprovalModeChange = useCallback((mode) => {
|
|
1254
|
+
const nextMode = normalizeAgentToolApprovalMode(mode, interactive);
|
|
1255
|
+
setToolApprovalMode(nextMode);
|
|
1256
|
+
client.agents
|
|
1257
|
+
.sendSignal(agentRunId, 'ToolApprovalModeChanged', { mode: nextMode })
|
|
1258
|
+
.catch((err) => {
|
|
1259
|
+
toast({
|
|
1260
|
+
status: 'error',
|
|
1261
|
+
title: t('agent.approvalMode.changeFailed'),
|
|
1262
|
+
description: err instanceof Error ? err.message : t('agent.unknownError'),
|
|
1263
|
+
duration: 3000,
|
|
1264
|
+
});
|
|
1265
|
+
});
|
|
1266
|
+
}, [agentRunId, client, interactive, t, toast]);
|
|
896
1267
|
// Drag and drop handlers for full-panel file upload
|
|
897
1268
|
const handleDragEnter = useCallback((e) => {
|
|
898
1269
|
if (!canUploadFiles)
|
|
@@ -936,30 +1307,68 @@ workingIndicatorClassName, messageListClassName, StoreLinkComponent, CollectionL
|
|
|
936
1307
|
const handleStopWorkflow = useCallback(async () => {
|
|
937
1308
|
if (isStopping)
|
|
938
1309
|
return;
|
|
1310
|
+
const messageId = `stop-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
1311
|
+
const optimisticMessage = {
|
|
1312
|
+
timestamp: Date.now(),
|
|
1313
|
+
workflow_run_id: agentRunId,
|
|
1314
|
+
type: AgentMessageType.IDLE,
|
|
1315
|
+
message: 'Stopped. Waiting for your command...',
|
|
1316
|
+
workstream_id: 'main',
|
|
1317
|
+
details: {
|
|
1318
|
+
_optimistic: true,
|
|
1319
|
+
_messageId: messageId,
|
|
1320
|
+
_deliveryStatus: 'sending',
|
|
1321
|
+
display_role: 'user_stopped',
|
|
1322
|
+
status_reason: 'user_stopped',
|
|
1323
|
+
},
|
|
1324
|
+
};
|
|
1325
|
+
addOptimisticMessage(optimisticMessage);
|
|
939
1326
|
setIsStopping(true);
|
|
940
1327
|
try {
|
|
941
1328
|
await client.agents.sendSignal(agentRunId, 'Stop', {
|
|
942
1329
|
message: 'User requested stop',
|
|
1330
|
+
client_message_id: messageId,
|
|
1331
|
+
metadata: {
|
|
1332
|
+
id: messageId,
|
|
1333
|
+
_messageId: messageId,
|
|
1334
|
+
},
|
|
943
1335
|
});
|
|
1336
|
+
updateOptimisticMessageStatus(messageId, 'received');
|
|
1337
|
+
}
|
|
1338
|
+
catch (err) {
|
|
944
1339
|
toast({
|
|
945
|
-
status: '
|
|
946
|
-
title: t('agent.
|
|
947
|
-
description: t('agent.
|
|
1340
|
+
status: 'error',
|
|
1341
|
+
title: t('agent.failedToInterrupt'),
|
|
1342
|
+
description: err instanceof Error ? err.message : t('agent.unknownError'),
|
|
948
1343
|
duration: 3000,
|
|
949
1344
|
});
|
|
1345
|
+
updateOptimisticMessageStatus(messageId, 'failed');
|
|
1346
|
+
}
|
|
1347
|
+
finally {
|
|
1348
|
+
setIsStopping(false);
|
|
1349
|
+
}
|
|
1350
|
+
}, [isStopping, agentRunId, addOptimisticMessage, client.agents, toast, t, updateOptimisticMessageStatus]);
|
|
1351
|
+
const handleCompactContext = useCallback(async () => {
|
|
1352
|
+
if (isCompactingContext || effectiveIsCompleted || !isPlaybackLive)
|
|
1353
|
+
return;
|
|
1354
|
+
setIsCompactingContext(true);
|
|
1355
|
+
try {
|
|
1356
|
+
await client.agents.sendSignal(agentRunId, 'TriggerCheckpoint', {
|
|
1357
|
+
reason: 'manual user request',
|
|
1358
|
+
});
|
|
950
1359
|
}
|
|
951
1360
|
catch (err) {
|
|
952
1361
|
toast({
|
|
953
1362
|
status: 'error',
|
|
954
|
-
title: t('agent.
|
|
1363
|
+
title: t('agent.failedToCompactContext'),
|
|
955
1364
|
description: err instanceof Error ? err.message : t('agent.unknownError'),
|
|
956
1365
|
duration: 3000,
|
|
957
1366
|
});
|
|
958
1367
|
}
|
|
959
1368
|
finally {
|
|
960
|
-
|
|
1369
|
+
setIsCompactingContext(false);
|
|
961
1370
|
}
|
|
962
|
-
}, [
|
|
1371
|
+
}, [agentRunId, client.agents, effectiveIsCompleted, isCompactingContext, isPlaybackLive, t, toast]);
|
|
963
1372
|
// Expose stop handler to external callers via ref
|
|
964
1373
|
useEffect(() => {
|
|
965
1374
|
if (stopRef)
|
|
@@ -1087,13 +1496,13 @@ workingIndicatorClassName, messageListClassName, StoreLinkComponent, CollectionL
|
|
|
1087
1496
|
? 'w-full flex-1 min-h-[50vh]'
|
|
1088
1497
|
: fullWidth
|
|
1089
1498
|
? 'flex-1 w-full'
|
|
1090
|
-
: `flex-1 mx-auto ${!isModal ? 'max-w-4xl' : ''}`), children: [!hideHeader && headerVariant === 'compact' && (_jsx("div", { className: "flex flex-shrink-0 justify-end border-b border-border/60 px-2 py-1 lg:hidden", children: renderConversationHeader('compact') })), !hideHeader && headerVariant !== 'compact' && (_jsx("div", { className: "flex-shrink-0", children: renderConversationHeader(headerVariant) })), isPlaybackEnabled && (_jsx("div", { className: "flex flex-shrink-0 justify-end px-2 py-1.5", children: _jsx(AgentChatPlaybackControls, { cursor: clampedPlaybackCursor, messages:
|
|
1499
|
+
: `flex-1 mx-auto ${!isModal ? 'max-w-4xl' : ''}`), children: [!hideHeader && headerVariant === 'compact' && (_jsx("div", { className: "flex flex-shrink-0 justify-end border-b border-border/60 px-2 py-1 lg:hidden", children: renderConversationHeader('compact') })), !hideHeader && headerVariant !== 'compact' && (_jsx("div", { className: "flex-shrink-0", children: renderConversationHeader(headerVariant) })), isPlaybackEnabled && (_jsx("div", { className: "flex flex-shrink-0 justify-end px-2 py-1.5", children: _jsx(AgentChatPlaybackControls, { cursor: clampedPlaybackCursor, messages: playbackSourceMessages, onChangeCursor: handleChangePlaybackCursor }) })), messages.length === 0 && !effectiveIsCompleted && pendingStartMessage && pendingStartTimestamp ? (_jsx(PendingStartConversation, { message: pendingStartMessage, startedAt: pendingStartTimestamp })) : (_jsx(AllMessagesMixed, { messages: displayedMessages, bottomRef: bottomRef, isCompleted: displayedIsCompleted, plan: getActivePlan.plan, workstreamStatus: getActivePlan.workstreamStatus, showPlanPanel: showRightPanelProp && showSlidingPanel, onTogglePlanPanel: handleTogglePlanPanel, plans: plans, activePlanIndex: activePlanIndex, onChangePlan: handleChangePlan, taskLabels: taskLabels, streamingMessages: displayedStreamingMessages, onSendMessage: isPlaybackLive ? handleSendMessage : undefined, messageItemClassNames: messageItemClassNames, messageStyleOverrides: messageStyleOverrides, toolCallGroupClassNames: toolCallGroupClassNames, hideToolCallsInViewMode: hideToolCallsInViewMode, streamingMessageClassNames: streamingMessageClassNames, batchProgressPanelClassNames: batchProgressPanelClassNames, artifactRunId: agentRunId, viewMode: viewMode, hideWorkstreamTabs: hideWorkstreamTabs, workingIndicatorClassName: workingIndicatorClassName, messageListClassName: messageListClassName, StoreLinkComponent: effectiveStoreLinkComponent, CollectionLinkComponent: CollectionLinkComponent, prependFriendlyMessage: prependFriendlyMessage, initialRequestData: initialRequestData, initialRequestSchema: initialRequestSchema, initialRequestTitle: initialRequestTitle, initialRequestTemplate: initialRequestTemplate, showInitialRequest: initialHistoryStatus === 'empty' && messages.length === 0, hiddenMessageTypes: hiddenMessageTypes, disableAutoScroll: !isPlaybackLive, renderRequestInputControls: !shouldShowRequestInputOverlay, activeWorkstream: activeWorkstream, onActiveWorkstreamChange: setActiveWorkstream })), shouldShowRequestInputOverlay ? (_jsx(AgentRequestInputOverlay, { message: pendingRequestInputMessage, onSendMessage: isPlaybackLive ? handleSendMessage : undefined, onMcpConnected: isPlaybackLive ? handleMcpConnected : undefined, disabled: isUploading || !isPlaybackLive, isLoading: isSending || isUploading })) : isViewingPlaybackHistory && playbackActiveWorkstreams.length > 0 ? (_jsx("div", { className: "flex-shrink-0 pb-safe-area", children: _jsx(ActiveWorkstreamsSummary, { activeWorkstreams: playbackActiveWorkstreams }) })) : (shouldRenderLiveMessageInputArea && (_jsx("div", { className: "flex-shrink-0 pb-safe-area", children: isFailed ? (
|
|
1091
1500
|
// FAILED takes priority over every other branch so the composer can
|
|
1092
1501
|
// never render for a failed run. Use the caller's action when provided,
|
|
1093
1502
|
// otherwise fall back to the default failed message box.
|
|
1094
1503
|
(failedAction ?? (_jsx(MessageBox, { status: "error", icon: null, className: "m-2", children: "This Workflow is FAILED" })))) : effectiveWorkflowStatus &&
|
|
1095
1504
|
effectiveWorkflowStatus !== 'RUNNING' &&
|
|
1096
|
-
!canContinueConversation ? (viewMode === 'sliding' && effectiveWorkflowStatus === 'COMPLETED' ? (_jsx("div", { className: "mx-auto w-full max-w-3xl px-4 py-3 text-sm text-muted", children: _jsxs("div", { className: "flex items-center gap-2 border-t border-success/25 pt-3 text-success", children: [_jsx(CheckCircle, { className: "size-4" }), _jsx("span", { className: "font-medium", children: "Workflow completed" })] }) })) : (_jsxs(MessageBox, { status: effectiveWorkflowStatus === 'COMPLETED' ? 'success' : 'done', icon: null, className: "m-2", children: ["This Workflow is ", effectiveWorkflowStatus] }))) : ((showInput || canContinueConversation) && (_jsx(MessageInput, { onSend: handleSendMessage, onStop: allowWorkflowControl ? handleStopWorkflow : undefined, disabled: isUploading || !isPlaybackLive, isSending: isSending || isUploading, isStopping: isStopping, isStreaming: !effectiveIsCompleted, isCompleted: effectiveIsCompleted,
|
|
1505
|
+
!canContinueConversation ? (viewMode === 'sliding' && effectiveWorkflowStatus === 'COMPLETED' ? (_jsx("div", { className: "mx-auto w-full max-w-3xl px-4 py-3 text-sm text-muted", children: _jsxs("div", { className: "flex items-center gap-2 border-t border-success/25 pt-3 text-success", children: [_jsx(CheckCircle, { className: "size-4" }), _jsx("span", { className: "font-medium", children: "Workflow completed" })] }) })) : (_jsxs(MessageBox, { status: effectiveWorkflowStatus === 'COMPLETED' ? 'success' : 'done', icon: null, className: "m-2", children: ["This Workflow is ", effectiveWorkflowStatus] }))) : ((showInput || canContinueConversation) && (_jsx(MessageInput, { onSend: handleSendMessage, onStop: allowWorkflowControl ? handleStopWorkflow : undefined, approvalModeSlot: interactive && toolApprovalMode ? (_jsx(AgentApprovalModeSelector, { mode: toolApprovalMode, onChange: handleToolApprovalModeChange, disabled: !isPlaybackLive || isWorkflowTerminal || !allowWorkflowControl })) : undefined, mcpSlot: _jsx(McpConnectionsActionMenu, { disabledCollections: mcpDisabled, onChange: handleMcpDisabledChange, onConnectionChange: handleMcpConnectionChange }), disabled: isUploading || !isPlaybackLive, isSending: isSending || isUploading, isStopping: isStopping, isStreaming: !effectiveIsCompleted, isCompleted: effectiveIsCompleted, contextWindowUsage: canCompactContext ? contextWindowUsage : undefined, onCompactContext: canCompactContext ? handleCompactContext : undefined, isCompactingContext: isCompactingContext, activeTaskCount: activeTaskCount, activeWorkstreams: composerActiveWorkstreams, placeholder: composerPlaceholder, onFilesSelected: canUploadFiles ? handleFileUpload : undefined, uploadedFiles: uploadedFiles, onRemoveFile: onRemoveFile, onRemoveProcessingFile: handleRemoveProcessingFile, acceptedFileTypes: acceptedFileTypes, maxFiles: maxFiles, processingFiles: processingFiles, artifactRunId: agentRunId, hasProcessingFiles: hasProcessingFiles, renderDocumentSearch: renderDocumentSearch, selectedDocuments: selectedDocuments, onRemoveDocument: onRemoveDocument, hideObjectLinking: hideObjectLinking, hideFileUpload: !canUploadFiles, disableDropZone: canUploadFiles, className: inputContainerClassName, inputClassName: inputClassName }))) })))] }));
|
|
1097
1506
|
// Main content - wrapped with FusionFragmentProvider when fusionData is provided
|
|
1098
1507
|
const mainContent = (_jsx(ArtifactUrlCacheProvider, { children: _jsx(ImageLightboxProvider, { children: _jsxs("div", { ref: conversationLayoutRef, className: cn('flex flex-col lg:flex-row gap-2 w-full h-full relative overflow-hidden', canUploadFiles && isDragOver && 'ring-2 ring-blue-400 ring-inset', className), onDragEnter: canUploadFiles ? handleDragEnter : undefined, onDragOver: canUploadFiles ? handleDragOver : undefined, onDragLeave: canUploadFiles ? handleDragLeave : undefined, onDrop: canUploadFiles ? handleDrop : undefined, children: [canUploadFiles && isDragOver && (_jsx("div", { className: "absolute inset-0 flex items-center justify-center bg-blue-100/80 dark:bg-blue-900/40 z-50 pointer-events-none rounded-lg", children: _jsxs("div", { className: "text-blue-600 dark:text-blue-400 font-medium flex items-center gap-2 text-lg", children: [_jsx(UploadIcon, { className: "size-6" }), "Drop files to upload"] }) })), !conversationTab && conversationAreaJsx, !conversationTab && headerVariant === 'compact' && !hideHeader && (_jsx("div", { className: "hidden h-full w-12 shrink-0 items-start justify-center px-1 pt-2 lg:flex", children: renderConversationHeader('compact') })), isRightPanelVisible && (_jsxs(_Fragment, { children: [!conversationTab && (_jsx("div", { role: "separator", "aria-orientation": "vertical", "aria-label": "Resize right panel", "aria-valuenow": Math.round(rightPanelWidth), "aria-valuemin": 300, "aria-valuetext": `${Math.round(rightPanelWidth)} pixels`, tabIndex: 0, className: "hidden lg:block lg:w-1 lg:shrink-0 cursor-col-resize bg-border/70 hover:bg-border transition-colors", onMouseDown: () => setIsRightPanelResizing(true), onKeyDown: (event) => {
|
|
1099
1508
|
if (event.key !== 'ArrowLeft' && event.key !== 'ArrowRight')
|