@aws/lsp-codewhisperer 0.0.56 → 0.0.58
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/CHANGELOG.md +36 -0
- package/out/language-server/agenticChat/agenticChatController.js +36 -23
- package/out/language-server/agenticChat/agenticChatController.js.map +1 -1
- package/out/language-server/agenticChat/errors.d.ts +60 -1
- package/out/language-server/agenticChat/errors.js +178 -1
- package/out/language-server/agenticChat/errors.js.map +1 -1
- package/out/language-server/agenticChat/tools/executeBash.d.ts +24 -1
- package/out/language-server/agenticChat/tools/executeBash.js +56 -9
- package/out/language-server/agenticChat/tools/executeBash.js.map +1 -1
- package/out/language-server/agenticChat/tools/fsReplace.js +6 -5
- package/out/language-server/agenticChat/tools/fsReplace.js.map +1 -1
- package/out/language-server/agenticChat/tools/fsWrite.js +5 -4
- package/out/language-server/agenticChat/tools/fsWrite.js.map +1 -1
- package/out/language-server/agenticChat/tools/toolServer.js +1 -12
- package/out/language-server/agenticChat/tools/toolServer.js.map +1 -1
- package/out/language-server/chat/chatSessionService.js +3 -0
- package/out/language-server/chat/chatSessionService.js.map +1 -1
- package/out/language-server/inline-completion/codeWhispererServer.js +274 -63
- package/out/language-server/inline-completion/codeWhispererServer.js.map +1 -1
- package/out/language-server/inline-completion/session/sessionManager.d.ts +2 -0
- package/out/language-server/inline-completion/session/sessionManager.js +13 -0
- package/out/language-server/inline-completion/session/sessionManager.js.map +1 -1
- package/out/language-server/workspaceContext/dependency/dependencyEventBundler.d.ts +24 -0
- package/out/language-server/workspaceContext/dependency/dependencyEventBundler.js +63 -0
- package/out/language-server/workspaceContext/dependency/dependencyEventBundler.js.map +1 -0
- package/out/language-server/workspaceContext/workspaceContextServer.js +12 -1
- package/out/language-server/workspaceContext/workspaceContextServer.js.map +1 -1
- package/out/shared/codeWhispererService.d.ts +1 -1
- package/out/shared/constants.d.ts +1 -0
- package/out/shared/constants.js +140 -1
- package/out/shared/constants.js.map +1 -1
- package/out/shared/localProjectContextController.d.ts +2 -2
- package/out/shared/localProjectContextController.js +42 -79
- package/out/shared/localProjectContextController.js.map +1 -1
- package/out/shared/telemetry/telemetryService.d.ts +1 -1
- package/out/shared/telemetry/telemetryService.js +8 -2
- package/out/shared/telemetry/telemetryService.js.map +1 -1
- package/out/shared/telemetryUtils.js +2 -2
- package/out/shared/telemetryUtils.js.map +1 -1
- package/out/shared/utils.d.ts +8 -0
- package/out/shared/utils.js +50 -0
- package/out/shared/utils.js.map +1 -1
- package/package.json +4 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chatSessionService.js","sourceRoot":"","sources":["../../../src/language-server/chat/chatSessionService.ts"],"names":[],"mappings":";;;AAOA,gFAI4C;AAE5C,
|
|
1
|
+
{"version":3,"file":"chatSessionService.js","sourceRoot":"","sources":["../../../src/language-server/chat/chatSessionService.ts"],"names":[],"mappings":"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"}
|
|
@@ -22,6 +22,11 @@ const workspaceFolderManager_1 = require("../workspaceContext/workspaceFolderMan
|
|
|
22
22
|
const path = require("path");
|
|
23
23
|
const util_1 = require("../workspaceContext/util");
|
|
24
24
|
const userWrittenCodeTracker_1 = require("../../shared/userWrittenCodeTracker");
|
|
25
|
+
const codeEditTracker_1 = require("./tracker/codeEditTracker");
|
|
26
|
+
const cursorTracker_1 = require("./tracker/cursorTracker");
|
|
27
|
+
const rejectedEditTracker_1 = require("./tracker/rejectedEditTracker");
|
|
28
|
+
const diffUtils_1 = require("./diffUtils");
|
|
29
|
+
const { editPredictionAutoTrigger } = require('./auto-trigger/editPredictionAutoTrigger');
|
|
25
30
|
const EMPTY_RESULT = { sessionId: '', items: [] };
|
|
26
31
|
exports.FILE_URI_CHARS_LIMIT = 1024;
|
|
27
32
|
exports.FILENAME_CHARS_LIMIT = 1024;
|
|
@@ -74,7 +79,10 @@ const emitServiceInvocationTelemetry = (telemetry, session, requestId) => {
|
|
|
74
79
|
telemetry.emitMetric({
|
|
75
80
|
name: 'codewhisperer_serviceInvocation',
|
|
76
81
|
result: 'Succeeded',
|
|
77
|
-
data
|
|
82
|
+
data: {
|
|
83
|
+
...data,
|
|
84
|
+
codewhispererImportRecommendationEnabled: session.includeImportsWithSuggestions,
|
|
85
|
+
},
|
|
78
86
|
});
|
|
79
87
|
};
|
|
80
88
|
const emitServiceInvocationFailure = (telemetry, session, error) => {
|
|
@@ -130,7 +138,7 @@ const emitPerceivedLatencyTelemetry = (telemetry, session) => {
|
|
|
130
138
|
data,
|
|
131
139
|
});
|
|
132
140
|
};
|
|
133
|
-
const emitUserTriggerDecisionTelemetry = async (telemetry, telemetryService, session, timeSinceLastUserModification) => {
|
|
141
|
+
const emitUserTriggerDecisionTelemetry = async (telemetry, telemetryService, session, timeSinceLastUserModification, addedCharsCountForEditSuggestion, deletedCharsCountForEditSuggestion, streakLength) => {
|
|
134
142
|
// Prevent reporting user decision if it was already sent
|
|
135
143
|
if (session.reportedUserDecision) {
|
|
136
144
|
return;
|
|
@@ -139,11 +147,11 @@ const emitUserTriggerDecisionTelemetry = async (telemetry, telemetryService, ses
|
|
|
139
147
|
if (!session.getAggregatedUserTriggerDecision()) {
|
|
140
148
|
return;
|
|
141
149
|
}
|
|
142
|
-
await emitAggregatedUserTriggerDecisionTelemetry(telemetryService, session, timeSinceLastUserModification);
|
|
150
|
+
await emitAggregatedUserTriggerDecisionTelemetry(telemetryService, session, timeSinceLastUserModification, addedCharsCountForEditSuggestion, deletedCharsCountForEditSuggestion, streakLength);
|
|
143
151
|
session.reportedUserDecision = true;
|
|
144
152
|
};
|
|
145
|
-
const emitAggregatedUserTriggerDecisionTelemetry = (telemetryService, session, timeSinceLastUserModification) => {
|
|
146
|
-
return telemetryService.emitUserTriggerDecision(session, timeSinceLastUserModification);
|
|
153
|
+
const emitAggregatedUserTriggerDecisionTelemetry = (telemetryService, session, timeSinceLastUserModification, addedCharsCountForEditSuggestion, deletedCharsCountForEditSuggestion, streakLength) => {
|
|
154
|
+
return telemetryService.emitUserTriggerDecision(session, timeSinceLastUserModification, addedCharsCountForEditSuggestion, deletedCharsCountForEditSuggestion, streakLength);
|
|
147
155
|
};
|
|
148
156
|
const mergeSuggestionsWithRightContext = (rightFileContext, suggestions, includeImportsWithSuggestions, range) => {
|
|
149
157
|
return suggestions.map(suggestion => {
|
|
@@ -190,12 +198,20 @@ const CodewhispererServerFactory = (serviceManager) => ({ credentialsProvider, l
|
|
|
190
198
|
let codePercentageTracker;
|
|
191
199
|
let userWrittenCodeTracker;
|
|
192
200
|
let codeDiffTracker;
|
|
201
|
+
// Trackers for monitoring edits and cursor position.
|
|
202
|
+
const recentEditTracker = codeEditTracker_1.RecentEditTracker.getInstance(logging, codeEditTracker_1.RecentEditTrackerDefaultConfig);
|
|
203
|
+
const cursorTracker = cursorTracker_1.CursorTracker.getInstance();
|
|
204
|
+
const rejectedEditTracker = rejectedEditTracker_1.RejectedEditTracker.getInstance(logging, rejectedEditTracker_1.DEFAULT_REJECTED_EDIT_TRACKER_CONFIG);
|
|
205
|
+
let editsEnabled = false;
|
|
193
206
|
const onInlineCompletionHandler = async (params, token) => {
|
|
194
207
|
// On every new completion request close current inflight session.
|
|
195
208
|
const currentSession = sessionManager.getCurrentSession();
|
|
196
209
|
if (currentSession && currentSession.state == 'REQUESTING' && !params.partialResultToken) {
|
|
197
210
|
currentSession.discardInflightSessionOnNewInvocation = true;
|
|
198
211
|
}
|
|
212
|
+
if (cursorTracker) {
|
|
213
|
+
cursorTracker.trackPosition(params.textDocument.uri, params.position);
|
|
214
|
+
}
|
|
199
215
|
return workspace.getTextDocument(params.textDocument.uri).then(async (textDocument) => {
|
|
200
216
|
const codeWhispererService = amazonQServiceManager.getCodewhispererService();
|
|
201
217
|
if (params.partialResultToken && currentSession) {
|
|
@@ -270,6 +286,9 @@ const CodewhispererServerFactory = (serviceManager) => ({ credentialsProvider, l
|
|
|
270
286
|
!autoTriggerResult.shouldTrigger) {
|
|
271
287
|
return EMPTY_RESULT;
|
|
272
288
|
}
|
|
289
|
+
// Get supplemental context from recent edits if available.
|
|
290
|
+
let supplementalContextFromEdits = undefined;
|
|
291
|
+
let predictionTypes = [['COMPLETIONS']];
|
|
273
292
|
// supplementalContext available only via token authentication
|
|
274
293
|
const supplementalContextPromise = codeWhispererService instanceof codeWhispererService_1.CodeWhispererServiceToken
|
|
275
294
|
? (0, supplementalContextUtil_1.fetchSupplementalContext)(textDocument, params.position, workspace, logging, token, amazonQServiceManager)
|
|
@@ -281,19 +300,87 @@ const CodewhispererServerFactory = (serviceManager) => ({ credentialsProvider, l
|
|
|
281
300
|
const supplementalContext = await supplementalContextPromise;
|
|
282
301
|
// TODO: logging
|
|
283
302
|
if (codeWhispererService instanceof codeWhispererService_1.CodeWhispererServiceToken) {
|
|
284
|
-
|
|
285
|
-
|
|
303
|
+
const supplementalContextItems = supplementalContext?.supplementalContextItems || [];
|
|
304
|
+
requestContext.supplementalContexts = [
|
|
305
|
+
...supplementalContextItems.map(v => ({
|
|
286
306
|
content: v.content,
|
|
287
307
|
filePath: v.filePath,
|
|
288
|
-
}))
|
|
289
|
-
|
|
308
|
+
})),
|
|
309
|
+
];
|
|
310
|
+
if (editsEnabled) {
|
|
311
|
+
// Step 0: Determine if we have "Rcent Edit context"
|
|
312
|
+
if (recentEditTracker) {
|
|
313
|
+
supplementalContextFromEdits =
|
|
314
|
+
await recentEditTracker.generateEditBasedContext(textDocument);
|
|
315
|
+
}
|
|
316
|
+
const editPredictionAutoTriggerResult = editPredictionAutoTrigger({
|
|
317
|
+
fileContext: fileContext,
|
|
318
|
+
lineNum: params.position.line,
|
|
319
|
+
char: triggerCharacter,
|
|
320
|
+
previousDecision: previousDecision,
|
|
321
|
+
cursorHistory: cursorTracker,
|
|
322
|
+
recentEdits: recentEditTracker,
|
|
323
|
+
});
|
|
324
|
+
predictionTypes = [
|
|
325
|
+
...(autoTriggerResult.shouldTrigger ? [['COMPLETIONS']] : []),
|
|
326
|
+
...(editPredictionAutoTriggerResult.shouldTrigger && editsEnabled ? [['EDITS']] : []),
|
|
327
|
+
];
|
|
328
|
+
// Step 1: Recent Edits context
|
|
329
|
+
const supplementalContextItemsForEdits = supplementalContextFromEdits?.supplementalContextItems || [];
|
|
330
|
+
requestContext.supplementalContexts.push(...supplementalContextItemsForEdits.map(v => ({
|
|
331
|
+
content: v.content,
|
|
332
|
+
filePath: v.filePath,
|
|
333
|
+
type: 'PreviousEditorState',
|
|
334
|
+
metadata: {
|
|
335
|
+
previousEditorStateMetadata: {
|
|
336
|
+
timeOffset: 1000,
|
|
337
|
+
},
|
|
338
|
+
},
|
|
339
|
+
})));
|
|
340
|
+
// Step 2: Prediction type COMPLETION, Edits or both
|
|
341
|
+
requestContext.predictionTypes = predictionTypes.flat();
|
|
342
|
+
// Step 3: Current Editor/Cursor state
|
|
343
|
+
requestContext.editorState = {
|
|
344
|
+
document: {
|
|
345
|
+
relativeFilePath: textDocument.uri,
|
|
346
|
+
programmingLanguage: {
|
|
347
|
+
languageName: textDocument.languageId,
|
|
348
|
+
},
|
|
349
|
+
text: textDocument.getText(),
|
|
350
|
+
},
|
|
351
|
+
cursorState: {
|
|
352
|
+
position: {
|
|
353
|
+
line: params.position.line,
|
|
354
|
+
character: params.position.character,
|
|
355
|
+
},
|
|
356
|
+
},
|
|
357
|
+
};
|
|
358
|
+
}
|
|
290
359
|
}
|
|
291
360
|
// Close ACTIVE session and record Discard trigger decision immediately
|
|
292
361
|
if (currentSession && currentSession.state === 'ACTIVE') {
|
|
293
362
|
// Emit user trigger decision at session close time for active session
|
|
294
363
|
sessionManager.discardSession(currentSession);
|
|
295
|
-
|
|
364
|
+
const streakLength = sessionManager.getAndUpdateStreakLength(false);
|
|
365
|
+
await emitUserTriggerDecisionTelemetry(telemetry, telemetryService, currentSession, timeSinceLastUserModification, 0, 0, streakLength);
|
|
296
366
|
}
|
|
367
|
+
const supplementalMetadata = editsEnabled
|
|
368
|
+
? {
|
|
369
|
+
// Merge metadata from edit-based context if available.
|
|
370
|
+
contentsLength: (supplementalContext?.contentsLength || 0) +
|
|
371
|
+
(supplementalContextFromEdits?.contentsLength || 0),
|
|
372
|
+
latency: Math.max(supplementalContext?.latency || 0, supplementalContextFromEdits?.latency || 0),
|
|
373
|
+
isUtg: supplementalContext?.isUtg || false,
|
|
374
|
+
isProcessTimeout: supplementalContext?.isProcessTimeout || false,
|
|
375
|
+
strategy: supplementalContextFromEdits
|
|
376
|
+
? 'recentEdits'
|
|
377
|
+
: supplementalContext?.strategy || 'Empty',
|
|
378
|
+
supplementalContextItems: [
|
|
379
|
+
...(supplementalContext?.supplementalContextItems || []),
|
|
380
|
+
...(supplementalContextFromEdits?.supplementalContextItems || []),
|
|
381
|
+
],
|
|
382
|
+
}
|
|
383
|
+
: supplementalContext;
|
|
297
384
|
const newSession = sessionManager.createSession({
|
|
298
385
|
document: textDocument,
|
|
299
386
|
startPosition: params.position,
|
|
@@ -305,7 +392,7 @@ const CodewhispererServerFactory = (serviceManager) => ({ credentialsProvider, l
|
|
|
305
392
|
classifierResult: autoTriggerResult?.classifierResult,
|
|
306
393
|
classifierThreshold: autoTriggerResult?.classifierThreshold,
|
|
307
394
|
credentialStartUrl: credentialsProvider.getConnectionMetadata?.()?.sso?.startUrl ?? undefined,
|
|
308
|
-
supplementalMetadata:
|
|
395
|
+
supplementalMetadata: supplementalMetadata,
|
|
309
396
|
customizationArn: lsp_core_1.textUtils.undefinedIfEmpty(codeWhispererService.customizationArn),
|
|
310
397
|
});
|
|
311
398
|
// Add extra context to request context
|
|
@@ -314,8 +401,7 @@ const CodewhispererServerFactory = (serviceManager) => ({ credentialsProvider, l
|
|
|
314
401
|
requestContext.fileContext.leftFileContent =
|
|
315
402
|
extraContext + '\n' + requestContext.fileContext.leftFileContent;
|
|
316
403
|
}
|
|
317
|
-
|
|
318
|
-
.generateSuggestions({
|
|
404
|
+
const generateCompletionReq = {
|
|
319
405
|
...requestContext,
|
|
320
406
|
fileContext: {
|
|
321
407
|
...requestContext.fileContext,
|
|
@@ -327,7 +413,9 @@ const CodewhispererServerFactory = (serviceManager) => ({ credentialsProvider, l
|
|
|
327
413
|
.replaceAll('\r\n', '\n'),
|
|
328
414
|
},
|
|
329
415
|
...(workspaceId ? { workspaceId: workspaceId } : {}),
|
|
330
|
-
}
|
|
416
|
+
};
|
|
417
|
+
return codeWhispererService
|
|
418
|
+
.generateSuggestions(generateCompletionReq)
|
|
331
419
|
.then(async (suggestionResponse) => {
|
|
332
420
|
return processSuggestionResponse(suggestionResponse, newSession, true, selectionRange);
|
|
333
421
|
})
|
|
@@ -337,7 +425,7 @@ const CodewhispererServerFactory = (serviceManager) => ({ credentialsProvider, l
|
|
|
337
425
|
}
|
|
338
426
|
});
|
|
339
427
|
};
|
|
340
|
-
const processSuggestionResponse = async (suggestionResponse, session, isNewSession, selectionRange) => {
|
|
428
|
+
const processSuggestionResponse = async (suggestionResponse, session, isNewSession, selectionRange, textDocument) => {
|
|
341
429
|
codePercentageTracker.countInvocation(session.language);
|
|
342
430
|
userWrittenCodeTracker?.recordUsageCount(session.language);
|
|
343
431
|
session.includeImportsWithSuggestions =
|
|
@@ -358,6 +446,7 @@ const CodewhispererServerFactory = (serviceManager) => ({ credentialsProvider, l
|
|
|
358
446
|
if (session.discardInflightSessionOnNewInvocation) {
|
|
359
447
|
session.discardInflightSessionOnNewInvocation = false;
|
|
360
448
|
sessionManager.discardSession(session);
|
|
449
|
+
const streakLength = sessionManager.getAndUpdateStreakLength(false);
|
|
361
450
|
await emitUserTriggerDecisionTelemetry(telemetry, telemetryService, session, timeSinceLastUserModification);
|
|
362
451
|
}
|
|
363
452
|
// session was closed by user already made decisions consequent completion request before new paginated API response was received
|
|
@@ -393,40 +482,69 @@ const CodewhispererServerFactory = (serviceManager) => ({ credentialsProvider, l
|
|
|
393
482
|
session.setSuggestionState(suggestion.itemId, 'Filter');
|
|
394
483
|
return false;
|
|
395
484
|
});
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
485
|
+
if (suggestionResponse.suggestionType === codeWhispererService_1.SuggestionType.COMPLETION) {
|
|
486
|
+
const { includeImportsWithSuggestions } = amazonQServiceManager.getConfiguration();
|
|
487
|
+
const suggestionsWithRightContext = mergeSuggestionsWithRightContext(session.requestContext.fileContext.rightFileContent, filteredSuggestions, includeImportsWithSuggestions, selectionRange).filter(suggestion => {
|
|
488
|
+
// Discard suggestions that have empty string insertText after right context merge and can't be displayed anymore
|
|
489
|
+
if (suggestion.insertText === '') {
|
|
490
|
+
session.setSuggestionState(suggestion.itemId, 'Discard');
|
|
491
|
+
return false;
|
|
492
|
+
}
|
|
493
|
+
return true;
|
|
494
|
+
});
|
|
495
|
+
suggestionsWithRightContext.forEach(suggestion => {
|
|
496
|
+
const cachedSuggestion = session.suggestions.find(s => s.itemId === suggestion.itemId);
|
|
497
|
+
if (cachedSuggestion)
|
|
498
|
+
cachedSuggestion.insertText = suggestion.insertText.toString();
|
|
499
|
+
});
|
|
500
|
+
// TODO: need dedupe after right context merging but I don't see one
|
|
501
|
+
session.suggestionsAfterRightContextMerge.push(...suggestionsWithRightContext);
|
|
502
|
+
session.codewhispererSuggestionImportCount =
|
|
503
|
+
session.codewhispererSuggestionImportCount +
|
|
504
|
+
suggestionsWithRightContext.reduce((total, suggestion) => {
|
|
505
|
+
return total + (suggestion.mostRelevantMissingImports?.length || 0);
|
|
506
|
+
}, 0);
|
|
507
|
+
// If after all server-side filtering no suggestions can be displayed, and there is no nextToken
|
|
508
|
+
// close session and return empty results
|
|
509
|
+
if (session.suggestionsAfterRightContextMerge.length === 0 &&
|
|
510
|
+
!suggestionResponse.responseContext.nextToken) {
|
|
511
|
+
sessionManager.closeSession(session);
|
|
512
|
+
await emitUserTriggerDecisionTelemetry(telemetry, telemetryService, session, timeSinceLastUserModification);
|
|
513
|
+
return EMPTY_RESULT;
|
|
402
514
|
}
|
|
403
|
-
return
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
515
|
+
return {
|
|
516
|
+
items: suggestionsWithRightContext,
|
|
517
|
+
sessionId: session.id,
|
|
518
|
+
partialResultToken: suggestionResponse.responseContext.nextToken,
|
|
519
|
+
};
|
|
520
|
+
}
|
|
521
|
+
else {
|
|
522
|
+
return {
|
|
523
|
+
items: suggestionResponse.suggestions
|
|
524
|
+
.map(suggestion => {
|
|
525
|
+
// Check if this suggestion is similar to a previously rejected edit
|
|
526
|
+
const isSimilarToRejected = rejectedEditTracker.isSimilarToRejected(suggestion.content, textDocument?.uri || '');
|
|
527
|
+
if (isSimilarToRejected) {
|
|
528
|
+
// Mark as rejected in the session
|
|
529
|
+
session.setSuggestionState(suggestion.itemId, 'Reject');
|
|
530
|
+
logging.debug(`[EDIT_PREDICTION] Filtered out suggestion similar to previously rejected edit`);
|
|
531
|
+
// Return empty item that will be filtered out
|
|
532
|
+
return {
|
|
533
|
+
insertText: '',
|
|
534
|
+
isInlineEdit: true,
|
|
535
|
+
itemId: suggestion.itemId,
|
|
536
|
+
};
|
|
537
|
+
}
|
|
538
|
+
return {
|
|
539
|
+
insertText: suggestion.content,
|
|
540
|
+
isInlineEdit: true,
|
|
541
|
+
itemId: suggestion.itemId,
|
|
542
|
+
};
|
|
543
|
+
})
|
|
544
|
+
.filter(item => item.insertText !== ''),
|
|
545
|
+
sessionId: session.id,
|
|
546
|
+
};
|
|
424
547
|
}
|
|
425
|
-
return {
|
|
426
|
-
items: suggestionsWithRightContext,
|
|
427
|
-
sessionId: session.id,
|
|
428
|
-
partialResultToken: suggestionResponse.responseContext.nextToken,
|
|
429
|
-
};
|
|
430
548
|
};
|
|
431
549
|
const handleSuggestionsErrors = (error, session) => {
|
|
432
550
|
logging.log('Recommendation failure: ' + error);
|
|
@@ -444,15 +562,17 @@ const CodewhispererServerFactory = (serviceManager) => ({ credentialsProvider, l
|
|
|
444
562
|
return EMPTY_RESULT;
|
|
445
563
|
};
|
|
446
564
|
// Schedule tracker for UserModification Telemetry event
|
|
447
|
-
const enqueueCodeDiffEntry = (session, acceptedSuggestion) => {
|
|
565
|
+
const enqueueCodeDiffEntry = (session, acceptedSuggestion, addedCharactersForEdit) => {
|
|
448
566
|
const endPosition = (0, utils_1.getEndPositionForAcceptedSuggestion)(acceptedSuggestion.content, session.startPosition);
|
|
567
|
+
// use the addedCharactersForEdit if it is EDIT suggestion type
|
|
568
|
+
const originalString = addedCharactersForEdit ? addedCharactersForEdit : acceptedSuggestion.content;
|
|
449
569
|
codeDiffTracker.enqueue({
|
|
450
570
|
sessionId: session.codewhispererSessionId || '',
|
|
451
571
|
requestId: session.responseContext?.requestId || '',
|
|
452
572
|
fileUrl: session.document.uri,
|
|
453
573
|
languageId: session.language,
|
|
454
574
|
time: Date.now(),
|
|
455
|
-
originalString:
|
|
575
|
+
originalString: originalString,
|
|
456
576
|
startPosition: session.startPosition,
|
|
457
577
|
endPosition: endPosition,
|
|
458
578
|
customizationArn: session.customizationArn,
|
|
@@ -462,7 +582,7 @@ const CodewhispererServerFactory = (serviceManager) => ({ credentialsProvider, l
|
|
|
462
582
|
});
|
|
463
583
|
};
|
|
464
584
|
const onLogInlineCompletionSessionResultsHandler = async (params) => {
|
|
465
|
-
const { sessionId, completionSessionResult, firstCompletionDisplayLatency, totalSessionDisplayTime, typeaheadLength, } = params;
|
|
585
|
+
const { sessionId, completionSessionResult, firstCompletionDisplayLatency, totalSessionDisplayTime, typeaheadLength, isInlineEdit, } = params;
|
|
466
586
|
const session = sessionManager.getSessionById(sessionId);
|
|
467
587
|
if (!session) {
|
|
468
588
|
logging.log(`ERROR: Session ID ${sessionId} was not found`);
|
|
@@ -473,13 +593,50 @@ const CodewhispererServerFactory = (serviceManager) => ({ credentialsProvider, l
|
|
|
473
593
|
return;
|
|
474
594
|
}
|
|
475
595
|
const acceptedItemId = Object.keys(params.completionSessionResult).find(k => params.completionSessionResult[k].accepted);
|
|
596
|
+
const isAccepted = acceptedItemId ? true : false;
|
|
476
597
|
const acceptedSuggestion = session.suggestions.find(s => s.itemId === acceptedItemId);
|
|
477
|
-
|
|
598
|
+
let addedCharactersForEditSuggestion = '';
|
|
599
|
+
let deletedCharactersForEditSuggestion = '';
|
|
600
|
+
if (acceptedSuggestion !== undefined) {
|
|
478
601
|
if (acceptedSuggestion) {
|
|
479
602
|
codePercentageTracker.countSuccess(session.language);
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
603
|
+
if (isInlineEdit && acceptedSuggestion.content) {
|
|
604
|
+
// [acceptedSuggestion.insertText] will be undefined for NEP suggestion. Use [acceptedSuggestion.content] instead.
|
|
605
|
+
// Since [acceptedSuggestion.content] is in the form of a diff, transform the content into addedCharacters and deletedCharacters.
|
|
606
|
+
const addedAndDeletedChars = (0, diffUtils_1.getAddedAndDeletedChars)(acceptedSuggestion.content);
|
|
607
|
+
if (addedAndDeletedChars) {
|
|
608
|
+
addedCharactersForEditSuggestion = addedAndDeletedChars.addedCharacters;
|
|
609
|
+
deletedCharactersForEditSuggestion = addedAndDeletedChars.deletedCharacters;
|
|
610
|
+
codePercentageTracker.countAcceptedTokens(session.language, addedCharactersForEditSuggestion);
|
|
611
|
+
codePercentageTracker.countTotalTokens(session.language, addedCharactersForEditSuggestion, true);
|
|
612
|
+
enqueueCodeDiffEntry(session, acceptedSuggestion, addedCharactersForEditSuggestion);
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
else if (acceptedSuggestion.insertText) {
|
|
616
|
+
codePercentageTracker.countAcceptedTokens(session.language, acceptedSuggestion.insertText);
|
|
617
|
+
codePercentageTracker.countTotalTokens(session.language, acceptedSuggestion.insertText, true);
|
|
618
|
+
enqueueCodeDiffEntry(session, acceptedSuggestion);
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
// Handle rejected edit predictions
|
|
623
|
+
if (isInlineEdit && !isAccepted) {
|
|
624
|
+
// Find all rejected suggestions in this session
|
|
625
|
+
const rejectedSuggestions = session.suggestions.filter(suggestion => {
|
|
626
|
+
const result = completionSessionResult[suggestion.itemId];
|
|
627
|
+
return result && result.seen && !result.accepted;
|
|
628
|
+
});
|
|
629
|
+
// Record each rejected edit
|
|
630
|
+
for (const rejectedSuggestion of rejectedSuggestions) {
|
|
631
|
+
if (rejectedSuggestion.content) {
|
|
632
|
+
rejectedEditTracker.recordRejectedEdit({
|
|
633
|
+
content: rejectedSuggestion.content,
|
|
634
|
+
timestamp: Date.now(),
|
|
635
|
+
documentUri: session.document.uri,
|
|
636
|
+
position: session.startPosition,
|
|
637
|
+
});
|
|
638
|
+
logging.debug(`[EDIT_PREDICTION] Recorded rejected edit: ${rejectedSuggestion.content.substring(0, 20)}...`);
|
|
639
|
+
}
|
|
483
640
|
}
|
|
484
641
|
}
|
|
485
642
|
session.setClientResultData(completionSessionResult, firstCompletionDisplayLatency, totalSessionDisplayTime, typeaheadLength);
|
|
@@ -487,7 +644,8 @@ const CodewhispererServerFactory = (serviceManager) => ({ credentialsProvider, l
|
|
|
487
644
|
emitPerceivedLatencyTelemetry(telemetry, session);
|
|
488
645
|
// Always emit user trigger decision at session close
|
|
489
646
|
sessionManager.closeSession(session);
|
|
490
|
-
|
|
647
|
+
const streakLength = sessionManager.getAndUpdateStreakLength(isAccepted);
|
|
648
|
+
await emitUserTriggerDecisionTelemetry(telemetry, telemetryService, session, timeSinceLastUserModification, addedCharactersForEditSuggestion.length, deletedCharactersForEditSuggestion.length, streakLength);
|
|
491
649
|
};
|
|
492
650
|
const updateConfiguration = (updatedConfig) => {
|
|
493
651
|
logging.debug('Updating configuration of inline complete server.');
|
|
@@ -501,9 +659,9 @@ const CodewhispererServerFactory = (serviceManager) => ({ credentialsProvider, l
|
|
|
501
659
|
}
|
|
502
660
|
logging.debug(`CodePercentageTracker customizationArn updated to ${customizationArn}`);
|
|
503
661
|
/*
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
662
|
+
The flag enableTelemetryEventsToDestination is set to true temporarily. It's value will be determined through destination
|
|
663
|
+
configuration post all events migration to STE. It'll be replaced by qConfig['enableTelemetryEventsToDestination'] === true
|
|
664
|
+
*/
|
|
507
665
|
// const enableTelemetryEventsToDestination = true
|
|
508
666
|
// telemetryService.updateEnableTelemetryEventsToDestination(enableTelemetryEventsToDestination)
|
|
509
667
|
telemetryService.updateOptOutPreference(optOutTelemetryPreference);
|
|
@@ -512,6 +670,10 @@ const CodewhispererServerFactory = (serviceManager) => ({ credentialsProvider, l
|
|
|
512
670
|
const onInitializedHandler = async () => {
|
|
513
671
|
amazonQServiceManager = serviceManager();
|
|
514
672
|
const clientParams = (0, utils_1.safeGet)(lsp.getClientInitializeParams(), new errors_1.AmazonQServiceInitializationError('TelemetryService initialized before LSP connection was initialized.'));
|
|
673
|
+
logging.log(`Client initialization params: ${JSON.stringify(clientParams)}`);
|
|
674
|
+
editsEnabled =
|
|
675
|
+
clientParams?.initializationOptions?.aws?.awsClientCapabilities?.textDocument
|
|
676
|
+
?.inlineCompletionWithReferences?.inlineEditSupport ?? false;
|
|
515
677
|
telemetryService = new telemetryService_1.TelemetryService(amazonQServiceManager, credentialsProvider, telemetry, logging);
|
|
516
678
|
telemetryService.updateUserContext((0, telemetryUtils_1.makeUserContextObject)(clientParams, runtime.platform, 'INLINE'));
|
|
517
679
|
codePercentageTracker = new codePercentage_1.CodePercentageTracker(telemetryService);
|
|
@@ -526,11 +688,13 @@ const CodewhispererServerFactory = (serviceManager) => ({ credentialsProvider, l
|
|
|
526
688
|
modificationPercentage: percentage,
|
|
527
689
|
unmodifiedAcceptedCharacterCount: unmodifiedAcceptedCharacterCount,
|
|
528
690
|
}, {
|
|
529
|
-
completionType: entry.completionType,
|
|
530
|
-
triggerType: entry.triggerType,
|
|
691
|
+
completionType: entry.completionType || 'LINE',
|
|
692
|
+
triggerType: entry.triggerType || 'OnDemand',
|
|
531
693
|
credentialStartUrl: entry.credentialStartUrl,
|
|
532
694
|
});
|
|
533
695
|
});
|
|
696
|
+
const periodicLoggingEnabled = process.env.LOG_EDIT_TRACKING === 'true';
|
|
697
|
+
logging.log(`[SERVER] Initialized telemetry-dependent components: CodePercentageTracker, CodeDiffTracker, periodicLogging=${periodicLoggingEnabled}`);
|
|
534
698
|
await amazonQServiceManager.addDidChangeConfigurationListener(updateConfiguration);
|
|
535
699
|
};
|
|
536
700
|
lsp.extensions.onInlineCompletionWithReferences(onInlineCompletionHandler);
|
|
@@ -542,6 +706,7 @@ const CodewhispererServerFactory = (serviceManager) => ({ credentialsProvider, l
|
|
|
542
706
|
if (!textDocument || !languageId) {
|
|
543
707
|
return;
|
|
544
708
|
}
|
|
709
|
+
logging.log(`Document changed: ${p.textDocument.uri}`);
|
|
545
710
|
p.contentChanges.forEach(change => {
|
|
546
711
|
codePercentageTracker.countTotalTokens(languageId, change.text, false);
|
|
547
712
|
const { sendUserWrittenCodeMetrics } = amazonQServiceManager.getConfiguration();
|
|
@@ -559,12 +724,58 @@ const CodewhispererServerFactory = (serviceManager) => ({ credentialsProvider, l
|
|
|
559
724
|
timeSinceLastUserModification = new Date().getTime() - lastUserModificationTime;
|
|
560
725
|
}
|
|
561
726
|
lastUserModificationTime = new Date().getTime();
|
|
727
|
+
// Process document changes with RecentEditTracker.
|
|
728
|
+
if (editsEnabled && recentEditTracker) {
|
|
729
|
+
logging.log(`[SERVER] Processing document change with RecentEditTracker: ${p.textDocument.uri}, version: ${textDocument.version}`);
|
|
730
|
+
logging.log(`[SERVER] Change details: ${p.contentChanges.length} changes`);
|
|
731
|
+
await recentEditTracker.handleDocumentChange({
|
|
732
|
+
uri: p.textDocument.uri,
|
|
733
|
+
languageId: textDocument.languageId,
|
|
734
|
+
version: textDocument.version,
|
|
735
|
+
text: textDocument.getText(),
|
|
736
|
+
});
|
|
737
|
+
}
|
|
738
|
+
});
|
|
739
|
+
lsp.onDidOpenTextDocument(p => {
|
|
740
|
+
logging.log(`Document opened: ${p.textDocument.uri}`);
|
|
741
|
+
// Track document opening with RecentEditTracker
|
|
742
|
+
if (recentEditTracker) {
|
|
743
|
+
logging.log(`[SERVER] Tracking document open with RecentEditTracker: ${p.textDocument.uri}`);
|
|
744
|
+
recentEditTracker.handleDocumentOpen({
|
|
745
|
+
uri: p.textDocument.uri,
|
|
746
|
+
languageId: p.textDocument.languageId,
|
|
747
|
+
version: p.textDocument.version,
|
|
748
|
+
text: p.textDocument.text,
|
|
749
|
+
});
|
|
750
|
+
}
|
|
751
|
+
});
|
|
752
|
+
lsp.onDidCloseTextDocument(p => {
|
|
753
|
+
logging.log(`Document closed: ${p.textDocument.uri}`);
|
|
754
|
+
// Track document closing with RecentEditTracker
|
|
755
|
+
if (recentEditTracker) {
|
|
756
|
+
logging.log(`[SERVER] Tracking document close with RecentEditTracker: ${p.textDocument.uri}`);
|
|
757
|
+
recentEditTracker.handleDocumentClose(p.textDocument.uri);
|
|
758
|
+
}
|
|
759
|
+
if (cursorTracker) {
|
|
760
|
+
cursorTracker.clearHistory(p.textDocument.uri);
|
|
761
|
+
}
|
|
562
762
|
});
|
|
563
763
|
logging.log('Amazon Q Inline Suggestion server has been initialised');
|
|
564
764
|
return async () => {
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
765
|
+
// Dispose all trackers in reverse order of initialization
|
|
766
|
+
if (codePercentageTracker)
|
|
767
|
+
codePercentageTracker.dispose();
|
|
768
|
+
if (userWrittenCodeTracker)
|
|
769
|
+
userWrittenCodeTracker?.dispose();
|
|
770
|
+
if (codeDiffTracker)
|
|
771
|
+
await codeDiffTracker.shutdown();
|
|
772
|
+
if (recentEditTracker)
|
|
773
|
+
recentEditTracker.dispose();
|
|
774
|
+
if (cursorTracker)
|
|
775
|
+
cursorTracker.dispose();
|
|
776
|
+
if (rejectedEditTracker)
|
|
777
|
+
rejectedEditTracker.dispose();
|
|
778
|
+
logging.log('Amazon Q Inline Suggestion server has been shut down');
|
|
568
779
|
};
|
|
569
780
|
};
|
|
570
781
|
exports.CodewhispererServerFactory = CodewhispererServerFactory;
|