@codingame/monaco-vscode-telemetry-service-override 36.2.7 → 37.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/index.js +1 -1
  2. package/package.json +2 -2
  3. package/vscode/src/vs/base/common/editArcTracker.d.ts +29 -0
  4. package/vscode/src/vs/base/common/editArcTracker.js +291 -0
  5. package/vscode/src/vs/platform/agentHost/common/diffComputeService.d.ts +19 -0
  6. package/vscode/src/vs/platform/agentHost/common/fileEditAttribution.d.ts +107 -0
  7. package/vscode/src/vs/platform/agentHost/common/fileEditAttribution.js +59 -0
  8. package/vscode/src/vs/platform/agentHost/common/fileEditAttribution.service.d.ts +12 -0
  9. package/vscode/src/vs/platform/telemetry/browser/errorTelemetry.js +5 -5
  10. package/vscode/src/vs/platform/telemetry/common/1dsAppender.d.ts +2 -0
  11. package/vscode/src/vs/platform/telemetry/common/1dsAppender.js +12 -10
  12. package/vscode/src/vs/platform/telemetry/common/editArcTelemetry.d.ts +141 -0
  13. package/vscode/src/vs/platform/telemetry/common/editArcTelemetry.js +5 -0
  14. package/vscode/src/vs/platform/telemetry/common/editTelemetry.d.ts +49 -0
  15. package/vscode/src/vs/platform/telemetry/common/editTelemetry.js +10 -0
  16. package/vscode/src/vs/platform/telemetry/common/telemetryLogAppender.d.ts +5 -2
  17. package/vscode/src/vs/platform/telemetry/common/telemetryLogAppender.js +4 -3
  18. package/vscode/src/vs/platform/telemetry/common/telemetryService.d.ts +14 -4
  19. package/vscode/src/vs/platform/telemetry/common/telemetryService.js +50 -34
  20. package/vscode/src/vs/workbench/contrib/editTelemetry/browser/editStats/aiStatsChart.js +1 -1
  21. package/vscode/src/vs/workbench/contrib/editTelemetry/browser/editStats/aiStatsStatusBar.js +8 -8
  22. package/vscode/src/vs/workbench/contrib/editTelemetry/browser/editTelemetry.contribution.js +12 -7
  23. package/vscode/src/vs/workbench/contrib/editTelemetry/browser/editTelemetryContribution.js +2 -1
  24. package/vscode/src/vs/workbench/contrib/editTelemetry/browser/helpers/documentWithAnnotatedEdits.d.ts +7 -1
  25. package/vscode/src/vs/workbench/contrib/editTelemetry/browser/helpers/documentWithAnnotatedEdits.js +15 -2
  26. package/vscode/src/vs/workbench/contrib/editTelemetry/browser/settingIds.d.ts +1 -1
  27. package/vscode/src/vs/workbench/contrib/editTelemetry/browser/settingIds.js +1 -2
  28. package/vscode/src/vs/workbench/contrib/editTelemetry/browser/telemetry/agentHostEditMarkerService.d.ts +83 -0
  29. package/vscode/src/vs/workbench/contrib/editTelemetry/browser/telemetry/agentHostEditMarkerService.js +690 -0
  30. package/vscode/src/vs/workbench/contrib/editTelemetry/browser/telemetry/arcTelemetryReporter.d.ts +2 -2
  31. package/vscode/src/vs/workbench/contrib/editTelemetry/browser/telemetry/arcTelemetrySender.d.ts +3 -3
  32. package/vscode/src/vs/workbench/contrib/editTelemetry/browser/telemetry/arcTelemetrySender.js +3 -0
  33. package/vscode/src/vs/workbench/contrib/editTelemetry/browser/telemetry/editSourceTrackingFeature.js +11 -4
  34. package/vscode/src/vs/workbench/contrib/editTelemetry/browser/telemetry/editSourceTrackingImpl.d.ts +15 -4
  35. package/vscode/src/vs/workbench/contrib/editTelemetry/browser/telemetry/editSourceTrackingImpl.js +185 -83
  36. package/vscode/src/vs/workbench/contrib/editTelemetry/browser/telemetry/editTracker.d.ts +21 -5
  37. package/vscode/src/vs/workbench/contrib/editTelemetry/browser/telemetry/editTracker.js +128 -12
  38. package/vscode/src/vs/workbench/contrib/editTelemetry/browser/telemetry/scmAdapter.d.ts +7 -2
  39. package/vscode/src/vs/workbench/contrib/editTelemetry/common/arcTracker.d.ts +3 -11
  40. package/vscode/src/vs/workbench/contrib/editTelemetry/common/arcTracker.js +17 -47
  41. package/vscode/src/vs/workbench/contrib/telemetry/browser/telemetry.contribution.js +13 -2
  42. package/vscode/src/vs/workbench/services/telemetry/browser/telemetryService.d.ts +1 -1
  43. package/vscode/src/vs/workbench/services/dataChannel/browser/dataChannelService.d.ts +0 -10
  44. package/vscode/src/vs/workbench/services/dataChannel/browser/dataChannelService.js +0 -30
@@ -3,7 +3,7 @@ import { IObservableWithChange, IObservable } from "@codingame/monaco-vscode-api
3
3
  import { BaseStringEdit } from "@codingame/monaco-vscode-api/vscode/vs/editor/common/core/edits/stringEdit";
4
4
  import { StringText } from "@codingame/monaco-vscode-api/vscode/vs/editor/common/core/text/abstractText";
5
5
  import { ITelemetryService } from "@codingame/monaco-vscode-api/vscode/vs/platform/telemetry/common/telemetry.service";
6
- import type { ScmRepoAdapter } from "./scmAdapter.js";
6
+ import type { IScmRepoAdapter } from "./scmAdapter.js";
7
7
  export declare class ArcTelemetryReporter extends Disposable {
8
8
  private readonly _timesMs;
9
9
  private readonly _documentValueBeforeTrackedEdit;
@@ -20,7 +20,7 @@ export declare class ArcTelemetryReporter extends Disposable {
20
20
  value: IObservableWithChange<StringText, {
21
21
  edit: BaseStringEdit;
22
22
  }>;
23
- }, _gitRepo: IObservable<ScmRepoAdapter | undefined>, _trackedEdit: BaseStringEdit, _sendTelemetryEvent: (res: ArcTelemetryReporterData) => void, _dispose: () => void, _telemetryService: ITelemetryService);
23
+ }, _gitRepo: IObservable<IScmRepoAdapter | undefined>, _trackedEdit: BaseStringEdit, _sendTelemetryEvent: (res: ArcTelemetryReporterData) => void, _dispose: () => void, _telemetryService: ITelemetryService);
24
24
  private _reportAfter;
25
25
  private _report;
26
26
  }
@@ -3,11 +3,11 @@ import { IObservable } from "@codingame/monaco-vscode-api/vscode/vs/base/common/
3
3
  import { IInstantiationService } from "@codingame/monaco-vscode-api/vscode/vs/platform/instantiation/common/instantiation";
4
4
  import { EditSourceData, IDocumentWithAnnotatedEdits } from "../helpers/documentWithAnnotatedEdits.js";
5
5
  import { IAiEditTelemetryService } from "@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/editTelemetry/browser/telemetry/aiEditTelemetry/aiEditTelemetryService.service";
6
- import type { ScmRepoAdapter } from "./scmAdapter.js";
6
+ import type { IScmRepoAdapter } from "./scmAdapter.js";
7
7
  import { IRandomService } from "@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/editTelemetry/browser/randomService.service";
8
8
  export declare class EditTelemetryReportInlineEditArcSender extends Disposable {
9
9
  private readonly _instantiationService;
10
- constructor(docWithAnnotatedEdits: IDocumentWithAnnotatedEdits<EditSourceData>, scmRepoBridge: IObservable<ScmRepoAdapter | undefined>, _instantiationService: IInstantiationService);
10
+ constructor(docWithAnnotatedEdits: IDocumentWithAnnotatedEdits<EditSourceData>, scmRepoBridge: IObservable<IScmRepoAdapter | undefined>, _instantiationService: IInstantiationService);
11
11
  }
12
12
  export declare class CreateSuggestionIdForChatOrInlineChatCaller extends Disposable {
13
13
  private readonly _aiEditTelemetryService;
@@ -16,5 +16,5 @@ export declare class CreateSuggestionIdForChatOrInlineChatCaller extends Disposa
16
16
  export declare class EditTelemetryReportEditArcForChatOrInlineChatSender extends Disposable {
17
17
  private readonly _instantiationService;
18
18
  private readonly _randomService;
19
- constructor(docWithAnnotatedEdits: IDocumentWithAnnotatedEdits<EditSourceData>, scmRepoBridge: IObservable<ScmRepoAdapter | undefined>, _instantiationService: IInstantiationService, _randomService: IRandomService);
19
+ constructor(docWithAnnotatedEdits: IDocumentWithAnnotatedEdits<EditSourceData>, scmRepoBridge: IObservable<IScmRepoAdapter | undefined>, _instantiationService: IInstantiationService, _randomService: IRandomService);
20
20
  }
@@ -151,6 +151,9 @@ let EditTelemetryReportEditArcForChatOrInlineChatSender = class EditTelemetryRep
151
151
  languageId: data.props.$$languageId,
152
152
  mode: data.props.$$mode,
153
153
  uniqueEditId,
154
+ provider: undefined,
155
+ agentSessionId: undefined,
156
+ isSubagentSession: undefined,
154
157
  didBranchChange: res.didBranchChange ? 1 : 0,
155
158
  timeDelayMs: res.timeDelayMs,
156
159
  originalCharCount: res.originalCharCount,
@@ -20,6 +20,7 @@ import { EditSourceTrackingImpl } from './editSourceTrackingImpl.js';
20
20
  import { DataChannelForwardingTelemetryService } from '@codingame/monaco-vscode-api/vscode/vs/platform/dataChannel/browser/forwardingTelemetryService';
21
21
  import { EDIT_TELEMETRY_SHOW_DECORATIONS, EDIT_TELEMETRY_SHOW_STATUS_BAR, EDIT_TELEMETRY_DETAILS_SETTING_ID } from '../settings.js';
22
22
  import { IExtensionService } from '@codingame/monaco-vscode-api/vscode/vs/workbench/services/extensions/common/extensions.service';
23
+ import { AgentHostEditMarkerService } from './agentHostEditMarkerService.js';
23
24
  import { observableFromEvent } from '@codingame/monaco-vscode-api/vscode/vs/base/common/observableInternal/observables/observableFromEvent';
24
25
  import { derived, derivedWithSetter } from '@codingame/monaco-vscode-api/vscode/vs/base/common/observableInternal/observables/derived';
25
26
  import { autorun } from '@codingame/monaco-vscode-api/vscode/vs/base/common/observableInternal/reactions/autorun';
@@ -54,8 +55,8 @@ let EditTrackingFeature = class EditTrackingFeature extends Disposable {
54
55
  const extensions = observableFromEvent(this._extensionService.onDidChangeExtensions, () => {
55
56
  return this._extensionService.extensions;
56
57
  });
57
- const extensionIds = derived(reader => ( new Set(( extensions.read(reader).map(e => e.id?.toLowerCase())))));
58
- function getExtensionInfoObs(extensionId, extensionService) {
58
+ const extensionIds = derived(reader => ( new Set(( extensions.read(reader).map(e => e.identifier.value.toLowerCase())))));
59
+ function getExtensionInfoObs(extensionId) {
59
60
  const extIdLowerCase = extensionId.toLowerCase();
60
61
  return derived(reader => ( extensionIds.read(reader).has(extIdLowerCase)));
61
62
  }
@@ -68,9 +69,15 @@ let EditTrackingFeature = class EditTrackingFeature extends Disposable {
68
69
  ITelemetryService,
69
70
  this._instantiationService.createInstance(DataChannelForwardingTelemetryService)
70
71
  ])));
71
- const impl = this._register(
72
- instantiationServiceWithInterceptedTelemetry.createInstance(EditSourceTrackingImpl, shouldSendDetails, this._annotatedDocuments)
72
+ const markerService = this._register(
73
+ instantiationServiceWithInterceptedTelemetry.createInstance(AgentHostEditMarkerService)
73
74
  );
75
+ const impl = this._register(instantiationServiceWithInterceptedTelemetry.createInstance(
76
+ EditSourceTrackingImpl,
77
+ shouldSendDetails,
78
+ this._annotatedDocuments,
79
+ markerService
80
+ ));
74
81
  this._register(autorun(reader => {
75
82
  if (!this._editSourceTrackingShowDecorations.read(reader)) {
76
83
  return;
@@ -1,41 +1,52 @@
1
1
  import { Disposable } from "@codingame/monaco-vscode-api/vscode/vs/base/common/lifecycle";
2
2
  import { IObservable } from "@codingame/monaco-vscode-api/vscode/vs/base/common/observable";
3
3
  import { IInstantiationService } from "@codingame/monaco-vscode-api/vscode/vs/platform/instantiation/common/instantiation";
4
+ import { EditTelemetryMode, EditTelemetryTrigger } from "../../../../../platform/telemetry/common/editTelemetry.js";
4
5
  import { ITelemetryService } from "@codingame/monaco-vscode-api/vscode/vs/platform/telemetry/common/telemetry.service";
5
6
  import { IUserAttentionService } from "@codingame/monaco-vscode-api/vscode/vs/workbench/services/userAttention/common/userAttentionService.service";
7
+ import { ITextFileService } from "@codingame/monaco-vscode-api/vscode/vs/workbench/services/textfile/common/textfiles.service";
8
+ import { ILogService } from "@codingame/monaco-vscode-api/vscode/vs/platform/log/common/log.service";
6
9
  import { AnnotatedDocument, IAnnotatedDocuments } from "../helpers/annotatedDocuments.js";
10
+ import { EditSource } from "../helpers/documentWithAnnotatedEdits.js";
7
11
  import { DocumentEditSourceTracker, TrackedEdit } from "./editTracker.js";
8
12
  import { ScmAdapter } from "./scmAdapter.js";
9
13
  import { IRandomService } from "@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/editTelemetry/browser/randomService.service";
10
- type EditTelemetryMode = "longterm" | "10minFocusWindow" | "20minFocusWindow";
11
- type EditTelemetryTrigger = "10hours" | "hashChange" | "branchChange" | "closed" | "time";
14
+ import { IAgentHostEditMarkerService } from "./agentHostEditMarkerService.js";
15
+ export type EditTelemetryCategory = "nes" | "inlineCompletionsCopilot" | "inlineCompletionsNES" | "inlineCompletionsOther" | "otherAI" | "agentHost" | "user" | "ide" | "external" | "unknown";
16
+ export declare function getEditTelemetryCategory(source: EditSource): EditTelemetryCategory;
12
17
  export declare class EditSourceTrackingImpl extends Disposable {
13
18
  private readonly _statsEnabled;
14
19
  private readonly _annotatedDocuments;
20
+ private readonly _agentHostEditMarkerService;
15
21
  private readonly _instantiationService;
16
22
  readonly docsState: IObservable<Map<import("../helpers/observableWorkspace.js").IObservableDocument, TrackedDocumentInfo>>;
17
23
  private readonly _states;
18
- constructor(_statsEnabled: IObservable<boolean>, _annotatedDocuments: IAnnotatedDocuments, _instantiationService: IInstantiationService);
24
+ constructor(_statsEnabled: IObservable<boolean>, _annotatedDocuments: IAnnotatedDocuments, _agentHostEditMarkerService: IAgentHostEditMarkerService | undefined, _instantiationService: IInstantiationService);
19
25
  }
20
26
  declare class TrackedDocumentInfo extends Disposable {
21
27
  private readonly _doc;
22
28
  private readonly _scm;
23
29
  private readonly _statsEnabled;
30
+ private readonly _agentHostEditMarkerService;
24
31
  private readonly _instantiationService;
25
32
  private readonly _telemetryService;
26
33
  private readonly _randomService;
27
34
  private readonly _userAttentionService;
35
+ private readonly _textFileService;
36
+ private readonly _logService;
28
37
  readonly longtermTracker: IObservable<DocumentEditSourceTracker<undefined> | undefined>;
29
38
  readonly windowedTracker: IObservable<DocumentEditSourceTracker<undefined> | undefined>;
30
39
  readonly windowedFocusTracker: IObservable<DocumentEditSourceTracker<undefined> | undefined>;
31
40
  private readonly _repo;
32
- constructor(_doc: AnnotatedDocument, _scm: ScmAdapter, _statsEnabled: IObservable<boolean>, _instantiationService: IInstantiationService, _telemetryService: ITelemetryService, _randomService: IRandomService, _userAttentionService: IUserAttentionService);
41
+ constructor(_doc: AnnotatedDocument, _scm: ScmAdapter, _statsEnabled: IObservable<boolean>, _agentHostEditMarkerService: IAgentHostEditMarkerService | undefined, _instantiationService: IInstantiationService, _telemetryService: ITelemetryService, _randomService: IRandomService, _userAttentionService: IUserAttentionService, _textFileService: ITextFileService, _logService: ILogService);
42
+ private _sendTelemetryAndLog;
33
43
  sendTelemetry(mode: EditTelemetryMode, trigger: EditTelemetryTrigger, t: DocumentEditSourceTracker, focusTime: number, actualTime: number): Promise<void>;
34
44
  getTelemetryData(ranges: readonly TrackedEdit[]): {
35
45
  nesModifiedCount: number;
36
46
  inlineCompletionsCopilotModifiedCount: number;
37
47
  inlineCompletionsNESModifiedCount: number;
38
48
  otherAIModifiedCount: number;
49
+ agentHostModifiedCount: number;
39
50
  userModifiedCount: number;
40
51
  ideModifiedCount: number;
41
52
  unknownModifiedCount: number;
@@ -5,57 +5,112 @@ import { IntervalTimer } from '@codingame/monaco-vscode-api/vscode/vs/base/commo
5
5
  import { Disposable, toDisposable } from '@codingame/monaco-vscode-api/vscode/vs/base/common/lifecycle';
6
6
  import '@codingame/monaco-vscode-api/vscode/vs/base/common/observableInternal/index';
7
7
  import { IInstantiationService } from '@codingame/monaco-vscode-api/vscode/vs/platform/instantiation/common/instantiation';
8
+ import { sendEditSourcesDetailsTelemetry, sendEditSourcesStatsTelemetry } from '../../../../../platform/telemetry/common/editTelemetry.js';
8
9
  import { ITelemetryService } from '@codingame/monaco-vscode-api/vscode/vs/platform/telemetry/common/telemetry.service';
9
10
  import { IUserAttentionService } from '@codingame/monaco-vscode-api/vscode/vs/workbench/services/userAttention/common/userAttentionService.service';
11
+ import { ITextFileService } from '@codingame/monaco-vscode-api/vscode/vs/workbench/services/textfile/common/textfiles.service';
12
+ import { ILogService } from '@codingame/monaco-vscode-api/vscode/vs/platform/log/common/log.service';
10
13
  import { EditTelemetryReportInlineEditArcSender, EditTelemetryReportEditArcForChatOrInlineChatSender, CreateSuggestionIdForChatOrInlineChatCaller } from './arcTelemetrySender.js';
11
14
  import { createDocWithJustReason } from '../helpers/documentWithAnnotatedEdits.js';
12
15
  import { DocumentEditSourceTracker } from './editTracker.js';
13
16
  import { sumByCategory } from '../helpers/utils.js';
14
17
  import { ScmAdapter } from './scmAdapter.js';
15
18
  import { IRandomService } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/editTelemetry/browser/randomService.service';
19
+ import { AgentHostEditAttributionDeferredError, AgentHostEditAttributionUnknownOutcomeError } from './agentHostEditMarkerService.js';
16
20
  import { mapObservableArrayCached } from '@codingame/monaco-vscode-api/vscode/vs/base/common/observableInternal/utils/utils';
17
21
  import { derived } from '@codingame/monaco-vscode-api/vscode/vs/base/common/observableInternal/observables/derived';
18
22
  import { observableSignal } from '@codingame/monaco-vscode-api/vscode/vs/base/common/observableInternal/observables/observableSignal';
19
23
  import { autorun } from '@codingame/monaco-vscode-api/vscode/vs/base/common/observableInternal/reactions/autorun';
20
24
  import { runOnChange } from '@codingame/monaco-vscode-api/vscode/vs/base/common/observableInternal/utils/runOnChange';
21
25
 
26
+ const FOCUS_CORRELATION_DRAIN_TIMEOUT = 1_000;
27
+ function getEditTelemetryCategory(source) {
28
+ if (source.category === "ai" && source.kind === "nes") {
29
+ return "nes";
30
+ }
31
+ if (source.category === "ai" && source.kind === "completion" && source.extensionId === "github.copilot") {
32
+ return "inlineCompletionsCopilot";
33
+ }
34
+ if (source.category === "ai" && source.kind === "completion" && source.extensionId === "github.copilot-chat" && source.providerId === "nes") {
35
+ return "inlineCompletionsNES";
36
+ }
37
+ if (source.category === "ai" && source.kind === "completion" && source.extensionId === "github.copilot-chat" && source.providerId === "completions") {
38
+ return "inlineCompletionsCopilot";
39
+ }
40
+ if (source.category === "ai" && source.kind === "completion") {
41
+ return "inlineCompletionsOther";
42
+ }
43
+ if (source.category === "ai") {
44
+ return "otherAI";
45
+ }
46
+ if (source.category === "agentHost") {
47
+ return "agentHost";
48
+ }
49
+ if (source.category === "user") {
50
+ return "user";
51
+ }
52
+ if (source.category === "ide") {
53
+ return "ide";
54
+ }
55
+ if (source.category === "external") {
56
+ return "external";
57
+ }
58
+ return "unknown";
59
+ }
22
60
  let EditSourceTrackingImpl = class EditSourceTrackingImpl extends Disposable {
23
- constructor(_statsEnabled, _annotatedDocuments, _instantiationService) {
61
+ constructor(
62
+ _statsEnabled,
63
+ _annotatedDocuments,
64
+ _agentHostEditMarkerService,
65
+ _instantiationService
66
+ ) {
24
67
  super();
25
68
  this._statsEnabled = _statsEnabled;
26
69
  this._annotatedDocuments = _annotatedDocuments;
70
+ this._agentHostEditMarkerService = _agentHostEditMarkerService;
27
71
  this._instantiationService = _instantiationService;
28
72
  const scmBridge = this._instantiationService.createInstance(ScmAdapter);
29
73
  this._states = mapObservableArrayCached(this, this._annotatedDocuments.documents, (doc, store) => {
30
- return [doc.document, store.add(
31
- this._instantiationService.createInstance(TrackedDocumentInfo, doc, scmBridge, this._statsEnabled)
32
- )];
74
+ return [doc.document, store.add(this._instantiationService.createInstance(
75
+ TrackedDocumentInfo,
76
+ doc,
77
+ scmBridge,
78
+ this._statsEnabled,
79
+ this._agentHostEditMarkerService
80
+ ))];
33
81
  });
34
82
  this.docsState = ( this._states.map(entries => ( new Map(entries))));
35
83
  this.docsState.recomputeInitiallyAndOnChange(this._store);
36
84
  }
37
85
  };
38
- EditSourceTrackingImpl = ( __decorate([( __param(2, IInstantiationService))], EditSourceTrackingImpl));
86
+ EditSourceTrackingImpl = ( __decorate([( __param(3, IInstantiationService))], EditSourceTrackingImpl));
39
87
  let TrackedDocumentInfo = class TrackedDocumentInfo extends Disposable {
40
88
  constructor(
41
89
  _doc,
42
90
  _scm,
43
91
  _statsEnabled,
92
+ _agentHostEditMarkerService,
44
93
  _instantiationService,
45
94
  _telemetryService,
46
95
  _randomService,
47
- _userAttentionService
96
+ _userAttentionService,
97
+ _textFileService,
98
+ _logService
48
99
  ) {
49
100
  super();
50
101
  this._doc = _doc;
51
102
  this._scm = _scm;
52
103
  this._statsEnabled = _statsEnabled;
104
+ this._agentHostEditMarkerService = _agentHostEditMarkerService;
53
105
  this._instantiationService = _instantiationService;
54
106
  this._telemetryService = _telemetryService;
55
107
  this._randomService = _randomService;
56
108
  this._userAttentionService = _userAttentionService;
109
+ this._textFileService = _textFileService;
110
+ this._logService = _logService;
57
111
  this._repo = derived(this, reader => this._scm.getRepo(_doc.document.uri, reader));
58
112
  const docWithJustReason = createDocWithJustReason(_doc.documentWithAnnotations, this._store);
113
+ const externalEditCorrelation = this._agentHostEditMarkerService?.createCorrelation(_doc.document.uri);
59
114
  const longtermResetSignal = observableSignal("resetSignal");
60
115
  let longtermReason = "closed";
61
116
  this.longtermTracker = derived(reader => {
@@ -63,20 +118,18 @@ let TrackedDocumentInfo = class TrackedDocumentInfo extends Disposable {
63
118
  return undefined;
64
119
  }
65
120
  longtermResetSignal.read(reader);
66
- const t = reader.store.add(( new DocumentEditSourceTracker(docWithJustReason, undefined)));
121
+ const t = ( new DocumentEditSourceTracker(docWithJustReason, undefined, externalEditCorrelation));
67
122
  const startFocusTime = this._userAttentionService.totalFocusTimeMs;
68
123
  const startTime = Date.now();
69
124
  reader.store.add(toDisposable(() => {
70
- if (!t.isEmpty()) {
71
- this.sendTelemetry(
72
- "longterm",
73
- longtermReason,
74
- t,
75
- this._userAttentionService.totalFocusTimeMs - startFocusTime,
76
- Date.now() - startTime
77
- );
78
- }
79
- t.dispose();
125
+ t.stopTracking();
126
+ this._sendTelemetryAndLog(
127
+ "longterm",
128
+ longtermReason,
129
+ t,
130
+ this._userAttentionService.totalFocusTimeMs - startFocusTime,
131
+ Date.now() - startTime
132
+ );
80
133
  }));
81
134
  return t;
82
135
  }).recomputeInitiallyAndOnChange(this._store);
@@ -127,18 +180,18 @@ let TrackedDocumentInfo = class TrackedDocumentInfo extends Disposable {
127
180
  resetSignal.trigger(undefined);
128
181
  })
129
182
  );
130
- const t = reader.store.add(( new DocumentEditSourceTracker(docWithJustReason, undefined)));
183
+ const t = ( new DocumentEditSourceTracker(docWithJustReason, undefined, externalEditCorrelation, "reattribute"));
131
184
  const startFocusTime = this._userAttentionService.totalFocusTimeMs;
132
185
  const startTime = Date.now();
133
- reader.store.add(toDisposable(async () => {
134
- this.sendTelemetry(
186
+ reader.store.add(toDisposable(() => {
187
+ t.stopTracking();
188
+ this._sendTelemetryAndLog(
135
189
  "10minFocusWindow",
136
190
  "time",
137
191
  t,
138
192
  this._userAttentionService.totalFocusTimeMs - startFocusTime,
139
193
  Date.now() - startTime
140
194
  );
141
- t.dispose();
142
195
  }));
143
196
  return t;
144
197
  }).recomputeInitiallyAndOnChange(this._store);
@@ -156,46 +209,118 @@ let TrackedDocumentInfo = class TrackedDocumentInfo extends Disposable {
156
209
  focusResetSignal.trigger(undefined);
157
210
  })
158
211
  );
159
- const t = reader.store.add(( new DocumentEditSourceTracker(docWithJustReason, undefined)));
212
+ const t = ( new DocumentEditSourceTracker(docWithJustReason, undefined, externalEditCorrelation, "reattribute"));
160
213
  const startFocusTime = this._userAttentionService.totalFocusTimeMs;
161
214
  const startTime = Date.now();
162
- reader.store.add(toDisposable(async () => {
163
- this.sendTelemetry(
215
+ reader.store.add(toDisposable(() => {
216
+ t.stopTracking();
217
+ this._sendTelemetryAndLog(
164
218
  "20minFocusWindow",
165
219
  "time",
166
220
  t,
167
221
  this._userAttentionService.totalFocusTimeMs - startFocusTime,
168
222
  Date.now() - startTime
169
223
  );
170
- t.dispose();
171
224
  }));
172
225
  return t;
173
226
  }).recomputeInitiallyAndOnChange(this._store);
174
227
  }
228
+ _sendTelemetryAndLog(mode, trigger, tracker, focusTime, actualTime) {
229
+ void this.sendTelemetry(mode, trigger, tracker, focusTime, actualTime).catch(error => {
230
+ this._logService.error(`[EditSourceTrackingImpl] Failed to send ${mode} edit telemetry: ${error}`);
231
+ }).finally(() => {
232
+ tracker.releaseExternalEditCorrelations();
233
+ tracker.dispose();
234
+ });
235
+ }
175
236
  async sendTelemetry(mode, trigger, t, focusTime, actualTime) {
176
- const ranges = t.getTrackedRanges();
177
- const keys = t.getAllKeys();
178
- if (keys.length === 0) {
179
- return;
237
+ if (mode !== "longterm") {
238
+ await t.waitForExternalEditCorrelations(FOCUS_CORRELATION_DRAIN_TIMEOUT);
180
239
  }
181
- const data = this.getTelemetryData(ranges);
240
+ t.applyPendingExternalEdits();
241
+ let ranges = t.getTrackedRanges();
242
+ let internalKeys = t.getAllKeys();
243
+ let data = this.getTelemetryData(ranges);
182
244
  const statsUuid = this._randomService.generateUuid();
183
- const sums = sumByCategory(ranges, r => r.range.length, r => r.sourceKey);
184
- const entries = Object.entries(sums).filter(([key, value]) => value !== undefined);
185
- entries.sort(reverseOrder(compareBy(([key, value]) => value, numberComparator)));
186
- entries.length = mode === "longterm" ? 30 : 10;
187
- for (const key of keys) {
188
- if (!sums[key]) {
189
- sums[key] = 0;
245
+ let preparedAgentFlush;
246
+ let deferSuppressedExternal = false;
247
+ const isDirty = this._textFileService.isDirty(this._doc.document.uri);
248
+ if (mode === "longterm" && this._agentHostEditMarkerService) {
249
+ try {
250
+ preparedAgentFlush = await this._agentHostEditMarkerService.prepareFlush(
251
+ this._doc.document.uri,
252
+ trigger,
253
+ statsUuid,
254
+ isDirty,
255
+ this._doc.document.languageId.get()
256
+ );
257
+ } catch (error) {
258
+ this._logService.error(
259
+ `[EditSourceTrackingImpl] Failed to prepare Agent Host edit attribution: ${error}`
260
+ );
261
+ deferSuppressedExternal = error instanceof AgentHostEditAttributionDeferredError || error instanceof AgentHostEditAttributionUnknownOutcomeError;
262
+ }
263
+ }
264
+ if (preparedAgentFlush) {
265
+ t.applyPendingExternalEdits();
266
+ ranges = t.getTrackedRanges();
267
+ internalKeys = t.getAllKeys();
268
+ data = this.getTelemetryData(ranges);
269
+ try {
270
+ await preparedAgentFlush.commit(
271
+ data.totalModifiedCharactersInFinalState + preparedAgentFlush.agentModifiedCount
272
+ );
273
+ } catch (error) {
274
+ this._logService.error(
275
+ `[EditSourceTrackingImpl] Failed to commit Agent Host edit attribution: ${error}`
276
+ );
277
+ if (!(error instanceof AgentHostEditAttributionUnknownOutcomeError)) {
278
+ preparedAgentFlush = undefined;
279
+ }
280
+ deferSuppressedExternal = error instanceof AgentHostEditAttributionDeferredError || error instanceof AgentHostEditAttributionUnknownOutcomeError;
190
281
  }
191
282
  }
192
- for (const [key, value] of Object.entries(sums)) {
193
- if (value === undefined) {
194
- continue;
283
+ const includeSuppressedExternal = !preparedAgentFlush && !deferSuppressedExternal && !isDirty && mode === "longterm" && !!this._agentHostEditMarkerService;
284
+ if (includeSuppressedExternal) {
285
+ ranges = t.getTrackedRanges(undefined, true);
286
+ internalKeys = t.getAllKeys(true);
287
+ data = this.getTelemetryData(ranges);
288
+ }
289
+ const coverageGap = mode === "longterm" && !isDirty && !deferSuppressedExternal && !preparedAgentFlush?.deferCoverageGap ? this._agentHostEditMarkerService?.takeCoverageGap?.(
290
+ this._doc.document.uri,
291
+ preparedAgentFlush?.coverageGapThroughSequence ?? preparedAgentFlush?.lastSequence
292
+ ) : undefined;
293
+ const agentModifiedCount = mode === "longterm" ? preparedAgentFlush?.agentModifiedCount ?? 0 : data.agentHostModifiedCount;
294
+ if (internalKeys.length === 0 && agentModifiedCount === 0 && !coverageGap) {
295
+ return;
296
+ }
297
+ const totalModifiedCount = data.totalModifiedCharactersInFinalState + (preparedAgentFlush?.agentModifiedCount ?? 0);
298
+ const telemetryKeys = ( new Map());
299
+ for (const internalKey of internalKeys) {
300
+ const representative = t.getRepresentative(internalKey);
301
+ const telemetryKey = representative.toKey(1);
302
+ const entry = telemetryKeys.get(telemetryKey) ?? {
303
+ representative,
304
+ modifiedCount: 0,
305
+ deltaModifiedCount: 0
306
+ };
307
+ entry.deltaModifiedCount += t.getTotalInsertedCharactersCount(internalKey, includeSuppressedExternal);
308
+ telemetryKeys.set(telemetryKey, entry);
309
+ }
310
+ for (const range of ranges) {
311
+ const representative = t.getRepresentative(range.sourceKey);
312
+ const entry = telemetryKeys.get(representative.toKey(1));
313
+ if (entry) {
314
+ entry.modifiedCount += range.range.length;
195
315
  }
196
- const repr = t.getRepresentative(key);
197
- const deltaModifiedCount = t.getTotalInsertedCharactersCount(key);
198
- this._telemetryService.publicLog2("editTelemetry.editSources.details", {
316
+ }
317
+ const sums = Object.fromEntries(Array.from(telemetryKeys, ([key, value]) => [key, value.modifiedCount]));
318
+ const entries = Object.entries(sums).filter(entry => entry[1] !== undefined).sort(reverseOrder(compareBy(([, value]) => value, numberComparator))).slice(0, mode === "longterm" ? 30 : 10);
319
+ for (const [key, value] of entries) {
320
+ const telemetryEntry = telemetryKeys.get(key);
321
+ const repr = telemetryEntry.representative;
322
+ const deltaModifiedCount = telemetryEntry.deltaModifiedCount;
323
+ sendEditSourcesDetailsTelemetry(this._telemetryService, {
199
324
  mode,
200
325
  sourceKey: key,
201
326
  sourceKeyCleaned: repr.toKey(1, {
@@ -211,13 +336,16 @@ let TrackedDocumentInfo = class TrackedDocumentInfo extends Disposable {
211
336
  statsUuid: statsUuid,
212
337
  conversationId: repr.props.$$sessionId,
213
338
  requestId: repr.props.$$requestId,
339
+ origin: repr.props.$origin,
340
+ harness: repr.props.$harness,
214
341
  modifiedCount: value,
215
342
  deltaModifiedCount: deltaModifiedCount,
216
- totalModifiedCount: data.totalModifiedCharactersInFinalState
343
+ totalModifiedCount
217
344
  });
218
345
  }
219
346
  const isTrackedByGit = await data.isTrackedByGit;
220
- this._telemetryService.publicLog2("editTelemetry.editSources.stats", {
347
+ sendEditSourcesStatsTelemetry(this._telemetryService, {
348
+ attributionSchemaVersion: 2,
221
349
  mode,
222
350
  languageId: this._doc.document.languageId.get(),
223
351
  statsUuid: statsUuid,
@@ -225,58 +353,32 @@ let TrackedDocumentInfo = class TrackedDocumentInfo extends Disposable {
225
353
  inlineCompletionsCopilotModifiedCount: data.inlineCompletionsCopilotModifiedCount,
226
354
  inlineCompletionsNESModifiedCount: data.inlineCompletionsNESModifiedCount,
227
355
  otherAIModifiedCount: data.otherAIModifiedCount,
356
+ agentHostModifiedCount: agentModifiedCount,
228
357
  unknownModifiedCount: data.unknownModifiedCount,
229
358
  userModifiedCount: data.userModifiedCount,
230
359
  ideModifiedCount: data.ideModifiedCount,
231
- totalModifiedCharacters: data.totalModifiedCharactersInFinalState,
360
+ totalModifiedCharacters: totalModifiedCount,
232
361
  externalModifiedCount: data.externalModifiedCount,
233
362
  isTrackedByGit: isTrackedByGit ? 1 : 0,
234
363
  focusTime,
235
364
  actualTime,
236
- trigger
365
+ trigger,
366
+ ...(mode === "longterm" ? {
367
+ agentHostAttributionCoverage: coverageGap ? "partial" : "complete",
368
+ agentHostUntrackedEditCount: coverageGap?.editCount ?? 0,
369
+ agentHostUntrackedInsertedCount: coverageGap?.insertedCount ?? 0
370
+ } : {})
237
371
  });
238
372
  }
239
373
  getTelemetryData(ranges) {
240
- const getEditCategory = source => {
241
- if (source.category === "ai" && source.kind === "nes") {
242
- return "nes";
243
- }
244
- if (source.category === "ai" && source.kind === "completion" && source.extensionId === "github.copilot") {
245
- return "inlineCompletionsCopilot";
246
- }
247
- if (source.category === "ai" && source.kind === "completion" && source.extensionId === "github.copilot-chat" && source.providerId === "completions") {
248
- return "inlineCompletionsCopilot";
249
- }
250
- if (source.category === "ai" && source.kind === "completion" && source.extensionId === "github.copilot-chat" && source.providerId === "nes") {
251
- return "inlineCompletionsNES";
252
- }
253
- if (source.category === "ai" && source.kind === "completion") {
254
- return "inlineCompletionsOther";
255
- }
256
- if (source.category === "ai") {
257
- return "otherAI";
258
- }
259
- if (source.category === "user") {
260
- return "user";
261
- }
262
- if (source.category === "ide") {
263
- return "ide";
264
- }
265
- if (source.category === "external") {
266
- return "external";
267
- }
268
- if (source.category === "unknown") {
269
- return "unknown";
270
- }
271
- return "unknown";
272
- };
273
- const sums = sumByCategory(ranges, r => r.range.length, r => getEditCategory(r.source));
374
+ const sums = sumByCategory(ranges, r => r.range.length, r => getEditTelemetryCategory(r.source));
274
375
  const totalModifiedCharactersInFinalState = sumBy(ranges, r => r.range.length);
275
376
  return {
276
377
  nesModifiedCount: sums.nes ?? 0,
277
378
  inlineCompletionsCopilotModifiedCount: sums.inlineCompletionsCopilot ?? 0,
278
379
  inlineCompletionsNESModifiedCount: sums.inlineCompletionsNES ?? 0,
279
380
  otherAIModifiedCount: sums.otherAI ?? 0,
381
+ agentHostModifiedCount: sums.agentHost ?? 0,
280
382
  userModifiedCount: sums.user ?? 0,
281
383
  ideModifiedCount: sums.ide ?? 0,
282
384
  unknownModifiedCount: sums.unknown ?? 0,
@@ -287,6 +389,6 @@ let TrackedDocumentInfo = class TrackedDocumentInfo extends Disposable {
287
389
  };
288
390
  }
289
391
  };
290
- TrackedDocumentInfo = ( __decorate([( __param(3, IInstantiationService)), ( __param(4, ITelemetryService)), ( __param(5, IRandomService)), ( __param(6, IUserAttentionService))], TrackedDocumentInfo));
392
+ TrackedDocumentInfo = ( __decorate([( __param(4, IInstantiationService)), ( __param(5, ITelemetryService)), ( __param(6, IRandomService)), ( __param(7, IUserAttentionService)), ( __param(8, ITextFileService)), ( __param(9, ILogService))], TrackedDocumentInfo));
291
393
 
292
- export { EditSourceTrackingImpl };
394
+ export { EditSourceTrackingImpl, getEditTelemetryCategory };
@@ -3,32 +3,48 @@ import { IReader } from "@codingame/monaco-vscode-api/vscode/vs/base/common/obse
3
3
  import { OffsetRange } from "@codingame/monaco-vscode-api/vscode/vs/editor/common/core/ranges/offsetRange";
4
4
  import { TextModelEditSource } from "@codingame/monaco-vscode-api/vscode/vs/editor/common/textModelEditSource";
5
5
  import { IDocumentWithAnnotatedEdits, EditSource } from "../helpers/documentWithAnnotatedEdits.js";
6
+ import { IExternalEditCorrelation } from "./agentHostEditMarkerService.js";
7
+ export type ExternalEditCorrelationPolicy = "suppress" | "reattribute";
6
8
  /**
7
9
  * Tracks a single document.
8
10
  */
9
11
  export declare class DocumentEditSourceTracker<T = void> extends Disposable {
10
12
  private readonly _doc;
11
13
  readonly data: T;
14
+ private readonly _externalEditCorrelation?;
15
+ private readonly _externalEditCorrelationPolicy;
12
16
  private _edits;
13
17
  private _pendingExternalEdits;
14
18
  private readonly _update;
19
+ private readonly _documentStore;
15
20
  private readonly _representativePerKey;
16
21
  private readonly _sumAddedCharactersPerKey;
17
- constructor(_doc: IDocumentWithAnnotatedEdits, data: T);
22
+ private readonly _externalObservationIds;
23
+ private readonly _ignoredInitialExternalObservationIds;
24
+ private readonly _suppressedExternalObservationIds;
25
+ private readonly _invalidatedExternalObservationIds;
26
+ private readonly _reattributedExternalObservations;
27
+ constructor(_doc: IDocumentWithAnnotatedEdits, data: T, _externalEditCorrelation?: IExternalEditCorrelation | undefined, _externalEditCorrelationPolicy?: ExternalEditCorrelationPolicy);
28
+ releaseExternalEditCorrelations(): void;
29
+ stopTracking(): void;
30
+ waitForExternalEditCorrelations(timeoutMs: number): Promise<void>;
18
31
  private _applyEdit;
19
32
  waitForQueue(): Promise<void>;
20
- getTotalInsertedCharactersCount(key: string): number;
21
- getAllKeys(): string[];
33
+ getTotalInsertedCharactersCount(key: string, includeSuppressed?: boolean): number;
34
+ getAllKeys(includeSuppressed?: boolean): string[];
22
35
  getRepresentative(key: string): TextModelEditSource | undefined;
23
- getTrackedRanges(reader?: IReader): TrackedEdit[];
36
+ applyPendingExternalEdits(): void;
37
+ getTrackedRanges(reader?: IReader, includeSuppressed?: boolean): TrackedEdit[];
24
38
  isEmpty(): boolean;
39
+ private _shouldIncludeKey;
40
+ private _resolveExternalObservation;
25
41
  _getDebugVisualization(): {
42
+ $fileExtension: string;
26
43
  value: string;
27
44
  decorations: {
28
45
  range: number[];
29
46
  color: string;
30
47
  }[];
31
- $fileExtension: string;
32
48
  };
33
49
  }
34
50
  export declare class TrackedEdit {