Skip to content

Commit bed75dd

Browse files
committed
chore(compass-preferences-model): use optInGenAIFeatures for Compass and DE
1 parent a9b2fa7 commit bed75dd

File tree

10 files changed

+100
-63
lines changed

10 files changed

+100
-63
lines changed

packages/compass-e2e-tests/tests/atlas-cloud/collection-ai-query.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ describe('Collection ai query', function () {
4949
true
5050
);
5151
await browser.setFeature('enableGenAIFeaturesAtlasOrg', true);
52-
await browser.setFeature('optInDataExplorerGenAIFeatures', true);
52+
await browser.setFeature('optInGenAIFeatures', true);
5353
});
5454

5555
describe('on the documents tab', function () {
@@ -170,7 +170,7 @@ describe('Collection ai query', function () {
170170
true
171171
);
172172
await browser.setFeature('enableGenAIFeaturesAtlasOrg', false);
173-
await browser.setFeature('optInDataExplorerGenAIFeatures', true);
173+
await browser.setFeature('optInGenAIFeatures', true);
174174
});
175175

176176
it('should not show the gen ai intro button', async function () {

packages/compass-generative-ai/src/atlas-ai-service.spec.ts

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,57 @@ describe('AtlasAiService', function () {
321321
});
322322
});
323323
});
324+
325+
describe('optIntoGenAIFeatures', function () {
326+
beforeEach(async function () {
327+
// Reset preferences
328+
await preferences.savePreferences({
329+
optInGenAIFeatures: false,
330+
});
331+
});
332+
333+
if (apiURLPreset === 'cloud') {
334+
it('should make a POST request to cloud endpoint and save preference when cloud preset', async function () {
335+
const fetchStub = sandbox.stub().resolves(makeResponse({}));
336+
global.fetch = fetchStub;
337+
338+
await atlasAiService.optIntoGenAIFeatures();
339+
340+
// Verify fetch was called with correct parameters
341+
expect(fetchStub).to.have.been.calledOnce;
342+
343+
expect(fetchStub).to.have.been.calledWith(
344+
'/cloud/settings/optInDataExplorerGenAIFeatures',
345+
{
346+
method: 'POST',
347+
headers: {
348+
'Content-Type': 'application/x-www-form-urlencoded',
349+
Accept: 'application/json',
350+
},
351+
body: new URLSearchParams([['value', 'true']]),
352+
}
353+
);
354+
355+
// Verify preference was saved
356+
const currentPreferences = preferences.getPreferences();
357+
expect(currentPreferences.optInGenAIFeatures).to.equal(true);
358+
});
359+
} else {
360+
it('should not make any fetch request and only save preference when admin-api preset', async function () {
361+
const fetchStub = sandbox.stub().resolves(makeResponse({}));
362+
global.fetch = fetchStub;
363+
364+
await atlasAiService.optIntoGenAIFeatures();
365+
366+
// Verify no fetch was called
367+
expect(fetchStub).to.not.have.been.called;
368+
369+
// Verify preference was saved
370+
const currentPreferences = preferences.getPreferences();
371+
expect(currentPreferences.optInGenAIFeatures).to.equal(true);
372+
});
373+
}
374+
});
324375
});
325376
}
326377
});

packages/compass-generative-ai/src/atlas-ai-service.ts

Lines changed: 19 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import type { ConnectionInfo } from '@mongodb-js/compass-connections/provider';
99
import type { Document } from 'mongodb';
1010
import type { Logger } from '@mongodb-js/compass-logging';
1111
import { EJSON } from 'bson';
12-
import { signIntoAtlasWithModalPrompt } from './store/atlas-signin-reducer';
1312
import { getStore } from './store/atlas-ai-store';
1413
import { optIntoGenAIWithModalPrompt } from './store/atlas-optin-reducer';
1514

@@ -277,13 +276,7 @@ export class AtlasAiService {
277276
}
278277

279278
async ensureAiFeatureAccess({ signal }: { signal?: AbortSignal } = {}) {
280-
// When the ai feature is attempted to be opened we make sure
281-
// the user is signed into Atlas and opted in.
282-
283-
if (this.apiURLPreset === 'cloud') {
284-
return getStore().dispatch(optIntoGenAIWithModalPrompt({ signal }));
285-
}
286-
return getStore().dispatch(signIntoAtlasWithModalPrompt({ signal }));
279+
return getStore().dispatch(optIntoGenAIWithModalPrompt({ signal }));
287280
}
288281

289282
private getQueryOrAggregationFromUserInput = async <T>(
@@ -391,23 +384,25 @@ export class AtlasAiService {
391384
);
392385
}
393386

394-
// Performs a post request to atlas to set the user opt in preference to true.
395-
async optIntoGenAIFeaturesAtlas() {
396-
await this.atlasService.authenticatedFetch(
397-
this.atlasService.cloudEndpoint(
398-
'/settings/optInDataExplorerGenAIFeatures'
399-
),
400-
{
401-
method: 'POST',
402-
headers: {
403-
'Content-Type': 'application/x-www-form-urlencoded',
404-
Accept: 'application/json',
405-
},
406-
body: new URLSearchParams([['value', 'true']]),
407-
}
408-
);
387+
async optIntoGenAIFeatures() {
388+
if (this.apiURLPreset === 'cloud') {
389+
// Performs a post request to Atlas to set the user opt in preference to true.
390+
await this.atlasService.authenticatedFetch(
391+
this.atlasService.cloudEndpoint(
392+
'settings/optInDataExplorerGenAIFeatures'
393+
),
394+
{
395+
method: 'POST',
396+
headers: {
397+
'Content-Type': 'application/x-www-form-urlencoded',
398+
Accept: 'application/json',
399+
},
400+
body: new URLSearchParams([['value', 'true']]),
401+
}
402+
);
403+
}
409404
await this.preferences.savePreferences({
410-
optInDataExplorerGenAIFeatures: true,
405+
optInGenAIFeatures: true,
411406
});
412407
}
413408

packages/compass-generative-ai/src/store/atlas-optin-reducer.spec.ts

Lines changed: 16 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ describe('atlasOptInReducer', function () {
2020
beforeEach(async function () {
2121
mockPreferences = await createSandboxFromDefaultPreferences();
2222
await mockPreferences.savePreferences({
23-
optInDataExplorerGenAIFeatures: false,
23+
optInGenAIFeatures: false,
2424
});
2525
});
2626

@@ -31,7 +31,7 @@ describe('atlasOptInReducer', function () {
3131
describe('optIn', function () {
3232
it('should check state and set state to success if already opted in', async function () {
3333
const mockAtlasAiService = {
34-
optIntoGenAIFeaturesAtlas: sandbox.stub().resolves({ sub: '1234' }),
34+
optIntoGenAIFeatures: sandbox.stub().resolves({ sub: '1234' }),
3535
};
3636
const store = configureStore({
3737
atlasAuthService: {} as any,
@@ -45,8 +45,7 @@ describe('atlasOptInReducer', function () {
4545
);
4646
void store.dispatch(atlasAiServiceOptedIn());
4747
await store.dispatch(optIn());
48-
expect(mockAtlasAiService.optIntoGenAIFeaturesAtlas).not.to.have.been
49-
.called;
48+
expect(mockAtlasAiService.optIntoGenAIFeatures).not.to.have.been.called;
5049
expect(store.getState().optIn).to.have.nested.property(
5150
'state',
5251
'optin-success'
@@ -55,7 +54,7 @@ describe('atlasOptInReducer', function () {
5554

5655
it('should start opt in, and set state to success', async function () {
5756
const mockAtlasAiService = {
58-
optIntoGenAIFeaturesAtlas: sandbox.stub().resolves({ sub: '1234' }),
57+
optIntoGenAIFeatures: sandbox.stub().resolves({ sub: '1234' }),
5958
};
6059
const store = configureStore({
6160
atlasAuthService: {} as any,
@@ -69,8 +68,7 @@ describe('atlasOptInReducer', function () {
6968
);
7069
void store.dispatch(optIntoGenAIWithModalPrompt()).catch(() => {});
7170
await store.dispatch(optIn());
72-
expect(mockAtlasAiService.optIntoGenAIFeaturesAtlas).to.have.been
73-
.calledOnce;
71+
expect(mockAtlasAiService.optIntoGenAIFeatures).to.have.been.calledOnce;
7472
expect(store.getState().optIn).to.have.nested.property(
7573
'state',
7674
'optin-success'
@@ -81,13 +79,13 @@ describe('atlasOptInReducer', function () {
8179
beforeEach(async function () {
8280
await mockPreferences.savePreferences({
8381
enableGenAIFeaturesAtlasProject: false,
84-
optInDataExplorerGenAIFeatures: true,
82+
optInGenAIFeatures: true,
8583
});
8684
});
8785

8886
it('should start the opt in flow', async function () {
8987
const mockAtlasAiService = {
90-
optIntoGenAIFeaturesAtlas: sandbox.stub().resolves({ sub: '1234' }),
88+
optIntoGenAIFeatures: sandbox.stub().resolves({ sub: '1234' }),
9189
};
9290
const store = configureStore({
9391
atlasAuthService: {} as any,
@@ -101,8 +99,7 @@ describe('atlasOptInReducer', function () {
10199
);
102100
void store.dispatch(optIntoGenAIWithModalPrompt()).catch(() => {});
103101
await store.dispatch(optIn());
104-
expect(mockAtlasAiService.optIntoGenAIFeaturesAtlas).to.have.been
105-
.calledOnce;
102+
expect(mockAtlasAiService.optIntoGenAIFeatures).to.have.been.calledOnce;
106103
expect(store.getState().optIn).to.have.nested.property(
107104
'state',
108105
'optin-success'
@@ -112,9 +109,7 @@ describe('atlasOptInReducer', function () {
112109

113110
it('should fail opt in if opt in failed', async function () {
114111
const mockAtlasAiService = {
115-
optIntoGenAIFeaturesAtlas: sandbox
116-
.stub()
117-
.rejects(new Error('Whooops!')),
112+
optIntoGenAIFeatures: sandbox.stub().rejects(new Error('Whooops!')),
118113
};
119114
const store = configureStore({
120115
atlasAuthService: {} as any,
@@ -127,8 +122,7 @@ describe('atlasOptInReducer', function () {
127122
// Avoid unhandled rejections.
128123
AttemptStateMap.get(attemptId)?.promise.catch(() => {});
129124
await optInPromise;
130-
expect(mockAtlasAiService.optIntoGenAIFeaturesAtlas).to.have.been
131-
.calledOnce;
125+
expect(mockAtlasAiService.optIntoGenAIFeatures).to.have.been.calledOnce;
132126
expect(store.getState().optIn).to.have.nested.property('state', 'error');
133127
});
134128
});
@@ -153,7 +147,7 @@ describe('atlasOptInReducer', function () {
153147

154148
it('should cancel opt in if opt in is in progress', async function () {
155149
const mockAtlasAiService = {
156-
optIntoGenAIFeaturesAtlas: sandbox
150+
optIntoGenAIFeatures: sandbox
157151
.stub()
158152
.callsFake(({ signal }: { signal: AbortSignal }) => {
159153
return new Promise((resolve, reject) => {
@@ -183,10 +177,10 @@ describe('atlasOptInReducer', function () {
183177
});
184178
});
185179

186-
describe('optIntoAtlasWithModalPrompt', function () {
180+
describe('optIntoGenAIWithModalPrompt', function () {
187181
it('should resolve when user finishes opt in with prompt flow', async function () {
188182
const mockAtlasAiService = {
189-
optIntoGenAIFeaturesAtlas: sandbox.stub().resolves({ sub: '1234' }),
183+
optIntoGenAIFeatures: sandbox.stub().resolves({ sub: '1234' }),
190184
};
191185
const store = configureStore({
192186
atlasAuthService: {} as any,
@@ -203,7 +197,7 @@ describe('atlasOptInReducer', function () {
203197

204198
it('should reject if opt in flow fails', async function () {
205199
const mockAtlasAiService = {
206-
optIntoGenAIFeaturesAtlas: sandbox.stub().rejects(new Error('Whoops!')),
200+
optIntoGenAIFeatures: sandbox.stub().rejects(new Error('Whoops!')),
207201
};
208202
const store = configureStore({
209203
atlasAuthService: {} as any,
@@ -226,7 +220,7 @@ describe('atlasOptInReducer', function () {
226220

227221
it('should reject if user dismissed the modal', async function () {
228222
const mockAtlasAiService = {
229-
optIntoGenAIFeaturesAtlas: sandbox.stub().resolves({ sub: '1234' }),
223+
optIntoGenAIFeatures: sandbox.stub().resolves({ sub: '1234' }),
230224
};
231225
const store = configureStore({
232226
atlasAuthService: {} as any,
@@ -249,7 +243,7 @@ describe('atlasOptInReducer', function () {
249243

250244
it('should reject if provided signal was aborted', async function () {
251245
const mockAtlasAiService = {
252-
optIntoGenAIFeaturesAtlas: sandbox.stub().resolves({ sub: '1234' }),
246+
optIntoGenAIFeatures: sandbox.stub().resolves({ sub: '1234' }),
253247
};
254248
const store = configureStore({
255249
atlasAuthService: {} as any,

packages/compass-generative-ai/src/store/atlas-optin-reducer.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ export const optIntoGenAIWithModalPrompt = ({
228228
const { state } = getState().optIn;
229229
if (
230230
(state === 'optin-success' ||
231-
preferences.getPreferences().optInDataExplorerGenAIFeatures) &&
231+
preferences.getPreferences().optInGenAIFeatures) &&
232232
preferences.getPreferences().enableGenAIFeaturesAtlasProject
233233
) {
234234
return Promise.resolve();
@@ -265,7 +265,7 @@ export const optIn = (): GenAIAtlasOptInThunkAction<Promise<void>> => {
265265

266266
try {
267267
throwIfAborted(signal);
268-
await atlasAiService.optIntoGenAIFeaturesAtlas();
268+
await atlasAiService.optIntoGenAIFeatures();
269269
dispatch(atlasAiServiceOptedIn());
270270
resolve();
271271
} catch (err) {

packages/compass-preferences-model/src/compass-web-preferences-access.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { getActiveUser } from './utils';
77

88
const editablePreferences: (keyof UserPreferences)[] = [
99
// Value can change from false to true during allocation / checking
10-
'optInDataExplorerGenAIFeatures',
10+
'optInGenAIFeatures',
1111
'cloudFeatureRolloutAccess',
1212
// TODO(COMPASS-9353): Provide a standard for updating Compass preferences in web
1313
'enableIndexesGuidanceExp',

packages/compass-preferences-model/src/preferences-schema.tsx

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ export type UserConfigurablePreferences = PermanentFeatureFlags &
8585
| 'web-sandbox-atlas-dev'
8686
| 'web-sandbox-atlas-qa'
8787
| 'web-sandbox-atlas';
88-
optInDataExplorerGenAIFeatures: boolean;
88+
optInGenAIFeatures: boolean;
8989
// Features that are enabled by default in Compass, but are disabled in Data
9090
// Explorer
9191
enableExplainPlan: boolean;
@@ -810,17 +810,16 @@ export const storedUserPreferencesProps: Required<{
810810
.default('atlas'),
811811
type: 'string',
812812
},
813-
optInDataExplorerGenAIFeatures: {
813+
optInGenAIFeatures: {
814814
ui: true,
815815
cli: false,
816816
global: false,
817817
description: {
818-
short: 'User Opt-in for Data Explorer Gen AI Features',
818+
short: 'User or Client Opt-in for Gen AI Features',
819819
},
820-
validator: z.boolean().default(true),
820+
validator: z.boolean().default(false),
821821
type: 'boolean',
822822
},
823-
824823
enableAtlasSearchIndexes: {
825824
ui: true,
826825
cli: true,

packages/compass-web/sandbox/index.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ const App = () => {
4848
enableGenAIFeaturesAtlasProject,
4949
enableGenAISampleDocumentPassingOnAtlasProject,
5050
enableGenAIFeaturesAtlasOrg,
51-
optInDataExplorerGenAIFeatures,
51+
optInGenAIFeatures,
5252
} = projectParams ?? {};
5353

5454
const atlasServiceSandboxBackendVariant =
@@ -135,8 +135,7 @@ const App = () => {
135135
isAtlas && !!enableGenAISampleDocumentPassingOnAtlasProject,
136136
enableGenAIFeaturesAtlasOrg:
137137
isAtlas && !!enableGenAIFeaturesAtlasOrg,
138-
optInDataExplorerGenAIFeatures:
139-
isAtlas && !!optInDataExplorerGenAIFeatures,
138+
optInGenAIFeatures: isAtlas && !!optInGenAIFeatures,
140139
enableDataModeling: true,
141140
}}
142141
onTrack={sandboxTelemetry.track}

packages/compass-web/sandbox/sandbox-atlas-sign-in.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ type ProjectParams = {
1919
enableGenAIFeaturesAtlasProject: boolean;
2020
enableGenAISampleDocumentPassingOnAtlasProject: boolean;
2121
enableGenAIFeaturesAtlasOrg: boolean;
22-
optInDataExplorerGenAIFeatures: boolean;
22+
optInGenAIFeatures: boolean;
2323
};
2424

2525
type AtlasLoginReturnValue =
@@ -129,8 +129,7 @@ export function useAtlasProxySignIn(): AtlasLoginReturnValue {
129129
projectId,
130130
csrfToken,
131131
csrfTime,
132-
optInDataExplorerGenAIFeatures:
133-
isOptedIntoDataExplorerGenAIFeatures,
132+
optInGenAIFeatures: isOptedIntoDataExplorerGenAIFeatures,
134133
enableGenAIFeaturesAtlasOrg: genAIFeaturesEnabled,
135134
enableGenAISampleDocumentPassingOnAtlasProject:
136135
groupEnabledFeatureFlags.includes(

packages/compass-web/src/preferences.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ export function useCompassWebPreferences(
5555
enableShell: false,
5656
enableCreatingNewConnections: false,
5757
enableGlobalWrites: false,
58-
optInDataExplorerGenAIFeatures: false,
58+
optInGenAIFeatures: false,
5959
enableConnectInNewWindow: false,
6060
...initialPreferences,
6161
})

0 commit comments

Comments
 (0)