in packages/core/src/codewhisperer/util/telemetryHelper.ts [351:465]
public sendUserTriggerDecisionTelemetry(
sessionId: string,
acceptedRecommendationContent: string,
referenceCount: number,
supplementalContextMetadata?: CodeWhispererSupplementalContext | undefined
) {
// the user trigger decision will aggregate information from request level user decisions within one session
// and add additional session level insights
if (!this.sessionDecisions.length) {
return
}
// TODO: add partial acceptance related metrics
const autoTriggerType = this.sessionDecisions[0].codewhispererAutomatedTriggerType
const language = this.sessionDecisions[0].codewhispererLanguage
const aggregatedCompletionType = this.sessionDecisions[0].codewhispererCompletionType
const aggregatedSuggestionState = this.getAggregatedSuggestionState(this.sessionDecisions)
const selectedCustomization = getSelectedCustomization()
const profile = AuthUtil.instance.regionProfileManager.activeRegionProfile
const generatedLines =
acceptedRecommendationContent.trim() === '' ? 0 : acceptedRecommendationContent.split('\n').length
const suggestionCount = this.sessionDecisions
.map((e) => e.codewhispererSuggestionCount)
.reduce((a, b) => a + b, 0)
const aggregated: CodewhispererUserTriggerDecision = {
codewhispererAutomatedTriggerType: autoTriggerType,
codewhispererCharactersAccepted: acceptedRecommendationContent.length,
codewhispererClassifierResult: this.classifierResult,
codewhispererClassifierThreshold: this.classifierThreshold,
codewhispererCompletionType: aggregatedCompletionType,
codewhispererCursorOffset: this.sessionDecisions[0].codewhispererCursorOffset,
codewhispererCustomizationArn: selectedCustomization.arn === '' ? undefined : selectedCustomization.arn,
codewhispererFeatureEvaluations: FeatureConfigProvider.instance.getFeatureConfigsTelemetry(),
codewhispererFirstRequestId: this.sessionDecisions[0].codewhispererFirstRequestId,
codewhispererGettingStartedTask: session.taskType,
codewhispererLanguage: language,
codewhispererLineNumber: this.sessionDecisions[0].codewhispererLineNumber,
codewhispererPreviousSuggestionState: this.prevTriggerDecision,
codewhispererSessionId: this.sessionDecisions[0].codewhispererSessionId,
codewhispererSuggestionCount: suggestionCount,
codewhispererSuggestionImportCount: this.sessionDecisions
.map((e) => e.codewhispererSuggestionImportCount || 0)
.reduce((a, b) => a + b, 0),
codewhispererSuggestionState: aggregatedSuggestionState,
codewhispererSupplementalContextIsUtg: supplementalContextMetadata?.isUtg,
codewhispererSupplementalContextLength: supplementalContextMetadata?.contentsLength,
// eslint-disable-next-line id-length
codewhispererSupplementalContextStrategyId: supplementalContextMetadata?.strategy,
codewhispererSupplementalContextTimeout: supplementalContextMetadata?.isProcessTimeout,
codewhispererTimeSinceLastDocumentChange: this.timeSinceLastModification
? this.timeSinceLastModification
: undefined,
codewhispererTimeSinceLastUserDecision: this.lastTriggerDecisionTime
? performance.now() - this.lastTriggerDecisionTime
: undefined,
codewhispererTimeToFirstRecommendation: session.timeToFirstRecommendation,
codewhispererTriggerCharacter: autoTriggerType === 'SpecialCharacters' ? this.triggerChar : undefined,
codewhispererTriggerType: this.sessionDecisions[0].codewhispererTriggerType,
codewhispererTypeaheadLength: this.typeAheadLength,
credentialStartUrl: this.sessionDecisions[0].credentialStartUrl,
traceId: this.traceId,
}
telemetry.codewhisperer_userTriggerDecision.emit(aggregated)
this.prevTriggerDecision = this.getAggregatedSuggestionState(this.sessionDecisions)
this.lastTriggerDecisionTime = performance.now()
// When we send a userTriggerDecision for neither Accept nor Reject, service side should not use this value
// and client side will set this value to 0.0.
let e2eLatency = session.firstSuggestionShowTime - session.invokeSuggestionStartTime
if (aggregatedSuggestionState !== 'Reject' && aggregatedSuggestionState !== 'Accept') {
e2eLatency = 0.0
}
client
.sendTelemetryEvent({
telemetryEvent: {
userTriggerDecisionEvent: {
sessionId: sessionId,
requestId: this.sessionDecisions[0].codewhispererFirstRequestId,
customizationArn: selectedCustomization.arn === '' ? undefined : selectedCustomization.arn,
programmingLanguage: {
languageName: runtimeLanguageContext.toRuntimeLanguage(
this.sessionDecisions[0].codewhispererLanguage
),
},
completionType: this.getSendTelemetryCompletionType(aggregatedCompletionType),
suggestionState: this.getSendTelemetrySuggestionState(aggregatedSuggestionState),
recommendationLatencyMilliseconds: e2eLatency,
triggerToResponseLatencyMilliseconds: session.timeToFirstRecommendation,
perceivedLatencyMilliseconds: session.perceivedLatency,
timestamp: new Date(Date.now()),
suggestionReferenceCount: referenceCount,
generatedLine: generatedLines,
numberOfRecommendations: suggestionCount,
acceptedCharacterCount: acceptedRecommendationContent.length,
},
},
profileArn: profile?.arn,
})
.then()
.catch((error) => {
let requestId: string | undefined
if (isAwsError(error)) {
requestId = error.requestId
}
getLogger().debug(
`Failed to sendTelemetryEvent to CodeWhisperer, requestId: ${requestId ?? ''}, message: ${
error.message
}`
)
})
this.resetUserTriggerDecisionTelemetry()
}