@sveda-ai/vue 0.1.0
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/LICENSE +21 -0
- package/README.md +9 -0
- package/dist/appearance.d.ts +52 -0
- package/dist/appearance.d.ts.map +1 -0
- package/dist/components/chat/AnimatedStreamBlock.vue.d.ts +16 -0
- package/dist/components/chat/AnimatedStreamBlock.vue.d.ts.map +1 -0
- package/dist/components/chat/ChatHistoryDropdown.vue.d.ts +17 -0
- package/dist/components/chat/ChatHistoryDropdown.vue.d.ts.map +1 -0
- package/dist/components/chat/ChatInput.vue.d.ts +30 -0
- package/dist/components/chat/ChatInput.vue.d.ts.map +1 -0
- package/dist/components/chat/ChatMessageActivityBlock.vue.d.ts +13 -0
- package/dist/components/chat/ChatMessageActivityBlock.vue.d.ts.map +1 -0
- package/dist/components/chat/ChatMessageItem.vue.d.ts +15 -0
- package/dist/components/chat/ChatMessageItem.vue.d.ts.map +1 -0
- package/dist/components/chat/ChatMessageList.vue.d.ts +31 -0
- package/dist/components/chat/ChatMessageList.vue.d.ts.map +1 -0
- package/dist/components/chat/ChatPendingIndicator.vue.d.ts +12 -0
- package/dist/components/chat/ChatPendingIndicator.vue.d.ts.map +1 -0
- package/dist/components/chat/ReasoningStream.vue.d.ts +11 -0
- package/dist/components/chat/ReasoningStream.vue.d.ts.map +1 -0
- package/dist/components/chat/index.d.ts +9 -0
- package/dist/components/chat/index.d.ts.map +1 -0
- package/dist/components/shell/SvedaAgentCompletedNotice.vue.d.ts +9 -0
- package/dist/components/shell/SvedaAgentCompletedNotice.vue.d.ts.map +1 -0
- package/dist/components/shell/SvedaAgentTasksPanel.vue.d.ts +12 -0
- package/dist/components/shell/SvedaAgentTasksPanel.vue.d.ts.map +1 -0
- package/dist/components/shell/SvedaChat.vue.d.ts +22 -0
- package/dist/components/shell/SvedaChat.vue.d.ts.map +1 -0
- package/dist/components/shell/SvedaContextUsageBar.vue.d.ts +10 -0
- package/dist/components/shell/SvedaContextUsageBar.vue.d.ts.map +1 -0
- package/dist/components/shell/SvedaHistorySheet.vue.d.ts +15 -0
- package/dist/components/shell/SvedaHistorySheet.vue.d.ts.map +1 -0
- package/dist/components/shell/SvedaHistorySidebar.vue.d.ts +15 -0
- package/dist/components/shell/SvedaHistorySidebar.vue.d.ts.map +1 -0
- package/dist/components/shell/SvedaInputSection.vue.d.ts +25 -0
- package/dist/components/shell/SvedaInputSection.vue.d.ts.map +1 -0
- package/dist/components/shell/SvedaLandingView.vue.d.ts +40 -0
- package/dist/components/shell/SvedaLandingView.vue.d.ts.map +1 -0
- package/dist/components/shell/SvedaMaxStepsNotice.vue.d.ts +13 -0
- package/dist/components/shell/SvedaMaxStepsNotice.vue.d.ts.map +1 -0
- package/dist/components/shell/SvedaMinimizedTrigger.vue.d.ts +15 -0
- package/dist/components/shell/SvedaMinimizedTrigger.vue.d.ts.map +1 -0
- package/dist/components/shell/SvedaModelControls.vue.d.ts +12 -0
- package/dist/components/shell/SvedaModelControls.vue.d.ts.map +1 -0
- package/dist/components/shell/SvedaModelSelect.vue.d.ts +10 -0
- package/dist/components/shell/SvedaModelSelect.vue.d.ts.map +1 -0
- package/dist/components/shell/SvedaQuickPrompts.vue.d.ts +13 -0
- package/dist/components/shell/SvedaQuickPrompts.vue.d.ts.map +1 -0
- package/dist/components/shell/SvedaResizeHandles.vue.d.ts +11 -0
- package/dist/components/shell/SvedaResizeHandles.vue.d.ts.map +1 -0
- package/dist/components/shell/SvedaTabs.vue.d.ts +17 -0
- package/dist/components/shell/SvedaTabs.vue.d.ts.map +1 -0
- package/dist/components/shell/SvedaToolbar.vue.d.ts +33 -0
- package/dist/components/shell/SvedaToolbar.vue.d.ts.map +1 -0
- package/dist/composables/useSvedaAgentTasks.d.ts +57 -0
- package/dist/composables/useSvedaAgentTasks.d.ts.map +1 -0
- package/dist/composables/useSvedaBootstrap.d.ts +18 -0
- package/dist/composables/useSvedaBootstrap.d.ts.map +1 -0
- package/dist/composables/useSvedaChat.d.ts +264 -0
- package/dist/composables/useSvedaChat.d.ts.map +1 -0
- package/dist/composables/useSvedaChatLayout.d.ts +39 -0
- package/dist/composables/useSvedaChatLayout.d.ts.map +1 -0
- package/dist/composables/useSvedaChatPage.d.ts +309 -0
- package/dist/composables/useSvedaChatPage.d.ts.map +1 -0
- package/dist/composables/useSvedaContextWindow.d.ts +10 -0
- package/dist/composables/useSvedaContextWindow.d.ts.map +1 -0
- package/dist/composables/useSvedaDocuments.d.ts +20 -0
- package/dist/composables/useSvedaDocuments.d.ts.map +1 -0
- package/dist/composables/useSvedaMaxStepsContinue.d.ts +12 -0
- package/dist/composables/useSvedaMaxStepsContinue.d.ts.map +1 -0
- package/dist/composables/useSvedaMessaging.d.ts +55 -0
- package/dist/composables/useSvedaMessaging.d.ts.map +1 -0
- package/dist/composables/useSvedaModel.d.ts +16 -0
- package/dist/composables/useSvedaModel.d.ts.map +1 -0
- package/dist/composables/useSvedaPrompts.d.ts +18 -0
- package/dist/composables/useSvedaPrompts.d.ts.map +1 -0
- package/dist/composables/useSvedaReadable.d.ts +3 -0
- package/dist/composables/useSvedaReadable.d.ts.map +1 -0
- package/dist/composables/useSvedaScroll.d.ts +19 -0
- package/dist/composables/useSvedaScroll.d.ts.map +1 -0
- package/dist/composables/useSvedaShell.d.ts +29 -0
- package/dist/composables/useSvedaShell.d.ts.map +1 -0
- package/dist/composables/useSvedaStreaming.d.ts +46 -0
- package/dist/composables/useSvedaStreaming.d.ts.map +1 -0
- package/dist/composables/useSvedaTool.d.ts +4 -0
- package/dist/composables/useSvedaTool.d.ts.map +1 -0
- package/dist/i18n/index.d.ts +18 -0
- package/dist/i18n/index.d.ts.map +1 -0
- package/dist/i18n/locales/en.d.ts +4 -0
- package/dist/i18n/locales/en.d.ts.map +1 -0
- package/dist/i18n/locales/ru.d.ts +4 -0
- package/dist/i18n/locales/ru.d.ts.map +1 -0
- package/dist/index.d.ts +64 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6612 -0
- package/dist/launcherIcons.d.ts +5 -0
- package/dist/launcherIcons.d.ts.map +1 -0
- package/dist/lib/assistantMessage.d.ts +89 -0
- package/dist/lib/assistantMessage.d.ts.map +1 -0
- package/dist/lib/chatHistoryMerge.d.ts +20 -0
- package/dist/lib/chatHistoryMerge.d.ts.map +1 -0
- package/dist/lib/chatI18nKeys.d.ts +2 -0
- package/dist/lib/chatI18nKeys.d.ts.map +1 -0
- package/dist/lib/chatMessageVisibility.d.ts +4 -0
- package/dist/lib/chatMessageVisibility.d.ts.map +1 -0
- package/dist/lib/chatTabs.d.ts +9 -0
- package/dist/lib/chatTabs.d.ts.map +1 -0
- package/dist/lib/chatTitle.d.ts +3 -0
- package/dist/lib/chatTitle.d.ts.map +1 -0
- package/dist/lib/chatUiStorage.d.ts +4 -0
- package/dist/lib/chatUiStorage.d.ts.map +1 -0
- package/dist/lib/finalizeMessages.d.ts +21 -0
- package/dist/lib/finalizeMessages.d.ts.map +1 -0
- package/dist/lib/markdown.d.ts +8 -0
- package/dist/lib/markdown.d.ts.map +1 -0
- package/dist/lib/modelLabels.d.ts +3 -0
- package/dist/lib/modelLabels.d.ts.map +1 -0
- package/dist/lib/pendingStatusRotation.d.ts +3 -0
- package/dist/lib/pendingStatusRotation.d.ts.map +1 -0
- package/dist/lib/useAnimatedText.d.ts +8 -0
- package/dist/lib/useAnimatedText.d.ts.map +1 -0
- package/dist/lib/userMessage.d.ts +17 -0
- package/dist/lib/userMessage.d.ts.map +1 -0
- package/dist/lib/utils.d.ts +3 -0
- package/dist/lib/utils.d.ts.map +1 -0
- package/dist/plugin.d.ts +64 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/styles.css +5 -0
- package/dist/ui/alert-dialog/AlertDialog.vue.d.ts +18 -0
- package/dist/ui/alert-dialog/AlertDialog.vue.d.ts.map +1 -0
- package/dist/ui/alert-dialog/AlertDialogAction.vue.d.ts +18 -0
- package/dist/ui/alert-dialog/AlertDialogAction.vue.d.ts.map +1 -0
- package/dist/ui/alert-dialog/AlertDialogCancel.vue.d.ts +18 -0
- package/dist/ui/alert-dialog/AlertDialogCancel.vue.d.ts.map +1 -0
- package/dist/ui/alert-dialog/AlertDialogContent.vue.d.ts +32 -0
- package/dist/ui/alert-dialog/AlertDialogContent.vue.d.ts.map +1 -0
- package/dist/ui/alert-dialog/AlertDialogDescription.vue.d.ts +18 -0
- package/dist/ui/alert-dialog/AlertDialogDescription.vue.d.ts.map +1 -0
- package/dist/ui/alert-dialog/AlertDialogFooter.vue.d.ts +17 -0
- package/dist/ui/alert-dialog/AlertDialogFooter.vue.d.ts.map +1 -0
- package/dist/ui/alert-dialog/AlertDialogHeader.vue.d.ts +17 -0
- package/dist/ui/alert-dialog/AlertDialogHeader.vue.d.ts.map +1 -0
- package/dist/ui/alert-dialog/AlertDialogTitle.vue.d.ts +18 -0
- package/dist/ui/alert-dialog/AlertDialogTitle.vue.d.ts.map +1 -0
- package/dist/ui/alert-dialog/AlertDialogTrigger.vue.d.ts +14 -0
- package/dist/ui/alert-dialog/AlertDialogTrigger.vue.d.ts.map +1 -0
- package/dist/ui/alert-dialog/index.d.ts +10 -0
- package/dist/ui/alert-dialog/index.d.ts.map +1 -0
- package/dist/ui/badge/Badge.vue.d.ts +19 -0
- package/dist/ui/badge/Badge.vue.d.ts.map +1 -0
- package/dist/ui/badge/index.d.ts +7 -0
- package/dist/ui/badge/index.d.ts.map +1 -0
- package/dist/ui/button/Button.vue.d.ts +23 -0
- package/dist/ui/button/Button.vue.d.ts.map +1 -0
- package/dist/ui/button/index.d.ts +9 -0
- package/dist/ui/button/index.d.ts.map +1 -0
- package/dist/ui/card/Card.vue.d.ts +17 -0
- package/dist/ui/card/Card.vue.d.ts.map +1 -0
- package/dist/ui/card/CardContent.vue.d.ts +17 -0
- package/dist/ui/card/CardContent.vue.d.ts.map +1 -0
- package/dist/ui/card/CardDescription.vue.d.ts +17 -0
- package/dist/ui/card/CardDescription.vue.d.ts.map +1 -0
- package/dist/ui/card/CardFooter.vue.d.ts +17 -0
- package/dist/ui/card/CardFooter.vue.d.ts.map +1 -0
- package/dist/ui/card/CardHeader.vue.d.ts +17 -0
- package/dist/ui/card/CardHeader.vue.d.ts.map +1 -0
- package/dist/ui/card/CardTitle.vue.d.ts +17 -0
- package/dist/ui/card/CardTitle.vue.d.ts.map +1 -0
- package/dist/ui/card/index.d.ts +7 -0
- package/dist/ui/card/index.d.ts.map +1 -0
- package/dist/ui/checkbox/Checkbox.vue.d.ts +30 -0
- package/dist/ui/checkbox/Checkbox.vue.d.ts.map +1 -0
- package/dist/ui/checkbox/index.d.ts +2 -0
- package/dist/ui/checkbox/index.d.ts.map +1 -0
- package/dist/ui/dialog/Dialog.vue.d.ts +18 -0
- package/dist/ui/dialog/Dialog.vue.d.ts.map +1 -0
- package/dist/ui/dialog/DialogClose.vue.d.ts +14 -0
- package/dist/ui/dialog/DialogClose.vue.d.ts.map +1 -0
- package/dist/ui/dialog/DialogContent.vue.d.ts +32 -0
- package/dist/ui/dialog/DialogContent.vue.d.ts.map +1 -0
- package/dist/ui/dialog/DialogDescription.vue.d.ts +18 -0
- package/dist/ui/dialog/DialogDescription.vue.d.ts.map +1 -0
- package/dist/ui/dialog/DialogFooter.vue.d.ts +17 -0
- package/dist/ui/dialog/DialogFooter.vue.d.ts.map +1 -0
- package/dist/ui/dialog/DialogHeader.vue.d.ts +17 -0
- package/dist/ui/dialog/DialogHeader.vue.d.ts.map +1 -0
- package/dist/ui/dialog/DialogScrollContent.vue.d.ts +32 -0
- package/dist/ui/dialog/DialogScrollContent.vue.d.ts.map +1 -0
- package/dist/ui/dialog/DialogTitle.vue.d.ts +18 -0
- package/dist/ui/dialog/DialogTitle.vue.d.ts.map +1 -0
- package/dist/ui/dialog/DialogTrigger.vue.d.ts +14 -0
- package/dist/ui/dialog/DialogTrigger.vue.d.ts.map +1 -0
- package/dist/ui/dialog/index.d.ts +10 -0
- package/dist/ui/dialog/index.d.ts.map +1 -0
- package/dist/ui/dropdown-menu/DropdownMenu.vue.d.ts +18 -0
- package/dist/ui/dropdown-menu/DropdownMenu.vue.d.ts.map +1 -0
- package/dist/ui/dropdown-menu/DropdownMenuCheckboxItem.vue.d.ts +24 -0
- package/dist/ui/dropdown-menu/DropdownMenuCheckboxItem.vue.d.ts.map +1 -0
- package/dist/ui/dropdown-menu/DropdownMenuContent.vue.d.ts +32 -0
- package/dist/ui/dropdown-menu/DropdownMenuContent.vue.d.ts.map +1 -0
- package/dist/ui/dropdown-menu/DropdownMenuGroup.vue.d.ts +14 -0
- package/dist/ui/dropdown-menu/DropdownMenuGroup.vue.d.ts.map +1 -0
- package/dist/ui/dropdown-menu/DropdownMenuItem.vue.d.ts +19 -0
- package/dist/ui/dropdown-menu/DropdownMenuItem.vue.d.ts.map +1 -0
- package/dist/ui/dropdown-menu/DropdownMenuLabel.vue.d.ts +19 -0
- package/dist/ui/dropdown-menu/DropdownMenuLabel.vue.d.ts.map +1 -0
- package/dist/ui/dropdown-menu/DropdownMenuRadioGroup.vue.d.ts +18 -0
- package/dist/ui/dropdown-menu/DropdownMenuRadioGroup.vue.d.ts.map +1 -0
- package/dist/ui/dropdown-menu/DropdownMenuRadioItem.vue.d.ts +22 -0
- package/dist/ui/dropdown-menu/DropdownMenuRadioItem.vue.d.ts.map +1 -0
- package/dist/ui/dropdown-menu/DropdownMenuSeparator.vue.d.ts +8 -0
- package/dist/ui/dropdown-menu/DropdownMenuSeparator.vue.d.ts.map +1 -0
- package/dist/ui/dropdown-menu/DropdownMenuShortcut.vue.d.ts +17 -0
- package/dist/ui/dropdown-menu/DropdownMenuShortcut.vue.d.ts.map +1 -0
- package/dist/ui/dropdown-menu/DropdownMenuSub.vue.d.ts +18 -0
- package/dist/ui/dropdown-menu/DropdownMenuSub.vue.d.ts.map +1 -0
- package/dist/ui/dropdown-menu/DropdownMenuSubContent.vue.d.ts +34 -0
- package/dist/ui/dropdown-menu/DropdownMenuSubContent.vue.d.ts.map +1 -0
- package/dist/ui/dropdown-menu/DropdownMenuSubTrigger.vue.d.ts +18 -0
- package/dist/ui/dropdown-menu/DropdownMenuSubTrigger.vue.d.ts.map +1 -0
- package/dist/ui/dropdown-menu/DropdownMenuTrigger.vue.d.ts +14 -0
- package/dist/ui/dropdown-menu/DropdownMenuTrigger.vue.d.ts.map +1 -0
- package/dist/ui/dropdown-menu/index.d.ts +16 -0
- package/dist/ui/dropdown-menu/index.d.ts.map +1 -0
- package/dist/ui/input/Input.vue.d.ts +13 -0
- package/dist/ui/input/Input.vue.d.ts.map +1 -0
- package/dist/ui/input/index.d.ts +2 -0
- package/dist/ui/input/index.d.ts.map +1 -0
- package/dist/ui/label/Label.vue.d.ts +18 -0
- package/dist/ui/label/Label.vue.d.ts.map +1 -0
- package/dist/ui/label/index.d.ts +2 -0
- package/dist/ui/label/index.d.ts.map +1 -0
- package/dist/ui/responsive-dialog/ResponsiveDialog.vue.d.ts +32 -0
- package/dist/ui/responsive-dialog/ResponsiveDialog.vue.d.ts.map +1 -0
- package/dist/ui/responsive-dialog/index.d.ts +2 -0
- package/dist/ui/responsive-dialog/index.d.ts.map +1 -0
- package/dist/ui/scroll-area/ScrollArea.vue.d.ts +18 -0
- package/dist/ui/scroll-area/ScrollArea.vue.d.ts.map +1 -0
- package/dist/ui/scroll-area/ScrollBar.vue.d.ts +10 -0
- package/dist/ui/scroll-area/ScrollBar.vue.d.ts.map +1 -0
- package/dist/ui/scroll-area/index.d.ts +3 -0
- package/dist/ui/scroll-area/index.d.ts.map +1 -0
- package/dist/ui/select/Select.vue.d.ts +21 -0
- package/dist/ui/select/Select.vue.d.ts.map +1 -0
- package/dist/ui/select/SelectContent.vue.d.ts +28 -0
- package/dist/ui/select/SelectContent.vue.d.ts.map +1 -0
- package/dist/ui/select/SelectGroup.vue.d.ts +18 -0
- package/dist/ui/select/SelectGroup.vue.d.ts.map +1 -0
- package/dist/ui/select/SelectItem.vue.d.ts +18 -0
- package/dist/ui/select/SelectItem.vue.d.ts.map +1 -0
- package/dist/ui/select/SelectItemText.vue.d.ts +14 -0
- package/dist/ui/select/SelectItemText.vue.d.ts.map +1 -0
- package/dist/ui/select/SelectLabel.vue.d.ts +18 -0
- package/dist/ui/select/SelectLabel.vue.d.ts.map +1 -0
- package/dist/ui/select/SelectScrollDownButton.vue.d.ts +18 -0
- package/dist/ui/select/SelectScrollDownButton.vue.d.ts.map +1 -0
- package/dist/ui/select/SelectScrollUpButton.vue.d.ts +18 -0
- package/dist/ui/select/SelectScrollUpButton.vue.d.ts.map +1 -0
- package/dist/ui/select/SelectSeparator.vue.d.ts +8 -0
- package/dist/ui/select/SelectSeparator.vue.d.ts.map +1 -0
- package/dist/ui/select/SelectTrigger.vue.d.ts +18 -0
- package/dist/ui/select/SelectTrigger.vue.d.ts.map +1 -0
- package/dist/ui/select/SelectValue.vue.d.ts +14 -0
- package/dist/ui/select/SelectValue.vue.d.ts.map +1 -0
- package/dist/ui/select/index.d.ts +12 -0
- package/dist/ui/select/index.d.ts.map +1 -0
- package/dist/ui/sheet/Sheet.vue.d.ts +18 -0
- package/dist/ui/sheet/Sheet.vue.d.ts.map +1 -0
- package/dist/ui/sheet/SheetClose.vue.d.ts +14 -0
- package/dist/ui/sheet/SheetClose.vue.d.ts.map +1 -0
- package/dist/ui/sheet/SheetContent.vue.d.ts +34 -0
- package/dist/ui/sheet/SheetContent.vue.d.ts.map +1 -0
- package/dist/ui/sheet/SheetDescription.vue.d.ts +18 -0
- package/dist/ui/sheet/SheetDescription.vue.d.ts.map +1 -0
- package/dist/ui/sheet/SheetFooter.vue.d.ts +17 -0
- package/dist/ui/sheet/SheetFooter.vue.d.ts.map +1 -0
- package/dist/ui/sheet/SheetHeader.vue.d.ts +17 -0
- package/dist/ui/sheet/SheetHeader.vue.d.ts.map +1 -0
- package/dist/ui/sheet/SheetTitle.vue.d.ts +18 -0
- package/dist/ui/sheet/SheetTitle.vue.d.ts.map +1 -0
- package/dist/ui/sheet/SheetTrigger.vue.d.ts +14 -0
- package/dist/ui/sheet/SheetTrigger.vue.d.ts.map +1 -0
- package/dist/ui/sheet/index.d.ts +14 -0
- package/dist/ui/sheet/index.d.ts.map +1 -0
- package/dist/ui/switch/Switch.vue.d.ts +23 -0
- package/dist/ui/switch/Switch.vue.d.ts.map +1 -0
- package/dist/ui/switch/index.d.ts +2 -0
- package/dist/ui/switch/index.d.ts.map +1 -0
- package/dist/ui/textarea/Textarea.vue.d.ts +13 -0
- package/dist/ui/textarea/Textarea.vue.d.ts.map +1 -0
- package/dist/ui/textarea/index.d.ts +2 -0
- package/dist/ui/textarea/index.d.ts.map +1 -0
- package/dist/ui/toast/Toast.vue.d.ts +96 -0
- package/dist/ui/toast/Toast.vue.d.ts.map +1 -0
- package/dist/ui/toast/ToastAction.vue.d.ts +18 -0
- package/dist/ui/toast/ToastAction.vue.d.ts.map +1 -0
- package/dist/ui/toast/ToastClose.vue.d.ts +8 -0
- package/dist/ui/toast/ToastClose.vue.d.ts.map +1 -0
- package/dist/ui/toast/ToastDescription.vue.d.ts +18 -0
- package/dist/ui/toast/ToastDescription.vue.d.ts.map +1 -0
- package/dist/ui/toast/ToastProvider.vue.d.ts +14 -0
- package/dist/ui/toast/ToastProvider.vue.d.ts.map +1 -0
- package/dist/ui/toast/ToastTitle.vue.d.ts +18 -0
- package/dist/ui/toast/ToastTitle.vue.d.ts.map +1 -0
- package/dist/ui/toast/ToastViewport.vue.d.ts +8 -0
- package/dist/ui/toast/ToastViewport.vue.d.ts.map +1 -0
- package/dist/ui/toast/Toaster.vue.d.ts +3 -0
- package/dist/ui/toast/Toaster.vue.d.ts.map +1 -0
- package/dist/ui/toast/index.d.ts +23 -0
- package/dist/ui/toast/index.d.ts.map +1 -0
- package/dist/ui/toast/use-toast.d.ts +23 -0
- package/dist/ui/toast/use-toast.d.ts.map +1 -0
- package/dist/ui/tooltip/Tooltip.vue.d.ts +18 -0
- package/dist/ui/tooltip/Tooltip.vue.d.ts.map +1 -0
- package/dist/ui/tooltip/TooltipContent.vue.d.ts +26 -0
- package/dist/ui/tooltip/TooltipContent.vue.d.ts.map +1 -0
- package/dist/ui/tooltip/TooltipProvider.vue.d.ts +14 -0
- package/dist/ui/tooltip/TooltipProvider.vue.d.ts.map +1 -0
- package/dist/ui/tooltip/TooltipTrigger.vue.d.ts +14 -0
- package/dist/ui/tooltip/TooltipTrigger.vue.d.ts.map +1 -0
- package/dist/ui/tooltip/index.d.ts +5 -0
- package/dist/ui/tooltip/index.d.ts.map +1 -0
- package/dist/ui/utils.d.ts +2 -0
- package/dist/ui/utils.d.ts.map +1 -0
- package/dist/vue.css +1 -0
- package/package.json +64 -0
- package/src/appearance.ts +568 -0
- package/src/components/chat/AnimatedStreamBlock.vue +94 -0
- package/src/components/chat/ChatHistoryDropdown.vue +226 -0
- package/src/components/chat/ChatInput.vue +571 -0
- package/src/components/chat/ChatMessageActivityBlock.vue +447 -0
- package/src/components/chat/ChatMessageItem.vue +357 -0
- package/src/components/chat/ChatMessageList.vue +178 -0
- package/src/components/chat/ChatPendingIndicator.vue +163 -0
- package/src/components/chat/ReasoningStream.vue +112 -0
- package/src/components/chat/index.ts +8 -0
- package/src/components/shell/SvedaAgentCompletedNotice.vue +25 -0
- package/src/components/shell/SvedaAgentTasksPanel.vue +146 -0
- package/src/components/shell/SvedaChat.vue +514 -0
- package/src/components/shell/SvedaContextUsageBar.vue +33 -0
- package/src/components/shell/SvedaHistorySheet.vue +52 -0
- package/src/components/shell/SvedaHistorySidebar.vue +41 -0
- package/src/components/shell/SvedaInputSection.vue +53 -0
- package/src/components/shell/SvedaLandingView.vue +93 -0
- package/src/components/shell/SvedaMaxStepsNotice.vue +33 -0
- package/src/components/shell/SvedaMinimizedTrigger.vue +43 -0
- package/src/components/shell/SvedaModelControls.vue +47 -0
- package/src/components/shell/SvedaModelSelect.vue +32 -0
- package/src/components/shell/SvedaQuickPrompts.vue +44 -0
- package/src/components/shell/SvedaResizeHandles.vue +31 -0
- package/src/components/shell/SvedaTabs.vue +123 -0
- package/src/components/shell/SvedaToolbar.vue +171 -0
- package/src/composables/useSvedaAgentTasks.ts +93 -0
- package/src/composables/useSvedaBootstrap.ts +36 -0
- package/src/composables/useSvedaChat.ts +593 -0
- package/src/composables/useSvedaChatLayout.ts +539 -0
- package/src/composables/useSvedaChatPage.ts +339 -0
- package/src/composables/useSvedaContextWindow.ts +31 -0
- package/src/composables/useSvedaDocuments.ts +115 -0
- package/src/composables/useSvedaMaxStepsContinue.ts +68 -0
- package/src/composables/useSvedaMessaging.ts +99 -0
- package/src/composables/useSvedaModel.ts +85 -0
- package/src/composables/useSvedaPrompts.ts +59 -0
- package/src/composables/useSvedaReadable.ts +33 -0
- package/src/composables/useSvedaScroll.ts +93 -0
- package/src/composables/useSvedaShell.ts +91 -0
- package/src/composables/useSvedaStreaming.ts +408 -0
- package/src/composables/useSvedaTool.ts +18 -0
- package/src/i18n/index.ts +72 -0
- package/src/i18n/locales/en.ts +58 -0
- package/src/i18n/locales/ru.ts +59 -0
- package/src/index.ts +141 -0
- package/src/launcherIcons.ts +39 -0
- package/src/lib/assistantMessage.ts +437 -0
- package/src/lib/chatHistoryMerge.ts +93 -0
- package/src/lib/chatI18nKeys.ts +62 -0
- package/src/lib/chatMessageVisibility.ts +50 -0
- package/src/lib/chatTabs.ts +54 -0
- package/src/lib/chatTitle.ts +30 -0
- package/src/lib/chatUiStorage.ts +33 -0
- package/src/lib/finalizeMessages.ts +81 -0
- package/src/lib/markdown.ts +90 -0
- package/src/lib/modelLabels.ts +24 -0
- package/src/lib/pendingStatusRotation.ts +26 -0
- package/src/lib/shims-vue.d.ts +6 -0
- package/src/lib/useAnimatedText.ts +78 -0
- package/src/lib/userMessage.ts +55 -0
- package/src/lib/utils.ts +6 -0
- package/src/plugin.ts +164 -0
- package/src/styles.css +5 -0
- package/src/theme.css +95 -0
- package/src/theme.test.mjs +80 -0
- package/src/ui/alert-dialog/AlertDialog.vue +14 -0
- package/src/ui/alert-dialog/AlertDialogAction.vue +17 -0
- package/src/ui/alert-dialog/AlertDialogCancel.vue +24 -0
- package/src/ui/alert-dialog/AlertDialogContent.vue +39 -0
- package/src/ui/alert-dialog/AlertDialogDescription.vue +22 -0
- package/src/ui/alert-dialog/AlertDialogFooter.vue +21 -0
- package/src/ui/alert-dialog/AlertDialogHeader.vue +16 -0
- package/src/ui/alert-dialog/AlertDialogTitle.vue +19 -0
- package/src/ui/alert-dialog/AlertDialogTrigger.vue +11 -0
- package/src/ui/alert-dialog/index.ts +9 -0
- package/src/ui/badge/Badge.vue +16 -0
- package/src/ui/badge/index.ts +27 -0
- package/src/ui/button/Button.vue +56 -0
- package/src/ui/button/index.ts +50 -0
- package/src/ui/card/Card.vue +14 -0
- package/src/ui/card/CardContent.vue +14 -0
- package/src/ui/card/CardDescription.vue +14 -0
- package/src/ui/card/CardFooter.vue +14 -0
- package/src/ui/card/CardHeader.vue +14 -0
- package/src/ui/card/CardTitle.vue +14 -0
- package/src/ui/card/index.ts +6 -0
- package/src/ui/checkbox/Checkbox.vue +41 -0
- package/src/ui/checkbox/index.ts +1 -0
- package/src/ui/dialog/Dialog.vue +14 -0
- package/src/ui/dialog/DialogClose.vue +11 -0
- package/src/ui/dialog/DialogContent.vue +50 -0
- package/src/ui/dialog/DialogDescription.vue +24 -0
- package/src/ui/dialog/DialogFooter.vue +19 -0
- package/src/ui/dialog/DialogHeader.vue +16 -0
- package/src/ui/dialog/DialogScrollContent.vue +59 -0
- package/src/ui/dialog/DialogTitle.vue +29 -0
- package/src/ui/dialog/DialogTrigger.vue +11 -0
- package/src/ui/dialog/index.ts +9 -0
- package/src/ui/dropdown-menu/DropdownMenu.vue +14 -0
- package/src/ui/dropdown-menu/DropdownMenuCheckboxItem.vue +42 -0
- package/src/ui/dropdown-menu/DropdownMenuContent.vue +40 -0
- package/src/ui/dropdown-menu/DropdownMenuGroup.vue +11 -0
- package/src/ui/dropdown-menu/DropdownMenuItem.vue +30 -0
- package/src/ui/dropdown-menu/DropdownMenuLabel.vue +21 -0
- package/src/ui/dropdown-menu/DropdownMenuRadioGroup.vue +14 -0
- package/src/ui/dropdown-menu/DropdownMenuRadioItem.vue +43 -0
- package/src/ui/dropdown-menu/DropdownMenuSeparator.vue +21 -0
- package/src/ui/dropdown-menu/DropdownMenuShortcut.vue +14 -0
- package/src/ui/dropdown-menu/DropdownMenuSub.vue +14 -0
- package/src/ui/dropdown-menu/DropdownMenuSubContent.vue +30 -0
- package/src/ui/dropdown-menu/DropdownMenuSubTrigger.vue +31 -0
- package/src/ui/dropdown-menu/DropdownMenuTrigger.vue +13 -0
- package/src/ui/dropdown-menu/index.ts +16 -0
- package/src/ui/input/Input.vue +32 -0
- package/src/ui/input/index.ts +1 -0
- package/src/ui/label/Label.vue +22 -0
- package/src/ui/label/index.ts +1 -0
- package/src/ui/responsive-dialog/ResponsiveDialog.vue +55 -0
- package/src/ui/responsive-dialog/index.ts +1 -0
- package/src/ui/scroll-area/ScrollArea.vue +29 -0
- package/src/ui/scroll-area/ScrollBar.vue +30 -0
- package/src/ui/scroll-area/index.ts +2 -0
- package/src/ui/select/Select.vue +15 -0
- package/src/ui/select/SelectContent.vue +53 -0
- package/src/ui/select/SelectGroup.vue +19 -0
- package/src/ui/select/SelectItem.vue +44 -0
- package/src/ui/select/SelectItemText.vue +11 -0
- package/src/ui/select/SelectLabel.vue +13 -0
- package/src/ui/select/SelectScrollDownButton.vue +24 -0
- package/src/ui/select/SelectScrollUpButton.vue +24 -0
- package/src/ui/select/SelectSeparator.vue +17 -0
- package/src/ui/select/SelectTrigger.vue +31 -0
- package/src/ui/select/SelectValue.vue +11 -0
- package/src/ui/select/index.ts +11 -0
- package/src/ui/sheet/Sheet.vue +14 -0
- package/src/ui/sheet/SheetClose.vue +11 -0
- package/src/ui/sheet/SheetContent.vue +53 -0
- package/src/ui/sheet/SheetDescription.vue +19 -0
- package/src/ui/sheet/SheetFooter.vue +12 -0
- package/src/ui/sheet/SheetHeader.vue +12 -0
- package/src/ui/sheet/SheetTitle.vue +19 -0
- package/src/ui/sheet/SheetTrigger.vue +11 -0
- package/src/ui/sheet/index.ts +29 -0
- package/src/ui/switch/Switch.vue +55 -0
- package/src/ui/switch/index.ts +1 -0
- package/src/ui/textarea/Textarea.vue +24 -0
- package/src/ui/textarea/index.ts +1 -0
- package/src/ui/toast/Toast.vue +28 -0
- package/src/ui/toast/ToastAction.vue +19 -0
- package/src/ui/toast/ToastClose.vue +22 -0
- package/src/ui/toast/ToastDescription.vue +19 -0
- package/src/ui/toast/ToastProvider.vue +11 -0
- package/src/ui/toast/ToastTitle.vue +19 -0
- package/src/ui/toast/ToastViewport.vue +17 -0
- package/src/ui/toast/Toaster.vue +48 -0
- package/src/ui/toast/index.ts +39 -0
- package/src/ui/toast/use-toast.ts +109 -0
- package/src/ui/tooltip/Tooltip.vue +14 -0
- package/src/ui/tooltip/TooltipContent.vue +39 -0
- package/src/ui/tooltip/TooltipProvider.vue +11 -0
- package/src/ui/tooltip/TooltipTrigger.vue +11 -0
- package/src/ui/tooltip/index.ts +4 -0
- package/src/ui/utils.ts +1 -0
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
export const chatComponentI18nKeys: Record<string, Record<string, string>> = {
|
|
2
|
+
en: {
|
|
3
|
+
typeMessage: 'Ask AI to help you...',
|
|
4
|
+
chatAttachFiles: 'Attach files (PDF, Word, Excel, presentations, images…)',
|
|
5
|
+
chatRemoveFile: 'Remove file',
|
|
6
|
+
attachmentsLabel: 'Attachments',
|
|
7
|
+
attachmentOnlyPlaceholder: 'Documents: {names}',
|
|
8
|
+
chatHistory: 'Chat History',
|
|
9
|
+
searchChats: 'Search chats...',
|
|
10
|
+
noChatsFound: 'No chats found',
|
|
11
|
+
today: 'Today',
|
|
12
|
+
yesterday: 'Yesterday',
|
|
13
|
+
dayBeforeYesterday: 'Day before yesterday',
|
|
14
|
+
daysAgo: '{count} days ago',
|
|
15
|
+
renameChat: 'Rename chat',
|
|
16
|
+
cancel: 'Cancel',
|
|
17
|
+
delete: 'Delete',
|
|
18
|
+
pendingStatus: 'Processing your request...',
|
|
19
|
+
phaseToolCalling: 'Using tools',
|
|
20
|
+
activityGroupSteps: '{label}: {count}',
|
|
21
|
+
voiceInputStart: 'Voice input',
|
|
22
|
+
voiceInputStop: 'Stop recording',
|
|
23
|
+
voiceInputUnsupported: 'Voice input is not supported in this browser.',
|
|
24
|
+
voiceInputError: 'Voice input',
|
|
25
|
+
voiceInputPermissionDenied: 'Microphone access was denied.',
|
|
26
|
+
voiceInputErrorGeneric: 'Something went wrong. Try again.',
|
|
27
|
+
voiceInputBrowserWarningTitle: 'Voice input in this browser',
|
|
28
|
+
voiceInputBrowserWarningDescription:
|
|
29
|
+
'Speech recognition may be inaccurate or unstable. For best results, use Google Chrome or Microsoft Edge. You can still continue in your current browser.',
|
|
30
|
+
voiceInputBrowserWarningContinue: 'Continue anyway',
|
|
31
|
+
},
|
|
32
|
+
ru: {
|
|
33
|
+
typeMessage: 'Попросите AI помочь вам...',
|
|
34
|
+
chatAttachFiles: 'Прикрепить файлы (PDF, Word, Excel, презентации, изображения…)',
|
|
35
|
+
chatRemoveFile: 'Убрать файл',
|
|
36
|
+
attachmentsLabel: 'Вложения',
|
|
37
|
+
attachmentOnlyPlaceholder: 'Документы: {names}',
|
|
38
|
+
chatHistory: 'История чатов',
|
|
39
|
+
searchChats: 'Поиск по чатам...',
|
|
40
|
+
noChatsFound: 'Чаты не найдены',
|
|
41
|
+
today: 'Сегодня',
|
|
42
|
+
yesterday: 'Вчера',
|
|
43
|
+
dayBeforeYesterday: 'Позавчера',
|
|
44
|
+
daysAgo: '{count} дней назад',
|
|
45
|
+
renameChat: 'Переименовать чат',
|
|
46
|
+
cancel: 'Отмена',
|
|
47
|
+
delete: 'Удалить',
|
|
48
|
+
pendingStatus: 'Обрабатываем ваш запрос...',
|
|
49
|
+
phaseToolCalling: 'Вызов инструментов',
|
|
50
|
+
activityGroupSteps: '{label}: {count}',
|
|
51
|
+
voiceInputStart: 'Голосовой ввод',
|
|
52
|
+
voiceInputStop: 'Остановить запись',
|
|
53
|
+
voiceInputUnsupported: 'Голосовой ввод не поддерживается в этом браузере.',
|
|
54
|
+
voiceInputError: 'Голосовой ввод',
|
|
55
|
+
voiceInputPermissionDenied: 'Доступ к микрофону запрещён.',
|
|
56
|
+
voiceInputErrorGeneric: 'Не получилось. Попробуйте ещё раз.',
|
|
57
|
+
voiceInputBrowserWarningTitle: 'Голосовой ввод в этом браузере',
|
|
58
|
+
voiceInputBrowserWarningDescription:
|
|
59
|
+
'Распознавание речи может работать неточно или нестабильно. Для лучшего результата используйте Google Chrome или Microsoft Edge. Вы всё равно можете продолжить в текущем браузере.',
|
|
60
|
+
voiceInputBrowserWarningContinue: 'Всё равно продолжить',
|
|
61
|
+
},
|
|
62
|
+
};
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { isAssistantToolPart, type SvedaChatMessageLike } from './assistantMessage.js';
|
|
2
|
+
|
|
3
|
+
export function messageHasVisibleAssistantContent(
|
|
4
|
+
message: SvedaChatMessageLike | null | undefined
|
|
5
|
+
): boolean {
|
|
6
|
+
if (!message || message.role !== 'assistant') {
|
|
7
|
+
return false;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
if (Array.isArray(message.parts) && message.parts.length > 0) {
|
|
11
|
+
return message.parts.some(part => {
|
|
12
|
+
if (part.type === 'text' && part.text?.trim()) {
|
|
13
|
+
return true;
|
|
14
|
+
}
|
|
15
|
+
if (part.type === 'reasoning' && part.text?.trim()) {
|
|
16
|
+
return true;
|
|
17
|
+
}
|
|
18
|
+
if (part.type === 'tool-call' || part.type === 'tool-result') {
|
|
19
|
+
return true;
|
|
20
|
+
}
|
|
21
|
+
if (isAssistantToolPart(part)) {
|
|
22
|
+
return true;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return false;
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return Boolean(message.content?.trim() || message.reasoningStream?.trim());
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function shouldShowChatPendingIndicator(
|
|
33
|
+
isThinking: boolean,
|
|
34
|
+
messages: SvedaChatMessageLike[]
|
|
35
|
+
): boolean {
|
|
36
|
+
if (!isThinking) {
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const lastMessage = messages[messages.length - 1];
|
|
41
|
+
if (!lastMessage) {
|
|
42
|
+
return true;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (lastMessage.role === 'user') {
|
|
46
|
+
return true;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return !messageHasVisibleAssistantContent(lastMessage);
|
|
50
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { userMessageHasVisibleContent, type SvedaUserMessageLike } from './userMessage';
|
|
2
|
+
|
|
3
|
+
export type SvedaTabChat = {
|
|
4
|
+
id: string;
|
|
5
|
+
title?: string;
|
|
6
|
+
messages?: SvedaUserMessageLike[];
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export const isNewChatPlaceholder = (chat: SvedaTabChat, newChatLabel: string): boolean => {
|
|
10
|
+
const messages = chat.messages || [];
|
|
11
|
+
if (messages.some(userMessageHasVisibleContent)) {
|
|
12
|
+
return false;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const title = (chat.title || '').trim();
|
|
16
|
+
if (!title || title === '__NEW_CHAT__' || title === 'New Chat') {
|
|
17
|
+
return true;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
if (title === newChatLabel) {
|
|
21
|
+
return true;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if (title.startsWith(`${newChatLabel} `)) {
|
|
25
|
+
const suffix = title.slice(newChatLabel.length).trim();
|
|
26
|
+
return /^\d+$/.test(suffix);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return false;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export const buildChatTabTitleMap = (
|
|
33
|
+
tabs: SvedaTabChat[],
|
|
34
|
+
translate: (key: string, params?: Record<string, unknown>) => string
|
|
35
|
+
): Map<string, string> => {
|
|
36
|
+
const newChatLabel = translate('newChat');
|
|
37
|
+
const placeholderTabs = tabs.filter(tab => isNewChatPlaceholder(tab, newChatLabel));
|
|
38
|
+
const titles = new Map<string, string>();
|
|
39
|
+
|
|
40
|
+
tabs.forEach(tab => {
|
|
41
|
+
if (!isNewChatPlaceholder(tab, newChatLabel)) {
|
|
42
|
+
titles.set(tab.id, (tab.title || '').trim() || newChatLabel);
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const index = placeholderTabs.findIndex(item => item.id === tab.id) + 1;
|
|
47
|
+
titles.set(
|
|
48
|
+
tab.id,
|
|
49
|
+
placeholderTabs.length > 1 ? translate('newChatNumbered', { number: index }) : newChatLabel
|
|
50
|
+
);
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
return titles;
|
|
54
|
+
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export const isChatTitlePlaceholder = (title: string, newChatLabel: string): boolean => {
|
|
2
|
+
const normalized = (title || '').trim();
|
|
3
|
+
if (!normalized || normalized === '__NEW_CHAT__' || normalized === 'New Chat') {
|
|
4
|
+
return true;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
if (normalized === newChatLabel) {
|
|
8
|
+
return true;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
if (normalized.startsWith(`${newChatLabel} `)) {
|
|
12
|
+
const suffix = normalized.slice(newChatLabel.length).trim();
|
|
13
|
+
return /^\d+$/.test(suffix);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
return false;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export const deriveProvisionalChatTitle = (userRequest: string): string => {
|
|
20
|
+
const text = userRequest.replace(/\s+/g, ' ').trim();
|
|
21
|
+
if (!text) {
|
|
22
|
+
return '';
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
if (text.length > 80) {
|
|
26
|
+
return text.slice(0, 80).trimEnd();
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return text;
|
|
30
|
+
};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export const SVEDA_CHAT_MINIMIZED_STORAGE_KEY = 'sveda.chat-minimized';
|
|
2
|
+
|
|
3
|
+
export const readPersistedMinimized = (): boolean => {
|
|
4
|
+
if (typeof window === 'undefined') {
|
|
5
|
+
return true;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
try {
|
|
9
|
+
const saved = localStorage.getItem(SVEDA_CHAT_MINIMIZED_STORAGE_KEY);
|
|
10
|
+
if (saved === 'true') {
|
|
11
|
+
return true;
|
|
12
|
+
}
|
|
13
|
+
if (saved === 'false') {
|
|
14
|
+
return false;
|
|
15
|
+
}
|
|
16
|
+
} catch {
|
|
17
|
+
return true;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
return true;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export const writePersistedMinimized = (isMinimized: boolean): void => {
|
|
24
|
+
if (typeof window === 'undefined') {
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
try {
|
|
29
|
+
localStorage.setItem(SVEDA_CHAT_MINIMIZED_STORAGE_KEY, isMinimized ? 'true' : 'false');
|
|
30
|
+
} catch {
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
};
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
export type SvedaFinalizableMessage = {
|
|
2
|
+
parts?: Array<{
|
|
3
|
+
type?: string;
|
|
4
|
+
state?: string;
|
|
5
|
+
output?: unknown;
|
|
6
|
+
result?: unknown;
|
|
7
|
+
[key: string]: unknown;
|
|
8
|
+
}>;
|
|
9
|
+
streaming?: boolean;
|
|
10
|
+
activity?: {
|
|
11
|
+
phase?: string;
|
|
12
|
+
steps?: Array<{ status?: string; [key: string]: unknown }>;
|
|
13
|
+
[key: string]: unknown;
|
|
14
|
+
};
|
|
15
|
+
[key: string]: unknown;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
const TERMINAL_ACTIVITY_PHASES = new Set(['done', 'error', 'stopped']);
|
|
19
|
+
|
|
20
|
+
const TOOL_COMPLETE_STATES = new Set([
|
|
21
|
+
'result',
|
|
22
|
+
'output-available',
|
|
23
|
+
'output-error',
|
|
24
|
+
'output-denied',
|
|
25
|
+
'done',
|
|
26
|
+
]);
|
|
27
|
+
|
|
28
|
+
const isToolPart = (part: { type?: string } | undefined): boolean =>
|
|
29
|
+
part?.type === 'dynamic-tool' ||
|
|
30
|
+
(typeof part?.type === 'string' && part.type.startsWith('tool-'));
|
|
31
|
+
|
|
32
|
+
function finalizeActivity<T extends SvedaFinalizableMessage>(message: T): T {
|
|
33
|
+
if (!message.activity) {
|
|
34
|
+
return message;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const activity = { ...message.activity };
|
|
38
|
+
if (activity.phase && !TERMINAL_ACTIVITY_PHASES.has(activity.phase)) {
|
|
39
|
+
activity.phase = 'done';
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (Array.isArray(activity.steps)) {
|
|
43
|
+
activity.steps = activity.steps.map(step => ({
|
|
44
|
+
...step,
|
|
45
|
+
status: step.status === 'running' ? 'success' : step.status,
|
|
46
|
+
}));
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return { ...message, activity };
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function finalizeParts<T extends SvedaFinalizableMessage>(message: T): T {
|
|
53
|
+
if (!Array.isArray(message.parts)) {
|
|
54
|
+
if (message.streaming === true) {
|
|
55
|
+
return { ...message, streaming: false };
|
|
56
|
+
}
|
|
57
|
+
return message;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const parts = message.parts.map(part => {
|
|
61
|
+
if (part?.state === 'streaming') {
|
|
62
|
+
return { ...part, state: 'done' };
|
|
63
|
+
}
|
|
64
|
+
if (isToolPart(part) && part.state && !TOOL_COMPLETE_STATES.has(part.state)) {
|
|
65
|
+
if (part.output !== undefined || part.result !== undefined) {
|
|
66
|
+
return { ...part, state: 'output-available' };
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return part;
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
return {
|
|
73
|
+
...message,
|
|
74
|
+
parts,
|
|
75
|
+
streaming: false,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export function finalizeMessagesForDisplay<T extends SvedaFinalizableMessage>(messages: T[]): T[] {
|
|
80
|
+
return messages.map(message => finalizeActivity(finalizeParts(message)));
|
|
81
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import DOMPurify from 'dompurify';
|
|
2
|
+
import hljs from 'highlight.js';
|
|
3
|
+
import { Marked, Renderer } from 'marked';
|
|
4
|
+
import type { SvedaResourceLink } from './assistantMessage.js';
|
|
5
|
+
|
|
6
|
+
const escapeHtml = (value: string): string =>
|
|
7
|
+
value
|
|
8
|
+
.replace(/&/g, '&')
|
|
9
|
+
.replace(/</g, '<')
|
|
10
|
+
.replace(/>/g, '>')
|
|
11
|
+
.replace(/"/g, '"');
|
|
12
|
+
|
|
13
|
+
const renderer = new Renderer();
|
|
14
|
+
renderer.code = ({ text, lang }): string => {
|
|
15
|
+
const language = lang && hljs.getLanguage(lang) ? lang : '';
|
|
16
|
+
const value = language ? hljs.highlight(text, { language }).value : escapeHtml(text);
|
|
17
|
+
const className = language ? ` class="hljs language-${language}"` : '';
|
|
18
|
+
return `<pre><code${className}>${value}</code></pre>`;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const markedInstance = new Marked({ gfm: true, breaks: true });
|
|
22
|
+
markedInstance.use({ renderer });
|
|
23
|
+
|
|
24
|
+
export function injectResourceLinks(html: string, resources: SvedaResourceLink[]): string {
|
|
25
|
+
if (!Array.isArray(resources) || resources.length === 0) {
|
|
26
|
+
return html;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const sorted = [...resources].sort((a, b) => b.label.length - a.label.length);
|
|
30
|
+
|
|
31
|
+
for (const resource of sorted) {
|
|
32
|
+
if (!resource.label || !resource.url) {
|
|
33
|
+
continue;
|
|
34
|
+
}
|
|
35
|
+
const escaped = resource.label.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
36
|
+
const pattern = new RegExp(
|
|
37
|
+
`(?<=^|[^a-zA-Zа-яА-ЯёЁ])(«${escaped}»|„${escaped}"|"${escaped}"|«${escaped}|${escaped}»|${escaped})(?=$|[^a-zA-Zа-яА-ЯёЁ])`,
|
|
38
|
+
'gu'
|
|
39
|
+
);
|
|
40
|
+
const safeLink = resource.url.replace(/"/g, '"');
|
|
41
|
+
const icon =
|
|
42
|
+
'<svg class="resource-link-icon" xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M7 7h10v10"/><path d="M7 17 17 7"/></svg>';
|
|
43
|
+
html = html.replace(pattern, `<a href="${safeLink}" class="resource-inline-link">$1${icon}</a>`);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return html;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export interface SvedaMarkdownOptions {
|
|
50
|
+
resources?: SvedaResourceLink[];
|
|
51
|
+
injectResources?: boolean;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export function renderMarkdown(text: string, options: SvedaMarkdownOptions = {}): string {
|
|
55
|
+
const body = text || '';
|
|
56
|
+
if (!body.trim()) {
|
|
57
|
+
return '';
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const raw = markedInstance.parse(body, { async: false });
|
|
61
|
+
let html = DOMPurify.sanitize(raw, {
|
|
62
|
+
ALLOWED_TAGS: [
|
|
63
|
+
'p',
|
|
64
|
+
'br',
|
|
65
|
+
'strong',
|
|
66
|
+
'em',
|
|
67
|
+
'code',
|
|
68
|
+
'pre',
|
|
69
|
+
'ul',
|
|
70
|
+
'ol',
|
|
71
|
+
'li',
|
|
72
|
+
'h1',
|
|
73
|
+
'h2',
|
|
74
|
+
'h3',
|
|
75
|
+
'h4',
|
|
76
|
+
'a',
|
|
77
|
+
'blockquote',
|
|
78
|
+
'hr',
|
|
79
|
+
'span',
|
|
80
|
+
'img',
|
|
81
|
+
],
|
|
82
|
+
ALLOWED_ATTR: ['href', 'src', 'alt', 'title', 'class', 'target', 'rel', 'loading'],
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
if (options.injectResources && Array.isArray(options.resources) && options.resources.length > 0) {
|
|
86
|
+
html = injectResourceLinks(html, options.resources);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return html;
|
|
90
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export function humanizeModelId(raw: string): string {
|
|
2
|
+
const part = raw.includes('/') ? (raw.split('/').pop() as string) : raw;
|
|
3
|
+
const cleaned = part.replace(/-preview$/i, '').replace(/_/g, '-');
|
|
4
|
+
return cleaned
|
|
5
|
+
.split('-')
|
|
6
|
+
.map(seg => {
|
|
7
|
+
if (/^\d+(\.\d+)?$/.test(seg)) {
|
|
8
|
+
return seg;
|
|
9
|
+
}
|
|
10
|
+
if (seg.length === 0) {
|
|
11
|
+
return '';
|
|
12
|
+
}
|
|
13
|
+
return seg[0].toUpperCase() + seg.slice(1).toLowerCase();
|
|
14
|
+
})
|
|
15
|
+
.join(' ');
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function getSvedaModelDisplayName(model: string | null | undefined): string {
|
|
19
|
+
if (!model) {
|
|
20
|
+
return '—';
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
return humanizeModelId(model);
|
|
24
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export function shuffleArray<T>(items: T[]): T[] {
|
|
2
|
+
const copy = [...items];
|
|
3
|
+
|
|
4
|
+
for (let index = copy.length - 1; index > 0; index -= 1) {
|
|
5
|
+
const swapIndex = Math.floor(Math.random() * (index + 1));
|
|
6
|
+
[copy[index], copy[swapIndex]] = [copy[swapIndex], copy[index]];
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
return copy;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function buildPendingStatusRotation(allMessages: string[]): string[] {
|
|
13
|
+
const messages = allMessages.filter(message => message.trim() !== '');
|
|
14
|
+
|
|
15
|
+
if (messages.length === 0) {
|
|
16
|
+
return [];
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
if (messages.length === 1) {
|
|
20
|
+
return [messages[0]];
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const [firstMessage, ...remainingMessages] = messages;
|
|
24
|
+
|
|
25
|
+
return [firstMessage, ...shuffleArray(remainingMessages)];
|
|
26
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { onUnmounted, ref, toValue, watch, type MaybeRefOrGetter, type Ref } from 'vue';
|
|
2
|
+
|
|
3
|
+
const CHAR_INTERVAL_MS = 12;
|
|
4
|
+
const CHARS_PER_TICK = 2;
|
|
5
|
+
|
|
6
|
+
export interface UseAnimatedTextOptions {
|
|
7
|
+
intervalMs?: number;
|
|
8
|
+
charsPerTick?: number;
|
|
9
|
+
enabled?: MaybeRefOrGetter<boolean>;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function useAnimatedText(
|
|
13
|
+
getSource: MaybeRefOrGetter<string>,
|
|
14
|
+
options: UseAnimatedTextOptions = {}
|
|
15
|
+
): Ref<string> {
|
|
16
|
+
const intervalMs = options.intervalMs ?? CHAR_INTERVAL_MS;
|
|
17
|
+
const charsPerTick = options.charsPerTick ?? CHARS_PER_TICK;
|
|
18
|
+
const getEnabled = options.enabled ?? (() => true);
|
|
19
|
+
const displayedText = ref('');
|
|
20
|
+
let tickId: ReturnType<typeof setInterval> | null = null;
|
|
21
|
+
|
|
22
|
+
function animateTowardsTarget() {
|
|
23
|
+
const target = toValue(getSource);
|
|
24
|
+
const targetStr = typeof target === 'string' ? target : '';
|
|
25
|
+
if (displayedText.value.length >= targetStr.length) {
|
|
26
|
+
if (tickId) {
|
|
27
|
+
clearInterval(tickId);
|
|
28
|
+
tickId = null;
|
|
29
|
+
}
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
const remaining = targetStr.length - displayedText.value.length;
|
|
33
|
+
const toAdd = Math.min(charsPerTick, remaining);
|
|
34
|
+
displayedText.value = targetStr.slice(0, displayedText.value.length + toAdd);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
watch(
|
|
38
|
+
() => {
|
|
39
|
+
const source = toValue(getSource);
|
|
40
|
+
const enabled = toValue(getEnabled);
|
|
41
|
+
return { source, enabled };
|
|
42
|
+
},
|
|
43
|
+
({ source, enabled }) => {
|
|
44
|
+
const newText = typeof source === 'string' ? source : '';
|
|
45
|
+
if (!enabled) {
|
|
46
|
+
displayedText.value = newText;
|
|
47
|
+
if (tickId) {
|
|
48
|
+
clearInterval(tickId);
|
|
49
|
+
tickId = null;
|
|
50
|
+
}
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
if (newText.length <= displayedText.value.length) {
|
|
54
|
+
displayedText.value = newText;
|
|
55
|
+
if (tickId) {
|
|
56
|
+
clearInterval(tickId);
|
|
57
|
+
tickId = null;
|
|
58
|
+
}
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
if (!tickId) {
|
|
62
|
+
tickId = setInterval(() => {
|
|
63
|
+
animateTowardsTarget();
|
|
64
|
+
}, intervalMs);
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
{ immediate: true }
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
onUnmounted(() => {
|
|
71
|
+
if (tickId) {
|
|
72
|
+
clearInterval(tickId);
|
|
73
|
+
tickId = null;
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
return displayedText;
|
|
78
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
export type SvedaUserMessageLike = {
|
|
2
|
+
role?: string;
|
|
3
|
+
content?: string;
|
|
4
|
+
attachmentNames?: string[];
|
|
5
|
+
metadata?: {
|
|
6
|
+
attachmentNames?: string[];
|
|
7
|
+
};
|
|
8
|
+
parts?: Array<{
|
|
9
|
+
type?: string;
|
|
10
|
+
text?: string;
|
|
11
|
+
name?: string;
|
|
12
|
+
}>;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export const getUserMessageText = (message: SvedaUserMessageLike): string => {
|
|
16
|
+
if (typeof message.content === 'string' && message.content.trim()) {
|
|
17
|
+
return message.content.trim();
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
if (!Array.isArray(message.parts)) {
|
|
21
|
+
return '';
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return message.parts
|
|
25
|
+
.filter(part => part?.type === 'text')
|
|
26
|
+
.map(part => String(part.text || '').trim())
|
|
27
|
+
.filter(Boolean)
|
|
28
|
+
.join(' ');
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export const getUserMessageAttachmentNames = (message: SvedaUserMessageLike): string[] => {
|
|
32
|
+
const raw = message.attachmentNames ?? message.metadata?.attachmentNames;
|
|
33
|
+
if (Array.isArray(raw)) {
|
|
34
|
+
return raw.map(name => String(name).trim()).filter(Boolean);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (!Array.isArray(message.parts)) {
|
|
38
|
+
return [];
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return message.parts
|
|
42
|
+
.filter(part => part?.type === 'file')
|
|
43
|
+
.map(part => String(part.name || '').trim())
|
|
44
|
+
.filter(Boolean);
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
export const userMessageHasVisibleContent = (message: SvedaUserMessageLike): boolean => {
|
|
48
|
+
if (message.role !== 'user') {
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return (
|
|
53
|
+
getUserMessageText(message).length > 0 || getUserMessageAttachmentNames(message).length > 0
|
|
54
|
+
);
|
|
55
|
+
};
|