@@ -36,7 +36,6 @@ import { supportedLanguagesList } from '../chat/chatRequest/converter'
3636import { AuthUtil } from '../../../codewhisperer/util/authUtil'
3737import { getSelectedCustomization } from '../../../codewhisperer/util/customizationUtil'
3838import { undefinedIfEmpty } from '../../../shared'
39- import { uiEventRecorder } from '../../../amazonq/util/eventRecorder'
4039
4140export function logSendTelemetryEventFailure ( error : any ) {
4241 let requestId : string | undefined
@@ -59,17 +58,42 @@ export function recordTelemetryChatRunCommand(type: CwsprChatCommandType, comman
5958}
6059
6160export class CWCTelemetryHelper {
61+ static instance : CWCTelemetryHelper
6262 private sessionStorage : ChatSessionStorage
6363 private triggerEventsStorage : TriggerEventsStorage
64- private responseStreamTotalTime : Map < string , number > = new Map ( )
6564 private responseStreamTimeForChunks : Map < string , number [ ] > = new Map ( )
6665 private responseWithProjectContext : Map < string , boolean > = new Map ( )
6766
67+ /**
68+ * Stores payload information about a message response until
69+ * the full round trip time finishes and addMessage telemetry
70+ * is sent
71+ */
72+ private messageStorage : Map <
73+ string ,
74+ {
75+ triggerPayload : TriggerPayload
76+ message : PromptAnswer
77+ }
78+ > = new Map ( )
79+
6880 constructor ( sessionStorage : ChatSessionStorage , triggerEventsStorage : TriggerEventsStorage ) {
6981 this . sessionStorage = sessionStorage
7082 this . triggerEventsStorage = triggerEventsStorage
7183 }
7284
85+ public static init ( sessionStorage : ChatSessionStorage , triggerEventsStorage : TriggerEventsStorage ) {
86+ const lastInstance = CWCTelemetryHelper . instance
87+ if ( lastInstance !== undefined ) {
88+ return lastInstance
89+ }
90+
91+ getLogger ( ) . debug ( 'CWCTelemetryHelper: Initialized new telemetry helper' )
92+ const instance = new CWCTelemetryHelper ( sessionStorage , triggerEventsStorage )
93+ CWCTelemetryHelper . instance = instance
94+ return instance
95+ }
96+
7397 private getUserIntentForTelemetry ( userIntent : UserIntent | undefined ) : CwsprChatUserIntent | undefined {
7498 switch ( userIntent ) {
7599 case UserIntent . EXPLAIN_CODE_SELECTION :
@@ -334,7 +358,26 @@ export class CWCTelemetryHelper {
334358 } )
335359 }
336360
361+ /**
362+ * Store the trigger payload and message until the full message round trip finishes
363+ *
364+ * @calls emitAddMessage when the full message round trip finishes
365+ */
337366 public recordAddMessage ( triggerPayload : TriggerPayload , message : PromptAnswer ) {
367+ this . messageStorage . set ( message . tabID , {
368+ triggerPayload,
369+ message,
370+ } )
371+ }
372+
373+ public emitAddMessage ( tabID : string , fullResponseLatency : number , startTime ?: number ) {
374+ const payload = this . messageStorage . get ( tabID )
375+ if ( ! payload ) {
376+ return
377+ }
378+
379+ const { triggerPayload, message } = payload
380+
338381 const triggerEvent = this . triggerEventsStorage . getLastTriggerEventByTabID ( message . tabID )
339382 const hasProjectLevelContext =
340383 triggerPayload . relevantTextDocuments &&
@@ -355,9 +398,9 @@ export class CWCTelemetryHelper {
355398 cwsprChatSourceLinkCount : message . suggestionCount ,
356399 cwsprChatReferencesCount : message . codeReferenceCount ,
357400 cwsprChatFollowUpCount : message . followUpCount ,
358- cwsprChatTimeToFirstChunk : this . getResponseStreamTimeToFirstChunk ( message . tabID ) ,
401+ cwsprChatTimeToFirstChunk : this . getResponseStreamTimeToFirstChunk ( message . tabID , startTime ) ,
359402 cwsprChatTimeBetweenChunks : JSON . stringify ( this . getResponseStreamTimeBetweenChunks ( message . tabID ) ) ,
360- cwsprChatFullResponseLatency : this . responseStreamTotalTime . get ( message . tabID ) ?? 0 ,
403+ cwsprChatFullResponseLatency : fullResponseLatency ,
361404 cwsprChatRequestLength : triggerPayload . message ?. length ?? 0 ,
362405 cwsprChatResponseLength : message . messageLength ,
363406 cwsprChatConversationType : 'Chat' ,
@@ -394,6 +437,8 @@ export class CWCTelemetryHelper {
394437 } )
395438 . then ( )
396439 . catch ( logSendTelemetryEventFailure )
440+
441+ this . messageStorage . delete ( tabID )
397442 }
398443
399444 public recordMessageResponseError ( triggerPayload : TriggerPayload , tabID : string , responseCode : number ) {
@@ -453,9 +498,12 @@ export class CWCTelemetryHelper {
453498 this . responseWithProjectContext . set ( messageId , true )
454499 }
455500
456- private getResponseStreamTimeToFirstChunk ( tabID : string ) : number {
501+ private getResponseStreamTimeToFirstChunk ( tabID : string , startTime ?: number ) : number {
502+ if ( ! startTime ) {
503+ return 0
504+ }
457505 const chunkTimes = this . responseStreamTimeForChunks . get ( tabID ) ?? [ 0 ]
458- return Math . round ( this . compareChatStartTime ( tabID , chunkTimes [ 0 ] ) )
506+ return Math . round ( chunkTimes [ 0 ] - startTime )
459507 }
460508
461509 private getResponseStreamTimeBetweenChunks ( tabID : string ) : number [ ] {
@@ -473,11 +521,6 @@ export class CWCTelemetryHelper {
473521 }
474522 }
475523
476- public setResponseStreamTotalTime ( tabID : string ) {
477- const totalTime = this . compareChatStartTime ( tabID , globals . clock . Date . now ( ) )
478- this . responseStreamTotalTime . set ( tabID , Math . round ( totalTime ) )
479- }
480-
481524 public getConversationId ( tabID : string ) : string | undefined {
482525 return this . sessionStorage . getSession ( tabID ) . sessionIdentifier
483526 }
@@ -489,20 +532,4 @@ export class CWCTelemetryHelper {
489532 supportedLanguagesList . includes ( programmingLanguage )
490533 )
491534 }
492-
493- /**
494- * Get the start time of this chat event and compare it to comparisonTime.
495- *
496- * @returns the duration between start time and comparisonTime or -1 if the message start time is not found
497- */
498- private compareChatStartTime ( tabID : string , comparisonTime : number ) {
499- const chatMessageSentTime = uiEventRecorder . get ( tabID ) ?. events ?. chatMessageSent
500- getLogger ( ) . info ( 'chat message sent time: %s. Comparison time: %s' , chatMessageSentTime , comparisonTime )
501- if ( chatMessageSentTime === undefined ) {
502- return - 1
503- }
504- getLogger ( ) . info ( 'time origin: %s' , performance . timeOrigin )
505-
506- return comparisonTime - chatMessageSentTime
507- }
508535}
0 commit comments