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