diff --git a/src/vs/workbench/contrib/inlineChat/browser/inlineChatSession.ts b/src/vs/workbench/contrib/inlineChat/browser/inlineChatSession.ts index 94f64a77e18..693fde05bab 100644 --- a/src/vs/workbench/contrib/inlineChat/browser/inlineChatSession.ts +++ b/src/vs/workbench/contrib/inlineChat/browser/inlineChatSession.ts @@ -39,12 +39,15 @@ export type TelemetryData = { extension: string; rounds: string; undos: string; - edits: boolean; unstashed: number; + edits: number; finishedByEdit: boolean; startTime: string; endTime: string; editMode: string; + acceptedHunks: number; + discardedHunks: number; + responseTypes: string; }; export type TelemetryDataClassification = { @@ -59,6 +62,9 @@ export type TelemetryDataClassification = { startTime: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comment: 'When the session started' }; endTime: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comment: 'When the session ended' }; editMode: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comment: 'What edit mode was choosen: live, livePreview, preview' }; + acceptedHunks: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; isMeasurement: true; comment: 'Number of accepted hunks' }; + discardedHunks: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; isMeasurement: true; comment: 'Number of discarded hunks' }; + responseTypes: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comment: 'Comma separated list of response types like edits, message, mixed' }; }; export enum ExpansionState { @@ -140,7 +146,7 @@ export class Session { private _isUnstashed: boolean = false; private readonly _exchange: SessionExchange[] = []; private readonly _startTime = new Date(); - private readonly _teldata: Partial; + private readonly _teldata: TelemetryData; readonly textModelNAltVersion: number; private _textModelNSnapshotAltVersion: number | undefined; @@ -168,12 +174,16 @@ export class Session { this._teldata = { extension: provider.debugName, startTime: this._startTime.toISOString(), - edits: false, + endTime: this._startTime.toISOString(), + edits: 0, finishedByEdit: false, rounds: '', undos: '', editMode, - unstashed: 0 + unstashed: 0, + acceptedHunks: 0, + discardedHunks: 0, + responseTypes: '' }; } @@ -214,6 +224,7 @@ export class Session { this._isUnstashed = false; const newLen = this._exchange.push(exchange); this._teldata.rounds += `${newLen}|`; + this._teldata.responseTypes += `${exchange.response instanceof ReplyResponse ? exchange.response.responseType : InlineChatResponseTypes.Empty}|`; } get exchanges(): Iterable { @@ -244,15 +255,25 @@ export class Session { } recordExternalEditOccurred(didFinish: boolean) { - this._teldata.edits = true; + this._teldata.edits += 1; this._teldata.finishedByEdit = didFinish; } asTelemetryData(): TelemetryData { - return { - ...this._teldata, - endTime: new Date().toISOString(), - }; + + for (const item of this.hunkData.getInfo()) { + switch (item.getState()) { + case HunkState.Accepted: + this._teldata.acceptedHunks += 1; + break; + case HunkState.Rejected: + this._teldata.discardedHunks += 1; + break; + } + } + + this._teldata.endTime = new Date().toISOString(); + return this._teldata; } asRecording(): Recording { diff --git a/src/vs/workbench/contrib/inlineChat/browser/inlineChatSessionServiceImpl.ts b/src/vs/workbench/contrib/inlineChat/browser/inlineChatSessionServiceImpl.ts index e711ffb0fbe..6d696545068 100644 --- a/src/vs/workbench/contrib/inlineChat/browser/inlineChatSessionServiceImpl.ts +++ b/src/vs/workbench/contrib/inlineChat/browser/inlineChatSessionServiceImpl.ts @@ -192,20 +192,18 @@ export class InlineChatSessionServiceImpl implements IInlineChatSessionService { releaseSession(session: Session): void { - let data: SessionData | undefined; + let tuple: [string, SessionData] | undefined; // cleanup - for (const [key, value] of this._sessions) { - if (value.session === session) { - data = value; - value.store.dispose(); - this._sessions.delete(key); - this._logService.trace(`[IE] did RELEASED session for ${value.editor.getId()}, ${session.provider.debugName}`); + for (const candidate of this._sessions) { + if (candidate[1].session === session) { + // if (value.session === session) { + tuple = candidate; break; } } - if (!data) { + if (!tuple) { // double remove return; } @@ -213,7 +211,12 @@ export class InlineChatSessionServiceImpl implements IInlineChatSessionService { this._keepRecording(session); this._telemetryService.publicLog2('interactiveEditor/session', session.asTelemetryData()); - this._onDidEndSession.fire({ editor: data.editor, session }); + const [key, value] = tuple; + value.store.dispose(); + this._sessions.delete(key); + this._logService.trace(`[IE] did RELEASED session for ${value.editor.getId()}, ${session.provider.debugName}`); + + this._onDidEndSession.fire({ editor: value.editor, session }); } stashSession(session: Session, editor: ICodeEditor, undoCancelEdits: IValidEditOperation[]): StashedSession {