@designcrowd/library.brand-page 5.17.10 → 5.17.11-ai-4

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 (91) hide show
  1. package/lib/src/{CreatedOnBrandCrowd-de-de-DoQhYZz4.js → CreatedOnBrandCrowd-de-de-CHy8IfZN.js} +1 -1
  2. package/lib/src/{CreatedOnBrandCrowd-en-us-B9ar12Is.js → CreatedOnBrandCrowd-en-us-BzC55g1K.js} +1 -1
  3. package/lib/src/{CreatedOnBrandCrowd-es-es-DutTtFX2.js → CreatedOnBrandCrowd-es-es-BAyaxKOu.js} +1 -1
  4. package/lib/src/{CreatedOnBrandCrowd-fr-fr-DPeUPXoU.js → CreatedOnBrandCrowd-fr-ca-DDJl4gX-.js} +1 -1
  5. package/lib/src/{CreatedOnBrandCrowd-fr-ca-DPeUPXoU.js → CreatedOnBrandCrowd-fr-fr-DDJl4gX-.js} +1 -1
  6. package/lib/src/{CreatedOnBrandCrowd-pt-pt-JkpeLUeO.js → CreatedOnBrandCrowd-pt-br-B3AbDqRJ.js} +1 -1
  7. package/lib/src/{CreatedOnBrandCrowd-pt-br-JkpeLUeO.js → CreatedOnBrandCrowd-pt-pt-B3AbDqRJ.js} +1 -1
  8. package/lib/src/{CreatedOnDcom-de-de-UDxsoo5Q.js → CreatedOnDcom-de-de-DsxcoJH9.js} +1 -1
  9. package/lib/src/{CreatedOnDcom-en-us-XAyatLAS.js → CreatedOnDcom-en-us-DgSltBWf.js} +1 -1
  10. package/lib/src/{CreatedOnDcom-es-es-CbZFMey5.js → CreatedOnDcom-es-es-DZWb1MzC.js} +1 -1
  11. package/lib/src/{CreatedOnDcom-fr-ca-CxA4chk3.js → CreatedOnDcom-fr-ca-pBrJ09Tk.js} +1 -1
  12. package/lib/src/{CreatedOnDcom-fr-fr-DWeUjjjN.js → CreatedOnDcom-fr-fr-CMQs7AcX.js} +1 -1
  13. package/lib/src/{CreatedOnDcom-pt-br-Bg0aa15z.js → CreatedOnDcom-pt-br-QI5iEC5y.js} +1 -1
  14. package/lib/src/{CreatedOnDcom-pt-pt-jfNQUP0S.js → CreatedOnDcom-pt-pt-eMMm8BrQ.js} +1 -1
  15. package/lib/src/brand-page-maker/composables/ai-chat/useAiWebsiteBuilderChat.js +153 -80
  16. package/lib/src/brand-page-maker/stores/ai-thread/ai-website-builder-thread-store.d.ts +10 -1
  17. package/lib/src/brand-page-maker/stores/ai-thread/ai-website-builder-thread-store.js +6 -0
  18. package/lib/src/clients/ai-assistant-client.d.ts +19 -0
  19. package/lib/src/clients/ai-assistant-client.js +29 -0
  20. package/lib/src/clients/websocket-gateway-client.d.ts +45 -0
  21. package/lib/src/clients/websocket-gateway-client.js +196 -0
  22. package/lib/src/index.d.ts +2 -0
  23. package/lib/src/index.mjs +58 -57
  24. package/lib/src/{lib-CWXnmOv-.js → lib-DKxDzUGF.js} +19387 -19195
  25. package/lib/src/lib.js +1 -0
  26. package/lib/src/metadata-builder/ai-metadata-executor.js +2 -1
  27. package/lib/src/metadata-builder/builders/section-builders/about-section-builder.js +1 -1
  28. package/lib/src/metadata-builder/builders/section-builders/banner-section-builder.js +15 -4
  29. package/lib/src/metadata-builder/builders/section-builders/base-section-builder.d.ts +5 -2
  30. package/lib/src/metadata-builder/builders/section-builders/base-section-builder.js +39 -4
  31. package/lib/src/metadata-builder/builders/section-builders/booking-section-builder.d.ts +6 -0
  32. package/lib/src/metadata-builder/builders/section-builders/booking-section-builder.js +36 -0
  33. package/lib/src/metadata-builder/builders/section-builders/button-section-builder.js +1 -1
  34. package/lib/src/metadata-builder/builders/section-builders/contact-form-builder.js +1 -1
  35. package/lib/src/metadata-builder/builders/section-builders/divider-section-builder.js +1 -1
  36. package/lib/src/metadata-builder/builders/section-builders/image-gallery-builder.js +1 -1
  37. package/lib/src/metadata-builder/builders/section-builders/images-section-builder.js +14 -3
  38. package/lib/src/metadata-builder/builders/section-builders/index.d.ts +1 -0
  39. package/lib/src/metadata-builder/builders/section-builders/index.js +1 -0
  40. package/lib/src/metadata-builder/builders/section-builders/mailing-list-builder.js +1 -1
  41. package/lib/src/metadata-builder/builders/section-builders/mailing-list-section-builder.js +1 -1
  42. package/lib/src/metadata-builder/builders/section-builders/profile-section-builder.js +18 -1
  43. package/lib/src/metadata-builder/builders/section-builders/shapes-section-builder.js +14 -3
  44. package/lib/src/metadata-builder/builders/section-builders/social-links-builder.js +1 -1
  45. package/lib/src/metadata-builder/builders/section-builders/testimonial-section-builder.js +1 -1
  46. package/lib/src/metadata-builder/builders/section-builders/text-section-builder.js +18 -12
  47. package/lib/src/metadata-builder/builders/section-field-maps.js +13 -0
  48. package/lib/src/metadata-builder/builders/section-field-utils.d.ts +1 -8
  49. package/lib/src/metadata-builder/builders/section-field-utils.js +7 -42
  50. package/lib/src/metadata-builder/helpers/rte.helpers.d.ts +6 -4
  51. package/lib/src/metadata-builder/helpers/rte.helpers.js +15 -10
  52. package/lib/src/metadata-builder/metadata-executor.js +3 -1
  53. package/lib/src/metadata-builder/models.d.ts +2 -0
  54. package/lib/src/metadata-builder/models.js +2 -0
  55. package/lib/src/metadata-builder/parsers/ai-toolcall-parser.d.ts +1 -0
  56. package/lib/src/metadata-builder/parsers/ai-toolcall-parser.js +4 -0
  57. package/lib/src/metadata-builder/parsers/section-tool-arguments.d.ts +55 -13
  58. package/lib/src/metadata-builder/parsers/section-tool-arguments.js +5 -1
  59. package/lib/src/utils/minify-brand-page-metadata.js +63 -120
  60. package/package.json +1 -1
  61. package/src/brand-page-maker/composables/ai-chat/useAiWebsiteBuilderChat.ts +189 -112
  62. package/src/brand-page-maker/stores/ai-thread/ai-website-builder-thread-store.ts +6 -0
  63. package/src/clients/ai-assistant-client.ts +66 -0
  64. package/src/clients/websocket-gateway-client.ts +265 -0
  65. package/src/lib.ts +10 -0
  66. package/src/metadata-builder/ai-metadata-executor.ts +2 -0
  67. package/src/metadata-builder/builders/section-builders/about-section-builder.ts +1 -1
  68. package/src/metadata-builder/builders/section-builders/banner-section-builder.ts +20 -8
  69. package/src/metadata-builder/builders/section-builders/base-section-builder.ts +56 -4
  70. package/src/metadata-builder/builders/section-builders/booking-section-builder.ts +54 -0
  71. package/src/metadata-builder/builders/section-builders/button-section-builder.ts +1 -1
  72. package/src/metadata-builder/builders/section-builders/contact-form-builder.ts +1 -1
  73. package/src/metadata-builder/builders/section-builders/divider-section-builder.ts +1 -1
  74. package/src/metadata-builder/builders/section-builders/image-gallery-builder.ts +1 -1
  75. package/src/metadata-builder/builders/section-builders/images-section-builder.ts +19 -10
  76. package/src/metadata-builder/builders/section-builders/index.ts +1 -0
  77. package/src/metadata-builder/builders/section-builders/mailing-list-builder.ts +1 -1
  78. package/src/metadata-builder/builders/section-builders/mailing-list-section-builder.ts +1 -1
  79. package/src/metadata-builder/builders/section-builders/profile-section-builder.ts +24 -2
  80. package/src/metadata-builder/builders/section-builders/shapes-section-builder.ts +19 -10
  81. package/src/metadata-builder/builders/section-builders/social-links-builder.ts +1 -1
  82. package/src/metadata-builder/builders/section-builders/testimonial-section-builder.ts +1 -1
  83. package/src/metadata-builder/builders/section-builders/text-section-builder.ts +24 -15
  84. package/src/metadata-builder/builders/section-field-maps.ts +16 -0
  85. package/src/metadata-builder/builders/section-field-utils.ts +12 -56
  86. package/src/metadata-builder/helpers/rte.helpers.ts +18 -13
  87. package/src/metadata-builder/metadata-executor.ts +3 -0
  88. package/src/metadata-builder/models.ts +2 -0
  89. package/src/metadata-builder/parsers/ai-toolcall-parser.ts +4 -0
  90. package/src/metadata-builder/parsers/section-tool-arguments.ts +79 -13
  91. package/src/utils/minify-brand-page-metadata.ts +83 -122
@@ -1,5 +1,5 @@
1
1
  import { openBlock as e, createElementBlock as l, createStaticVNode as a } from "vue";
2
- import { _ as t } from "./lib-CWXnmOv-.js";
2
+ import { _ as t } from "./lib-DKxDzUGF.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-CWXnmOv-.js";
2
+ import { _ as t } from "./lib-DKxDzUGF.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-CWXnmOv-.js";
2
+ import { _ as t } from "./lib-DKxDzUGF.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-CWXnmOv-.js";
2
+ import { _ as t } from "./lib-DKxDzUGF.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-CWXnmOv-.js";
2
+ import { _ as t } from "./lib-DKxDzUGF.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-CWXnmOv-.js";
2
+ import { _ as t } from "./lib-DKxDzUGF.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-CWXnmOv-.js";
2
+ import { _ as t } from "./lib-DKxDzUGF.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-CWXnmOv-.js";
2
+ import { _ as e } from "./lib-DKxDzUGF.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-CWXnmOv-.js";
2
+ import { _ as e } from "./lib-DKxDzUGF.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-CWXnmOv-.js";
2
+ import { _ as e } from "./lib-DKxDzUGF.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-CWXnmOv-.js";
2
+ import { _ as e } from "./lib-DKxDzUGF.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-CWXnmOv-.js";
2
+ import { _ as e } from "./lib-DKxDzUGF.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-CWXnmOv-.js";
2
+ import { _ as M } from "./lib-DKxDzUGF.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-CWXnmOv-.js";
2
+ import { _ as M } from "./lib-DKxDzUGF.js";
3
3
  const Z = {}, e = {
4
4
  width: "232",
5
5
  height: "36",
@@ -1,13 +1,15 @@
1
1
  import { ref, computed, watch, nextTick, onUnmounted } from 'vue';
2
2
  import { getInstance as getAiAssistantClient, AI_ASSISTANT_AGENT_TYPES, buildWebsiteBuilderMessage, } from '../../../clients/ai-assistant-client';
3
+ import { WebSocketGatewayClient, } from '../../../clients/websocket-gateway-client';
3
4
  import { minifyBrandPageMetadata } from '../../../utils/minify-brand-page-metadata';
4
5
  import { useSnapshotStore, useAiWebsiteBuilderThreadStore } from '../../stores';
5
6
  import { useBrandPageMakerStore } from '../../stores';
6
- import { useUiPageSettingsStore } from '../../../shared/page-settings/store';
7
7
  import { useAiMetadataBuilder } from './useAiMetadataBuilder';
8
8
  import { Logger } from '../../../metadata-builder/logger';
9
- const MAX_TOOL_CALL_ITERATIONS = 5;
9
+ const BUILD_TIMEOUT_MS = 600000;
10
10
  const aiLogger = new Logger();
11
+ let activeBuildWsClient = null;
12
+ const MAX_TOOL_CALL_ITERATIONS = 5;
11
13
  export function useAiWebsiteBuilderChat() {
12
14
  const aiThreadStore = useAiWebsiteBuilderThreadStore();
13
15
  const snapshotStore = useSnapshotStore();
@@ -38,6 +40,35 @@ export function useAiWebsiteBuilderChat() {
38
40
  const isStopped = ref(false);
39
41
  const generatedText = ref(null);
40
42
  const generatedStyle = ref(null);
43
+ const SERVICE_UNAVAILABLE_MESSAGE = 'This service is not available right now. Please try again later.';
44
+ const addServiceUnavailableBubble = () => {
45
+ threadItems.value.push({
46
+ id: Date.now().toString(),
47
+ type: 'text',
48
+ role: 'agent',
49
+ text: SERVICE_UNAVAILABLE_MESSAGE,
50
+ isTyping: false,
51
+ isError: true,
52
+ timestamp: new Date(),
53
+ });
54
+ };
55
+ const ensureConnectedAsync = async () => {
56
+ const existingId = activeBuildWsClient?.getConnectionId();
57
+ if (activeBuildWsClient && existingId) {
58
+ return existingId;
59
+ }
60
+ if (activeBuildWsClient) {
61
+ activeBuildWsClient.disconnect();
62
+ }
63
+ const wsClient = new WebSocketGatewayClient();
64
+ const connectionId = await wsClient.connect();
65
+ wsClient.onDisconnect(() => {
66
+ activeBuildWsClient = null;
67
+ addServiceUnavailableBubble();
68
+ });
69
+ activeBuildWsClient = wsClient;
70
+ return connectionId;
71
+ };
41
72
  const buildMessage = (userPrompt) => {
42
73
  const minified = minifyBrandPageMetadata(brandPageMakerStore.brandPageData);
43
74
  return buildWebsiteBuilderMessage(userPrompt, minified);
@@ -69,81 +100,115 @@ export function useAiWebsiteBuilderChat() {
69
100
  aiMessage,
70
101
  };
71
102
  };
72
- const submitToolResults = async (toolResults) => {
73
- if (!aiThreadStore.threadId || !aiThreadStore.runId || !toolResults.length)
74
- return null;
75
- const client = getAiAssistantClient();
76
- const { response } = await client.submitWebsiteToolCallOutputAsync(aiThreadStore.threadId, {
77
- runId: aiThreadStore.runId,
78
- toolCalls: toolResults,
79
- agentType: AI_ASSISTANT_AGENT_TYPES.WEBSITE_BUILDER,
80
- websiteSnapshot: snapshotStore.snapshotBase64 || undefined,
81
- });
82
- return response;
83
- };
84
- const callApiAsync = async (userPrompt) => {
85
- generatedText.value = null;
86
- generatedStyle.value = null;
87
- const client = getAiAssistantClient();
88
- let aiAssistantResponse = {};
89
- if (!aiThreadStore.threadId) {
90
- const { response } = await client.createWebsiteThreadAndSendMessageAsync({
91
- message: buildMessage(userPrompt || ''),
92
- websiteSnapshot: snapshotStore.snapshotBase64 || undefined,
93
- agentType: AI_ASSISTANT_AGENT_TYPES.WEBSITE_BUILDER,
94
- });
95
- aiAssistantResponse = response;
96
- aiThreadStore.threadId = response.threadId;
97
- aiThreadStore.runId = response.runId || null;
98
- }
99
- else {
100
- const { response } = await client.sendWebsiteMessageAsync(aiThreadStore.threadId, {
101
- message: buildMessage(userPrompt),
102
- websiteSnapshot: snapshotStore.snapshotBase64 || undefined,
103
- agentType: AI_ASSISTANT_AGENT_TYPES.WEBSITE_BUILDER,
104
- });
105
- aiAssistantResponse = response;
106
- }
107
- aiLogger.log('callApiAsync response', { aiAssistantResponse });
108
- if (isStopped.value)
109
- return { text: null };
110
- const handledResponse = await handleAiResponseAsync(aiAssistantResponse);
111
- return {
112
- text: handledResponse.aiMessage ||
113
- 'I was unable to make the changes. Please try again.',
114
- langChainUrl: aiAssistantResponse.langChainUrl,
115
- };
116
- };
117
- const handleToolResponseAsync = async (response) => {
118
- let { shouldContinue, toolResults, aiMessage } = await applyToolCallsAsync(response);
119
- let iterations = 0;
120
- while (shouldContinue && iterations < MAX_TOOL_CALL_ITERATIONS) {
121
- if (isStopped.value)
122
- return { aiMessage: '' };
123
- const nextResponse = await submitToolResults(toolResults);
124
- aiLogger.log('handleToolResponseAsync submitToolResults', {
125
- toolResults,
126
- nextResponse,
103
+ const callApiBuildAsync = async (userPrompt) => {
104
+ const connectionId = await ensureConnectedAsync();
105
+ const wsClient = activeBuildWsClient;
106
+ try {
107
+ const client = getAiAssistantClient();
108
+ const message = buildMessage(userPrompt);
109
+ wsClient.sendHeartbeat();
110
+ let buildResponse;
111
+ if (!aiThreadStore.threadId) {
112
+ buildResponse = await client.createWebsiteThreadBuildAsync({
113
+ message,
114
+ websiteSnapshot: snapshotStore.snapshotBase64 || undefined,
115
+ agentType: AI_ASSISTANT_AGENT_TYPES.WEBSITE_BUILDER,
116
+ connectionId,
117
+ });
118
+ }
119
+ else {
120
+ buildResponse = await client.sendWebsiteMessageBuildAsync(aiThreadStore.threadId, {
121
+ message,
122
+ websiteSnapshot: snapshotStore.snapshotBase64 || undefined,
123
+ agentType: AI_ASSISTANT_AGENT_TYPES.WEBSITE_BUILDER,
124
+ connectionId,
125
+ });
126
+ }
127
+ aiThreadStore.threadId = buildResponse.threadId;
128
+ aiThreadStore.buildId = buildResponse.buildId;
129
+ aiThreadStore.isBuildInProgress = true;
130
+ aiThreadStore.buildSectionsCompleted = 0;
131
+ const langChainUrl = buildResponse.langChainUrl;
132
+ wsClient.setBuildActive(true);
133
+ wsClient.startResponseHeartbeat();
134
+ return new Promise((resolve, reject) => {
135
+ let settled = false;
136
+ let handler = null;
137
+ const finishBuild = () => {
138
+ aiThreadStore.isBuildInProgress = false;
139
+ wsClient.setBuildActive(false);
140
+ wsClient.stopResponseHeartbeat();
141
+ if (handler)
142
+ wsClient.offMessage(handler);
143
+ };
144
+ const timeout = setTimeout(() => {
145
+ if (settled)
146
+ return;
147
+ settled = true;
148
+ finishBuild();
149
+ reject(new Error('Build timeout'));
150
+ }, BUILD_TIMEOUT_MS);
151
+ handler = (msg) => {
152
+ if (settled)
153
+ 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);
179
+ }
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
+ })();
193
+ }
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.',
200
+ });
201
+ }
202
+ };
203
+ wsClient.onMessage(handler);
127
204
  });
128
- if (!nextResponse)
129
- break;
130
- const retryResult = await applyToolCallsAsync(nextResponse);
131
- shouldContinue = retryResult.shouldContinue;
132
- toolResults = retryResult.toolResults;
133
- aiMessage = retryResult.aiMessage || aiMessage;
134
- iterations += 1;
135
205
  }
136
- return { aiMessage };
137
- };
138
- const handleAiResponseAsync = async (response) => {
139
- const aiMessageResult = response.message || '';
140
- if (response.toolCalls && response.toolCalls.length > 0) {
141
- const toolResult = await handleToolResponseAsync(response);
142
- // Todo: For now dont show tool result message as it is not functional
143
- // aiMessageResult = toolResult.aiMessage || aiMessageResult;
144
- aiLogger.log('handleAiResponseAsync toolResult', { toolResult });
206
+ catch (err) {
207
+ aiThreadStore.isBuildInProgress = false;
208
+ wsClient.setBuildActive(false);
209
+ wsClient.stopResponseHeartbeat();
210
+ throw err;
145
211
  }
146
- return { aiMessage: aiMessageResult };
147
212
  };
148
213
  const sendMessageAsync = async (messageOptions) => {
149
214
  const { text, images } = messageOptions;
@@ -182,15 +247,15 @@ export function useAiWebsiteBuilderChat() {
182
247
  try {
183
248
  aiLogger.startGroup();
184
249
  aiLogger.log('sendMessageAsync', { messageOptions });
185
- const apiResult = await callApiAsync(text || '');
250
+ const result = await callApiBuildAsync(text || '');
186
251
  if (isStopped.value)
187
252
  return;
188
253
  const messageIndex = threadItems.value.findIndex((msg) => msg.id === agentMessageId);
189
254
  if (messageIndex !== -1) {
190
- if (apiResult.text) {
191
- threadItems.value[messageIndex].text = apiResult.text;
255
+ if (result.text) {
256
+ threadItems.value[messageIndex].text = result.text;
192
257
  threadItems.value[messageIndex].isTyping = false;
193
- threadItems.value[messageIndex].langChainUrl = apiResult.langChainUrl;
258
+ threadItems.value[messageIndex].langChainUrl = result.langChainUrl;
194
259
  }
195
260
  else {
196
261
  threadItems.value[messageIndex].text =
@@ -203,10 +268,13 @@ export function useAiWebsiteBuilderChat() {
203
268
  catch (error) {
204
269
  if (isStopped.value)
205
270
  return;
271
+ const isConnectionError = error?.message?.includes('WebSocket connection') ||
272
+ error?.message?.includes('WebSocket connection timeout');
206
273
  const messageIndex = threadItems.value.findIndex((msg) => msg.id === agentMessageId);
207
274
  if (messageIndex !== -1) {
208
- threadItems.value[messageIndex].text =
209
- error?.response?.data?.error ||
275
+ threadItems.value[messageIndex].text = isConnectionError
276
+ ? SERVICE_UNAVAILABLE_MESSAGE
277
+ : error?.response?.data?.error ||
210
278
  'An error occurred. Please try again.';
211
279
  threadItems.value[messageIndex].isTyping = false;
212
280
  threadItems.value[messageIndex].isError = true;
@@ -229,6 +297,11 @@ export function useAiWebsiteBuilderChat() {
229
297
  };
230
298
  const stopGenerationAsync = async () => {
231
299
  isStopped.value = true;
300
+ aiThreadStore.isBuildInProgress = false;
301
+ if (activeBuildWsClient) {
302
+ activeBuildWsClient.setBuildActive(false);
303
+ activeBuildWsClient.stopResponseHeartbeat();
304
+ }
232
305
  if (currentTypingMessageId.value) {
233
306
  deleteMessage(currentTypingMessageId.value);
234
307
  currentTypingMessageId.value = null;
@@ -3,13 +3,19 @@ export declare const useAiWebsiteBuilderThreadStore: import("pinia").StoreDefini
3
3
  runId: import("vue").Ref<string | null, string | null>;
4
4
  messages: import("vue").Ref<any[], any[]>;
5
5
  isProcessing: import("vue").Ref<boolean, boolean>;
6
+ buildId: import("vue").Ref<string | null, string | null>;
7
+ isBuildInProgress: import("vue").Ref<boolean, boolean>;
8
+ buildSectionsCompleted: import("vue").Ref<number, number>;
6
9
  promptText: import("vue").Ref<string, string>;
7
10
  stopGeneration: import("vue").Ref<(() => void) | null, (() => void) | null>;
8
- }, "threadId" | "runId" | "messages" | "isProcessing" | "stopGeneration" | "promptText">, Pick<{
11
+ }, "threadId" | "runId" | "messages" | "isProcessing" | "stopGeneration" | "buildId" | "isBuildInProgress" | "buildSectionsCompleted" | "promptText">, Pick<{
9
12
  threadId: import("vue").Ref<string | null, string | null>;
10
13
  runId: import("vue").Ref<string | null, string | null>;
11
14
  messages: import("vue").Ref<any[], any[]>;
12
15
  isProcessing: import("vue").Ref<boolean, boolean>;
16
+ buildId: import("vue").Ref<string | null, string | null>;
17
+ isBuildInProgress: import("vue").Ref<boolean, boolean>;
18
+ buildSectionsCompleted: import("vue").Ref<number, number>;
13
19
  promptText: import("vue").Ref<string, string>;
14
20
  stopGeneration: import("vue").Ref<(() => void) | null, (() => void) | null>;
15
21
  }, never>, Pick<{
@@ -17,6 +23,9 @@ export declare const useAiWebsiteBuilderThreadStore: import("pinia").StoreDefini
17
23
  runId: import("vue").Ref<string | null, string | null>;
18
24
  messages: import("vue").Ref<any[], any[]>;
19
25
  isProcessing: import("vue").Ref<boolean, boolean>;
26
+ buildId: import("vue").Ref<string | null, string | null>;
27
+ isBuildInProgress: import("vue").Ref<boolean, boolean>;
28
+ buildSectionsCompleted: import("vue").Ref<number, number>;
20
29
  promptText: import("vue").Ref<string, string>;
21
30
  stopGeneration: import("vue").Ref<(() => void) | null, (() => void) | null>;
22
31
  }, never>>;
@@ -5,6 +5,9 @@ export const useAiWebsiteBuilderThreadStore = defineStore('aiWebsiteBuilderThrea
5
5
  const runId = ref(null);
6
6
  const messages = ref([]);
7
7
  const isProcessing = ref(false);
8
+ const buildId = ref(null);
9
+ const isBuildInProgress = ref(false);
10
+ const buildSectionsCompleted = ref(0);
8
11
  const promptText = ref('');
9
12
  const stopGeneration = ref(null);
10
13
  return {
@@ -12,6 +15,9 @@ export const useAiWebsiteBuilderThreadStore = defineStore('aiWebsiteBuilderThrea
12
15
  runId,
13
16
  messages,
14
17
  isProcessing,
18
+ buildId,
19
+ isBuildInProgress,
20
+ buildSectionsCompleted,
15
21
  promptText,
16
22
  stopGeneration,
17
23
  };
@@ -48,6 +48,23 @@ export interface WebsiteToolSubmissionRequest {
48
48
  websiteSnapshot?: string;
49
49
  agentType: AiAssistantAgentType;
50
50
  }
51
+ export interface WebsiteCreateThreadBuildRequest {
52
+ message: string;
53
+ websiteSnapshot?: string;
54
+ agentType: AiAssistantAgentType;
55
+ connectionId: string;
56
+ }
57
+ export interface WebsiteSendMessageBuildRequest {
58
+ message: string;
59
+ websiteSnapshot?: string;
60
+ agentType: AiAssistantAgentType;
61
+ connectionId: string;
62
+ }
63
+ export interface AiAssistantBuildResponse {
64
+ threadId: string;
65
+ buildId: string;
66
+ langChainUrl?: string;
67
+ }
51
68
  export interface AiAssistantResponse {
52
69
  threadId: string;
53
70
  runId?: string;
@@ -95,6 +112,8 @@ export declare class AiAssistantClient {
95
112
  response: AiAssistantResponse;
96
113
  creditInfo: AiAssistantCreditInfo;
97
114
  }>;
115
+ createWebsiteThreadBuildAsync(request: WebsiteCreateThreadBuildRequest): Promise<AiAssistantBuildResponse>;
116
+ sendWebsiteMessageBuildAsync(threadId: string, request: WebsiteSendMessageBuildRequest): Promise<AiAssistantBuildResponse>;
98
117
  private handleError;
99
118
  }
100
119
  /**
@@ -90,6 +90,35 @@ export class AiAssistantClient {
90
90
  throw error;
91
91
  }
92
92
  }
93
+ async createWebsiteThreadBuildAsync(request) {
94
+ try {
95
+ const response = await axios.post(getWebsiteCreateThreadEndpoint(), request, {
96
+ withCredentials: true,
97
+ headers: this.getRequestHeaders(),
98
+ });
99
+ return response.data;
100
+ }
101
+ catch (error) {
102
+ this.handleError(error);
103
+ throw error;
104
+ }
105
+ }
106
+ async sendWebsiteMessageBuildAsync(threadId, request) {
107
+ if (!threadId) {
108
+ throw new Error('threadId is required');
109
+ }
110
+ try {
111
+ const response = await axios.post(getWebsiteSendMessageEndpoint(threadId), request, {
112
+ withCredentials: true,
113
+ headers: this.getRequestHeaders(),
114
+ });
115
+ return response.data;
116
+ }
117
+ catch (error) {
118
+ this.handleError(error);
119
+ throw error;
120
+ }
121
+ }
93
122
  handleError(error) {
94
123
  if (process.env.NODE_ENV !== 'production') {
95
124
  const errorData = error.response?.data;
@@ -0,0 +1,45 @@
1
+ export interface WebSocketConnectResponse {
2
+ connectionUrl: string;
3
+ }
4
+ export interface WebSocketMessage {
5
+ type: 'connected' | 'section_complete' | 'build_complete' | 'build_error';
6
+ buildId?: string;
7
+ connectionId?: string;
8
+ pageId?: string;
9
+ order?: number;
10
+ sectionType?: string;
11
+ mode?: string;
12
+ toolCalls?: unknown[];
13
+ message?: string;
14
+ error?: string;
15
+ }
16
+ type MessageHandler = (msg: WebSocketMessage) => void;
17
+ type DisconnectHandler = (reason: 'reconnect_failed' | 'error') => void;
18
+ export declare class WebSocketGatewayClient {
19
+ private ws;
20
+ private connectionId;
21
+ private messageHandlers;
22
+ private disconnectHandler;
23
+ private lifetimeTimer;
24
+ private heartbeatTimer;
25
+ private isReconnecting;
26
+ private isBuildActive;
27
+ private getRequestVerificationToken;
28
+ connect(): Promise<string>;
29
+ private openConnection;
30
+ private openWebSocket;
31
+ sendHeartbeat(): void;
32
+ startResponseHeartbeat(): void;
33
+ stopResponseHeartbeat(): void;
34
+ setBuildActive(active: boolean): void;
35
+ onDisconnect(handler: DisconnectHandler): void;
36
+ onMessage(handler: MessageHandler): void;
37
+ offMessage(handler: MessageHandler): void;
38
+ disconnect(): void;
39
+ getConnectionId(): string | null;
40
+ private closeSocket;
41
+ private startLifetimeTimer;
42
+ private clearLifetimeTimer;
43
+ private reconnectAsync;
44
+ }
45
+ export {};