Path: blob/main/extensions/copilot/src/platform/networking/node/chatWebSocketTelemetry.ts
13400 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45import { ITelemetryService } from '../../telemetry/common/telemetry';67interface IChatWebSocketConnectionTelemetryProperties {8conversationId: string;9initiatingRequestId: string;10gitHubRequestId: string;11}1213interface IChatWebSocketRequestTelemetryProperties extends IChatWebSocketConnectionTelemetryProperties {14modelId: string | undefined;15requestId: string | undefined;16turnId: string | undefined;17previousTurnId: string | undefined;18hadActiveRequest: boolean;19}2021export interface IChatWebSocketConnectedTelemetryProperties extends IChatWebSocketConnectionTelemetryProperties {22connectDurationMs: number;23}2425export interface IChatWebSocketConnectErrorTelemetryProperties extends IChatWebSocketConnectionTelemetryProperties {26error: string;27connectDurationMs: number;28responseStatusCode: number | undefined;29responseStatusText: string | undefined;30networkError: string | undefined;31}3233export interface IChatWebSocketCloseTelemetryProperties extends IChatWebSocketRequestTelemetryProperties {34closeCode: number;35closeReason: string;36closeEventReason: string;37closeEventWasClean: string;38connectionDurationMs: number;39totalSentMessageCount: number;40totalReceivedMessageCount: number;41totalSentCharacters: number;42totalReceivedCharacters: number;43}4445export interface IChatWebSocketErrorTelemetryProperties extends IChatWebSocketRequestTelemetryProperties {46error: string;47connectionDurationMs: number;48totalSentMessageCount: number;49totalReceivedMessageCount: number;50totalSentCharacters: number;51totalReceivedCharacters: number;52}5354export interface IChatWebSocketCloseDuringSetupTelemetryProperties extends IChatWebSocketConnectionTelemetryProperties {55closeCode: number;56closeReason: string;57closeEventReason: string;58closeEventWasClean: string;59connectDurationMs: number;60}6162export interface IChatWebSocketRequestSentTelemetryProperties extends IChatWebSocketRequestTelemetryProperties {63statefulMarkerMatched: boolean;64previousResponseIdUnset: boolean;65hasCompactionData: boolean;66summarizedAtRoundIdSet: boolean;67summarizedAtRoundIdMatched: boolean;68modeChanged: boolean | undefined;69compactionThreshold: number | undefined;70tokenCountMax: number;71modelMaxPromptTokens: number;72connectionDurationMs: number;73totalSentMessageCount: number;74totalReceivedMessageCount: number;75sentMessageCharacters: number;76totalSentCharacters: number;77totalReceivedCharacters: number;78}7980export interface IChatWebSocketMessageParseErrorTelemetryProperties extends IChatWebSocketRequestTelemetryProperties {81error: string;82connectionDurationMs: number;83totalSentMessageCount: number;84totalReceivedMessageCount: number;85receivedMessageCharacters: number;86totalSentCharacters: number;87totalReceivedCharacters: number;88}8990export type ChatWebSocketRequestOutcome = 'completed' | 'response_failed' | 'response_incomplete' | 'response_cancelled' | 'upstream_error' | 'canceled' | 'superseded' | 'connection_closed' | 'connection_disposed' | 'error_response';9192export interface IChatWebSocketRequestOutcomeTelemetryProperties extends IChatWebSocketRequestTelemetryProperties {93requestOutcome: ChatWebSocketRequestOutcome;94statefulMarkerMatched: boolean;95previousResponseIdUnset: boolean;96hasCompactionData: boolean;97summarizedAtRoundIdSet: boolean;98summarizedAtRoundIdMatched: boolean;99modeChanged: boolean | undefined;100compactionThreshold: number | undefined;101promptTokenCount: number;102tokenCountMax: number;103modelMaxPromptTokens: number;104connectionDurationMs: number;105requestDurationMs: number;106totalSentMessageCount: number;107totalReceivedMessageCount: number;108totalSentCharacters: number;109totalReceivedCharacters: number;110requestSentMessageCount: number;111requestReceivedMessageCount: number;112requestSentCharacters: number;113requestReceivedCharacters: number;114closeCode?: number;115closeReason?: string;116serverErrorMessage?: string;117serverErrorCode?: string;118}119120export class ChatWebSocketTelemetrySender {121122public static sendConnectedTelemetry(123telemetryService: ITelemetryService,124properties: IChatWebSocketConnectedTelemetryProperties,125) {126/* __GDPR__127"websocket.connected" : {128"owner": "chrmarti",129"comment": "Report a successful WebSocket connection.",130"conversationId": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Id of the conversation" },131"initiatingRequestId": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Id of the request that initiated the connection" },132"gitHubRequestId": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "GitHub request id if available" },133"connectDurationMs": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Time to establish the WebSocket connection in milliseconds", "isMeasurement": true }134}135*/136telemetryService.sendTelemetryEvent('websocket.connected', { github: true, microsoft: true }, {137conversationId: properties.conversationId,138initiatingRequestId: properties.initiatingRequestId,139gitHubRequestId: properties.gitHubRequestId,140}, {141connectDurationMs: properties.connectDurationMs,142});143}144145public static sendConnectErrorTelemetry(146telemetryService: ITelemetryService,147properties: IChatWebSocketConnectErrorTelemetryProperties,148) {149/* __GDPR__150"websocket.connectError" : {151"owner": "chrmarti",152"comment": "Report a failed WebSocket connection attempt.",153"conversationId": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Id of the conversation" },154"initiatingRequestId": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Id of the request that initiated the connection" },155"gitHubRequestId": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "GitHub request id if available" },156"error": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Error message for the failed connection" },157"connectDurationMs": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Time until the connection error in milliseconds", "isMeasurement": true },158"responseStatusCode": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "HTTP response status code from the failed connection attempt", "isMeasurement": true },159"responseStatusText": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "HTTP response status text from the failed connection attempt" },160"networkError": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "The underlying network error code and message from the dispatch layer" }161}162*/163telemetryService.sendTelemetryErrorEvent('websocket.connectError', { github: true, microsoft: true }, {164conversationId: properties.conversationId,165initiatingRequestId: properties.initiatingRequestId,166gitHubRequestId: properties.gitHubRequestId,167error: properties.error,168responseStatusText: properties.responseStatusText,169networkError: properties.networkError,170}, {171connectDurationMs: properties.connectDurationMs,172responseStatusCode: properties.responseStatusCode,173});174}175176public static sendCloseTelemetry(177telemetryService: ITelemetryService,178properties: IChatWebSocketCloseTelemetryProperties,179) {180/* __GDPR__181"websocket.close" : {182"owner": "chrmarti",183"comment": "Report a WebSocket connection close event.",184"conversationId": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Id of the conversation" },185"initiatingRequestId": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Id of the request that initiated the connection" },186"turnId": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Id of the turn" },187"previousTurnId": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Turn id of the previous request on this connection" },188"hadActiveRequest": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Whether the previous request was still active when the new one began", "isMeasurement": true },189"requestId": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Id of the current turn request" },190"gitHubRequestId": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "GitHub request id if available" },191"modelId": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Model identifier from the request body" },192"closeReason": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Human-readable description of the close code" },193"closeEventReason": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Close event reason string from server" },194"closeEventWasClean": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Whether the connection closed cleanly" },195"closeCode": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "WebSocket close code", "isMeasurement": true },196"totalSentMessageCount": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Number of messages sent over this connection", "isMeasurement": true },197"totalReceivedMessageCount": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Number of messages received over this connection", "isMeasurement": true },198"totalSentCharacters": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Total characters sent over this connection", "isMeasurement": true },199"totalReceivedCharacters": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Total characters received over this connection", "isMeasurement": true },200"connectionDurationMs": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "How long the connection was open in milliseconds", "isMeasurement": true }201}202*/203telemetryService.sendTelemetryEvent('websocket.close', { github: true, microsoft: true }, {204conversationId: properties.conversationId,205initiatingRequestId: properties.initiatingRequestId,206turnId: properties.turnId,207previousTurnId: properties.previousTurnId,208requestId: properties.requestId,209gitHubRequestId: properties.gitHubRequestId,210modelId: properties.modelId,211closeReason: properties.closeReason,212closeEventReason: properties.closeEventReason,213closeEventWasClean: properties.closeEventWasClean,214}, {215hadActiveRequest: properties.hadActiveRequest ? 1 : 0,216closeCode: properties.closeCode,217totalSentMessageCount: properties.totalSentMessageCount,218totalReceivedMessageCount: properties.totalReceivedMessageCount,219totalSentCharacters: properties.totalSentCharacters,220totalReceivedCharacters: properties.totalReceivedCharacters,221connectionDurationMs: properties.connectionDurationMs,222});223}224225public static sendErrorTelemetry(226telemetryService: ITelemetryService,227properties: IChatWebSocketErrorTelemetryProperties,228) {229/* __GDPR__230"websocket.error" : {231"owner": "chrmarti",232"comment": "Report a runtime error on an established WebSocket connection.",233"conversationId": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Id of the conversation" },234"initiatingRequestId": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Id of the request that initiated the connection" },235"turnId": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Id of the turn" },236"previousTurnId": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Turn id of the previous request on this connection" },237"hadActiveRequest": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Whether the previous request was still active when the new one began", "isMeasurement": true },238"requestId": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Id of the current turn request" },239"gitHubRequestId": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "GitHub request id if available" },240"modelId": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Model identifier from the request body" },241"error": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Error message" },242"totalSentMessageCount": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Number of messages sent over this connection", "isMeasurement": true },243"totalReceivedMessageCount": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Number of messages received over this connection", "isMeasurement": true },244"totalSentCharacters": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Total characters sent over this connection", "isMeasurement": true },245"totalReceivedCharacters": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Total characters received over this connection", "isMeasurement": true },246"connectionDurationMs": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "How long the connection was open before the error in milliseconds", "isMeasurement": true }247}248*/249telemetryService.sendTelemetryErrorEvent('websocket.error', { github: true, microsoft: true }, {250conversationId: properties.conversationId,251initiatingRequestId: properties.initiatingRequestId,252turnId: properties.turnId,253previousTurnId: properties.previousTurnId,254requestId: properties.requestId,255gitHubRequestId: properties.gitHubRequestId,256modelId: properties.modelId,257error: properties.error,258}, {259hadActiveRequest: properties.hadActiveRequest ? 1 : 0,260totalSentMessageCount: properties.totalSentMessageCount,261totalReceivedMessageCount: properties.totalReceivedMessageCount,262totalSentCharacters: properties.totalSentCharacters,263totalReceivedCharacters: properties.totalReceivedCharacters,264connectionDurationMs: properties.connectionDurationMs,265});266}267268public static sendCloseDuringSetupTelemetry(269telemetryService: ITelemetryService,270properties: IChatWebSocketCloseDuringSetupTelemetryProperties,271) {272/* __GDPR__273"websocket.closeDuringSetup" : {274"owner": "chrmarti",275"comment": "Report when a WebSocket connection is closed during setup before fully opening.",276"conversationId": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Id of the conversation" },277"initiatingRequestId": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Id of the request that initiated the connection" },278"gitHubRequestId": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "GitHub request id if available" },279"closeReason": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Human-readable description of the close code" },280"closeEventReason": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Close event reason string from server" },281"closeEventWasClean": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Whether the connection closed cleanly" },282"closeCode": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "WebSocket close code", "isMeasurement": true },283"connectDurationMs": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Time until the connection was closed during setup in milliseconds", "isMeasurement": true }284}285*/286telemetryService.sendTelemetryErrorEvent('websocket.closeDuringSetup', { github: true, microsoft: true }, {287conversationId: properties.conversationId,288initiatingRequestId: properties.initiatingRequestId,289gitHubRequestId: properties.gitHubRequestId,290closeReason: properties.closeReason,291closeEventReason: properties.closeEventReason,292closeEventWasClean: properties.closeEventWasClean,293}, {294closeCode: properties.closeCode,295connectDurationMs: properties.connectDurationMs,296});297}298299public static sendRequestSentTelemetry(300telemetryService: ITelemetryService,301properties: IChatWebSocketRequestSentTelemetryProperties,302) {303/* __GDPR__304"websocket.requestSent" : {305"owner": "chrmarti",306"comment": "Report when a request is sent over the WebSocket connection.",307"conversationId": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Id of the conversation" },308"initiatingRequestId": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Id of the request that initiated the connection" },309"turnId": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Id of the turn" },310"previousTurnId": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Turn id of the previous request on this connection" },311"hadActiveRequest": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Whether the previous request was still active when the new one began", "isMeasurement": true },312"requestId": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Id of the current turn request" },313"gitHubRequestId": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "GitHub request id if available" },314"modelId": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Model identifier from the request body" },315"statefulMarkerMatched": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Whether the connection stateful marker matched the previous_response_id sent in the request", "isMeasurement": true },316"previousResponseIdUnset": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Whether previous_response_id was undefined in the request", "isMeasurement": true },317"hasCompactionData": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Whether the request input contains compaction data", "isMeasurement": true },318"summarizedAtRoundIdSet": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Whether a summarized round ID was set in the request options", "isMeasurement": true },319"summarizedAtRoundIdMatched": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Whether the summarized round ID matches the one stored on the connection", "isMeasurement": true },320"modeChanged": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Whether the mode instructions changed since the previous request (-1 if unknown, 0 if unchanged, 1 if changed)", "isMeasurement": true },321"compactionThreshold": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Compaction threshold from context_management in the request body", "isMeasurement": true },322"tokenCountMax": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Maximum generated tokens", "isMeasurement": true },323"modelMaxPromptTokens": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Maximum prompt tokens for the model", "isMeasurement": true },324"totalSentMessageCount": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Number of messages sent over this connection", "isMeasurement": true },325"totalReceivedMessageCount": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Number of messages received over this connection", "isMeasurement": true },326"sentMessageCharacters": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Character count of this sent message payload", "isMeasurement": true },327"totalSentCharacters": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Total characters sent over this connection", "isMeasurement": true },328"totalReceivedCharacters": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Total characters received over this connection", "isMeasurement": true },329"connectionDurationMs": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "How long the connection has been open when the request is sent in milliseconds", "isMeasurement": true }330}331*/332telemetryService.sendTelemetryEvent('websocket.requestSent', { github: true, microsoft: true }, {333conversationId: properties.conversationId,334initiatingRequestId: properties.initiatingRequestId,335turnId: properties.turnId,336previousTurnId: properties.previousTurnId,337requestId: properties.requestId,338gitHubRequestId: properties.gitHubRequestId,339modelId: properties.modelId,340}, {341hadActiveRequest: properties.hadActiveRequest ? 1 : 0,342statefulMarkerMatched: properties.statefulMarkerMatched ? 1 : 0,343previousResponseIdUnset: properties.previousResponseIdUnset ? 1 : 0,344hasCompactionData: properties.hasCompactionData ? 1 : 0,345summarizedAtRoundIdSet: properties.summarizedAtRoundIdSet ? 1 : 0,346summarizedAtRoundIdMatched: properties.summarizedAtRoundIdMatched ? 1 : 0,347modeChanged: properties.modeChanged === undefined ? -1 : properties.modeChanged ? 1 : 0,348compactionThreshold: properties.compactionThreshold,349tokenCountMax: properties.tokenCountMax,350modelMaxPromptTokens: properties.modelMaxPromptTokens,351totalSentMessageCount: properties.totalSentMessageCount,352totalReceivedMessageCount: properties.totalReceivedMessageCount,353sentMessageCharacters: properties.sentMessageCharacters,354totalSentCharacters: properties.totalSentCharacters,355totalReceivedCharacters: properties.totalReceivedCharacters,356connectionDurationMs: properties.connectionDurationMs,357});358}359360public static sendMessageParseErrorTelemetry(361telemetryService: ITelemetryService,362properties: IChatWebSocketMessageParseErrorTelemetryProperties,363) {364/* __GDPR__365"websocket.messageParseError" : {366"owner": "chrmarti",367"comment": "Report when a received websocket message fails JSON parsing.",368"conversationId": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Id of the conversation" },369"initiatingRequestId": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Id of the request that initiated the connection" },370"turnId": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Id of the turn" },371"previousTurnId": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Turn id of the previous request on this connection" },372"hadActiveRequest": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Whether the previous request was still active when the new one began", "isMeasurement": true },373"requestId": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Id of the current turn request" },374"gitHubRequestId": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "GitHub request id if available" },375"modelId": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Model identifier from the request body" },376"error": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Parse error message" },377"totalSentMessageCount": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Number of messages sent over this connection", "isMeasurement": true },378"totalReceivedMessageCount": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Number of messages received over this connection", "isMeasurement": true },379"receivedMessageCharacters": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Character count of the received message that failed parsing", "isMeasurement": true },380"totalSentCharacters": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Total characters sent over this connection", "isMeasurement": true },381"totalReceivedCharacters": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Total characters received over this connection", "isMeasurement": true },382"connectionDurationMs": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "How long the connection has been open when parsing fails in milliseconds", "isMeasurement": true }383}384*/385telemetryService.sendTelemetryErrorEvent('websocket.messageParseError', { github: true, microsoft: true }, {386conversationId: properties.conversationId,387initiatingRequestId: properties.initiatingRequestId,388turnId: properties.turnId,389previousTurnId: properties.previousTurnId,390requestId: properties.requestId,391gitHubRequestId: properties.gitHubRequestId,392modelId: properties.modelId,393error: properties.error,394}, {395hadActiveRequest: properties.hadActiveRequest ? 1 : 0,396totalSentMessageCount: properties.totalSentMessageCount,397totalReceivedMessageCount: properties.totalReceivedMessageCount,398receivedMessageCharacters: properties.receivedMessageCharacters,399totalSentCharacters: properties.totalSentCharacters,400totalReceivedCharacters: properties.totalReceivedCharacters,401connectionDurationMs: properties.connectionDurationMs,402});403}404405public static sendRequestOutcomeTelemetry(406telemetryService: ITelemetryService,407properties: IChatWebSocketRequestOutcomeTelemetryProperties,408) {409/* __GDPR__410"websocket.requestOutcome" : {411"owner": "chrmarti",412"comment": "Report terminal outcome for a websocket request.",413"conversationId": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Id of the conversation" },414"initiatingRequestId": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Id of the request that initiated the connection" },415"turnId": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Id of the turn" },416"previousTurnId": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Turn id of the previous request on this connection" },417"hadActiveRequest": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Whether the previous request was still active when the new one began", "isMeasurement": true },418"requestId": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Id of the current turn request" },419"gitHubRequestId": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "GitHub request id if available" },420"modelId": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Model identifier from the request body" },421"requestOutcome": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Terminal outcome of the websocket request" },422"statefulMarkerMatched": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Whether the connection stateful marker matched the previous_response_id sent in the request", "isMeasurement": true },423"previousResponseIdUnset": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Whether previous_response_id was undefined in the request", "isMeasurement": true },424"hasCompactionData": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Whether the request input contains compaction data", "isMeasurement": true },425"summarizedAtRoundIdSet": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Whether a summarized round ID was set in the request options", "isMeasurement": true },426"summarizedAtRoundIdMatched": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Whether the summarized round ID matches the one stored on the connection", "isMeasurement": true },427"modeChanged": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Whether the mode instructions changed since the previous request (-1 if unknown, 0 if unchanged, 1 if changed)", "isMeasurement": true },428"compactionThreshold": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Compaction threshold from context_management in the request body", "isMeasurement": true },429"promptTokenCount": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Number of prompt tokens, locally counted", "isMeasurement": true },430"tokenCountMax": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Maximum generated tokens", "isMeasurement": true },431"modelMaxPromptTokens": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Maximum prompt tokens for the model", "isMeasurement": true },432"totalSentMessageCount": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Number of messages sent over this connection", "isMeasurement": true },433"totalReceivedMessageCount": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Number of messages received over this connection", "isMeasurement": true },434"totalSentCharacters": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Total characters sent over this connection", "isMeasurement": true },435"totalReceivedCharacters": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Total characters received over this connection", "isMeasurement": true },436"requestSentMessageCount": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Number of messages sent during this request", "isMeasurement": true },437"requestReceivedMessageCount": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Number of messages received during this request", "isMeasurement": true },438"requestSentCharacters": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Number of characters sent during this request", "isMeasurement": true },439"requestReceivedCharacters": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Number of characters received during this request", "isMeasurement": true },440"connectionDurationMs": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "How long the connection has been open when the request ended in milliseconds", "isMeasurement": true },441"requestDurationMs": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "How long the request took before terminal outcome in milliseconds", "isMeasurement": true },442"closeCode": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "WebSocket close code when outcome is connection_closed", "isMeasurement": true },443"closeReason": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "WebSocket close reason when outcome is connection_closed" },444"serverErrorMessage": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Error message from server error event when outcome is error_response" },445"serverErrorCode": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "comment": "Error code from server error event when outcome is error_response" }446}447*/448telemetryService.sendTelemetryEvent('websocket.requestOutcome', { github: true, microsoft: true }, {449conversationId: properties.conversationId,450initiatingRequestId: properties.initiatingRequestId,451turnId: properties.turnId,452previousTurnId: properties.previousTurnId,453requestId: properties.requestId,454gitHubRequestId: properties.gitHubRequestId,455modelId: properties.modelId,456requestOutcome: properties.requestOutcome,457closeReason: properties.closeReason,458serverErrorMessage: properties.serverErrorMessage,459serverErrorCode: properties.serverErrorCode,460}, {461hadActiveRequest: properties.hadActiveRequest ? 1 : 0,462statefulMarkerMatched: properties.statefulMarkerMatched ? 1 : 0,463previousResponseIdUnset: properties.previousResponseIdUnset ? 1 : 0,464hasCompactionData: properties.hasCompactionData ? 1 : 0,465summarizedAtRoundIdSet: properties.summarizedAtRoundIdSet ? 1 : 0,466summarizedAtRoundIdMatched: properties.summarizedAtRoundIdMatched ? 1 : 0,467modeChanged: properties.modeChanged === undefined ? -1 : properties.modeChanged ? 1 : 0,468compactionThreshold: properties.compactionThreshold,469promptTokenCount: properties.promptTokenCount,470tokenCountMax: properties.tokenCountMax,471modelMaxPromptTokens: properties.modelMaxPromptTokens,472totalSentMessageCount: properties.totalSentMessageCount,473totalReceivedMessageCount: properties.totalReceivedMessageCount,474totalSentCharacters: properties.totalSentCharacters,475totalReceivedCharacters: properties.totalReceivedCharacters,476requestSentMessageCount: properties.requestSentMessageCount,477requestReceivedMessageCount: properties.requestReceivedMessageCount,478requestSentCharacters: properties.requestSentCharacters,479requestReceivedCharacters: properties.requestReceivedCharacters,480connectionDurationMs: properties.connectionDurationMs,481requestDurationMs: properties.requestDurationMs,482closeCode: properties.closeCode,483});484}485}486487488