@vertesia/ui 1.5.0-dev.20260722.120446Z → 1.5.0-dev.20260725.083715Z
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/filters/filterBar.d.ts.map +1 -1
- package/lib/core/components/shadcn/filters/filterBar.js +1 -1
- package/lib/core/components/shadcn/filters/filterBar.js.map +1 -1
- package/lib/core/components/shadcn/modal/dialog.d.ts +1 -1
- package/lib/core/components/shadcn/modal/dialog.d.ts.map +1 -1
- package/lib/core/components/shadcn/modal/dialog.js +2 -0
- package/lib/core/components/shadcn/modal/dialog.js.map +1 -1
- package/lib/core/components/shadcn/tabs.d.ts +12 -1
- package/lib/core/components/shadcn/tabs.d.ts.map +1 -1
- package/lib/core/components/shadcn/tabs.js +12 -4
- package/lib/core/components/shadcn/tabs.js.map +1 -1
- package/lib/features/agent/chat/AgentRightPanel.d.ts +5 -1
- package/lib/features/agent/chat/AgentRightPanel.d.ts.map +1 -1
- package/lib/features/agent/chat/AgentRightPanel.js +2 -2
- package/lib/features/agent/chat/AgentRightPanel.js.map +1 -1
- package/lib/features/agent/chat/ArtifactsTab.d.ts +5 -1
- package/lib/features/agent/chat/ArtifactsTab.d.ts.map +1 -1
- package/lib/features/agent/chat/ArtifactsTab.js +48 -11
- package/lib/features/agent/chat/ArtifactsTab.js.map +1 -1
- package/lib/features/agent/chat/DocumentEditingActionCard.d.ts +6 -0
- package/lib/features/agent/chat/DocumentEditingActionCard.d.ts.map +1 -0
- package/lib/features/agent/chat/DocumentEditingActionCard.js +129 -0
- package/lib/features/agent/chat/DocumentEditingActionCard.js.map +1 -0
- package/lib/features/agent/chat/ModernAgentConversation.d.ts +19 -1
- package/lib/features/agent/chat/ModernAgentConversation.d.ts.map +1 -1
- package/lib/features/agent/chat/ModernAgentConversation.js +125 -27
- package/lib/features/agent/chat/ModernAgentConversation.js.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/AgentMarkdownAnchor.d.ts +45 -0
- package/lib/features/agent/chat/ModernAgentOutput/AgentMarkdownAnchor.d.ts.map +1 -0
- package/lib/features/agent/chat/ModernAgentOutput/AgentMarkdownAnchor.js +40 -0
- package/lib/features/agent/chat/ModernAgentOutput/AgentMarkdownAnchor.js.map +1 -0
- package/lib/features/agent/chat/ModernAgentOutput/AllMessagesMixed.d.ts +3 -1
- package/lib/features/agent/chat/ModernAgentOutput/AllMessagesMixed.d.ts.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/AllMessagesMixed.js +94 -49
- package/lib/features/agent/chat/ModernAgentOutput/AllMessagesMixed.js.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/AttachmentPreview.d.ts +2 -1
- package/lib/features/agent/chat/ModernAgentOutput/AttachmentPreview.d.ts.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/AttachmentPreview.js +9 -5
- package/lib/features/agent/chat/ModernAgentOutput/AttachmentPreview.js.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/CollapsibleAgentMarkdown.d.ts +25 -0
- package/lib/features/agent/chat/ModernAgentOutput/CollapsibleAgentMarkdown.d.ts.map +1 -0
- package/lib/features/agent/chat/ModernAgentOutput/CollapsibleAgentMarkdown.js +33 -0
- package/lib/features/agent/chat/ModernAgentOutput/CollapsibleAgentMarkdown.js.map +1 -0
- package/lib/features/agent/chat/ModernAgentOutput/MessageItem.d.ts +3 -1
- package/lib/features/agent/chat/ModernAgentOutput/MessageItem.d.ts.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/MessageItem.js +22 -24
- package/lib/features/agent/chat/ModernAgentOutput/MessageItem.js.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/ResourceChangeSummary.d.ts +14 -0
- package/lib/features/agent/chat/ModernAgentOutput/ResourceChangeSummary.d.ts.map +1 -0
- package/lib/features/agent/chat/ModernAgentOutput/ResourceChangeSummary.js +21 -0
- package/lib/features/agent/chat/ModernAgentOutput/ResourceChangeSummary.js.map +1 -0
- package/lib/features/agent/chat/ModernAgentOutput/ResourceChip.d.ts +30 -0
- package/lib/features/agent/chat/ModernAgentOutput/ResourceChip.d.ts.map +1 -0
- package/lib/features/agent/chat/ModernAgentOutput/ResourceChip.js +53 -0
- package/lib/features/agent/chat/ModernAgentOutput/ResourceChip.js.map +1 -0
- package/lib/features/agent/chat/ModernAgentOutput/ToolCallGroup.d.ts.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/ToolCallGroup.js +21 -2
- package/lib/features/agent/chat/ModernAgentOutput/ToolCallGroup.js.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/resourceLinks.d.ts +6 -0
- package/lib/features/agent/chat/ModernAgentOutput/resourceLinks.d.ts.map +1 -0
- package/lib/features/agent/chat/ModernAgentOutput/resourceLinks.js +29 -0
- package/lib/features/agent/chat/ModernAgentOutput/resourceLinks.js.map +1 -0
- package/lib/features/agent/chat/ModernAgentOutput/resourceSummary.d.ts +33 -0
- package/lib/features/agent/chat/ModernAgentOutput/resourceSummary.d.ts.map +1 -0
- package/lib/features/agent/chat/ModernAgentOutput/resourceSummary.js +129 -0
- package/lib/features/agent/chat/ModernAgentOutput/resourceSummary.js.map +1 -0
- package/lib/features/agent/chat/ModernAgentOutput/utils.d.ts +7 -0
- package/lib/features/agent/chat/ModernAgentOutput/utils.d.ts.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/utils.js +11 -1
- package/lib/features/agent/chat/ModernAgentOutput/utils.js.map +1 -1
- package/lib/features/agent/chat/hooks/useAgentStream.d.ts +1 -1
- package/lib/features/agent/chat/hooks/useAgentStream.d.ts.map +1 -1
- package/lib/features/agent/chat/hooks/useAgentStream.js +24 -9
- package/lib/features/agent/chat/hooks/useAgentStream.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 +3 -0
- package/lib/features/agent/chat/index.js.map +1 -1
- package/lib/features/store/objects/DocumentSearchResults.js +2 -2
- package/lib/features/store/objects/DocumentSearchResults.js.map +1 -1
- package/lib/features/store/objects/components/ContentOverview.d.ts +2 -1
- package/lib/features/store/objects/components/ContentOverview.d.ts.map +1 -1
- package/lib/features/store/objects/components/ContentOverview.js +86 -15
- package/lib/features/store/objects/components/ContentOverview.js.map +1 -1
- package/lib/features/store/objects/components/DocumentEditingConfigurationSelector.d.ts +16 -0
- package/lib/features/store/objects/components/DocumentEditingConfigurationSelector.d.ts.map +1 -0
- package/lib/features/store/objects/components/DocumentEditingConfigurationSelector.js +116 -0
- package/lib/features/store/objects/components/DocumentEditingConfigurationSelector.js.map +1 -0
- package/lib/features/store/objects/components/DocumentEditingLockStatus.d.ts +7 -0
- package/lib/features/store/objects/components/DocumentEditingLockStatus.d.ts.map +1 -0
- package/lib/features/store/objects/components/DocumentEditingLockStatus.js +13 -0
- package/lib/features/store/objects/components/DocumentEditingLockStatus.js.map +1 -0
- package/lib/features/store/objects/components/DocumentEditingPanel.d.ts +48 -0
- package/lib/features/store/objects/components/DocumentEditingPanel.d.ts.map +1 -0
- package/lib/features/store/objects/components/DocumentEditingPanel.js +720 -0
- package/lib/features/store/objects/components/DocumentEditingPanel.js.map +1 -0
- package/lib/features/store/objects/components/TextEditorPanel.d.ts.map +1 -1
- package/lib/features/store/objects/components/TextEditorPanel.js +22 -9
- package/lib/features/store/objects/components/TextEditorPanel.js.map +1 -1
- package/lib/features/store/objects/components/documentArtifactRefs.d.ts +26 -0
- package/lib/features/store/objects/components/documentArtifactRefs.d.ts.map +1 -0
- package/lib/features/store/objects/components/documentArtifactRefs.js +52 -0
- package/lib/features/store/objects/components/documentArtifactRefs.js.map +1 -0
- package/lib/features/store/objects/components/documentEditingAgentConfig.d.ts +4 -0
- package/lib/features/store/objects/components/documentEditingAgentConfig.d.ts.map +1 -0
- package/lib/features/store/objects/components/documentEditingAgentConfig.js +40 -0
- package/lib/features/store/objects/components/documentEditingAgentConfig.js.map +1 -0
- package/lib/features/store/objects/components/documentEditingPrompts.d.ts +3 -0
- package/lib/features/store/objects/components/documentEditingPrompts.d.ts.map +1 -0
- package/lib/features/store/objects/components/documentEditingPrompts.js +13 -0
- package/lib/features/store/objects/components/documentEditingPrompts.js.map +1 -0
- package/lib/features/store/objects/components/documentEditingRun.d.ts +27 -0
- package/lib/features/store/objects/components/documentEditingRun.d.ts.map +1 -0
- package/lib/features/store/objects/components/documentEditingRun.js +126 -0
- package/lib/features/store/objects/components/documentEditingRun.js.map +1 -0
- package/lib/features/store/objects/components/documentEditingTarget.d.ts +20 -0
- package/lib/features/store/objects/components/documentEditingTarget.d.ts.map +1 -0
- package/lib/features/store/objects/components/documentEditingTarget.js +40 -0
- package/lib/features/store/objects/components/documentEditingTarget.js.map +1 -0
- package/lib/features/store/objects/components/index.d.ts +1 -0
- package/lib/features/store/objects/components/index.d.ts.map +1 -1
- package/lib/features/store/objects/components/index.js +1 -0
- package/lib/features/store/objects/components/index.js.map +1 -1
- package/lib/features/store/objects/components/useContentPanelHooks.d.ts +5 -1
- package/lib/features/store/objects/components/useContentPanelHooks.d.ts.map +1 -1
- package/lib/features/store/objects/components/useContentPanelHooks.js +53 -29
- package/lib/features/store/objects/components/useContentPanelHooks.js.map +1 -1
- package/lib/features/store/objects/components/useDownloadFile.d.ts +2 -1
- package/lib/features/store/objects/components/useDownloadFile.d.ts.map +1 -1
- package/lib/features/store/objects/components/useDownloadFile.js +3 -0
- package/lib/features/store/objects/components/useDownloadFile.js.map +1 -1
- package/lib/features/store/objects/selection/actions/StartWorkflowButton.js +1 -1
- package/lib/features/store/objects/selection/actions/StartWorkflowButton.js.map +1 -1
- package/lib/i18n/locales/ar.json +118 -1
- package/lib/i18n/locales/de.json +118 -1
- package/lib/i18n/locales/en.json +118 -0
- package/lib/i18n/locales/es.json +118 -1
- package/lib/i18n/locales/fr.json +118 -1
- package/lib/i18n/locales/it.json +118 -1
- package/lib/i18n/locales/ja.json +118 -1
- package/lib/i18n/locales/ko.json +118 -1
- package/lib/i18n/locales/pt.json +118 -1
- package/lib/i18n/locales/ru.json +118 -1
- package/lib/i18n/locales/tr.json +118 -1
- package/lib/i18n/locales/zh-TW.json +118 -1
- package/lib/i18n/locales/zh.json +118 -1
- package/lib/rich-text/EditorToolbar.d.ts +37 -0
- package/lib/rich-text/EditorToolbar.d.ts.map +1 -0
- package/lib/rich-text/EditorToolbar.js +215 -0
- package/lib/rich-text/EditorToolbar.js.map +1 -0
- package/lib/rich-text/VertesiaRichTextEditor.d.ts +26 -0
- package/lib/rich-text/VertesiaRichTextEditor.d.ts.map +1 -0
- package/lib/rich-text/VertesiaRichTextEditor.js +67 -0
- package/lib/rich-text/VertesiaRichTextEditor.js.map +1 -0
- package/lib/rich-text/index.d.ts +2 -0
- package/lib/rich-text/index.d.ts.map +1 -0
- package/lib/rich-text/index.js +2 -0
- package/lib/rich-text/index.js.map +1 -0
- package/lib/vertesia-ui-core.js +2 -2
- package/lib/vertesia-ui-core.js.map +1 -1
- package/lib/vertesia-ui-features.js +35 -30
- package/lib/vertesia-ui-features.js.map +1 -1
- package/lib/vertesia-ui-i18n.js +14 -14
- package/lib/vertesia-ui-i18n.js.map +1 -1
- package/lib/vertesia-ui-rich-text.js +5 -0
- package/lib/vertesia-ui-rich-text.js.map +1 -0
- package/lib/vertesia-ui-widgets.js +25 -7
- package/lib/vertesia-ui-widgets.js.map +1 -1
- package/lib/widgets/markdown/AgentResourceResolver.d.ts +31 -0
- package/lib/widgets/markdown/AgentResourceResolver.d.ts.map +1 -0
- package/lib/widgets/markdown/AgentResourceResolver.js +39 -0
- package/lib/widgets/markdown/AgentResourceResolver.js.map +1 -0
- package/lib/widgets/markdown/ArtifactEditingSurface.d.ts +63 -0
- package/lib/widgets/markdown/ArtifactEditingSurface.d.ts.map +1 -0
- package/lib/widgets/markdown/ArtifactEditingSurface.js +582 -0
- package/lib/widgets/markdown/ArtifactEditingSurface.js.map +1 -0
- package/lib/widgets/markdown/CollaborativeMarkdownRenderer.d.ts +69 -0
- package/lib/widgets/markdown/CollaborativeMarkdownRenderer.d.ts.map +1 -0
- package/lib/widgets/markdown/CollaborativeMarkdownRenderer.js +374 -0
- package/lib/widgets/markdown/CollaborativeMarkdownRenderer.js.map +1 -0
- package/lib/widgets/markdown/MarkdownLink.d.ts +3 -1
- package/lib/widgets/markdown/MarkdownLink.d.ts.map +1 -1
- package/lib/widgets/markdown/MarkdownLink.js +41 -14
- package/lib/widgets/markdown/MarkdownLink.js.map +1 -1
- package/lib/widgets/markdown/MarkdownRenderer.d.ts +8 -1
- package/lib/widgets/markdown/MarkdownRenderer.d.ts.map +1 -1
- package/lib/widgets/markdown/MarkdownRenderer.js +20 -4
- package/lib/widgets/markdown/MarkdownRenderer.js.map +1 -1
- package/lib/widgets/markdown/index.d.ts +5 -1
- package/lib/widgets/markdown/index.d.ts.map +1 -1
- package/lib/widgets/markdown/index.js +5 -1
- package/lib/widgets/markdown/index.js.map +1 -1
- package/lib/widgets/markdown/normalizeCustomSchemeLinks.d.ts.map +1 -1
- package/lib/widgets/markdown/normalizeCustomSchemeLinks.js +14 -2
- package/lib/widgets/markdown/normalizeCustomSchemeLinks.js.map +1 -1
- package/lib/widgets/markdown/textDiff.d.ts +52 -0
- package/lib/widgets/markdown/textDiff.d.ts.map +1 -0
- package/lib/widgets/markdown/textDiff.js +362 -0
- package/lib/widgets/markdown/textDiff.js.map +1 -0
- package/lib/widgets/markdown/useArtifactContent.d.ts +5 -3
- package/lib/widgets/markdown/useArtifactContent.d.ts.map +1 -1
- package/lib/widgets/markdown/useArtifactContent.js +6 -3
- package/lib/widgets/markdown/useArtifactContent.js.map +1 -1
- package/lib/widgets/markdown/useResolvedUrl.d.ts +1 -5
- package/lib/widgets/markdown/useResolvedUrl.d.ts.map +1 -1
- package/lib/widgets/markdown/useResolvedUrl.js +19 -31
- package/lib/widgets/markdown/useResolvedUrl.js.map +1 -1
- package/lib/widgets/xml-viewer/hooks/useXMLViewer.d.ts +9 -0
- package/lib/widgets/xml-viewer/hooks/useXMLViewer.d.ts.map +1 -1
- package/lib/widgets/xml-viewer/hooks/useXMLViewer.js +20 -17
- package/lib/widgets/xml-viewer/hooks/useXMLViewer.js.map +1 -1
- package/package.json +13 -9
- package/src/__tests__/a11y.test.tsx +4 -1
- package/src/__tests__/axe-helper.ts +17 -7
- package/src/__tests__/setup.ts +25 -0
- package/src/core/components/shadcn/filters/filterBar.tsx +1 -0
- package/src/core/components/shadcn/modal/dialog.tsx +3 -1
- package/src/core/components/shadcn/tabs.test.tsx +65 -0
- package/src/core/components/shadcn/tabs.tsx +25 -3
- package/src/features/agent/chat/AgentRightPanel.tsx +16 -1
- package/src/features/agent/chat/ArtifactsTab.test.tsx +55 -0
- package/src/features/agent/chat/ArtifactsTab.tsx +203 -52
- package/src/features/agent/chat/DocumentEditingActionCard.test.tsx +105 -0
- package/src/features/agent/chat/DocumentEditingActionCard.tsx +210 -0
- package/src/features/agent/chat/ModernAgentConversation.test.tsx +237 -40
- package/src/features/agent/chat/ModernAgentConversation.tsx +247 -75
- package/src/features/agent/chat/ModernAgentOutput/AgentMarkdownAnchor.test.tsx +79 -0
- package/src/features/agent/chat/ModernAgentOutput/AgentMarkdownAnchor.tsx +94 -0
- package/src/features/agent/chat/ModernAgentOutput/AllMessagesMixed.test.tsx +257 -34
- package/src/features/agent/chat/ModernAgentOutput/AllMessagesMixed.tsx +217 -105
- package/src/features/agent/chat/ModernAgentOutput/AttachmentPreview.tsx +17 -0
- package/src/features/agent/chat/ModernAgentOutput/CollapsibleAgentMarkdown.test.tsx +44 -0
- package/src/features/agent/chat/ModernAgentOutput/CollapsibleAgentMarkdown.tsx +88 -0
- package/src/features/agent/chat/ModernAgentOutput/MessageItem.tsx +30 -46
- package/src/features/agent/chat/ModernAgentOutput/ResourceChangeSummary.tsx +40 -0
- package/src/features/agent/chat/ModernAgentOutput/ResourceChip.test.tsx +148 -0
- package/src/features/agent/chat/ModernAgentOutput/ResourceChip.tsx +141 -0
- package/src/features/agent/chat/ModernAgentOutput/ToolCallGroup.tsx +33 -1
- package/src/features/agent/chat/ModernAgentOutput/resourceLinks.tsx +43 -0
- package/src/features/agent/chat/ModernAgentOutput/resourceSummary.test.ts +229 -0
- package/src/features/agent/chat/ModernAgentOutput/resourceSummary.ts +152 -0
- package/src/features/agent/chat/ModernAgentOutput/utils.test.ts +17 -0
- package/src/features/agent/chat/ModernAgentOutput/utils.ts +14 -1
- package/src/features/agent/chat/hooks/useAgentStream.test.tsx +188 -0
- package/src/features/agent/chat/hooks/useAgentStream.ts +28 -8
- package/src/features/agent/chat/index.ts +11 -0
- package/src/features/store/objects/DocumentSearchResults.tsx +2 -2
- package/src/features/store/objects/components/ContentOverview.tsx +216 -65
- package/src/features/store/objects/components/DocumentEditingConfigurationSelector.test.ts +34 -0
- package/src/features/store/objects/components/DocumentEditingConfigurationSelector.tsx +211 -0
- package/src/features/store/objects/components/DocumentEditingLockStatus.test.tsx +32 -0
- package/src/features/store/objects/components/DocumentEditingLockStatus.tsx +45 -0
- package/src/features/store/objects/components/DocumentEditingPanel.test.tsx +336 -0
- package/src/features/store/objects/components/DocumentEditingPanel.tsx +1236 -0
- package/src/features/store/objects/components/TextEditorPanel.test.tsx +48 -0
- package/src/features/store/objects/components/TextEditorPanel.tsx +41 -20
- package/src/features/store/objects/components/documentArtifactRefs.test.ts +65 -0
- package/src/features/store/objects/components/documentArtifactRefs.ts +72 -0
- package/src/features/store/objects/components/documentEditingAgentConfig.test.ts +28 -0
- package/src/features/store/objects/components/documentEditingAgentConfig.ts +41 -0
- package/src/features/store/objects/components/documentEditingPrompts.test.ts +26 -0
- package/src/features/store/objects/components/documentEditingPrompts.ts +12 -0
- package/src/features/store/objects/components/documentEditingRun.test.ts +176 -0
- package/src/features/store/objects/components/documentEditingRun.ts +184 -0
- package/src/features/store/objects/components/documentEditingTarget.test.ts +96 -0
- package/src/features/store/objects/components/documentEditingTarget.ts +63 -0
- package/src/features/store/objects/components/index.ts +1 -0
- package/src/features/store/objects/components/useContentPanelHooks.ts +52 -27
- package/src/features/store/objects/components/useDownloadFile.test.ts +20 -0
- package/src/features/store/objects/components/useDownloadFile.ts +5 -1
- package/src/features/store/objects/selection/actions/StartWorkflowButton.tsx +2 -2
- package/src/i18n/locales/ar.json +118 -1
- package/src/i18n/locales/de.json +118 -1
- package/src/i18n/locales/en.json +118 -0
- package/src/i18n/locales/es.json +118 -1
- package/src/i18n/locales/fr.json +118 -1
- package/src/i18n/locales/it.json +118 -1
- package/src/i18n/locales/ja.json +118 -1
- package/src/i18n/locales/ko.json +118 -1
- package/src/i18n/locales/pt.json +118 -1
- package/src/i18n/locales/ru.json +118 -1
- package/src/i18n/locales/tr.json +118 -1
- package/src/i18n/locales/zh-TW.json +118 -1
- package/src/i18n/locales/zh.json +118 -1
- package/src/rich-text/EditorToolbar.tsx +708 -0
- package/src/rich-text/VertesiaRichTextEditor.test.tsx +211 -0
- package/src/rich-text/VertesiaRichTextEditor.tsx +241 -0
- package/src/rich-text/index.ts +9 -0
- package/src/session/UserSession.test.ts +11 -11
- package/src/widgets/markdown/AgentResourceResolver.test.ts +24 -0
- package/src/widgets/markdown/AgentResourceResolver.tsx +70 -0
- package/src/widgets/markdown/ArtifactEditingSurface.test.tsx +537 -0
- package/src/widgets/markdown/ArtifactEditingSurface.tsx +878 -0
- package/src/widgets/markdown/CollaborativeMarkdownRenderer.test.tsx +484 -0
- package/src/widgets/markdown/CollaborativeMarkdownRenderer.tsx +825 -0
- package/src/widgets/markdown/MarkdownLink.test.tsx +122 -0
- package/src/widgets/markdown/MarkdownLink.tsx +102 -17
- package/src/widgets/markdown/MarkdownRenderer.tsx +30 -3
- package/src/widgets/markdown/index.ts +39 -1
- package/src/widgets/markdown/normalizeCustomSchemeLinks.ts +15 -2
- package/src/widgets/markdown/textDiff.test.ts +156 -0
- package/src/widgets/markdown/textDiff.ts +399 -0
- package/src/widgets/markdown/useArtifactContent.ts +9 -3
- package/src/widgets/markdown/useResolvedUrl.test.ts +29 -40
- package/src/widgets/markdown/useResolvedUrl.ts +33 -35
- package/src/widgets/xml-viewer/hooks/useXMLViewer.test.ts +26 -0
- package/src/widgets/xml-viewer/hooks/useXMLViewer.ts +23 -18
|
@@ -30,6 +30,11 @@ import {
|
|
|
30
30
|
} from '@vertesia/ui/core';
|
|
31
31
|
import { useUITranslation } from '@vertesia/ui/i18n';
|
|
32
32
|
import { useUserSession } from '@vertesia/ui/session';
|
|
33
|
+
import {
|
|
34
|
+
type AgentResourceResolver,
|
|
35
|
+
AgentResourceResolverProvider,
|
|
36
|
+
isArtifactRefreshEvent,
|
|
37
|
+
} from '@vertesia/ui/widgets';
|
|
33
38
|
import { ArrowUpIcon, Bot, CheckCircle, Cpu, FileTextIcon, UploadIcon, XIcon } from 'lucide-react';
|
|
34
39
|
import type React from 'react';
|
|
35
40
|
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
@@ -69,6 +74,7 @@ import {
|
|
|
69
74
|
getConversationUrl,
|
|
70
75
|
getWorkstreamId,
|
|
71
76
|
isInProgress,
|
|
77
|
+
isPassiveArtifactUpdate,
|
|
72
78
|
} from './ModernAgentOutput/utils';
|
|
73
79
|
import {
|
|
74
80
|
type AgentChatPlaybackCursor,
|
|
@@ -97,6 +103,8 @@ export type StartWorkflowFn = (
|
|
|
97
103
|
options?: StartWorkflowOptions,
|
|
98
104
|
) => Promise<{ agent_run_id: string } | undefined>;
|
|
99
105
|
|
|
106
|
+
export type SendAgentMessageFn = (message: string, inputMetadata?: Record<string, unknown>) => void;
|
|
107
|
+
|
|
100
108
|
const EMPTY_STREAMING_MESSAGES = new Map<string, never>();
|
|
101
109
|
|
|
102
110
|
function getTimestampMs(timestamp: number | string | undefined): number {
|
|
@@ -533,6 +541,12 @@ function downloadJsonFile(filename: string, payload: unknown) {
|
|
|
533
541
|
export interface ModernAgentConversationProps {
|
|
534
542
|
/** Stable AgentRun ID — the primary identifier for all runtime operations. */
|
|
535
543
|
agentRunId?: string;
|
|
544
|
+
/**
|
|
545
|
+
* Optional override for mapping agent resource references (documents, collections, interactions,
|
|
546
|
+
* ...) to navigation or activation targets in the chat. This overrides an inherited
|
|
547
|
+
* AgentResourceResolverProvider; without either, resources remain non-interactive.
|
|
548
|
+
*/
|
|
549
|
+
resourceResolver?: AgentResourceResolver;
|
|
536
550
|
title?: string;
|
|
537
551
|
interactive?: boolean;
|
|
538
552
|
onClose?: () => void;
|
|
@@ -567,6 +581,12 @@ export interface ModernAgentConversationProps {
|
|
|
567
581
|
|
|
568
582
|
/** Ref populated with the internal file upload handler for external triggering */
|
|
569
583
|
fileUploadRef?: React.MutableRefObject<((files: File[]) => void) | null>;
|
|
584
|
+
/** Ref populated with the internal message sender for document or artifact collaboration controls. */
|
|
585
|
+
sendMessageRef?: React.MutableRefObject<SendAgentMessageFn | null>;
|
|
586
|
+
/** Called for each live message delivered after the conversation stream connects. */
|
|
587
|
+
onMessage?: (message: AgentMessage) => void;
|
|
588
|
+
/** Called when the main agent turn starts or reaches an idle/terminal state. */
|
|
589
|
+
onAgentWorkingChange?: (isWorking: boolean) => void;
|
|
570
590
|
/** Called when processingFiles state changes (for external progress display) */
|
|
571
591
|
onProcessingFilesChange?: (files: Map<string, ConversationFile>) => void;
|
|
572
592
|
/** Processing files to display in the right panel Uploads tab */
|
|
@@ -607,6 +627,8 @@ export interface ModernAgentConversationProps {
|
|
|
607
627
|
hideHeader?: boolean;
|
|
608
628
|
/** Header density. Use compact when the surrounding page already identifies the run. */
|
|
609
629
|
headerVariant?: 'full' | 'compact';
|
|
630
|
+
/** Start-screen layout. Compact removes empty history; expanded-composer gives that space to the first input. */
|
|
631
|
+
startViewVariant?: 'default' | 'compact' | 'expanded-composer';
|
|
610
632
|
/** Hide the internal message input (for apps that render their own) */
|
|
611
633
|
hideMessageInput?: boolean;
|
|
612
634
|
/** Custom action shown in place of the input box when the run status is FAILED.
|
|
@@ -643,6 +665,8 @@ export interface ModernAgentConversationProps {
|
|
|
643
665
|
inputContainerClassName?: string;
|
|
644
666
|
/** Additional className for the input field */
|
|
645
667
|
inputClassName?: string;
|
|
668
|
+
/** Read-only context rendered immediately above the live conversation composer. */
|
|
669
|
+
composerContext?: React.ReactNode;
|
|
646
670
|
|
|
647
671
|
/** Additional className for the root container */
|
|
648
672
|
className?: string;
|
|
@@ -708,14 +732,19 @@ export interface ModernAgentConversationProps {
|
|
|
708
732
|
}
|
|
709
733
|
|
|
710
734
|
export function ModernAgentConversation(props: ModernAgentConversationProps) {
|
|
711
|
-
const { agentRunId, startWorkflow } = props;
|
|
735
|
+
const { agentRunId, startWorkflow, resourceResolver } = props;
|
|
712
736
|
|
|
713
737
|
if (agentRunId) {
|
|
714
|
-
|
|
738
|
+
const conversation = (
|
|
715
739
|
<SkillWidgetProvider>
|
|
716
740
|
<ModernAgentConversationInner {...props} agentRunId={agentRunId} />
|
|
717
741
|
</SkillWidgetProvider>
|
|
718
742
|
);
|
|
743
|
+
return resourceResolver ? (
|
|
744
|
+
<AgentResourceResolverProvider value={resourceResolver}>{conversation}</AgentResourceResolverProvider>
|
|
745
|
+
) : (
|
|
746
|
+
conversation
|
|
747
|
+
);
|
|
719
748
|
} else if (startWorkflow) {
|
|
720
749
|
// If we have startWorkflow capability but no agentRunId yet
|
|
721
750
|
return <StartWorkflowView {...props} />;
|
|
@@ -758,13 +787,17 @@ function StartWorkflowView({
|
|
|
758
787
|
hideFileUpload = false,
|
|
759
788
|
hideObjectLinking,
|
|
760
789
|
headerVariant,
|
|
790
|
+
startViewVariant = 'default',
|
|
761
791
|
inputContainerClassName,
|
|
762
792
|
inputClassName,
|
|
763
793
|
className,
|
|
764
794
|
allowWorkflowControl,
|
|
765
795
|
initialToolApprovalMode,
|
|
796
|
+
onAgentWorkingChange,
|
|
766
797
|
}: ModernAgentConversationProps) {
|
|
767
798
|
const { t } = useUITranslation();
|
|
799
|
+
const isCompactStartView = startViewVariant !== 'default';
|
|
800
|
+
const isExpandedStartComposer = startViewVariant === 'expanded-composer';
|
|
768
801
|
const canStageFiles = !hideFileUpload;
|
|
769
802
|
const resolvedPlaceholder = placeholder ?? t('agent.typeYourMessage');
|
|
770
803
|
const resolvedStartButtonText = startButtonText ?? t('agent.startAgent');
|
|
@@ -785,6 +818,10 @@ function StartWorkflowView({
|
|
|
785
818
|
// Staged files - stored locally until workflow starts
|
|
786
819
|
const [stagedFiles, setStagedFiles] = useState<File[]>([]);
|
|
787
820
|
|
|
821
|
+
useEffect(() => {
|
|
822
|
+
onAgentWorkingChange?.(isSending);
|
|
823
|
+
}, [isSending, onAgentWorkingChange]);
|
|
824
|
+
|
|
788
825
|
// Drag and drop state
|
|
789
826
|
const [isDragOver, setIsDragOver] = useState(false);
|
|
790
827
|
const dragCounterRef = useRef(0);
|
|
@@ -1021,10 +1058,14 @@ function StartWorkflowView({
|
|
|
1021
1058
|
const adjustTextareaHeight = useCallback(() => {
|
|
1022
1059
|
const textarea = inputRef.current;
|
|
1023
1060
|
if (textarea) {
|
|
1061
|
+
if (isExpandedStartComposer) {
|
|
1062
|
+
textarea.style.height = '100%';
|
|
1063
|
+
return;
|
|
1064
|
+
}
|
|
1024
1065
|
textarea.style.height = 'auto';
|
|
1025
1066
|
textarea.style.height = `${Math.min(textarea.scrollHeight, 200)}px`;
|
|
1026
1067
|
}
|
|
1027
|
-
}, []);
|
|
1068
|
+
}, [isExpandedStartComposer]);
|
|
1028
1069
|
|
|
1029
1070
|
useEffect(() => {
|
|
1030
1071
|
void inputValue;
|
|
@@ -1049,6 +1090,7 @@ function StartWorkflowView({
|
|
|
1049
1090
|
inputClassName,
|
|
1050
1091
|
className,
|
|
1051
1092
|
allowWorkflowControl,
|
|
1093
|
+
onAgentWorkingChange,
|
|
1052
1094
|
}}
|
|
1053
1095
|
agentRunId={startedAgentRunId}
|
|
1054
1096
|
title={title}
|
|
@@ -1060,11 +1102,18 @@ function StartWorkflowView({
|
|
|
1060
1102
|
}
|
|
1061
1103
|
|
|
1062
1104
|
return (
|
|
1063
|
-
<div
|
|
1105
|
+
<div
|
|
1106
|
+
className={cn(
|
|
1107
|
+
'flex flex-col items-center bg-background',
|
|
1108
|
+
isCompactStartView && !isExpandedStartComposer ? '' : 'h-full',
|
|
1109
|
+
className,
|
|
1110
|
+
)}
|
|
1111
|
+
>
|
|
1064
1112
|
{/* biome-ignore lint/a11y/noStaticElementInteractions: drag/drop target only; file selection is also exposed via the upload button. */}
|
|
1065
1113
|
<div
|
|
1066
1114
|
className={cn(
|
|
1067
|
-
'relative flex
|
|
1115
|
+
'relative flex w-full flex-col overflow-hidden border-0',
|
|
1116
|
+
isCompactStartView && !isExpandedStartComposer ? '' : 'h-full',
|
|
1068
1117
|
fullWidth ? '' : 'max-w-4xl',
|
|
1069
1118
|
)}
|
|
1070
1119
|
onDragEnter={canStageFiles ? handleDragEnter : undefined}
|
|
@@ -1120,11 +1169,21 @@ function StartWorkflowView({
|
|
|
1120
1169
|
)}
|
|
1121
1170
|
|
|
1122
1171
|
{/* Empty conversation area with instructions */}
|
|
1123
|
-
<div
|
|
1172
|
+
<div
|
|
1173
|
+
className={cn(
|
|
1174
|
+
'flex flex-col items-center justify-end bg-background px-4',
|
|
1175
|
+
isCompactStartView ? 'shrink-0 pt-3' : 'flex-1 overflow-y-auto',
|
|
1176
|
+
)}
|
|
1177
|
+
>
|
|
1124
1178
|
{pendingStartMessage && pendingStartTimestamp ? (
|
|
1125
1179
|
<PendingStartConversation message={pendingStartMessage} startedAt={pendingStartTimestamp} />
|
|
1126
1180
|
) : (
|
|
1127
|
-
<div
|
|
1181
|
+
<div
|
|
1182
|
+
className={cn(
|
|
1183
|
+
'mx-auto flex w-full max-w-3xl flex-col justify-end',
|
|
1184
|
+
isCompactStartView ? '' : 'min-h-full py-8',
|
|
1185
|
+
)}
|
|
1186
|
+
>
|
|
1128
1187
|
{initialMessage && (
|
|
1129
1188
|
<div className="text-[15px] leading-relaxed text-foreground/80">{initialMessage}</div>
|
|
1130
1189
|
)}
|
|
@@ -1133,10 +1192,16 @@ function StartWorkflowView({
|
|
|
1133
1192
|
</div>
|
|
1134
1193
|
|
|
1135
1194
|
{/* Input Area */}
|
|
1136
|
-
<div
|
|
1195
|
+
<div
|
|
1196
|
+
className={cn(
|
|
1197
|
+
'bg-background px-4 pb-safe-area-4 pt-2',
|
|
1198
|
+
isExpandedStartComposer ? 'flex min-h-0 flex-1 flex-col' : 'shrink-0',
|
|
1199
|
+
)}
|
|
1200
|
+
>
|
|
1137
1201
|
<div
|
|
1138
1202
|
className={cn(
|
|
1139
1203
|
'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',
|
|
1204
|
+
isExpandedStartComposer && 'min-h-0 w-full flex-1',
|
|
1140
1205
|
inputContainerClassName,
|
|
1141
1206
|
)}
|
|
1142
1207
|
>
|
|
@@ -1176,9 +1241,14 @@ function StartWorkflowView({
|
|
|
1176
1241
|
rows={2}
|
|
1177
1242
|
className={cn(
|
|
1178
1243
|
'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',
|
|
1244
|
+
isExpandedStartComposer && 'min-h-0 flex-1',
|
|
1179
1245
|
inputClassName,
|
|
1180
1246
|
)}
|
|
1181
|
-
style={
|
|
1247
|
+
style={
|
|
1248
|
+
isExpandedStartComposer
|
|
1249
|
+
? { minHeight: '72px', maxHeight: 'none' }
|
|
1250
|
+
: { minHeight: '72px', maxHeight: '200px' }
|
|
1251
|
+
}
|
|
1182
1252
|
/>
|
|
1183
1253
|
|
|
1184
1254
|
<div className="flex items-center justify-between gap-3">
|
|
@@ -1274,10 +1344,14 @@ function ModernAgentConversationInner({
|
|
|
1274
1344
|
className,
|
|
1275
1345
|
inputContainerClassName,
|
|
1276
1346
|
inputClassName,
|
|
1347
|
+
composerContext,
|
|
1277
1348
|
// Fusion fragment data
|
|
1278
1349
|
fusionData,
|
|
1279
1350
|
// External file upload API
|
|
1280
1351
|
fileUploadRef,
|
|
1352
|
+
sendMessageRef,
|
|
1353
|
+
onMessage,
|
|
1354
|
+
onAgentWorkingChange,
|
|
1281
1355
|
onProcessingFilesChange,
|
|
1282
1356
|
processingFiles: processingFilesProp,
|
|
1283
1357
|
// External plan panel API
|
|
@@ -1338,7 +1412,7 @@ function ModernAgentConversationInner({
|
|
|
1338
1412
|
agentRunStatus,
|
|
1339
1413
|
workflowRunId,
|
|
1340
1414
|
serverFileUpdates,
|
|
1341
|
-
} = useAgentStream(client, agentRunId);
|
|
1415
|
+
} = useAgentStream(client, agentRunId, onMessage);
|
|
1342
1416
|
|
|
1343
1417
|
const {
|
|
1344
1418
|
plans,
|
|
@@ -1548,9 +1622,10 @@ function ModernAgentConversationInner({
|
|
|
1548
1622
|
const canShowPlaybackToggle = showPlaybackToggle && enablePlayback === undefined && isAgentChatPlaybackAvailable();
|
|
1549
1623
|
const isPlaybackEnabled = enablePlayback ?? (isAgentChatPlaybackEnabled() || isPlaybackToggleEnabled);
|
|
1550
1624
|
const playbackSourceMessages = useMemo(() => {
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1625
|
+
// Passive artifact autosaves are surfaced by the editor's own save indicator, not the chat.
|
|
1626
|
+
const visibleMessages = messages.filter(
|
|
1627
|
+
(message) => !isPassiveArtifactUpdate(message) && !(hiddenMessageTypes?.includes(message.type) ?? false),
|
|
1628
|
+
);
|
|
1554
1629
|
return filterMessagesForActiveWorkstream(visibleMessages, activeWorkstream);
|
|
1555
1630
|
}, [activeWorkstream, hiddenMessageTypes, messages]);
|
|
1556
1631
|
const playbackState = useMemo(
|
|
@@ -1573,11 +1648,20 @@ function ModernAgentConversationInner({
|
|
|
1573
1648
|
);
|
|
1574
1649
|
const effectiveIsCompleted = useMemo(() => isCompleted || !isInProgress(messages), [isCompleted, messages]);
|
|
1575
1650
|
const displayedIsCompleted = isPlaybackLive || isPlaybackAtLatest ? effectiveIsCompleted : false;
|
|
1651
|
+
const isAgentWorking = !effectiveIsCompleted && !isWorkflowTerminal;
|
|
1652
|
+
|
|
1653
|
+
useEffect(() => {
|
|
1654
|
+
onAgentWorkingChange?.(isAgentWorking);
|
|
1655
|
+
}, [isAgentWorking, onAgentWorkingChange]);
|
|
1576
1656
|
const pendingRequestInputMessage = useMemo(
|
|
1577
1657
|
() => getPendingRequestInputMessage(displayedMessages),
|
|
1578
1658
|
[displayedMessages],
|
|
1579
1659
|
);
|
|
1580
|
-
|
|
1660
|
+
// A terminal run silently drops user input unless it can be continued (see the guard in
|
|
1661
|
+
// handleSendMessage), so never surface an actionable question overlay in that state —
|
|
1662
|
+
// the terminal status box renders instead.
|
|
1663
|
+
const shouldShowRequestInputOverlay =
|
|
1664
|
+
Boolean(pendingRequestInputMessage) && !isFailed && (!isWorkflowTerminal || canContinueConversation);
|
|
1581
1665
|
const isViewingPlaybackHistory = isPlaybackEnabled && !isPlaybackLive;
|
|
1582
1666
|
const shouldRenderLiveMessageInputArea = shouldRenderMessageInputArea && !isViewingPlaybackHistory;
|
|
1583
1667
|
const contextWindowUsage = useMemo(() => toContextWindowUsage(messages), [messages]);
|
|
@@ -1672,15 +1756,6 @@ function ModernAgentConversationInner({
|
|
|
1672
1756
|
// ────────────────────────────────────────────
|
|
1673
1757
|
// Stable callbacks
|
|
1674
1758
|
// ────────────────────────────────────────────
|
|
1675
|
-
const handleTogglePlanPanel = useCallback(() => {
|
|
1676
|
-
setShowSlidingPanel((prev: boolean) => {
|
|
1677
|
-
if (!prev) {
|
|
1678
|
-
sessionStorage.setItem('plan-panel-shown', 'true');
|
|
1679
|
-
}
|
|
1680
|
-
return !prev;
|
|
1681
|
-
});
|
|
1682
|
-
}, [setShowSlidingPanel]);
|
|
1683
|
-
|
|
1684
1759
|
const handleChangePlan = useCallback(
|
|
1685
1760
|
(index: number) => {
|
|
1686
1761
|
setActivePlanIndex(index);
|
|
@@ -1695,17 +1770,44 @@ function ModernAgentConversationInner({
|
|
|
1695
1770
|
const [rightPanelTab, setRightPanelTab] = useState<RightPanelTab>(
|
|
1696
1771
|
conversationContent || conversationTab ? 'conversation' : 'plan',
|
|
1697
1772
|
);
|
|
1773
|
+
const [selectedArtifactPath, setSelectedArtifactPath] = useState<string | null>(null);
|
|
1698
1774
|
const [rightPanelWidth, setRightPanelWidth] = useState(400);
|
|
1699
1775
|
const [isRightPanelResizing, setIsRightPanelResizing] = useState(false);
|
|
1776
|
+
// Master override for the "Toggle right sidebar" control. `showSlidingPanel` only tracks the
|
|
1777
|
+
// plan; open documents/workstreams keep the panel visible on their own, so without this the
|
|
1778
|
+
// toggle can't hide the panel while a document is open. Explicit reveals (opening an artifact
|
|
1779
|
+
// or document) clear it again.
|
|
1780
|
+
const [rightPanelManuallyClosed, setRightPanelManuallyClosed] = useState(false);
|
|
1700
1781
|
|
|
1701
1782
|
const isRightPanelVisible =
|
|
1702
1783
|
showRightPanelProp &&
|
|
1784
|
+
!rightPanelManuallyClosed &&
|
|
1703
1785
|
(showSlidingPanel ||
|
|
1704
1786
|
isDocPanelOpen ||
|
|
1705
1787
|
(!hideWorkstreamTabs && panelWorkstreams.length > 0) ||
|
|
1706
1788
|
!!conversationContent ||
|
|
1707
1789
|
conversationTab);
|
|
1708
1790
|
|
|
1791
|
+
// A newly opened document should reveal the panel even if the user had manually collapsed it.
|
|
1792
|
+
const previousDocPanelOpenRef = useRef(isDocPanelOpen);
|
|
1793
|
+
useEffect(() => {
|
|
1794
|
+
if (isDocPanelOpen && !previousDocPanelOpenRef.current) {
|
|
1795
|
+
setRightPanelManuallyClosed(false);
|
|
1796
|
+
}
|
|
1797
|
+
previousDocPanelOpenRef.current = isDocPanelOpen;
|
|
1798
|
+
}, [isDocPanelOpen]);
|
|
1799
|
+
|
|
1800
|
+
const handleTogglePlanPanel = useCallback(() => {
|
|
1801
|
+
if (isRightPanelVisible) {
|
|
1802
|
+
setRightPanelManuallyClosed(true);
|
|
1803
|
+
setShowSlidingPanel(false);
|
|
1804
|
+
} else {
|
|
1805
|
+
setRightPanelManuallyClosed(false);
|
|
1806
|
+
setShowSlidingPanel(true);
|
|
1807
|
+
sessionStorage.setItem('plan-panel-shown', 'true');
|
|
1808
|
+
}
|
|
1809
|
+
}, [isRightPanelVisible, setShowSlidingPanel]);
|
|
1810
|
+
|
|
1709
1811
|
useEffect(() => {
|
|
1710
1812
|
if (!isRightPanelVisible && isRightPanelResizing) {
|
|
1711
1813
|
setIsRightPanelResizing(false);
|
|
@@ -1747,10 +1849,44 @@ function ModernAgentConversationInner({
|
|
|
1747
1849
|
}, [isRightPanelResizing]);
|
|
1748
1850
|
|
|
1749
1851
|
const handleCloseRightPanel = useCallback(() => {
|
|
1852
|
+
setRightPanelManuallyClosed(true);
|
|
1750
1853
|
setShowSlidingPanel(false);
|
|
1751
1854
|
handleCloseDocPanel();
|
|
1752
1855
|
}, [setShowSlidingPanel, handleCloseDocPanel]);
|
|
1753
1856
|
|
|
1857
|
+
const handleOpenArtifact = useCallback(
|
|
1858
|
+
(path: string) => {
|
|
1859
|
+
if (!/\.md$/i.test(path)) return;
|
|
1860
|
+
setRightPanelManuallyClosed(false);
|
|
1861
|
+
setSelectedArtifactPath(path);
|
|
1862
|
+
setRightPanelTab('artifacts');
|
|
1863
|
+
setShowSlidingPanel(true);
|
|
1864
|
+
},
|
|
1865
|
+
[setShowSlidingPanel],
|
|
1866
|
+
);
|
|
1867
|
+
|
|
1868
|
+
// The `display_artifact` tool emits a `display_artifact` stream event asking the UI
|
|
1869
|
+
// to reveal a text artifact in the editor. Act on the latest such event, once per
|
|
1870
|
+
// distinct occurrence so the user can still close the panel without it snapping back.
|
|
1871
|
+
const displayedArtifactMarkerRef = useRef<string | null>(null);
|
|
1872
|
+
useEffect(() => {
|
|
1873
|
+
let target: string | undefined;
|
|
1874
|
+
let marker: string | undefined;
|
|
1875
|
+
for (const message of messages) {
|
|
1876
|
+
const details = message.details as Record<string, unknown> | undefined;
|
|
1877
|
+
if (details?.event_class === 'display_artifact' && typeof details.path === 'string') {
|
|
1878
|
+
target = details.path;
|
|
1879
|
+
marker = `${message.timestamp ?? ''}:${details.path}`;
|
|
1880
|
+
}
|
|
1881
|
+
}
|
|
1882
|
+
if (!target || !marker || marker === displayedArtifactMarkerRef.current) return;
|
|
1883
|
+
displayedArtifactMarkerRef.current = marker;
|
|
1884
|
+
setRightPanelManuallyClosed(false);
|
|
1885
|
+
setSelectedArtifactPath(target);
|
|
1886
|
+
setRightPanelTab('artifacts');
|
|
1887
|
+
setShowSlidingPanel(true);
|
|
1888
|
+
}, [messages, setShowSlidingPanel]);
|
|
1889
|
+
|
|
1754
1890
|
// Default StoreLinkComponent that opens documents in the panel
|
|
1755
1891
|
const internalStoreLinkComponent = useCallback(
|
|
1756
1892
|
({ href, documentId, children }: { href: string; documentId: string; children: React.ReactNode }) => (
|
|
@@ -1801,6 +1937,7 @@ function ModernAgentConversationInner({
|
|
|
1801
1937
|
|
|
1802
1938
|
useEffect(() => {
|
|
1803
1939
|
void agentRunId;
|
|
1940
|
+
setSelectedArtifactPath(null);
|
|
1804
1941
|
workstreamFetchFailedRef.current = false;
|
|
1805
1942
|
setIsWorkstreamQueryUnavailable(false);
|
|
1806
1943
|
setQueriedActiveWorkstreams([]);
|
|
@@ -1978,7 +2115,12 @@ function ModernAgentConversationInner({
|
|
|
1978
2115
|
type: AgentMessageType.QUESTION,
|
|
1979
2116
|
message: messageContent,
|
|
1980
2117
|
workstream_id: 'main',
|
|
1981
|
-
details: {
|
|
2118
|
+
details: {
|
|
2119
|
+
_optimistic: true,
|
|
2120
|
+
_messageId: messageId,
|
|
2121
|
+
_deliveryStatus: 'sending',
|
|
2122
|
+
...(inputMetadata?.editing_action ? { editing_action: inputMetadata.editing_action } : {}),
|
|
2123
|
+
},
|
|
1982
2124
|
};
|
|
1983
2125
|
|
|
1984
2126
|
addOptimisticMessage(optimisticMessage);
|
|
@@ -2049,6 +2191,13 @@ function ModernAgentConversationInner({
|
|
|
2049
2191
|
],
|
|
2050
2192
|
);
|
|
2051
2193
|
|
|
2194
|
+
useEffect(() => {
|
|
2195
|
+
if (sendMessageRef) sendMessageRef.current = handleSendMessage;
|
|
2196
|
+
return () => {
|
|
2197
|
+
if (sendMessageRef?.current === handleSendMessage) sendMessageRef.current = null;
|
|
2198
|
+
};
|
|
2199
|
+
}, [handleSendMessage, sendMessageRef]);
|
|
2200
|
+
|
|
2052
2201
|
// After the user connects an MCP server requested via request_mcp_connection, flag the
|
|
2053
2202
|
// conversation for tool re-discovery and resume it with a confirmation message so the agent
|
|
2054
2203
|
// continues automatically with the newly-available tools.
|
|
@@ -2382,6 +2531,21 @@ function ModernAgentConversationInner({
|
|
|
2382
2531
|
return false;
|
|
2383
2532
|
}).length;
|
|
2384
2533
|
}, [messages]);
|
|
2534
|
+
const selectedArtifactRefresh = useMemo(() => {
|
|
2535
|
+
if (!selectedArtifactPath) return { key: artifactRefreshKey, details: undefined };
|
|
2536
|
+
|
|
2537
|
+
let key = 0;
|
|
2538
|
+
let details: Record<string, unknown> | undefined;
|
|
2539
|
+
for (const message of messages) {
|
|
2540
|
+
const candidate = message.details as Record<string, unknown> | undefined;
|
|
2541
|
+
if (!isArtifactRefreshEvent(candidate, selectedArtifactPath)) continue;
|
|
2542
|
+
key++;
|
|
2543
|
+
details = candidate;
|
|
2544
|
+
}
|
|
2545
|
+
return { key, details };
|
|
2546
|
+
}, [artifactRefreshKey, messages, selectedArtifactPath]);
|
|
2547
|
+
const canCollaborateWithArtifacts =
|
|
2548
|
+
interactive && isPlaybackLive && effectiveWorkflowStatus?.toUpperCase() === 'RUNNING';
|
|
2385
2549
|
|
|
2386
2550
|
// PERFORMANCE: Memoize taskLabels to prevent AllMessagesMixed re-renders
|
|
2387
2551
|
const taskLabels = useMemo(
|
|
@@ -2405,7 +2569,7 @@ function ModernAgentConversationInner({
|
|
|
2405
2569
|
workflowRunId={workflowRunId || ''}
|
|
2406
2570
|
viewMode={viewMode}
|
|
2407
2571
|
onViewModeChange={handleViewModeChange}
|
|
2408
|
-
showPlanPanel={
|
|
2572
|
+
showPlanPanel={isRightPanelVisible}
|
|
2409
2573
|
hasPlan={showRightPanelProp && plans.length > 0}
|
|
2410
2574
|
showPlanButton={showRightPanelProp && !conversationTab}
|
|
2411
2575
|
onTogglePlanPanel={handleTogglePlanPanel}
|
|
@@ -2479,6 +2643,7 @@ function ModernAgentConversationInner({
|
|
|
2479
2643
|
taskLabels={taskLabels}
|
|
2480
2644
|
streamingMessages={displayedStreamingMessages}
|
|
2481
2645
|
onSendMessage={isPlaybackLive ? handleSendMessage : undefined}
|
|
2646
|
+
onOpenArtifact={showArtifacts ? handleOpenArtifact : undefined}
|
|
2482
2647
|
messageItemClassNames={messageItemClassNames}
|
|
2483
2648
|
messageStyleOverrides={messageStyleOverrides}
|
|
2484
2649
|
toolCallGroupClassNames={toolCallGroupClassNames}
|
|
@@ -2551,56 +2716,59 @@ function ModernAgentConversationInner({
|
|
|
2551
2716
|
)
|
|
2552
2717
|
) : (
|
|
2553
2718
|
(showInput || canContinueConversation) && (
|
|
2554
|
-
|
|
2555
|
-
|
|
2556
|
-
|
|
2557
|
-
|
|
2558
|
-
|
|
2559
|
-
|
|
2560
|
-
|
|
2561
|
-
|
|
2562
|
-
|
|
2563
|
-
|
|
2564
|
-
|
|
2719
|
+
<>
|
|
2720
|
+
{composerContext}
|
|
2721
|
+
<MessageInput
|
|
2722
|
+
onSend={handleSendMessage}
|
|
2723
|
+
onStop={allowWorkflowControl ? handleStopWorkflow : undefined}
|
|
2724
|
+
approvalModeSlot={
|
|
2725
|
+
interactive && toolApprovalMode ? (
|
|
2726
|
+
<AgentApprovalModeSelector
|
|
2727
|
+
mode={toolApprovalMode}
|
|
2728
|
+
onChange={handleToolApprovalModeChange}
|
|
2729
|
+
disabled={
|
|
2730
|
+
!isPlaybackLive || isWorkflowTerminal || !allowWorkflowControl
|
|
2731
|
+
}
|
|
2732
|
+
/>
|
|
2733
|
+
) : undefined
|
|
2734
|
+
}
|
|
2735
|
+
mcpSlot={
|
|
2736
|
+
<McpConnectionsActionMenu
|
|
2737
|
+
disabledCollections={mcpDisabled}
|
|
2738
|
+
onChange={handleMcpDisabledChange}
|
|
2739
|
+
onConnectionChange={handleMcpConnectionChange}
|
|
2565
2740
|
/>
|
|
2566
|
-
|
|
2567
|
-
|
|
2568
|
-
|
|
2569
|
-
|
|
2570
|
-
|
|
2571
|
-
|
|
2572
|
-
|
|
2573
|
-
|
|
2574
|
-
|
|
2575
|
-
|
|
2576
|
-
|
|
2577
|
-
|
|
2578
|
-
|
|
2579
|
-
|
|
2580
|
-
|
|
2581
|
-
|
|
2582
|
-
|
|
2583
|
-
|
|
2584
|
-
|
|
2585
|
-
|
|
2586
|
-
|
|
2587
|
-
|
|
2588
|
-
|
|
2589
|
-
|
|
2590
|
-
|
|
2591
|
-
|
|
2592
|
-
|
|
2593
|
-
|
|
2594
|
-
|
|
2595
|
-
|
|
2596
|
-
|
|
2597
|
-
onRemoveDocument={onRemoveDocument}
|
|
2598
|
-
hideObjectLinking={hideObjectLinking}
|
|
2599
|
-
hideFileUpload={!canUploadFiles}
|
|
2600
|
-
disableDropZone={canUploadFiles}
|
|
2601
|
-
className={inputContainerClassName}
|
|
2602
|
-
inputClassName={inputClassName}
|
|
2603
|
-
/>
|
|
2741
|
+
}
|
|
2742
|
+
disabled={isUploading || !isPlaybackLive}
|
|
2743
|
+
isSending={isSending || isUploading}
|
|
2744
|
+
isStopping={isStopping}
|
|
2745
|
+
isStreaming={!effectiveIsCompleted}
|
|
2746
|
+
isCompleted={effectiveIsCompleted}
|
|
2747
|
+
contextWindowUsage={canCompactContext ? contextWindowUsage : undefined}
|
|
2748
|
+
onCompactContext={canCompactContext ? handleCompactContext : undefined}
|
|
2749
|
+
isCompactingContext={isCompactingContext}
|
|
2750
|
+
activeTaskCount={activeTaskCount}
|
|
2751
|
+
activeWorkstreams={composerActiveWorkstreams}
|
|
2752
|
+
placeholder={composerPlaceholder}
|
|
2753
|
+
onFilesSelected={canUploadFiles ? handleFileUpload : undefined}
|
|
2754
|
+
uploadedFiles={uploadedFiles}
|
|
2755
|
+
onRemoveFile={onRemoveFile}
|
|
2756
|
+
onRemoveProcessingFile={handleRemoveProcessingFile}
|
|
2757
|
+
acceptedFileTypes={acceptedFileTypes}
|
|
2758
|
+
maxFiles={maxFiles}
|
|
2759
|
+
processingFiles={processingFiles}
|
|
2760
|
+
artifactRunId={agentRunId}
|
|
2761
|
+
hasProcessingFiles={hasProcessingFiles}
|
|
2762
|
+
renderDocumentSearch={renderDocumentSearch}
|
|
2763
|
+
selectedDocuments={selectedDocuments}
|
|
2764
|
+
onRemoveDocument={onRemoveDocument}
|
|
2765
|
+
hideObjectLinking={hideObjectLinking}
|
|
2766
|
+
hideFileUpload={!canUploadFiles}
|
|
2767
|
+
disableDropZone={canUploadFiles}
|
|
2768
|
+
className={inputContainerClassName}
|
|
2769
|
+
inputClassName={inputClassName}
|
|
2770
|
+
/>
|
|
2771
|
+
</>
|
|
2604
2772
|
)
|
|
2605
2773
|
)}
|
|
2606
2774
|
</div>
|
|
@@ -2717,7 +2885,11 @@ function ModernAgentConversationInner({
|
|
|
2717
2885
|
processingFiles={processingFilesProp ?? processingFiles}
|
|
2718
2886
|
// Artifacts
|
|
2719
2887
|
showArtifacts={showArtifacts}
|
|
2720
|
-
artifactRefreshKey={
|
|
2888
|
+
artifactRefreshKey={selectedArtifactRefresh.key}
|
|
2889
|
+
artifactRefreshDetails={selectedArtifactRefresh.details}
|
|
2890
|
+
selectedArtifactPath={selectedArtifactPath}
|
|
2891
|
+
onSelectedArtifactPathChange={setSelectedArtifactPath}
|
|
2892
|
+
onSendMessage={canCollaborateWithArtifacts ? handleSendMessage : undefined}
|
|
2721
2893
|
// Messages (for workstreams tab context)
|
|
2722
2894
|
messages={messages}
|
|
2723
2895
|
// Payload content
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
// @vitest-environment jsdom
|
|
2
|
+
import { cleanup, render, screen } from '@testing-library/react';
|
|
3
|
+
import type React from 'react';
|
|
4
|
+
import { afterEach, describe, expect, it, vi } from 'vitest';
|
|
5
|
+
import { createAgentMarkdownAnchor } from './AgentMarkdownAnchor';
|
|
6
|
+
|
|
7
|
+
afterEach(() => cleanup());
|
|
8
|
+
|
|
9
|
+
describe('createAgentMarkdownAnchor', () => {
|
|
10
|
+
it.each([
|
|
11
|
+
'https://example.com/store/objects/doc-1?view=full#section',
|
|
12
|
+
'//example.com/store/collections/col-1?view=full#section',
|
|
13
|
+
])('keeps external resource-shaped URLs external: %s', (href) => {
|
|
14
|
+
const StoreLinkComponent = vi.fn(() => null);
|
|
15
|
+
const CollectionLinkComponent = vi.fn(() => null);
|
|
16
|
+
const Anchor = createAgentMarkdownAnchor({ StoreLinkComponent, CollectionLinkComponent });
|
|
17
|
+
|
|
18
|
+
render(<Anchor href={href}>External</Anchor>);
|
|
19
|
+
|
|
20
|
+
expect(screen.getByRole('link', { name: 'External' }).getAttribute('href')).toBe(href);
|
|
21
|
+
expect(screen.getByRole('link', { name: 'External' }).getAttribute('target')).toBe('_blank');
|
|
22
|
+
expect(StoreLinkComponent).not.toHaveBeenCalled();
|
|
23
|
+
expect(CollectionLinkComponent).not.toHaveBeenCalled();
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it('passes a clean document id and styling to the host document link', () => {
|
|
27
|
+
const StoreLinkComponent = ({
|
|
28
|
+
href,
|
|
29
|
+
documentId,
|
|
30
|
+
className,
|
|
31
|
+
children,
|
|
32
|
+
}: {
|
|
33
|
+
href: string;
|
|
34
|
+
documentId: string;
|
|
35
|
+
className?: string;
|
|
36
|
+
children: React.ReactNode;
|
|
37
|
+
}) => (
|
|
38
|
+
<a href={href} className={className} data-document-id={documentId}>
|
|
39
|
+
{children}
|
|
40
|
+
</a>
|
|
41
|
+
);
|
|
42
|
+
const Anchor = createAgentMarkdownAnchor({
|
|
43
|
+
StoreLinkComponent,
|
|
44
|
+
addStickyParams: (href) => `${href}&a=account-1`,
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
render(
|
|
48
|
+
<Anchor href="/store/objects/doc-1?revision=rev-1#properties" className="resource-link">
|
|
49
|
+
Document
|
|
50
|
+
</Anchor>,
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
const link = screen.getByRole('link', { name: 'Document' });
|
|
54
|
+
expect(link.getAttribute('data-document-id')).toBe('doc-1');
|
|
55
|
+
expect(link.getAttribute('href')).toBe('/store/objects/doc-1?revision=rev-1#properties&a=account-1');
|
|
56
|
+
expect(link.className).toBe('resource-link');
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
it('passes a clean collection id to the host collection link', () => {
|
|
60
|
+
const CollectionLinkComponent = ({
|
|
61
|
+
href,
|
|
62
|
+
collectionId,
|
|
63
|
+
children,
|
|
64
|
+
}: {
|
|
65
|
+
href: string;
|
|
66
|
+
collectionId: string;
|
|
67
|
+
children: React.ReactNode;
|
|
68
|
+
}) => (
|
|
69
|
+
<a href={href} data-collection-id={collectionId}>
|
|
70
|
+
{children}
|
|
71
|
+
</a>
|
|
72
|
+
);
|
|
73
|
+
const Anchor = createAgentMarkdownAnchor({ CollectionLinkComponent });
|
|
74
|
+
|
|
75
|
+
render(<Anchor href="/store/collections/col-1?tab=objects#top">Collection</Anchor>);
|
|
76
|
+
|
|
77
|
+
expect(screen.getByRole('link', { name: 'Collection' }).getAttribute('data-collection-id')).toBe('col-1');
|
|
78
|
+
});
|
|
79
|
+
});
|