@parhelia/core 0.1.12556 → 0.1.12565
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/dist/agents-view/AgentCard.d.ts +6 -4
- package/dist/agents-view/AgentCard.js +143 -24
- package/dist/agents-view/AgentCard.js.map +1 -1
- package/dist/agents-view/AgentsInbox.d.ts +1 -1
- package/dist/agents-view/AgentsInbox.js +7 -92
- package/dist/agents-view/AgentsInbox.js.map +1 -1
- package/dist/agents-view/AgentsTitlebar.js +3 -2
- package/dist/agents-view/AgentsTitlebar.js.map +1 -1
- package/dist/agents-view/AgentsView.d.ts +6 -7
- package/dist/agents-view/AgentsView.js +191 -99
- package/dist/agents-view/AgentsView.js.map +1 -1
- package/dist/agents-view/AgentsWorkspaceView.d.ts +2 -6
- package/dist/agents-view/AgentsWorkspaceView.js +266 -113
- package/dist/agents-view/AgentsWorkspaceView.js.map +1 -1
- package/dist/agents-view/ProfileAgentsGroup.d.ts +2 -1
- package/dist/agents-view/ProfileAgentsGroup.js +4 -3
- package/dist/agents-view/ProfileAgentsGroup.js.map +1 -1
- package/dist/components/ActionButton.d.ts +1 -1
- package/dist/components/ActionButton.js.map +1 -1
- package/dist/components/FilterInput.d.ts +1 -1
- package/dist/components/FilterInput.js +1 -1
- package/dist/components/FilterInput.js.map +1 -1
- package/dist/components/ui/LanguageSelector.js +2 -4
- package/dist/components/ui/LanguageSelector.js.map +1 -1
- package/dist/components/ui/PlaceholderInput.js +3 -3
- package/dist/components/ui/PlaceholderInput.js.map +1 -1
- package/dist/components/ui/PlaceholderInputTypes.js +1 -1
- package/dist/components/ui/PlaceholderInputTypes.js.map +1 -1
- package/dist/components/ui/alert-dialog.d.ts +1 -1
- package/dist/components/ui/alert-dialog.js +6 -10
- package/dist/components/ui/alert-dialog.js.map +1 -1
- package/dist/components/ui/button.d.ts +4 -4
- package/dist/components/ui/button.js +4 -1
- package/dist/components/ui/button.js.map +1 -1
- package/dist/components/ui/context-menu.d.ts +1 -1
- package/dist/components/ui/context-menu.js +12 -4
- package/dist/components/ui/context-menu.js.map +1 -1
- package/dist/components/ui/copy-button.d.ts +2 -1
- package/dist/components/ui/copy-button.js +2 -2
- package/dist/components/ui/copy-button.js.map +1 -1
- package/dist/components/ui/dialog.d.ts +1 -1
- package/dist/components/ui/dialog.js +21 -126
- package/dist/components/ui/dialog.js.map +1 -1
- package/dist/components/ui/input.d.ts +1 -1
- package/dist/components/ui/input.js +5 -3
- package/dist/components/ui/input.js.map +1 -1
- package/dist/components/ui/paste-button.d.ts +2 -1
- package/dist/components/ui/paste-button.js +2 -2
- package/dist/components/ui/paste-button.js.map +1 -1
- package/dist/components/ui/popover.js +1 -9
- package/dist/components/ui/popover.js.map +1 -1
- package/dist/components/ui/select.js +1 -1
- package/dist/components/ui/select.js.map +1 -1
- package/dist/components/ui/styled-dialog-title.js +1 -1
- package/dist/components/ui/styled-dialog-title.js.map +1 -1
- package/dist/components/ui/tabs.d.ts +1 -1
- package/dist/components/ui/tabs.js +4 -11
- package/dist/components/ui/tabs.js.map +1 -1
- package/dist/config/config.d.ts +4 -2
- package/dist/config/config.js +250 -70
- package/dist/config/config.js.map +1 -1
- package/dist/config/notificationRoutes.js +14 -0
- package/dist/config/notificationRoutes.js.map +1 -1
- package/dist/config/types/workspace.d.ts +6 -0
- package/dist/config/types.d.ts +63 -12
- package/dist/config/types.js.map +1 -1
- package/dist/editor/ConfirmationDialog.js +20 -4
- package/dist/editor/ConfirmationDialog.js.map +1 -1
- package/dist/editor/ContentTree.d.ts +2 -1
- package/dist/editor/ContentTree.js +93 -32
- package/dist/editor/ContentTree.js.map +1 -1
- package/dist/editor/Editor.js +87 -22
- package/dist/editor/Editor.js.map +1 -1
- package/dist/editor/FieldHistory.js +84 -36
- package/dist/editor/FieldHistory.js.map +1 -1
- package/dist/editor/FieldListField.js +21 -9
- package/dist/editor/FieldListField.js.map +1 -1
- package/dist/editor/FieldListFieldWithFallbacks.js +23 -2
- package/dist/editor/FieldListFieldWithFallbacks.js.map +1 -1
- package/dist/editor/GlobalMenuBar.js +29 -2
- package/dist/editor/GlobalMenuBar.js.map +1 -1
- package/dist/editor/ImageEditor.js +5 -2
- package/dist/editor/ImageEditor.js.map +1 -1
- package/dist/editor/ItemInfo.js +36 -1
- package/dist/editor/ItemInfo.js.map +1 -1
- package/dist/editor/LinkEditorDialog.js +3 -0
- package/dist/editor/LinkEditorDialog.js.map +1 -1
- package/dist/editor/MainLayout.d.ts +0 -2
- package/dist/editor/MainLayout.js +65 -8
- package/dist/editor/MainLayout.js.map +1 -1
- package/dist/editor/MigrationsView.js +29 -5
- package/dist/editor/MigrationsView.js.map +1 -1
- package/dist/editor/MobileLayout.js +37 -12
- package/dist/editor/MobileLayout.js.map +1 -1
- package/dist/editor/PictureCropper.js +54 -45
- package/dist/editor/PictureCropper.js.map +1 -1
- package/dist/editor/PictureEditor.js +17 -15
- package/dist/editor/PictureEditor.js.map +1 -1
- package/dist/editor/QuickItemSwitcher.js +21 -21
- package/dist/editor/QuickItemSwitcher.js.map +1 -1
- package/dist/editor/SetupWizard.js +52 -12
- package/dist/editor/SetupWizard.js.map +1 -1
- package/dist/editor/Titlebar.js +7 -2
- package/dist/editor/Titlebar.js.map +1 -1
- package/dist/editor/ai/AgentCostDisplay.d.ts +1 -0
- package/dist/editor/ai/AgentCostDisplay.js +1 -1
- package/dist/editor/ai/AgentCostDisplay.js.map +1 -1
- package/dist/editor/ai/AgentDocumentList.js +32 -14
- package/dist/editor/ai/AgentDocumentList.js.map +1 -1
- package/dist/editor/ai/AgentGreeting.js +3 -2
- package/dist/editor/ai/AgentGreeting.js.map +1 -1
- package/dist/editor/ai/AgentProfileSelector.js +2 -1
- package/dist/editor/ai/AgentProfileSelector.js.map +1 -1
- package/dist/editor/ai/AgentStatusBadge.d.ts +0 -5
- package/dist/editor/ai/AgentStatusBadge.js +67 -65
- package/dist/editor/ai/AgentStatusBadge.js.map +1 -1
- package/dist/editor/ai/AgentTerminal.d.ts +14 -2
- package/dist/editor/ai/AgentTerminal.js +2406 -496
- package/dist/editor/ai/AgentTerminal.js.map +1 -1
- package/dist/editor/ai/AgentTerminalStatusBar.d.ts +8 -3
- package/dist/editor/ai/AgentTerminalStatusBar.js +481 -56
- package/dist/editor/ai/AgentTerminalStatusBar.js.map +1 -1
- package/dist/editor/ai/Agents.js +161 -113
- package/dist/editor/ai/Agents.js.map +1 -1
- package/dist/editor/ai/AiResponseMessage.d.ts +10 -1
- package/dist/editor/ai/AiResponseMessage.js +267 -26
- package/dist/editor/ai/AiResponseMessage.js.map +1 -1
- package/dist/editor/ai/ContextInfoBar.d.ts +2 -3
- package/dist/editor/ai/ContextInfoBar.js +64 -7
- package/dist/editor/ai/ContextInfoBar.js.map +1 -1
- package/dist/editor/ai/GuidanceOverlay.js +17 -11
- package/dist/editor/ai/GuidanceOverlay.js.map +1 -1
- package/dist/editor/ai/InlineAiDialog.d.ts +1 -1
- package/dist/editor/ai/InlineAiDialog.js +514 -192
- package/dist/editor/ai/InlineAiDialog.js.map +1 -1
- package/dist/editor/ai/InlineAiTrigger.js +115 -12
- package/dist/editor/ai/InlineAiTrigger.js.map +1 -1
- package/dist/editor/ai/MediaImage.js +40 -8
- package/dist/editor/ai/MediaImage.js.map +1 -1
- package/dist/editor/ai/SpawnedAgentsPanel.js +10 -12
- package/dist/editor/ai/SpawnedAgentsPanel.js.map +1 -1
- package/dist/editor/ai/ToolCallDisplay.d.ts +22 -2
- package/dist/editor/ai/ToolCallDisplay.js +542 -150
- package/dist/editor/ai/ToolCallDisplay.js.map +1 -1
- package/dist/editor/ai/agentDiagnostics.d.ts +7 -0
- package/dist/editor/ai/agentDiagnostics.js.map +1 -1
- package/dist/editor/ai/dialogs/AgentDialogHandler.d.ts +1 -8
- package/dist/editor/ai/dialogs/AgentDialogHandler.js +379 -42
- package/dist/editor/ai/dialogs/AgentDialogHandler.js.map +1 -1
- package/dist/editor/ai/dialogs/QuestionnaireInline.d.ts +5 -1
- package/dist/editor/ai/dialogs/QuestionnaireInline.js +628 -60
- package/dist/editor/ai/dialogs/QuestionnaireInline.js.map +1 -1
- package/dist/editor/ai/dialogs/agentDialogTypes.d.ts +115 -0
- package/dist/editor/ai/dialogs/agentDialogTypes.js +2 -0
- package/dist/editor/ai/dialogs/agentDialogTypes.js.map +1 -1
- package/dist/editor/ai/types.d.ts +3 -1
- package/dist/editor/ai/useAgentStatus.d.ts +2 -1
- package/dist/editor/ai/useAgentStatus.js +90 -100
- package/dist/editor/ai/useAgentStatus.js.map +1 -1
- package/dist/editor/ai/useInlineAiPosition.js +45 -5
- package/dist/editor/ai/useInlineAiPosition.js.map +1 -1
- package/dist/editor/client/AboutDialog.js +4 -2
- package/dist/editor/client/AboutDialog.js.map +1 -1
- package/dist/editor/client/EditorShell.d.ts +4 -1
- package/dist/editor/client/EditorShell.js +770 -237
- package/dist/editor/client/EditorShell.js.map +1 -1
- package/dist/editor/client/editContext.d.ts +33 -19
- package/dist/editor/client/editContext.js.map +1 -1
- package/dist/editor/client/helpers.js +6 -0
- package/dist/editor/client/helpers.js.map +1 -1
- package/dist/editor/client/hooks/useEditorUrlSync.js +1 -2
- package/dist/editor/client/hooks/useEditorUrlSync.js.map +1 -1
- package/dist/editor/client/hooks/useEditorWebSocket.d.ts +10 -0
- package/dist/editor/client/hooks/useEditorWebSocket.js +209 -14
- package/dist/editor/client/hooks/useEditorWebSocket.js.map +1 -1
- package/dist/editor/client/hooks/useQuota.d.ts +8 -0
- package/dist/editor/client/hooks/useQuota.js.map +1 -1
- package/dist/editor/client/hooks/useSocketMessageHandler.js +73 -15
- package/dist/editor/client/hooks/useSocketMessageHandler.js.map +1 -1
- package/dist/editor/client/itemsRepository.js +10 -6
- package/dist/editor/client/itemsRepository.js.map +1 -1
- package/dist/editor/client/navigation.js +35 -3
- package/dist/editor/client/navigation.js.map +1 -1
- package/dist/editor/client/operations.d.ts +6 -3
- package/dist/editor/client/operations.js +208 -30
- package/dist/editor/client/operations.js.map +1 -1
- package/dist/editor/client/pageModelBuilder.js +4 -31
- package/dist/editor/client/pageModelBuilder.js.map +1 -1
- package/dist/editor/client/ui/DevModeIndicator.js +2 -2
- package/dist/editor/client/ui/DevModeIndicator.js.map +1 -1
- package/dist/editor/client/ui/EditorChrome.d.ts +0 -6
- package/dist/editor/client/ui/EditorChrome.js +55 -72
- package/dist/editor/client/ui/EditorChrome.js.map +1 -1
- package/dist/editor/client/ui/FullscreenControls.js +5 -3
- package/dist/editor/client/ui/FullscreenControls.js.map +1 -1
- package/dist/editor/commands/commands.d.ts +11 -1
- package/dist/editor/commands/commands.js +12 -1
- package/dist/editor/commands/commands.js.map +1 -1
- package/dist/editor/commands/componentCommands.js +109 -55
- package/dist/editor/commands/componentCommands.js.map +1 -1
- package/dist/editor/commands/customCommandConverter.d.ts +8 -1
- package/dist/editor/commands/customCommandConverter.js +35 -5
- package/dist/editor/commands/customCommandConverter.js.map +1 -1
- package/dist/editor/commands/handlers/agentHandler.js +2 -1
- package/dist/editor/commands/handlers/agentHandler.js.map +1 -1
- package/dist/editor/commands/itemCommands.d.ts +3 -0
- package/dist/editor/commands/itemCommands.js +93 -10
- package/dist/editor/commands/itemCommands.js.map +1 -1
- package/dist/editor/commands/undo.d.ts +9 -15
- package/dist/editor/commands/undo.js +24 -0
- package/dist/editor/commands/undo.js.map +1 -1
- package/dist/editor/context-menu/InsertMenu.js +83 -39
- package/dist/editor/context-menu/InsertMenu.js.map +1 -1
- package/dist/editor/field-types/MultiLineText.js +1 -1
- package/dist/editor/field-types/MultiLineText.js.map +1 -1
- package/dist/editor/field-types/RawEditor.js +1 -1
- package/dist/editor/field-types/RichTextEditor.js +13 -5
- package/dist/editor/field-types/RichTextEditor.js.map +1 -1
- package/dist/editor/field-types/RichTextEditorComponent.js +37 -3
- package/dist/editor/field-types/RichTextEditorComponent.js.map +1 -1
- package/dist/editor/field-types/SingleLineText.js +1 -1
- package/dist/editor/field-types/TreeListEditor.js +3 -2
- package/dist/editor/field-types/TreeListEditor.js.map +1 -1
- package/dist/editor/field-types/richtext/components/ReactSlate.css +23 -5
- package/dist/editor/field-types/richtext/components/ReactSlate.d.ts +2 -0
- package/dist/editor/field-types/richtext/components/ReactSlate.js +28 -4
- package/dist/editor/field-types/richtext/components/ReactSlate.js.map +1 -1
- package/dist/editor/field-types/richtext/components/ToolbarButton.js +4 -2
- package/dist/editor/field-types/richtext/components/ToolbarButton.js.map +1 -1
- package/dist/editor/field-types/richtext/contextMenuFactory.d.ts +13 -0
- package/dist/editor/field-types/richtext/contextMenuFactory.js +181 -24
- package/dist/editor/field-types/richtext/contextMenuFactory.js.map +1 -1
- package/dist/editor/field-types/richtext/types.d.ts +2 -0
- package/dist/editor/field-types/richtext/types.js.map +1 -1
- package/dist/editor/field-types/richtext/utils/plugins.js +4 -0
- package/dist/editor/field-types/richtext/utils/plugins.js.map +1 -1
- package/dist/editor/field-types/textContextMenuFactory.js +3 -2
- package/dist/editor/field-types/textContextMenuFactory.js.map +1 -1
- package/dist/editor/media-selector/AiImageSearchPrompt.js +4 -2
- package/dist/editor/media-selector/AiImageSearchPrompt.js.map +1 -1
- package/dist/editor/media-selector/MediaFolderBrowser.js +1 -1
- package/dist/editor/media-selector/MediaFolderBrowser.js.map +1 -1
- package/dist/editor/media-selector/MediaSelector.js +7 -1
- package/dist/editor/media-selector/MediaSelector.js.map +1 -1
- package/dist/editor/media-selector/TreeSelector.js +40 -35
- package/dist/editor/media-selector/TreeSelector.js.map +1 -1
- package/dist/editor/menubar/ActiveUsers.js +1 -1
- package/dist/editor/menubar/ActiveUsers.js.map +1 -1
- package/dist/editor/menubar/GenericToolbar.js +4 -2
- package/dist/editor/menubar/GenericToolbar.js.map +1 -1
- package/dist/editor/menubar/ItemLanguageVersion.js +2 -2
- package/dist/editor/menubar/ItemLanguageVersion.js.map +1 -1
- package/dist/editor/menubar/PageSelector.js +26 -147
- package/dist/editor/menubar/PageSelector.js.map +1 -1
- package/dist/editor/menubar/Separator.js +1 -1
- package/dist/editor/menubar/VersionSelector.js +2 -4
- package/dist/editor/menubar/VersionSelector.js.map +1 -1
- package/dist/editor/menubar/WorkflowButton.js +39 -12
- package/dist/editor/menubar/WorkflowButton.js.map +1 -1
- package/dist/editor/menubar/toolbar-sections/CustomCommandsToolbar.js +16 -38
- package/dist/editor/menubar/toolbar-sections/CustomCommandsToolbar.js.map +1 -1
- package/dist/editor/menubar/toolbar-sections/EditControls.js +3 -3
- package/dist/editor/menubar/toolbar-sections/EditControls.js.map +1 -1
- package/dist/editor/menubar/toolbar-sections/HelpButton.js +1 -0
- package/dist/editor/menubar/toolbar-sections/HelpButton.js.map +1 -1
- package/dist/editor/menubar/toolbar-sections/ManualBrowser.d.ts +6 -10
- package/dist/editor/menubar/toolbar-sections/ManualBrowser.js +597 -220
- package/dist/editor/menubar/toolbar-sections/ManualBrowser.js.map +1 -1
- package/dist/editor/menubar/toolbar-sections/UtilityControls.js +13 -2
- package/dist/editor/menubar/toolbar-sections/UtilityControls.js.map +1 -1
- package/dist/editor/page-editor-chrome/CommentHighlighting.js +42 -1
- package/dist/editor/page-editor-chrome/CommentHighlighting.js.map +1 -1
- package/dist/editor/page-editor-chrome/FrameMenu.js +1 -1
- package/dist/editor/page-editor-chrome/FrameMenu.js.map +1 -1
- package/dist/editor/page-editor-chrome/InlineEditor.js +97 -48
- package/dist/editor/page-editor-chrome/InlineEditor.js.map +1 -1
- package/dist/editor/page-editor-chrome/PlaceholderDropZone.js +38 -17
- package/dist/editor/page-editor-chrome/PlaceholderDropZone.js.map +1 -1
- package/dist/editor/page-editor-chrome/PlaceholderDropZones.js +17 -11
- package/dist/editor/page-editor-chrome/PlaceholderDropZones.js.map +1 -1
- package/dist/editor/page-editor-chrome/useInlineAICompletion.js +301 -301
- package/dist/editor/page-editor-chrome/useInlineAICompletion.js.map +1 -1
- package/dist/editor/page-viewer/DeviceToolbar.js +1 -1
- package/dist/editor/page-viewer/DeviceToolbar.js.map +1 -1
- package/dist/editor/page-viewer/EditorForm.js +69 -11
- package/dist/editor/page-viewer/EditorForm.js.map +1 -1
- package/dist/editor/page-viewer/MiniMap.d.ts +2 -4
- package/dist/editor/page-viewer/MiniMap.js +91 -28
- package/dist/editor/page-viewer/MiniMap.js.map +1 -1
- package/dist/editor/page-viewer/PageViewer.d.ts +3 -1
- package/dist/editor/page-viewer/PageViewer.js +92 -19
- package/dist/editor/page-viewer/PageViewer.js.map +1 -1
- package/dist/editor/page-viewer/PageViewerFrame.d.ts +2 -1
- package/dist/editor/page-viewer/PageViewerFrame.js +348 -115
- package/dist/editor/page-viewer/PageViewerFrame.js.map +1 -1
- package/dist/editor/page-viewer/pageModelSkeletonBuilder.js +114 -49
- package/dist/editor/page-viewer/pageModelSkeletonBuilder.js.map +1 -1
- package/dist/editor/page-viewer/pageViewContext.d.ts +1 -0
- package/dist/editor/page-viewer/pageViewContext.js +51 -14
- package/dist/editor/page-viewer/pageViewContext.js.map +1 -1
- package/dist/editor/pageModel.d.ts +14 -1
- package/dist/editor/reviews/Comment.js +26 -12
- package/dist/editor/reviews/Comment.js.map +1 -1
- package/dist/editor/reviews/CommentDisplayPopover.js +7 -5
- package/dist/editor/reviews/CommentDisplayPopover.js.map +1 -1
- package/dist/editor/reviews/CommentView.js +19 -4
- package/dist/editor/reviews/CommentView.js.map +1 -1
- package/dist/editor/reviews/Comments.js +89 -72
- package/dist/editor/reviews/Comments.js.map +1 -1
- package/dist/editor/reviews/CreateReviewDialog.js +281 -177
- package/dist/editor/reviews/CreateReviewDialog.js.map +1 -1
- package/dist/editor/reviews/DecisionsMatrix.js +96 -25
- package/dist/editor/reviews/DecisionsMatrix.js.map +1 -1
- package/dist/editor/reviews/DiffView.js +7 -14
- package/dist/editor/reviews/DiffView.js.map +1 -1
- package/dist/editor/reviews/EditReviewSettingsDialog.js +6 -4
- package/dist/editor/reviews/EditReviewSettingsDialog.js.map +1 -1
- package/dist/editor/reviews/MultiReviewManager.js +25 -3
- package/dist/editor/reviews/MultiReviewManager.js.map +1 -1
- package/dist/editor/reviews/PagesPanel.js +31 -15
- package/dist/editor/reviews/PagesPanel.js.map +1 -1
- package/dist/editor/reviews/PreviewInfo.js +1 -4
- package/dist/editor/reviews/PreviewInfo.js.map +1 -1
- package/dist/editor/reviews/ReviewCard.js +13 -7
- package/dist/editor/reviews/ReviewCard.js.map +1 -1
- package/dist/editor/reviews/ReviewDetail.js +3 -2
- package/dist/editor/reviews/ReviewDetail.js.map +1 -1
- package/dist/editor/reviews/ReviewsList.js +7 -3
- package/dist/editor/reviews/ReviewsList.js.map +1 -1
- package/dist/editor/reviews/SuggestedEdit.js +34 -3
- package/dist/editor/reviews/SuggestedEdit.js.map +1 -1
- package/dist/editor/reviews/SuggestionDisplayPopover.js +31 -5
- package/dist/editor/reviews/SuggestionDisplayPopover.js.map +1 -1
- package/dist/editor/reviews/commentAi.js +25 -6
- package/dist/editor/reviews/commentAi.js.map +1 -1
- package/dist/editor/reviews/reviewCommands.js +4 -1
- package/dist/editor/reviews/reviewCommands.js.map +1 -1
- package/dist/editor/reviews/useMultiReview.js +2 -2
- package/dist/editor/reviews/useMultiReview.js.map +1 -1
- package/dist/editor/reviews/useReviews.d.ts +2 -2
- package/dist/editor/reviews/useReviews.js +12 -30
- package/dist/editor/reviews/useReviews.js.map +1 -1
- package/dist/editor/services/agentErrorMessage.d.ts +1 -0
- package/dist/editor/services/agentErrorMessage.js +91 -0
- package/dist/editor/services/agentErrorMessage.js.map +1 -0
- package/dist/editor/services/agentService.d.ts +229 -5
- package/dist/editor/services/agentService.js +292 -39
- package/dist/editor/services/agentService.js.map +1 -1
- package/dist/editor/services/agentStatus.d.ts +1 -0
- package/dist/editor/services/agentStatus.js +19 -0
- package/dist/editor/services/agentStatus.js.map +1 -1
- package/dist/editor/services/aiService.d.ts +57 -1
- package/dist/editor/services/aiService.js +79 -6
- package/dist/editor/services/aiService.js.map +1 -1
- package/dist/editor/services/contentService.d.ts +6 -3
- package/dist/editor/services/contentService.js +13 -12
- package/dist/editor/services/contentService.js.map +1 -1
- package/dist/editor/services/editService.d.ts +52 -1
- package/dist/editor/services/editService.js +94 -2
- package/dist/editor/services/editService.js.map +1 -1
- package/dist/editor/services/indexService.js +1 -1
- package/dist/editor/services/indexService.js.map +1 -1
- package/dist/editor/services/reviewsService.d.ts +3 -6
- package/dist/editor/services/reviewsService.js +2 -11
- package/dist/editor/services/reviewsService.js.map +1 -1
- package/dist/editor/services/serviceHelper.d.ts +2 -1
- package/dist/editor/services/serviceHelper.js +112 -20
- package/dist/editor/services/serviceHelper.js.map +1 -1
- package/dist/editor/services/systemService.d.ts +2 -1
- package/dist/editor/services/systemService.js +3 -0
- package/dist/editor/services/systemService.js.map +1 -1
- package/dist/editor/services-server/api.d.ts +1 -2
- package/dist/editor/services-server/api.js +11 -6
- package/dist/editor/services-server/api.js.map +1 -1
- package/dist/editor/settings/About.js +317 -3
- package/dist/editor/settings/About.js.map +1 -1
- package/dist/editor/settings/QuotaInfo.js +210 -4
- package/dist/editor/settings/QuotaInfo.js.map +1 -1
- package/dist/editor/settings/SettingsView.js +25 -23
- package/dist/editor/settings/SettingsView.js.map +1 -1
- package/dist/editor/settings/Status.js +7 -6
- package/dist/editor/settings/Status.js.map +1 -1
- package/dist/editor/settings/index/useIndexStatus.js +20 -22
- package/dist/editor/settings/index/useIndexStatus.js.map +1 -1
- package/dist/editor/settings/panels/AgentsPanel.d.ts +0 -4
- package/dist/editor/settings/panels/AgentsPanel.js +95 -121
- package/dist/editor/settings/panels/AgentsPanel.js.map +1 -1
- package/dist/editor/settings/panels/ModelsPanel.js +329 -108
- package/dist/editor/settings/panels/ModelsPanel.js.map +1 -1
- package/dist/editor/settings/panels/ProvidersPanel.d.ts +1 -1
- package/dist/editor/settings/panels/ProvidersPanel.js +86 -59
- package/dist/editor/settings/panels/ProvidersPanel.js.map +1 -1
- package/dist/editor/settings/panels/SearchConfigPanel.js +4 -4
- package/dist/editor/settings/panels/SearchConfigPanel.js.map +1 -1
- package/dist/editor/settings/panels/index.d.ts +3 -2
- package/dist/editor/settings/panels/index.js +3 -2
- package/dist/editor/settings/panels/index.js.map +1 -1
- package/dist/editor/settings/status/coreStatusChecks.js +124 -19
- package/dist/editor/settings/status/coreStatusChecks.js.map +1 -1
- package/dist/editor/settings/status/useStartupChecks.d.ts +3 -1
- package/dist/editor/settings/status/useStartupChecks.js +9 -5
- package/dist/editor/settings/status/useStartupChecks.js.map +1 -1
- package/dist/editor/setup-wizard/steps/CompleteStep.d.ts +2 -1
- package/dist/editor/setup-wizard/steps/CompleteStep.js +2 -1
- package/dist/editor/setup-wizard/steps/CompleteStep.js.map +1 -1
- package/dist/editor/sidebar/ComponentPalette.js +2 -1
- package/dist/editor/sidebar/ComponentPalette.js.map +1 -1
- package/dist/editor/sidebar/ComponentTree.d.ts +8 -1
- package/dist/editor/sidebar/ComponentTree.js +216 -69
- package/dist/editor/sidebar/ComponentTree.js.map +1 -1
- package/dist/editor/sidebar/EditHistory.js +22 -46
- package/dist/editor/sidebar/EditHistory.js.map +1 -1
- package/dist/editor/sidebar/Favorites.js +4 -8
- package/dist/editor/sidebar/Favorites.js.map +1 -1
- package/dist/editor/sidebar/MainContentTree.js +4 -3
- package/dist/editor/sidebar/MainContentTree.js.map +1 -1
- package/dist/editor/sidebar/OperationItem.js +21 -7
- package/dist/editor/sidebar/OperationItem.js.map +1 -1
- package/dist/editor/sidebar/SidebarPanel.d.ts +3 -1
- package/dist/editor/sidebar/SidebarPanel.js +44 -12
- package/dist/editor/sidebar/SidebarPanel.js.map +1 -1
- package/dist/editor/sidebar/SidebarStack.d.ts +2 -1
- package/dist/editor/sidebar/SidebarStack.js +4 -3
- package/dist/editor/sidebar/SidebarStack.js.map +1 -1
- package/dist/editor/sidebar/Validation.js +24 -12
- package/dist/editor/sidebar/Validation.js.map +1 -1
- package/dist/editor/sidebar/Workbox.js +53 -3
- package/dist/editor/sidebar/Workbox.js.map +1 -1
- package/dist/editor/sidebar/WorkspaceRail.d.ts +0 -1
- package/dist/editor/sidebar/WorkspaceRail.js +56 -167
- package/dist/editor/sidebar/WorkspaceRail.js.map +1 -1
- package/dist/editor/tree-indicators/GutterColumns.d.ts +3 -1
- package/dist/editor/tree-indicators/GutterColumns.js +26 -5
- package/dist/editor/tree-indicators/GutterColumns.js.map +1 -1
- package/dist/editor/tree-indicators/GutterContext.d.ts +4 -0
- package/dist/editor/tree-indicators/GutterContext.js +23 -0
- package/dist/editor/tree-indicators/GutterContext.js.map +1 -1
- package/dist/editor/tree-indicators/index.d.ts +0 -1
- package/dist/editor/tree-indicators/index.js +0 -1
- package/dist/editor/tree-indicators/index.js.map +1 -1
- package/dist/editor/tree-indicators/types.d.ts +12 -1
- package/dist/editor/ui/CopyMoveTargetSelectorDialog.js +1 -1
- package/dist/editor/ui/CopyMoveTargetSelectorDialog.js.map +1 -1
- package/dist/editor/ui/Icons.js +1 -1
- package/dist/editor/ui/Icons.js.map +1 -1
- package/dist/editor/ui/ItemNameDialogNew.d.ts +2 -0
- package/dist/editor/ui/ItemNameDialogNew.js +33 -17
- package/dist/editor/ui/ItemNameDialogNew.js.map +1 -1
- package/dist/editor/ui/ItemSearch.js +7 -11
- package/dist/editor/ui/ItemSearch.js.map +1 -1
- package/dist/editor/ui/SimpleIconButton.js +1 -1
- package/dist/editor/ui/SimpleIconButton.js.map +1 -1
- package/dist/editor/ui/SimpleTabs.d.ts +1 -0
- package/dist/editor/ui/SimpleTabs.js +45 -25
- package/dist/editor/ui/SimpleTabs.js.map +1 -1
- package/dist/editor/ui/Splitter.d.ts +1 -0
- package/dist/editor/ui/Splitter.js +102 -86
- package/dist/editor/ui/Splitter.js.map +1 -1
- package/dist/editor/ui/TemplateSelectorDialog.js +4 -4
- package/dist/editor/ui/TemplateSelectorDialog.js.map +1 -1
- package/dist/editor/ui/TreeListSelector.d.ts +6 -1
- package/dist/editor/ui/TreeListSelector.js +2 -2
- package/dist/editor/ui/TreeListSelector.js.map +1 -1
- package/dist/editor/utils/keyboardNavigation.d.ts +6 -20
- package/dist/editor/utils/keyboardNavigation.js +48 -140
- package/dist/editor/utils/keyboardNavigation.js.map +1 -1
- package/dist/editor/utils.js +19 -9
- package/dist/editor/utils.js.map +1 -1
- package/dist/editor/views/CompareView.d.ts +3 -1
- package/dist/editor/views/CompareView.js +7 -5
- package/dist/editor/views/CompareView.js.map +1 -1
- package/dist/editor/views/EditView.js +1 -1
- package/dist/editor/views/EditView.js.map +1 -1
- package/dist/editor/views/EditorSlot.js +27 -34
- package/dist/editor/views/EditorSlot.js.map +1 -1
- package/dist/editor/views/ItemEditor.js +7 -3
- package/dist/editor/views/ItemEditor.js.map +1 -1
- package/dist/editor/views/MediaFolderEditView.js +1 -1
- package/dist/editor/views/MediaFolderEditView.js.map +1 -1
- package/dist/editor/views/ParheliaView.js +5 -6
- package/dist/editor/views/ParheliaView.js.map +1 -1
- package/dist/editor/views/SingleEditView.d.ts +2 -1
- package/dist/editor/views/SingleEditView.js +10 -8
- package/dist/editor/views/SingleEditView.js.map +1 -1
- package/dist/editor/views/editorSlotContext.js +35 -6
- package/dist/editor/views/editorSlotContext.js.map +1 -1
- package/dist/index.d.ts +16 -2
- package/dist/index.js +11 -0
- package/dist/index.js.map +1 -1
- package/dist/revision.d.ts +2 -2
- package/dist/revision.js +2 -2
- package/dist/setup/services/setupWizardService.d.ts +40 -13
- package/dist/setup/services/setupWizardService.js +32 -17
- package/dist/setup/services/setupWizardService.js.map +1 -1
- package/dist/setup/wizard/steps/AddModelDialog.js +12 -3
- package/dist/setup/wizard/steps/AddModelDialog.js.map +1 -1
- package/dist/setup/wizard/steps/ImportModelDialog.js +39 -22
- package/dist/setup/wizard/steps/ImportModelDialog.js.map +1 -1
- package/dist/splash-screen/ModernSplashScreen.js +112 -32
- package/dist/splash-screen/ModernSplashScreen.js.map +1 -1
- package/dist/splash-screen/NewPage.js +33 -50
- package/dist/splash-screen/NewPage.js.map +1 -1
- package/dist/splash-screen/OpenPage.js +2 -6
- package/dist/splash-screen/OpenPage.js.map +1 -1
- package/dist/splash-screen/ParheliaAssistantChat.js +12 -29
- package/dist/splash-screen/ParheliaAssistantChat.js.map +1 -1
- package/dist/splash-screen/ParheliaLogo.js +87 -37
- package/dist/splash-screen/ParheliaLogo.js.map +1 -1
- package/dist/splash-screen/RecentPages.js +3 -3
- package/dist/splash-screen/RecentPages.js.map +1 -1
- package/dist/tour/Tour.d.ts +2 -1
- package/dist/tour/Tour.js +256 -75
- package/dist/tour/Tour.js.map +1 -1
- package/dist/tour/default-tour.js +222 -96
- package/dist/tour/default-tour.js.map +1 -1
- package/dist/types.d.ts +63 -29
- package/package.json +19 -15
- package/styles.css +39 -10
- package/dist/editor/ComponentInfo.d.ts +0 -4
- package/dist/editor/ComponentInfo.js +0 -41
- package/dist/editor/ComponentInfo.js.map +0 -1
- package/dist/editor/ai/HelpTerminal.d.ts +0 -5
- package/dist/editor/ai/HelpTerminal.js +0 -166
- package/dist/editor/ai/HelpTerminal.js.map +0 -1
- package/dist/editor/field-types/ReactQuill.d.ts +0 -125
- package/dist/editor/field-types/ReactQuill.js +0 -385
- package/dist/editor/field-types/ReactQuill.js.map +0 -1
- package/dist/editor/services-server/graphQL.d.ts +0 -29
- package/dist/editor/services-server/graphQL.js +0 -53
- package/dist/editor/services-server/graphQL.js.map +0 -1
- package/dist/editor/settings/AllAgentsPanel.d.ts +0 -5
- package/dist/editor/settings/AllAgentsPanel.js +0 -139
- package/dist/editor/settings/AllAgentsPanel.js.map +0 -1
- package/dist/editor/settings/LatestFeedback.d.ts +0 -1
- package/dist/editor/settings/LatestFeedback.js +0 -136
- package/dist/editor/settings/LatestFeedback.js.map +0 -1
- package/dist/editor/settings/Setup.d.ts +0 -1
- package/dist/editor/settings/Setup.js +0 -211
- package/dist/editor/settings/Setup.js.map +0 -1
- package/dist/editor/settings/panels/DatabasePanel.d.ts +0 -6
- package/dist/editor/settings/panels/DatabasePanel.js +0 -50
- package/dist/editor/settings/panels/DatabasePanel.js.map +0 -1
- package/dist/editor/settings/setup-steps/AiSetupStep/EmbeddingsModelSection.d.ts +0 -2
- package/dist/editor/settings/setup-steps/AiSetupStep/EmbeddingsModelSection.js +0 -195
- package/dist/editor/settings/setup-steps/AiSetupStep/EmbeddingsModelSection.js.map +0 -1
- package/dist/editor/settings/setup-steps/AiSetupStep/index.d.ts +0 -2
- package/dist/editor/settings/setup-steps/AiSetupStep/index.js +0 -21
- package/dist/editor/settings/setup-steps/AiSetupStep/index.js.map +0 -1
- package/dist/editor/settings/setup-steps/AiSetupStep/provider/ProviderSection.d.ts +0 -1
- package/dist/editor/settings/setup-steps/AiSetupStep/provider/ProviderSection.js +0 -233
- package/dist/editor/settings/setup-steps/AiSetupStep/provider/ProviderSection.js.map +0 -1
- package/dist/editor/settings/setup-steps/AiSetupStep/required-containers/RequiredContainersList.d.ts +0 -15
- package/dist/editor/settings/setup-steps/AiSetupStep/required-containers/RequiredContainersList.js +0 -14
- package/dist/editor/settings/setup-steps/AiSetupStep/required-containers/RequiredContainersList.js.map +0 -1
- package/dist/editor/settings/setup-steps/AiSetupStep/required-containers/RequiredContainersSection.d.ts +0 -1
- package/dist/editor/settings/setup-steps/AiSetupStep/required-containers/RequiredContainersSection.js +0 -94
- package/dist/editor/settings/setup-steps/AiSetupStep/required-containers/RequiredContainersSection.js.map +0 -1
- package/dist/editor/settings/setup-steps/AiSetupStep/types.d.ts +0 -1
- package/dist/editor/settings/setup-steps/AiSetupStep/types.js +0 -2
- package/dist/editor/settings/setup-steps/AiSetupStep/types.js.map +0 -1
- package/dist/editor/settings/setup-steps/AiSetupStep/utils.d.ts +0 -5
- package/dist/editor/settings/setup-steps/AiSetupStep/utils.js +0 -44
- package/dist/editor/settings/setup-steps/AiSetupStep/utils.js.map +0 -1
- package/dist/editor/settings/setup-steps/IndexSetupStep.d.ts +0 -2
- package/dist/editor/settings/setup-steps/IndexSetupStep.js +0 -36
- package/dist/editor/settings/setup-steps/IndexSetupStep.js.map +0 -1
- package/dist/editor/settings/setup-steps/SettingsSetupStep.d.ts +0 -2
- package/dist/editor/settings/setup-steps/SettingsSetupStep.js +0 -111
- package/dist/editor/settings/setup-steps/SettingsSetupStep.js.map +0 -1
- package/dist/editor/settings/setup-steps/SetupOverview.d.ts +0 -14
- package/dist/editor/settings/setup-steps/SetupOverview.js +0 -38
- package/dist/editor/settings/setup-steps/SetupOverview.js.map +0 -1
- package/dist/editor/sidebar/Debug.d.ts +0 -1
- package/dist/editor/sidebar/Debug.js +0 -70
- package/dist/editor/sidebar/Debug.js.map +0 -1
- package/dist/editor/sidebar/GraphQL.d.ts +0 -2
- package/dist/editor/sidebar/GraphQL.js +0 -234
- package/dist/editor/sidebar/GraphQL.js.map +0 -1
- package/dist/editor/sidebar/LeftToolbar.d.ts +0 -1
- package/dist/editor/sidebar/LeftToolbar.js +0 -12
- package/dist/editor/sidebar/LeftToolbar.js.map +0 -1
- package/dist/editor/sidebar/NavigationSidebar.d.ts +0 -4
- package/dist/editor/sidebar/NavigationSidebar.js +0 -254
- package/dist/editor/sidebar/NavigationSidebar.js.map +0 -1
- package/dist/editor/tree-indicators/GutterSelector.d.ts +0 -5
- package/dist/editor/tree-indicators/GutterSelector.js +0 -91
- package/dist/editor/tree-indicators/GutterSelector.js.map +0 -1
|
@@ -1,27 +1,188 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { useState, useCallback, useRef, useEffect, useLayoutEffect, useMemo } from "react";
|
|
4
|
-
import { Sparkles, Check, X,
|
|
4
|
+
import { Sparkles, Check, X, SendHorizonal, Wand2, RotateCcw, Maximize2, History, Cpu, RotateCw, StopCircle, } from "lucide-react";
|
|
5
5
|
import { Button } from "../../components/ui/button";
|
|
6
|
+
import { Badge } from "../../components/ui/badge";
|
|
6
7
|
import { Textarea } from "../../components/ui/textarea";
|
|
7
8
|
import { Popover, PopoverTrigger, PopoverContent } from "../../components/ui/popover";
|
|
8
9
|
import { cn } from "../../lib/utils";
|
|
10
|
+
import { sanitizeSvg } from "../../lib/sanitize";
|
|
9
11
|
import { useEditContext } from "../client/editContext";
|
|
10
12
|
import { startAgent, closeAgent } from "../services/agentService";
|
|
11
13
|
import { getAiTextEditPrompts, getEditorSettings } from "../services/systemService";
|
|
12
14
|
import { loadAiProfiles } from "../services/aiService";
|
|
15
|
+
import { localStorageService } from "../services/localStorageService";
|
|
13
16
|
// Default Profile ID for the Inline Text Editor profile
|
|
14
17
|
const DEFAULT_INLINE_TEXT_EDITOR_PROFILE_ID = "d7e8f9a0-b1c2-4d3e-a5f6-789012345678";
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
18
|
+
const AI_TEXT_EDIT_MODELS_STORAGE_KEY = "aiTextEdit.selectedModelIds";
|
|
19
|
+
/** Normalize profile ID to a stable key (lowercase, no braces) so storage works regardless of API casing. */
|
|
20
|
+
function normalizeProfileIdForStorage(profileId) {
|
|
21
|
+
return profileId.replace(/^\{|\}$/g, "").toLowerCase();
|
|
22
|
+
}
|
|
23
|
+
function getStoredModelIds(profileId) {
|
|
24
|
+
try {
|
|
25
|
+
const parsed = localStorageService.getItem(AI_TEXT_EDIT_MODELS_STORAGE_KEY);
|
|
26
|
+
if (!parsed)
|
|
27
|
+
return null;
|
|
28
|
+
const normalizedKey = normalizeProfileIdForStorage(profileId);
|
|
29
|
+
// Prefer exact normalized key, then find any key that normalizes to the same
|
|
30
|
+
let ids = parsed?.[normalizedKey] ?? null;
|
|
31
|
+
if (!ids && parsed && typeof parsed === "object") {
|
|
32
|
+
for (const key of Object.keys(parsed)) {
|
|
33
|
+
if (normalizeProfileIdForStorage(key) === normalizedKey) {
|
|
34
|
+
ids = parsed[key] ?? null;
|
|
35
|
+
break;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return Array.isArray(ids) && ids.length > 0 ? ids : null;
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
function setStoredModelIds(profileId, modelIds) {
|
|
46
|
+
try {
|
|
47
|
+
const parsed = localStorageService.getItem(AI_TEXT_EDIT_MODELS_STORAGE_KEY) || {};
|
|
48
|
+
const normalizedKey = normalizeProfileIdForStorage(profileId);
|
|
49
|
+
// Merge: keep other profiles' keys as-is, but normalize keys we care about so we don't accumulate duplicates
|
|
50
|
+
const data = {};
|
|
51
|
+
const seen = new Set();
|
|
52
|
+
for (const key of Object.keys(parsed)) {
|
|
53
|
+
const n = normalizeProfileIdForStorage(key);
|
|
54
|
+
if (seen.has(n))
|
|
55
|
+
continue;
|
|
56
|
+
seen.add(n);
|
|
57
|
+
data[n] = parsed[key] ?? [];
|
|
58
|
+
}
|
|
59
|
+
data[normalizedKey] = modelIds;
|
|
60
|
+
localStorageService.setItem(AI_TEXT_EDIT_MODELS_STORAGE_KEY, data);
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
// ignore
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
const AI_TEXT_EDIT_RESPONSE_FORMAT_INSTRUCTION = `Return ONLY valid JSON (no markdown, no code fences, no extra text).
|
|
67
|
+
Use exactly one of these shapes:
|
|
68
|
+
{"replacementText":"<the modified text>"}
|
|
69
|
+
{"error":"<short explanation of why you cannot complete this request>"}`;
|
|
70
|
+
function tryExtractFirstJsonObject(input) {
|
|
71
|
+
const start = input.indexOf("{");
|
|
72
|
+
if (start < 0)
|
|
73
|
+
return null;
|
|
74
|
+
let depth = 0;
|
|
75
|
+
let inString = false;
|
|
76
|
+
let escaped = false;
|
|
77
|
+
for (let i = start; i < input.length; i++) {
|
|
78
|
+
const ch = input[i];
|
|
79
|
+
if (inString) {
|
|
80
|
+
if (escaped) {
|
|
81
|
+
escaped = false;
|
|
82
|
+
}
|
|
83
|
+
else if (ch === "\\") {
|
|
84
|
+
escaped = true;
|
|
85
|
+
}
|
|
86
|
+
else if (ch === "\"") {
|
|
87
|
+
inString = false;
|
|
88
|
+
}
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
if (ch === "\"") {
|
|
92
|
+
inString = true;
|
|
93
|
+
continue;
|
|
94
|
+
}
|
|
95
|
+
if (ch === "{")
|
|
96
|
+
depth++;
|
|
97
|
+
if (ch === "}") {
|
|
98
|
+
depth--;
|
|
99
|
+
if (depth === 0) {
|
|
100
|
+
return input.slice(start, i + 1);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
return null;
|
|
105
|
+
}
|
|
106
|
+
function cleanAgentResponse(raw) {
|
|
107
|
+
return raw
|
|
108
|
+
.trim()
|
|
109
|
+
.replace(/^```[\s\S]*?\n/, "")
|
|
110
|
+
.replace(/\n```$/, "")
|
|
111
|
+
.trim();
|
|
112
|
+
}
|
|
113
|
+
function parseAiTextEditResponse(raw) {
|
|
114
|
+
const cleaned = cleanAgentResponse(raw);
|
|
115
|
+
if (!cleaned) {
|
|
116
|
+
return { error: "AI returned an empty response." };
|
|
117
|
+
}
|
|
118
|
+
try {
|
|
119
|
+
let parsed = JSON.parse(cleaned);
|
|
120
|
+
// Some models return JSON wrapped as a JSON string; parse one extra level.
|
|
121
|
+
if (typeof parsed === "string") {
|
|
122
|
+
const reparsed = JSON.parse(parsed);
|
|
123
|
+
parsed = reparsed;
|
|
124
|
+
}
|
|
125
|
+
const parsedObj = parsed;
|
|
126
|
+
if (!parsedObj || typeof parsedObj !== "object") {
|
|
127
|
+
return { error: "AI returned an invalid response format." };
|
|
128
|
+
}
|
|
129
|
+
if (typeof parsedObj.error === "string" && parsedObj.error.trim().length > 0) {
|
|
130
|
+
return { error: parsedObj.error.trim() };
|
|
131
|
+
}
|
|
132
|
+
if (typeof parsedObj.replacementText === "string") {
|
|
133
|
+
return { replacementText: parsedObj.replacementText };
|
|
134
|
+
}
|
|
135
|
+
return { error: "AI response is missing `replacementText` or `error`." };
|
|
136
|
+
}
|
|
137
|
+
catch {
|
|
138
|
+
const extractedJson = tryExtractFirstJsonObject(cleaned);
|
|
139
|
+
if (extractedJson) {
|
|
140
|
+
try {
|
|
141
|
+
const recovered = JSON.parse(extractedJson);
|
|
142
|
+
if (recovered && typeof recovered === "object") {
|
|
143
|
+
if (typeof recovered.error === "string" && recovered.error.trim()) {
|
|
144
|
+
return { error: recovered.error.trim() };
|
|
145
|
+
}
|
|
146
|
+
if (typeof recovered.replacementText === "string") {
|
|
147
|
+
return { replacementText: recovered.replacementText };
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
catch {
|
|
152
|
+
// ignore and fall through to regular error handling
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
if (cleaned && !cleaned.includes("{")) {
|
|
156
|
+
return { error: cleaned.slice(0, 300) };
|
|
157
|
+
}
|
|
158
|
+
return { error: "AI returned invalid JSON. Please try again." };
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
function extractAgentErrorMessage(message) {
|
|
162
|
+
const payload = message?.payload ?? {};
|
|
163
|
+
const payloadData = payload?.data ?? {};
|
|
164
|
+
const candidates = [
|
|
165
|
+
payload?.error,
|
|
166
|
+
payload?.Error,
|
|
167
|
+
payload?.message,
|
|
168
|
+
payload?.Message,
|
|
169
|
+
payload?.statusMessage,
|
|
170
|
+
payload?.StatusMessage,
|
|
171
|
+
payloadData?.error,
|
|
172
|
+
payloadData?.Error,
|
|
173
|
+
payloadData?.message,
|
|
174
|
+
payloadData?.Message,
|
|
175
|
+
payloadData?.statusMessage,
|
|
176
|
+
payloadData?.StatusMessage,
|
|
177
|
+
message?.data?.error,
|
|
178
|
+
];
|
|
179
|
+
for (const candidate of candidates) {
|
|
180
|
+
if (typeof candidate === "string" && candidate.trim()) {
|
|
181
|
+
return candidate.trim();
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
return null;
|
|
185
|
+
}
|
|
25
186
|
export function InlineAiDialog({ selectedText = "", contextBefore, contextAfter, onAccept, onClose, position, className, }) {
|
|
26
187
|
const editContext = useEditContext();
|
|
27
188
|
const [state, setState] = useState("input");
|
|
@@ -32,15 +193,18 @@ export function InlineAiDialog({ selectedText = "", contextBefore, contextAfter,
|
|
|
32
193
|
const [quickActions, setQuickActions] = useState([]);
|
|
33
194
|
const [profileId, setProfileId] = useState(DEFAULT_INLINE_TEXT_EDITOR_PROFILE_ID);
|
|
34
195
|
const [activeProfile, setActiveProfile] = useState(undefined);
|
|
35
|
-
const [
|
|
196
|
+
const [selectedModelIds, setSelectedModelIds] = useState([]);
|
|
197
|
+
const [modelRuns, setModelRuns] = useState({});
|
|
36
198
|
const inputRef = useRef(null);
|
|
37
199
|
const dialogRef = useRef(null);
|
|
38
200
|
const [isLarge, setIsLarge] = useState(false);
|
|
39
201
|
const [clampedPosition, setClampedPosition] = useState(position);
|
|
40
|
-
// Agent state
|
|
41
|
-
const
|
|
202
|
+
// Agent state for the current multi-model run
|
|
203
|
+
const activeAgentIdsRef = useRef(new Set());
|
|
42
204
|
const unsubscribeRef = useRef(null);
|
|
43
|
-
const
|
|
205
|
+
const modelRunsRef = useRef({});
|
|
206
|
+
const latestRawContentRef = useRef({});
|
|
207
|
+
const lastParsedRawRef = useRef({});
|
|
44
208
|
// Model popover state
|
|
45
209
|
const [modelPopoverOpen, setModelPopoverOpen] = useState(false);
|
|
46
210
|
// ALT+letter quick select state
|
|
@@ -50,14 +214,29 @@ export function InlineAiDialog({ selectedText = "", contextBefore, contextAfter,
|
|
|
50
214
|
// Available models from the profile
|
|
51
215
|
const availableModels = activeProfile?.models || [];
|
|
52
216
|
const hasMultipleModels = availableModels.length > 1;
|
|
53
|
-
//
|
|
54
|
-
const
|
|
55
|
-
if (!
|
|
217
|
+
// Build the selected model list (fallback to first model if somehow stale)
|
|
218
|
+
const selectedModels = useMemo(() => {
|
|
219
|
+
if (!availableModels.length)
|
|
220
|
+
return [];
|
|
221
|
+
const byId = new Map(availableModels.map((m) => [m.id, m]));
|
|
222
|
+
const selected = selectedModelIds.map((id) => byId.get(id)).filter(Boolean);
|
|
223
|
+
return selected.length ? selected : availableModels.slice(0, 1);
|
|
224
|
+
}, [selectedModelIds, availableModels]);
|
|
225
|
+
const selectedModelSummary = useMemo(() => {
|
|
226
|
+
if (!selectedModels.length)
|
|
56
227
|
return null;
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
228
|
+
if (selectedModels.length === 1)
|
|
229
|
+
return selectedModels[0]?.name || null;
|
|
230
|
+
return `${selectedModels.length} models selected`;
|
|
231
|
+
}, [selectedModels]);
|
|
232
|
+
const successfulRuns = useMemo(() => Object.values(modelRuns).filter((run) => run.status === "done" && typeof run.replacementText === "string" && run.replacementText.length > 0), [modelRuns]);
|
|
233
|
+
const hasMultipleResults = successfulRuns.length > 1;
|
|
234
|
+
// Automatically switch to larger mode when showing more than one response
|
|
235
|
+
useEffect(() => {
|
|
236
|
+
if (state === "preview" && hasMultipleResults) {
|
|
237
|
+
setIsLarge(true);
|
|
238
|
+
}
|
|
239
|
+
}, [state, hasMultipleResults]);
|
|
61
240
|
useEffect(() => {
|
|
62
241
|
const loadSettings = async () => {
|
|
63
242
|
try {
|
|
@@ -85,13 +264,19 @@ export function InlineAiDialog({ selectedText = "", contextBefore, contextAfter,
|
|
|
85
264
|
return;
|
|
86
265
|
try {
|
|
87
266
|
const profiles = await loadAiProfiles();
|
|
88
|
-
const
|
|
267
|
+
const normalizedProfileId = normalizeProfileIdForStorage(profileId);
|
|
268
|
+
const profile = profiles.find((p) => normalizeProfileIdForStorage(p.id) === normalizedProfileId);
|
|
89
269
|
if (profile) {
|
|
90
270
|
setActiveProfile(profile);
|
|
91
|
-
|
|
271
|
+
const availableModelIds = new Set((profile.models ?? []).map((m) => m.id));
|
|
92
272
|
const defaultModelId = profile.defaultModelId || profile.models?.[0]?.id;
|
|
93
|
-
|
|
94
|
-
|
|
273
|
+
const stored = getStoredModelIds(profileId);
|
|
274
|
+
const validStored = stored?.filter((id) => availableModelIds.has(id));
|
|
275
|
+
if (validStored?.length) {
|
|
276
|
+
setSelectedModelIds(validStored);
|
|
277
|
+
}
|
|
278
|
+
else if (defaultModelId) {
|
|
279
|
+
setSelectedModelIds([defaultModelId]);
|
|
95
280
|
}
|
|
96
281
|
}
|
|
97
282
|
}
|
|
@@ -101,136 +286,230 @@ export function InlineAiDialog({ selectedText = "", contextBefore, contextAfter,
|
|
|
101
286
|
};
|
|
102
287
|
loadProfile();
|
|
103
288
|
}, [profileId]);
|
|
289
|
+
useEffect(() => {
|
|
290
|
+
modelRunsRef.current = modelRuns;
|
|
291
|
+
}, [modelRuns]);
|
|
292
|
+
// Persist model selection to localStorage when it or profileId changes
|
|
293
|
+
useEffect(() => {
|
|
294
|
+
if (profileId && selectedModelIds.length > 0) {
|
|
295
|
+
setStoredModelIds(profileId, selectedModelIds);
|
|
296
|
+
}
|
|
297
|
+
}, [profileId, selectedModelIds]);
|
|
104
298
|
// Focus input on mount
|
|
105
299
|
useEffect(() => {
|
|
106
300
|
if (inputRef.current) {
|
|
107
301
|
inputRef.current.focus();
|
|
108
302
|
}
|
|
109
303
|
}, []);
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
304
|
+
const evaluateRunCompletion = useCallback((runs) => {
|
|
305
|
+
const values = Object.values(runs);
|
|
306
|
+
if (!values.length)
|
|
307
|
+
return;
|
|
308
|
+
const allTerminal = values.every((run) => run.status === "done" || run.status === "error");
|
|
309
|
+
if (!allTerminal)
|
|
310
|
+
return;
|
|
311
|
+
const doneRuns = values.filter((run) => run.status === "done" && run.replacementText?.length);
|
|
312
|
+
if (doneRuns.length === 0) {
|
|
313
|
+
setError("All selected models failed. See each model’s card for details. You can retry or change your instruction.");
|
|
314
|
+
setResult("");
|
|
315
|
+
// Stay in preview so the user sees per-model error cards and can Retry/Discard
|
|
316
|
+
return;
|
|
317
|
+
}
|
|
318
|
+
if (doneRuns.length === 1) {
|
|
319
|
+
setResult(doneRuns[0]?.replacementText ?? "");
|
|
320
|
+
}
|
|
321
|
+
else {
|
|
322
|
+
setResult("");
|
|
323
|
+
}
|
|
324
|
+
setError(null);
|
|
325
|
+
// State is already "preview" – we show results side-by-side as they stream in
|
|
122
326
|
}, []);
|
|
123
|
-
|
|
124
|
-
|
|
327
|
+
const updateModelRun = useCallback((agentId, updater) => {
|
|
328
|
+
setModelRuns((prev) => {
|
|
329
|
+
const current = prev[agentId];
|
|
330
|
+
if (!current)
|
|
331
|
+
return prev;
|
|
332
|
+
const updated = updater(current);
|
|
333
|
+
const next = { ...prev, [agentId]: updated };
|
|
334
|
+
modelRunsRef.current = next;
|
|
335
|
+
evaluateRunCompletion(next);
|
|
336
|
+
return next;
|
|
337
|
+
});
|
|
338
|
+
}, [evaluateRunCompletion]);
|
|
339
|
+
const subscribeAgent = useCallback((agentId) => {
|
|
125
340
|
const socket = globalThis.editorSocket;
|
|
126
341
|
if (!socket || socket.readyState !== WebSocket.OPEN) {
|
|
127
342
|
console.warn("[InlineAiDialog] WebSocket not available");
|
|
128
343
|
return;
|
|
129
344
|
}
|
|
130
|
-
// Send subscription message
|
|
131
345
|
socket.send(JSON.stringify({
|
|
132
346
|
type: "agent:subscribe",
|
|
133
|
-
agentId
|
|
347
|
+
agentId,
|
|
134
348
|
}));
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
349
|
+
}, []);
|
|
350
|
+
const unsubscribeAllAgents = useCallback(() => {
|
|
351
|
+
const socket = globalThis.editorSocket;
|
|
352
|
+
if (!socket || socket.readyState !== WebSocket.OPEN)
|
|
353
|
+
return;
|
|
354
|
+
for (const agentId of activeAgentIdsRef.current) {
|
|
355
|
+
socket.send(JSON.stringify({
|
|
356
|
+
type: "agent:unsubscribe",
|
|
357
|
+
agentId,
|
|
358
|
+
}));
|
|
359
|
+
}
|
|
360
|
+
}, []);
|
|
361
|
+
const closeAllActiveAgents = useCallback(() => {
|
|
362
|
+
for (const agentId of activeAgentIdsRef.current) {
|
|
363
|
+
closeAgent(agentId).catch(() => { });
|
|
364
|
+
}
|
|
365
|
+
activeAgentIdsRef.current.clear();
|
|
366
|
+
latestRawContentRef.current = {};
|
|
367
|
+
lastParsedRawRef.current = {};
|
|
368
|
+
}, []);
|
|
369
|
+
const handleStopModelRun = useCallback((agentId) => {
|
|
370
|
+
activeAgentIdsRef.current.delete(agentId);
|
|
371
|
+
delete latestRawContentRef.current[agentId];
|
|
372
|
+
delete lastParsedRawRef.current[agentId];
|
|
373
|
+
closeAgent(agentId).catch(() => { });
|
|
374
|
+
updateModelRun(agentId, (current) => ({
|
|
375
|
+
...current,
|
|
376
|
+
status: "error",
|
|
377
|
+
error: "Stopped by user",
|
|
378
|
+
}));
|
|
379
|
+
}, [updateModelRun]);
|
|
380
|
+
// Cleanup on unmount
|
|
381
|
+
useEffect(() => {
|
|
382
|
+
return () => {
|
|
383
|
+
unsubscribeAllAgents();
|
|
384
|
+
if (unsubscribeRef.current) {
|
|
385
|
+
unsubscribeRef.current();
|
|
386
|
+
}
|
|
387
|
+
closeAllActiveAgents();
|
|
388
|
+
};
|
|
389
|
+
}, [unsubscribeAllAgents, closeAllActiveAgents]);
|
|
390
|
+
const ensureSocketListener = useCallback(() => {
|
|
391
|
+
if (!editContext?.addSocketMessageListener || unsubscribeRef.current) {
|
|
392
|
+
return;
|
|
393
|
+
}
|
|
394
|
+
const handleMessage = (message) => {
|
|
395
|
+
const messageAgentId = message.agentId || message.payload?.agentId;
|
|
396
|
+
if (!messageAgentId || !activeAgentIdsRef.current.has(messageAgentId)) {
|
|
397
|
+
return;
|
|
398
|
+
}
|
|
399
|
+
const msgType = message.type;
|
|
400
|
+
if (msgType === "agent:run:delta") {
|
|
401
|
+
const deltaData = message.payload?.data;
|
|
402
|
+
const content = deltaData?.deltaContent || "";
|
|
403
|
+
const isIncremental = deltaData?.isIncremental !== false;
|
|
404
|
+
if (!content)
|
|
140
405
|
return;
|
|
406
|
+
const previousRaw = latestRawContentRef.current[messageAgentId] || "";
|
|
407
|
+
const nextRaw = isIncremental ? previousRaw + content : content;
|
|
408
|
+
latestRawContentRef.current[messageAgentId] = nextRaw;
|
|
409
|
+
const existingRun = modelRunsRef.current[messageAgentId];
|
|
410
|
+
if (existingRun) {
|
|
411
|
+
modelRunsRef.current = {
|
|
412
|
+
...modelRunsRef.current,
|
|
413
|
+
[messageAgentId]: {
|
|
414
|
+
...existingRun,
|
|
415
|
+
status: "streaming",
|
|
416
|
+
rawContent: nextRaw,
|
|
417
|
+
},
|
|
418
|
+
};
|
|
141
419
|
}
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
420
|
+
updateModelRun(messageAgentId, (current) => {
|
|
421
|
+
const nextRawContent = isIncremental ? current.rawContent + content : content;
|
|
422
|
+
return {
|
|
423
|
+
...current,
|
|
424
|
+
status: "streaming",
|
|
425
|
+
rawContent: nextRawContent,
|
|
426
|
+
};
|
|
427
|
+
});
|
|
428
|
+
}
|
|
429
|
+
else if (msgType === "agent:run:status" || msgType === "agent:status:update") {
|
|
430
|
+
const statusData = message.payload?.data || message.payload || {};
|
|
431
|
+
const normalizedStatus = (statusData.state || statusData.status || "").toString().toLowerCase();
|
|
432
|
+
if (normalizedStatus === "error") {
|
|
433
|
+
const errorMsg = extractAgentErrorMessage(message) || "AI could not complete this request.";
|
|
434
|
+
updateModelRun(messageAgentId, (current) => {
|
|
435
|
+
if (current.status === "done")
|
|
436
|
+
return current; // don't overwrite success
|
|
437
|
+
return { ...current, status: "error", error: errorMsg };
|
|
438
|
+
});
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
else if (msgType === "agent:run:error" || msgType === "agent:error") {
|
|
442
|
+
const errorMsg = extractAgentErrorMessage(message) || "AI could not complete this request.";
|
|
443
|
+
updateModelRun(messageAgentId, (current) => {
|
|
444
|
+
if (current.status === "done")
|
|
445
|
+
return current; // don't overwrite success
|
|
446
|
+
return { ...current, status: "error", error: errorMsg };
|
|
447
|
+
});
|
|
448
|
+
}
|
|
449
|
+
else if (msgType === "agent:message:complete" || msgType === "agent:run:complete") {
|
|
450
|
+
const lifecycleError = extractAgentErrorMessage(message);
|
|
451
|
+
if (lifecycleError) {
|
|
452
|
+
updateModelRun(messageAgentId, (current) => ({
|
|
453
|
+
...current,
|
|
454
|
+
status: "error",
|
|
455
|
+
error: lifecycleError,
|
|
456
|
+
}));
|
|
457
|
+
return;
|
|
164
458
|
}
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
459
|
+
const current = modelRunsRef.current[messageAgentId];
|
|
460
|
+
const rawContentToParse = latestRawContentRef.current[messageAgentId] ?? current?.rawContent ?? "";
|
|
461
|
+
if (lastParsedRawRef.current[messageAgentId] === rawContentToParse) {
|
|
462
|
+
return;
|
|
168
463
|
}
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
464
|
+
lastParsedRawRef.current[messageAgentId] = rawContentToParse;
|
|
465
|
+
const parsed = parseAiTextEditResponse(rawContentToParse);
|
|
466
|
+
if (parsed.error) {
|
|
467
|
+
updateModelRun(messageAgentId, (run) => ({
|
|
468
|
+
...run,
|
|
469
|
+
status: "error",
|
|
470
|
+
error: parsed.error,
|
|
471
|
+
}));
|
|
174
472
|
}
|
|
175
|
-
else
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
setError(message.payload?.message || "Agent error");
|
|
183
|
-
setState("input");
|
|
184
|
-
}
|
|
473
|
+
else {
|
|
474
|
+
updateModelRun(messageAgentId, (run) => ({
|
|
475
|
+
...run,
|
|
476
|
+
status: "done",
|
|
477
|
+
replacementText: parsed.replacementText ?? "",
|
|
478
|
+
error: undefined,
|
|
479
|
+
}));
|
|
185
480
|
}
|
|
186
|
-
};
|
|
187
|
-
unsubscribeRef.current = editContext.addSocketMessageListener(handleMessage);
|
|
188
|
-
}
|
|
189
|
-
}, [editContext]);
|
|
190
|
-
// Unsubscribe from current agent
|
|
191
|
-
const unsubscribeFromAgent = useCallback(() => {
|
|
192
|
-
if (unsubscribeRef.current) {
|
|
193
|
-
unsubscribeRef.current();
|
|
194
|
-
unsubscribeRef.current = null;
|
|
195
|
-
}
|
|
196
|
-
if (agentIdRef.current) {
|
|
197
|
-
const socket = globalThis.editorSocket;
|
|
198
|
-
if (socket && socket.readyState === WebSocket.OPEN) {
|
|
199
|
-
socket.send(JSON.stringify({
|
|
200
|
-
type: "agent:unsubscribe",
|
|
201
|
-
agentId: agentIdRef.current,
|
|
202
|
-
}));
|
|
203
481
|
}
|
|
204
|
-
}
|
|
205
|
-
|
|
482
|
+
};
|
|
483
|
+
unsubscribeRef.current = editContext.addSocketMessageListener(handleMessage);
|
|
484
|
+
}, [editContext, updateModelRun]);
|
|
206
485
|
const executeAiModification = useCallback(async (customInstruction) => {
|
|
207
486
|
if (!editContext)
|
|
208
487
|
return;
|
|
209
|
-
|
|
488
|
+
if (!selectedModels.length) {
|
|
489
|
+
setError("Select at least one model.");
|
|
490
|
+
return;
|
|
491
|
+
}
|
|
210
492
|
setError(null);
|
|
211
|
-
resultRef.current = "";
|
|
212
493
|
setResult("");
|
|
494
|
+
setModelRuns({});
|
|
495
|
+
modelRunsRef.current = {};
|
|
496
|
+
latestRawContentRef.current = {};
|
|
497
|
+
lastParsedRawRef.current = {};
|
|
498
|
+
unsubscribeAllAgents();
|
|
499
|
+
closeAllActiveAgents();
|
|
213
500
|
try {
|
|
214
|
-
//
|
|
215
|
-
const
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
}
|
|
219
|
-
const agentId = agentIdRef.current;
|
|
220
|
-
// Build the message - include context on first message
|
|
221
|
-
let message;
|
|
222
|
-
if (isNewAgent) {
|
|
223
|
-
// Include context around the selection if available
|
|
224
|
-
const hasContext = contextBefore || contextAfter;
|
|
225
|
-
const contextInfo = hasContext
|
|
226
|
-
? `CONTEXT (text surrounding the selection):
|
|
501
|
+
// Build the message with context around the selection if available
|
|
502
|
+
const hasContext = contextBefore || contextAfter;
|
|
503
|
+
const contextInfo = hasContext
|
|
504
|
+
? `CONTEXT (text surrounding the selection):
|
|
227
505
|
Before: "${contextBefore || ""}"
|
|
228
506
|
After: "${contextAfter || ""}"
|
|
229
507
|
|
|
230
508
|
`
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
509
|
+
: "";
|
|
510
|
+
let message;
|
|
511
|
+
if (selectedText) {
|
|
512
|
+
message = `${contextInfo}I need you to modify ONLY the following selected portion of the text:
|
|
234
513
|
|
|
235
514
|
SELECTED TEXT TO MODIFY:
|
|
236
515
|
"""
|
|
@@ -239,31 +518,22 @@ ${selectedText}
|
|
|
239
518
|
|
|
240
519
|
${customInstruction}
|
|
241
520
|
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
521
|
+
Return ONLY the modified version of the selected text, not the entire field.
|
|
522
|
+
${AI_TEXT_EDIT_RESPONSE_FORMAT_INSTRUCTION}`;
|
|
523
|
+
}
|
|
524
|
+
else {
|
|
525
|
+
message = `${contextInfo}I need you to generate text at the cursor position.
|
|
246
526
|
|
|
247
527
|
${customInstruction}
|
|
248
528
|
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
}
|
|
252
|
-
else {
|
|
253
|
-
// For refinements, just send the instruction
|
|
254
|
-
message = customInstruction;
|
|
529
|
+
Return ONLY the text to insert at the cursor position, not the entire field.
|
|
530
|
+
${AI_TEXT_EDIT_RESPONSE_FORMAT_INSTRUCTION}`;
|
|
255
531
|
}
|
|
256
|
-
// Subscribe to WebSocket before starting
|
|
257
|
-
if (isNewAgent) {
|
|
258
|
-
subscribeToAgent(agentId);
|
|
259
|
-
}
|
|
260
|
-
// Track conversation history
|
|
261
532
|
setConversationHistory((prev) => [...prev, customInstruction]);
|
|
262
|
-
// Build context based on profile's editorContextMode setting
|
|
263
533
|
let agentContext = undefined;
|
|
264
534
|
const contextMode = activeProfile?.editorContextMode;
|
|
265
535
|
const shouldIncludeContext = contextMode === "onCreate" || contextMode === "live";
|
|
266
|
-
if (shouldIncludeContext
|
|
536
|
+
if (shouldIncludeContext) {
|
|
267
537
|
const item = editContext.currentItemDescriptor;
|
|
268
538
|
if (item) {
|
|
269
539
|
agentContext = {
|
|
@@ -293,25 +563,66 @@ Remember: Return ONLY the text to insert at the cursor position, not the entire
|
|
|
293
563
|
};
|
|
294
564
|
}
|
|
295
565
|
}
|
|
296
|
-
|
|
297
|
-
const
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
566
|
+
ensureSocketListener();
|
|
567
|
+
const initialRuns = {};
|
|
568
|
+
for (const model of selectedModels) {
|
|
569
|
+
const agentId = crypto.randomUUID();
|
|
570
|
+
activeAgentIdsRef.current.add(agentId);
|
|
571
|
+
latestRawContentRef.current[agentId] = "";
|
|
572
|
+
delete lastParsedRawRef.current[agentId];
|
|
573
|
+
initialRuns[agentId] = {
|
|
574
|
+
agentId,
|
|
575
|
+
modelId: model.id,
|
|
576
|
+
modelName: model.name,
|
|
577
|
+
status: "pending",
|
|
578
|
+
rawContent: "",
|
|
579
|
+
};
|
|
580
|
+
}
|
|
581
|
+
setModelRuns(initialRuns);
|
|
582
|
+
modelRunsRef.current = initialRuns;
|
|
583
|
+
setState("preview"); // Show results immediately side-by-side as they stream in
|
|
584
|
+
await Promise.all(Object.values(initialRuns).map(async (run) => {
|
|
585
|
+
subscribeAgent(run.agentId);
|
|
586
|
+
try {
|
|
587
|
+
await startAgent({
|
|
588
|
+
agentId: run.agentId,
|
|
589
|
+
message,
|
|
590
|
+
sessionId: editContext.sessionId,
|
|
591
|
+
profileId: profileId,
|
|
592
|
+
mode: "autonomous",
|
|
593
|
+
model: run.modelId,
|
|
594
|
+
context: agentContext,
|
|
595
|
+
});
|
|
596
|
+
}
|
|
597
|
+
catch (runErr) {
|
|
598
|
+
const errorMsg = runErr instanceof Error ? runErr.message : "Failed to start model run";
|
|
599
|
+
updateModelRun(run.agentId, (current) => ({
|
|
600
|
+
...current,
|
|
601
|
+
status: "error",
|
|
602
|
+
error: errorMsg,
|
|
603
|
+
}));
|
|
604
|
+
}
|
|
605
|
+
}));
|
|
308
606
|
}
|
|
309
607
|
catch (err) {
|
|
310
608
|
console.error("AI modification error:", err);
|
|
311
609
|
setError(err instanceof Error ? err.message : "An error occurred");
|
|
312
610
|
setState("input");
|
|
313
611
|
}
|
|
314
|
-
}, [
|
|
612
|
+
}, [
|
|
613
|
+
editContext,
|
|
614
|
+
selectedText,
|
|
615
|
+
contextBefore,
|
|
616
|
+
contextAfter,
|
|
617
|
+
profileId,
|
|
618
|
+
activeProfile,
|
|
619
|
+
selectedModels,
|
|
620
|
+
closeAllActiveAgents,
|
|
621
|
+
unsubscribeAllAgents,
|
|
622
|
+
ensureSocketListener,
|
|
623
|
+
subscribeAgent,
|
|
624
|
+
updateModelRun,
|
|
625
|
+
]);
|
|
315
626
|
const handleQuickAction = useCallback((action) => {
|
|
316
627
|
executeAiModification(action.instruction);
|
|
317
628
|
}, [executeAiModification]);
|
|
@@ -387,38 +698,50 @@ Remember: Return ONLY the text to insert at the cursor position, not the entire
|
|
|
387
698
|
}
|
|
388
699
|
};
|
|
389
700
|
}, [state, isAltPressed, altSearchBuffer, quickActions, handleQuickAction]);
|
|
390
|
-
const
|
|
391
|
-
if (
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
}, [
|
|
701
|
+
const handleUseRunResult = useCallback((replacementText) => {
|
|
702
|
+
if (!replacementText)
|
|
703
|
+
return;
|
|
704
|
+
onAccept(replacementText);
|
|
705
|
+
}, [onAccept]);
|
|
706
|
+
const toggleModelSelection = useCallback((modelId) => {
|
|
707
|
+
setSelectedModelIds((prev) => {
|
|
708
|
+
if (prev.includes(modelId)) {
|
|
709
|
+
if (prev.length === 1) {
|
|
710
|
+
return prev;
|
|
711
|
+
}
|
|
712
|
+
return prev.filter((id) => id !== modelId);
|
|
713
|
+
}
|
|
714
|
+
return [...prev, modelId];
|
|
715
|
+
});
|
|
716
|
+
}, []);
|
|
395
717
|
const handleTryAgain = useCallback(() => {
|
|
396
718
|
// Go back to input state to refine
|
|
397
719
|
setState("input");
|
|
398
720
|
setResult("");
|
|
399
|
-
resultRef.current = "";
|
|
400
|
-
// Keep the agent for conversation history
|
|
401
721
|
}, []);
|
|
402
|
-
const
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
closeAgent(agentIdRef.current).catch(() => { });
|
|
407
|
-
agentIdRef.current = null;
|
|
722
|
+
const handleRetry = useCallback(() => {
|
|
723
|
+
const lastInstruction = conversationHistory[conversationHistory.length - 1];
|
|
724
|
+
if (lastInstruction) {
|
|
725
|
+
executeAiModification(lastInstruction);
|
|
408
726
|
}
|
|
727
|
+
}, [conversationHistory, executeAiModification]);
|
|
728
|
+
const handleStartOver = useCallback(() => {
|
|
729
|
+
unsubscribeAllAgents();
|
|
730
|
+
closeAllActiveAgents();
|
|
731
|
+
setModelRuns({});
|
|
732
|
+
modelRunsRef.current = {};
|
|
733
|
+
latestRawContentRef.current = {};
|
|
734
|
+
lastParsedRawRef.current = {};
|
|
409
735
|
setState("input");
|
|
410
736
|
setResult("");
|
|
411
|
-
resultRef.current = "";
|
|
412
737
|
setConversationHistory([]);
|
|
413
738
|
setError(null);
|
|
414
|
-
}, [
|
|
739
|
+
}, [unsubscribeAllAgents, closeAllActiveAgents]);
|
|
415
740
|
const handleClose = useCallback(() => {
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
closeAgent(agentIdRef.current).catch(() => { });
|
|
419
|
-
}
|
|
741
|
+
unsubscribeAllAgents();
|
|
742
|
+
closeAllActiveAgents();
|
|
420
743
|
onClose();
|
|
421
|
-
}, [
|
|
744
|
+
}, [unsubscribeAllAgents, closeAllActiveAgents, onClose]);
|
|
422
745
|
const toggleLarge = useCallback(() => {
|
|
423
746
|
setIsLarge((prev) => !prev);
|
|
424
747
|
}, []);
|
|
@@ -493,7 +816,7 @@ Remember: Return ONLY the text to insert at the cursor position, not the entire
|
|
|
493
816
|
resizeObserver.disconnect();
|
|
494
817
|
};
|
|
495
818
|
// Re-clamp when the content changes (height changes) or when the requested position changes.
|
|
496
|
-
}, [position?.x, position?.y, state, result, selectedText, isLarge]);
|
|
819
|
+
}, [position?.x, position?.y, state, result, selectedText, isLarge, modelRuns, hasMultipleResults]);
|
|
497
820
|
return (_jsxs("div", { ref: dialogRef, className: cn("bg-white/95 backdrop-blur-sm rounded-xl shadow-[0_10px_40px_rgba(0,0,0,0.1)] border border-gray-100 max-h-[80vh] flex flex-col overflow-hidden agent-inline-dialog transition-all duration-300 ease-in-out", isLarge ? "w-[800px]" : "w-[420px]", "animate-in fade-in-0 zoom-in-95 duration-200 ease-out", className), style: clampedPosition
|
|
498
821
|
? {
|
|
499
822
|
position: "fixed",
|
|
@@ -502,14 +825,13 @@ Remember: Return ONLY the text to insert at the cursor position, not the entire
|
|
|
502
825
|
zIndex: 95,
|
|
503
826
|
}
|
|
504
827
|
: undefined, onKeyDown: handleKeyDown, children: [_jsxs("div", { className: "flex-shrink-0 flex items-center gap-2.5 px-4 py-3 bg-gradient-to-r from-violet-500/5 to-purple-500/5 border-b border-gray-100", children: [_jsx("div", { className: "flex items-center justify-center w-6 h-6 rounded-lg bg-violet-600 shadow-sm shadow-violet-200", children: _jsx(Sparkles, { className: "w-3.5 h-3.5 text-white" }) }), _jsxs("div", { className: "flex flex-col", children: [_jsx("span", { className: "text-sm font-semibold text-gray-800 leading-tight", children: "AI Text Edit" }), conversationHistory.length > 0 && (_jsxs("span", { className: "text-[10px] text-gray-400 font-medium", children: [conversationHistory.length, " ", conversationHistory.length === 1 ? "turn" : "turns", " in history"] }))] }), _jsxs("div", { className: "ml-auto flex items-center gap-1", children: [_jsx("button", { onClick: toggleLarge, className: cn("p-1.5 hover:bg-gray-100 rounded-lg transition-all duration-200 group", isLarge && "bg-violet-50 text-violet-600 hover:bg-violet-100"), title: isLarge ? "Make smaller" : "Make larger", children: _jsx(Maximize2, { className: cn("w-4 h-4 text-gray-400 group-hover:text-gray-600", isLarge && "text-violet-600") }) }), _jsx("button", { onClick: handleClose, className: "p-1.5 hover:bg-gray-100 rounded-lg transition-all duration-200 group", title: "Close", children: _jsx(X, { className: "w-4 h-4 text-gray-400 group-hover:text-gray-600" }) })] })] }), selectedText && (_jsxs("div", { className: "flex-shrink-0 px-4 py-3 bg-gray-50/50 border-b border-gray-100", children: [_jsxs("div", { className: "flex items-center gap-1.5 text-[10px] font-bold text-gray-400 uppercase tracking-wider mb-2", children: [_jsx("div", { className: "w-1.5 h-1.5 rounded-full bg-gray-200" }), "Selected Content"] }), _jsxs("div", { className: "relative max-h-48 overflow-y-auto whitespace-pre-wrap transition-all duration-300", children: [_jsx("div", { className: "absolute left-0 top-0 bottom-0 w-0.5 bg-violet-200 rounded-full" }), _jsx("div", { className: "pl-3", children: renderTextWithContext(selectedText) })] })] })), _jsxs("div", { className: "p-4 min-h-0 flex-1 overflow-y-auto", children: [state === "input" && (_jsxs("div", { className: "space-y-4", children: [_jsxs("div", { className: "space-y-2", children: [isAltPressed && (_jsxs("div", { className: "flex items-center gap-2 text-xs text-violet-600 bg-violet-50 px-2.5 py-1.5 rounded-lg animate-in fade-in duration-150", children: [_jsx("kbd", { className: "px-1.5 py-0.5 bg-violet-100 rounded text-[10px] font-mono font-bold", children: "ALT" }), _jsx("span", { className: "font-medium", children: altSearchBuffer ? (_jsxs(_Fragment, { children: ["Type to select: ", _jsx("span", { className: "font-bold", children: altSearchBuffer })] })) : ("Type first letters of an action...") })] })), _jsx("div", { className: "flex flex-wrap gap-2", children: quickActions.map((action) => {
|
|
505
|
-
const
|
|
506
|
-
const IconComponent = !isSvgIcon ? (ICON_MAP[action.icon] || HelpCircle) : null;
|
|
828
|
+
const hasSvgIcon = action.icon?.trim() && (action.icon.trim().startsWith("<svg") || action.icon.trim().startsWith("<?xml"));
|
|
507
829
|
const labelLower = action.label.toLowerCase();
|
|
508
830
|
const isMatch = isAltPressed && altSearchBuffer && labelLower.startsWith(altSearchBuffer);
|
|
509
831
|
const isPartialMatch = isAltPressed && altSearchBuffer && labelLower.includes(altSearchBuffer) && !isMatch;
|
|
510
|
-
return (_jsxs("button", { onClick: () => handleQuickAction(action), className: cn("flex items-center gap-1.5 px-2.5 py-1.5 text-xs font-medium rounded-lg transition-all duration-200", "bg-white border border-gray-200 text-gray-600", "hover:border-violet-300 hover:text-violet-700 hover:bg-violet-50", "active:scale-95 shadow-sm hover:shadow-md", isMatch && "border-violet-400 bg-violet-100 text-violet-700 ring-2 ring-violet-300", isPartialMatch && "border-violet-200 bg-violet-50/50", isAltPressed && !isMatch && !isPartialMatch && "opacity-50"), children: [
|
|
511
|
-
__html: action.icon,
|
|
512
|
-
} }))
|
|
832
|
+
return (_jsxs("button", { onClick: () => handleQuickAction(action), className: cn("flex items-center gap-1.5 px-2.5 py-1.5 text-xs font-medium rounded-lg transition-all duration-200", "bg-white border border-gray-200 text-gray-600", "hover:border-violet-300 hover:text-violet-700 hover:bg-violet-50", "active:scale-95 shadow-sm hover:shadow-md", isMatch && "border-violet-400 bg-violet-100 text-violet-700 ring-2 ring-violet-300", isPartialMatch && "border-violet-200 bg-violet-50/50", isAltPressed && !isMatch && !isPartialMatch && "opacity-50"), children: [hasSvgIcon && (_jsx("div", { className: "w-3.5 h-3.5 flex items-center justify-center [&>svg]:w-full [&>svg]:h-full shrink-0", dangerouslySetInnerHTML: {
|
|
833
|
+
__html: sanitizeSvg(action.icon.trim()),
|
|
834
|
+
} })), isAltPressed && altSearchBuffer ? (_jsxs("span", { children: [_jsx("span", { className: cn(isMatch && "font-bold underline underline-offset-2"), children: action.label.slice(0, altSearchBuffer.length) }), action.label.slice(altSearchBuffer.length)] })) : (action.label)] }, action.id));
|
|
513
835
|
}) })] }), _jsxs("form", { onSubmit: (e) => {
|
|
514
836
|
e.preventDefault();
|
|
515
837
|
if (instruction.trim()) {
|
|
@@ -518,27 +840,27 @@ Remember: Return ONLY the text to insert at the cursor position, not the entire
|
|
|
518
840
|
}
|
|
519
841
|
}, className: "relative group", children: [_jsx(Textarea, { ref: inputRef, value: instruction, onChange: (e) => setInstruction(e.target.value), onKeyDown: handleTextareaKeyDown, placeholder: conversationHistory.length > 0
|
|
520
842
|
? "How can I improve this further?"
|
|
521
|
-
: "Describe the change you want...", className: cn("w-full py-3 pl-3 pr-14 text-
|
|
522
|
-
setSelectedModelId(model.id);
|
|
523
|
-
setModelPopoverOpen(false);
|
|
524
|
-
}, className: cn("w-full text-left px-2 py-1.5 text-xs rounded-md transition-colors", selectedModelId === model.id
|
|
843
|
+
: "Describe the change you want...", className: cn("w-full py-3 pl-3 pr-14 text-xs rounded-2xl border border-gray-200", "focus:border-violet-400 focus:ring-4 focus:ring-violet-500/10", "outline-none transition-all duration-200 bg-gray-50/30 resize-none", isLarge ? "min-h-[200px]" : "min-h-[100px]") }), _jsxs("div", { className: "absolute right-2 bottom-2 flex items-center gap-1", children: [hasMultipleModels && (_jsxs(Popover, { open: modelPopoverOpen, onOpenChange: setModelPopoverOpen, children: [_jsx(PopoverTrigger, { asChild: true, children: _jsx("button", { type: "button", className: cn("p-1.5 rounded-lg transition-all duration-200", "text-gray-400 hover:text-violet-600 hover:bg-violet-50", modelPopoverOpen && "text-violet-600 bg-violet-50"), title: selectedModelSummary ? `Models: ${selectedModelSummary}` : "Select models", children: _jsx(Cpu, { className: "w-3.5 h-3.5" }) }) }), _jsxs(PopoverContent, { className: "w-56 p-1.5", align: "end", sideOffset: 8, children: [_jsxs("div", { className: "flex items-center justify-between px-2 py-1", children: [_jsx("span", { className: "text-[10px] font-semibold text-gray-400 uppercase tracking-wider", children: "Models" }), _jsxs("span", { className: "text-[10px] text-violet-600 font-medium", children: [selectedModels.length, " selected"] })] }), _jsx("div", { className: "space-y-0.5", children: availableModels.map((model) => (_jsxs("button", { type: "button", onClick: () => toggleModelSelection(model.id), className: cn("w-full text-left px-2 py-1.5 text-xs rounded-md transition-colors flex items-center gap-2", selectedModelIds.includes(model.id)
|
|
525
844
|
? "bg-violet-100 text-violet-700 font-medium"
|
|
526
|
-
: "text-gray-600 hover:bg-gray-100"), children:
|
|
845
|
+
: "text-gray-600 hover:bg-gray-100"), children: [_jsx("span", { className: cn("w-3.5 h-3.5 rounded border flex items-center justify-center", selectedModelIds.includes(model.id)
|
|
846
|
+
? "border-violet-600 bg-violet-600 text-white"
|
|
847
|
+
: "border-gray-300 bg-white text-transparent"), children: _jsx(Check, { className: "w-3 h-3" }) }), model.name] }, model.id))) })] })] })), _jsx("button", { type: "submit", disabled: !instruction.trim() || selectedModels.length === 0, className: cn("p-2.5 rounded-xl transition-all duration-300", instruction.trim() && selectedModels.length > 0
|
|
527
848
|
? "bg-violet-600 text-white shadow-lg shadow-violet-200 hover:bg-violet-700 hover:-translate-y-0.5"
|
|
528
|
-
: "bg-gray-100 text-gray-400 cursor-not-allowed"), title: "Send (Enter)", children: _jsx(SendHorizonal, { className: "w-4 h-4" }) })] })] }), conversationHistory.length > 0 && (_jsxs("div", { className: "flex items-center justify-between pt-1", children: [_jsxs("div", { className: "flex items-center gap-1.5 text-[10px] text-gray-400 font-medium", children: [_jsx(History, { className: "w-3 h-3" }), "Conversation active"] }), _jsxs("button", { onClick: handleStartOver, className: "text-[10px] font-bold text-violet-600 hover:text-violet-700 uppercase tracking-tight flex items-center gap-1 transition-colors", children: [_jsx(RotateCcw, { className: "w-3 h-3" }), "Clear History"] })] })), error && (_jsxs("div", { className: "text-xs text-red-600 bg-red-50 px-3 py-2 rounded-lg border border-red-100 flex items-start gap-2 animate-in fade-in slide-in-from-top-1 duration-200", children: [_jsx(X, { className: "w-3.5 h-3.5 mt-0.5 shrink-0" }), _jsx("span", { children: error })] }))] })), state === "
|
|
849
|
+
: "bg-gray-100 text-gray-400 cursor-not-allowed"), title: "Send (Enter)", children: _jsx(SendHorizonal, { className: "w-4 h-4" }) })] })] }), conversationHistory.length > 0 && (_jsxs("div", { className: "flex items-center justify-between pt-1", children: [_jsxs("div", { className: "flex items-center gap-1.5 text-[10px] text-gray-400 font-medium", children: [_jsx(History, { className: "w-3 h-3" }), "Conversation active"] }), _jsxs("button", { onClick: handleStartOver, className: "text-[10px] font-bold text-violet-600 hover:text-violet-700 uppercase tracking-tight flex items-center gap-1 transition-colors", children: [_jsx(RotateCcw, { className: "w-3 h-3" }), "Clear History"] })] })), error && (_jsxs("div", { className: "text-xs text-red-600 bg-red-50 px-3 py-2 rounded-lg border border-red-100 flex items-start gap-2 animate-in fade-in slide-in-from-top-1 duration-200", children: [_jsx(X, { className: "w-3.5 h-3.5 mt-0.5 shrink-0" }), _jsx("span", { children: error })] }))] })), state === "preview" && (_jsxs("div", { className: "space-y-4 animate-in fade-in slide-in-from-bottom-2 duration-300", children: [Object.keys(modelRuns).length > 0 && (_jsxs("div", { className: "space-y-2", children: [_jsxs("div", { className: "flex items-center gap-1.5 text-[10px] font-bold text-gray-500 uppercase tracking-wider", children: [_jsx("div", { className: "w-1.5 h-1.5 rounded-full bg-violet-400" }), Object.values(modelRuns).some((r) => r.status === "pending" || r.status === "streaming")
|
|
850
|
+
? "Responses (live)"
|
|
851
|
+
: "Model responses"] }), _jsx("div", { className: "flex gap-3 overflow-x-auto pb-1", children: Object.values(modelRuns).map((run) => (_jsxs("div", { className: cn("min-w-[280px] flex-1 rounded-xl p-3 flex flex-col gap-2 border", run.status === "done" && "border-green-100 bg-green-50/40", run.status === "error" && "border-red-100 bg-red-50/30", (run.status === "pending" || run.status === "streaming") && "border-violet-100 bg-violet-50/30"), children: [_jsxs("div", { className: "flex items-center justify-between gap-2", children: [_jsx("div", { className: "text-xs font-semibold text-gray-700 truncate", children: run.modelName }), _jsxs("div", { className: "flex items-center gap-2 shrink-0", children: [(run.status === "pending" || run.status === "streaming") && (_jsx("button", { type: "button", onClick: () => handleStopModelRun(run.agentId), className: "p-1.5 rounded-lg text-gray-500 hover:text-red-600 hover:bg-red-50 transition-colors", title: "Stop this model", children: _jsx(StopCircle, { className: "w-4 h-4" }) })), _jsxs(Badge, { variant: "outline", className: cn("text-[10px]", run.status === "done" && "border-green-300 text-green-700", run.status === "error" && "border-red-300 text-red-700", (run.status === "pending" || run.status === "streaming") && "border-violet-300 text-violet-700"), children: [run.status === "pending" && "Queued", run.status === "streaming" && "Streaming…", run.status === "done" && "Ready", run.status === "error" && "Error"] })] })] }), _jsxs("div", { className: cn("text-xs whitespace-pre-wrap rounded-lg p-2 overflow-y-auto border min-h-[80px]", run.status === "done" && "bg-white/80 border-green-100", run.status === "error" && "bg-white/80 border-red-100 text-red-700", (run.status === "pending" || run.status === "streaming") && "bg-white/60 border-violet-100"), style: { maxHeight: isLarge ? "420px" : "200px" }, children: [run.status === "pending" && (_jsx("span", { className: "text-gray-400 italic", children: "Starting\u2026" })), run.status === "streaming" && (_jsx(_Fragment, { children: run.rawContent?.trim() ? (renderTextWithContext(run.rawContent, false)) : (_jsx("span", { className: "text-gray-400 italic", children: "Waiting for response\u2026" })) })), run.status === "done" && run.replacementText != null && (_jsxs(_Fragment, { children: [renderTextWithContext(run.replacementText, true), _jsxs(Button, { size: "sm", onClick: () => handleUseRunResult(run.replacementText), className: "mt-2 bg-violet-600 hover:bg-violet-700 text-white rounded-lg font-semibold w-full", children: [_jsx(Check, { className: "w-4 h-4 mr-1.5" }), "Use this"] })] })), run.status === "error" && (_jsx("div", { className: "text-red-700", children: run.error || "Something went wrong." }))] })] }, run.agentId))) })] })), _jsxs("form", { onSubmit: (e) => {
|
|
529
852
|
e.preventDefault();
|
|
530
853
|
if (instruction.trim()) {
|
|
531
854
|
executeAiModification(instruction.trim());
|
|
532
855
|
setInstruction("");
|
|
533
856
|
}
|
|
534
|
-
}, className: "relative group", children: [_jsx(Textarea, { ref: inputRef, value: instruction, onChange: (e) => setInstruction(e.target.value), onKeyDown: handleTextareaKeyDown, placeholder: "Not quite right? Ask for a change...", className: cn("w-full min-h-[80px] py-3 pl-3 pr-14 text-
|
|
535
|
-
setSelectedModelId(model.id);
|
|
536
|
-
setModelPopoverOpen(false);
|
|
537
|
-
}, className: cn("w-full text-left px-2 py-1.5 text-xs rounded-md transition-colors", selectedModelId === model.id
|
|
857
|
+
}, className: "relative group", children: [_jsx(Textarea, { ref: inputRef, value: instruction, onChange: (e) => setInstruction(e.target.value), onKeyDown: handleTextareaKeyDown, placeholder: "Not quite right? Ask for a change...", className: cn("w-full min-h-[80px] py-3 pl-3 pr-14 text-xs rounded-2xl border border-gray-200", "focus:border-violet-400 focus:ring-4 focus:ring-violet-500/10", "outline-none transition-all duration-200 bg-gray-50/30 resize-none") }), _jsxs("div", { className: "absolute right-2 bottom-2 flex items-center gap-1", children: [hasMultipleModels && (_jsxs(Popover, { open: modelPopoverOpen, onOpenChange: setModelPopoverOpen, children: [_jsx(PopoverTrigger, { asChild: true, children: _jsx("button", { type: "button", className: cn("p-1.5 rounded-lg transition-all duration-200", "text-gray-400 hover:text-violet-600 hover:bg-violet-50", modelPopoverOpen && "text-violet-600 bg-violet-50"), title: selectedModelSummary ? `Models: ${selectedModelSummary}` : "Select models", children: _jsx(Cpu, { className: "w-3.5 h-3.5" }) }) }), _jsxs(PopoverContent, { className: "w-56 p-1.5", align: "end", sideOffset: 8, children: [_jsxs("div", { className: "flex items-center justify-between px-2 py-1", children: [_jsx("span", { className: "text-[10px] font-semibold text-gray-400 uppercase tracking-wider", children: "Models" }), _jsxs("span", { className: "text-[10px] text-violet-600 font-medium", children: [selectedModels.length, " selected"] })] }), _jsx("div", { className: "space-y-0.5", children: availableModels.map((model) => (_jsxs("button", { type: "button", onClick: () => toggleModelSelection(model.id), className: cn("w-full text-left px-2 py-1.5 text-xs rounded-md transition-colors flex items-center gap-2", selectedModelIds.includes(model.id)
|
|
538
858
|
? "bg-violet-100 text-violet-700 font-medium"
|
|
539
|
-
: "text-gray-600 hover:bg-gray-100"), children:
|
|
859
|
+
: "text-gray-600 hover:bg-gray-100"), children: [_jsx("span", { className: cn("w-3.5 h-3.5 rounded border flex items-center justify-center", selectedModelIds.includes(model.id)
|
|
860
|
+
? "border-violet-600 bg-violet-600 text-white"
|
|
861
|
+
: "border-gray-300 bg-white text-transparent"), children: _jsx(Check, { className: "w-3 h-3" }) }), model.name] }, model.id))) })] })] })), _jsx("button", { type: "submit", disabled: !instruction.trim() || selectedModels.length === 0, className: cn("p-2.5 rounded-xl transition-all duration-300", instruction.trim() && selectedModels.length > 0
|
|
540
862
|
? "bg-violet-600 text-white shadow-lg shadow-violet-200 hover:bg-violet-700 hover:-translate-y-0.5"
|
|
541
|
-
: "bg-gray-100 text-gray-400 cursor-not-allowed"), title: "Refine (Enter)", children: _jsx(Wand2, { className: "w-4 h-4" }) })] })] }), _jsxs("div", { className: "flex gap-2.5 pt-1", children: [_jsxs(Button, { variant: "ghost", size: "sm", onClick: handleStartOver, className: "flex-1 text-gray-500 hover:text-gray-700 hover:bg-gray-100 rounded-xl font-medium", children: [_jsx(RotateCcw, { className: "w-4 h-4 mr-2" }), "Discard"] }), _jsxs(Button, { size: "sm", onClick:
|
|
863
|
+
: "bg-gray-100 text-gray-400 cursor-not-allowed"), title: "Refine (Enter)", children: _jsx(Wand2, { className: "w-4 h-4" }) })] })] }), _jsxs("div", { className: "flex gap-2.5 pt-1", children: [_jsxs(Button, { variant: "ghost", size: "sm", onClick: handleStartOver, className: "flex-1 text-gray-500 hover:text-gray-700 hover:bg-gray-100 rounded-xl font-medium", children: [_jsx(RotateCcw, { className: "w-4 h-4 mr-2" }), "Discard"] }), _jsxs(Button, { variant: "ghost", size: "sm", onClick: handleRetry, disabled: conversationHistory.length === 0, className: "flex-1 text-violet-600 hover:text-violet-700 hover:bg-violet-50 rounded-xl font-medium disabled:opacity-50 disabled:pointer-events-none", title: "Run the same request again", children: [_jsx(RotateCw, { className: "w-4 h-4 mr-2" }), "Retry"] })] })] }))] })] }));
|
|
542
864
|
}
|
|
543
865
|
export default InlineAiDialog;
|
|
544
866
|
//# sourceMappingURL=InlineAiDialog.js.map
|