@designcrowd/library.brand-page 6.0.5 → 6.0.6-ast-bugs
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/src/{CreatedOnBrandCrowd-de-de-DhzvKlTS.js → CreatedOnBrandCrowd-de-de-SHCspMwS.js} +3 -3
- package/lib/src/{CreatedOnBrandCrowd-en-us-DKH4lmNV.js → CreatedOnBrandCrowd-en-us-C6lITAAT.js} +3 -3
- package/lib/src/{CreatedOnBrandCrowd-es-es-RloPCLuV.js → CreatedOnBrandCrowd-es-es-Uh69c4vZ.js} +3 -3
- package/lib/src/{CreatedOnBrandCrowd-fr-fr-Cu9e2H0K.js → CreatedOnBrandCrowd-fr-ca-Bb0rp7BV.js} +3 -3
- package/lib/src/{CreatedOnBrandCrowd-fr-ca-Cu9e2H0K.js → CreatedOnBrandCrowd-fr-fr-Bb0rp7BV.js} +3 -3
- package/lib/src/{CreatedOnBrandCrowd-pt-pt-CiCnjxBZ.js → CreatedOnBrandCrowd-pt-br-DsrQHcjs.js} +3 -3
- package/lib/src/{CreatedOnBrandCrowd-pt-br-CiCnjxBZ.js → CreatedOnBrandCrowd-pt-pt-DsrQHcjs.js} +3 -3
- package/lib/src/{CreatedOnDcom-de-de-CwlnedFV.js → CreatedOnDcom-de-de-BshZYzSp.js} +3 -3
- package/lib/src/{CreatedOnDcom-en-us-DFHex61v.js → CreatedOnDcom-en-us-CLu8mKUW.js} +3 -3
- package/lib/src/{CreatedOnDcom-es-es-BTxH6I4V.js → CreatedOnDcom-es-es-BZYhkONd.js} +3 -3
- package/lib/src/{CreatedOnDcom-fr-ca-BVw0KYxu.js → CreatedOnDcom-fr-ca-CIaBEp_9.js} +3 -3
- package/lib/src/{CreatedOnDcom-fr-fr-DaqNz1Er.js → CreatedOnDcom-fr-fr-dyF7hioJ.js} +3 -3
- package/lib/src/{CreatedOnDcom-pt-br-B4KsMI8W.js → CreatedOnDcom-pt-br-CUHjk2du.js} +3 -3
- package/lib/src/{CreatedOnDcom-pt-pt-CWoHEtOZ.js → CreatedOnDcom-pt-pt-CWDvQidv.js} +3 -3
- package/lib/src/brand-page/clients/brand-page.client.d.ts +9 -9
- package/lib/src/brand-page/components/banner-section/BannerSection.mixin.d.ts +103 -0
- package/lib/src/brand-page/components/banner-section/BannerSection.mixin.js +178 -0
- package/lib/src/brand-page/components/image-gallery/masonry/MasonryGallery.mixin.d.ts +1 -2
- package/lib/src/brand-page/components/navigation/hamburger/HamburgerNavigation.mixin.d.ts +4 -2
- package/lib/src/brand-page/components/navigation/hamburger/HamburgerNavigation.mixin.js +1 -0
- package/lib/src/brand-page/components/navigation/navigation-side-menu/NavigationSideMenu.mixin.d.ts +4 -2
- package/lib/src/brand-page/components/navigation/navigation-side-menu/NavigationSideMenu.mixin.js +11 -5
- package/lib/src/brand-page/components/page/Page.mixin.d.ts +1 -1
- package/lib/src/brand-page/components/page/PageComponent.mixin.d.ts +1 -1
- package/lib/src/brand-page/components/payment/Payment.mixin.d.ts +3 -3
- package/lib/src/brand-page/components/payment/__fixtures__/request-payment.d.ts +13 -13
- package/lib/src/brand-page/components/payment/__fixtures__/support-me.d.ts +13 -13
- package/lib/src/brand-page/constants/sections/footer-display.constants.js +1 -1
- package/lib/src/brand-page/models/index.d.ts +2 -13
- package/lib/src/brand-page/models/index.js +3 -0
- package/lib/src/brand-page/models/payment.model.d.ts +1 -1
- package/lib/src/brand-page/utils/personalisation.util.js +72 -14
- package/lib/src/brand-page-maker/components/action-bar/ActionBar.mixin.d.ts +21 -19
- package/lib/src/brand-page-maker/components/action-bar/ActionBar.mixin.js +1 -0
- package/lib/src/brand-page-maker/components/admin-background-settings/AdminBackgroundSettings.mixin.d.ts +16 -10
- package/lib/src/brand-page-maker/components/admin-background-settings/ShapePositionSlider.mixin.d.ts +1 -1
- package/lib/src/brand-page-maker/components/admin-logo-settings/AdminLogoSettings.mixin.d.ts +3 -3
- package/lib/src/brand-page-maker/components/brand-page-maker/BrandPageMaker.mixin.d.ts +181 -170
- package/lib/src/brand-page-maker/components/brand-page-maker/BrandPageMaker.mixin.js +3 -0
- package/lib/src/brand-page-maker/components/brand-page-maker/BrandPageMaker.stories.js +1 -0
- package/lib/src/brand-page-maker/components/brand-page-maker/BrandPageMakerTemplateSettings.mixin.d.ts +12 -12
- package/lib/src/brand-page-maker/components/brand-page-maker/BrandPageMakerTemplateSettings.stories.js +2 -2
- package/lib/src/brand-page-maker/components/brand-page-maker/__fixtures__/brand-page-payment.js +0 -7
- package/lib/src/brand-page-maker/components/brandpage-maker-page/BrandPageMakerPage.mixin.d.ts +148 -149
- package/lib/src/brand-page-maker/components/brandpage-settings/ReplaceImageSettingsForBrandPageSettings.mixin.d.ts +21 -21
- package/lib/src/brand-page-maker/components/brandpage-settings/ReplaceImageSettingsForBrandPageSettings.mixin.js +1 -1
- package/lib/src/brand-page-maker/components/color-picker/components/ColorModeSelect.mixin.d.ts +4 -2
- package/lib/src/brand-page-maker/components/color-picker/components/ColorModeSelect.mixin.js +1 -0
- package/lib/src/brand-page-maker/components/color-picker/components/GradientColorSlider.mixin.d.ts +4 -2
- package/lib/src/brand-page-maker/components/color-picker/components/GradientColorSlider.mixin.js +1 -0
- package/lib/src/brand-page-maker/components/color-picker/components/GradientColorSliderHandler.mixin.d.ts +5 -2
- package/lib/src/brand-page-maker/components/color-picker/components/GradientColorSliderHandler.mixin.js +1 -0
- package/lib/src/brand-page-maker/components/color-picker/components/GradientTypeSelector.mixin.d.ts +4 -2
- package/lib/src/brand-page-maker/components/color-picker/components/GradientTypeSelector.mixin.js +1 -0
- package/lib/src/brand-page-maker/components/device/Device.mixin.d.ts +4 -2
- package/lib/src/brand-page-maker/components/device/Device.mixin.js +1 -0
- package/lib/src/brand-page-maker/components/navigation/Navigation.mixin.d.ts +4 -2
- package/lib/src/brand-page-maker/components/navigation/Navigation.mixin.js +1 -0
- package/lib/src/brand-page-maker/components/preview/Preview.mixin.d.ts +3 -3
- package/lib/src/brand-page-maker/components/quick-link-bar/QuickLinkBar.mixin.d.ts +11 -11
- package/lib/src/brand-page-maker/components/seo-settings/SeoPageSettings.mixin.d.ts +27 -25
- package/lib/src/brand-page-maker/components/seo-settings/SeoPageSettings.mixin.js +1 -0
- package/lib/src/brand-page-maker/components/seo-settings/UrlSettings.mixin.d.ts +27 -27
- package/lib/src/brand-page-maker/components/seo-settings/UrlSettings.mixin.js +1 -1
- package/lib/src/brand-page-maker/components/seo-settings/UseExistingDomainModal.mixin.d.ts +17 -12
- package/lib/src/brand-page-maker/components/social-share/SocialShare.mixin.d.ts +12 -12
- package/lib/src/brand-page-maker/components/template-preview/TemplatePreview.mixin.d.ts +30 -32
- package/lib/src/brand-page-maker/components/template-preview/TemplatePreview.mixin.js +16 -5
- package/lib/src/brand-page-maker/components/upgrade-to-premium-button/UpgradeToPremiumButton.mixin.d.ts +11 -11
- package/lib/src/brand-page-maker/composables/ai-chat/types.d.ts +3 -0
- package/lib/src/brand-page-maker/composables/ai-chat/ui-actions.d.ts +29 -0
- package/lib/src/brand-page-maker/composables/ai-chat/ui-actions.js +32 -0
- package/lib/src/brand-page-maker/composables/ai-chat/useAiWebsiteBuilderChat.js +204 -177
- package/lib/src/brand-page-maker/composables/rich-text-editor/useRichTextEditor.d.ts +1 -1
- package/lib/src/brand-page-maker/composables/rich-text-editor/useRichTextEditor.js +6 -6
- package/lib/src/brand-page-maker/composables/useEventTracker.d.ts +3 -2
- package/lib/src/brand-page-maker/composables/useEventTracker.js +1 -0
- package/lib/src/brand-page-maker/constants/config-settings-constant.d.ts +6 -6
- package/lib/src/brand-page-maker/constants/config-settings-constant.js +3 -3
- package/lib/src/brand-page-maker/convertors/text-image-display-style.convertor.d.ts +1 -1
- package/lib/src/brand-page-maker/convertors/text-image-display-style.convertor.js +1 -1
- package/lib/src/brand-page-maker/models/content-settings.d.ts +1 -1
- package/lib/src/brand-page-maker/models/navigation-style-configs.js +1 -1
- package/lib/src/brand-page-maker/routing/brand-page-maker-router.d.ts +1 -2
- package/lib/src/brand-page-maker/stores/ai-checkpoint/ai-checkpoint-store.d.ts +366 -378
- package/lib/src/brand-page-maker/stores/brandpage-container/brand-page-container-store.d.ts +5 -4
- package/lib/src/brand-page-maker/stores/brandpage-container/brand-page-container-store.js +8 -5
- package/lib/src/brand-page-maker/stores/brandpage-maker/brandpage-maker-store.d.ts +3 -1
- package/lib/src/brand-page-maker/stores/brandpage-maker/brandpage-maker-store.js +7 -3
- package/lib/src/brand-page-maker/stores/history/history-store.d.ts +15 -15
- package/lib/src/brand-page-maker/stores/ui/ui-store.d.ts +6 -0
- package/lib/src/brand-page-maker/stores/ui/ui-store.js +8 -0
- package/lib/src/brand-page-maker/utils/content-settings.util.js +1 -1
- package/lib/src/brand-page-maker/utils/rich-text-editor.util.d.ts +1 -1
- package/lib/src/brand-page-maker/utils/rich-text-editor.util.js +4 -4
- package/lib/src/clients/ai-assistant-client.d.ts +7 -0
- package/lib/src/clients/brand-page-client.d.ts +16 -15
- package/lib/src/clients/design-template-client.d.ts +3 -0
- package/lib/src/clients/media-client.d.ts +2 -2
- package/lib/src/clients/models.d.ts +2 -0
- package/lib/src/composables/useSnapshot.js +18 -18
- package/lib/src/css/library.brand-page-brandCrowd.min.css +371 -344
- package/lib/src/css/library.brand-page-brandPage.min.css +649 -344
- package/lib/src/css/library.brand-page-designCom.min.css +371 -344
- package/lib/src/css/library.brand-page-preview.min.css +627 -344
- package/lib/src/index.d.ts +4 -0
- package/lib/src/index.mjs +107 -104
- package/lib/src/{lib-BPI8E2Ui.js → lib-COw-Rz05.js} +37005 -33761
- package/lib/src/lib.js +10 -0
- package/lib/src/metadata-builder/builders/footer-builder.js +105 -62
- package/lib/src/metadata-builder/builders/section-builders/image-gallery-builder.js +68 -57
- package/lib/src/metadata-builder/builders/section-builders/images-section-builder.js +93 -58
- package/lib/src/metadata-builder/builders/section-builders/shapes-section-builder.js +99 -66
- package/lib/src/metadata-builder/builders/section-builders/social-links-builder.js +17 -57
- package/lib/src/metadata-builder/builders/section-builders/testimonial-section-builder.js +85 -51
- package/lib/src/metadata-builder/builders/section-builders/text-section-builder.js +74 -49
- package/lib/src/metadata-builder/builders/section-field-utils.d.ts +7 -0
- package/lib/src/metadata-builder/builders/section-field-utils.js +1 -1
- package/lib/src/metadata-builder/builders/shape-color-utils.js +1 -1
- package/lib/src/metadata-builder/parsers/ai-toolcall-parser.d.ts +7 -16
- package/lib/src/metadata-builder/parsers/section-tool-arguments.d.ts +48 -66
- package/lib/src/plugins/google-maps-plugin/google-maps-plugin.d.ts +1 -1
- package/lib/src/plugins/google-maps-plugin/google-maps-plugin.js +8 -8
- package/lib/src/shared/background-settings/components/background-shapes/BackgroundShapeSettings.mixin.d.ts +13 -13
- package/lib/src/shared/background-settings/store/background-settings-store.d.ts +3 -3
- package/lib/src/shared/color-picker/components/ColorPicker.mixin.d.ts +4 -2
- package/lib/src/shared/color-picker/components/ColorPicker.mixin.js +2 -2
- package/lib/src/shared/color-picker/components/ColorPickerSwatch.mixin.d.ts +4 -2
- package/lib/src/shared/color-picker/components/ColorPickerSwatch.mixin.js +1 -0
- package/lib/src/shared/confirm-modal/ConfirmModal.mixin.d.ts +5 -2
- package/lib/src/shared/confirm-modal/ConfirmModal.mixin.js +1 -0
- package/lib/src/shared/content-settings/components/GenericTextInput.mixin.d.ts +0 -1
- package/lib/src/shared/content-settings/components/content-settings/ContentSettings.mixin.d.ts +131 -129
- package/lib/src/shared/content-settings/components/content-settings/ContentSettings.mixin.js +2 -1
- package/lib/src/shared/content-settings/components/content-settings/ReplaceImageSettingsForContent.mixin.d.ts +111 -110
- package/lib/src/shared/content-settings/components/content-settings-item/ContentSettingsItem.mixin.d.ts +84 -81
- package/lib/src/shared/content-settings/components/content-settings-item/ContentSettingsItem.mixin.js +5 -0
- package/lib/src/shared/content-settings/components/content-settings-item/ContentSettingsItemField.mixin.d.ts +117 -109
- package/lib/src/shared/content-settings/components/content-settings-item/ContentSettingsItemField.mixin.js +1 -14
- package/lib/src/shared/content-settings/components/email-field/EmailField.mixin.d.ts +0 -1
- package/lib/src/shared/content-settings/components/focused-content-item-settings/FocusedContentItemSettings.mixin.d.ts +72 -70
- package/lib/src/shared/content-settings/components/focused-content-item-settings/FocusedContentItemSettings.mixin.js +4 -3
- package/lib/src/shared/content-settings/components/form-fields-field/FormFieldsField.mixin.d.ts +4 -4
- package/lib/src/shared/content-settings/components/icon-library/IconLibrary.mixin.d.ts +3 -1
- package/lib/src/shared/content-settings/components/icon-library/IconLibrary.mixin.js +1 -0
- package/lib/src/shared/content-settings/components/images-field/ImagesField.mixin.d.ts +2 -2
- package/lib/src/shared/content-settings/components/items-field/ItemsField.mixin.d.ts +4 -3
- package/lib/src/shared/content-settings/components/items-field/ItemsField.mixin.js +1 -1
- package/lib/src/shared/content-settings/components/payment-config-field/PaymentConfigField.mixin.d.ts +40 -40
- package/lib/src/shared/content-settings/components/payment-config-field/PaymentConfigOptionField.mixin.d.ts +5 -6
- package/lib/src/shared/content-settings/components/shape-field/ShapeField.mixin.d.ts +0 -1
- package/lib/src/shared/content-settings/components/slider-field/SliderField.mixin.d.ts +2 -2
- package/lib/src/shared/content-settings/components/tel-field/TelField.mixin.d.ts +0 -1
- package/lib/src/shared/content-settings/components/testimonial-items-field/TestimonialItemsField.mixin.d.ts +1 -2
- package/lib/src/shared/content-settings/components/text-field/TextField.mixin.d.ts +0 -1
- package/lib/src/shared/content-settings/components/text-items-field/TextItemsField.mixin.d.ts +1 -2
- package/lib/src/shared/content-settings/components/text-items-field/TextItemsField.mixin.js +1 -1
- package/lib/src/shared/content-settings/components/text-style-field/TextStyleField.mixin.d.ts +28 -28
- package/lib/src/shared/content-settings/components/textarea-field/TextareaField.mixin.d.ts +0 -1
- package/lib/src/shared/content-settings/components/toggle-field/ToggleField.mixin.d.ts +2 -2
- package/lib/src/shared/content-settings/components/url-field/UrlField.mixin.d.ts +0 -1
- package/lib/src/shared/content-settings/components/youtube-video-field/YoutubeVideoField.mixin.d.ts +0 -1
- package/lib/src/shared/content-settings/store/content-settings-store.d.ts +39 -39
- package/lib/src/shared/content-settings/utils.js +0 -1
- package/lib/src/shared/font-family-selector/FontFamilySelector.mixin.d.ts +6 -4
- package/lib/src/shared/font-family-selector/FontFamilySelector.mixin.js +1 -0
- package/lib/src/shared/image-gallery-style-settings/ImageGalleryStyleSettings.mixin.d.ts +4 -2
- package/lib/src/shared/image-gallery-style-settings/ImageGalleryStyleSettings.mixin.js +1 -0
- package/lib/src/shared/logo-settings/components/EditLogoSettings.mixin.d.ts +29 -21
- package/lib/src/shared/logo-settings/components/EditLogoSettings.mixin.js +1 -1
- package/lib/src/shared/logo-settings/components/LogoSettings.mixin.d.ts +50 -51
- package/lib/src/shared/logo-settings/components/LogoSettingsHeader.mixin.d.ts +6 -4
- package/lib/src/shared/logo-settings/components/LogoSettingsHeader.mixin.js +1 -0
- package/lib/src/shared/logo-settings/store/editable-logo-store.js +1 -1
- package/lib/src/shared/logo-settings/store/logo-settings-store.d.ts +1 -1
- package/lib/src/shared/logo-versions/LogoVersions.mixin.d.ts +13 -5
- package/lib/src/shared/logo-versions/LogoVersions.mixin.js +1 -0
- package/lib/src/shared/models.d.ts +2 -0
- package/lib/src/shared/my-designs/MyDesigns.mixin.d.ts +14 -6
- package/lib/src/shared/my-designs/MyDesigns.mixin.js +1 -0
- package/lib/src/shared/my-uploads/MyMedia.mixin.d.ts +14 -5
- package/lib/src/shared/my-uploads/MyMedia.mixin.js +1 -0
- package/lib/src/shared/my-uploads/MyUploads.mixin.d.ts +14 -5
- package/lib/src/shared/my-uploads/MyUploads.mixin.js +1 -0
- package/lib/src/shared/navigation-style-settings/components/navigation-style-settings/NavigationStyleSettings.mixin.d.ts +5 -3
- package/lib/src/shared/navigation-style-settings/components/navigation-style-settings/NavigationStyleSettings.mixin.js +1 -0
- package/lib/src/shared/navigation-style-settings/store/index.d.ts +2 -2
- package/lib/src/shared/page-navigation/store/page-navigation-store.d.ts +2 -2
- package/lib/src/shared/page-settings/components/new-page-modal/NewPageModal.mixin.d.ts +27 -28
- package/lib/src/shared/page-settings/components/new-page-modal/NewPageModal.mixin.js +0 -2
- package/lib/src/shared/page-settings/components/page-settings/PageSettings.mixin.d.ts +188 -179
- package/lib/src/shared/page-settings/components/page-settings-section-styles/PageSettingsSectionStyles.mixin.d.ts +181 -177
- package/lib/src/shared/page-settings/components/page-settings-section-styles/PageSettingsSectionStyles.mixin.js +1 -1
- package/lib/src/shared/page-settings/store/page-settings-store.d.ts +9 -9
- package/lib/src/shared/publish-brand-page-with-state/PublishBrandPageModalWithState.mixin.d.ts +39 -39
- package/lib/src/shared/publish-brand-page-with-state/PublishBrandPageModalWithState.mixin.js +0 -1
- package/lib/src/shared/side-bar/components/SideBar.mixin.d.ts +18 -18
- package/lib/src/shared/side-bar/components/SideBarTabButton.mixin.d.ts +6 -6
- package/lib/src/shared/style-settings/components/StyleSettings.mixin.d.ts +66 -60
- package/lib/src/shared/style-settings/store/style-settings-store.d.ts +1 -1
- package/lib/src/shared/style-settings/store/style-settings-store.js +1 -1
- package/lib/src/shared/template-settings/components/TemplatesSettings.mixin.d.ts +20 -450
- package/lib/src/shared/template-settings/components/TemplatesSettings.mixin.js +2 -2
- package/lib/src/shared/template-settings/models.d.ts +1 -0
- package/lib/src/shared/template-settings/store/template-settings-store.d.ts +4 -0
- package/lib/src/shared/template-settings/store/template-settings-store.js +79 -11
- package/lib/src/shared/unsplash-library/UnsplashLibrary.mixin.d.ts +9 -4
- package/lib/src/utils/build-asset-manifest.d.ts +4 -0
- package/lib/src/utils/build-asset-manifest.js +8 -0
- package/lib/src/utils/minify-brand-page-metadata.d.ts +0 -2
- package/lib/src/utils/minify-brand-page-metadata.js +2 -17
- package/package.json +60 -56
- package/src/brand-page/components/about-section/AboutSection.vue.test.ts +7 -5
- package/src/brand-page/components/banner-section/BannerSection.mixin.ts +210 -0
- package/src/brand-page/components/banner-section/BannerSection.vue +5 -1
- package/src/brand-page/components/brand-page-footer/BrandPageFooter.vue +1 -1
- package/src/brand-page/components/image/Image.mixin.ts +1 -1
- package/src/brand-page/components/image/Image.test.ts +1 -1
- package/src/brand-page/components/image-gallery/masonry/MasonryGallery.mixin.ts +1 -2
- package/src/brand-page/components/images-section/ImagesSection.vue +0 -1
- package/src/brand-page/components/logo/LogoRender.vue +188 -188
- package/src/brand-page/components/navigation/hamburger/HamburgerNavigation.mixin.ts +1 -0
- package/src/brand-page/components/navigation/navigation-side-menu/NavigationSideMenu.mixin.ts +25 -8
- package/src/brand-page/components/page-footer/PageFooter.vue +1 -0
- package/src/brand-page/components/page-header/HeaderLayout.vue +12 -6
- package/src/brand-page/components/page-header/PageHeader.vue +1 -0
- package/src/brand-page/components/shapes-section/ShapesSection.vue +1 -1
- package/src/brand-page/components/shop/CartModal.vue +1 -3
- package/src/brand-page/components/shop/FeaturedDisplay.vue +2 -2
- package/src/brand-page/components/shop/PaymentModal.vue +1 -5
- package/src/brand-page/components/shop/ProductDetailModal.vue +1 -1
- package/src/brand-page/components/shop/Shop.vue +1 -5
- package/src/brand-page/components/shop/TextDisplay.vue +1 -1
- package/src/brand-page/components/shop/ThumbnailDisplay.vue +2 -2
- package/src/brand-page/components/testimonial-section/TestimonialSection.vue +3 -3
- package/src/brand-page/components/text-wrapper/TextWrapper.vue +3 -1
- package/src/brand-page/constants/sections/footer-display.constants.ts +1 -1
- package/src/brand-page/models/index.ts +4 -12
- package/src/brand-page/models/payment.model.ts +2 -1
- package/src/brand-page/models/shop.model.ts +0 -2
- package/src/brand-page/models/user-personalisation.model.ts +1 -2
- package/src/brand-page/utils/__snapshots__/migration.util.test.ts.snap +3 -0
- package/src/brand-page/utils/__snapshots__/migration2.util.test.ts.snap +1 -0
- package/src/brand-page/utils/__snapshots__/model.util.test.ts.snap +2 -0
- package/src/brand-page/utils/migration/migration-01_1.ts +1 -1
- package/src/brand-page/utils/migration/migration-02.ts +0 -1
- package/src/brand-page/utils/migration/migration-03.ts +0 -1
- package/src/brand-page/utils/migration/migration-04.ts +0 -1
- package/src/brand-page/utils/migration/migration-05.ts +1 -5
- package/src/brand-page/utils/migration/migration-05_2.ts +1 -1
- package/src/brand-page/utils/migration/migration-08.test.ts +1 -1
- package/src/brand-page/utils/personalisation.util.test.ts +35 -0
- package/src/brand-page/utils/personalisation.util.ts +119 -23
- package/src/brand-page/view-models.ts +38 -56
- package/src/brand-page-maker/assessors/banner-section-description-visibility.assessor.ts +6 -6
- package/src/brand-page-maker/assessors/color-replacement-icon-visibility.assessor.ts +2 -2
- package/src/brand-page-maker/assessors/color-replacement-profile-visibility.assessor.ts +2 -2
- package/src/brand-page-maker/assessors/color-replacement-visibility.assessor.ts +2 -2
- package/src/brand-page-maker/assessors/contact-form-visibility.assessor.ts +14 -14
- package/src/brand-page-maker/components/action-bar/ActionBar.mixin.ts +1 -0
- package/src/brand-page-maker/components/ai-text-edit/AiActionButtons.vue +27 -12
- package/src/brand-page-maker/components/ai-text-edit/AiChatbox.vue +3 -2
- package/src/brand-page-maker/components/ai-text-edit/TextBubble.vue +8 -7
- package/src/brand-page-maker/components/ai-website-builder/AiWebsiteBuilder.vue +21 -1
- package/src/brand-page-maker/components/brand-page-maker/BrandPageMaker.mixin.ts +5 -1
- package/src/brand-page-maker/components/brand-page-maker/BrandPageMaker.stories.ts +1 -0
- package/src/brand-page-maker/components/brand-page-maker/BrandPageMakerTemplateSettings.stories.ts +2 -5
- package/src/brand-page-maker/components/brand-page-maker/__fixtures__/brand-page-examples.ts +0 -5
- package/src/brand-page-maker/components/brand-page-maker/__fixtures__/brand-page-payment.ts +0 -8
- package/src/brand-page-maker/components/brand-page-maker/__fixtures__/brand-site-template.examples.ts +0 -2
- package/src/brand-page-maker/components/brandpage-maker-page/BrandPageMakerPage.vue +1 -0
- package/src/brand-page-maker/components/brandpage-settings/ReplaceImageSettingsForBrandPageSettings.mixin.ts +1 -1
- package/src/brand-page-maker/components/color-palette/BpColorPalette.vue +1 -2
- package/src/brand-page-maker/components/color-picker/components/ColorModeSelect.mixin.ts +1 -0
- package/src/brand-page-maker/components/color-picker/components/GradientColorSlider.mixin.ts +1 -0
- package/src/brand-page-maker/components/color-picker/components/GradientColorSliderHandler.mixin.ts +1 -0
- package/src/brand-page-maker/components/color-picker/components/GradientTypeSelector.mixin.ts +1 -0
- package/src/brand-page-maker/components/device/Device.mixin.ts +1 -0
- package/src/brand-page-maker/components/navigation/Navigation.mixin.ts +1 -0
- package/src/brand-page-maker/components/rich-text-editor/RichTextEditor.vue +3 -1
- package/src/brand-page-maker/components/sensitive-content/SensitiveContent.vue +1 -4
- package/src/brand-page-maker/components/seo-settings/DeleteDomainModal.vue +1 -1
- package/src/brand-page-maker/components/seo-settings/SeoPageSettings.mixin.ts +1 -0
- package/src/brand-page-maker/components/seo-settings/SeoPageSettings.vue +1 -1
- package/src/brand-page-maker/components/seo-settings/UrlSettings.mixin.ts +0 -1
- package/src/brand-page-maker/components/seo-settings/UrlSettings.vue +0 -1
- package/src/brand-page-maker/components/seo-settings/UseExistingDomainModal.vue +1 -5
- package/src/brand-page-maker/components/shop/AddOrEditProductContainer.vue +1 -1
- package/src/brand-page-maker/components/shop/ReplaceImageSettingsForShop.vue +1 -1
- package/src/brand-page-maker/components/social-share/SocialShare.vue +1 -1
- package/src/brand-page-maker/components/template-preview/TemplatePreview.mixin.ts +22 -8
- package/src/brand-page-maker/components/template-preview/TemplatePreview.vue +5 -10
- package/src/brand-page-maker/components/template-preview/TemplatePreviewAiBadge.vue +12 -0
- package/src/brand-page-maker/components/video-play/VideoPlayButton.vue +1 -1
- package/src/brand-page-maker/composables/ai-chat/types.ts +6 -0
- package/src/brand-page-maker/composables/ai-chat/ui-actions.test.ts +80 -0
- package/src/brand-page-maker/composables/ai-chat/ui-actions.ts +58 -0
- package/src/brand-page-maker/composables/ai-chat/useAiWebsiteBuilderChat.ts +308 -262
- package/src/brand-page-maker/composables/rich-text-editor/useRichTextEditor.ts +6 -6
- package/src/brand-page-maker/composables/useEventTracker.ts +1 -0
- package/src/brand-page-maker/constants/config-settings-constant.ts +5 -5
- package/src/brand-page-maker/convertors/text-image-display-style.convertor.ts +1 -1
- package/src/brand-page-maker/models/button-styles-config.ts +4 -2
- package/src/brand-page-maker/models/content-settings-configs.ts +4 -2
- package/src/brand-page-maker/models/navigation-style-configs.ts +5 -6
- package/src/brand-page-maker/stores/admin-logo-settings/admin-logo-settings-store.ts +0 -1
- package/src/brand-page-maker/stores/brandpage-container/brand-page-container-store.ts +8 -5
- package/src/brand-page-maker/stores/brandpage-maker/brandpage-maker-store.test.ts +1 -3
- package/src/brand-page-maker/stores/brandpage-maker/brandpage-maker-store.ts +12 -4
- package/src/brand-page-maker/stores/ui/ui-store.ts +16 -0
- package/src/brand-page-maker/utils/content-settings.util.ts +1 -1
- package/src/brand-page-maker/utils/rich-text-editor.util.ts +4 -4
- package/src/clients/ai-assistant-client.ts +7 -0
- package/src/clients/design-template-client.ts +3 -0
- package/src/clients/models.ts +2 -0
- package/src/composables/useSnapshot.ts +19 -22
- package/src/lib.ts +12 -0
- package/src/metadata-builder/builders/footer-builder.test.ts +130 -229
- package/src/metadata-builder/builders/footer-builder.ts +155 -90
- package/src/metadata-builder/builders/section-builders/image-gallery-builder.ts +88 -62
- package/src/metadata-builder/builders/section-builders/images-section-builder.ts +129 -66
- package/src/metadata-builder/builders/section-builders/shapes-section-builder.ts +160 -105
- package/src/metadata-builder/builders/section-builders/social-links-builder.ts +20 -65
- package/src/metadata-builder/builders/section-builders/testimonial-section-builder.ts +146 -83
- package/src/metadata-builder/builders/section-builders/text-section-builder.ts +122 -70
- package/src/metadata-builder/builders/section-field-utils.ts +1 -1
- package/src/metadata-builder/builders/shape-color-utils.ts +2 -2
- package/src/metadata-builder/parsers/ai-toolcall-parser.ts +7 -16
- package/src/metadata-builder/parsers/section-tool-arguments.ts +48 -66
- package/src/plugins/google-maps-plugin/google-maps-plugin.ts +8 -8
- package/src/shared/background-settings/components/BackgroundSettings.vue +1 -1
- package/src/shared/background-settings/components/background-color/BackgroundColorSettings.vue +1 -1
- package/src/shared/color-picker/components/ColorPicker.mixin.ts +2 -7
- package/src/shared/color-picker/components/ColorPickerSwatch.mixin.ts +1 -0
- package/src/shared/common/NumberInput.vue +1 -0
- package/src/shared/common/SideBarSettingsHeader.vue +2 -2
- package/src/shared/confirm-modal/ConfirmModal.mixin.ts +1 -0
- package/src/shared/content-settings/components/booking-url-field/BookingUrlField.vue +1 -0
- package/src/shared/content-settings/components/button-configuration-field/ButtonConfigurationField.vue +1 -0
- package/src/shared/content-settings/components/color-field/ColorField.vue +3 -10
- package/src/shared/content-settings/components/content-settings/ContentSettings.mixin.ts +1 -1
- package/src/shared/content-settings/components/content-settings/ContentSettingsLockedButton.vue +1 -0
- package/src/shared/content-settings/components/content-settings-item/ContentSettingsItem.mixin.ts +5 -0
- package/src/shared/content-settings/components/content-settings-item/ContentSettingsItemField.mixin.ts +1 -14
- package/src/shared/content-settings/components/focused-content-item-settings/FocusedContentItemSettings.mixin.ts +4 -6
- package/src/shared/content-settings/components/icon-library/IconLibrary.mixin.ts +1 -0
- package/src/shared/content-settings/components/items-field/ItemsField.mixin.ts +1 -1
- package/src/shared/content-settings/components/logo-selection-field/LogoSelectionField.vue +1 -1
- package/src/shared/content-settings/components/logo-size-field/LogoSizeSliderField.vue +1 -1
- package/src/shared/content-settings/components/page-dropdown-field/PageDropdownField.vue +1 -1
- package/src/shared/content-settings/components/personalisation-role-field/PersonalisationRoleField.vue +4 -4
- package/src/shared/content-settings/components/text-image-field/TextImageField.vue +2 -8
- package/src/shared/content-settings/components/text-items-field/TextItemsField.mixin.ts +1 -1
- package/src/shared/content-settings/models.ts +3 -2
- package/src/shared/content-settings/utils.ts +0 -1
- package/src/shared/dropzone-image-uploader/components/DropzoneImageUploader.vue +1 -0
- package/src/shared/ecommerce-settings/store/cart-store.test.ts +1 -1
- package/src/shared/font-family-selector/FontFamilySelector.mixin.ts +1 -0
- package/src/shared/image-gallery-style-settings/ImageGalleryStyleSettings.mixin.ts +1 -0
- package/src/shared/logo-settings/components/EditLogoSettings.mixin.ts +1 -1
- package/src/shared/logo-settings/components/LogoSettings.mixin.ts +0 -1
- package/src/shared/logo-settings/components/LogoSettingsHeader.mixin.ts +1 -0
- package/src/shared/logo-settings/components/LogoStyleSettingsWithState.vue +2 -2
- package/src/shared/logo-settings/components/LogoTemplateSearch.vue +1 -1
- package/src/shared/logo-settings/store/editable-logo-store.ts +1 -1
- package/src/shared/logo-settings/store/logo-settings-store.test.ts +4 -4
- package/src/shared/logo-versions/LogoVersions.mixin.ts +1 -0
- package/src/shared/models.ts +6 -0
- package/src/shared/my-designs/MyDesigns.mixin.ts +1 -0
- package/src/shared/my-uploads/MyMedia.mixin.ts +1 -0
- package/src/shared/my-uploads/MyMediaSelectionItem.vue +2 -1
- package/src/shared/my-uploads/MyUploads.mixin.ts +1 -0
- package/src/shared/my-uploads/models.ts +1 -2
- package/src/shared/navigation-style-settings/components/navigation-style-settings/NavigationStyleSettings.mixin.ts +1 -0
- package/src/shared/navigation-style-settings/components/navigation-style-settings/NavigationStyleSettings.vue +1 -1
- package/src/shared/page-settings/components/new-page-modal/NewPageModal.mixin.ts +0 -3
- package/src/shared/page-settings/components/page-settings/NestedDraggable.vue +1 -1
- package/src/shared/page-settings/components/page-settings/PageSettings.vue +1 -2
- package/src/shared/page-settings/components/page-settings-section-styles/HeaderDisplayStyle.vue +1 -1
- package/src/shared/page-settings/components/page-settings-section-styles/PageSettingsSectionStyles.mixin.ts +1 -1
- package/src/shared/page-settings/store/page-settings-store.test.ts +4 -8
- package/src/shared/publish-brand-page-with-state/PublishBrandPageModalWithState.mixin.ts +0 -1
- package/src/shared/shape-library/ShapeLibrary.vue +2 -2
- package/src/shared/style-settings/store/style-settings-store.ts +1 -1
- package/src/shared/template-settings/components/TemplatesSettings.mixin.ts +2 -2
- package/src/shared/template-settings/models.ts +1 -0
- package/src/shared/template-settings/store/template-settings-store.ts +105 -18
- package/src/shared/unsplash-library/UnsplashLibrary.vue +2 -6
- package/src/shared/video-library/VideoLibrary.vue +1 -1
- package/src/utils/build-asset-manifest.ts +12 -0
- package/src/utils/minify-brand-page-metadata.ts +7 -27
- package/lib/src/metadata-builder/builders/item-id-utils.d.ts +0 -54
- package/lib/src/metadata-builder/builders/item-id-utils.js +0 -96
- package/src/metadata-builder/builders/item-id-utils.test.ts +0 -184
- package/src/metadata-builder/builders/item-id-utils.ts +0 -117
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ref, computed, watch, nextTick
|
|
1
|
+
import { ref, computed, watch, nextTick } from 'vue';
|
|
2
2
|
import type { BrandPageModel } from '../../../brand-page/models';
|
|
3
3
|
import {
|
|
4
4
|
getInstance as getAiAssistantClient,
|
|
@@ -18,8 +18,8 @@ import {
|
|
|
18
18
|
type PlanItem,
|
|
19
19
|
} from '../../../clients/websocket-gateway-client';
|
|
20
20
|
import { minifyBrandPageMetadata } from '../../../utils/minify-brand-page-metadata';
|
|
21
|
-
import { ensureBrandPageItemIds } from '../../../metadata-builder/builders/item-id-utils';
|
|
22
21
|
import { buildAssetManifest } from '../../../utils/build-asset-manifest';
|
|
22
|
+
import cloneDeep from 'lodash.clonedeep';
|
|
23
23
|
import { usePageNavigationStore } from '../../../shared/page-navigation/store/page-navigation-store';
|
|
24
24
|
import { navigateToPageByPageId } from '../../routing';
|
|
25
25
|
import {
|
|
@@ -47,7 +47,9 @@ import type {
|
|
|
47
47
|
ThreadMessage,
|
|
48
48
|
TextThreadMessage,
|
|
49
49
|
SendMessageOptions,
|
|
50
|
+
AgentAction,
|
|
50
51
|
} from './types';
|
|
52
|
+
import { partitionAiToolCalls } from './ui-actions';
|
|
51
53
|
|
|
52
54
|
const BUILD_TIMEOUT_MS = 600000;
|
|
53
55
|
|
|
@@ -257,11 +259,6 @@ export function useAiWebsiteBuilderChat(): UseAiChatResult {
|
|
|
257
259
|
|
|
258
260
|
const buildMessagePayload = async (userPrompt: string) => {
|
|
259
261
|
const brandPageData = brandPageMakerStore.brandPageData;
|
|
260
|
-
|
|
261
|
-
// BP-5603: stamp stable uuid ids onto every nested item BEFORE minifying,
|
|
262
|
-
// so the id the AI is shown (and returns as `item_id`) is the exact id the
|
|
263
|
-
// executor matches when applying tool calls to this same live model.
|
|
264
|
-
ensureBrandPageItemIds(brandPageData);
|
|
265
262
|
const headerLogoDraftToken =
|
|
266
263
|
brandPageData.pageHeaderDesktop?.logoImage?.logoDraftToken ??
|
|
267
264
|
uiStore.logoDraftToken;
|
|
@@ -274,6 +271,7 @@ export function useAiWebsiteBuilderChat(): UseAiChatResult {
|
|
|
274
271
|
|
|
275
272
|
const websiteContext = {
|
|
276
273
|
metadata: minifyBrandPageMetadata(brandPageData, assets),
|
|
274
|
+
metadataFull: cloneDeep(brandPageData),
|
|
277
275
|
...(assets.length > 0 && { assets }),
|
|
278
276
|
websiteTemplateToken: containerStore.designTemplateToken,
|
|
279
277
|
...(containerStore.designDraftToken && {
|
|
@@ -467,7 +465,11 @@ export function useAiWebsiteBuilderChat(): UseAiChatResult {
|
|
|
467
465
|
const callApiBuildAsync = async (
|
|
468
466
|
userPrompt: string,
|
|
469
467
|
userMessageId: string,
|
|
470
|
-
): Promise<{
|
|
468
|
+
): Promise<{
|
|
469
|
+
text: string | null;
|
|
470
|
+
isError?: boolean;
|
|
471
|
+
actions?: AgentAction[];
|
|
472
|
+
}> => {
|
|
471
473
|
const connectionId = await ensureConnectedAsync();
|
|
472
474
|
const wsClient = activeBuildWsClient!;
|
|
473
475
|
|
|
@@ -538,296 +540,323 @@ export function useAiWebsiteBuilderChat(): UseAiChatResult {
|
|
|
538
540
|
});
|
|
539
541
|
}
|
|
540
542
|
|
|
541
|
-
return new Promise<{
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
543
|
+
return new Promise<{
|
|
544
|
+
text: string | null;
|
|
545
|
+
isError?: boolean;
|
|
546
|
+
actions?: AgentAction[];
|
|
547
|
+
}>((resolve, reject) => {
|
|
548
|
+
let settled = false;
|
|
549
|
+
let retryCount = 0;
|
|
550
|
+
let lastAiMessage: string | null = null;
|
|
551
|
+
let lastActions: AgentAction[] | undefined;
|
|
552
|
+
let handler: ((msg: WebSocketMessage) => void) | null = null;
|
|
553
|
+
// Vacant-slot queue scoped to this build session. Persists across
|
|
554
|
+
// retry rounds so a failed CREATE returns to its planned slot via
|
|
555
|
+
// a synthesised `move_before_content_id`.
|
|
556
|
+
const vacantSlots: VacantSlotMap = new Map();
|
|
557
|
+
|
|
558
|
+
const finishBuild = () => {
|
|
559
|
+
aiThreadStore.isBuildInProgress = false;
|
|
560
|
+
wsClient.setBuildActive(false);
|
|
561
|
+
wsClient.stopResponseHeartbeat();
|
|
562
|
+
|
|
563
|
+
if (handler) wsClient.offMessage(handler);
|
|
564
|
+
};
|
|
562
565
|
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
reject(new Error('Build timeout'));
|
|
566
|
-
}, BUILD_TIMEOUT_MS);
|
|
566
|
+
const timeout = setTimeout(() => {
|
|
567
|
+
if (settled) return;
|
|
567
568
|
|
|
568
|
-
|
|
569
|
-
|
|
569
|
+
settled = true;
|
|
570
|
+
finishBuild();
|
|
571
|
+
reject(new Error('Build timeout'));
|
|
572
|
+
}, BUILD_TIMEOUT_MS);
|
|
570
573
|
|
|
571
|
-
|
|
572
|
-
|
|
574
|
+
// Transition the build to "done" exactly once (idempotent). Returns
|
|
575
|
+
// false when already settled, so callers can early-return.
|
|
576
|
+
const markDone = (): boolean => {
|
|
577
|
+
if (settled) return false;
|
|
573
578
|
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
finishBuild();
|
|
578
|
-
resolve({ text: null });
|
|
579
|
+
settled = true;
|
|
580
|
+
clearTimeout(timeout);
|
|
581
|
+
finishBuild();
|
|
579
582
|
|
|
580
|
-
|
|
581
|
-
|
|
583
|
+
return true;
|
|
584
|
+
};
|
|
582
585
|
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
586
|
+
// The single terminal path. Every resolve goes through here, so "where
|
|
587
|
+
// does this Promise settle?" has one answer.
|
|
588
|
+
const settle = (result: {
|
|
589
|
+
text: string | null;
|
|
590
|
+
isError?: boolean;
|
|
591
|
+
actions?: AgentAction[];
|
|
592
|
+
}): void => {
|
|
593
|
+
if (markDone()) resolve(result);
|
|
594
|
+
};
|
|
587
595
|
|
|
588
|
-
|
|
589
|
-
|
|
596
|
+
// Streaming progress frames mutate the in-flight typing bubble and never
|
|
597
|
+
// settle the build. Returns true when `msg` was a progress frame.
|
|
598
|
+
const applyProgressUpdate = (msg: WebSocketMessage): boolean => {
|
|
599
|
+
if (msg.type === 'chat_started' && msg.message) {
|
|
600
|
+
withTypingMessage((m) => {
|
|
601
|
+
m.initialMessage = msg.message;
|
|
602
|
+
});
|
|
590
603
|
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
if (!m.planItems) m.planItems = msg.items as PlanItem[];
|
|
594
|
-
});
|
|
604
|
+
return true;
|
|
605
|
+
}
|
|
595
606
|
|
|
596
|
-
|
|
597
|
-
|
|
607
|
+
if (msg.type === 'plan_announced' && msg.items) {
|
|
608
|
+
withTypingMessage((m) => {
|
|
609
|
+
if (!m.planItems) m.planItems = msg.items as PlanItem[];
|
|
610
|
+
});
|
|
598
611
|
|
|
599
|
-
|
|
600
|
-
|
|
612
|
+
return true;
|
|
613
|
+
}
|
|
601
614
|
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
m.completedItemIds = [
|
|
605
|
-
...(m.completedItemIds ?? []),
|
|
606
|
-
itemId,
|
|
607
|
-
];
|
|
608
|
-
}
|
|
609
|
-
});
|
|
615
|
+
if (msg.type === 'item_complete' && msg.itemId) {
|
|
616
|
+
const itemId = msg.itemId;
|
|
610
617
|
|
|
611
|
-
|
|
618
|
+
withTypingMessage((m) => {
|
|
619
|
+
if (!m.completedItemIds?.includes(itemId)) {
|
|
620
|
+
m.completedItemIds = [...(m.completedItemIds ?? []), itemId];
|
|
612
621
|
}
|
|
622
|
+
});
|
|
613
623
|
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
[]) as AiAssistantToolCall[];
|
|
617
|
-
const aiResponse: AiAssistantResponse = {
|
|
618
|
-
threadId: aiThreadStore.threadId || '',
|
|
619
|
-
toolCalls,
|
|
620
|
-
message: msg.message || null,
|
|
621
|
-
type: 'tool_calls',
|
|
622
|
-
totalPaidToolCalls: 0,
|
|
623
|
-
timestamp: Date.now(),
|
|
624
|
-
};
|
|
625
|
-
|
|
626
|
-
(async () => {
|
|
627
|
-
try {
|
|
628
|
-
// No tool calls = build cycle complete (success, max retries, or no retryable sections)
|
|
629
|
-
if (toolCalls.length === 0) {
|
|
630
|
-
// Defence-in-depth: a server_response with no toolCalls AND
|
|
631
|
-
// no message text is a degenerate response — it means the
|
|
632
|
-
// backend graph reached END without producing anything
|
|
633
|
-
// actionable. The server-side fix in stream_with_push now
|
|
634
|
-
// converts this to a build_error frame, but if a future
|
|
635
|
-
// regression slips through we must NOT show "Your website
|
|
636
|
-
// has been updated" — that hides real failures from users
|
|
637
|
-
// and from monitoring.
|
|
638
|
-
const hasMeaningfulMessage = Boolean(
|
|
639
|
-
aiResponse.message || lastAiMessage,
|
|
640
|
-
);
|
|
641
|
-
|
|
642
|
-
if (!hasMeaningfulMessage) {
|
|
643
|
-
raygunUtil.safeSendRaygunError(
|
|
644
|
-
new Error(
|
|
645
|
-
'AI build server_response had empty toolCalls and empty message',
|
|
646
|
-
),
|
|
647
|
-
{
|
|
648
|
-
tags: [
|
|
649
|
-
'feature:ai-website-builder',
|
|
650
|
-
'failure:degenerate_server_response',
|
|
651
|
-
],
|
|
652
|
-
customData: {
|
|
653
|
-
build_id: aiThreadStore.buildId ?? null,
|
|
654
|
-
thread_id: aiThreadStore.threadId ?? null,
|
|
655
|
-
},
|
|
656
|
-
},
|
|
657
|
-
);
|
|
658
|
-
settled = true;
|
|
659
|
-
clearTimeout(timeout);
|
|
660
|
-
finishBuild();
|
|
661
|
-
resolve({
|
|
662
|
-
text: 'Something went wrong while updating your website. Please try again.',
|
|
663
|
-
isError: true,
|
|
664
|
-
});
|
|
665
|
-
|
|
666
|
-
return;
|
|
667
|
-
}
|
|
668
|
-
|
|
669
|
-
settled = true;
|
|
670
|
-
clearTimeout(timeout);
|
|
671
|
-
finishBuild();
|
|
672
|
-
resolve({
|
|
673
|
-
text: aiResponse.message || lastAiMessage || '',
|
|
674
|
-
});
|
|
675
|
-
|
|
676
|
-
return;
|
|
677
|
-
}
|
|
678
|
-
|
|
679
|
-
// Tool calls present — apply locally and submit results back
|
|
680
|
-
const { toolResults, aiMessage } =
|
|
681
|
-
await applyToolCallsAsync(
|
|
682
|
-
aiResponse,
|
|
683
|
-
userMessageId,
|
|
684
|
-
vacantSlots,
|
|
685
|
-
);
|
|
686
|
-
|
|
687
|
-
lastAiMessage = aiMessage;
|
|
688
|
-
|
|
689
|
-
// Submit all tool results (success + failure) so the AI pipeline
|
|
690
|
-
// persists ToolMessages matching every tool_call in the conversation.
|
|
691
|
-
const failedResults = toolResults.filter(
|
|
692
|
-
(tr) => tr.success !== 'success',
|
|
693
|
-
);
|
|
694
|
-
|
|
695
|
-
aiLogger.log('tool submission for results', {
|
|
696
|
-
total: toolResults.length,
|
|
697
|
-
failed: failedResults.length,
|
|
698
|
-
failedResults,
|
|
699
|
-
retryCount,
|
|
700
|
-
});
|
|
701
|
-
|
|
702
|
-
const submitResult =
|
|
703
|
-
await client.submitToolResultsBuildAsync(
|
|
704
|
-
aiThreadStore.threadId!,
|
|
705
|
-
{
|
|
706
|
-
toolCalls: toolResults,
|
|
707
|
-
agentType: AI_ASSISTANT_AGENT_TYPES.WEBSITE_BUILDER,
|
|
708
|
-
connectionId,
|
|
709
|
-
retryCount,
|
|
710
|
-
userPlan,
|
|
711
|
-
},
|
|
712
|
-
);
|
|
713
|
-
|
|
714
|
-
if (failedResults.length === 0) {
|
|
715
|
-
settled = true;
|
|
716
|
-
clearTimeout(timeout);
|
|
717
|
-
finishBuild();
|
|
718
|
-
resolve({
|
|
719
|
-
text: aiMessage || 'Your website has been updated.',
|
|
720
|
-
});
|
|
721
|
-
|
|
722
|
-
return;
|
|
723
|
-
}
|
|
724
|
-
|
|
725
|
-
// Update buildId so the handler matches subsequent WS messages
|
|
726
|
-
if (submitResult.buildId) {
|
|
727
|
-
aiThreadStore.buildId = submitResult.buildId;
|
|
728
|
-
}
|
|
729
|
-
|
|
730
|
-
// eslint-disable-next-line no-plusplus
|
|
731
|
-
retryCount++;
|
|
732
|
-
} catch (err) {
|
|
733
|
-
aiLogger.log('server_response apply error', { err });
|
|
734
|
-
// Client-side apply failure (metadata builder, tool-call parser,
|
|
735
|
-
// missing field, etc.) — server thinks the build succeeded but we
|
|
736
|
-
// couldn't materialise the changes. Mark the chat bubble as an
|
|
737
|
-
// error so the user sees the real outcome, and report to Raygun
|
|
738
|
-
// so the failure is visible in monitoring (the server didn't see it).
|
|
739
|
-
raygunUtil.safeSendRaygunError(
|
|
740
|
-
err instanceof Error
|
|
741
|
-
? err
|
|
742
|
-
: new Error('AI apply failed: non-Error thrown'),
|
|
743
|
-
{
|
|
744
|
-
tags: [
|
|
745
|
-
'feature:ai-website-builder',
|
|
746
|
-
'failure:apply_error',
|
|
747
|
-
'stage:client_apply',
|
|
748
|
-
],
|
|
749
|
-
customData: {
|
|
750
|
-
thread_id: aiThreadStore.threadId ?? null,
|
|
751
|
-
build_id: aiThreadStore.buildId ?? null,
|
|
752
|
-
},
|
|
753
|
-
},
|
|
754
|
-
);
|
|
755
|
-
settled = true;
|
|
756
|
-
clearTimeout(timeout);
|
|
757
|
-
finishBuild();
|
|
758
|
-
resolve({
|
|
759
|
-
text: "I couldn't apply those changes to your website. Please try again.",
|
|
760
|
-
isError: true,
|
|
761
|
-
});
|
|
762
|
-
}
|
|
763
|
-
})();
|
|
764
|
-
|
|
765
|
-
return;
|
|
766
|
-
}
|
|
624
|
+
return true;
|
|
625
|
+
}
|
|
767
626
|
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
clearTimeout(timeout);
|
|
771
|
-
finishBuild();
|
|
772
|
-
|
|
773
|
-
// Backend already reports the underlying pipeline failure to
|
|
774
|
-
// Raygun via its structured handler (stage:run_build /
|
|
775
|
-
// stage:section_builder / etc. with full Python traceback).
|
|
776
|
-
// We report the frontend's RECEIPT of the error frame as a
|
|
777
|
-
// separate signal — distinct tag, distinct grouping. This
|
|
778
|
-
// gives triangulation: both sides have entry → normal crash;
|
|
779
|
-
// frontend only → backend Raygun outage; backend only → WS
|
|
780
|
-
// frame didn't reach client (different bug shape).
|
|
781
|
-
const wsMsg = msg as {
|
|
782
|
-
type: string;
|
|
783
|
-
code?: string;
|
|
784
|
-
message?: string;
|
|
785
|
-
error?: string;
|
|
786
|
-
buildId?: string;
|
|
787
|
-
};
|
|
627
|
+
return false;
|
|
628
|
+
};
|
|
788
629
|
|
|
630
|
+
// Apply one round of build tool calls: settle on completion/failure, or
|
|
631
|
+
// bump retryCount so the handler processes the next round's frame.
|
|
632
|
+
const processServerResponse = async (
|
|
633
|
+
aiResponse: AiAssistantResponse,
|
|
634
|
+
): Promise<void> => {
|
|
635
|
+
const toolCalls = aiResponse.toolCalls ?? [];
|
|
636
|
+
|
|
637
|
+
try {
|
|
638
|
+
// No tool calls = build cycle complete (success, max retries, or no retryable sections).
|
|
639
|
+
if (toolCalls.length === 0) {
|
|
640
|
+
// Defence-in-depth: empty toolCalls AND empty message is a
|
|
641
|
+
// degenerate response (graph reached END producing nothing). Never
|
|
642
|
+
// show "Your website has been updated" — it hides real failures.
|
|
643
|
+
const hasMeaningfulMessage = Boolean(
|
|
644
|
+
aiResponse.message || lastAiMessage,
|
|
645
|
+
);
|
|
646
|
+
|
|
647
|
+
if (!hasMeaningfulMessage) {
|
|
789
648
|
raygunUtil.safeSendRaygunError(
|
|
790
649
|
new Error(
|
|
791
|
-
|
|
650
|
+
'AI build server_response had empty toolCalls and empty message',
|
|
792
651
|
),
|
|
793
652
|
{
|
|
794
653
|
tags: [
|
|
795
654
|
'feature:ai-website-builder',
|
|
796
|
-
'failure:
|
|
797
|
-
`frame_type:${wsMsg.type}`,
|
|
655
|
+
'failure:degenerate_server_response',
|
|
798
656
|
],
|
|
799
657
|
customData: {
|
|
800
|
-
|
|
801
|
-
message: wsMsg.message ?? null,
|
|
802
|
-
error: wsMsg.error ?? null,
|
|
803
|
-
build_id: wsMsg.buildId ?? null,
|
|
658
|
+
build_id: aiThreadStore.buildId ?? null,
|
|
804
659
|
thread_id: aiThreadStore.threadId ?? null,
|
|
805
660
|
},
|
|
806
661
|
},
|
|
807
662
|
);
|
|
808
|
-
|
|
809
|
-
|
|
663
|
+
settle({
|
|
664
|
+
text: 'Something went wrong while updating your website. Please try again.',
|
|
665
|
+
isError: true,
|
|
666
|
+
});
|
|
810
667
|
|
|
811
668
|
return;
|
|
812
669
|
}
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
670
|
+
|
|
671
|
+
// Mark settled BEFORE the await so concurrent frames are ignored.
|
|
672
|
+
if (!markDone()) return;
|
|
673
|
+
|
|
674
|
+
await snapshotStore.refreshSnapshotAsync();
|
|
675
|
+
resolve({
|
|
676
|
+
text: aiResponse.message || lastAiMessage || '',
|
|
677
|
+
actions: lastActions,
|
|
817
678
|
});
|
|
818
679
|
|
|
819
|
-
|
|
820
|
-
settled = true;
|
|
821
|
-
clearTimeout(timeout);
|
|
822
|
-
finishBuild();
|
|
823
|
-
resolve({ text: 'An error occurred during the build.' });
|
|
824
|
-
}
|
|
680
|
+
return;
|
|
825
681
|
}
|
|
682
|
+
|
|
683
|
+
// Tool calls present — apply locally and submit results back.
|
|
684
|
+
const { toolResults, aiMessage } = await applyToolCallsAsync(
|
|
685
|
+
aiResponse,
|
|
686
|
+
userMessageId,
|
|
687
|
+
vacantSlots,
|
|
688
|
+
);
|
|
689
|
+
|
|
690
|
+
lastAiMessage = aiMessage;
|
|
691
|
+
|
|
692
|
+
// Submit all tool results (success + failure) so the AI pipeline
|
|
693
|
+
// persists ToolMessages matching every tool_call in the conversation.
|
|
694
|
+
const failedResults = toolResults.filter(
|
|
695
|
+
(tr) => tr.success !== 'success',
|
|
696
|
+
);
|
|
697
|
+
|
|
698
|
+
aiLogger.log('tool submission for results', {
|
|
699
|
+
total: toolResults.length,
|
|
700
|
+
failed: failedResults.length,
|
|
701
|
+
failedResults,
|
|
702
|
+
retryCount,
|
|
703
|
+
});
|
|
704
|
+
|
|
705
|
+
const submitResult = await client.submitToolResultsBuildAsync(
|
|
706
|
+
aiThreadStore.threadId!,
|
|
707
|
+
{
|
|
708
|
+
toolCalls: toolResults,
|
|
709
|
+
agentType: AI_ASSISTANT_AGENT_TYPES.WEBSITE_BUILDER,
|
|
710
|
+
connectionId,
|
|
711
|
+
retryCount,
|
|
712
|
+
userPlan,
|
|
713
|
+
},
|
|
714
|
+
);
|
|
715
|
+
|
|
716
|
+
if (failedResults.length === 0) {
|
|
717
|
+
settle({
|
|
718
|
+
text: aiMessage || 'Your website has been updated.',
|
|
719
|
+
actions: lastActions,
|
|
720
|
+
});
|
|
721
|
+
|
|
722
|
+
return;
|
|
723
|
+
}
|
|
724
|
+
|
|
725
|
+
// Failed sections will retry: refresh buildId so the handler matches
|
|
726
|
+
// the next round's frames, and count the round.
|
|
727
|
+
if (submitResult.buildId) {
|
|
728
|
+
aiThreadStore.buildId = submitResult.buildId;
|
|
729
|
+
}
|
|
730
|
+
|
|
731
|
+
retryCount += 1;
|
|
732
|
+
} catch (err) {
|
|
733
|
+
aiLogger.log('server_response apply error', { err });
|
|
734
|
+
// Client-side apply failure (metadata builder, tool-call parser,
|
|
735
|
+
// missing field, etc.) — the server thinks the build succeeded but we
|
|
736
|
+
// couldn't materialise the changes. Surface it and report to Raygun
|
|
737
|
+
// (the server didn't see this failure).
|
|
738
|
+
raygunUtil.safeSendRaygunError(
|
|
739
|
+
err instanceof Error
|
|
740
|
+
? err
|
|
741
|
+
: new Error('AI apply failed: non-Error thrown'),
|
|
742
|
+
{
|
|
743
|
+
tags: [
|
|
744
|
+
'feature:ai-website-builder',
|
|
745
|
+
'failure:apply_error',
|
|
746
|
+
'stage:client_apply',
|
|
747
|
+
],
|
|
748
|
+
customData: {
|
|
749
|
+
thread_id: aiThreadStore.threadId ?? null,
|
|
750
|
+
build_id: aiThreadStore.buildId ?? null,
|
|
751
|
+
},
|
|
752
|
+
},
|
|
753
|
+
);
|
|
754
|
+
settle({
|
|
755
|
+
text: "I couldn't apply those changes to your website. Please try again.",
|
|
756
|
+
isError: true,
|
|
757
|
+
});
|
|
758
|
+
}
|
|
759
|
+
};
|
|
760
|
+
|
|
761
|
+
const handleBuildError = (msg: WebSocketMessage): void => {
|
|
762
|
+
if (!markDone()) return;
|
|
763
|
+
|
|
764
|
+
// Backend already reports the underlying pipeline failure to Raygun
|
|
765
|
+
// (with full traceback). We report the frontend's RECEIPT of the error
|
|
766
|
+
// frame as a separate signal — distinct tag/grouping — for triangulation:
|
|
767
|
+
// both sides → normal crash; frontend only → backend Raygun outage;
|
|
768
|
+
// backend only → WS frame didn't reach client.
|
|
769
|
+
const wsMsg = msg as {
|
|
770
|
+
type: string;
|
|
771
|
+
code?: string;
|
|
772
|
+
message?: string;
|
|
773
|
+
error?: string;
|
|
774
|
+
buildId?: string;
|
|
826
775
|
};
|
|
827
776
|
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
777
|
+
raygunUtil.safeSendRaygunError(
|
|
778
|
+
new Error(
|
|
779
|
+
`AI build ${wsMsg.type}: ${wsMsg.code ?? wsMsg.error ?? 'unknown'}`,
|
|
780
|
+
),
|
|
781
|
+
{
|
|
782
|
+
tags: [
|
|
783
|
+
'feature:ai-website-builder',
|
|
784
|
+
'failure:websocket_error_received',
|
|
785
|
+
`frame_type:${wsMsg.type}`,
|
|
786
|
+
],
|
|
787
|
+
customData: {
|
|
788
|
+
code: wsMsg.code ?? null,
|
|
789
|
+
message: wsMsg.message ?? null,
|
|
790
|
+
error: wsMsg.error ?? null,
|
|
791
|
+
build_id: wsMsg.buildId ?? null,
|
|
792
|
+
thread_id: aiThreadStore.threadId ?? null,
|
|
793
|
+
},
|
|
794
|
+
},
|
|
795
|
+
);
|
|
796
|
+
|
|
797
|
+
resolve({ text: pickWsErrorMessage(msg), isError: true });
|
|
798
|
+
};
|
|
799
|
+
|
|
800
|
+
// Single dispatch point: ignore stale/already-settled frames, then route
|
|
801
|
+
// by frame kind. Progress frames update the bubble; server_response and
|
|
802
|
+
// error frames are the only ones that can settle the build.
|
|
803
|
+
handler = (msg: WebSocketMessage) => {
|
|
804
|
+
if (settled) return;
|
|
805
|
+
|
|
806
|
+
try {
|
|
807
|
+
if (msg.buildId !== aiThreadStore.buildId) return;
|
|
808
|
+
|
|
809
|
+
if (isStopped.value) {
|
|
810
|
+
settle({ text: null });
|
|
811
|
+
|
|
812
|
+
return;
|
|
813
|
+
}
|
|
814
|
+
|
|
815
|
+
if (applyProgressUpdate(msg)) return;
|
|
816
|
+
|
|
817
|
+
if (msg.type === 'server_response') {
|
|
818
|
+
// CTA buttons (e.g. Upgrade) ride in toolCalls but are presentation,
|
|
819
|
+
// not page edits. Split them out so only real mutations reach the
|
|
820
|
+
// metadata-builder and the tool-result submission — a UI action must
|
|
821
|
+
// never be answered with a tool result (it isn't in the agent's
|
|
822
|
+
// conversation), or the next turn on the thread fails.
|
|
823
|
+
const { mutationToolCalls, actions } = partitionAiToolCalls(
|
|
824
|
+
(msg.toolCalls || []) as AiAssistantToolCall[],
|
|
825
|
+
);
|
|
826
|
+
|
|
827
|
+
if (actions.length) lastActions = actions;
|
|
828
|
+
|
|
829
|
+
void processServerResponse({
|
|
830
|
+
threadId: aiThreadStore.threadId || '',
|
|
831
|
+
toolCalls: mutationToolCalls,
|
|
832
|
+
message: msg.message || null,
|
|
833
|
+
type: 'tool_calls',
|
|
834
|
+
totalPaidToolCalls: 0,
|
|
835
|
+
timestamp: Date.now(),
|
|
836
|
+
});
|
|
837
|
+
|
|
838
|
+
return;
|
|
839
|
+
}
|
|
840
|
+
|
|
841
|
+
if (msg.type === 'server_error' || msg.type === 'build_error') {
|
|
842
|
+
handleBuildError(msg);
|
|
843
|
+
|
|
844
|
+
return;
|
|
845
|
+
}
|
|
846
|
+
} catch (err) {
|
|
847
|
+
aiLogger.log('Unexpected error in WS message handler', {
|
|
848
|
+
err,
|
|
849
|
+
type: msg.type,
|
|
850
|
+
});
|
|
851
|
+
settle({
|
|
852
|
+
text: 'An error occurred during the build.',
|
|
853
|
+
isError: true,
|
|
854
|
+
});
|
|
855
|
+
}
|
|
856
|
+
};
|
|
857
|
+
|
|
858
|
+
wsClient.onMessage(handler);
|
|
859
|
+
});
|
|
831
860
|
} catch (err) {
|
|
832
861
|
aiThreadStore.isBuildInProgress = false;
|
|
833
862
|
wsClient.setBuildActive(false);
|
|
@@ -927,6 +956,18 @@ export function useAiWebsiteBuilderChat(): UseAiChatResult {
|
|
|
927
956
|
if (result.isError) {
|
|
928
957
|
threadItems.value[messageIndex].isError = true;
|
|
929
958
|
}
|
|
959
|
+
|
|
960
|
+
// Attach agent-driven actions (e.g. upgrade CTA) only on successful
|
|
961
|
+
// (non-error) responses. Suppressed for premium users client-side as
|
|
962
|
+
// a defence-in-depth guard (server also vetoes via eligibility logic).
|
|
963
|
+
if (
|
|
964
|
+
!result.isError &&
|
|
965
|
+
result.actions?.length &&
|
|
966
|
+
!userStore.hasPremiumSubscription
|
|
967
|
+
) {
|
|
968
|
+
(threadItems.value[messageIndex] as TextThreadMessage).actions =
|
|
969
|
+
result.actions;
|
|
970
|
+
}
|
|
930
971
|
} else {
|
|
931
972
|
threadItems.value[messageIndex].text =
|
|
932
973
|
'Failed to apply changes. Please try again.';
|
|
@@ -1028,6 +1069,11 @@ export function useAiWebsiteBuilderChat(): UseAiChatResult {
|
|
|
1028
1069
|
completedItemIds:
|
|
1029
1070
|
(msg as TextThreadMessage).completedItemIds ?? [],
|
|
1030
1071
|
}),
|
|
1072
|
+
...(msg.type === 'text' &&
|
|
1073
|
+
!msg.isTyping &&
|
|
1074
|
+
(msg as TextThreadMessage).actions?.length && {
|
|
1075
|
+
actions: (msg as TextThreadMessage).actions,
|
|
1076
|
+
}),
|
|
1031
1077
|
} as Record<string, unknown>,
|
|
1032
1078
|
};
|
|
1033
1079
|
});
|