Skip to content

Commit 5bf6e18

Browse files
pras0131Paras
andauthored
chore: emit telemetry for inline chat result (#1131)
* feat: change to emit STE event for inline chat action * chore: add support for emitting telemetry related to inlineChatResult * fix: fix merge conflict * chore: remove the unused imports from TelemetryService class --------- Co-authored-by: Paras <[email protected]>
1 parent 2dfc9cb commit 5bf6e18

File tree

6 files changed

+156
-2
lines changed

6 files changed

+156
-2
lines changed

server/aws-lsp-codewhisperer/src/language-server/agenticChat/agenticChatController.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1739,7 +1739,9 @@ export class AgenticChatController implements ChatHandlers {
17391739
}
17401740
}
17411741

1742-
async onInlineChatResult(handler: InlineChatResultParams) {}
1742+
async onInlineChatResult(params: InlineChatResultParams) {
1743+
await this.#telemetryService.emitInlineChatResultLog(params)
1744+
}
17431745

17441746
async onCodeInsertToCursorPosition(params: InsertToCursorPositionParams) {
17451747
// Implementation based on https://github.com/aws/aws-toolkit-vscode/blob/1814cc84228d4bf20270574c5980b91b227f31cf/packages/core/src/amazonq/commons/controllers/contentController.ts#L38

server/aws-lsp-codewhisperer/src/language-server/agenticChat/qAgenticChatServer.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,10 @@ export const QAgenticChatServer =
155155
return chatController.onButtonClick(params)
156156
})
157157

158+
chat.onInlineChatResult(params => {
159+
return chatController.onInlineChatResult(params)
160+
})
161+
158162
logging.log('Q Chat server has been initialized')
159163

160164
return () => {

server/aws-lsp-codewhisperer/src/language-server/chat/chatController.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,9 @@ export class ChatController implements ChatHandlers {
285285
}
286286
}
287287

288-
async onInlineChatResult(handler: InlineChatResultParams) {}
288+
async onInlineChatResult(params: InlineChatResultParams) {
289+
await this.#telemetryService.emitInlineChatResultLog(params)
290+
}
289291

290292
async onCodeInsertToCursorPosition(params: InsertToCursorPositionParams) {
291293
// Implementation based on https://github.com/aws/aws-toolkit-vscode/blob/1814cc84228d4bf20270574c5980b91b227f31cf/packages/core/src/amazonq/commons/controllers/contentController.ts#L38

server/aws-lsp-codewhisperer/src/language-server/chat/qChatServer.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,10 @@ export const QChatServerFactory =
116116
return chatController.onCodeInsertToCursorPosition(params)
117117
})
118118

119+
chat.onInlineChatResult(params => {
120+
return chatController.onInlineChatResult(params)
121+
})
122+
119123
logging.log('Q Chat server has been initialized')
120124

121125
return () => {

server/aws-lsp-codewhisperer/src/shared/telemetry/telemetryService.test.ts

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -907,4 +907,119 @@ describe('TelemetryService', () => {
907907
sinon.assert.notCalled(codeWhisperServiceStub.sendTelemetryEvent)
908908
})
909909
})
910+
911+
describe('Inline chat result notification', () => {
912+
let telemetryService: TelemetryService
913+
let mockCredentialsProvider: MockCredentialsProvider
914+
915+
beforeEach(() => {
916+
mockCredentialsProvider = new MockCredentialsProvider()
917+
mockCredentialsProvider.setConnectionMetadata({
918+
sso: {
919+
startUrl: 'idc-start-url',
920+
},
921+
})
922+
923+
codeWhisperServiceStub.getCredentialsType.returns('bearer')
924+
telemetryService = new TelemetryService(serviceManagerStub, mockCredentialsProvider, telemetry, logging)
925+
})
926+
927+
afterEach(() => {
928+
sinon.restore()
929+
})
930+
931+
it('should send InlineChatEvent with correct parameters', () => {
932+
const timestamp = new Date()
933+
telemetryService.emitInlineChatResultLog({
934+
requestId: 'mock-request-id',
935+
inputLength: 10,
936+
selectedLines: 2,
937+
suggestionAddedChars: 20,
938+
suggestionAddedLines: 3,
939+
suggestionDeletedChars: 10,
940+
suggestionDeletedLines: 2,
941+
codeIntent: true,
942+
userDecision: 'ACCEPT',
943+
responseStartLatency: 1250,
944+
responseEndLatency: 1500,
945+
programmingLanguage: {
946+
languageName: 'typescript',
947+
},
948+
})
949+
950+
const expectedEvent = {
951+
telemetryEvent: {
952+
inlineChatEvent: {
953+
requestId: 'mock-request-id',
954+
timestamp: timestamp,
955+
inputLength: 10,
956+
numSelectedLines: 2,
957+
numSuggestionAddChars: 20,
958+
numSuggestionAddLines: 3,
959+
numSuggestionDelChars: 10,
960+
numSuggestionDelLines: 2,
961+
codeIntent: true,
962+
userDecision: 'ACCEPT',
963+
responseStartLatency: 1250,
964+
responseEndLatency: 1500,
965+
programmingLanguage: {
966+
languageName: 'typescript',
967+
},
968+
},
969+
},
970+
}
971+
sinon.assert.calledOnceWithExactly(codeWhisperServiceStub.sendTelemetryEvent, expectedEvent)
972+
})
973+
974+
it('should not send InlineChatEvent when credentialsType is IAM', () => {
975+
codeWhisperServiceStub.getCredentialsType.returns('iam')
976+
telemetryService = new TelemetryService(serviceManagerStub, mockCredentialsProvider, telemetry, logging)
977+
const timestamp = new Date()
978+
telemetryService.emitInlineChatResultLog({
979+
requestId: 'mock-request-id',
980+
inputLength: 10,
981+
selectedLines: 2,
982+
suggestionAddedChars: 20,
983+
suggestionAddedLines: 3,
984+
suggestionDeletedChars: 10,
985+
suggestionDeletedLines: 2,
986+
codeIntent: true,
987+
userDecision: 'ACCEPT',
988+
responseStartLatency: 1250,
989+
responseEndLatency: 1500,
990+
programmingLanguage: {
991+
languageName: 'typescript',
992+
},
993+
})
994+
sinon.assert.notCalled(codeWhisperServiceStub.sendTelemetryEvent)
995+
})
996+
997+
it('should not send InlineChatEvent when login is BuilderID, but user chose OPTOUT option', () => {
998+
mockCredentialsProvider.setConnectionMetadata({
999+
sso: {
1000+
startUrl: BUILDER_ID_START_URL,
1001+
},
1002+
})
1003+
telemetryService = new TelemetryService(serviceManagerStub, mockCredentialsProvider, telemetry, logging)
1004+
telemetryService.updateOptOutPreference('OPTOUT')
1005+
const timestamp = new Date()
1006+
telemetryService.emitInlineChatResultLog({
1007+
requestId: 'mock-request-id',
1008+
inputLength: 10,
1009+
selectedLines: 2,
1010+
suggestionAddedChars: 20,
1011+
suggestionAddedLines: 3,
1012+
suggestionDeletedChars: 10,
1013+
suggestionDeletedLines: 2,
1014+
codeIntent: true,
1015+
userDecision: 'ACCEPT',
1016+
responseStartLatency: 1250,
1017+
responseEndLatency: 1500,
1018+
programmingLanguage: {
1019+
languageName: 'typescript',
1020+
},
1021+
})
1022+
sinon.assert.notCalled(codeWhisperServiceStub.sendTelemetryEvent)
1023+
})
1024+
})
9101025
})

server/aws-lsp-codewhisperer/src/shared/telemetry/telemetryService.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import {
1818
TelemetryEvent,
1919
ChatAddMessageEvent,
2020
UserIntent,
21+
InlineChatEvent,
2122
} from '../../client/token/codewhispererbearertokenclient'
2223
import { getCompletionType, getSsoConnectionType, isAwsError } from '../utils'
2324
import {
@@ -34,6 +35,7 @@ import {
3435
import { CodewhispererLanguage, getRuntimeLanguage } from '../languageDetection'
3536
import { CONVERSATION_ID_METRIC_KEY } from '../../language-server/chat/telemetry/chatTelemetryController'
3637
import { AmazonQBaseServiceManager } from '../amazonQServiceManager/BaseAmazonQServiceManager'
38+
import { InlineChatResultParams } from '@aws/language-server-runtimes/protocol'
3739

3840
export class TelemetryService {
3941
// Using Base service manager here to support fallback cases such as in codeWhispererServer
@@ -530,4 +532,29 @@ export class TelemetryService {
530532
chatAddMessageEvent: event,
531533
})
532534
}
535+
536+
public emitInlineChatResultLog(params: InlineChatResultParams) {
537+
const event: InlineChatEvent = {
538+
requestId: params.requestId,
539+
timestamp: new Date(),
540+
inputLength: params.inputLength,
541+
numSelectedLines: params.selectedLines,
542+
numSuggestionAddChars: params.suggestionAddedChars,
543+
numSuggestionAddLines: params.suggestionAddedLines,
544+
numSuggestionDelChars: params.suggestionDeletedChars,
545+
numSuggestionDelLines: params.suggestionDeletedLines,
546+
codeIntent: params.codeIntent,
547+
userDecision: params.userDecision,
548+
responseStartLatency: params.responseStartLatency,
549+
responseEndLatency: params.responseEndLatency,
550+
}
551+
if (params.programmingLanguage) {
552+
event.programmingLanguage = {
553+
languageName: getRuntimeLanguage(params.programmingLanguage.languageName as CodewhispererLanguage),
554+
}
555+
}
556+
return this.invokeSendTelemetryEvent({
557+
inlineChatEvent: event,
558+
})
559+
}
533560
}

0 commit comments

Comments
 (0)