Path: blob/main/extensions/copilot/src/extension/prompt/node/chatParticipantTelemetry.ts
13399 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 { PromptReference, Raw } from '@vscode/prompt-tsx';6import type * as vscode from 'vscode';7import { ChatFetchResponseType, ChatLocation } from '../../../platform/chat/common/commonTypes';8import { getTextPart, roleToString } from '../../../platform/chat/common/globalStringUtils';9import { ConfigKey, IConfigurationService } from '../../../platform/configuration/common/configurationService';10import { isAutoModel } from '../../../platform/endpoint/node/autoChatEndpoint';11import { IVSCodeExtensionContext } from '../../../platform/extContext/common/extensionContext';12import { ILanguageDiagnosticsService } from '../../../platform/languages/common/languageDiagnosticsService';13import { IChatEndpoint } from '../../../platform/networking/common/networking';14import { ITelemetryService } from '../../../platform/telemetry/common/telemetry';15import { TelemetryData as PlatformTelemetryData } from '../../../platform/telemetry/common/telemetryData';16import { getCachedSha256Hash } from '../../../util/common/crypto';17import { isNotebookCellOrNotebookChatInput } from '../../../util/common/notebooks';18import { extUriBiasedIgnorePathCase } from '../../../util/vs/base/common/resources';19import { URI } from '../../../util/vs/base/common/uri';20import { IInstantiationService } from '../../../util/vs/platform/instantiation/common/instantiation';21import { isBYOKModel } from '../../byok/node/openAIEndpoint';22import { Intent, agentsToCommands } from '../../common/constants';23import { DiagnosticsTelemetryData, findDiagnosticsTelemetry } from '../../inlineChat/node/diagnosticsTelemetry';24import { InteractionOutcome } from '../../inlineChat/node/promptCraftingTypes';25import { AgentIntent } from '../../intents/node/agentIntent';26import { EditCodeIntent } from '../../intents/node/editCodeIntent';27import { getCustomInstructionTelemetry } from '../../prompts/node/panel/customInstructions';28import { PATCH_PREFIX } from '../../tools/node/applyPatch/parseApplyPatch';29import { ChatVariablesCollection, parseSlashCommand } from '../common/chatVariablesCollection';30import { Conversation } from '../common/conversation';31import { IToolCall, IToolCallRound } from '../common/intents';32import { IDocumentContext } from './documentContext';33import { IIntent, TelemetryData } from './intents';34import { RepoInfoTelemetry } from './repoInfoTelemetry';35import { ConversationalBaseTelemetryData, ConversationalTelemetryData, createTelemetryWithId, extendUserMessageTelemetryData, getCodeBlocks, sendModelMessageTelemetry, sendOffTopicMessageTelemetry, sendUserActionTelemetry, sendUserMessageTelemetry } from './telemetry';3637// #region: internal telemetry for responses3839type ResponseInternalTelemetryProperties = {40chatLocation: 'inline' | 'panel';41intent: string;42request: string;43response: string;44baseModel: string;45apiType: string | undefined;46};4748// EVENT: interactiveSessionResponse49type ResponseInternalPanelTelemetryProperties = ResponseInternalTelemetryProperties & {50chatLocation: 'panel';51requestId: string;5253// shareable but NOT54isParticipantDetected: string;55sessionId: string;56};5758// EVENT: interactiveSessionResponse59type ResponseInternalPanelTelemetryMeasurements = {60turnNumber: number;61};6263// EVENT: interactiveSessionResponse64type ResponseInternalInlineTelemetryProperties = ResponseInternalTelemetryProperties & {65chatLocation: 'inline';6667// shareable but NOT68conversationId: string;69requestId: string;70responseType: ChatFetchResponseType;7172// editor-specific73problems: string;74selectionProblems: string;75diagnosticCodes: string;76selectionDiagnosticCodes: string;77diagnosticsProvider: string;78language: string;79};8081// EVENT: interactiveSessionResponse82type ResponseInternalInlineTelemetryMeasurements = {83isNotebook: number;84turnNumber: number;85};8687// #endregion8889// #region: internal telemetry for requests9091// EVENT: interactiveSessionMessage9293type RequestInternalPanelTelemetryProperties = {94chatLocation: 'panel';95sessionId: string;96requestId: string;97baseModel: string;98apiType: string | undefined;99intent: string;100isParticipantDetected: string;101detectedIntent: string;102contextTypes: string;103query: string;104};105106// EVENT: interactiveSessionRequest107108type RequestInternalInlineTelemetryProperties = {109chatLocation: 'inline';110conversationId: string;111requestId: string;112intent: string;113language: string;114prompt: string;115model: string;116apiType: string | undefined;117};118119type RequestInternalInlineTelemetryMeasurements = {120isNotebook: number;121turnNumber: number;122};123124// #endregion125126127//#region public telemetry for requests128129// EVENT: panel.request130131type RequestTelemetryProperties = {132command: string;133contextTypes: string;134promptTypes: string;135conversationId: string;136requestId: string;137138responseType: string;139languageId: string | undefined;140model: string;141apiType: string | undefined;142toolCounts: string;143};144145type RequestPanelTelemetryProperties = RequestTelemetryProperties & {146responseId: string;147codeBlocks: string;148isParticipantDetected: string;149mode: string;150parentRequestId: string | undefined;151vscodeRequestId: string | undefined;152slashCommand: string;153isSystemInitiated: string;154};155156type RequestTelemetryMeasurements = {157promptTokenCount: number;158timeToRequest: number;159timeToFirstToken: number;160timeToComplete: number;161responseTokenCount: number;162messageTokenCount: number;163numToolCalls: number;164availableToolCount: number;165toolTokenCount: number;166isBYOK: number;167isAuto: number;168};169170type RequestPanelTelemetryMeasurements = RequestTelemetryMeasurements & {171turn: number;172round: number;173textBlocks: number;174links: number;175maybeOffTopic: number;176userPromptCount: number;177summarizationEnabled: number;178};179180// EVENT: inline.request181182type RequestInlineTelemetryProperties = RequestTelemetryProperties & {183languageId: string;184replyType: string;185diagnosticsProvider: string;186diagnosticCodes: string;187selectionDiagnosticCodes: string;188outcomeAnnotations: string;189};190191type RequestInlineTelemetryMeasurements = RequestTelemetryMeasurements & {192firstTurn: number;193isNotebook: number;194withIntentDetection: number;195implicitCommand: number;196attemptCount: number;197selectionLineCount: number;198wholeRangeLineCount: number;199editCount: number;200editLineCount: number;201markdownCharCount: number;202problemsCount: number;203selectionProblemsCount: number;204diagnosticsCount: number;205selectionDiagnosticsCount: number;206};207208//#endregion209210const builtinSlashCommands = new Set(211Object.values(agentsToCommands).flatMap(commands => commands ? Object.keys(commands) : [])212);213214function getSlashCommandForTelemetry(request: vscode.ChatRequest, extensionUri: URI): string {215// Built-in slash commands (explain, fix, tests, etc.) are safe to send as plain text216if (request.command && builtinSlashCommands.has(request.command)) {217return request.command;218}219220// Parse the query for /command and match against prompt file references221const match = parseSlashCommand(request.prompt, new ChatVariablesCollection(request.references));222if (!match) {223return '';224}225226// Extension-provided prompt files are safe to send as plain text227if (URI.isUri(match.variable.value) && extUriBiasedIgnorePathCase.isEqualOrParent(match.variable.value, extensionUri)) {228return match.command;229}230231// User-defined prompt file slash commands may contain PII — hash them232return getCachedSha256Hash(match.command);233}234235export class ChatTelemetryBuilder {236237public readonly baseUserTelemetry: ConversationalBaseTelemetryData;238239private readonly _repoInfoTelemetry: RepoInfoTelemetry;240241public get telemetryMessageId() {242return this.baseUserTelemetry.properties.messageId;243}244245constructor(246private readonly _startTime: number,247private readonly _sessionId: string,248private readonly _documentContext: IDocumentContext | undefined,249private readonly _firstTurn: boolean,250private readonly _request: vscode.ChatRequest,251telemetryMessageId: string | undefined,252@IInstantiationService private readonly instantiationService: IInstantiationService,253) {254this.baseUserTelemetry = telemetryMessageId255? new ConversationalTelemetryData(PlatformTelemetryData.createAndMarkAsIssued({ messageId: telemetryMessageId }))256: createTelemetryWithId();257// Repo info telemetry is held here as the begin event should be sent only by the first PanelChatTelemetry instance created for a user request.258// and a new PanelChatTelemetry instance is created per step in the request.259this._repoInfoTelemetry = this.instantiationService.createInstance(RepoInfoTelemetry, this.baseUserTelemetry.properties.messageId);260}261262public makeRequest(intent: IIntent, location: ChatLocation.Editor, conversation: Conversation, messages: Raw.ChatMessage[], promptTokenLength: number, references: readonly PromptReference[], endpoint: IChatEndpoint, telemetryData: readonly TelemetryData[], availableToolCount: number, toolTokenCount: number): InlineChatTelemetry;263public makeRequest(intent: IIntent, location: ChatLocation, conversation: Conversation, messages: Raw.ChatMessage[], promptTokenLength: number, references: readonly PromptReference[], endpoint: IChatEndpoint, telemetryData: readonly TelemetryData[], availableToolCount: number, toolTokenCount: number): PanelChatTelemetry;264public makeRequest(intent: IIntent, location: ChatLocation, conversation: Conversation, messages: Raw.ChatMessage[], promptTokenLength: number, references: readonly PromptReference[], endpoint: IChatEndpoint, telemetryData: readonly TelemetryData[], availableToolCount: number, toolTokenCount: number): InlineChatTelemetry | PanelChatTelemetry {265266if (location === ChatLocation.Editor) {267return this.instantiationService.createInstance(InlineChatTelemetry,268this._sessionId,269this._documentContext!,270this._firstTurn,271this._request,272this._startTime,273this.baseUserTelemetry,274conversation,275intent,276messages,277references,278endpoint,279promptTokenLength,280telemetryData,281availableToolCount,282toolTokenCount,283this._repoInfoTelemetry284);285} else {286return this.instantiationService.createInstance(PanelChatTelemetry,287this._sessionId,288this._documentContext!,289this._firstTurn,290this._request,291this._startTime,292this.baseUserTelemetry,293conversation,294intent,295messages,296references,297endpoint,298promptTokenLength,299telemetryData,300availableToolCount,301toolTokenCount,302this._repoInfoTelemetry303);304}305}306}307308export abstract class ChatTelemetry<C extends IDocumentContext | undefined = IDocumentContext | undefined> {309310protected readonly _userTelemetry: ConversationalBaseTelemetryData;311312protected readonly _requestStartTime: number = Date.now();313protected _firstTokenTime: number = 0;314315protected _addedLinkCount = 0;316protected _markdownCharCount: number = 0;317protected _editCount: number = 0;318protected _editLineCount: number = 0;319320// todo@connor4312: temporary event to track occurences of patches in response321// text, ref https://github.com/microsoft/vscode-copilot/issues/16608322private _didSeePatchInResponse = false;323private _lastMarkdownLine = '';324325public get telemetryMessageId(): string {326return this._userTelemetry.properties.messageId;327}328329public get editCount(): number {330return this._editCount;331}332333public get editLineCount(): number {334return this._editLineCount;335}336337public get sessionId(): string {338return this._sessionId;339}340341constructor(342protected readonly _location: ChatLocation,343protected readonly _sessionId: string,344protected readonly _documentContext: C,345protected readonly _firstTurn: boolean,346protected readonly _request: vscode.ChatRequest,347protected readonly _startTime: number,348baseUserTelemetry: ConversationalBaseTelemetryData,349protected readonly _conversation: Conversation,350protected readonly _intent: IIntent,351protected readonly _messages: Raw.ChatMessage[],352protected readonly _references: readonly PromptReference[],353protected readonly _endpoint: IChatEndpoint,354promptTokenLength: number,355protected readonly _genericTelemetryData: readonly TelemetryData[],356protected readonly _availableToolCount: number,357protected readonly _toolTokenCount: number,358protected readonly _repoInfoTelemetry: RepoInfoTelemetry,359@ITelemetryService protected readonly _telemetryService: ITelemetryService,360) {361// Extend the base user telemetry with message and prompt information.362// We don't send this telemetry yet, but we will need it later to include the off topic scores.363this._userTelemetry = extendUserMessageTelemetryData(364this._conversation,365this._sessionId,366this._location,367this._request.prompt,368promptTokenLength,369// this._tokenizer.countMessagesTokens(this._messages),370this._intent.id,371baseUserTelemetry372);373374// we are in a super-ctor and use a microtask to give sub-classes a change to initialize properties375// that might be used in their _sendInternalRequestTelemetryEvent-method376queueMicrotask(() => this._sendInternalRequestTelemetryEvent());377}378379public markReceivedToken(): void {380if (this._firstTokenTime === 0) {381this._firstTokenTime = Date.now();382}383}384385public markAddedLinks(n: number): void {386this._addedLinkCount += n;387}388389public markEmittedMarkdown(str: vscode.MarkdownString) {390this._markdownCharCount += str.value.length;391this._lastMarkdownLine += str.value;392if (this._lastMarkdownLine.includes(PATCH_PREFIX.trim())) {393this._didSeePatchInResponse = true;394}395396const i = this._lastMarkdownLine.lastIndexOf('\n');397this._lastMarkdownLine = this._lastMarkdownLine.slice(i + 1);398}399400public markEmittedEdits(uri: vscode.Uri, edits: vscode.TextEdit[]) {401this._editCount += edits.length;402this._editLineCount += edits.reduce((acc, edit) => acc + edit.newText.split('\n').length, 0);403}404405public async sendTelemetry(requestId: string, responseType: ChatFetchResponseType, response: string, interactionOutcome: InteractionOutcome, toolCalls: IToolCall[]): Promise<void> {406// We can send the user message telemetry event now that the response is returned, including off-topic prediction.407sendUserMessageTelemetry(408this._telemetryService,409this._location,410requestId,411this._request.prompt,412responseType === ChatFetchResponseType.OffTopic ? true : false,413this._documentContext?.document,414this._userTelemetry,415this._getModeNameForTelemetry(),416);417418if (responseType === ChatFetchResponseType.OffTopic) {419sendOffTopicMessageTelemetry(420this._telemetryService,421this._conversation,422this._location,423this._request.prompt,424this.telemetryMessageId, // That's the message id of the user message425this._documentContext?.document,426this._userTelemetry427);428}429430if (responseType === ChatFetchResponseType.Success) {431sendModelMessageTelemetry(432this._telemetryService,433this._conversation,434this._location,435response,436this.telemetryMessageId, // That's the message id of the user message437this._documentContext?.document,438this._userTelemetry.extendedBy({ replyType: interactionOutcome.kind }),439this._getModeNameForTelemetry()440);441}442443await this._sendResponseTelemetryEvent(responseType, response, interactionOutcome, toolCalls);444this._sendResponseInternalTelemetryEvent(responseType, response);445446447// todo@connor4312: temporary event to track occurences of patches in response448// text, ref https://github.com/microsoft/vscode-copilot/issues/16608449if (this._didSeePatchInResponse) {450/* __GDPR__451"applyPatch.inResponse" : {452"owner": "digitarald",453"comment": "Metadata about an inline response from the model",454"model": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "comment": "The model that is used in the endpoint." }455}456*/457this._telemetryService.sendMSFTTelemetryEvent('applyPatch.inResponse', {458model: this._endpoint.model459});460}461}462463protected _getModeNameForTelemetry(): string {464return this._request.modeInstructions2 ? (this._request.modeInstructions2.isBuiltin ? this._request.modeInstructions2.name.toLowerCase() : 'custom') :465this._intent.id === AgentIntent.ID ? 'agent' :466(this._intent.id === EditCodeIntent.ID) ? 'edit' :467(this._intent.id === Intent.InlineChat) ? 'inlineChatIntent' :468'ask';469}470471public sendToolCallingTelemetry(toolCallRounds: IToolCallRound[], availableTools: readonly vscode.LanguageModelToolInformation[], responseType: ChatFetchResponseType | 'cancelled' | 'maxToolCalls'): void {472if (availableTools.length === 0) {473return;474}475476const toolCounts = toolCallRounds.reduce((acc, round) => {477round.toolCalls.forEach(call => {478acc[call.name] = (acc[call.name] || 0) + 1;479});480return acc;481}, {} as Record<string, number>);482483const invalidToolCallCount = toolCallRounds.reduce((acc, round) => {484if (round.toolInputRetry > 0) {485acc++;486}487return acc;488}, 0);489490let totalToolCalls = 0;491let parallelToolCallRounds = 0;492let parallelToolCallsTotal = 0;493for (const round of toolCallRounds) {494const count = round.toolCalls.length;495totalToolCalls += count;496if (count > 1) {497parallelToolCallRounds++;498parallelToolCallsTotal += count;499}500}501502const toolCallProperties = {503intentId: this._intent.id,504conversationId: this._conversation.sessionId,505requestId: this.telemetryMessageId,506responseType,507toolCounts: JSON.stringify(toolCounts),508model: this._endpoint.model509};510511const toolCallMeasurements = {512numRequests: toolCallRounds.length, // This doesn't include cancelled requests513turnIndex: this._conversation.turns.length,514sessionDuration: Date.now() - this._conversation.turns[0].startTime,515turnDuration: Date.now() - this._conversation.getLatestTurn().startTime,516promptTokenCount: this._userTelemetry.measurements.promptTokenLen,517messageCharLen: this._userTelemetry.measurements.messageCharLen,518availableToolCount: availableTools.length,519toolTokenCount: this._toolTokenCount,520invalidToolCallCount,521totalToolCalls,522parallelToolCallRounds,523parallelToolCallsTotal524};525526/* __GDPR__527"toolCallDetails" : {528"owner": "roblourens",529"comment": "Records information about tool calls during a request.",530"intentId": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "comment": "Id for the invoked intent." },531"conversationId": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "comment": "Id for the current chat conversation." },532"requestId": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "comment": "Id for the current turn request." },533"numRequests": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "comment": "The total number of requests made" },534"turnIndex": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "comment": "The conversation turn index" },535"toolCounts": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": false, "comment": "The number of times each tool was used" },536"sessionDuration": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "comment": "The time since the session started" },537"turnDuration": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "comment": "The time since the turn started" },538"promptTokenCount": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "comment": "How many tokens were in the last generated prompt." },539"messageCharLen": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "comment": "How many characters were in the user message." },540"availableToolCount": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "comment": "How number of tools that were available." },541"toolTokenCount": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "comment": "How many tokens were used by tool definitions." },542"responseType": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "comment": "If the final response was successful or how it failed." },543"invalidToolCallCount": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "comment": "The number of tool call rounds that had an invalid tool call." },544"model": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "comment": "The model used for the request." },545"totalToolCalls": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "comment": "Total number of tool calls across all rounds." },546"parallelToolCallRounds": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "comment": "Number of rounds where the model called multiple tools in parallel." },547"parallelToolCallsTotal": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "comment": "Total number of tool calls that were part of a parallel round." }548}549*/550this._telemetryService.sendMSFTTelemetryEvent('toolCallDetails', toolCallProperties, toolCallMeasurements);551552this._telemetryService.sendInternalMSFTTelemetryEvent('toolCallDetailsInternal', {553...toolCallProperties,554messageId: this.telemetryMessageId,555availableTools: JSON.stringify(availableTools.map(tool => tool.name))556}, toolCallMeasurements);557558this._telemetryService.sendEnhancedGHTelemetryEvent('toolCallDetailsExternal', {559...toolCallProperties,560messageId: this.telemetryMessageId,561availableTools: JSON.stringify(availableTools.map(tool => tool.name))562}, toolCallMeasurements);563564// Send internal repo info telemetry at the end of the tool loop565this._repoInfoTelemetry.sendEndTelemetry();566}567568protected abstract _sendInternalRequestTelemetryEvent(): void;569570protected abstract _sendResponseTelemetryEvent(responseType: ChatFetchResponseType, response: string, interactionOutcome: InteractionOutcome, toolCalls?: IToolCall[]): Promise<void>;571572protected abstract _sendResponseInternalTelemetryEvent(responseType: ChatFetchResponseType, response: string): void;573574protected _getTelemetryData<T extends TelemetryData>(ctor: new (...args: any[]) => T): T | undefined {575return <T>this._genericTelemetryData.find(d => d instanceof ctor);576}577578}579580export class PanelChatTelemetry extends ChatTelemetry<IDocumentContext | undefined> {581582constructor(583sessionId: string,584documentContext: IDocumentContext | undefined,585firstTurn: boolean,586request: vscode.ChatRequest,587startTime: number,588baseUserTelemetry: ConversationalBaseTelemetryData,589conversation: Conversation,590intent: IIntent,591messages: Raw.ChatMessage[],592references: readonly PromptReference[],593endpoint: IChatEndpoint,594promptTokenLength: number,595genericTelemetryData: readonly TelemetryData[],596availableToolCount: number,597toolTokenCount: number,598repoInfoTelemetry: RepoInfoTelemetry,599@ITelemetryService telemetryService: ITelemetryService,600@IConfigurationService private readonly _configurationService: IConfigurationService,601@IVSCodeExtensionContext private readonly _extensionContext: IVSCodeExtensionContext,602) {603super(ChatLocation.Panel,604sessionId,605documentContext,606firstTurn,607request,608startTime,609baseUserTelemetry,610conversation,611intent,612messages,613references,614endpoint,615promptTokenLength,616genericTelemetryData,617availableToolCount,618toolTokenCount,619repoInfoTelemetry,620telemetryService621);622}623624protected override _sendInternalRequestTelemetryEvent(): void {625626627// Capture the created prompt in internal telemetry628this._telemetryService.sendInternalMSFTTelemetryEvent('interactiveSessionMessage', {629chatLocation: 'panel',630sessionId: this._sessionId,631requestId: this.telemetryMessageId,632baseModel: this._endpoint.model,633apiType: this._endpoint.apiType,634intent: this._intent.id,635isParticipantDetected: String(this._request.isParticipantDetected),636detectedIntent: this._request.enableCommandDetection ? this._intent?.id : 'none',637contextTypes: 'none', // TODO this is defunct638query: this._request.prompt639} satisfies RequestInternalPanelTelemetryProperties, {640turnNumber: this._conversation.turns.length,641} satisfies ResponseInternalPanelTelemetryMeasurements);642643// Send the begin telemetry for repo info, this uses the same repo info telemetry instance held by the builder class644// as the begin event need to be sent only once per user request and PanelChatTelemetry is recreated per step. The class is645// guarded to only send one time.646this._repoInfoTelemetry.sendBeginTelemetryIfNeeded();647}648649protected override async _sendResponseTelemetryEvent(responseType: ChatFetchResponseType, response: string, interactionOutcome: InteractionOutcome, toolCalls: IToolCall[] = []): Promise<void> {650651652const turn = this._conversation.getLatestTurn();653const roundIndex = turn.rounds.length - 1;654655const codeBlocks = response ? getCodeBlocks(response) : [];656const codeBlockLanguages = codeBlocks.map(block => block.languageId);657658// TBD@digitarald: This is a first cheap way to detect off-topic LLM responses.659const offTopicHints = ['programming-related tasks', 'programming related questions', 'software development topics', 'related to programming', 'expertise is limited', 'sorry, i can\'t assist with that'];660let maybeOffTopic = 0;661if (responseType === ChatFetchResponseType.Success && !response.trim().includes('\n')) {662// Check responseMessage663if (offTopicHints.some(flag => response.toLowerCase().includes(flag))) {664maybeOffTopic = 1;665}666}667668const toolCounts = toolCalls.reduce((acc, call) => {669acc[call.name] = (acc[call.name] || 0) + 1;670return acc;671}, {} as Record<string, number>);672673const messageTokenCount = await this._endpoint.acquireTokenizer().tokenLength(turn.request.message);674const promptTokenCount = await this._endpoint.acquireTokenizer().countMessagesTokens(this._messages);675const responseTokenCount = await this._endpoint.acquireTokenizer().tokenLength(response) ?? 0;676677/* __GDPR__678"panel.request" : {679"owner": "digitarald",680"comment": "Metadata about one message turn in a chat conversation.",681"command": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "comment": "The command which was used in providing the response." },682"contextTypes": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "comment": "The context parts which were used in providing the response." },683"promptTypes": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "comment": "The prompt types and their length which were used in providing the response." },684"conversationId": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "comment": "Id for the current chat conversation." },685"requestId": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "comment": "Id for this message request." },686"responseId": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "comment": "Id for this message response." },687"responseType": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "comment": "If the response was successful or how it failed." },688"languageId": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "comment": "The language of the active editor." },689"codeBlocks": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "comment": "Code block languages in the response." },690"model": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "comment": "The model that is used in the endpoint." },691"apiType": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "comment": "The API type used in the endpoint- responses or chatCompletions" },692"turn": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "comment": "How many turns have been made in the conversation." },693"round": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "comment": "The current round index of the turn." },694"textBlocks": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "comment": "For text-only responses (no code), how many paragraphs were in the response." },695"links": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "comment": "Symbol and file links in the response.", "isMeasurement": true },696"maybeOffTopic": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "comment": "If the response sounds like it got rejected due to the request being off-topic." },697"messageTokenCount": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "comment": "How many characters were in the user message." },698"promptTokenCount": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "comment": "How many characters were in the generated prompt." },699"userPromptCount": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "comment": "How many user messages were in the generated prompt." },700"responseTokenCount": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "comment": "How many characters were in the response." },701"timeToRequest": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true, "comment": "How long it took to start the final request." },702"timeToFirstToken": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true, "comment": "How long it took to get the first token." },703"timeToComplete": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true, "comment": "How long it took to complete the request." },704"codeGenInstructionsCount": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "comment": "How many code generation instructions are in the request." },705"codeGenInstructionsLength": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "comment": "Whats the length of the code generation instructions that were added to request." },706"codeGenInstructionsFilteredCount": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "comment": "How many code generation instructions were filtered." },707"codeGenInstructionFileCount": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "comment": "How many code generation instruction files were read." },708"codeGenInstructionSettingsCount": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "comment": "How many code generation instructions originated from settings." },709"toolCounts": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": false, "comment": "The number of times each tool was used" },710"numToolCalls": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "comment": "The total number of tool calls" },711"availableToolCount": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "comment": "How number of tools that were available." },712"toolTokenCount": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "comment": "How many tokens were used by tool definitions." },713"summarizationEnabled" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true, "comment": "Whether summarization is enabled (the default) or disabled (via user setting)" },714"isBYOK": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "comment": "Whether the request was for a BYOK model" },715"isAuto": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "comment": "Whether the request was for an Auto model" },716"mode": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "comment": "The chat mode used for this request (e.g., ask, edit, agent, custom)." },717"parentRequestId": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "comment": "The parent request id if this request is from a subagent." },718"vscodeRequestId": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "comment": "The VS Code chat request id, for joining with VS Code telemetry events." },719"slashCommand": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "comment": "The slash command used by the user, if any (e.g. troubleshoot, explain). Empty if no slash command was used." },720"isSystemInitiated": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "comment": "Whether the request was system-initiated (e.g. terminal completion notification) rather than user-typed." }721}722*/723this._telemetryService.sendMSFTTelemetryEvent('panel.request', {724command: this._intent.id,725contextTypes: 'none', // TODO this is defunct726promptTypes: this._messages.map(msg => `${msg.role}${'name' in msg && msg.name ? `-${msg.name}` : ''}:${getTextPart(msg.content).length}`).join(','),727conversationId: this._sessionId,728requestId: turn.id,729responseId: turn.id, // SAME as fetchResult.requestId ,730responseType,731languageId: this._documentContext?.document.languageId,732codeBlocks: codeBlockLanguages.join(','),733model: this._endpoint.model,734apiType: this._endpoint.apiType,735isParticipantDetected: String(this._request.isParticipantDetected),736toolCounts: JSON.stringify(toolCounts),737mode: this._getModeNameForTelemetry(),738parentRequestId: this._request.parentRequestId,739vscodeRequestId: this._request.id,740slashCommand: getSlashCommandForTelemetry(this._request, URI.from(this._extensionContext.extensionUri)),741isSystemInitiated: String(!!this._request.isSystemInitiated)742} satisfies RequestPanelTelemetryProperties, {743turn: this._conversation.turns.length,744round: roundIndex,745textBlocks: codeBlocks.length ? -1 : response.split(/\n{2,}/).length ?? 0,746links: this._addedLinkCount,747maybeOffTopic: maybeOffTopic,748messageTokenCount,749promptTokenCount,750userPromptCount: this._messages.filter(msg => msg.role === Raw.ChatRole.User).length,751responseTokenCount,752timeToRequest: this._requestStartTime - this._startTime,753timeToFirstToken: this._firstTokenTime ? this._firstTokenTime - this._startTime : -1,754timeToComplete: Date.now() - this._startTime,755...getCustomInstructionTelemetry(turn.references),756numToolCalls: toolCalls.length,757availableToolCount: this._availableToolCount,758toolTokenCount: this._toolTokenCount,759summarizationEnabled: this._configurationService.getConfig(ConfigKey.SummarizeAgentConversationHistory) ? 1 : 0,760isBYOK: isBYOKModel(this._endpoint),761isAuto: isAutoModel(this._endpoint)762} satisfies RequestPanelTelemetryMeasurements);763764const modeName = this._getModeNameForTelemetry();765sendUserActionTelemetry(766this._telemetryService,767undefined,768{769command: this._intent.id,770conversationId: this._sessionId,771requestId: turn.id,772responseType,773languageId: this._documentContext?.document.languageId ?? '',774model: this._endpoint.model,775isParticipantDetected: String(this._request.isParticipantDetected),776toolCounts: JSON.stringify(toolCounts),777mode: modeName,778codeBlocks: JSON.stringify(codeBlocks),779vscodeRequestId: this._request.id,780},781{782isAgent: this._intent.id === AgentIntent.ID ? 1 : 0,783turn: this._conversation.turns.length,784round: roundIndex,785textBlocks: codeBlocks.length ? -1 : response.split(/\n{2,}/).length ?? 0,786links: this._addedLinkCount,787maybeOffTopic,788messageTokenCount,789promptTokenCount,790userPromptCount: this._messages.filter(msg => msg.role === Raw.ChatRole.User).length,791responseTokenCount,792timeToRequest: this._requestStartTime - this._startTime,793timeToFirstToken: this._firstTokenTime ? this._firstTokenTime - this._startTime : -1,794timeToComplete: Date.now() - this._startTime,795numToolCalls: toolCalls.length,796availableToolCount: this._availableToolCount,797},798'panel_request'799);800}801802protected override _sendResponseInternalTelemetryEvent(_responseType: ChatFetchResponseType, response: string): void {803804this._telemetryService.sendInternalMSFTTelemetryEvent('interactiveSessionResponse', {805// shared806chatLocation: 'panel',807requestId: this.telemetryMessageId,808intent: this._intent.id,809request: this._request.prompt,810response: response ?? '',811baseModel: this._endpoint.model,812apiType: this._endpoint.apiType,813814// shareable but NOT815isParticipantDetected: String(this._request.isParticipantDetected),816sessionId: this._sessionId,817} satisfies ResponseInternalPanelTelemetryProperties, {818turnNumber: this._conversation.turns.length,819} satisfies ResponseInternalPanelTelemetryMeasurements);820}821}822823export class InlineChatTelemetry extends ChatTelemetry<IDocumentContext> {824825private readonly _diagnosticsTelemetryData: {826fileDiagnosticsTelemetry: DiagnosticsTelemetryData;827selectionDiagnosticsTelemetry: DiagnosticsTelemetryData;828diagnosticsProvider: string;829};830831private get _isNotebookDocument(): number {832return isNotebookCellOrNotebookChatInput(this._documentContext.document.uri) ? 1 : 0;833}834835constructor(836sessionId: string,837documentContext: IDocumentContext,838firstTurn: boolean,839request: vscode.ChatRequest,840startTime: number,841baseUserTelemetry: ConversationalBaseTelemetryData,842conversation: Conversation,843intent: IIntent,844messages: Raw.ChatMessage[],845references: readonly PromptReference[],846endpoint: IChatEndpoint,847promptTokenLength: number,848genericTelemetryData: readonly TelemetryData[],849availableToolCount: number,850toolTokenCount: number,851repoInfoTelemetry: RepoInfoTelemetry,852@ITelemetryService telemetryService: ITelemetryService,853@ILanguageDiagnosticsService private readonly _languageDiagnosticsService: ILanguageDiagnosticsService,854) {855super(ChatLocation.Editor,856sessionId,857documentContext,858firstTurn,859request,860startTime,861baseUserTelemetry,862conversation,863intent,864messages,865references,866endpoint,867promptTokenLength,868genericTelemetryData,869availableToolCount,870toolTokenCount,871repoInfoTelemetry,872telemetryService873);874875this._diagnosticsTelemetryData = findDiagnosticsTelemetry(this._documentContext.selection, this._languageDiagnosticsService.getDiagnostics(this._documentContext.document.uri));876}877878protected override _sendInternalRequestTelemetryEvent(): void {879// Capture the created prompt in internal telemetry880this._telemetryService.sendInternalMSFTTelemetryEvent('interactiveSessionRequest', {881conversationId: this._sessionId,882requestId: this.telemetryMessageId,883chatLocation: 'inline',884intent: this._intent.id,885language: this._documentContext.document.languageId,886prompt: this._messages.map(m => `${roleToString(m.role).toUpperCase()}:\n${m.content}`).join('\n---\n'),887model: this._endpoint.model,888apiType: this._endpoint.apiType889} satisfies RequestInternalInlineTelemetryProperties, {890isNotebook: this._isNotebookDocument,891turnNumber: this._conversation.turns.length,892} satisfies RequestInternalInlineTelemetryMeasurements);893}894895protected override async _sendResponseTelemetryEvent(responseType: ChatFetchResponseType, response: string, interactionOutcome: InteractionOutcome, toolCalls: IToolCall[] = []): Promise<void> {896897const toolCounts = toolCalls.reduce((acc, call) => {898acc[call.name] = (acc[call.name] || 0) + 1;899return acc;900}, {} as Record<string, number>);901902/* __GDPR__903"inline.request" : {904"owner": "digitarald",905"comment": "Metadata about an inline response from the model",906"command": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "comment": "The command which was used in providing the response." },907"contextTypes": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "comment": "The context parts which were used in providing the response." },908"promptTypes": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "comment": "The prompt types and their length which were used in providing the response." },909"conversationId": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "comment": "The id of the conversation." },910"requestId": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "comment": "Id for this message request." },911"languageId": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "comment": "The language of the current document." },912"responseType": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "comment": "The result type of the response." },913"replyType": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "comment": "How response is shown in the interface." },914"model": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "comment": "The model that is used in the endpoint." },915"apiType": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "comment": "The API type used in the endpoint- responses or chatCompletions" },916"diagnosticsProvider": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "comment": "The diagnostics provider." },917"diagnosticCodes": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "comment": "The diagnostics codes in the file." },918"selectionDiagnosticCodes": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "comment": "The selected diagnostics codes." },919"firstTurn": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "comment": "Whether this is the first turn in the conversation." },920"isNotebook": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "comment": "Whether this is a notebook document." },921"messageTokenCount": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "comment": "How many tokens are in the rest of the query, without the command." },922"promptTokenCount": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "comment": "How many tokens are in the overall prompt." },923"responseTokenCount": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "comment": "How many tokens were in the response." },924"implicitCommand": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "comment": "Whether the command was implictly detected or provided by the user." },925"attemptCount": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "comment": "How many times the user has retried." },926"selectionLineCount": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "comment": "How many lines are in the current selection." },927"wholeRangeLineCount": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "comment": "How many lines are in the expanded whole range." },928"editCount": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "comment": "How many edits are suggested." },929"editLineCount": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "comment": "How many lines are in all suggested edits." },930"markdownCharCount": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "comment": "How many characters were emitted as markdown to vscode in the response stream." },931"problemsCount": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "comment": "How many problems are in the current document." },932"selectionProblemsCount": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "comment": "How many problems are in the current selected code." },933"diagnosticsCount": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "comment": "How many diagnostic codes are in the current ." },934"selectionDiagnosticsCount": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "comment": "How many diagnostic codes are in the code at the selection." },935"outcomeAnnotations": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "comment": "Annotations about the outcome of the request." },936"timeToRequest": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true, "comment": "How long it took to start the final request." },937"timeToFirstToken": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true, "comment": "How long it took to get the first token." },938"timeToComplete": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true, "comment": "How long it took to complete the request." },939"codeGenInstructionsCount": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "comment": "How many code generation instructions are in the request." },940"codeGenInstructionsLength": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "comment": "The length of the code generation instructions that were added to request." },941"codeGenInstructionsFilteredCount": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "comment": "How many code generation instructions were filtered." },942"codeGenInstructionFileCount": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "comment": "How many code generation instruction files were read." },943"codeGenInstructionSettingsCount": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "comment": "How many code generation instructions originated from settings." },944"toolCounts": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": false, "comment": "The number of times each tool was used" },945"numToolCalls": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "comment": "The total number of tool calls" },946"availableToolCount": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "comment": "How number of tools that were available." },947"toolTokenCount": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "comment": "How many tokens were used by tool definitions." },948"isBYOK": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "comment": "Whether the request was for a BYOK model" },949"isAuto": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "comment": "Whether the request was for an Auto model" }950}951*/952this._telemetryService.sendMSFTTelemetryEvent('inline.request', {953command: this._intent.id,954contextTypes: 'none',// TODO@jrieken intentResult.contexts.map(part => part.kind).join(',') ?? 'none',955promptTypes: this._messages.map(msg => `${msg.role}${'name' in msg && msg.name ? `-${msg.name}` : ''}:${getTextPart(msg.content).length}`).join(','),956conversationId: this._sessionId,957requestId: this.telemetryMessageId,958languageId: this._documentContext.document.languageId,959responseType: responseType,960replyType: interactionOutcome.kind,961model: this._endpoint.model,962apiType: this._endpoint.apiType,963diagnosticsProvider: this._diagnosticsTelemetryData.diagnosticsProvider,964diagnosticCodes: this._diagnosticsTelemetryData.fileDiagnosticsTelemetry.diagnosticCodes,965selectionDiagnosticCodes: this._diagnosticsTelemetryData.selectionDiagnosticsTelemetry.diagnosticCodes,966outcomeAnnotations: interactionOutcome.annotations?.map(a => a.label).join(','),967toolCounts: JSON.stringify(toolCounts),968} satisfies RequestInlineTelemetryProperties, {969firstTurn: this._firstTurn ? 1 : 0,970isNotebook: this._isNotebookDocument,971withIntentDetection: this._request.enableCommandDetection ? 1 : 0,972messageTokenCount: await this._endpoint.acquireTokenizer().tokenLength(this._request.prompt),973promptTokenCount: await this._endpoint.acquireTokenizer().countMessagesTokens(this._messages),974responseTokenCount: responseType === ChatFetchResponseType.Success ? await this._endpoint.acquireTokenizer().tokenLength(response) : -1,975implicitCommand: (!this._request.prompt.trim().startsWith(`/${this._intent.id}`) ? 1 : 0),976attemptCount: this._request.attempt || 0,977selectionLineCount: Math.abs(this._documentContext.selection.end.line - this._documentContext.selection.start.line) + 1,978wholeRangeLineCount: Math.abs(this._documentContext.wholeRange.end.line - this._documentContext.wholeRange.start.line) + 1,979editCount: this._editCount > 0 ? this._editCount : -1,980editLineCount: this._editLineCount > 0 ? this._editLineCount : -1,981markdownCharCount: this._markdownCharCount,982problemsCount: this._diagnosticsTelemetryData.fileDiagnosticsTelemetry.problemsCount,983selectionProblemsCount: this._diagnosticsTelemetryData.selectionDiagnosticsTelemetry.problemsCount,984diagnosticsCount: this._diagnosticsTelemetryData.fileDiagnosticsTelemetry.diagnosticsCount,985selectionDiagnosticsCount: this._diagnosticsTelemetryData.selectionDiagnosticsTelemetry.diagnosticsCount,986timeToRequest: this._requestStartTime - this._startTime,987timeToFirstToken: this._firstTokenTime ? this._firstTokenTime - this._startTime : -1,988timeToComplete: Date.now() - this._startTime,989...getCustomInstructionTelemetry(this._references),990numToolCalls: toolCalls.length,991availableToolCount: this._availableToolCount,992toolTokenCount: this._toolTokenCount,993isBYOK: isBYOKModel(this._endpoint),994isAuto: isAutoModel(this._endpoint)995} satisfies RequestInlineTelemetryMeasurements);996}997998protected override _sendResponseInternalTelemetryEvent(responseType: ChatFetchResponseType, response: string): void {999this._telemetryService.sendInternalMSFTTelemetryEvent('interactiveSessionResponse', {1000chatLocation: 'inline',1001intent: this._intent.id,1002request: this._request.prompt,1003response,1004conversationId: this._sessionId,1005requestId: this.telemetryMessageId,1006baseModel: this._endpoint.model,1007apiType: this._endpoint.apiType,1008responseType,1009problems: this._diagnosticsTelemetryData.fileDiagnosticsTelemetry.problems,1010selectionProblems: this._diagnosticsTelemetryData.selectionDiagnosticsTelemetry.problems,1011diagnosticCodes: this._diagnosticsTelemetryData.fileDiagnosticsTelemetry.diagnosticCodes,1012selectionDiagnosticCodes: this._diagnosticsTelemetryData.selectionDiagnosticsTelemetry.diagnosticCodes,1013diagnosticsProvider: this._diagnosticsTelemetryData.diagnosticsProvider,1014language: this._documentContext.document.languageId,1015} satisfies ResponseInternalInlineTelemetryProperties, {1016isNotebook: this._isNotebookDocument,1017turnNumber: this._conversation.turns.length,1018} satisfies ResponseInternalInlineTelemetryMeasurements);1019}1020}102110221023