@parhelia/core 0.1.12556 → 0.1.12560
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 +187 -98
- 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 +2377 -483
- package/dist/editor/ai/AgentTerminal.js.map +1 -1
- package/dist/editor/ai/AgentTerminalStatusBar.d.ts +8 -3
- package/dist/editor/ai/AgentTerminalStatusBar.js +460 -56
- package/dist/editor/ai/AgentTerminalStatusBar.js.map +1 -1
- package/dist/editor/ai/Agents.js +150 -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 +238 -23
- 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 +518 -147
- package/dist/editor/ai/ToolCallDisplay.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 +86 -99
- 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 +68 -7
- 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/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/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 +22 -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 +14 -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,62 +1,193 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { useState, useEffect, useMemo } from "react";
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { useState, useEffect, useMemo, useCallback } from "react";
|
|
3
3
|
import { Button } from "../../../components/ui/button";
|
|
4
|
+
import { Input } from "../../../components/ui/input";
|
|
5
|
+
import { Select } from "../../../components/ui/select";
|
|
6
|
+
import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from "../../../components/ui/dialog";
|
|
4
7
|
import { setupWizardService, } from "../../../setup/services/setupWizardService";
|
|
5
|
-
import {
|
|
8
|
+
import { AlertCircle, RefreshCw, Upload, Plus, ArrowRight, Brain, Image, Settings, Cloud, Trash2, Copy, } from "lucide-react";
|
|
9
|
+
import { useSearchParams } from "../../client/navigation";
|
|
6
10
|
import { AddModelDialog } from "../../../setup/wizard/steps/AddModelDialog";
|
|
7
11
|
import { ImportModelDialog } from "../../../setup/wizard/steps/ImportModelDialog";
|
|
8
12
|
import { Splitter } from "../../ui/Splitter";
|
|
9
|
-
import {
|
|
13
|
+
import { ModelConfigPanel } from "./ModelConfigPanel";
|
|
10
14
|
import { useEditContext } from "../../client/editContext";
|
|
11
15
|
import { FilterInput } from "../../../components/FilterInput";
|
|
16
|
+
const SELECTED_MODEL_QUERY_PARAM = "modelId";
|
|
17
|
+
/**
|
|
18
|
+
* True when a numeric price is present (including 0). Used for display and
|
|
19
|
+
* "missing pricing" detection; provider import leaves fields empty instead of "0".
|
|
20
|
+
*/
|
|
21
|
+
const hasDefinedPricingValue = (value) => value !== undefined && value !== null;
|
|
22
|
+
const hasUsableImagePricing = (model) => hasDefinedPricingValue(model.pricing?.requestCost) ||
|
|
23
|
+
hasDefinedPricingValue(model.pricing?.imageCost) ||
|
|
24
|
+
hasDefinedPricingValue(model.pricing?.imageOutputCost) ||
|
|
25
|
+
hasDefinedPricingValue(model.pricing?.imageTokenCost) ||
|
|
26
|
+
hasDefinedPricingValue(model.pricing?.inputTextTokenCostPerMillion) ||
|
|
27
|
+
hasDefinedPricingValue(model.pricing?.inputImageTokenCostPerMillion) ||
|
|
28
|
+
hasDefinedPricingValue(model.pricing?.outputImageTokenCostPerMillion);
|
|
29
|
+
/**
|
|
30
|
+
* True when the model row has nothing to show on the pricing line (no usable
|
|
31
|
+
* token/image figures). This is the same condition used to decide whether to
|
|
32
|
+
* show the warning — avoids blank rows when field-level "missing" logic drifts.
|
|
33
|
+
*/
|
|
34
|
+
const isPricingLineEmpty = (model) => !hasVisiblePricingSummary(model);
|
|
35
|
+
const getPricingWarningMessage = (model) => {
|
|
36
|
+
const template = model.templateType || "Ai Chat Model";
|
|
37
|
+
if (template === "Ai Image Model") {
|
|
38
|
+
return "Pricing information is missing. Configure at least one image pricing field.";
|
|
39
|
+
}
|
|
40
|
+
if (template === "Ai Embeddings Model") {
|
|
41
|
+
return "Pricing information is missing. Set Input Cost Per Million Tokens.";
|
|
42
|
+
}
|
|
43
|
+
const missingFields = [];
|
|
44
|
+
if (!hasDefinedPricingValue(model.pricing?.inputCostPerMillionTokens)) {
|
|
45
|
+
missingFields.push("Input Cost Per Million Tokens");
|
|
46
|
+
}
|
|
47
|
+
if (!hasDefinedPricingValue(model.pricing?.outputCostPerMillionTokens)) {
|
|
48
|
+
missingFields.push("Output Cost Per Million Tokens");
|
|
49
|
+
}
|
|
50
|
+
if (missingFields.length === 0) {
|
|
51
|
+
return "Pricing information is missing.";
|
|
52
|
+
}
|
|
53
|
+
return `Pricing information is missing. Set ${missingFields.join(" and ")}.`;
|
|
54
|
+
};
|
|
55
|
+
const hasVisiblePricingSummary = (model) => {
|
|
56
|
+
if (!model.pricing) {
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
if (model.templateType === "Ai Image Model") {
|
|
60
|
+
return hasUsableImagePricing(model);
|
|
61
|
+
}
|
|
62
|
+
return (hasDefinedPricingValue(model.pricing.inputCostPerMillionTokens) ||
|
|
63
|
+
hasDefinedPricingValue(model.pricing.outputCostPerMillionTokens) ||
|
|
64
|
+
hasDefinedPricingValue(model.pricing.cachedInputCostPerMillionTokens));
|
|
65
|
+
};
|
|
66
|
+
/** Sitecore item name for lists and dialogs; falls back to API model id / key. */
|
|
67
|
+
function getModelListLabel(model) {
|
|
68
|
+
return model.itemName?.trim() || model.name || model.key || "";
|
|
69
|
+
}
|
|
70
|
+
function normalizeModelId(id) {
|
|
71
|
+
return (id || "").replace(/[{}]/g, "").toLowerCase();
|
|
72
|
+
}
|
|
73
|
+
function getModelTypeLabel(templateType) {
|
|
74
|
+
switch (templateType) {
|
|
75
|
+
case "Ai Chat Model":
|
|
76
|
+
return "Chat";
|
|
77
|
+
case "Ai Embeddings Model":
|
|
78
|
+
return "Embeddings";
|
|
79
|
+
case "Ai Image Model":
|
|
80
|
+
return "Image";
|
|
81
|
+
default:
|
|
82
|
+
return templateType;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
12
85
|
/**
|
|
13
86
|
* Settings panel for AI Models configuration.
|
|
14
87
|
* Install and configure AI models for chat and other tasks.
|
|
15
88
|
*/
|
|
16
89
|
export function ModelsPanel() {
|
|
17
90
|
const editContext = useEditContext();
|
|
91
|
+
const searchParams = useSearchParams();
|
|
18
92
|
const [state, setState] = useState("loading");
|
|
19
93
|
const [installedModels, setInstalledModels] = useState([]);
|
|
20
94
|
const [providers, setProviders] = useState([]);
|
|
95
|
+
const [settingsExists, setSettingsExists] = useState(false);
|
|
96
|
+
const [defaultChatModelId, setDefaultChatModelId] = useState("");
|
|
97
|
+
const [defaultImageModelId, setDefaultImageModelId] = useState("");
|
|
98
|
+
const [savingDefaults, setSavingDefaults] = useState(false);
|
|
21
99
|
const [error, setError] = useState(null);
|
|
22
100
|
const [updating, setUpdating] = useState(null);
|
|
23
101
|
// Dialog states
|
|
24
102
|
const [showAddDialog, setShowAddDialog] = useState(false);
|
|
25
103
|
const [showImportDialog, setShowImportDialog] = useState(false);
|
|
26
|
-
//
|
|
104
|
+
// URL-synced model selection
|
|
105
|
+
const [urlSelectedModelId, setUrlSelectedModelId] = useState(searchParams.get(SELECTED_MODEL_QUERY_PARAM) ||
|
|
106
|
+
(typeof window !== "undefined"
|
|
107
|
+
? new URLSearchParams(window.location.search).get(SELECTED_MODEL_QUERY_PARAM)
|
|
108
|
+
: null));
|
|
27
109
|
const [selectedModel, setSelectedModel] = useState(null);
|
|
28
110
|
// Bulk pricing update state
|
|
29
111
|
const [updatingAllPricing, setUpdatingAllPricing] = useState(false);
|
|
30
|
-
const [updatingModelPricing, setUpdatingModelPricing] = useState(null);
|
|
31
112
|
// Delete state
|
|
32
113
|
const [deleting, setDeleting] = useState(null);
|
|
114
|
+
// Duplicate state
|
|
115
|
+
const [duplicatingId, setDuplicatingId] = useState(null);
|
|
116
|
+
const [duplicateDialogModel, setDuplicateDialogModel] = useState(null);
|
|
117
|
+
const [duplicateItemName, setDuplicateItemName] = useState("");
|
|
33
118
|
// Provider types (discovered from backend)
|
|
34
119
|
const [providerTypes, setProviderTypes] = useState([]);
|
|
35
120
|
// Filter state
|
|
36
121
|
const [filterText, setFilterText] = useState("");
|
|
122
|
+
useEffect(() => {
|
|
123
|
+
const key = searchParams.get(SELECTED_MODEL_QUERY_PARAM) ||
|
|
124
|
+
(typeof window !== "undefined"
|
|
125
|
+
? new URLSearchParams(window.location.search).get(SELECTED_MODEL_QUERY_PARAM)
|
|
126
|
+
: null);
|
|
127
|
+
setUrlSelectedModelId(key);
|
|
128
|
+
}, [searchParams]);
|
|
129
|
+
useEffect(() => {
|
|
130
|
+
if (typeof window === "undefined")
|
|
131
|
+
return;
|
|
132
|
+
const handlePopState = () => {
|
|
133
|
+
setUrlSelectedModelId(new URLSearchParams(window.location.search).get(SELECTED_MODEL_QUERY_PARAM));
|
|
134
|
+
};
|
|
135
|
+
window.addEventListener("popstate", handlePopState);
|
|
136
|
+
return () => window.removeEventListener("popstate", handlePopState);
|
|
137
|
+
}, []);
|
|
138
|
+
useEffect(() => {
|
|
139
|
+
if (!urlSelectedModelId) {
|
|
140
|
+
if (selectedModel)
|
|
141
|
+
setSelectedModel(null);
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
const match = installedModels.find((m) => m.id === urlSelectedModelId);
|
|
145
|
+
if (match && match !== selectedModel) {
|
|
146
|
+
setSelectedModel(match);
|
|
147
|
+
}
|
|
148
|
+
}, [installedModels, urlSelectedModelId, selectedModel]);
|
|
149
|
+
const updateSelectedModelUrl = useCallback((modelId) => {
|
|
150
|
+
editContext?.updateUrl({
|
|
151
|
+
[SELECTED_MODEL_QUERY_PARAM]: modelId || undefined,
|
|
152
|
+
});
|
|
153
|
+
setUrlSelectedModelId(modelId || null);
|
|
154
|
+
}, [editContext]);
|
|
37
155
|
const handleOpenConfig = (model) => {
|
|
38
156
|
setSelectedModel(model);
|
|
157
|
+
updateSelectedModelUrl(model.id);
|
|
39
158
|
};
|
|
40
159
|
const handleCloseConfig = () => {
|
|
41
160
|
setSelectedModel(null);
|
|
161
|
+
updateSelectedModelUrl(null);
|
|
42
162
|
};
|
|
43
163
|
const loadData = async () => {
|
|
44
164
|
try {
|
|
45
165
|
setState("loading");
|
|
46
166
|
setError(null);
|
|
47
|
-
const [installed, providersData, providerTypesData] = await Promise.all([
|
|
167
|
+
const [installed, providersData, providerTypesData, defaultModels, hasSettings,] = await Promise.all([
|
|
48
168
|
setupWizardService.getInstalledModels(),
|
|
49
169
|
setupWizardService.getProviders(),
|
|
50
170
|
setupWizardService.getProviderTypes(),
|
|
171
|
+
setupWizardService.getDefaultModels(),
|
|
172
|
+
setupWizardService.getSettingsExists(),
|
|
51
173
|
]);
|
|
52
174
|
setInstalledModels(installed);
|
|
53
175
|
setProviders(providersData);
|
|
54
176
|
setProviderTypes(providerTypesData);
|
|
177
|
+
setSettingsExists(hasSettings);
|
|
178
|
+
const resolvedChatModel = installed.find((model) => normalizeModelId(model.id) ===
|
|
179
|
+
normalizeModelId(defaultModels.chatModelId));
|
|
180
|
+
const resolvedImageModel = installed.find((model) => normalizeModelId(model.id) ===
|
|
181
|
+
normalizeModelId(defaultModels.imageModelId));
|
|
182
|
+
setDefaultChatModelId(resolvedChatModel?.id || defaultModels.chatModelId || "");
|
|
183
|
+
setDefaultImageModelId(resolvedImageModel?.id || defaultModels.imageModelId || "");
|
|
55
184
|
setState("success");
|
|
185
|
+
return installed;
|
|
56
186
|
}
|
|
57
187
|
catch (e) {
|
|
58
188
|
setState("error");
|
|
59
189
|
setError(e?.message || "Failed to load models");
|
|
190
|
+
return undefined;
|
|
60
191
|
}
|
|
61
192
|
};
|
|
62
193
|
// Get providers that support model import (any provider with a registered provider type)
|
|
@@ -120,88 +251,131 @@ export function ModelsPanel() {
|
|
|
120
251
|
setUpdatingAllPricing(false);
|
|
121
252
|
}
|
|
122
253
|
};
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
if (!model.providerId || !model.name) {
|
|
126
|
-
setError("Model provider or name is missing");
|
|
254
|
+
const handleUpdate = async (model) => {
|
|
255
|
+
if (!model.id || !model.key)
|
|
127
256
|
return;
|
|
128
|
-
}
|
|
129
257
|
try {
|
|
130
|
-
|
|
258
|
+
setUpdating(model.id);
|
|
131
259
|
setError(null);
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
mode: "updatePricing",
|
|
260
|
+
await setupWizardService.updateModel({
|
|
261
|
+
modelId: model.id,
|
|
262
|
+
sourceModelKey: model.key,
|
|
136
263
|
});
|
|
137
264
|
await loadData();
|
|
138
|
-
if (result.errors.length > 0) {
|
|
139
|
-
setError(`Errors: ${result.errors.join(", ")}`);
|
|
140
|
-
}
|
|
141
265
|
}
|
|
142
266
|
catch (e) {
|
|
143
|
-
setError(e?.message || "Failed to update
|
|
267
|
+
setError(e?.message || "Failed to update model");
|
|
144
268
|
}
|
|
145
269
|
finally {
|
|
146
|
-
|
|
270
|
+
setUpdating(null);
|
|
147
271
|
}
|
|
148
272
|
};
|
|
149
|
-
const
|
|
150
|
-
if (!
|
|
273
|
+
const handleDefaultModelsChange = async (nextChatModelId, nextImageModelId) => {
|
|
274
|
+
if (!settingsExists) {
|
|
275
|
+
setError("Parhelia settings item not found");
|
|
151
276
|
return;
|
|
277
|
+
}
|
|
278
|
+
const previousChatModelId = defaultChatModelId;
|
|
279
|
+
const previousImageModelId = defaultImageModelId;
|
|
280
|
+
setDefaultChatModelId(nextChatModelId);
|
|
281
|
+
setDefaultImageModelId(nextImageModelId);
|
|
152
282
|
try {
|
|
153
|
-
|
|
283
|
+
setSavingDefaults(true);
|
|
154
284
|
setError(null);
|
|
155
|
-
await setupWizardService.
|
|
156
|
-
|
|
157
|
-
|
|
285
|
+
await setupWizardService.setDefaultModels({
|
|
286
|
+
chatModelId: nextChatModelId,
|
|
287
|
+
imageModelId: nextImageModelId,
|
|
158
288
|
});
|
|
159
|
-
await loadData();
|
|
160
289
|
}
|
|
161
290
|
catch (e) {
|
|
162
|
-
|
|
291
|
+
setDefaultChatModelId(previousChatModelId);
|
|
292
|
+
setDefaultImageModelId(previousImageModelId);
|
|
293
|
+
setError(e?.message || "Failed to save default models");
|
|
163
294
|
}
|
|
164
295
|
finally {
|
|
165
|
-
|
|
296
|
+
setSavingDefaults(false);
|
|
166
297
|
}
|
|
167
298
|
};
|
|
168
|
-
const handleDelete = (model) => {
|
|
299
|
+
const handleDelete = async (model) => {
|
|
169
300
|
if (!editContext || !model.id)
|
|
170
301
|
return;
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
id: model.id,
|
|
188
|
-
language: editContext.item?.language ??
|
|
189
|
-
editContext.currentItemDescriptor?.language ??
|
|
190
|
-
"en",
|
|
191
|
-
version: 0,
|
|
192
|
-
},
|
|
193
|
-
]);
|
|
194
|
-
// Reload the models list
|
|
195
|
-
await loadData();
|
|
196
|
-
}
|
|
197
|
-
catch (e) {
|
|
198
|
-
setError(e?.message || "Failed to delete model");
|
|
302
|
+
try {
|
|
303
|
+
setDeleting(model.id);
|
|
304
|
+
setError(null);
|
|
305
|
+
const deleted = await editContext.operations.deleteItems([
|
|
306
|
+
{
|
|
307
|
+
id: model.id,
|
|
308
|
+
language: editContext.item?.language ??
|
|
309
|
+
editContext.currentItemDescriptor?.language ??
|
|
310
|
+
"en",
|
|
311
|
+
version: 0,
|
|
312
|
+
},
|
|
313
|
+
]);
|
|
314
|
+
if (deleted) {
|
|
315
|
+
if (selectedModel?.id === model.id) {
|
|
316
|
+
setSelectedModel(null);
|
|
317
|
+
updateSelectedModelUrl(null);
|
|
199
318
|
}
|
|
200
|
-
|
|
201
|
-
|
|
319
|
+
await loadData();
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
catch (e) {
|
|
323
|
+
setError(e?.message || "Failed to delete model");
|
|
324
|
+
}
|
|
325
|
+
finally {
|
|
326
|
+
setDeleting(null);
|
|
327
|
+
}
|
|
328
|
+
};
|
|
329
|
+
const openDuplicateDialog = (model) => {
|
|
330
|
+
const segment = model.itemName?.trim() ||
|
|
331
|
+
(model.key.includes("/") && model.key.split("/").length > 0
|
|
332
|
+
? model.key.split("/").pop()
|
|
333
|
+
: model.name || model.key);
|
|
334
|
+
setDuplicateItemName(`Copy of ${segment}`);
|
|
335
|
+
setDuplicateDialogModel(model);
|
|
336
|
+
};
|
|
337
|
+
const handleConfirmDuplicate = async () => {
|
|
338
|
+
if (!editContext || !duplicateDialogModel?.id) {
|
|
339
|
+
return;
|
|
340
|
+
}
|
|
341
|
+
const parentId = duplicateDialogModel.parentId;
|
|
342
|
+
if (!parentId) {
|
|
343
|
+
return;
|
|
344
|
+
}
|
|
345
|
+
const name = duplicateItemName.trim();
|
|
346
|
+
if (!name) {
|
|
347
|
+
setError("Enter a name for the duplicate item");
|
|
348
|
+
return;
|
|
349
|
+
}
|
|
350
|
+
const model = duplicateDialogModel;
|
|
351
|
+
const lang = editContext.item?.language ??
|
|
352
|
+
editContext.currentItemDescriptor?.language ??
|
|
353
|
+
"en";
|
|
354
|
+
try {
|
|
355
|
+
setDuplicatingId(model.id);
|
|
356
|
+
setError(null);
|
|
357
|
+
const created = await editContext.operations.duplicateItem({ id: model.id, language: lang, version: 0 }, { id: parentId, language: lang, version: 0 }, name);
|
|
358
|
+
if (!created) {
|
|
359
|
+
setDuplicatingId(null);
|
|
360
|
+
return;
|
|
361
|
+
}
|
|
362
|
+
setDuplicateDialogModel(null);
|
|
363
|
+
const list = await loadData();
|
|
364
|
+
if (list) {
|
|
365
|
+
const createdId = String(created.id).replace(/[{}]/g, "").toLowerCase();
|
|
366
|
+
const next = list.find((m) => m.id.replace(/[{}]/g, "").toLowerCase() === createdId);
|
|
367
|
+
if (next) {
|
|
368
|
+
setSelectedModel(next);
|
|
369
|
+
updateSelectedModelUrl(next.id);
|
|
202
370
|
}
|
|
203
|
-
}
|
|
204
|
-
}
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
catch (e) {
|
|
374
|
+
setError(e?.message || "Failed to duplicate model");
|
|
375
|
+
}
|
|
376
|
+
finally {
|
|
377
|
+
setDuplicatingId(null);
|
|
378
|
+
}
|
|
205
379
|
};
|
|
206
380
|
useEffect(() => {
|
|
207
381
|
loadData();
|
|
@@ -211,25 +385,50 @@ export function ModelsPanel() {
|
|
|
211
385
|
window.location.hash = "#providers";
|
|
212
386
|
}
|
|
213
387
|
};
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
const
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
388
|
+
const chatModels = useMemo(() => installedModels
|
|
389
|
+
.filter((model) => model.templateType === "Ai Chat Model")
|
|
390
|
+
.sort((a, b) => getModelListLabel(a).localeCompare(getModelListLabel(b))), [installedModels]);
|
|
391
|
+
const imageModels = useMemo(() => installedModels
|
|
392
|
+
.filter((model) => model.templateType === "Ai Image Model")
|
|
393
|
+
.sort((a, b) => getModelListLabel(a).localeCompare(getModelListLabel(b))), [installedModels]);
|
|
394
|
+
const chatDefaultConfiguredModel = useMemo(() => chatModels.find((model) => normalizeModelId(model.id) === normalizeModelId(defaultChatModelId)), [chatModels, defaultChatModelId]);
|
|
395
|
+
const imageDefaultConfiguredModel = useMemo(() => imageModels.find((model) => normalizeModelId(model.id) === normalizeModelId(defaultImageModelId)), [imageModels, defaultImageModelId]);
|
|
396
|
+
const chatModelOptions = useMemo(() => {
|
|
397
|
+
const options = [
|
|
398
|
+
{ value: "", label: "Not set" },
|
|
399
|
+
...chatModels.map((model) => ({
|
|
400
|
+
value: model.id,
|
|
401
|
+
label: getModelListLabel(model),
|
|
402
|
+
description: model.providerName || undefined,
|
|
403
|
+
})),
|
|
404
|
+
];
|
|
405
|
+
if (defaultChatModelId && !chatDefaultConfiguredModel) {
|
|
406
|
+
options.push({
|
|
407
|
+
value: defaultChatModelId,
|
|
408
|
+
label: "Configured model not found",
|
|
409
|
+
description: defaultChatModelId,
|
|
410
|
+
});
|
|
231
411
|
}
|
|
232
|
-
|
|
412
|
+
return options;
|
|
413
|
+
}, [chatModels, defaultChatModelId, chatDefaultConfiguredModel]);
|
|
414
|
+
const imageModelOptions = useMemo(() => {
|
|
415
|
+
const options = [
|
|
416
|
+
{ value: "", label: "Not set" },
|
|
417
|
+
...imageModels.map((model) => ({
|
|
418
|
+
value: model.id,
|
|
419
|
+
label: getModelListLabel(model),
|
|
420
|
+
description: model.providerName || undefined,
|
|
421
|
+
})),
|
|
422
|
+
];
|
|
423
|
+
if (defaultImageModelId && !imageDefaultConfiguredModel) {
|
|
424
|
+
options.push({
|
|
425
|
+
value: defaultImageModelId,
|
|
426
|
+
label: "Configured model not found",
|
|
427
|
+
description: defaultImageModelId,
|
|
428
|
+
});
|
|
429
|
+
}
|
|
430
|
+
return options;
|
|
431
|
+
}, [imageModels, defaultImageModelId, imageDefaultConfiguredModel]);
|
|
233
432
|
// Filter models based on filter text
|
|
234
433
|
const filteredModels = useMemo(() => {
|
|
235
434
|
if (!filterText.trim()) {
|
|
@@ -237,18 +436,20 @@ export function ModelsPanel() {
|
|
|
237
436
|
}
|
|
238
437
|
const searchTerm = filterText.toLowerCase().trim();
|
|
239
438
|
return installedModels.filter((model) => {
|
|
439
|
+
const listLabel = getModelListLabel(model).toLowerCase();
|
|
240
440
|
const modelName = (model.name || model.key || "").toLowerCase();
|
|
241
441
|
const providerName = (model.providerName || "").toLowerCase();
|
|
242
442
|
const templateType = (model.templateType || "").toLowerCase();
|
|
243
443
|
const modelTypeLabel = getModelTypeLabel(model.templateType || "Ai Chat Model").toLowerCase();
|
|
244
|
-
return (
|
|
444
|
+
return (listLabel.includes(searchTerm) ||
|
|
445
|
+
modelName.includes(searchTerm) ||
|
|
245
446
|
providerName.includes(searchTerm) ||
|
|
246
447
|
templateType.includes(searchTerm) ||
|
|
247
448
|
modelTypeLabel.includes(searchTerm));
|
|
248
449
|
});
|
|
249
|
-
}, [installedModels, filterText
|
|
450
|
+
}, [installedModels, filterText]);
|
|
250
451
|
// Group models by provider for display
|
|
251
|
-
const groupModelsByProvider = (models) => {
|
|
452
|
+
const groupModelsByProvider = useCallback((models) => {
|
|
252
453
|
const groups = {};
|
|
253
454
|
models.forEach((model) => {
|
|
254
455
|
const providerId = model.providerId || "unknown";
|
|
@@ -265,42 +466,60 @@ export function ModelsPanel() {
|
|
|
265
466
|
const typeOrder = (a.templateType || "").localeCompare(b.templateType || "");
|
|
266
467
|
if (typeOrder !== 0)
|
|
267
468
|
return typeOrder;
|
|
268
|
-
return (a
|
|
469
|
+
return getModelListLabel(a).localeCompare(getModelListLabel(b));
|
|
269
470
|
});
|
|
270
471
|
});
|
|
271
472
|
return groups;
|
|
272
|
-
};
|
|
273
|
-
const modelsByProvider = useMemo(() => groupModelsByProvider(filteredModels), [filteredModels,
|
|
274
|
-
const
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
if (currentState === "error")
|
|
278
|
-
return _jsx(AlertCircle, { className: "h-4 w-4 text-red-600", strokeWidth: 1 });
|
|
279
|
-
return (_jsx(RefreshCw, { className: "h-4 w-4 animate-spin text-amber-600", strokeWidth: 1 }));
|
|
280
|
-
};
|
|
473
|
+
}, [providers]);
|
|
474
|
+
const modelsByProvider = useMemo(() => groupModelsByProvider(filteredModels), [filteredModels, groupModelsByProvider]);
|
|
475
|
+
const modelsMissingPricing = useMemo(() => {
|
|
476
|
+
return installedModels.filter((model) => isPricingLineEmpty(model));
|
|
477
|
+
}, [installedModels]);
|
|
281
478
|
// Build the models list content
|
|
282
|
-
const modelsListContent = (_jsx("div", { className: "flex h-full flex-col p-4", children: _jsx("div", { className: "mx-auto flex w-full flex-1 flex-col overflow-hidden", children: _jsxs("div", { className: "flex h-full flex-col overflow-hidden", children: [_jsxs("div", { className: "shrink-0
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
479
|
+
const modelsListContent = (_jsx("div", { className: "flex h-full flex-col p-4", children: _jsx("div", { className: "mx-auto flex w-full flex-1 flex-col overflow-hidden", children: _jsxs("div", { className: "flex h-full flex-col overflow-hidden", children: [_jsxs("div", { className: "mt-1 shrink-0", children: [_jsxs("div", { className: "mb-2 rounded-t-lg bg-white p-4", children: [_jsxs("div", { className: "flex flex-wrap items-start justify-between gap-3", children: [_jsxs("div", { children: [_jsx("h2", { className: "text-sm font-semibold text-gray-900", children: "Default models" }), _jsx("p", { className: "mt-1 text-xs text-gray-500", children: "Choose the shared defaults used when a chat or image model is not configured elsewhere." })] }), savingDefaults && (_jsxs("div", { className: "flex items-center gap-2 text-xs text-gray-500", children: [_jsx(RefreshCw, { className: "h-3.5 w-3.5 animate-spin" }), "Saving..."] }))] }), _jsxs("div", { className: "mt-4 grid gap-4 md:grid-cols-2", children: [_jsxs("div", { className: "space-y-2", children: [_jsxs("label", { className: "flex items-center gap-2 text-sm font-medium text-gray-700", children: [_jsx(Brain, { className: "h-4 w-4 text-purple-600", strokeWidth: 1.5 }), "Default chat model"] }), _jsx(Select, { value: defaultChatModelId, onValueChange: (value) => void handleDefaultModelsChange(value, defaultImageModelId), options: chatModelOptions, placeholder: "Select a chat model", disabled: savingDefaults || !settingsExists, searchable: true, searchPlaceholder: "Search chat models..." }), _jsx("p", { className: "text-xs text-gray-500", children: "Used by features that fall back to the settings-level chat model." })] }), _jsxs("div", { className: "space-y-2", children: [_jsxs("label", { className: "flex items-center gap-2 text-sm font-medium text-gray-700", children: [_jsx(Image, { className: "h-4 w-4 text-green-600", strokeWidth: 1.5 }), "Default image model"] }), _jsx(Select, { value: defaultImageModelId, onValueChange: (value) => void handleDefaultModelsChange(defaultChatModelId, value), options: imageModelOptions, placeholder: "Select an image model", disabled: savingDefaults || !settingsExists, searchable: true, searchPlaceholder: "Search image models..." }), _jsx("p", { className: "text-xs text-gray-500", children: "Used by image generation and editing features that rely on the shared default." })] })] }), !settingsExists && (_jsx("div", { className: "mt-4 rounded border border-yellow-200 bg-yellow-50 p-3 text-xs text-yellow-800", children: "Create the Parhelia settings item before saving default models." }))] }), _jsx("div", { className: "rounded-t-lg bg-white p-4", children: _jsxs("div", { className: "flex flex-wrap items-start justify-between gap-3", children: [_jsxs("div", { children: [_jsxs("h2", { className: "text-sm font-semibold text-gray-900", children: ["Installed models (", installedModels.length, ")"] }), _jsx("p", { className: "mt-1 text-xs text-gray-500", children: "Browse, filter, and configure the models available in Parhelia." }), modelsMissingPricing.length > 0 && (_jsxs("div", { className: "mt-3 rounded border border-yellow-200 bg-yellow-50 p-3 text-xs text-yellow-800", children: [modelsMissingPricing.length, " installed model", modelsMissingPricing.length !== 1
|
|
480
|
+
? "s have"
|
|
481
|
+
: " has", " ", "missing or incomplete pricing information. A warning is shown on each affected model below."] }))] }), _jsx("div", { className: "flex flex-wrap items-center gap-3", children: importableInstalledModels.length > 0 && (_jsxs(Button, { size: "sm", variant: "outline", onClick: handleUpdateAllPricing, disabled: updatingAllPricing, title: "Update pricing for all models from their provider APIs", children: [updatingAllPricing ? (_jsx(RefreshCw, { className: "mr-1 h-4 w-4 animate-spin" })) : (_jsx(RefreshCw, { className: "mr-1 h-4 w-4" })), "Update All Pricing"] })) })] }) }), _jsxs("div", { className: "bg-white px-4", children: [state !== "loading" && providers.length === 0 && (_jsx("div", { className: "rounded border border-yellow-200 bg-yellow-50 p-4", children: _jsxs("div", { className: "flex items-start gap-3", children: [_jsx(AlertCircle, { className: "mt-0.5 h-5 w-5 shrink-0 text-yellow-600" }), _jsxs("div", { className: "flex-1", children: [_jsx("p", { className: "mb-1 text-sm font-medium text-yellow-800", children: "No providers configured" }), _jsx("p", { className: "mb-3 text-xs text-yellow-700", children: "You need to configure at least one provider before you can add models." }), _jsxs(Button, { size: "sm", variant: "outline", onClick: handleNavigateToProviders, className: "text-xs", children: ["Go to Providers", _jsx(ArrowRight, { className: "ml-1 h-3 w-3" })] })] })] }) })), providers.length > 0 && (_jsxs("div", { className: "mb-4 flex gap-2", children: [importableProviders.length > 0 && (_jsxs(Button, { size: "sm", variant: "outline", onClick: () => {
|
|
482
|
+
setShowImportDialog(true);
|
|
483
|
+
setError(null);
|
|
484
|
+
}, children: [_jsx(Cloud, { strokeWidth: 1, className: "mr-1 h-4 w-4" }), "Import from Provider"] })), _jsxs(Button, { size: "sm", variant: "outline", onClick: () => {
|
|
485
|
+
setShowAddDialog(true);
|
|
486
|
+
setError(null);
|
|
487
|
+
}, children: [_jsx(Plus, { strokeWidth: 1, className: "mr-1 h-4 w-4" }), "Add Manually"] })] })), error && (_jsx("div", { className: "rounded border border-red-200 bg-red-50 p-2 text-xs whitespace-pre-wrap text-red-700", children: error })), _jsx(FilterInput, { value: filterText, onChange: setFilterText, placeholder: "Filter models by name, provider, or type...", className: "mb-4 w-full" })] })] }), _jsx("div", { className: "min-h-0 flex-1 overflow-y-auto rounded-b-lg bg-white px-4 pb-4", children: filterText && filteredModels.length === 0 ? (_jsxs("div", { className: "flex items-center justify-center py-8 text-sm text-gray-500", children: ["No models found matching ", `"${filterText}"`] })) : (_jsx("div", { className: "space-y-4", children: Object.entries(modelsByProvider).map(([providerId, { providerName, models }]) => {
|
|
289
488
|
if (models.length === 0)
|
|
290
489
|
return null;
|
|
291
490
|
return (_jsxs("div", { className: "space-y-2", children: [_jsxs("label", { className: "block text-sm font-medium text-gray-700", children: [providerName, _jsxs("span", { className: "ml-2 text-xs font-normal text-gray-500", children: ["(", models.length, " model", models.length !== 1 ? "s" : "", ")"] })] }), _jsx("div", { className: "space-y-2", children: models.map((model) => {
|
|
292
491
|
const status = model.status;
|
|
293
492
|
const isSelected = selectedModel?.id === model.id;
|
|
493
|
+
const showPricingLine = hasVisiblePricingSummary(model);
|
|
294
494
|
return (_jsxs("div", { className: `flex flex-wrap items-center gap-2 rounded border p-3 text-sm transition-shadow hover:shadow-sm ${isSelected
|
|
295
495
|
? "border-blue-400 bg-blue-50"
|
|
296
|
-
: "border-gray-200 bg-white"}`, children: [_jsxs("div", { className: "min-w-0 flex-1", children: [_jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [_jsx("span", { className: "truncate font-medium", children: model
|
|
297
|
-
|
|
496
|
+
: "border-gray-200 bg-white"}`, children: [_jsxs("div", { className: "min-w-0 flex-1", children: [_jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [_jsx("span", { className: "truncate font-medium", children: getModelListLabel(model) }), _jsx("span", { className: "shrink-0 rounded bg-gray-100 px-1.5 py-0.5 text-xs text-gray-600", children: getModelTypeLabel(model.templateType || "Ai Chat Model") }), normalizeModelId(model.id) ===
|
|
497
|
+
normalizeModelId(defaultChatModelId) && (_jsx("span", { className: "shrink-0 rounded bg-purple-100 px-1.5 py-0.5 text-xs text-purple-700", children: "Default chat" })), normalizeModelId(model.id) ===
|
|
498
|
+
normalizeModelId(defaultImageModelId) && (_jsx("span", { className: "shrink-0 rounded bg-green-100 px-1.5 py-0.5 text-xs text-green-700", children: "Default image" })), status === "Outdated" && (_jsx("span", { className: "shrink-0 rounded bg-amber-100 px-1.5 py-0.5 text-xs text-amber-700", children: "Update available" })), !showPricingLine && (_jsx("span", { className: "shrink-0 rounded bg-yellow-100 px-1.5 py-0.5 text-xs text-yellow-800", children: "Pricing missing" }))] }), showPricingLine && model.pricing ? (_jsx("div", { className: "mt-1 text-xs text-gray-500", children: model.templateType ===
|
|
499
|
+
"Ai Image Model" &&
|
|
500
|
+
hasUsableImagePricing(model) ? (_jsxs(_Fragment, { children: [hasDefinedPricingValue(model.pricing.inputTextTokenCostPerMillion) && (_jsxs("span", { children: ["Input Text: $", model.pricing.inputTextTokenCostPerMillion.toFixed(2), "/M"] })), hasDefinedPricingValue(model.pricing.inputImageTokenCostPerMillion) && (_jsxs("span", { className: "ml-2", children: ["Input Image: $", model.pricing.inputImageTokenCostPerMillion.toFixed(2), "/M"] })), hasDefinedPricingValue(model.pricing.outputImageTokenCostPerMillion) && (_jsxs("span", { className: "ml-2", children: ["Output Image: $", model.pricing.outputImageTokenCostPerMillion.toFixed(2), "/M"] })), hasDefinedPricingValue(model.pricing.imageTokenCost) &&
|
|
501
|
+
!hasDefinedPricingValue(model.pricing.outputImageTokenCostPerMillion) && (_jsxs("span", { className: "ml-2", children: ["Image Tokens: $", model.pricing.imageTokenCost.toFixed(2), "/M"] }))] })) : (_jsxs(_Fragment, { children: [hasDefinedPricingValue(model.pricing
|
|
502
|
+
.inputCostPerMillionTokens) && (_jsxs("span", { children: ["Input: $", model.pricing.inputCostPerMillionTokens.toFixed(2), "/M"] })), hasDefinedPricingValue(model.pricing
|
|
503
|
+
.outputCostPerMillionTokens) && (_jsxs("span", { className: "ml-2", children: ["Output: $", model.pricing.outputCostPerMillionTokens.toFixed(2), "/M"] })), hasDefinedPricingValue(model.pricing
|
|
504
|
+
.cachedInputCostPerMillionTokens) && (_jsxs("span", { className: "ml-2", children: ["Cached: $", model.pricing.cachedInputCostPerMillionTokens.toFixed(2), "/M"] }))] })) })) : (_jsxs("div", { className: "mt-1 flex items-start gap-2 rounded border border-yellow-200 bg-yellow-50 px-2 py-1.5 text-xs text-yellow-800", children: [_jsx(AlertCircle, { className: "mt-0.5 h-3.5 w-3.5 shrink-0" }), _jsx("span", { children: getPricingWarningMessage(model) })] })), (model.maxContextWindowTokens ||
|
|
298
505
|
model.maxResponseTokens) && (_jsxs("div", { className: "mt-1 text-xs text-gray-500", children: [model.maxContextWindowTokens && (_jsxs("span", { children: ["Context:", " ", model.maxContextWindowTokens.toLocaleString(), " ", "tokens"] })), model.maxContextWindowTokens &&
|
|
299
506
|
model.maxResponseTokens &&
|
|
300
|
-
" • ", model.maxResponseTokens && (_jsxs("span", { children: ["Max Response:", " ", model.maxResponseTokens.toLocaleString(), " ", "tokens"] }))] }))] }), _jsxs("div", { className: "flex shrink-0 items-center gap-1", children: [status === "Outdated" && (_jsxs(Button, { size: "sm", variant: "outline", onClick: () => handleUpdate(model), disabled: updating === model.id, title: "Update model", children: [updating === model.id ? (_jsx(RefreshCw, { strokeWidth: 1, className: "h-3 w-3 animate-spin" })) : (_jsx(Upload, { strokeWidth: 1, className: "h-3 w-3" })), _jsx("span", { className: "ml-1 hidden sm:inline", children: "Update" })] })),
|
|
301
|
-
|
|
507
|
+
" • ", model.maxResponseTokens && (_jsxs("span", { children: ["Max Response:", " ", model.maxResponseTokens.toLocaleString(), " ", "tokens"] }))] }))] }), _jsxs("div", { className: "flex shrink-0 items-center gap-1", children: [status === "Outdated" && (_jsxs(Button, { size: "sm", variant: "outline", onClick: () => handleUpdate(model), disabled: updating === model.id, title: "Update model", children: [updating === model.id ? (_jsx(RefreshCw, { strokeWidth: 1, className: "h-3 w-3 animate-spin" })) : (_jsx(Upload, { strokeWidth: 1, className: "h-3 w-3" })), _jsx("span", { className: "ml-1 hidden sm:inline", children: "Update" })] })), _jsxs(Button, { size: "sm", variant: isSelected ? "default" : "ghost", onClick: () => handleOpenConfig(model), title: "Configure model", children: [_jsx(Settings, { className: "h-4 w-4", strokeWidth: 1.5 }), _jsx("span", { className: "ml-1 hidden sm:inline", children: "Configure" })] }), _jsxs(Button, { size: "sm", variant: "ghost", onClick: () => openDuplicateDialog(model), disabled: !editContext ||
|
|
508
|
+
!model.parentId ||
|
|
509
|
+
duplicatingId === model.id, title: "Duplicate model", children: [duplicatingId === model.id ? (_jsx(RefreshCw, { strokeWidth: 1, className: "h-3 w-3 animate-spin" })) : (_jsx(Copy, { strokeWidth: 1, className: "h-3 w-3" })), _jsx("span", { className: "ml-1 hidden sm:inline", children: "Duplicate" })] }), _jsx(Button, { size: "sm", variant: "ghost", onClick: () => handleDelete(model), disabled: deleting === model.id, title: "Delete model", className: "text-red-600 hover:bg-red-50 hover:text-red-700", children: deleting === model.id ? (_jsx(RefreshCw, { strokeWidth: 1, className: "h-3 w-3 animate-spin" })) : (_jsx(Trash2, { strokeWidth: 1, className: "h-3 w-3" })) })] })] }, model.id));
|
|
302
510
|
}) })] }, providerId));
|
|
303
|
-
}) })) }), _jsx(AddModelDialog, { open: showAddDialog, onOpenChange: setShowAddDialog, onSuccess: loadData, providers: providers, installedModels: installedModels }), _jsx(ImportModelDialog, { open: showImportDialog, onOpenChange: setShowImportDialog, onSuccess: loadData, importableProviders: importableProviders, providerTypes: providerTypes })
|
|
511
|
+
}) })) }), _jsx(AddModelDialog, { open: showAddDialog, onOpenChange: setShowAddDialog, onSuccess: loadData, providers: providers, installedModels: installedModels }), _jsx(ImportModelDialog, { open: showImportDialog, onOpenChange: setShowImportDialog, onSuccess: loadData, importableProviders: importableProviders, providerTypes: providerTypes }), _jsx(Dialog, { open: duplicateDialogModel !== null, onOpenChange: (open) => {
|
|
512
|
+
if (!open)
|
|
513
|
+
setDuplicateDialogModel(null);
|
|
514
|
+
}, children: _jsxs(DialogContent, { className: "max-w-md", children: [_jsxs(DialogHeader, { className: "pr-14", children: [_jsx(DialogTitle, { children: "Duplicate model" }), _jsx(DialogDescription, { children: "New Sitecore item name. Field values (including model name and reasoning) are copied; adjust them in Configure after duplicating." })] }), _jsxs("div", { className: "space-y-2 px-8 pb-6", children: [_jsx("label", { htmlFor: "duplicate-model-item-name", className: "block text-sm font-medium text-gray-700", children: "Item name" }), _jsx(Input, { id: "duplicate-model-item-name", value: duplicateItemName, onChange: (e) => setDuplicateItemName(e.target.value), onKeyDown: (e) => {
|
|
515
|
+
if (e.key === "Enter") {
|
|
516
|
+
e.preventDefault();
|
|
517
|
+
void handleConfirmDuplicate();
|
|
518
|
+
}
|
|
519
|
+
}, autoFocus: true })] }), _jsxs(DialogFooter, { className: "border-t border-gray-100 pt-4", children: [_jsx(Button, { type: "button", variant: "outline", className: "min-h-9 min-w-22", onClick: () => setDuplicateDialogModel(null), children: "Cancel" }), _jsx(Button, { type: "button", className: "min-h-9 min-w-22", onClick: () => void handleConfirmDuplicate(), disabled: !duplicateItemName.trim() ||
|
|
520
|
+
(duplicateDialogModel != null &&
|
|
521
|
+
duplicatingId === duplicateDialogModel.id), children: duplicateDialogModel != null &&
|
|
522
|
+
duplicatingId === duplicateDialogModel.id ? (_jsxs(_Fragment, { children: [_jsx(RefreshCw, { className: "mr-1 h-4 w-4 animate-spin" }), "Duplicating\u2026"] })) : ("Duplicate") })] })] }) })] }) }) }));
|
|
304
523
|
// Build splitter panels - only show config panel when a model is selected
|
|
305
524
|
const panels = selectedModel?.id
|
|
306
525
|
? [
|
|
@@ -313,7 +532,9 @@ export function ModelsPanel() {
|
|
|
313
532
|
{
|
|
314
533
|
name: "model-config",
|
|
315
534
|
defaultSize: 400,
|
|
316
|
-
content: (_jsx(
|
|
535
|
+
content: (_jsx(ModelConfigPanel, { itemId: selectedModel.id, title: `Configure: ${getModelListLabel(selectedModel) || "Model"}`, onClose: handleCloseConfig, onModelRenamed: async () => {
|
|
536
|
+
await loadData();
|
|
537
|
+
} }, selectedModel.id)),
|
|
317
538
|
className: "overflow-hidden",
|
|
318
539
|
},
|
|
319
540
|
]
|