@designcrowd/library.brand-page 6.2.12-publish-2 → 6.2.13

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 (55) hide show
  1. package/lib/src/{CreatedOnBrandCrowd-de-de-BtVKllNQ.js → CreatedOnBrandCrowd-de-de-COhZYMwW.js} +1 -1
  2. package/lib/src/{CreatedOnBrandCrowd-en-us-CX5V0v8u.js → CreatedOnBrandCrowd-en-us-De5eIVfZ.js} +1 -1
  3. package/lib/src/{CreatedOnBrandCrowd-es-es-CbA02PCL.js → CreatedOnBrandCrowd-es-es-D7Bk2q4d.js} +1 -1
  4. package/lib/src/{CreatedOnBrandCrowd-fr-fr-BQAKruBF.js → CreatedOnBrandCrowd-fr-ca-BBCuO0D-.js} +1 -1
  5. package/lib/src/{CreatedOnBrandCrowd-fr-ca-BQAKruBF.js → CreatedOnBrandCrowd-fr-fr-BBCuO0D-.js} +1 -1
  6. package/lib/src/{CreatedOnBrandCrowd-pt-pt-Yk_yzB3s.js → CreatedOnBrandCrowd-pt-br-B5MrGFq-.js} +1 -1
  7. package/lib/src/{CreatedOnBrandCrowd-pt-br-Yk_yzB3s.js → CreatedOnBrandCrowd-pt-pt-B5MrGFq-.js} +1 -1
  8. package/lib/src/{CreatedOnDcom-de-de-DJZQbPSD.js → CreatedOnDcom-de-de-CJSWCbRg.js} +1 -1
  9. package/lib/src/{CreatedOnDcom-en-us-BJvNAa4l.js → CreatedOnDcom-en-us-OO0s0TRW.js} +1 -1
  10. package/lib/src/{CreatedOnDcom-es-es-CUwB1FRY.js → CreatedOnDcom-es-es-DQX1lZq7.js} +1 -1
  11. package/lib/src/{CreatedOnDcom-fr-ca-CK54U4oh.js → CreatedOnDcom-fr-ca-C5cQ3rla.js} +1 -1
  12. package/lib/src/{CreatedOnDcom-fr-fr-DuUNBGrM.js → CreatedOnDcom-fr-fr-UdyUX0b_.js} +1 -1
  13. package/lib/src/{CreatedOnDcom-pt-br-BfODpFNV.js → CreatedOnDcom-pt-br-C0FiDCQG.js} +1 -1
  14. package/lib/src/{CreatedOnDcom-pt-pt-Cf6u2GCg.js → CreatedOnDcom-pt-pt-CbbnZ7aN.js} +1 -1
  15. package/lib/src/brand-page/models/brand-page-context.model.d.ts +0 -2
  16. package/lib/src/brand-page/models/brand-page-context.model.js +0 -7
  17. package/lib/src/brand-page-maker/components/brand-page-maker/BrandPageMaker.mixin.d.ts +0 -21
  18. package/lib/src/brand-page-maker/components/brandpage-maker-page/BrandPageMakerPage.mixin.d.ts +0 -21
  19. package/lib/src/brand-page-maker/components/preview/Preview.mixin.d.ts +0 -7
  20. package/lib/src/brand-page-maker/components/quick-link-bar/QuickLinkBar.mixin.d.ts +0 -21
  21. package/lib/src/brand-page-maker/components/seo-settings/SeoPageSettings.mixin.d.ts +0 -21
  22. package/lib/src/brand-page-maker/components/seo-settings/UrlSettings.mixin.d.ts +0 -21
  23. package/lib/src/brand-page-maker/components/seo-settings/UseExistingDomainModal.mixin.d.ts +0 -21
  24. package/lib/src/brand-page-maker/components/template-preview/TemplatePreview.mixin.d.ts +0 -21
  25. package/lib/src/brand-page-maker/components/upgrade-to-premium-button/UpgradeToPremiumButton.mixin.d.ts +0 -21
  26. package/lib/src/brand-page-maker/composables/ai-chat/useAiWebsiteBuilderChat.js +0 -13
  27. package/lib/src/brand-page-maker/stores/ai-thread/ai-website-builder-thread-store.d.ts +2 -9
  28. package/lib/src/brand-page-maker/stores/ai-thread/ai-website-builder-thread-store.js +0 -20
  29. package/lib/src/brand-page-maker/stores/brandpage-container/brand-page-container-store.d.ts +0 -21
  30. package/lib/src/clients/ai-assistant-client.d.ts +1 -6
  31. package/lib/src/clients/ai-assistant-client.js +15 -7
  32. package/lib/src/index.mjs +1 -1
  33. package/lib/src/{lib-kGRlD3_P.js → lib-DgFekeRm.js} +19378 -19392
  34. package/lib/src/shared/background-settings/store/background-settings-store.js +3 -1
  35. package/lib/src/shared/content-settings/components/content-settings/ContentSettings.mixin.d.ts +1 -1
  36. package/lib/src/shared/content-settings/components/content-settings/ReplaceImageSettingsForContent.mixin.d.ts +1 -1
  37. package/lib/src/shared/content-settings/components/payment-config-field/PaymentConfigField.mixin.d.ts +0 -21
  38. package/lib/src/shared/logo-settings/components/LogoSettings.mixin.d.ts +0 -21
  39. package/lib/src/shared/page-settings/components/page-settings/PageSettings.mixin.d.ts +0 -21
  40. package/lib/src/shared/page-settings/components/page-settings-section-styles/PageSettingsSectionStyles.mixin.d.ts +0 -21
  41. package/lib/src/shared/publish-brand-page-with-state/PublishBrandPageModalWithState.mixin.d.ts +0 -28
  42. package/lib/src/shared/side-bar/components/SideBar.mixin.d.ts +1 -22
  43. package/lib/src/shared/style-settings/components/StyleSettings.mixin.d.ts +0 -21
  44. package/package.json +2 -2
  45. package/src/brand-page/models/brand-page-context.model.test.ts +38 -0
  46. package/src/brand-page/models/brand-page-context.model.ts +0 -13
  47. package/src/brand-page-maker/composables/ai-chat/useAiWebsiteBuilderChat.ts +0 -18
  48. package/src/brand-page-maker/stores/ai-thread/ai-website-builder-thread-store.ts +0 -30
  49. package/src/clients/ai-assistant-client.test.ts +135 -0
  50. package/src/clients/ai-assistant-client.ts +18 -12
  51. package/src/shared/background-settings/store/background-settings-store.ts +3 -1
  52. package/lib/src/brand-page-maker/composables/ai-chat/ai-builder-experiment.d.ts +0 -10
  53. package/lib/src/brand-page-maker/composables/ai-chat/ai-builder-experiment.js +0 -11
  54. package/src/brand-page-maker/composables/ai-chat/ai-builder-experiment.test.ts +0 -82
  55. package/src/brand-page-maker/composables/ai-chat/ai-builder-experiment.ts +0 -19
@@ -0,0 +1,135 @@
1
+ import axios from 'axios';
2
+ import { createPinia, setActivePinia } from 'pinia';
3
+ import { beforeEach, describe, expect, test, vi } from 'vitest';
4
+ import {
5
+ getInstance,
6
+ getWebsiteCreateThreadEndpoint,
7
+ getWebsiteSendMessageEndpoint,
8
+ getWebsiteToolSubmissionEndpoint,
9
+ type WebsiteCreateThreadRequest,
10
+ type WebsiteSendMessageRequest,
11
+ type WebsiteToolSubmissionRequest,
12
+ type WebsiteCreateThreadBuildRequest,
13
+ type WebsiteSendMessageBuildRequest,
14
+ } from './ai-assistant-client';
15
+
16
+ vi.mock('axios');
17
+
18
+ const THREAD_ID = 'thread-1';
19
+
20
+ beforeEach(() => {
21
+ setActivePinia(createPinia());
22
+ vi.clearAllMocks();
23
+ vi.mocked(axios.post).mockResolvedValue({
24
+ data: { threadId: THREAD_ID, buildId: 'build-1' },
25
+ headers: {},
26
+ } as any);
27
+ });
28
+
29
+ // BP-6193: the client, not the caller, names the agent — tool results sent to a
30
+ // different agent than the one running the thread fail the build
31
+ // (ai-v2-tool-submission-routing.md).
32
+ describe('AiAssistantClient — every website call names the V2 builder', () => {
33
+ test('the three build methods post agentType: V2', async () => {
34
+ const client = getInstance();
35
+
36
+ await client.createWebsiteThreadBuildAsync({
37
+ message: 'hello',
38
+ connectionId: 'conn-1',
39
+ } as WebsiteCreateThreadBuildRequest);
40
+ await client.sendWebsiteMessageBuildAsync(THREAD_ID, {
41
+ message: 'hello',
42
+ connectionId: 'conn-1',
43
+ } as WebsiteSendMessageBuildRequest);
44
+ await client.submitToolResultsBuildAsync(THREAD_ID, {
45
+ toolCalls: [],
46
+ } as WebsiteToolSubmissionRequest);
47
+
48
+ vi.mocked(axios.post).mock.calls.forEach(([, body]) => {
49
+ expect(body).toMatchObject({ agentType: 'website_builder_v2' });
50
+ });
51
+ });
52
+
53
+ test('the three unused V1-era methods also post agentType: V2', async () => {
54
+ const client = getInstance();
55
+
56
+ await client.createWebsiteThreadAndSendMessageAsync({
57
+ message: 'hello',
58
+ } as WebsiteCreateThreadRequest);
59
+ await client.sendWebsiteMessageAsync(THREAD_ID, {
60
+ message: 'hello',
61
+ } as WebsiteSendMessageRequest);
62
+ await client.submitWebsiteToolCallOutputAsync(THREAD_ID, {
63
+ toolCalls: [],
64
+ } as WebsiteToolSubmissionRequest);
65
+
66
+ vi.mocked(axios.post).mock.calls.forEach(([, body]) => {
67
+ expect(body).toMatchObject({ agentType: 'website_builder_v2' });
68
+ });
69
+ });
70
+
71
+ test('a caller-supplied agentType cannot override V2', async () => {
72
+ const client = getInstance();
73
+
74
+ await client.createWebsiteThreadBuildAsync({
75
+ message: 'hello',
76
+ connectionId: 'conn-1',
77
+ agentType: 'website_builder',
78
+ } as never);
79
+
80
+ const [, body] = vi.mocked(axios.post).mock.calls[0];
81
+
82
+ expect(body).toMatchObject({ agentType: 'website_builder_v2' });
83
+ });
84
+
85
+ test('each method posts to its own endpoint and keeps the caller fields', async () => {
86
+ const client = getInstance();
87
+
88
+ await client.createWebsiteThreadBuildAsync({
89
+ message: 'hello',
90
+ connectionId: 'conn-1',
91
+ userPlan: 'premium',
92
+ locale: 'en-US',
93
+ } as WebsiteCreateThreadBuildRequest);
94
+ await client.sendWebsiteMessageBuildAsync(THREAD_ID, {
95
+ message: 'follow-up',
96
+ connectionId: 'conn-1',
97
+ userPlan: 'free',
98
+ locale: 'en-US',
99
+ } as WebsiteSendMessageBuildRequest);
100
+ await client.submitToolResultsBuildAsync(THREAD_ID, {
101
+ toolCalls: [{ toolId: 't1', success: 'success' }],
102
+ connectionId: 'conn-1',
103
+ retryCount: 1,
104
+ userPlan: 'free',
105
+ locale: 'en-US',
106
+ } as WebsiteToolSubmissionRequest);
107
+
108
+ const calls = vi.mocked(axios.post).mock.calls;
109
+
110
+ expect(calls[0][0]).toBe(getWebsiteCreateThreadEndpoint());
111
+ expect(calls[0][1]).toMatchObject({
112
+ message: 'hello',
113
+ connectionId: 'conn-1',
114
+ userPlan: 'premium',
115
+ locale: 'en-US',
116
+ });
117
+
118
+ expect(calls[1][0]).toBe(getWebsiteSendMessageEndpoint(THREAD_ID));
119
+ expect(calls[1][1]).toMatchObject({
120
+ message: 'follow-up',
121
+ connectionId: 'conn-1',
122
+ userPlan: 'free',
123
+ locale: 'en-US',
124
+ });
125
+
126
+ expect(calls[2][0]).toBe(getWebsiteToolSubmissionEndpoint(THREAD_ID));
127
+ expect(calls[2][1]).toMatchObject({
128
+ toolCalls: [{ toolId: 't1', success: 'success' }],
129
+ connectionId: 'conn-1',
130
+ retryCount: 1,
131
+ userPlan: 'free',
132
+ locale: 'en-US',
133
+ });
134
+ });
135
+ });
@@ -29,7 +29,6 @@ export interface WebsiteContext {
29
29
 
30
30
  // Agent types
31
31
  export const AI_ASSISTANT_AGENT_TYPES = {
32
- WEBSITE_BUILDER: 'website_builder',
33
32
  WEBSITE_BUILDER_V2: 'website_builder_v2',
34
33
  } as const;
35
34
 
@@ -67,18 +66,15 @@ export interface WebsiteCreateThreadRequest {
67
66
  message: string;
68
67
  websiteContext?: WebsiteContext;
69
68
  websiteSnapshot?: string;
70
- agentType: AiAssistantAgentType;
71
69
  }
72
70
 
73
71
  export interface WebsiteSendMessageRequest {
74
72
  message: string;
75
73
  websiteContext?: WebsiteContext;
76
74
  websiteSnapshot?: string;
77
- agentType: AiAssistantAgentType;
78
75
  }
79
76
 
80
77
  export interface WebsiteToolSubmissionRequest {
81
- agentType: AiAssistantAgentType;
82
78
  toolCalls: AiAssistantToolResult[];
83
79
  runId?: string | null;
84
80
  message?: string;
@@ -95,7 +91,6 @@ export interface WebsiteCreateThreadBuildRequest {
95
91
  message: string;
96
92
  websiteContext?: WebsiteContext;
97
93
  websiteSnapshot?: string;
98
- agentType: AiAssistantAgentType;
99
94
  userPlan?: UserPlan;
100
95
  connectionId: string;
101
96
  // TCI-1349: dedicated LLM-gateway locale attribution (cost tag only).
@@ -106,7 +101,6 @@ export interface WebsiteSendMessageBuildRequest {
106
101
  message: string;
107
102
  websiteContext?: WebsiteContext;
108
103
  websiteSnapshot?: string;
109
- agentType: AiAssistantAgentType;
110
104
  userPlan?: UserPlan;
111
105
  connectionId: string;
112
106
  // TCI-1349: dedicated LLM-gateway locale attribution (cost tag only).
@@ -177,6 +171,18 @@ export class AiAssistantClient {
177
171
  };
178
172
  }
179
173
 
174
+ // The agent spread last, so no caller can override it. Tool results sent to a
175
+ // different agent than the one running the thread fail the build
176
+ // (ai-v2-tool-submission-routing.md).
177
+ private withAgentType<T extends object>(
178
+ request: T,
179
+ ): T & { agentType: AiAssistantAgentType } {
180
+ return {
181
+ ...request,
182
+ agentType: AI_ASSISTANT_AGENT_TYPES.WEBSITE_BUILDER_V2,
183
+ };
184
+ }
185
+
180
186
  /**
181
187
  * Create a new Website AI Assistant thread
182
188
  */
@@ -189,7 +195,7 @@ export class AiAssistantClient {
189
195
  try {
190
196
  const response = await axios.post<AiAssistantResponse>(
191
197
  getWebsiteCreateThreadEndpoint(),
192
- request,
198
+ this.withAgentType(request),
193
199
  {
194
200
  withCredentials: true,
195
201
  headers: this.getRequestHeaders(),
@@ -225,7 +231,7 @@ export class AiAssistantClient {
225
231
  try {
226
232
  const response = await axios.post<AiAssistantResponse>(
227
233
  getWebsiteSendMessageEndpoint(threadId),
228
- request,
234
+ this.withAgentType(request),
229
235
  {
230
236
  withCredentials: true,
231
237
  headers: this.getRequestHeaders(),
@@ -261,7 +267,7 @@ export class AiAssistantClient {
261
267
  try {
262
268
  const response = await axios.post<AiAssistantResponse>(
263
269
  getWebsiteToolSubmissionEndpoint(threadId),
264
- request,
270
+ this.withAgentType(request),
265
271
  {
266
272
  withCredentials: true,
267
273
  headers: this.getRequestHeaders(),
@@ -286,7 +292,7 @@ export class AiAssistantClient {
286
292
  try {
287
293
  const response = await axios.post<AiAssistantBuildResponse>(
288
294
  getWebsiteCreateThreadEndpoint(),
289
- request,
295
+ this.withAgentType(request),
290
296
  {
291
297
  withCredentials: true,
292
298
  headers: this.getRequestHeaders(),
@@ -311,7 +317,7 @@ export class AiAssistantClient {
311
317
  try {
312
318
  const response = await axios.post<AiAssistantBuildResponse>(
313
319
  getWebsiteSendMessageEndpoint(threadId),
314
- request,
320
+ this.withAgentType(request),
315
321
  {
316
322
  withCredentials: true,
317
323
  headers: this.getRequestHeaders(),
@@ -336,7 +342,7 @@ export class AiAssistantClient {
336
342
  try {
337
343
  const response = await axios.post<AiAssistantBuildResponse>(
338
344
  getWebsiteToolSubmissionEndpoint(threadId),
339
- request,
345
+ this.withAgentType(request),
340
346
  {
341
347
  withCredentials: true,
342
348
  headers: this.getRequestHeaders(),
@@ -24,7 +24,9 @@ import type {
24
24
  } from '../models';
25
25
  import { backgroundSettingsTabId } from '../models';
26
26
  import { defineStore } from 'pinia';
27
- import { useUiStore, useVideoStore } from '@brand-page-maker/stores';
27
+ // Direct paths, not the stores barrel: it sits in an import cycle with this store.
28
+ import { useUiStore } from '@brand-page-maker/stores/ui/ui-store';
29
+ import { useVideoStore } from '@brand-page-maker/stores/video/video-store';
28
30
  import type {
29
31
  GettyVideoMediaSelectedPayload,
30
32
  MediaBaseSelectedPayload,
@@ -1,10 +0,0 @@
1
- import type { AbTestResult } from '../../../brand-page/models/brand-page-context.model';
2
- import { type AiAssistantAgentType } from '../../../clients/ai-assistant-client';
3
- /**
4
- * A/B test: control keeps the V1 AI website builder, variation-1 gets V2.
5
- *
6
- * bc-net (WebsiteMakerInteractor) buckets post-purchase users who get the AI tab at
7
- * editor load and sends the arm in `abTests`. No arm, control and excluded all stay
8
- * on V1, so a missing value is today's production behaviour.
9
- */
10
- export declare const aiBuilderAgentTypeForArm: (arm: AbTestResult | undefined) => AiAssistantAgentType;
@@ -1,11 +0,0 @@
1
- import { AI_ASSISTANT_AGENT_TYPES, } from '../../../clients/ai-assistant-client';
2
- /**
3
- * A/B test: control keeps the V1 AI website builder, variation-1 gets V2.
4
- *
5
- * bc-net (WebsiteMakerInteractor) buckets post-purchase users who get the AI tab at
6
- * editor load and sends the arm in `abTests`. No arm, control and excluded all stay
7
- * on V1, so a missing value is today's production behaviour.
8
- */
9
- export const aiBuilderAgentTypeForArm = (arm) => arm?.isVariation
10
- ? AI_ASSISTANT_AGENT_TYPES.WEBSITE_BUILDER_V2
11
- : AI_ASSISTANT_AGENT_TYPES.WEBSITE_BUILDER;
@@ -1,82 +0,0 @@
1
- import { describe, it, expect, beforeEach } from 'vitest';
2
- import { createPinia, setActivePinia } from 'pinia';
3
- import { aiBuilderAgentTypeForArm } from './ai-builder-experiment';
4
- import { getAbTestResults } from '../../../brand-page/models/brand-page-context.model';
5
- import { useAiWebsiteBuilderThreadStore } from '../../stores';
6
-
7
- // Must match `Bp6136V2AiBuilderStrategy` in bc-net and the LaunchDarkly flag.
8
- const CAMPAIGN = 'bc-bp-6136-v2-ai-builder';
9
-
10
- // The arm arrives as the raw bc-net campaign string, so go through the real parser.
11
- const armFor = (value?: string) =>
12
- getAbTestResults(value ? ({ [CAMPAIGN]: value } as never) : {})
13
- .bp_6136_v2_ai_builder;
14
-
15
- describe('BP-6136 arm to AI builder agent type', () => {
16
- it('variation-1 gets the V2 builder', () => {
17
- expect(aiBuilderAgentTypeForArm(armFor('bp-6136-variation-1'))).toBe(
18
- 'website_builder_v2',
19
- );
20
- });
21
-
22
- it('control stays on V1', () => {
23
- expect(aiBuilderAgentTypeForArm(armFor('bp-6136-control'))).toBe(
24
- 'website_builder',
25
- );
26
- });
27
-
28
- it('excluded stays on V1', () => {
29
- expect(aiBuilderAgentTypeForArm(armFor('bp-6136-excluded'))).toBe(
30
- 'website_builder',
31
- );
32
- });
33
-
34
- it('no arm at all (pre-purchase, AI tab off, older bc-net) stays on V1', () => {
35
- expect(aiBuilderAgentTypeForArm(armFor(undefined))).toBe('website_builder');
36
- expect(aiBuilderAgentTypeForArm(undefined)).toBe('website_builder');
37
- });
38
- });
39
-
40
- describe('thread store agent type', () => {
41
- beforeEach(() => {
42
- setActivePinia(createPinia());
43
- });
44
-
45
- it('starts on V1, the production default', () => {
46
- expect(useAiWebsiteBuilderThreadStore().agentType).toBe('website_builder');
47
- });
48
-
49
- it('switching before any thread exists keeps the pending prompt and does not reset', () => {
50
- const threadStore = useAiWebsiteBuilderThreadStore();
51
-
52
- threadStore.promptText = 'draft the user is typing';
53
-
54
- threadStore.setAgentType('website_builder_v2');
55
-
56
- expect(threadStore.agentType).toBe('website_builder_v2');
57
- expect(threadStore.promptText).toBe('draft the user is typing');
58
- expect(threadStore.resetToken).toBe(0);
59
- });
60
-
61
- it('switching under a running thread drops that thread', () => {
62
- const threadStore = useAiWebsiteBuilderThreadStore();
63
-
64
- threadStore.threadId = 'thread-on-v1';
65
-
66
- threadStore.setAgentType('website_builder_v2');
67
-
68
- expect(threadStore.threadId).toBeNull();
69
- expect(threadStore.resetToken).toBe(1);
70
- });
71
-
72
- it('setting the same agent again is a no-op', () => {
73
- const threadStore = useAiWebsiteBuilderThreadStore();
74
-
75
- threadStore.threadId = 'thread-on-v1';
76
-
77
- threadStore.setAgentType('website_builder');
78
-
79
- expect(threadStore.threadId).toBe('thread-on-v1');
80
- expect(threadStore.resetToken).toBe(0);
81
- });
82
- });
@@ -1,19 +0,0 @@
1
- import type { AbTestResult } from '../../../brand-page/models/brand-page-context.model';
2
- import {
3
- AI_ASSISTANT_AGENT_TYPES,
4
- type AiAssistantAgentType,
5
- } from '../../../clients/ai-assistant-client';
6
-
7
- /**
8
- * A/B test: control keeps the V1 AI website builder, variation-1 gets V2.
9
- *
10
- * bc-net (WebsiteMakerInteractor) buckets post-purchase users who get the AI tab at
11
- * editor load and sends the arm in `abTests`. No arm, control and excluded all stay
12
- * on V1, so a missing value is today's production behaviour.
13
- */
14
- export const aiBuilderAgentTypeForArm = (
15
- arm: AbTestResult | undefined,
16
- ): AiAssistantAgentType =>
17
- arm?.isVariation
18
- ? AI_ASSISTANT_AGENT_TYPES.WEBSITE_BUILDER_V2
19
- : AI_ASSISTANT_AGENT_TYPES.WEBSITE_BUILDER;