@designcrowd/library.brand-page 5.17.15 → 5.17.16-ai-32

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.
Files changed (129) hide show
  1. package/lib/src/{CreatedOnBrandCrowd-de-de-BKNej8ZT.js → CreatedOnBrandCrowd-de-de-COCtbe_y.js} +1 -1
  2. package/lib/src/{CreatedOnBrandCrowd-en-us-ogKV49pg.js → CreatedOnBrandCrowd-en-us-Bck3qysH.js} +1 -1
  3. package/lib/src/{CreatedOnBrandCrowd-es-es-C61Up_D5.js → CreatedOnBrandCrowd-es-es-CteGOR8z.js} +1 -1
  4. package/lib/src/{CreatedOnBrandCrowd-fr-fr-CgkbsVnk.js → CreatedOnBrandCrowd-fr-ca-vxiV7Hau.js} +1 -1
  5. package/lib/src/{CreatedOnBrandCrowd-fr-ca-CgkbsVnk.js → CreatedOnBrandCrowd-fr-fr-vxiV7Hau.js} +1 -1
  6. package/lib/src/{CreatedOnBrandCrowd-pt-pt-DIcjlmcn.js → CreatedOnBrandCrowd-pt-br-Df73YRCR.js} +1 -1
  7. package/lib/src/{CreatedOnBrandCrowd-pt-br-DIcjlmcn.js → CreatedOnBrandCrowd-pt-pt-Df73YRCR.js} +1 -1
  8. package/lib/src/{CreatedOnDcom-de-de-OY2ieqRz.js → CreatedOnDcom-de-de-aquAtk-7.js} +1 -1
  9. package/lib/src/{CreatedOnDcom-en-us-DvZlTQTs.js → CreatedOnDcom-en-us-BnYDKmVv.js} +1 -1
  10. package/lib/src/{CreatedOnDcom-es-es-C52TrGZQ.js → CreatedOnDcom-es-es-2-bL5oTZ.js} +1 -1
  11. package/lib/src/{CreatedOnDcom-fr-ca-B0Kipm6g.js → CreatedOnDcom-fr-ca-DQl3p2m8.js} +1 -1
  12. package/lib/src/{CreatedOnDcom-fr-fr-C1FEzqvW.js → CreatedOnDcom-fr-fr-XUsMCrPw.js} +1 -1
  13. package/lib/src/{CreatedOnDcom-pt-br-uptTt9JP.js → CreatedOnDcom-pt-br-CC4XkuOv.js} +1 -1
  14. package/lib/src/{CreatedOnDcom-pt-pt-C60roAt5.js → CreatedOnDcom-pt-pt-D5czjL5q.js} +1 -1
  15. package/lib/src/brand-page/components/image-gallery/ImageGalleryModal.mixin.js +2 -2
  16. package/lib/src/brand-page/models/brand-page-context.model.js +1 -1
  17. package/lib/src/brand-page-maker/components/brand-page-maker/BrandPageMaker.mixin.d.ts +1 -1
  18. package/lib/src/brand-page-maker/composables/ai-chat/useAiChat.d.ts +5 -0
  19. package/lib/src/brand-page-maker/composables/ai-chat/useAiChat.js +9 -2
  20. package/lib/src/brand-page-maker/composables/ai-chat/useAiWebsiteBuilderChat.js +149 -49
  21. package/lib/src/brand-page-maker/constants/sidebar-constant.js +7 -7
  22. package/lib/src/brand-page-maker/stores/ai-thread/ai-thread-store.d.ts +48 -0
  23. package/lib/src/brand-page-maker/stores/brandpage-maker/brandpage-maker-store.js +42 -2
  24. package/lib/src/clients/ai-assistant-client.d.ts +11 -2
  25. package/lib/src/clients/ai-assistant-client.js +16 -0
  26. package/lib/src/clients/websocket-gateway-client.d.ts +9 -1
  27. package/lib/src/css/library.brand-page-brandCrowd.min.css +223 -77
  28. package/lib/src/css/library.brand-page-brandPage.min.css +225 -77
  29. package/lib/src/css/library.brand-page-designCom.min.css +223 -77
  30. package/lib/src/css/library.brand-page-preview.min.css +223 -77
  31. package/lib/src/index.mjs +1 -1
  32. package/lib/src/{lib-C9NGI-t2.js → lib-Cb6m6aD2.js} +21537 -20923
  33. package/lib/src/metadata-builder/ai-metadata-executor.js +26 -1
  34. package/lib/src/metadata-builder/builders/footer-builder.d.ts +11 -0
  35. package/lib/src/metadata-builder/builders/footer-builder.js +128 -0
  36. package/lib/src/metadata-builder/builders/global-styles-builder.d.ts +15 -0
  37. package/lib/src/metadata-builder/builders/global-styles-builder.js +106 -0
  38. package/lib/src/metadata-builder/builders/header-builder.d.ts +11 -0
  39. package/lib/src/metadata-builder/builders/header-builder.js +135 -0
  40. package/lib/src/metadata-builder/builders/reorder-pages-builder.d.ts +13 -0
  41. package/lib/src/metadata-builder/builders/reorder-pages-builder.js +49 -0
  42. package/lib/src/metadata-builder/builders/section-builders/about-section-builder.js +1 -1
  43. package/lib/src/metadata-builder/builders/section-builders/banner-section-builder.js +42 -4
  44. package/lib/src/metadata-builder/builders/section-builders/base-section-builder.d.ts +5 -2
  45. package/lib/src/metadata-builder/builders/section-builders/base-section-builder.js +39 -4
  46. package/lib/src/metadata-builder/builders/section-builders/booking-section-builder.d.ts +6 -0
  47. package/lib/src/metadata-builder/builders/section-builders/booking-section-builder.js +50 -0
  48. package/lib/src/metadata-builder/builders/section-builders/button-section-builder.js +1 -1
  49. package/lib/src/metadata-builder/builders/section-builders/contact-form-builder.js +1 -1
  50. package/lib/src/metadata-builder/builders/section-builders/divider-section-builder.js +7 -1
  51. package/lib/src/metadata-builder/builders/section-builders/image-gallery-builder.js +4 -8
  52. package/lib/src/metadata-builder/builders/section-builders/images-section-builder.js +31 -10
  53. package/lib/src/metadata-builder/builders/section-builders/index.d.ts +1 -0
  54. package/lib/src/metadata-builder/builders/section-builders/index.js +1 -0
  55. package/lib/src/metadata-builder/builders/section-builders/mailing-list-builder.js +18 -2
  56. package/lib/src/metadata-builder/builders/section-builders/mailing-list-section-builder.js +18 -2
  57. package/lib/src/metadata-builder/builders/section-builders/profile-section-builder.js +39 -1
  58. package/lib/src/metadata-builder/builders/section-builders/shapes-section-builder.js +28 -3
  59. package/lib/src/metadata-builder/builders/section-builders/social-links-builder.js +1 -1
  60. package/lib/src/metadata-builder/builders/section-builders/testimonial-section-builder.js +1 -1
  61. package/lib/src/metadata-builder/builders/section-builders/text-section-builder.js +32 -18
  62. package/lib/src/metadata-builder/builders/section-field-maps.js +21 -1
  63. package/lib/src/metadata-builder/builders/section-field-utils.d.ts +1 -8
  64. package/lib/src/metadata-builder/builders/section-field-utils.js +7 -42
  65. package/lib/src/metadata-builder/helpers/rte.helpers.d.ts +6 -4
  66. package/lib/src/metadata-builder/helpers/rte.helpers.js +15 -10
  67. package/lib/src/metadata-builder/metadata-executor.js +12 -1
  68. package/lib/src/metadata-builder/models.d.ts +5 -0
  69. package/lib/src/metadata-builder/models.js +8 -0
  70. package/lib/src/metadata-builder/parsers/ai-toolcall-parser.d.ts +121 -0
  71. package/lib/src/metadata-builder/parsers/ai-toolcall-parser.js +10 -0
  72. package/lib/src/metadata-builder/parsers/section-tool-arguments.d.ts +62 -14
  73. package/lib/src/metadata-builder/parsers/section-tool-arguments.js +5 -1
  74. package/lib/src/shared/navigation-style-settings/store/index.js +1 -0
  75. package/lib/src/shared/page-navigation/store/page-navigation-store.js +1 -20
  76. package/lib/src/shared/page-navigation/utils/nav-order-utils.d.ts +3 -0
  77. package/lib/src/shared/page-navigation/utils/nav-order-utils.js +20 -0
  78. package/lib/src/utils/minify-brand-page-metadata.d.ts +45 -0
  79. package/lib/src/utils/minify-brand-page-metadata.js +120 -119
  80. package/package.json +1 -1
  81. package/src/brand-page/components/image-gallery/ImageGalleryModal.mixin.ts +6 -2
  82. package/src/brand-page/models/brand-page-context.model.ts +1 -1
  83. package/src/brand-page-maker/components/ai-text-edit/AiChatbox.vue +2 -2
  84. package/src/brand-page-maker/components/ai-text-edit/AiProgressFeed.vue +162 -0
  85. package/src/brand-page-maker/components/ai-text-edit/AiTextEdit.vue +1 -8
  86. package/src/brand-page-maker/components/ai-text-edit/TextBubble.vue +44 -4
  87. package/src/brand-page-maker/components/ai-website-builder/AiWebsiteBuilder.vue +1 -2
  88. package/src/brand-page-maker/components/rich-text-editor/RichTextEditor.vue +1 -1
  89. package/src/brand-page-maker/composables/ai-chat/useAiChat.ts +17 -2
  90. package/src/brand-page-maker/composables/ai-chat/useAiWebsiteBuilderChat.ts +181 -57
  91. package/src/brand-page-maker/constants/sidebar-constant.ts +7 -7
  92. package/src/brand-page-maker/stores/brandpage-maker/brandpage-maker-store.ts +76 -0
  93. package/src/clients/ai-assistant-client.ts +37 -2
  94. package/src/clients/websocket-gateway-client.ts +17 -1
  95. package/src/metadata-builder/ai-metadata-executor.ts +36 -0
  96. package/src/metadata-builder/builders/footer-builder.ts +190 -0
  97. package/src/metadata-builder/builders/global-styles-builder.ts +162 -0
  98. package/src/metadata-builder/builders/header-builder.ts +204 -0
  99. package/src/metadata-builder/builders/reorder-pages-builder.ts +80 -0
  100. package/src/metadata-builder/builders/section-builders/about-section-builder.ts +1 -1
  101. package/src/metadata-builder/builders/section-builders/banner-section-builder.ts +49 -8
  102. package/src/metadata-builder/builders/section-builders/base-section-builder.ts +56 -4
  103. package/src/metadata-builder/builders/section-builders/booking-section-builder.ts +68 -0
  104. package/src/metadata-builder/builders/section-builders/button-section-builder.ts +1 -1
  105. package/src/metadata-builder/builders/section-builders/contact-form-builder.ts +1 -1
  106. package/src/metadata-builder/builders/section-builders/divider-section-builder.ts +8 -1
  107. package/src/metadata-builder/builders/section-builders/image-gallery-builder.ts +23 -27
  108. package/src/metadata-builder/builders/section-builders/images-section-builder.ts +62 -45
  109. package/src/metadata-builder/builders/section-builders/index.ts +1 -0
  110. package/src/metadata-builder/builders/section-builders/mailing-list-builder.ts +22 -2
  111. package/src/metadata-builder/builders/section-builders/mailing-list-section-builder.ts +22 -2
  112. package/src/metadata-builder/builders/section-builders/profile-section-builder.ts +44 -2
  113. package/src/metadata-builder/builders/section-builders/shapes-section-builder.ts +31 -10
  114. package/src/metadata-builder/builders/section-builders/social-links-builder.ts +1 -1
  115. package/src/metadata-builder/builders/section-builders/testimonial-section-builder.ts +1 -1
  116. package/src/metadata-builder/builders/section-builders/text-section-builder.ts +58 -21
  117. package/src/metadata-builder/builders/section-field-maps.ts +25 -1
  118. package/src/metadata-builder/builders/section-field-utils.ts +12 -56
  119. package/src/metadata-builder/helpers/rte.helpers.ts +18 -13
  120. package/src/metadata-builder/metadata-executor.ts +15 -0
  121. package/src/metadata-builder/models.ts +11 -0
  122. package/src/metadata-builder/parsers/ai-toolcall-parser.ts +121 -0
  123. package/src/metadata-builder/parsers/section-tool-arguments.ts +86 -14
  124. package/src/shared/navigation-style-settings/store/index.ts +5 -0
  125. package/src/shared/page-navigation/PageSelectorDropdown.vue +1 -1
  126. package/src/shared/page-navigation/store/page-navigation-store.ts +4 -31
  127. package/src/shared/page-navigation/utils/nav-order-utils.ts +32 -0
  128. package/src/shared/side-bar/components/SideBar.vue +20 -1
  129. package/src/utils/minify-brand-page-metadata.ts +185 -120
@@ -1,5 +1,5 @@
1
1
  import { openBlock as e, createElementBlock as l, createStaticVNode as a } from "vue";
2
- import { _ as t } from "./lib-C9NGI-t2.js";
2
+ import { _ as t } from "./lib-Cb6m6aD2.js";
3
3
  const i = {}, h = {
4
4
  width: "275",
5
5
  height: "36",
@@ -1,5 +1,5 @@
1
1
  import { openBlock as e, createElementBlock as l, createStaticVNode as a } from "vue";
2
- import { _ as t } from "./lib-C9NGI-t2.js";
2
+ import { _ as t } from "./lib-Cb6m6aD2.js";
3
3
  const i = {}, h = {
4
4
  width: "251",
5
5
  height: "36",
@@ -1,5 +1,5 @@
1
1
  import { openBlock as e, createElementBlock as l, createStaticVNode as a } from "vue";
2
- import { _ as t } from "./lib-C9NGI-t2.js";
2
+ import { _ as t } from "./lib-Cb6m6aD2.js";
3
3
  const i = {}, h = {
4
4
  width: "250",
5
5
  height: "36",
@@ -1,5 +1,5 @@
1
1
  import { openBlock as e, createElementBlock as l, createStaticVNode as a } from "vue";
2
- import { _ as t } from "./lib-C9NGI-t2.js";
2
+ import { _ as t } from "./lib-Cb6m6aD2.js";
3
3
  const i = {}, h = {
4
4
  width: "237",
5
5
  height: "36",
@@ -1,5 +1,5 @@
1
1
  import { openBlock as e, createElementBlock as l, createStaticVNode as a } from "vue";
2
- import { _ as t } from "./lib-C9NGI-t2.js";
2
+ import { _ as t } from "./lib-Cb6m6aD2.js";
3
3
  const i = {}, h = {
4
4
  width: "237",
5
5
  height: "36",
@@ -1,5 +1,5 @@
1
1
  import { openBlock as e, createElementBlock as l, createStaticVNode as a } from "vue";
2
- import { _ as t } from "./lib-C9NGI-t2.js";
2
+ import { _ as t } from "./lib-Cb6m6aD2.js";
3
3
  const i = {}, h = {
4
4
  width: "263",
5
5
  height: "36",
@@ -1,5 +1,5 @@
1
1
  import { openBlock as e, createElementBlock as l, createStaticVNode as a } from "vue";
2
- import { _ as t } from "./lib-C9NGI-t2.js";
2
+ import { _ as t } from "./lib-Cb6m6aD2.js";
3
3
  const i = {}, h = {
4
4
  width: "263",
5
5
  height: "36",
@@ -1,5 +1,5 @@
1
1
  import { openBlock as H, createElementBlock as V, createStaticVNode as t } from "vue";
2
- import { _ as e } from "./lib-C9NGI-t2.js";
2
+ import { _ as e } from "./lib-Cb6m6aD2.js";
3
3
  const M = {}, Z = {
4
4
  width: "242",
5
5
  height: "36",
@@ -1,5 +1,5 @@
1
1
  import { openBlock as H, createElementBlock as V, createStaticVNode as t } from "vue";
2
- import { _ as e } from "./lib-C9NGI-t2.js";
2
+ import { _ as e } from "./lib-Cb6m6aD2.js";
3
3
  const i = {}, M = {
4
4
  width: "231",
5
5
  height: "36",
@@ -1,5 +1,5 @@
1
1
  import { openBlock as H, createElementBlock as V, createStaticVNode as t } from "vue";
2
- import { _ as e } from "./lib-C9NGI-t2.js";
2
+ import { _ as e } from "./lib-Cb6m6aD2.js";
3
3
  const M = {}, Z = {
4
4
  width: "230",
5
5
  height: "36",
@@ -1,5 +1,5 @@
1
1
  import { openBlock as H, createElementBlock as V, createStaticVNode as t } from "vue";
2
- import { _ as e } from "./lib-C9NGI-t2.js";
2
+ import { _ as e } from "./lib-Cb6m6aD2.js";
3
3
  const i = {}, l = {
4
4
  width: "216",
5
5
  height: "36",
@@ -1,5 +1,5 @@
1
1
  import { openBlock as H, createElementBlock as V, createStaticVNode as t } from "vue";
2
- import { _ as e } from "./lib-C9NGI-t2.js";
2
+ import { _ as e } from "./lib-Cb6m6aD2.js";
3
3
  const i = {}, l = {
4
4
  width: "216",
5
5
  height: "36",
@@ -1,5 +1,5 @@
1
1
  import { openBlock as H, createElementBlock as V, createStaticVNode as t } from "vue";
2
- import { _ as M } from "./lib-C9NGI-t2.js";
2
+ import { _ as M } from "./lib-Cb6m6aD2.js";
3
3
  const Z = {}, e = {
4
4
  width: "232",
5
5
  height: "36",
@@ -1,5 +1,5 @@
1
1
  import { openBlock as H, createElementBlock as V, createStaticVNode as t } from "vue";
2
- import { _ as M } from "./lib-C9NGI-t2.js";
2
+ import { _ as M } from "./lib-Cb6m6aD2.js";
3
3
  const Z = {}, e = {
4
4
  width: "232",
5
5
  height: "36",
@@ -95,14 +95,14 @@ export default defineComponent({
95
95
  images: {
96
96
  deep: true,
97
97
  handler(newImages) {
98
- this.carouselImages = cloneDeep(newImages);
98
+ this.carouselImages = cloneDeep(newImages).map(({ width, height, ...rest }) => rest);
99
99
  },
100
100
  },
101
101
  },
102
102
  created() {
103
103
  // FIXME - types for this were added on 6/6/24 and usage of cloneDeep here fails type check
104
104
  // @ts-ignore
105
- this.carouselImages = cloneDeep(this.images);
105
+ this.carouselImages = cloneDeep(this.images).map(({ width, height, ...rest }) => rest);
106
106
  },
107
107
  methods: {
108
108
  checkImageModalImageComplete() {
@@ -26,7 +26,7 @@ const AB_TEST_KEYS = {
26
26
  BP_3926_FREEMIUM_WATERMARK: 'bc-bp-3926-freemium-cta-in-website-editor',
27
27
  BP_4572_AI_TEXT_GENERATION_POST_PURCHASE: 'bc-bp-4572-ai-text-generation-post-purchase',
28
28
  BP_4964_AI_TEXT_GENERATION_IMPROVEMENT: 'bc-bp-4964-ai-text-improvement-post-purchase-on-website',
29
- BP_5245_AI_WEBSITE_ASSISTANT: 'bc-bp-5245-ai-website-assistant',
29
+ BP_5245_AI_WEBSITE_ASSISTANT: 'bc-bp-5245-ai-website-assistant-postpurchase',
30
30
  };
31
31
  export const MEDIA_SIZES = {
32
32
  size1x: 'size1x',
@@ -32,7 +32,7 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
32
32
  }>, {
33
33
  commonTr: (key: any) => any;
34
34
  currentNotificationMessage: import("vue").ComputedRef<false | {
35
- type: "success" | "warning" | "error";
35
+ type: "error" | "success" | "warning";
36
36
  label: string;
37
37
  description: string | false;
38
38
  }>;
@@ -1,4 +1,5 @@
1
1
  import { type ComputedRef, type Ref } from 'vue';
2
+ import { type PlanItem } from '../../../clients/websocket-gateway-client';
2
3
  export interface BaseThreadMessage {
3
4
  id: string;
4
5
  role: 'user' | 'agent';
@@ -10,7 +11,11 @@ export interface BaseThreadMessage {
10
11
  export interface TextThreadMessage extends BaseThreadMessage {
11
12
  type: 'text';
12
13
  text: string;
14
+ initialMessage?: string;
15
+ planItems?: PlanItem[];
16
+ completedItemIds?: string[];
13
17
  }
18
+ export { type PlanItem };
14
19
  export interface ImageThreadMessage extends BaseThreadMessage {
15
20
  type: 'image';
16
21
  images: {
@@ -1,5 +1,6 @@
1
1
  import { ref, computed, watch, nextTick, } from 'vue';
2
2
  import { getInstance as getAiAssistantClient, AI_ASSISTANT_AGENT_TYPES, buildWebsiteTextElementMessage, } from '../../../clients/ai-assistant-client';
3
+ import {} from '../../../clients/websocket-gateway-client';
3
4
  import { getCurrentLocale } from '../../../composables/useTranslate';
4
5
  import { storeToRefs } from 'pinia';
5
6
  import { useSnapshotStore, useAiThreadStore } from '../../stores';
@@ -7,6 +8,7 @@ import { useBrandPageMakerStore } from '../../stores';
7
8
  import { useUiPageSettingsStore } from '../../../shared/page-settings/store';
8
9
  import { useAiMetadataBuilder } from '../ai-chat/useAiMetadataBuilder';
9
10
  import { Logger } from '../../../metadata-builder/logger';
11
+ export {};
10
12
  const MAX_TOOL_CALL_ITERATIONS = 5;
11
13
  const TEXT_DISPLAY_LIMIT = 150;
12
14
  const truncateText = (text) => {
@@ -186,10 +188,15 @@ export function useAiChat(options) {
186
188
  await submitCancelledToolCallsAsync();
187
189
  return { aiMessage: '' };
188
190
  }
189
- const nextResponse = await submitToolResults(toolResults);
191
+ // Only submit failed tool results — skip submission entirely if all succeeded
192
+ const failedResults = toolResults.filter((tr) => tr.success !== 'success');
193
+ if (failedResults.length === 0) {
194
+ break;
195
+ }
196
+ const nextResponse = await submitToolResults(failedResults);
190
197
  pendingToolCalls.value = []; // Cleared after successful submission
191
198
  aiLogger.log('handleToolResponseAsync submitToolResults', {
192
- toolResults,
199
+ toolResults: failedResults,
193
200
  nextResponse,
194
201
  });
195
202
  if (!nextResponse)
@@ -4,16 +4,17 @@ import { WebSocketGatewayClient, } from '../../../clients/websocket-gateway-clie
4
4
  import { minifyBrandPageMetadata } from '../../../utils/minify-brand-page-metadata';
5
5
  import { useSnapshotStore, useAiWebsiteBuilderThreadStore } from '../../stores';
6
6
  import { useBrandPageMakerStore } from '../../stores';
7
+ import { useBrandPageMakerUserStore } from '../../stores/user/user-store';
7
8
  import { useAiMetadataBuilder } from './useAiMetadataBuilder';
8
9
  import { Logger } from '../../../metadata-builder/logger';
9
10
  const BUILD_TIMEOUT_MS = 600000;
10
11
  const aiLogger = new Logger();
11
12
  let activeBuildWsClient = null;
12
- const MAX_TOOL_CALL_ITERATIONS = 5;
13
13
  export function useAiWebsiteBuilderChat() {
14
14
  const aiThreadStore = useAiWebsiteBuilderThreadStore();
15
15
  const snapshotStore = useSnapshotStore();
16
16
  const brandPageMakerStore = useBrandPageMakerStore();
17
+ const userStore = useBrandPageMakerUserStore();
17
18
  const aiMetadataBuilder = useAiMetadataBuilder(aiLogger);
18
19
  const hasStoredMessages = aiThreadStore.messages.length > 0;
19
20
  const threadItems = ref(aiThreadStore.messages.length > 0
@@ -77,10 +78,12 @@ export function useAiWebsiteBuilderChat() {
77
78
  let aiMessage = response.message || '';
78
79
  const modelToUpdate = brandPageMakerStore.brandPageData;
79
80
  const updateResult = await aiMetadataBuilder.applyAiToolCallsAsync(modelToUpdate, response.toolCalls || []);
80
- const toolResults = updateResult.results.map((x) => {
81
+ const toolResults = updateResult.results.map((x, i) => {
81
82
  return {
82
83
  toolId: x.toolId,
83
84
  success: x.errors && x.errors.length > 0 ? 'failed' : 'success',
85
+ name: (response.toolCalls || [])[i]?.function,
86
+ errorMessage: x.errors?.length ? x.errors.join('; ') : undefined,
84
87
  };
85
88
  });
86
89
  updateResult.parsedToolCalls.forEach((toolCall) => {
@@ -89,7 +92,6 @@ export function useAiWebsiteBuilderChat() {
89
92
  aiMessage = aiMessage ? `${aiMessage} ${args.message}` : args.message;
90
93
  }
91
94
  });
92
- console.log('updateResult.model', JSON.parse(JSON.stringify(updateResult.model)));
93
95
  await brandPageMakerStore.initialiseStoresByBrandPageModelAsync(updateResult.model);
94
96
  await nextTick();
95
97
  // Re-capture snapshot so subsequent messages reflect the updated page
@@ -106,13 +108,16 @@ export function useAiWebsiteBuilderChat() {
106
108
  try {
107
109
  const client = getAiAssistantClient();
108
110
  const message = buildMessage(userPrompt);
109
- wsClient.sendHeartbeat();
111
+ const userPlan = userStore.hasPremiumSubscription
112
+ ? 'premium'
113
+ : 'free';
110
114
  let buildResponse;
111
115
  if (!aiThreadStore.threadId) {
112
116
  buildResponse = await client.createWebsiteThreadBuildAsync({
113
117
  message,
114
118
  websiteSnapshot: snapshotStore.snapshotBase64 || undefined,
115
119
  agentType: AI_ASSISTANT_AGENT_TYPES.WEBSITE_BUILDER,
120
+ userPlan,
116
121
  connectionId,
117
122
  });
118
123
  }
@@ -121,6 +126,7 @@ export function useAiWebsiteBuilderChat() {
121
126
  message,
122
127
  websiteSnapshot: snapshotStore.snapshotBase64 || undefined,
123
128
  agentType: AI_ASSISTANT_AGENT_TYPES.WEBSITE_BUILDER,
129
+ userPlan,
124
130
  connectionId,
125
131
  });
126
132
  }
@@ -131,8 +137,18 @@ export function useAiWebsiteBuilderChat() {
131
137
  const langChainUrl = buildResponse.langChainUrl;
132
138
  wsClient.setBuildActive(true);
133
139
  wsClient.startResponseHeartbeat();
140
+ const withTypingMessage = (fn) => {
141
+ const typingId = currentTypingMessageId.value;
142
+ if (!typingId)
143
+ return;
144
+ const idx = threadItems.value.findIndex((m) => m.id === typingId);
145
+ if (idx !== -1)
146
+ fn(threadItems.value[idx]);
147
+ };
134
148
  return new Promise((resolve, reject) => {
135
149
  let settled = false;
150
+ let retryCount = 0;
151
+ let lastAiMessage = null;
136
152
  let handler = null;
137
153
  const finishBuild = () => {
138
154
  aiThreadStore.isBuildInProgress = false;
@@ -151,53 +167,132 @@ export function useAiWebsiteBuilderChat() {
151
167
  handler = (msg) => {
152
168
  if (settled)
153
169
  return;
154
- if (msg.buildId !== aiThreadStore.buildId)
155
- return;
156
- if (isStopped.value) {
157
- settled = true;
158
- clearTimeout(timeout);
159
- finishBuild();
160
- resolve({ text: null });
161
- return;
162
- }
163
- if (msg.type === 'build_complete') {
164
- settled = true;
165
- clearTimeout(timeout);
166
- const toolCalls = (msg.toolCalls || []);
167
- const aiResponse = {
168
- threadId: aiThreadStore.threadId || '',
169
- toolCalls,
170
- message: msg.message || null,
171
- type: 'tool_calls',
172
- totalPaidToolCalls: 0,
173
- timestamp: Date.now(),
174
- };
175
- (async () => {
176
- try {
177
- if (toolCalls.length > 0) {
178
- await applyToolCallsAsync(aiResponse);
170
+ try {
171
+ if (msg.buildId !== aiThreadStore.buildId)
172
+ return;
173
+ if (isStopped.value) {
174
+ settled = true;
175
+ clearTimeout(timeout);
176
+ finishBuild();
177
+ resolve({ text: null });
178
+ return;
179
+ }
180
+ if (msg.type === 'chat_started' && msg.message) {
181
+ withTypingMessage((m) => {
182
+ m.initialMessage = msg.message;
183
+ });
184
+ return;
185
+ }
186
+ if (msg.type === 'plan_announced' && msg.items) {
187
+ withTypingMessage((m) => {
188
+ if (!m.planItems)
189
+ m.planItems = msg.items;
190
+ });
191
+ return;
192
+ }
193
+ if (msg.type === 'item_complete' && msg.itemId) {
194
+ const itemId = msg.itemId;
195
+ withTypingMessage((m) => {
196
+ if (!m.completedItemIds?.includes(itemId)) {
197
+ m.completedItemIds = [
198
+ ...(m.completedItemIds ?? []),
199
+ itemId,
200
+ ];
201
+ }
202
+ });
203
+ return;
204
+ }
205
+ if (msg.type === 'server_response') {
206
+ const toolCalls = (msg.toolCalls ||
207
+ []);
208
+ const aiResponse = {
209
+ threadId: aiThreadStore.threadId || '',
210
+ toolCalls,
211
+ message: msg.message || null,
212
+ type: 'tool_calls',
213
+ totalPaidToolCalls: 0,
214
+ timestamp: Date.now(),
215
+ };
216
+ (async () => {
217
+ try {
218
+ // No tool calls = build cycle complete (success, max retries, or no retryable sections)
219
+ if (toolCalls.length === 0) {
220
+ settled = true;
221
+ clearTimeout(timeout);
222
+ finishBuild();
223
+ await snapshotStore.refreshSnapshotAsync();
224
+ resolve({
225
+ text: aiResponse.message ||
226
+ lastAiMessage ||
227
+ 'Your website has been updated.',
228
+ langChainUrl,
229
+ });
230
+ return;
231
+ }
232
+ // Tool calls present — apply locally and submit results back
233
+ const { toolResults, aiMessage } = await applyToolCallsAsync(aiResponse);
234
+ lastAiMessage = aiMessage;
235
+ // Only submit failed tool results — the server retries only failed sections.
236
+ const failedResults = toolResults.filter((tr) => tr.success !== 'success');
237
+ if (failedResults.length === 0) {
238
+ settled = true;
239
+ clearTimeout(timeout);
240
+ finishBuild();
241
+ resolve({
242
+ text: aiMessage || 'Your website has been updated.',
243
+ langChainUrl,
244
+ });
245
+ return;
246
+ }
247
+ aiLogger.log('tool submission for failed results', {
248
+ failedResults,
249
+ retryCount,
250
+ });
251
+ const submitResult = await client.submitToolResultsBuildAsync(aiThreadStore.threadId, {
252
+ toolCalls: failedResults,
253
+ agentType: AI_ASSISTANT_AGENT_TYPES.WEBSITE_BUILDER,
254
+ connectionId,
255
+ retryCount,
256
+ userPlan,
257
+ });
258
+ // Update buildId so the handler matches subsequent WS messages
259
+ if (submitResult.buildId) {
260
+ aiThreadStore.buildId = submitResult.buildId;
261
+ }
262
+ // eslint-disable-next-line no-plusplus
263
+ retryCount++;
264
+ }
265
+ catch (err) {
266
+ aiLogger.log('server_response apply error', { err });
267
+ settled = true;
268
+ clearTimeout(timeout);
269
+ finishBuild();
270
+ resolve({ text: 'An error occurred applying changes.' });
179
271
  }
180
- finishBuild();
181
- await snapshotStore.refreshSnapshotAsync();
182
- resolve({
183
- text: aiResponse.message || 'Your website has been updated.',
184
- langChainUrl,
185
- });
186
- }
187
- catch (err) {
188
- aiLogger.log('build_complete apply error', { err });
189
- finishBuild();
190
- resolve({ text: 'An error occurred applying changes.' });
191
- }
192
- })();
272
+ })();
273
+ return;
274
+ }
275
+ if (msg.type === 'server_error' || msg.type === 'build_error') {
276
+ settled = true;
277
+ clearTimeout(timeout);
278
+ finishBuild();
279
+ resolve({
280
+ text: msg.error || 'An error occurred during the build.',
281
+ });
282
+ return;
283
+ }
193
284
  }
194
- if (msg.type === 'build_error') {
195
- settled = true;
196
- clearTimeout(timeout);
197
- finishBuild();
198
- resolve({
199
- text: msg.error || 'An error occurred during the build.',
285
+ catch (err) {
286
+ aiLogger.log('Unexpected error in WS message handler', {
287
+ err,
288
+ type: msg.type,
200
289
  });
290
+ if (!settled) {
291
+ settled = true;
292
+ clearTimeout(timeout);
293
+ finishBuild();
294
+ resolve({ text: 'An error occurred during the build.' });
295
+ }
201
296
  }
202
297
  };
203
298
  wsClient.onMessage(handler);
@@ -287,7 +382,6 @@ export function useAiWebsiteBuilderChat() {
287
382
  // was destroyed (tab switch) and the writable computed setter is inert.
288
383
  aiThreadStore.isProcessing = false;
289
384
  }
290
- console.log('aiLogger', aiLogger);
291
385
  };
292
386
  const deleteMessage = (messageId) => {
293
387
  const index = threadItems.value.findIndex((msg) => msg.id === messageId);
@@ -331,6 +425,12 @@ export function useAiWebsiteBuilderChat() {
331
425
  isResponse: index >= 1,
332
426
  disableAnimation: index < initialMessageCount,
333
427
  langChainUrl: msg.langChainUrl,
428
+ ...(msg.type === 'text' &&
429
+ msg.isTyping && {
430
+ initialMessage: msg.initialMessage,
431
+ planItems: msg.planItems ?? [],
432
+ completedItemIds: msg.completedItemIds ?? [],
433
+ }),
334
434
  },
335
435
  }));
336
436
  });
@@ -43,13 +43,6 @@ export const DEFAULT_SIDE_BAR_TABS = () => [
43
43
  accessibleDisplayName: 'AI Text Edit',
44
44
  isVisible: false,
45
45
  },
46
- {
47
- name: SIDE_BAR_TAB_NAMES.AI_WEBSITE_BUILDER,
48
- displayName: 'AI Builder',
49
- iconName: 'ai',
50
- accessibleDisplayName: 'AI Website Builder',
51
- isVisible: true,
52
- },
53
46
  {
54
47
  name: SIDE_BAR_TAB_NAMES.BACKGROUND_SETTINGS,
55
48
  displayName: constantsTr(`backgroundDisplayName`),
@@ -98,4 +91,11 @@ export const DEFAULT_SIDE_BAR_TABS = () => [
98
91
  accessibleDisplayName: 'Settings',
99
92
  isVisible: true,
100
93
  },
94
+ {
95
+ name: SIDE_BAR_TAB_NAMES.AI_WEBSITE_BUILDER,
96
+ displayName: 'AI',
97
+ iconName: 'ai',
98
+ accessibleDisplayName: 'AI Website Builder',
99
+ isVisible: true,
100
+ },
101
101
  ];
@@ -5,6 +5,14 @@ export declare const useAiThreadStore: import("pinia").StoreDefinition<"aiThread
5
5
  messages: import("vue").Ref<({
6
6
  type: "text";
7
7
  text: string;
8
+ initialMessage?: string | undefined;
9
+ planItems?: {
10
+ id: string;
11
+ pendingLabel: string;
12
+ completeLabel: string;
13
+ subIds?: string[] | undefined;
14
+ }[] | undefined;
15
+ completedItemIds?: string[] | undefined;
8
16
  id: string;
9
17
  role: "user" | "agent";
10
18
  isTyping?: boolean | undefined;
@@ -27,6 +35,14 @@ export declare const useAiThreadStore: import("pinia").StoreDefinition<"aiThread
27
35
  })[], ThreadMessage[] | ({
28
36
  type: "text";
29
37
  text: string;
38
+ initialMessage?: string | undefined;
39
+ planItems?: {
40
+ id: string;
41
+ pendingLabel: string;
42
+ completeLabel: string;
43
+ subIds?: string[] | undefined;
44
+ }[] | undefined;
45
+ completedItemIds?: string[] | undefined;
30
46
  id: string;
31
47
  role: "user" | "agent";
32
48
  isTyping?: boolean | undefined;
@@ -56,6 +72,14 @@ export declare const useAiThreadStore: import("pinia").StoreDefinition<"aiThread
56
72
  messages: import("vue").Ref<({
57
73
  type: "text";
58
74
  text: string;
75
+ initialMessage?: string | undefined;
76
+ planItems?: {
77
+ id: string;
78
+ pendingLabel: string;
79
+ completeLabel: string;
80
+ subIds?: string[] | undefined;
81
+ }[] | undefined;
82
+ completedItemIds?: string[] | undefined;
59
83
  id: string;
60
84
  role: "user" | "agent";
61
85
  isTyping?: boolean | undefined;
@@ -78,6 +102,14 @@ export declare const useAiThreadStore: import("pinia").StoreDefinition<"aiThread
78
102
  })[], ThreadMessage[] | ({
79
103
  type: "text";
80
104
  text: string;
105
+ initialMessage?: string | undefined;
106
+ planItems?: {
107
+ id: string;
108
+ pendingLabel: string;
109
+ completeLabel: string;
110
+ subIds?: string[] | undefined;
111
+ }[] | undefined;
112
+ completedItemIds?: string[] | undefined;
81
113
  id: string;
82
114
  role: "user" | "agent";
83
115
  isTyping?: boolean | undefined;
@@ -107,6 +139,14 @@ export declare const useAiThreadStore: import("pinia").StoreDefinition<"aiThread
107
139
  messages: import("vue").Ref<({
108
140
  type: "text";
109
141
  text: string;
142
+ initialMessage?: string | undefined;
143
+ planItems?: {
144
+ id: string;
145
+ pendingLabel: string;
146
+ completeLabel: string;
147
+ subIds?: string[] | undefined;
148
+ }[] | undefined;
149
+ completedItemIds?: string[] | undefined;
110
150
  id: string;
111
151
  role: "user" | "agent";
112
152
  isTyping?: boolean | undefined;
@@ -129,6 +169,14 @@ export declare const useAiThreadStore: import("pinia").StoreDefinition<"aiThread
129
169
  })[], ThreadMessage[] | ({
130
170
  type: "text";
131
171
  text: string;
172
+ initialMessage?: string | undefined;
173
+ planItems?: {
174
+ id: string;
175
+ pendingLabel: string;
176
+ completeLabel: string;
177
+ subIds?: string[] | undefined;
178
+ }[] | undefined;
179
+ completedItemIds?: string[] | undefined;
132
180
  id: string;
133
181
  role: "user" | "agent";
134
182
  isTyping?: boolean | undefined;