@designcrowd/library.brand-page 5.17.28 → 5.18.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/lib/src/{CreatedOnBrandCrowd-de-de-CJZpKPNH.js → CreatedOnBrandCrowd-de-de-xmkupPus.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-en-us-DkIa7iEb.js → CreatedOnBrandCrowd-en-us-Ck7EdTtb.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-es-es-CE2p6XHz.js → CreatedOnBrandCrowd-es-es-BC8sJuDH.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-fr-fr-BBjOZS3M.js → CreatedOnBrandCrowd-fr-ca-CN-UBe1q.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-fr-ca-BBjOZS3M.js → CreatedOnBrandCrowd-fr-fr-CN-UBe1q.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-pt-pt-Dayzl4BZ.js → CreatedOnBrandCrowd-pt-br-CajQyNkx.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-pt-br-Dayzl4BZ.js → CreatedOnBrandCrowd-pt-pt-CajQyNkx.js} +1 -1
- package/lib/src/{CreatedOnDcom-de-de-CFzDqfCb.js → CreatedOnDcom-de-de-BRCNMmDq.js} +1 -1
- package/lib/src/{CreatedOnDcom-en-us-C2jIPBDY.js → CreatedOnDcom-en-us-BzQDtZhc.js} +1 -1
- package/lib/src/{CreatedOnDcom-es-es-qejpzqho.js → CreatedOnDcom-es-es-D-qAM4Cd.js} +1 -1
- package/lib/src/{CreatedOnDcom-fr-ca-DMO9Ld7K.js → CreatedOnDcom-fr-ca-CZ1irFOc.js} +1 -1
- package/lib/src/{CreatedOnDcom-fr-fr-BFWN9qTP.js → CreatedOnDcom-fr-fr-Gb5BCF0N.js} +1 -1
- package/lib/src/{CreatedOnDcom-pt-br-CneD3ghF.js → CreatedOnDcom-pt-br-CAQV0q6o.js} +1 -1
- package/lib/src/{CreatedOnDcom-pt-pt-Cg1B7s0o.js → CreatedOnDcom-pt-pt-D6tQdQFh.js} +1 -1
- package/lib/src/brand-page/components/image-gallery/ImageGalleryModal.mixin.js +2 -2
- package/lib/src/brand-page/models/brand-page-context.model.d.ts +0 -2
- package/lib/src/brand-page/models/brand-page-context.model.js +1 -11
- package/lib/src/brand-page/models/index.d.ts +1 -0
- package/lib/src/brand-page/models/index.js +1 -0
- package/lib/src/brand-page/utils/color.util.js +23 -3
- package/lib/src/brand-page/utils/raygun.util.d.ts +5 -1
- package/lib/src/brand-page/utils/raygun.util.js +7 -2
- package/lib/src/brand-page/utils/svg-color.util.js +1 -2
- package/lib/src/brand-page/utils/view-model.util.js +1 -1
- package/lib/src/brand-page-maker/components/brand-page-maker/BrandPageMaker.mixin.d.ts +1 -31
- package/lib/src/brand-page-maker/components/brand-page-maker/__fixtures__/brand-page-examples.js +0 -2
- package/lib/src/brand-page-maker/components/brandpage-maker-page/BrandPageMakerPage.mixin.d.ts +2 -31
- package/lib/src/brand-page-maker/components/preview/Preview.mixin.d.ts +0 -14
- package/lib/src/brand-page-maker/components/quick-link-bar/QuickLinkBar.mixin.d.ts +0 -28
- package/lib/src/brand-page-maker/components/seo-settings/SeoPageSettings.mixin.d.ts +0 -28
- package/lib/src/brand-page-maker/components/seo-settings/UrlSettings.mixin.d.ts +0 -28
- package/lib/src/brand-page-maker/components/seo-settings/UseExistingDomainModal.mixin.d.ts +0 -28
- package/lib/src/brand-page-maker/components/template-preview/TemplatePreview.mixin.d.ts +0 -28
- package/lib/src/brand-page-maker/components/upgrade-to-premium-button/UpgradeToPremiumButton.mixin.d.ts +0 -28
- package/lib/src/brand-page-maker/composables/ai-chat/aiErrorCopy.d.ts +35 -0
- package/lib/src/brand-page-maker/composables/ai-chat/aiErrorCopy.js +108 -0
- package/lib/src/brand-page-maker/composables/ai-chat/{useAiChat.d.ts → types.d.ts} +5 -13
- package/lib/src/brand-page-maker/composables/ai-chat/types.js +1 -0
- package/lib/src/brand-page-maker/composables/ai-chat/useAiMetadataBuilder.d.ts +19 -0
- package/lib/src/brand-page-maker/composables/ai-chat/useAiMetadataBuilder.js +1 -0
- package/lib/src/brand-page-maker/composables/ai-chat/useAiWebsiteBuilderChat.d.ts +1 -1
- package/lib/src/brand-page-maker/composables/ai-chat/useAiWebsiteBuilderChat.js +488 -82
- package/lib/src/brand-page-maker/composables/rich-text-editor/useRichTextEditor.js +5 -5
- package/lib/src/brand-page-maker/composables/useEventTracker.d.ts +6 -16
- package/lib/src/brand-page-maker/composables/useEventTracker.js +19 -21
- package/lib/src/brand-page-maker/constants/sidebar-constant.d.ts +0 -1
- package/lib/src/brand-page-maker/constants/sidebar-constant.js +7 -15
- package/lib/src/brand-page-maker/convertors/image-aspect-ratio.convertor.js +2 -2
- package/lib/src/brand-page-maker/convertors/text-size-value.convertor.js +3 -1
- package/lib/src/brand-page-maker/stores/ai-checkpoint/ai-checkpoint-store.d.ts +30660 -0
- package/lib/src/brand-page-maker/stores/ai-checkpoint/ai-checkpoint-store.js +34 -0
- package/lib/src/brand-page-maker/stores/ai-thread/ai-website-builder-thread-store.d.ts +1 -1
- package/lib/src/brand-page-maker/stores/brandpage-container/brand-page-container-store.d.ts +0 -28
- package/lib/src/brand-page-maker/stores/brandpage-maker/brandpage-maker-store.js +42 -2
- package/lib/src/brand-page-maker/stores/index.d.ts +1 -1
- package/lib/src/brand-page-maker/stores/index.js +1 -1
- package/lib/src/brand-page-maker/stores/user/user-store.js +0 -1
- package/lib/src/bundled-translations-CnareLWC.js +175 -0
- package/lib/src/bundled-translations.de-DE-2Ys7epLO.js +175 -0
- package/lib/src/bundled-translations.es-ES-Cjp-G8rT.js +175 -0
- package/lib/src/bundled-translations.fr-CA-CsaW4Oae.js +175 -0
- package/lib/src/bundled-translations.fr-FR-DIT2dd8J.js +175 -0
- package/lib/src/bundled-translations.pt-BR-BamoBpDW.js +175 -0
- package/lib/src/bundled-translations.pt-PT-C9A4hY_e.js +175 -0
- package/lib/src/bundles/bundled-translations.de-DE.json +1 -20
- package/lib/src/bundles/bundled-translations.es-ES.json +1 -20
- package/lib/src/bundles/bundled-translations.fr-CA.json +1 -20
- package/lib/src/bundles/bundled-translations.fr-FR.json +1 -20
- package/lib/src/bundles/bundled-translations.json +1 -20
- package/lib/src/bundles/bundled-translations.pt-BR.json +1 -20
- package/lib/src/bundles/bundled-translations.pt-PT.json +1 -20
- package/lib/src/clients/ai-assistant-client.d.ts +30 -29
- package/lib/src/clients/ai-assistant-client.js +16 -16
- package/lib/src/clients/design-template-client.d.ts +0 -2
- package/lib/src/clients/design-template-client.js +0 -38
- package/lib/src/clients/websocket-gateway-client.d.ts +9 -1
- package/lib/src/composables/useTranslate.d.ts +2 -1
- package/lib/src/composables/useTranslate.js +2 -1
- package/lib/src/constants/ui.d.ts +0 -1
- package/lib/src/css/library.brand-page-brandCrowd.min.css +225 -134
- package/lib/src/css/library.brand-page-brandPage.min.css +227 -121
- package/lib/src/css/library.brand-page-designCom.min.css +225 -134
- package/lib/src/css/library.brand-page-preview.min.css +225 -118
- package/lib/src/index.d.ts +1 -1
- package/lib/src/index.mjs +1 -1
- package/lib/src/{lib-33w_DBny.js → lib-CSRUPpSo.js} +30887 -29395
- package/lib/src/metadata-builder/ai-metadata-executor.d.ts +21 -0
- package/lib/src/metadata-builder/ai-metadata-executor.js +56 -3
- package/lib/src/metadata-builder/builders/add-page-builder.d.ts +2 -4
- package/lib/src/metadata-builder/builders/add-page-builder.js +5 -8
- package/lib/src/metadata-builder/builders/footer-builder.d.ts +11 -0
- package/lib/src/metadata-builder/builders/footer-builder.js +151 -0
- package/lib/src/metadata-builder/builders/global-styles-builder.d.ts +15 -0
- package/lib/src/metadata-builder/builders/global-styles-builder.js +129 -0
- package/lib/src/metadata-builder/builders/header-builder.d.ts +11 -0
- package/lib/src/metadata-builder/builders/header-builder.js +167 -0
- package/lib/src/metadata-builder/builders/rename-page-builder.d.ts +12 -0
- package/lib/src/metadata-builder/builders/rename-page-builder.js +49 -0
- package/lib/src/metadata-builder/builders/section-builders/about-section-builder.d.ts +2 -0
- package/lib/src/metadata-builder/builders/section-builders/about-section-builder.js +44 -4
- package/lib/src/metadata-builder/builders/section-builders/banner-section-builder.d.ts +2 -0
- package/lib/src/metadata-builder/builders/section-builders/banner-section-builder.js +70 -6
- package/lib/src/metadata-builder/builders/section-builders/base-section-builder.d.ts +36 -4
- package/lib/src/metadata-builder/builders/section-builders/base-section-builder.js +102 -12
- package/lib/src/metadata-builder/builders/section-builders/booking-section-builder.d.ts +8 -0
- package/lib/src/metadata-builder/builders/section-builders/booking-section-builder.js +50 -0
- package/lib/src/metadata-builder/builders/section-builders/button-section-builder.d.ts +2 -0
- package/lib/src/metadata-builder/builders/section-builders/button-section-builder.js +5 -1
- package/lib/src/metadata-builder/builders/section-builders/contact-form-builder.d.ts +2 -0
- package/lib/src/metadata-builder/builders/section-builders/contact-form-builder.js +47 -3
- package/lib/src/metadata-builder/builders/section-builders/delete-section-builder.d.ts +2 -1
- package/lib/src/metadata-builder/builders/section-builders/delete-section-builder.js +5 -2
- package/lib/src/metadata-builder/builders/section-builders/divider-section-builder.d.ts +2 -0
- package/lib/src/metadata-builder/builders/section-builders/divider-section-builder.js +11 -1
- package/lib/src/metadata-builder/builders/section-builders/image-gallery-builder.d.ts +2 -0
- package/lib/src/metadata-builder/builders/section-builders/image-gallery-builder.js +52 -13
- package/lib/src/metadata-builder/builders/section-builders/images-section-builder.d.ts +2 -0
- package/lib/src/metadata-builder/builders/section-builders/images-section-builder.js +47 -17
- package/lib/src/metadata-builder/builders/section-builders/index.d.ts +1 -0
- package/lib/src/metadata-builder/builders/section-builders/index.js +1 -0
- package/lib/src/metadata-builder/builders/section-builders/mailing-list-builder.d.ts +2 -0
- package/lib/src/metadata-builder/builders/section-builders/mailing-list-builder.js +20 -2
- package/lib/src/metadata-builder/builders/section-builders/mailing-list-section-builder.d.ts +2 -0
- package/lib/src/metadata-builder/builders/section-builders/mailing-list-section-builder.js +20 -2
- package/lib/src/metadata-builder/builders/section-builders/profile-section-builder.d.ts +2 -0
- package/lib/src/metadata-builder/builders/section-builders/profile-section-builder.js +36 -2
- package/lib/src/metadata-builder/builders/section-builders/shapes-section-builder.d.ts +2 -0
- package/lib/src/metadata-builder/builders/section-builders/shapes-section-builder.js +70 -27
- package/lib/src/metadata-builder/builders/section-builders/social-links-builder.d.ts +2 -0
- package/lib/src/metadata-builder/builders/section-builders/social-links-builder.js +7 -2
- package/lib/src/metadata-builder/builders/section-builders/testimonial-section-builder.d.ts +2 -0
- package/lib/src/metadata-builder/builders/section-builders/testimonial-section-builder.js +91 -26
- package/lib/src/metadata-builder/builders/section-builders/text-section-builder.d.ts +2 -0
- package/lib/src/metadata-builder/builders/section-builders/text-section-builder.js +69 -31
- package/lib/src/metadata-builder/builders/section-content-factory.d.ts +2 -2
- package/lib/src/metadata-builder/builders/section-content-factory.js +8 -2
- package/lib/src/metadata-builder/builders/section-field-maps.js +30 -2
- package/lib/src/metadata-builder/builders/section-field-utils.d.ts +46 -7
- package/lib/src/metadata-builder/builders/section-field-utils.js +86 -62
- package/lib/src/metadata-builder/builders/section-rules/about-section.rules.d.ts +2 -0
- package/lib/src/metadata-builder/builders/section-rules/about-section.rules.js +20 -0
- package/lib/src/metadata-builder/builders/section-rules/add-page.rules.d.ts +7 -0
- package/lib/src/metadata-builder/builders/section-rules/add-page.rules.js +8 -0
- package/lib/src/metadata-builder/builders/section-rules/banner-section.rules.d.ts +2 -0
- package/lib/src/metadata-builder/builders/section-rules/banner-section.rules.js +27 -0
- package/lib/src/metadata-builder/builders/section-rules/booking-section.rules.d.ts +2 -0
- package/lib/src/metadata-builder/builders/section-rules/booking-section.rules.js +16 -0
- package/lib/src/metadata-builder/builders/section-rules/button-section.rules.d.ts +2 -0
- package/lib/src/metadata-builder/builders/section-rules/button-section.rules.js +13 -0
- package/lib/src/metadata-builder/builders/section-rules/contact-form.rules.d.ts +2 -0
- package/lib/src/metadata-builder/builders/section-rules/contact-form.rules.js +16 -0
- package/lib/src/metadata-builder/builders/section-rules/divider-section.rules.d.ts +2 -0
- package/lib/src/metadata-builder/builders/section-rules/divider-section.rules.js +7 -0
- package/lib/src/metadata-builder/builders/section-rules/footer.rules.d.ts +4 -0
- package/lib/src/metadata-builder/builders/section-rules/footer.rules.js +5 -0
- package/lib/src/metadata-builder/builders/section-rules/global-styles.rules.d.ts +6 -0
- package/lib/src/metadata-builder/builders/section-rules/global-styles.rules.js +26 -0
- package/lib/src/metadata-builder/builders/section-rules/header.rules.d.ts +4 -0
- package/lib/src/metadata-builder/builders/section-rules/header.rules.js +41 -0
- package/lib/src/metadata-builder/builders/section-rules/image-gallery.rules.d.ts +2 -0
- package/lib/src/metadata-builder/builders/section-rules/image-gallery.rules.js +10 -0
- package/lib/src/metadata-builder/builders/section-rules/images-section.rules.d.ts +2 -0
- package/lib/src/metadata-builder/builders/section-rules/images-section.rules.js +31 -0
- package/lib/src/metadata-builder/builders/section-rules/mailing-list.rules.d.ts +2 -0
- package/lib/src/metadata-builder/builders/section-rules/mailing-list.rules.js +11 -0
- package/lib/src/metadata-builder/builders/section-rules/profile.rules.d.ts +2 -0
- package/lib/src/metadata-builder/builders/section-rules/profile.rules.js +14 -0
- package/lib/src/metadata-builder/builders/section-rules/rename-page.rules.d.ts +7 -0
- package/lib/src/metadata-builder/builders/section-rules/rename-page.rules.js +8 -0
- package/lib/src/metadata-builder/builders/section-rules/shapes-section.rules.d.ts +2 -0
- package/lib/src/metadata-builder/builders/section-rules/shapes-section.rules.js +27 -0
- package/lib/src/metadata-builder/builders/section-rules/social-links.rules.d.ts +2 -0
- package/lib/src/metadata-builder/builders/section-rules/social-links.rules.js +9 -0
- package/lib/src/metadata-builder/builders/section-rules/testimonial-section.rules.d.ts +7 -0
- package/lib/src/metadata-builder/builders/section-rules/testimonial-section.rules.js +26 -0
- package/lib/src/metadata-builder/builders/section-rules/text-section.rules.d.ts +2 -0
- package/lib/src/metadata-builder/builders/section-rules/text-section.rules.js +14 -0
- package/lib/src/metadata-builder/builders/shape-color-utils.d.ts +26 -0
- package/lib/src/metadata-builder/builders/shape-color-utils.js +52 -0
- package/lib/src/metadata-builder/builders/undo-builder.d.ts +48 -0
- package/lib/src/metadata-builder/builders/undo-builder.js +58 -0
- package/lib/src/metadata-builder/builders/update-content-text-style-builder.js +5 -1
- package/lib/src/metadata-builder/helpers/rte.helpers.d.ts +15 -4
- package/lib/src/metadata-builder/helpers/rte.helpers.js +24 -10
- package/lib/src/metadata-builder/metadata-executor.d.ts +2 -1
- package/lib/src/metadata-builder/metadata-executor.js +32 -5
- package/lib/src/metadata-builder/models.d.ts +26 -1
- package/lib/src/metadata-builder/models.js +14 -1
- package/lib/src/metadata-builder/parsers/ai-toolcall-parser.d.ts +144 -0
- package/lib/src/metadata-builder/parsers/ai-toolcall-parser.js +17 -0
- package/lib/src/metadata-builder/parsers/section-tool-arguments.d.ts +113 -24
- package/lib/src/metadata-builder/parsers/section-tool-arguments.js +5 -1
- package/lib/src/metadata-builder/sanitizers/rte-schema-check.d.ts +22 -0
- package/lib/src/metadata-builder/sanitizers/rte-schema-check.js +84 -0
- package/lib/src/metadata-builder/sanitizers/sanitizer-rules.d.ts +47 -0
- package/lib/src/metadata-builder/sanitizers/sanitizer-rules.js +60 -0
- package/lib/src/metadata-builder/sanitizers/section-args-validator.d.ts +41 -0
- package/lib/src/metadata-builder/sanitizers/section-args-validator.js +274 -0
- package/lib/src/shared/content-settings/components/content-settings/ContentSettings.mixin.d.ts +2 -1
- package/lib/src/shared/content-settings/components/content-settings/ContentSettings.mixin.js +2 -16
- package/lib/src/shared/content-settings/components/content-settings/ContentSettings.stories.js +0 -1
- package/lib/src/shared/content-settings/components/content-settings/ReplaceImageSettingsForContent.mixin.d.ts +2 -1
- package/lib/src/shared/content-settings/components/content-settings-item/ContentSettingsItem.mixin.d.ts +2 -3
- package/lib/src/shared/content-settings/components/content-settings-item/ContentSettingsItemField.mixin.d.ts +0 -4
- package/lib/src/shared/content-settings/components/content-settings-item/ContentSettingsItemField.mixin.js +6 -8
- package/lib/src/shared/content-settings/components/payment-config-field/PaymentConfigField.mixin.d.ts +0 -28
- package/lib/src/shared/logo-settings/components/EditLogoSettings.mixin.d.ts +2 -1
- package/lib/src/shared/logo-settings/components/LogoSettings.mixin.d.ts +0 -28
- package/lib/src/shared/navigation-style-settings/store/index.js +1 -0
- package/lib/src/shared/page-navigation/store/page-navigation-store.js +1 -20
- package/lib/src/shared/page-navigation/utils/nav-order-utils.d.ts +3 -0
- package/lib/src/shared/page-navigation/utils/nav-order-utils.js +20 -0
- package/lib/src/shared/page-settings/components/page-settings/PageSettings.mixin.d.ts +2 -30
- package/lib/src/shared/page-settings/components/page-settings-section-styles/PageSettingsSectionStyles.mixin.d.ts +0 -28
- package/lib/src/shared/publish-brand-page-with-state/PublishBrandPageModalWithState.mixin.d.ts +2 -43
- package/lib/src/shared/side-bar/components/SideBar.mixin.d.ts +0 -30
- package/lib/src/shared/side-bar/components/SideBarTabButton.mixin.d.ts +2 -3
- package/lib/src/shared/side-bar/store/side-bar-store.d.ts +0 -12
- package/lib/src/shared/side-bar/store/side-bar-store.js +0 -7
- package/lib/src/shared/style-settings/components/StyleSettings.mixin.d.ts +2 -29
- package/lib/src/shared/template-settings/components/TemplatesSettings.mixin.d.ts +2 -1
- package/lib/src/utils/build-asset-manifest.d.ts +26 -0
- package/lib/src/utils/build-asset-manifest.js +114 -0
- package/lib/src/utils/minify-brand-page-metadata.d.ts +49 -1
- package/lib/src/utils/minify-brand-page-metadata.js +216 -129
- package/package.json +1 -1
- package/src/brand-page/components/banner-section/BannerSection.vue +1 -1
- package/src/brand-page/components/contact-form/ContactForm.vue +29 -26
- package/src/brand-page/components/image-gallery/ImageGalleryModal.mixin.ts +6 -2
- package/src/brand-page/components/text-media-section/TextMediaSection.vue +1 -5
- package/src/brand-page/models/brand-page-context.model.ts +1 -25
- package/src/brand-page/models/index.ts +1 -0
- package/src/brand-page/utils/color.util.test.ts +48 -0
- package/src/brand-page/utils/color.util.ts +29 -4
- package/src/brand-page/utils/raygun.util.ts +11 -2
- package/src/brand-page/utils/svg-color.util.ts +1 -3
- package/src/brand-page/utils/view-model.util.ts +1 -4
- package/src/brand-page-maker/components/ai-text-edit/AiChatbox.vue +2 -2
- package/src/brand-page-maker/components/ai-text-edit/AiProgressFeed.vue +162 -0
- package/src/brand-page-maker/components/ai-text-edit/TextBubble.vue +57 -5
- package/src/brand-page-maker/components/ai-text-edit/i18n/generate-ai.de-DE.json +0 -20
- package/src/brand-page-maker/components/ai-text-edit/i18n/generate-ai.es-ES.json +0 -20
- package/src/brand-page-maker/components/ai-text-edit/i18n/generate-ai.fr-CA.json +0 -20
- package/src/brand-page-maker/components/ai-text-edit/i18n/generate-ai.fr-FR.json +0 -20
- package/src/brand-page-maker/components/ai-text-edit/i18n/generate-ai.json +0 -20
- package/src/brand-page-maker/components/ai-text-edit/i18n/generate-ai.pt-BR.json +0 -20
- package/src/brand-page-maker/components/ai-text-edit/i18n/generate-ai.pt-PT.json +0 -20
- package/src/brand-page-maker/components/ai-website-builder/AiWebsiteBuilder.vue +1 -2
- package/src/brand-page-maker/components/ai-website-builder/i18n/ai-website-builder.de-DE.json +3 -0
- package/src/brand-page-maker/components/ai-website-builder/i18n/ai-website-builder.es-ES.json +3 -0
- package/src/brand-page-maker/components/ai-website-builder/i18n/ai-website-builder.fr-CA.json +3 -0
- package/src/brand-page-maker/components/ai-website-builder/i18n/ai-website-builder.fr-FR.json +3 -0
- package/src/brand-page-maker/components/ai-website-builder/i18n/ai-website-builder.json +3 -0
- package/src/brand-page-maker/components/ai-website-builder/i18n/ai-website-builder.pt-BR.json +3 -0
- package/src/brand-page-maker/components/ai-website-builder/i18n/ai-website-builder.pt-PT.json +3 -0
- package/src/brand-page-maker/components/brand-page-maker/BrandPageMaker.vue +3 -28
- package/src/brand-page-maker/components/brand-page-maker/__fixtures__/brand-page-examples.ts +0 -2
- package/src/brand-page-maker/composables/ai-chat/aiErrorCopy.test.ts +229 -0
- package/src/brand-page-maker/composables/ai-chat/aiErrorCopy.ts +164 -0
- package/src/brand-page-maker/composables/ai-chat/types.ts +49 -0
- package/src/brand-page-maker/composables/ai-chat/useAiMetadataBuilder.ts +20 -0
- package/src/brand-page-maker/composables/ai-chat/useAiWebsiteBuilderChat.ts +651 -94
- package/src/brand-page-maker/composables/rich-text-editor/useRichTextEditor.ts +9 -9
- package/src/brand-page-maker/composables/useEventTracker.ts +31 -25
- package/src/brand-page-maker/constants/sidebar-constant.ts +7 -15
- package/src/brand-page-maker/convertors/image-aspect-ratio.convertor.ts +2 -2
- package/src/brand-page-maker/convertors/text-size-value.convertor.ts +3 -3
- package/src/brand-page-maker/stores/ai-checkpoint/ai-checkpoint-store.ts +54 -0
- package/src/brand-page-maker/stores/brandpage-maker/brandpage-maker-store.ts +76 -0
- package/src/brand-page-maker/stores/index.ts +1 -1
- package/src/brand-page-maker/stores/user/user-store.ts +0 -1
- package/src/bundles/bundled-translations.de-DE.json +1 -20
- package/src/bundles/bundled-translations.es-ES.json +1 -20
- package/src/bundles/bundled-translations.fr-CA.json +1 -20
- package/src/bundles/bundled-translations.fr-FR.json +1 -20
- package/src/bundles/bundled-translations.json +1 -20
- package/src/bundles/bundled-translations.pt-BR.json +1 -20
- package/src/bundles/bundled-translations.pt-PT.json +1 -20
- package/src/clients/ai-assistant-client.ts +59 -46
- package/src/clients/design-template-client.ts +0 -66
- package/src/clients/websocket-gateway-client.ts +17 -1
- package/src/composables/useTranslate.ts +3 -0
- package/src/constants/ui.ts +0 -1
- package/src/lib.ts +1 -0
- package/src/metadata-builder/ai-metadata-executor.ts +94 -1
- package/src/metadata-builder/builders/add-page-builder.ts +9 -13
- package/src/metadata-builder/builders/footer-builder.test.ts +76 -0
- package/src/metadata-builder/builders/footer-builder.ts +226 -0
- package/src/metadata-builder/builders/global-styles-builder.ts +187 -0
- package/src/metadata-builder/builders/header-builder.test.ts +106 -0
- package/src/metadata-builder/builders/header-builder.ts +254 -0
- package/src/metadata-builder/builders/rename-page-builder.ts +79 -0
- package/src/metadata-builder/builders/section-builders/about-section-builder.ts +73 -5
- package/src/metadata-builder/builders/section-builders/banner-section-builder.ts +112 -7
- package/src/metadata-builder/builders/section-builders/base-section-builder.ts +149 -11
- package/src/metadata-builder/builders/section-builders/booking-section-builder.ts +87 -0
- package/src/metadata-builder/builders/section-builders/button-section-builder.ts +6 -1
- package/src/metadata-builder/builders/section-builders/contact-form-builder.ts +74 -4
- package/src/metadata-builder/builders/section-builders/delete-section-builder.ts +15 -1
- package/src/metadata-builder/builders/section-builders/divider-section-builder.ts +13 -1
- package/src/metadata-builder/builders/section-builders/image-gallery-builder.ts +91 -31
- package/src/metadata-builder/builders/section-builders/images-section-builder.ts +102 -48
- package/src/metadata-builder/builders/section-builders/index.ts +1 -0
- package/src/metadata-builder/builders/section-builders/mailing-list-builder.ts +38 -2
- package/src/metadata-builder/builders/section-builders/mailing-list-section-builder.ts +38 -2
- package/src/metadata-builder/builders/section-builders/profile-section-builder.ts +55 -3
- package/src/metadata-builder/builders/section-builders/shapes-section-builder.ts +170 -77
- package/src/metadata-builder/builders/section-builders/social-links-builder.test.ts +119 -0
- package/src/metadata-builder/builders/section-builders/social-links-builder.ts +13 -2
- package/src/metadata-builder/builders/section-builders/testimonial-section-builder.ts +178 -57
- package/src/metadata-builder/builders/section-builders/text-section-builder.ts +130 -30
- package/src/metadata-builder/builders/section-content-factory.ts +15 -2
- package/src/metadata-builder/builders/section-field-maps.ts +34 -1
- package/src/metadata-builder/builders/section-field-utils.ts +131 -72
- package/src/metadata-builder/builders/section-rules/about-section.rules.ts +38 -0
- package/src/metadata-builder/builders/section-rules/add-page.rules.ts +17 -0
- package/src/metadata-builder/builders/section-rules/banner-section.rules.ts +49 -0
- package/src/metadata-builder/builders/section-rules/booking-section.rules.ts +34 -0
- package/src/metadata-builder/builders/section-rules/button-section.rules.ts +22 -0
- package/src/metadata-builder/builders/section-rules/contact-form.rules.ts +30 -0
- package/src/metadata-builder/builders/section-rules/divider-section.rules.ts +17 -0
- package/src/metadata-builder/builders/section-rules/footer.rules.ts +21 -0
- package/src/metadata-builder/builders/section-rules/global-styles.rules.ts +44 -0
- package/src/metadata-builder/builders/section-rules/header.rules.ts +75 -0
- package/src/metadata-builder/builders/section-rules/image-gallery.rules.ts +22 -0
- package/src/metadata-builder/builders/section-rules/images-section.rules.ts +55 -0
- package/src/metadata-builder/builders/section-rules/mailing-list.rules.ts +21 -0
- package/src/metadata-builder/builders/section-rules/profile.rules.ts +27 -0
- package/src/metadata-builder/builders/section-rules/rename-page.rules.ts +17 -0
- package/src/metadata-builder/builders/section-rules/shapes-section.rules.ts +51 -0
- package/src/metadata-builder/builders/section-rules/social-links.rules.ts +27 -0
- package/src/metadata-builder/builders/section-rules/testimonial-section.rules.ts +48 -0
- package/src/metadata-builder/builders/section-rules/text-section.rules.ts +28 -0
- package/src/metadata-builder/builders/shape-color-utils.test.ts +115 -0
- package/src/metadata-builder/builders/shape-color-utils.ts +75 -0
- package/src/metadata-builder/builders/undo-builder.ts +105 -0
- package/src/metadata-builder/builders/update-content-text-style-builder.ts +4 -1
- package/src/metadata-builder/helpers/rte.helpers.ts +27 -13
- package/src/metadata-builder/metadata-executor.ts +42 -2
- package/src/metadata-builder/models.ts +39 -1
- package/src/metadata-builder/parsers/ai-toolcall-parser.ts +152 -0
- package/src/metadata-builder/parsers/section-tool-arguments.ts +138 -24
- package/src/metadata-builder/sanitizers/__tests__/section-args-validator.test.ts +659 -0
- package/src/metadata-builder/sanitizers/rte-schema-check.ts +99 -0
- package/src/metadata-builder/sanitizers/sanitizer-rules.ts +97 -0
- package/src/metadata-builder/sanitizers/section-args-validator.ts +445 -0
- package/src/shared/content-settings/components/content-settings/ContentSettings.mixin.ts +10 -16
- package/src/shared/content-settings/components/content-settings/ContentSettings.stories.ts +0 -1
- package/src/shared/content-settings/components/content-settings-item/ContentSettingsItemField.mixin.ts +6 -10
- package/src/shared/content-settings/components/content-settings-item/ContentSettingsItemField.vue +1 -23
- package/src/shared/content-settings/components/testimonial-items-field/TestimonialItemsField.vue +0 -15
- package/src/shared/content-settings/components/text-items-field/TextItemsField.vue +0 -15
- package/src/shared/navigation-style-settings/store/index.ts +5 -0
- package/src/shared/page-navigation/store/page-navigation-store.ts +4 -31
- package/src/shared/page-navigation/utils/nav-order-utils.ts +32 -0
- package/src/shared/side-bar/components/SideBar.vue +14 -1
- package/src/shared/side-bar/store/side-bar-store.ts +0 -20
- package/src/utils/build-asset-manifest.ts +153 -0
- package/src/utils/minify-brand-page-metadata.ts +362 -130
- package/lib/src/brand-page-maker/composables/ai-chat/useAiChat.js +0 -368
- package/lib/src/brand-page-maker/composables/ai-chat/useAiTextEditPrompts.d.ts +0 -18
- package/lib/src/brand-page-maker/composables/ai-chat/useAiTextEditPrompts.js +0 -144
- package/lib/src/brand-page-maker/stores/ai-thread/ai-thread-store.d.ts +0 -155
- package/lib/src/brand-page-maker/stores/ai-thread/ai-thread-store.js +0 -25
- package/lib/src/brand-page-maker/utils/mixpanel.util.d.ts +0 -1
- package/lib/src/brand-page-maker/utils/mixpanel.util.js +0 -29
- package/lib/src/bundled-translations-CNK7l6_v.js +0 -173
- package/lib/src/bundled-translations.de-DE-BLE4_y0H.js +0 -173
- package/lib/src/bundled-translations.es-ES-thO9osbg.js +0 -173
- package/lib/src/bundled-translations.fr-CA-BZkhiNgU.js +0 -173
- package/lib/src/bundled-translations.fr-FR-bhDLPKgZ.js +0 -173
- package/lib/src/bundled-translations.pt-BR-CI9a5Bq1.js +0 -173
- package/lib/src/bundled-translations.pt-PT-DBoErBaq.js +0 -173
- package/src/brand-page-maker/components/ai-text-edit/AiTextEdit.vue +0 -154
- package/src/brand-page-maker/composables/ai-chat/useAiChat.ts +0 -562
- package/src/brand-page-maker/composables/ai-chat/useAiTextEditPrompts.ts +0 -196
- package/src/brand-page-maker/stores/ai-thread/ai-thread-store.ts +0 -31
- package/src/brand-page-maker/utils/mixpanel.util.ts +0 -42
- package/src/shared/content-settings/components/generate-ai-button/GenerateAiButton.vue +0 -114
- package/src/shared/content-settings/components/generate-ai-modal/GenerateAiModal.vue +0 -761
|
@@ -1,20 +1,34 @@
|
|
|
1
1
|
import { ref, computed, watch, nextTick, onUnmounted } from 'vue';
|
|
2
|
-
import { getInstance as getAiAssistantClient, AI_ASSISTANT_AGENT_TYPES,
|
|
2
|
+
import { getInstance as getAiAssistantClient, AI_ASSISTANT_AGENT_TYPES, } from '../../../clients/ai-assistant-client';
|
|
3
|
+
import { FabricRenderClient } from '../../../clients/fabric-render-client';
|
|
4
|
+
import { parseLogoThemeToCssStyles } from '../../../brand-page/utils/style.util';
|
|
5
|
+
import { AI_ASSISTANT_TOOL_NAMES } from '../../../metadata-builder/parsers/ai-toolcall-parser';
|
|
3
6
|
import { WebSocketGatewayClient, } from '../../../clients/websocket-gateway-client';
|
|
4
7
|
import { minifyBrandPageMetadata } from '../../../utils/minify-brand-page-metadata';
|
|
5
|
-
import {
|
|
8
|
+
import { buildAssetManifest } from '../../../utils/build-asset-manifest';
|
|
9
|
+
import { usePageNavigationStore } from '../../../shared/page-navigation/store/page-navigation-store';
|
|
10
|
+
import { navigateToPageByPageId } from '../../routing';
|
|
11
|
+
import { useSnapshotStore, useAiWebsiteBuilderThreadStore, useAiCheckpointStore, useBrandPageContainerStore, useUiStore, } from '../../stores';
|
|
6
12
|
import { useBrandPageMakerStore } from '../../stores';
|
|
13
|
+
import { useBrandPageMakerUserStore } from '../../stores/user/user-store';
|
|
7
14
|
import { useAiMetadataBuilder } from './useAiMetadataBuilder';
|
|
15
|
+
import { pickErrorMessage, pickWsErrorMessage, buildSubmitErrorReport, } from './aiErrorCopy';
|
|
16
|
+
import raygunUtil from '../../../brand-page/utils/raygun.util';
|
|
17
|
+
import { useEventTracker, AI_CTA_LOCATIONS } from '../useEventTracker';
|
|
8
18
|
import { Logger } from '../../../metadata-builder/logger';
|
|
9
19
|
const BUILD_TIMEOUT_MS = 600000;
|
|
10
20
|
const aiLogger = new Logger();
|
|
11
21
|
let activeBuildWsClient = null;
|
|
12
|
-
const MAX_TOOL_CALL_ITERATIONS = 5;
|
|
13
22
|
export function useAiWebsiteBuilderChat() {
|
|
14
23
|
const aiThreadStore = useAiWebsiteBuilderThreadStore();
|
|
15
24
|
const snapshotStore = useSnapshotStore();
|
|
16
25
|
const brandPageMakerStore = useBrandPageMakerStore();
|
|
26
|
+
const containerStore = useBrandPageContainerStore();
|
|
27
|
+
const userStore = useBrandPageMakerUserStore();
|
|
28
|
+
const uiStore = useUiStore();
|
|
17
29
|
const aiMetadataBuilder = useAiMetadataBuilder(aiLogger);
|
|
30
|
+
const checkpointStore = useAiCheckpointStore();
|
|
31
|
+
const eventTracker = useEventTracker();
|
|
18
32
|
const hasStoredMessages = aiThreadStore.messages.length > 0;
|
|
19
33
|
const threadItems = ref(aiThreadStore.messages.length > 0
|
|
20
34
|
? aiThreadStore.messages
|
|
@@ -27,6 +41,45 @@ export function useAiWebsiteBuilderChat() {
|
|
|
27
41
|
timestamp: new Date(),
|
|
28
42
|
},
|
|
29
43
|
]);
|
|
44
|
+
// ---------------------------------------------------------------------------
|
|
45
|
+
// Undo snapshot lifecycle (WL9) — reuses the existing `checkpointStore`,
|
|
46
|
+
// which stores pre-prompt BrandPageModel snapshots keyed by user message id.
|
|
47
|
+
//
|
|
48
|
+
// Capture rule: one checkpoint per user prompt, but ONLY when the response
|
|
49
|
+
// contains at least one non-undo tool call. Conversational responses and
|
|
50
|
+
// pure-undo responses leave checkpoint state untouched. This is handled
|
|
51
|
+
// inside `applyToolCallsAsync`, which is idempotent per user prompt thanks
|
|
52
|
+
// to the `hasCheckpoint(userMessageId)` guard — so multi-turn retry flows
|
|
53
|
+
// (where `applyToolCallsAsync` may run multiple times for one user prompt)
|
|
54
|
+
// only create the checkpoint on the first change-producing response.
|
|
55
|
+
//
|
|
56
|
+
// Restore rule: the UndoBuilder calls `undoHandler` which reverts to the
|
|
57
|
+
// latest checkpoint. `checkpointStore.revertToCheckpoint` splices away the
|
|
58
|
+
// target plus all subsequent entries in one step — exactly the pop-and-
|
|
59
|
+
// cleanup semantics we want.
|
|
60
|
+
//
|
|
61
|
+
// User-facing feedback comes from the AI pipeline's AIMessage content
|
|
62
|
+
// (e.g., "Reverted your last change.", server-side Gate 1 refusals for
|
|
63
|
+
// empty history) — NOT from this handler. Server-side Gate 1 already
|
|
64
|
+
// refuses undo when the conversation has no prior change-producing action,
|
|
65
|
+
// so a null return here is a defensive no-op rather than a normal path.
|
|
66
|
+
// ---------------------------------------------------------------------------
|
|
67
|
+
/**
|
|
68
|
+
* Resolver invoked by the UndoBuilder at execute time.
|
|
69
|
+
*
|
|
70
|
+
* Pops the latest checkpoint and returns its model; returns `null` when
|
|
71
|
+
* no checkpoint exists (defensive — server-side Gate 1 should prevent
|
|
72
|
+
* undo from reaching this handler on an empty history). The UndoBuilder
|
|
73
|
+
* surfaces the null case as a tool error, which the caller may log; no
|
|
74
|
+
* thread-level UI bubble is appended here.
|
|
75
|
+
*/
|
|
76
|
+
const undoHandler = () => {
|
|
77
|
+
const { checkpoints } = checkpointStore;
|
|
78
|
+
if (checkpoints.length === 0)
|
|
79
|
+
return null;
|
|
80
|
+
const latest = checkpoints[checkpoints.length - 1];
|
|
81
|
+
return checkpointStore.revertToCheckpoint(latest.userMessageId);
|
|
82
|
+
};
|
|
30
83
|
const isProcessing = computed({
|
|
31
84
|
get: () => aiThreadStore.isProcessing,
|
|
32
85
|
set: (value) => {
|
|
@@ -63,34 +116,187 @@ export function useAiWebsiteBuilderChat() {
|
|
|
63
116
|
const wsClient = new WebSocketGatewayClient();
|
|
64
117
|
const connectionId = await wsClient.connect();
|
|
65
118
|
wsClient.onDisconnect(() => {
|
|
119
|
+
// Only report when a build was actively in flight. Idle disconnects
|
|
120
|
+
// (page reload, server restart with no user-visible build) would
|
|
121
|
+
// otherwise flood Raygun with non-actionable noise.
|
|
122
|
+
const wasBuildInFlight = aiThreadStore.isBuildInProgress;
|
|
66
123
|
activeBuildWsClient = null;
|
|
67
124
|
addServiceUnavailableBubble();
|
|
125
|
+
if (wasBuildInFlight) {
|
|
126
|
+
const err = new Error('There was a disruption in the connection while building your website. Please try again.');
|
|
127
|
+
raygunUtil.safeSendRaygunError(err, {
|
|
128
|
+
tags: [
|
|
129
|
+
'feature:ai-website-builder',
|
|
130
|
+
'failure:websocket_disconnect',
|
|
131
|
+
'stage:in_flight_build',
|
|
132
|
+
],
|
|
133
|
+
customData: {
|
|
134
|
+
build_id: aiThreadStore.buildId ?? null,
|
|
135
|
+
thread_id: aiThreadStore.threadId ?? null,
|
|
136
|
+
},
|
|
137
|
+
});
|
|
138
|
+
}
|
|
68
139
|
});
|
|
69
140
|
activeBuildWsClient = wsClient;
|
|
70
141
|
return connectionId;
|
|
71
142
|
};
|
|
72
|
-
const
|
|
73
|
-
|
|
74
|
-
|
|
143
|
+
const USER_PROMPT_PARAM_MAX_LENGTH = 100;
|
|
144
|
+
const appendUserPromptParam = (rawUrl, userPrompt) => {
|
|
145
|
+
try {
|
|
146
|
+
const url = new URL(rawUrl);
|
|
147
|
+
const trimmed = userPrompt.trim().slice(0, USER_PROMPT_PARAM_MAX_LENGTH);
|
|
148
|
+
if (trimmed) {
|
|
149
|
+
url.searchParams.set('user_prompt', trimmed);
|
|
150
|
+
}
|
|
151
|
+
return url.toString();
|
|
152
|
+
}
|
|
153
|
+
catch {
|
|
154
|
+
return rawUrl;
|
|
155
|
+
}
|
|
156
|
+
};
|
|
157
|
+
const fetchLogoContext = async (logoDraftToken) => {
|
|
158
|
+
if (!logoDraftToken)
|
|
159
|
+
return undefined;
|
|
160
|
+
const client = FabricRenderClient.getInstance();
|
|
161
|
+
if (!client)
|
|
162
|
+
return undefined;
|
|
163
|
+
const attributes = await client.getLogoAttributesByLogoDraftTokenAsync(logoDraftToken);
|
|
164
|
+
if (!attributes?.logoTheme)
|
|
165
|
+
return undefined;
|
|
166
|
+
const { logoTextColor, logoBackgroundColor } = parseLogoThemeToCssStyles(attributes.logoTheme);
|
|
167
|
+
const context = {};
|
|
168
|
+
if (logoTextColor.rgb)
|
|
169
|
+
context.logoTextColor = logoTextColor.rgb;
|
|
170
|
+
if (logoBackgroundColor.rgb)
|
|
171
|
+
context.logoBackgroundColor = logoBackgroundColor.rgb;
|
|
172
|
+
return Object.keys(context).length > 0 ? context : undefined;
|
|
173
|
+
};
|
|
174
|
+
const buildMessagePayload = async (userPrompt) => {
|
|
175
|
+
const brandPageData = brandPageMakerStore.brandPageData;
|
|
176
|
+
const headerLogoDraftToken = brandPageData.pageHeaderDesktop?.logoImage?.logoDraftToken ??
|
|
177
|
+
uiStore.logoDraftToken;
|
|
178
|
+
const [assets, logoContext] = await Promise.all([
|
|
179
|
+
buildAssetManifest(brandPageData),
|
|
180
|
+
fetchLogoContext(headerLogoDraftToken),
|
|
181
|
+
]);
|
|
182
|
+
const pageNavigationStore = usePageNavigationStore();
|
|
183
|
+
const currentPageId = pageNavigationStore.activePageId;
|
|
184
|
+
const websiteContext = {
|
|
185
|
+
metadata: minifyBrandPageMetadata(brandPageData, assets),
|
|
186
|
+
...(assets.length > 0 && { assets }),
|
|
187
|
+
websiteTemplateToken: containerStore.designTemplateToken,
|
|
188
|
+
...(containerStore.designDraftToken && {
|
|
189
|
+
websiteDraftToken: containerStore.designDraftToken,
|
|
190
|
+
}),
|
|
191
|
+
...(currentPageId && { activeContext: { currentPageId } }),
|
|
192
|
+
...(brandPageMakerStore.businessName && {
|
|
193
|
+
businessName: brandPageMakerStore.businessName,
|
|
194
|
+
}),
|
|
195
|
+
...(logoContext && { logoContext }),
|
|
196
|
+
};
|
|
197
|
+
return { message: userPrompt, websiteContext };
|
|
75
198
|
};
|
|
76
|
-
const applyToolCallsAsync = async (response) => {
|
|
199
|
+
const applyToolCallsAsync = async (response, userMessageId, vacantSlots) => {
|
|
77
200
|
let aiMessage = response.message || '';
|
|
78
201
|
const modelToUpdate = brandPageMakerStore.brandPageData;
|
|
79
|
-
const
|
|
80
|
-
|
|
202
|
+
const preCallModel = modelToUpdate;
|
|
203
|
+
// Conditional per-prompt checkpoint creation. Guarded by:
|
|
204
|
+
// - has at least one non-undo tool call (skip conversational + pure-undo
|
|
205
|
+
// responses — nothing worth reverting to),
|
|
206
|
+
// - no checkpoint exists yet for this user prompt (idempotent across the
|
|
207
|
+
// multi-turn retry flow, which calls applyToolCallsAsync multiple
|
|
208
|
+
// times for the same userMessageId).
|
|
209
|
+
const hasChangeProducingToolCall = (response.toolCalls ?? []).some((tc) => tc.function !== AI_ASSISTANT_TOOL_NAMES.UNDO);
|
|
210
|
+
if (hasChangeProducingToolCall &&
|
|
211
|
+
!checkpointStore.hasCheckpoint(userMessageId)) {
|
|
212
|
+
checkpointStore.createCheckpoint(userMessageId, preCallModel);
|
|
213
|
+
}
|
|
214
|
+
// PRE-PASS: for each create-mode section tool call on a page with a
|
|
215
|
+
// pending anchored vacant slot, splice `move_before_content_id` into
|
|
216
|
+
// the wire arguments so the executor places the section at the planned
|
|
217
|
+
// index instead of the end of the page. We rewrite the JSON string
|
|
218
|
+
// because parseToolCalls owns the parse step downstream.
|
|
219
|
+
const enrichedToolCalls = (response.toolCalls ?? []).map((tc) => {
|
|
220
|
+
try {
|
|
221
|
+
const args = JSON.parse(tc.arguments);
|
|
222
|
+
const mode = args.mode;
|
|
223
|
+
const pageId = args.page_id;
|
|
224
|
+
if (mode === 'create' &&
|
|
225
|
+
pageId &&
|
|
226
|
+
!args.move_before_content_id &&
|
|
227
|
+
(vacantSlots.get(pageId)?.length ?? 0) > 0) {
|
|
228
|
+
const slots = vacantSlots.get(pageId);
|
|
229
|
+
const anchorIdx = slots.findIndex((a) => a !== null);
|
|
230
|
+
if (anchorIdx !== -1) {
|
|
231
|
+
const anchor = slots[anchorIdx];
|
|
232
|
+
slots.splice(anchorIdx, 1);
|
|
233
|
+
args.move_before_content_id = anchor;
|
|
234
|
+
return { ...tc, arguments: JSON.stringify(args) };
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
catch {
|
|
239
|
+
// Malformed arguments — leave as-is; parseToolCalls will surface the error.
|
|
240
|
+
}
|
|
241
|
+
return tc;
|
|
242
|
+
});
|
|
243
|
+
const updateResult = await aiMetadataBuilder.applyAiToolCallsAsync(modelToUpdate, enrichedToolCalls, {
|
|
244
|
+
undoHandler,
|
|
245
|
+
eventTracker,
|
|
246
|
+
});
|
|
247
|
+
const toolResults = updateResult.results.map((x, i) => {
|
|
81
248
|
return {
|
|
82
249
|
toolId: x.toolId,
|
|
83
250
|
success: x.errors && x.errors.length > 0 ? 'failed' : 'success',
|
|
251
|
+
name: enrichedToolCalls[i]?.function,
|
|
252
|
+
errorMessage: x.errors?.length ? x.errors.join('; ') : undefined,
|
|
84
253
|
};
|
|
85
254
|
});
|
|
255
|
+
// POST-PASS: walk this batch's create-mode results in plan order.
|
|
256
|
+
// - Failure → append `null` to the page's vacant queue. Anchor unknown
|
|
257
|
+
// until a later successful CREATE on the same page binds it.
|
|
258
|
+
// - Success → if the page has any pending `null` placeholders from
|
|
259
|
+
// earlier failures in this batch, bind the FIRST one to this new
|
|
260
|
+
// content id. The retry batch will pop it in plan order, which
|
|
261
|
+
// matches the backend's ascending-`order` retry emission.
|
|
262
|
+
updateResult.parsedToolCalls.forEach((parsed, i) => {
|
|
263
|
+
const args = parsed.arguments;
|
|
264
|
+
if (args.mode !== 'create' || !args.page_id)
|
|
265
|
+
return;
|
|
266
|
+
const result = updateResult.results[i];
|
|
267
|
+
const pageId = args.page_id;
|
|
268
|
+
const slots = vacantSlots.get(pageId) ?? [];
|
|
269
|
+
if (result.errors && result.errors.length > 0) {
|
|
270
|
+
slots.push(null);
|
|
271
|
+
}
|
|
272
|
+
else if (result.contentId) {
|
|
273
|
+
const nullIdx = slots.indexOf(null);
|
|
274
|
+
if (nullIdx !== -1) {
|
|
275
|
+
slots[nullIdx] = result.contentId;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
vacantSlots.set(pageId, slots);
|
|
279
|
+
});
|
|
86
280
|
updateResult.parsedToolCalls.forEach((toolCall) => {
|
|
87
281
|
const args = toolCall.arguments;
|
|
88
282
|
if (args.message) {
|
|
89
283
|
aiMessage = aiMessage ? `${aiMessage} ${args.message}` : args.message;
|
|
90
284
|
}
|
|
91
285
|
});
|
|
92
|
-
console.log('updateResult.model', JSON.parse(JSON.stringify(updateResult.model)));
|
|
93
286
|
await brandPageMakerStore.initialiseStoresByBrandPageModelAsync(updateResult.model);
|
|
287
|
+
// AI tool calls can regenerate the active page's slug (e.g. rename_page
|
|
288
|
+
// recomputes pageSlug from the new title). The in-memory maker router's
|
|
289
|
+
// currentRoute still holds the pre-change slug, so the preview's
|
|
290
|
+
// slug-keyed page lookup (findNavItemByRelativePath) misses and silently
|
|
291
|
+
// falls back to pages[0]. Re-push by the stable pageId — which survives
|
|
292
|
+
// any rename — to refresh routeStore.currentRoute.params to the new slug
|
|
293
|
+
// and keep the preview on the page the user was editing. Unconditional:
|
|
294
|
+
// a push to an unchanged slug is a no-op, and an empty activePageId (e.g.
|
|
295
|
+
// initial load) is a safe early-return inside navigateToPageByPageId.
|
|
296
|
+
const pageNavigationStore = usePageNavigationStore();
|
|
297
|
+
if (pageNavigationStore.activePageId) {
|
|
298
|
+
navigateToPageByPageId(pageNavigationStore.activePageId);
|
|
299
|
+
}
|
|
94
300
|
await nextTick();
|
|
95
301
|
// Re-capture snapshot so subsequent messages reflect the updated page
|
|
96
302
|
await snapshotStore.refreshSnapshotAsync();
|
|
@@ -100,27 +306,33 @@ export function useAiWebsiteBuilderChat() {
|
|
|
100
306
|
aiMessage,
|
|
101
307
|
};
|
|
102
308
|
};
|
|
103
|
-
const callApiBuildAsync = async (userPrompt) => {
|
|
309
|
+
const callApiBuildAsync = async (userPrompt, userMessageId) => {
|
|
104
310
|
const connectionId = await ensureConnectedAsync();
|
|
105
311
|
const wsClient = activeBuildWsClient;
|
|
106
312
|
try {
|
|
107
313
|
const client = getAiAssistantClient();
|
|
108
|
-
const message =
|
|
109
|
-
|
|
314
|
+
const { message, websiteContext } = await buildMessagePayload(userPrompt);
|
|
315
|
+
const userPlan = userStore.hasPremiumSubscription
|
|
316
|
+
? 'premium'
|
|
317
|
+
: 'free';
|
|
110
318
|
let buildResponse;
|
|
111
319
|
if (!aiThreadStore.threadId) {
|
|
112
320
|
buildResponse = await client.createWebsiteThreadBuildAsync({
|
|
113
321
|
message,
|
|
322
|
+
websiteContext,
|
|
114
323
|
websiteSnapshot: snapshotStore.snapshotBase64 || undefined,
|
|
115
324
|
agentType: AI_ASSISTANT_AGENT_TYPES.WEBSITE_BUILDER,
|
|
325
|
+
userPlan,
|
|
116
326
|
connectionId,
|
|
117
327
|
});
|
|
118
328
|
}
|
|
119
329
|
else {
|
|
120
330
|
buildResponse = await client.sendWebsiteMessageBuildAsync(aiThreadStore.threadId, {
|
|
121
331
|
message,
|
|
332
|
+
websiteContext,
|
|
122
333
|
websiteSnapshot: snapshotStore.snapshotBase64 || undefined,
|
|
123
334
|
agentType: AI_ASSISTANT_AGENT_TYPES.WEBSITE_BUILDER,
|
|
335
|
+
userPlan,
|
|
124
336
|
connectionId,
|
|
125
337
|
});
|
|
126
338
|
}
|
|
@@ -128,12 +340,34 @@ export function useAiWebsiteBuilderChat() {
|
|
|
128
340
|
aiThreadStore.buildId = buildResponse.buildId;
|
|
129
341
|
aiThreadStore.isBuildInProgress = true;
|
|
130
342
|
aiThreadStore.buildSectionsCompleted = 0;
|
|
131
|
-
const langChainUrl = buildResponse.langChainUrl;
|
|
132
343
|
wsClient.setBuildActive(true);
|
|
133
344
|
wsClient.startResponseHeartbeat();
|
|
345
|
+
const withTypingMessage = (fn) => {
|
|
346
|
+
const typingId = currentTypingMessageId.value;
|
|
347
|
+
if (!typingId)
|
|
348
|
+
return;
|
|
349
|
+
const idx = threadItems.value.findIndex((m) => m.id === typingId);
|
|
350
|
+
if (idx !== -1)
|
|
351
|
+
fn(threadItems.value[idx]);
|
|
352
|
+
};
|
|
353
|
+
// Surface the thread URL on the agent bubble as soon as the API returns
|
|
354
|
+
// it, so the button is available while the build is still streaming and
|
|
355
|
+
// is preserved if the build later errors or times out.
|
|
356
|
+
if (buildResponse.langChainUrl) {
|
|
357
|
+
const url = appendUserPromptParam(buildResponse.langChainUrl, userPrompt);
|
|
358
|
+
withTypingMessage((m) => {
|
|
359
|
+
m.langChainUrl = url;
|
|
360
|
+
});
|
|
361
|
+
}
|
|
134
362
|
return new Promise((resolve, reject) => {
|
|
135
363
|
let settled = false;
|
|
364
|
+
let retryCount = 0;
|
|
365
|
+
let lastAiMessage = null;
|
|
136
366
|
let handler = null;
|
|
367
|
+
// Vacant-slot queue scoped to this build session. Persists across
|
|
368
|
+
// retry rounds so a failed CREATE returns to its planned slot via
|
|
369
|
+
// a synthesised `move_before_content_id`.
|
|
370
|
+
const vacantSlots = new Map();
|
|
137
371
|
const finishBuild = () => {
|
|
138
372
|
aiThreadStore.isBuildInProgress = false;
|
|
139
373
|
wsClient.setBuildActive(false);
|
|
@@ -151,53 +385,202 @@ export function useAiWebsiteBuilderChat() {
|
|
|
151
385
|
handler = (msg) => {
|
|
152
386
|
if (settled)
|
|
153
387
|
return;
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
388
|
+
try {
|
|
389
|
+
if (msg.buildId !== aiThreadStore.buildId)
|
|
390
|
+
return;
|
|
391
|
+
if (isStopped.value) {
|
|
392
|
+
settled = true;
|
|
393
|
+
clearTimeout(timeout);
|
|
394
|
+
finishBuild();
|
|
395
|
+
resolve({ text: null });
|
|
396
|
+
return;
|
|
397
|
+
}
|
|
398
|
+
if (msg.type === 'chat_started' && msg.message) {
|
|
399
|
+
withTypingMessage((m) => {
|
|
400
|
+
m.initialMessage = msg.message;
|
|
401
|
+
});
|
|
402
|
+
return;
|
|
403
|
+
}
|
|
404
|
+
if (msg.type === 'plan_announced' && msg.items) {
|
|
405
|
+
withTypingMessage((m) => {
|
|
406
|
+
if (!m.planItems)
|
|
407
|
+
m.planItems = msg.items;
|
|
408
|
+
});
|
|
409
|
+
return;
|
|
410
|
+
}
|
|
411
|
+
if (msg.type === 'item_complete' && msg.itemId) {
|
|
412
|
+
const itemId = msg.itemId;
|
|
413
|
+
withTypingMessage((m) => {
|
|
414
|
+
if (!m.completedItemIds?.includes(itemId)) {
|
|
415
|
+
m.completedItemIds = [
|
|
416
|
+
...(m.completedItemIds ?? []),
|
|
417
|
+
itemId,
|
|
418
|
+
];
|
|
419
|
+
}
|
|
420
|
+
});
|
|
421
|
+
return;
|
|
422
|
+
}
|
|
423
|
+
if (msg.type === 'server_response') {
|
|
424
|
+
const toolCalls = (msg.toolCalls ||
|
|
425
|
+
[]);
|
|
426
|
+
const aiResponse = {
|
|
427
|
+
threadId: aiThreadStore.threadId || '',
|
|
428
|
+
toolCalls,
|
|
429
|
+
message: msg.message || null,
|
|
430
|
+
type: 'tool_calls',
|
|
431
|
+
totalPaidToolCalls: 0,
|
|
432
|
+
timestamp: Date.now(),
|
|
433
|
+
};
|
|
434
|
+
(async () => {
|
|
435
|
+
try {
|
|
436
|
+
// No tool calls = build cycle complete (success, max retries, or no retryable sections)
|
|
437
|
+
if (toolCalls.length === 0) {
|
|
438
|
+
// Defence-in-depth: a server_response with no toolCalls AND
|
|
439
|
+
// no message text is a degenerate response — it means the
|
|
440
|
+
// backend graph reached END without producing anything
|
|
441
|
+
// actionable. The server-side fix in stream_with_push now
|
|
442
|
+
// converts this to a build_error frame, but if a future
|
|
443
|
+
// regression slips through we must NOT show "Your website
|
|
444
|
+
// has been updated" — that hides real failures from users
|
|
445
|
+
// and from monitoring.
|
|
446
|
+
const hasMeaningfulMessage = Boolean(aiResponse.message || lastAiMessage);
|
|
447
|
+
if (!hasMeaningfulMessage) {
|
|
448
|
+
raygunUtil.safeSendRaygunError(new Error('AI build server_response had empty toolCalls and empty message'), {
|
|
449
|
+
tags: [
|
|
450
|
+
'feature:ai-website-builder',
|
|
451
|
+
'failure:degenerate_server_response',
|
|
452
|
+
],
|
|
453
|
+
customData: {
|
|
454
|
+
build_id: aiThreadStore.buildId ?? null,
|
|
455
|
+
thread_id: aiThreadStore.threadId ?? null,
|
|
456
|
+
},
|
|
457
|
+
});
|
|
458
|
+
settled = true;
|
|
459
|
+
clearTimeout(timeout);
|
|
460
|
+
finishBuild();
|
|
461
|
+
resolve({
|
|
462
|
+
text: 'Something went wrong while updating your website. Please try again.',
|
|
463
|
+
isError: true,
|
|
464
|
+
});
|
|
465
|
+
return;
|
|
466
|
+
}
|
|
467
|
+
settled = true;
|
|
468
|
+
clearTimeout(timeout);
|
|
469
|
+
finishBuild();
|
|
470
|
+
await snapshotStore.refreshSnapshotAsync();
|
|
471
|
+
resolve({
|
|
472
|
+
text: aiResponse.message || lastAiMessage || '',
|
|
473
|
+
});
|
|
474
|
+
return;
|
|
475
|
+
}
|
|
476
|
+
// Tool calls present — apply locally and submit results back
|
|
477
|
+
const { toolResults, aiMessage } = await applyToolCallsAsync(aiResponse, userMessageId, vacantSlots);
|
|
478
|
+
lastAiMessage = aiMessage;
|
|
479
|
+
// Submit all tool results (success + failure) so the AI pipeline
|
|
480
|
+
// persists ToolMessages matching every tool_call in the conversation.
|
|
481
|
+
const failedResults = toolResults.filter((tr) => tr.success !== 'success');
|
|
482
|
+
aiLogger.log('tool submission for results', {
|
|
483
|
+
total: toolResults.length,
|
|
484
|
+
failed: failedResults.length,
|
|
485
|
+
failedResults,
|
|
486
|
+
retryCount,
|
|
487
|
+
});
|
|
488
|
+
const submitResult = await client.submitToolResultsBuildAsync(aiThreadStore.threadId, {
|
|
489
|
+
toolCalls: toolResults,
|
|
490
|
+
agentType: AI_ASSISTANT_AGENT_TYPES.WEBSITE_BUILDER,
|
|
491
|
+
connectionId,
|
|
492
|
+
retryCount,
|
|
493
|
+
userPlan,
|
|
494
|
+
});
|
|
495
|
+
if (failedResults.length === 0) {
|
|
496
|
+
settled = true;
|
|
497
|
+
clearTimeout(timeout);
|
|
498
|
+
finishBuild();
|
|
499
|
+
resolve({
|
|
500
|
+
text: aiMessage || 'Your website has been updated.',
|
|
501
|
+
});
|
|
502
|
+
return;
|
|
503
|
+
}
|
|
504
|
+
// Update buildId so the handler matches subsequent WS messages
|
|
505
|
+
if (submitResult.buildId) {
|
|
506
|
+
aiThreadStore.buildId = submitResult.buildId;
|
|
507
|
+
}
|
|
508
|
+
// eslint-disable-next-line no-plusplus
|
|
509
|
+
retryCount++;
|
|
179
510
|
}
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
511
|
+
catch (err) {
|
|
512
|
+
aiLogger.log('server_response apply error', { err });
|
|
513
|
+
// Client-side apply failure (metadata builder, tool-call parser,
|
|
514
|
+
// missing field, etc.) — server thinks the build succeeded but we
|
|
515
|
+
// couldn't materialise the changes. Mark the chat bubble as an
|
|
516
|
+
// error so the user sees the real outcome, and report to Raygun
|
|
517
|
+
// so the failure is visible in monitoring (the server didn't see it).
|
|
518
|
+
raygunUtil.safeSendRaygunError(err instanceof Error
|
|
519
|
+
? err
|
|
520
|
+
: new Error('AI apply failed: non-Error thrown'), {
|
|
521
|
+
tags: [
|
|
522
|
+
'feature:ai-website-builder',
|
|
523
|
+
'failure:apply_error',
|
|
524
|
+
'stage:client_apply',
|
|
525
|
+
],
|
|
526
|
+
customData: {
|
|
527
|
+
thread_id: aiThreadStore.threadId ?? null,
|
|
528
|
+
build_id: aiThreadStore.buildId ?? null,
|
|
529
|
+
},
|
|
530
|
+
});
|
|
531
|
+
settled = true;
|
|
532
|
+
clearTimeout(timeout);
|
|
533
|
+
finishBuild();
|
|
534
|
+
resolve({
|
|
535
|
+
text: "I couldn't apply those changes to your website. Please try again.",
|
|
536
|
+
isError: true,
|
|
537
|
+
});
|
|
538
|
+
}
|
|
539
|
+
})();
|
|
540
|
+
return;
|
|
541
|
+
}
|
|
542
|
+
if (msg.type === 'server_error' || msg.type === 'build_error') {
|
|
543
|
+
settled = true;
|
|
544
|
+
clearTimeout(timeout);
|
|
545
|
+
finishBuild();
|
|
546
|
+
// Backend already reports the underlying pipeline failure to
|
|
547
|
+
// Raygun via its structured handler (stage:run_build /
|
|
548
|
+
// stage:section_builder / etc. with full Python traceback).
|
|
549
|
+
// We report the frontend's RECEIPT of the error frame as a
|
|
550
|
+
// separate signal — distinct tag, distinct grouping. This
|
|
551
|
+
// gives triangulation: both sides have entry → normal crash;
|
|
552
|
+
// frontend only → backend Raygun outage; backend only → WS
|
|
553
|
+
// frame didn't reach client (different bug shape).
|
|
554
|
+
const wsMsg = msg;
|
|
555
|
+
raygunUtil.safeSendRaygunError(new Error(`AI build ${wsMsg.type}: ${wsMsg.code ?? wsMsg.error ?? 'unknown'}`), {
|
|
556
|
+
tags: [
|
|
557
|
+
'feature:ai-website-builder',
|
|
558
|
+
'failure:websocket_error_received',
|
|
559
|
+
`frame_type:${wsMsg.type}`,
|
|
560
|
+
],
|
|
561
|
+
customData: {
|
|
562
|
+
code: wsMsg.code ?? null,
|
|
563
|
+
message: wsMsg.message ?? null,
|
|
564
|
+
error: wsMsg.error ?? null,
|
|
565
|
+
build_id: wsMsg.buildId ?? null,
|
|
566
|
+
thread_id: aiThreadStore.threadId ?? null,
|
|
567
|
+
},
|
|
568
|
+
});
|
|
569
|
+
resolve({ text: pickWsErrorMessage(msg), isError: true });
|
|
570
|
+
return;
|
|
571
|
+
}
|
|
193
572
|
}
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
resolve({
|
|
199
|
-
text: msg.error || 'An error occurred during the build.',
|
|
573
|
+
catch (err) {
|
|
574
|
+
aiLogger.log('Unexpected error in WS message handler', {
|
|
575
|
+
err,
|
|
576
|
+
type: msg.type,
|
|
200
577
|
});
|
|
578
|
+
if (!settled) {
|
|
579
|
+
settled = true;
|
|
580
|
+
clearTimeout(timeout);
|
|
581
|
+
finishBuild();
|
|
582
|
+
resolve({ text: 'An error occurred during the build.' });
|
|
583
|
+
}
|
|
201
584
|
}
|
|
202
585
|
};
|
|
203
586
|
wsClient.onMessage(handler);
|
|
@@ -214,6 +597,7 @@ export function useAiWebsiteBuilderChat() {
|
|
|
214
597
|
const { text, images } = messageOptions;
|
|
215
598
|
if (!text?.trim() && (!images || images.length === 0))
|
|
216
599
|
return;
|
|
600
|
+
eventTracker.sendAiSendPromptEvent(AI_CTA_LOCATIONS.AI_BUILDER_TAB);
|
|
217
601
|
isStopped.value = false;
|
|
218
602
|
aiThreadStore.isProcessing = true;
|
|
219
603
|
const userMessage = images
|
|
@@ -233,6 +617,11 @@ export function useAiWebsiteBuilderChat() {
|
|
|
233
617
|
timestamp: new Date(),
|
|
234
618
|
};
|
|
235
619
|
threadItems.value.push(userMessage);
|
|
620
|
+
// Checkpoint creation is now conditional and happens inside
|
|
621
|
+
// `applyToolCallsAsync` — it fires only when the response carries at
|
|
622
|
+
// least one change-producing tool call, and only once per user prompt
|
|
623
|
+
// (idempotent across the multi-turn retry flow). See the "Undo snapshot
|
|
624
|
+
// lifecycle (WL9)" block near the top of this composable.
|
|
236
625
|
const agentMessageId = (Date.now() + 1).toString();
|
|
237
626
|
currentTypingMessageId.value = agentMessageId;
|
|
238
627
|
const agentMessage = {
|
|
@@ -247,7 +636,7 @@ export function useAiWebsiteBuilderChat() {
|
|
|
247
636
|
try {
|
|
248
637
|
aiLogger.startGroup();
|
|
249
638
|
aiLogger.log('sendMessageAsync', { messageOptions });
|
|
250
|
-
const result = await callApiBuildAsync(text || '');
|
|
639
|
+
const result = await callApiBuildAsync(text || '', userMessage.id);
|
|
251
640
|
if (isStopped.value)
|
|
252
641
|
return;
|
|
253
642
|
const messageIndex = threadItems.value.findIndex((msg) => msg.id === agentMessageId);
|
|
@@ -255,7 +644,12 @@ export function useAiWebsiteBuilderChat() {
|
|
|
255
644
|
if (result.text) {
|
|
256
645
|
threadItems.value[messageIndex].text = result.text;
|
|
257
646
|
threadItems.value[messageIndex].isTyping = false;
|
|
258
|
-
|
|
647
|
+
// Honour the isError flag set by error paths in callApiBuildAsync
|
|
648
|
+
// (apply-failure catch, server_error / build_error WS frames).
|
|
649
|
+
// Without this, error text would render as a normal AI reply.
|
|
650
|
+
if (result.isError) {
|
|
651
|
+
threadItems.value[messageIndex].isError = true;
|
|
652
|
+
}
|
|
259
653
|
}
|
|
260
654
|
else {
|
|
261
655
|
threadItems.value[messageIndex].text =
|
|
@@ -274,11 +668,20 @@ export function useAiWebsiteBuilderChat() {
|
|
|
274
668
|
if (messageIndex !== -1) {
|
|
275
669
|
threadItems.value[messageIndex].text = isConnectionError
|
|
276
670
|
? SERVICE_UNAVAILABLE_MESSAGE
|
|
277
|
-
: error
|
|
278
|
-
'An error occurred. Please try again.';
|
|
671
|
+
: pickErrorMessage(error);
|
|
279
672
|
threadItems.value[messageIndex].isTyping = false;
|
|
280
673
|
threadItems.value[messageIndex].isError = true;
|
|
281
674
|
}
|
|
675
|
+
// REL 1 item (4): report request-path failures to Raygun so we can
|
|
676
|
+
// see network / proxy / upstream errors separately from pipeline
|
|
677
|
+
// failures (which are reported server-side via build_error).
|
|
678
|
+
const report = buildSubmitErrorReport(error, { stage: 'submit' });
|
|
679
|
+
if (report) {
|
|
680
|
+
raygunUtil.safeSendRaygunError(report.error, {
|
|
681
|
+
tags: report.tags,
|
|
682
|
+
customData: report.customData,
|
|
683
|
+
});
|
|
684
|
+
}
|
|
282
685
|
}
|
|
283
686
|
finally {
|
|
284
687
|
currentTypingMessageId.value = null;
|
|
@@ -287,7 +690,6 @@ export function useAiWebsiteBuilderChat() {
|
|
|
287
690
|
// was destroyed (tab switch) and the writable computed setter is inert.
|
|
288
691
|
aiThreadStore.isProcessing = false;
|
|
289
692
|
}
|
|
290
|
-
console.log('aiLogger', aiLogger);
|
|
291
693
|
};
|
|
292
694
|
const deleteMessage = (messageId) => {
|
|
293
695
|
const index = threadItems.value.findIndex((msg) => msg.id === messageId);
|
|
@@ -296,6 +698,7 @@ export function useAiWebsiteBuilderChat() {
|
|
|
296
698
|
}
|
|
297
699
|
};
|
|
298
700
|
const stopGenerationAsync = async () => {
|
|
701
|
+
eventTracker.sendAiStopGenerationEvent(AI_CTA_LOCATIONS.AI_BUILDER_TAB);
|
|
299
702
|
isStopped.value = true;
|
|
300
703
|
aiThreadStore.isBuildInProgress = false;
|
|
301
704
|
if (activeBuildWsClient) {
|
|
@@ -310,29 +713,32 @@ export function useAiWebsiteBuilderChat() {
|
|
|
310
713
|
aiThreadStore.isProcessing = false;
|
|
311
714
|
};
|
|
312
715
|
aiThreadStore.stopGeneration = stopGenerationAsync;
|
|
313
|
-
onUnmounted(() => {
|
|
314
|
-
if (aiThreadStore.stopGeneration === stopGenerationAsync) {
|
|
315
|
-
aiThreadStore.stopGeneration = null;
|
|
316
|
-
}
|
|
317
|
-
});
|
|
318
716
|
const formattedMessages = computed(() => {
|
|
319
717
|
const initialMessageCount = hasStoredMessages
|
|
320
718
|
? aiThreadStore.messages.length
|
|
321
719
|
: 1;
|
|
322
|
-
return threadItems.value.map((msg, index) =>
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
720
|
+
return threadItems.value.map((msg, index) => {
|
|
721
|
+
return {
|
|
722
|
+
type: msg.type,
|
|
723
|
+
props: {
|
|
724
|
+
...(msg.type === 'text' && { text: msg.text }),
|
|
725
|
+
...(msg.type === 'image' && { images: msg.images, text: msg.text }),
|
|
726
|
+
isUser: msg.role === 'user',
|
|
727
|
+
isAi: msg.role === 'agent',
|
|
728
|
+
showIcon: msg.role === 'agent',
|
|
729
|
+
isTyping: msg.isTyping,
|
|
730
|
+
isResponse: index >= 1,
|
|
731
|
+
disableAnimation: index < initialMessageCount,
|
|
732
|
+
langChainUrl: msg.langChainUrl,
|
|
733
|
+
...(msg.type === 'text' &&
|
|
734
|
+
msg.isTyping && {
|
|
735
|
+
initialMessage: msg.initialMessage,
|
|
736
|
+
planItems: msg.planItems ?? [],
|
|
737
|
+
completedItemIds: msg.completedItemIds ?? [],
|
|
738
|
+
}),
|
|
739
|
+
},
|
|
740
|
+
};
|
|
741
|
+
});
|
|
336
742
|
});
|
|
337
743
|
return {
|
|
338
744
|
threadItems,
|