Skip to content

Commit 5d873df

Browse files
committed
refactor: more cleanup
1 parent ea05667 commit 5d873df

File tree

9 files changed

+102
-119
lines changed

9 files changed

+102
-119
lines changed

src/editors/playgroundController.ts

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -503,12 +503,7 @@ export default class PlaygroundController {
503503
title: 'Running MongoDB playground...',
504504
cancellable: true,
505505
},
506-
async (progress, token): Promise<ShellEvaluateResult> => {
507-
token.onCancellationRequested(() => {
508-
// If the user clicks the cancel button,
509-
// terminate all processes running on the language server.
510-
this._languageServerController.cancelAll();
511-
});
506+
(progress, token): Promise<ShellEvaluateResult> => {
512507
return this._evaluate(codeToEvaluate, token);
513508
}
514509
);

src/language/languageServerController.ts

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ const log = createLogger('language server controller');
2828
*/
2929
export default class LanguageServerController {
3030
_context: ExtensionContext;
31-
_isExecutingInProgress = false;
3231
_client: LanguageClient;
3332
_currentConnectionId: string | null = null;
3433
_currentConnectionString?: string;
@@ -185,7 +184,6 @@ export default class LanguageServerController {
185184
filePath: playgroundExecuteParameters.filePath,
186185
inputLength: playgroundExecuteParameters.codeToEvaluate.length,
187186
});
188-
this._isExecutingInProgress = true;
189187
this._consoleOutputChannel.clear();
190188

191189
// Send a request with a cancellation token
@@ -197,8 +195,6 @@ export default class LanguageServerController {
197195
token
198196
);
199197

200-
this._isExecutingInProgress = false;
201-
202198
log.info('Evaluate response', {
203199
namespace: res?.result?.namespace,
204200
type: res?.result?.type,
@@ -263,17 +259,6 @@ export default class LanguageServerController {
263259
);
264260
}
265261

266-
cancelAll(): void {
267-
log.info('Canceling a playground...');
268-
// Send a request for cancellation. As a result
269-
// the associated CancellationToken will be notified of the cancellation,
270-
// the onCancellationRequested event will be fired,
271-
// and IsCancellationRequested will return true.
272-
if (this._isExecutingInProgress) {
273-
this._isExecutingInProgress = false;
274-
}
275-
}
276-
277262
async updateCurrentSessionFields(params): Promise<void> {
278263
await this._client.sendRequest(
279264
ServerCommands.UPDATE_CURRENT_SESSION_FIELDS,

src/participant/participant.ts

Lines changed: 11 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -134,44 +134,6 @@ export default class ParticipantController {
134134
return this._participant;
135135
}
136136

137-
handleError(err: any, command: string): void {
138-
let errorCode: string | undefined;
139-
let errorName: ParticipantErrorTypes;
140-
// Making the chat request might fail because
141-
// - model does not exist
142-
// - user consent not given
143-
// - quote limits exceeded
144-
if (err instanceof vscode.LanguageModelError) {
145-
errorCode = err.code;
146-
}
147-
148-
if (err instanceof Error) {
149-
// Unwrap the error if a cause is provided
150-
err = err.cause || err;
151-
}
152-
153-
const message: string = err.message || err.toString();
154-
155-
if (message.includes('off_topic')) {
156-
errorName = ParticipantErrorTypes.CHAT_MODEL_OFF_TOPIC;
157-
} else if (message.includes('Filtered by Responsible AI Service')) {
158-
errorName = ParticipantErrorTypes.FILTERED;
159-
} else if (message.includes('Prompt failed validation')) {
160-
errorName = ParticipantErrorTypes.INVALID_PROMPT;
161-
} else {
162-
errorName = ParticipantErrorTypes.OTHER;
163-
}
164-
165-
this._telemetryService.track(
166-
TelemetryEventTypes.PARTICIPANT_RESPONSE_FAILED,
167-
{
168-
command,
169-
error_code: errorCode,
170-
error_name: errorName,
171-
}
172-
);
173-
}
174-
175137
/**
176138
* In order to get access to the model, and to write more messages to the chat after
177139
* an async event that occurs after we've already completed our response, we need
@@ -1222,7 +1184,7 @@ export default class ParticipantController {
12221184
title: 'Exporting code to a playground...',
12231185
cancellable: true,
12241186
},
1225-
async (progress, token): Promise<string | undefined> => {
1187+
(progress, token): Promise<string | undefined> => {
12261188
token.onCancellationRequested(async () => {
12271189
await vscode.window.showInformationMessage(
12281190
'The running export to a playground operation was canceled.'
@@ -1263,7 +1225,10 @@ export default class ParticipantController {
12631225

12641226
return true;
12651227
} catch (error) {
1266-
this.handleError(error, 'exportToPlayground');
1228+
this._telemetryService.trackCopilotParticipantError(
1229+
error,
1230+
'exportToPlayground'
1231+
);
12671232
await vscode.window.showErrorMessage(
12681233
`An error occurred exporting to a playground: ${
12691234
formatError(error).message
@@ -1319,10 +1284,13 @@ Please see our [FAQ](https://www.mongodb.com/docs/generative-ai-faq/) for more i
13191284

13201285
return await this.handleGenericRequest(...args);
13211286
}
1322-
} catch (e) {
1323-
this.handleError(e, request.command || 'generic');
1287+
} catch (error) {
1288+
this._telemetryService.trackCopilotParticipantError(
1289+
error,
1290+
request.command || 'generic'
1291+
);
13241292
// Re-throw other errors so they show up in the UI.
1325-
throw e;
1293+
throw error;
13261294
}
13271295
}
13281296

src/participant/prompts/exportToPlayground.ts

Lines changed: 43 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,51 @@ import * as vscode from 'vscode';
33
export class ExportToPlaygroundPrompt {
44
static getAssistantPrompt(): vscode.LanguageModelChatMessage {
55
const prompt = `You are a MongoDB expert.
6-
Your task is to help the user build MongoDB queries and aggregation pipelines that perform their task.
7-
You convert user's code written in any programming language to the MongoDB Shell syntax.
6+
Your task is to convert user's code written in any programming language to the MongoDB mongosh shell script.
7+
8+
Example:
9+
User:
10+
public class InsertMany {
11+
public static void main(String[] args) {
12+
// Replace the uri string with your MongoDB deployment's connection string
13+
String uri = "<connection string uri>";
14+
try (MongoClient mongoClient = MongoClients.create(uri)) {
15+
MongoDatabase database = mongoClient.getDatabase("sample_mflix");
16+
MongoCollection<Document> collection = database.getCollection("movies");
17+
List<Document> movieList = Arrays.asList(
18+
new Document().append("title", "Short Circuit 3"),
19+
new Document().append("title", "The Lego Frozen Movie"));
20+
try {
21+
InsertManyResult result = collection.insertMany(movieList);
22+
System.out.println("Inserted document ids: " + result.getInsertedIds());
23+
} catch (MongoException me) {
24+
System.err.println("Unable to insert due to an error: " + me);
25+
}
26+
}
27+
}
28+
}
29+
Response:
30+
class InsertMany {
31+
main(args) {
32+
const uri = "<connection string uri>/sample_mflix";
33+
// Replace the uri string with your MongoDB deployment's connection string
34+
db = connect(uri);
35+
36+
try {
37+
const ids = db.movies.insertMany([
38+
{ "title": "Short Circuit 3" },
39+
{ "title": "The Lego Frozen Movie" },
40+
]);
41+
printjson(ids.insertedIds);
42+
} catch (error) {
43+
print(error);
44+
}
45+
}
46+
}
47+
848
Take a user prompt as an input string and translate it to the MongoDB Shell language.
949
Keep your response concise.
10-
You should suggest queries that are performant and correct.
11-
Respond with markdown, suggest code in a Markdown code block that begins with \`\`\`javascript and ends with \`\`\`.
12-
Respond in MongoDB shell syntax using the \`\`\`javascript code block syntax.`;
50+
Respond with markdown, suggest code in a Markdown code block that begins with \`\`\`javascript and ends with \`\`\`.`;
1351

1452
// eslint-disable-next-line new-cap
1553
return vscode.LanguageModelChatMessage.Assistant(prompt);

src/telemetry/telemetryService.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -430,4 +430,39 @@ export default class TelemetryService {
430430
trackCopilotParticipantFeedback(props: ParticipantFeedbackProperties): void {
431431
this.track(TelemetryEventTypes.PARTICIPANT_FEEDBACK, props);
432432
}
433+
434+
trackCopilotParticipantError(err: any, command: string): void {
435+
let errorCode: string | undefined;
436+
let errorName: ParticipantErrorTypes;
437+
// Making the chat request might fail because
438+
// - model does not exist
439+
// - user consent not given
440+
// - quote limits exceeded
441+
if (err instanceof vscode.LanguageModelError) {
442+
errorCode = err.code;
443+
}
444+
445+
if (err instanceof Error) {
446+
// Unwrap the error if a cause is provided
447+
err = err.cause || err;
448+
}
449+
450+
const message: string = err.message || err.toString();
451+
452+
if (message.includes('off_topic')) {
453+
errorName = ParticipantErrorTypes.CHAT_MODEL_OFF_TOPIC;
454+
} else if (message.includes('Filtered by Responsible AI Service')) {
455+
errorName = ParticipantErrorTypes.FILTERED;
456+
} else if (message.includes('Prompt failed validation')) {
457+
errorName = ParticipantErrorTypes.INVALID_PROMPT;
458+
} else {
459+
errorName = ParticipantErrorTypes.OTHER;
460+
}
461+
462+
this.track(TelemetryEventTypes.PARTICIPANT_RESPONSE_FAILED, {
463+
command,
464+
error_code: errorCode,
465+
error_name: errorName,
466+
});
467+
}
433468
}

src/test/suite/editors/playgroundController.test.ts

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -317,20 +317,6 @@ suite('Playground Controller Test Suite', function () {
317317
expect(showTextDocumentOptions.viewColumn).to.be.equal(-2);
318318
});
319319

320-
test('close cancelation modal when a playground is canceled', async () => {
321-
sandbox.replace(
322-
testPlaygroundController,
323-
'_evaluate',
324-
sandbox.fake.resolves(null)
325-
);
326-
327-
const result = await testPlaygroundController._evaluateWithCancelModal(
328-
''
329-
);
330-
331-
expect(result).to.deep.equal(null);
332-
});
333-
334320
test('playground controller loads the active editor on start', () => {
335321
sandbox.replaceGetter(
336322
vscode.window,

src/test/suite/language/languageServerController.test.ts

Lines changed: 0 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -105,37 +105,6 @@ suite('Language Server Controller Test Suite', () => {
105105
sandbox.restore();
106106
});
107107

108-
test('cancel a long-running script', async () => {
109-
expect(languageServerControllerStub._isExecutingInProgress).to.equal(false);
110-
const source = new vscode.CancellationTokenSource();
111-
await languageServerControllerStub.evaluate(
112-
{
113-
codeToEvaluate: `
114-
const names = [
115-
"flour",
116-
"butter",
117-
"water",
118-
"salt",
119-
"onions",
120-
"leek"
121-
];
122-
let currentName = '';
123-
names.forEach((name) => {
124-
setTimeout(() => {
125-
currentName = name;
126-
}, 500);
127-
});
128-
currentName
129-
`,
130-
connectionId: 'pineapple',
131-
},
132-
source.token
133-
);
134-
135-
languageServerControllerStub.cancelAll();
136-
expect(languageServerControllerStub._isExecutingInProgress).to.equal(false);
137-
});
138-
139108
test('the language server dependency bundle exists', async () => {
140109
const extensionPath = mdbTestExtension.extensionContextStub.extensionPath;
141110
const languageServerModuleBundlePath = path.join(

src/test/suite/participant/participant.test.ts

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1440,7 +1440,10 @@ Schema:
14401440

14411441
test('reports error', function () {
14421442
const err = Error('Filtered by Responsible AI Service');
1443-
testParticipantController.handleError(err, 'query');
1443+
testParticipantController._telemetryService.trackCopilotParticipantError(
1444+
err,
1445+
'query'
1446+
);
14441447
sinon.assert.calledOnce(telemetryTrackStub);
14451448

14461449
expect(telemetryTrackStub.lastCall.args[0]).to.be.equal(
@@ -1458,7 +1461,10 @@ Schema:
14581461
test('reports nested error', function () {
14591462
const err = new Error('Parent error');
14601463
err.cause = Error('This message is flagged as off topic: off_topic.');
1461-
testParticipantController.handleError(err, 'docs');
1464+
testParticipantController._telemetryService.trackCopilotParticipantError(
1465+
err,
1466+
'docs'
1467+
);
14621468
sinon.assert.calledOnce(telemetryTrackStub);
14631469

14641470
expect(telemetryTrackStub.lastCall.args[0]).to.be.equal(
@@ -1474,7 +1480,10 @@ Schema:
14741480
test('Reports error code when available', function () {
14751481
// eslint-disable-next-line new-cap
14761482
const err = vscode.LanguageModelError.NotFound('Model not found');
1477-
testParticipantController.handleError(err, 'schema');
1483+
testParticipantController._telemetryService.trackCopilotParticipantError(
1484+
err,
1485+
'schema'
1486+
);
14781487
sinon.assert.calledOnce(telemetryTrackStub);
14791488

14801489
expect(telemetryTrackStub.lastCall.args[0]).to.be.equal(

src/test/suite/stubs.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,6 @@ class LanguageServerControllerStub {
265265
_context: ExtensionContextStub;
266266
_storageController?: StorageController;
267267
_source?: CancellationTokenSource;
268-
_isExecutingInProgress: boolean;
269268
_client: LanguageClient;
270269
_currentConnectionId: string | null = null;
271270
_consoleOutputChannel =
@@ -331,7 +330,6 @@ class LanguageServerControllerStub {
331330
serverOptions,
332331
clientOptions
333332
);
334-
this._isExecutingInProgress = false;
335333
}
336334

337335
startLanguageServer(): Promise<void> {

0 commit comments

Comments
 (0)