@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.
- package/lib/src/{CreatedOnBrandCrowd-de-de-BtVKllNQ.js → CreatedOnBrandCrowd-de-de-COhZYMwW.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-en-us-CX5V0v8u.js → CreatedOnBrandCrowd-en-us-De5eIVfZ.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-es-es-CbA02PCL.js → CreatedOnBrandCrowd-es-es-D7Bk2q4d.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-fr-fr-BQAKruBF.js → CreatedOnBrandCrowd-fr-ca-BBCuO0D-.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-fr-ca-BQAKruBF.js → CreatedOnBrandCrowd-fr-fr-BBCuO0D-.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-pt-pt-Yk_yzB3s.js → CreatedOnBrandCrowd-pt-br-B5MrGFq-.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-pt-br-Yk_yzB3s.js → CreatedOnBrandCrowd-pt-pt-B5MrGFq-.js} +1 -1
- package/lib/src/{CreatedOnDcom-de-de-DJZQbPSD.js → CreatedOnDcom-de-de-CJSWCbRg.js} +1 -1
- package/lib/src/{CreatedOnDcom-en-us-BJvNAa4l.js → CreatedOnDcom-en-us-OO0s0TRW.js} +1 -1
- package/lib/src/{CreatedOnDcom-es-es-CUwB1FRY.js → CreatedOnDcom-es-es-DQX1lZq7.js} +1 -1
- package/lib/src/{CreatedOnDcom-fr-ca-CK54U4oh.js → CreatedOnDcom-fr-ca-C5cQ3rla.js} +1 -1
- package/lib/src/{CreatedOnDcom-fr-fr-DuUNBGrM.js → CreatedOnDcom-fr-fr-UdyUX0b_.js} +1 -1
- package/lib/src/{CreatedOnDcom-pt-br-BfODpFNV.js → CreatedOnDcom-pt-br-C0FiDCQG.js} +1 -1
- package/lib/src/{CreatedOnDcom-pt-pt-Cf6u2GCg.js → CreatedOnDcom-pt-pt-CbbnZ7aN.js} +1 -1
- 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 +0 -7
- package/lib/src/brand-page-maker/components/brand-page-maker/BrandPageMaker.mixin.d.ts +0 -21
- package/lib/src/brand-page-maker/components/brandpage-maker-page/BrandPageMakerPage.mixin.d.ts +0 -21
- package/lib/src/brand-page-maker/components/preview/Preview.mixin.d.ts +0 -7
- package/lib/src/brand-page-maker/components/quick-link-bar/QuickLinkBar.mixin.d.ts +0 -21
- package/lib/src/brand-page-maker/components/seo-settings/SeoPageSettings.mixin.d.ts +0 -21
- package/lib/src/brand-page-maker/components/seo-settings/UrlSettings.mixin.d.ts +0 -21
- package/lib/src/brand-page-maker/components/seo-settings/UseExistingDomainModal.mixin.d.ts +0 -21
- package/lib/src/brand-page-maker/components/template-preview/TemplatePreview.mixin.d.ts +0 -21
- package/lib/src/brand-page-maker/components/upgrade-to-premium-button/UpgradeToPremiumButton.mixin.d.ts +0 -21
- package/lib/src/brand-page-maker/composables/ai-chat/useAiWebsiteBuilderChat.js +0 -13
- package/lib/src/brand-page-maker/stores/ai-thread/ai-website-builder-thread-store.d.ts +2 -9
- package/lib/src/brand-page-maker/stores/ai-thread/ai-website-builder-thread-store.js +0 -20
- package/lib/src/brand-page-maker/stores/brandpage-container/brand-page-container-store.d.ts +0 -21
- package/lib/src/clients/ai-assistant-client.d.ts +1 -6
- package/lib/src/clients/ai-assistant-client.js +15 -7
- package/lib/src/index.mjs +1 -1
- package/lib/src/{lib-kGRlD3_P.js → lib-DgFekeRm.js} +19378 -19392
- package/lib/src/shared/background-settings/store/background-settings-store.js +3 -1
- package/lib/src/shared/content-settings/components/content-settings/ContentSettings.mixin.d.ts +1 -1
- package/lib/src/shared/content-settings/components/content-settings/ReplaceImageSettingsForContent.mixin.d.ts +1 -1
- package/lib/src/shared/content-settings/components/payment-config-field/PaymentConfigField.mixin.d.ts +0 -21
- package/lib/src/shared/logo-settings/components/LogoSettings.mixin.d.ts +0 -21
- package/lib/src/shared/page-settings/components/page-settings/PageSettings.mixin.d.ts +0 -21
- package/lib/src/shared/page-settings/components/page-settings-section-styles/PageSettingsSectionStyles.mixin.d.ts +0 -21
- package/lib/src/shared/publish-brand-page-with-state/PublishBrandPageModalWithState.mixin.d.ts +0 -28
- package/lib/src/shared/side-bar/components/SideBar.mixin.d.ts +1 -22
- package/lib/src/shared/style-settings/components/StyleSettings.mixin.d.ts +0 -21
- package/package.json +2 -2
- package/src/brand-page/models/brand-page-context.model.test.ts +38 -0
- package/src/brand-page/models/brand-page-context.model.ts +0 -13
- package/src/brand-page-maker/composables/ai-chat/useAiWebsiteBuilderChat.ts +0 -18
- package/src/brand-page-maker/stores/ai-thread/ai-website-builder-thread-store.ts +0 -30
- package/src/clients/ai-assistant-client.test.ts +135 -0
- package/src/clients/ai-assistant-client.ts +18 -12
- package/src/shared/background-settings/store/background-settings-store.ts +3 -1
- package/lib/src/brand-page-maker/composables/ai-chat/ai-builder-experiment.d.ts +0 -10
- package/lib/src/brand-page-maker/composables/ai-chat/ai-builder-experiment.js +0 -11
- package/src/brand-page-maker/composables/ai-chat/ai-builder-experiment.test.ts +0 -82
- 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
|
-
|
|
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;
|