Skip to content

editTelemetry: unify long-term edit source tracking#326403

Draft
amunger wants to merge 1 commit into
mainfrom
aamunger/unified-edit-attribution
Draft

editTelemetry: unify long-term edit source tracking#326403
amunger wants to merge 1 commit into
mainfrom
aamunger/unified-edit-attribution

Conversation

@amunger

@amunger amunger commented Jul 17, 2026

Copy link
Copy Markdown
Collaborator

closes https://github.com/microsoft/vscode-internalbacklog/issues/8467

Overview

What

Unifies long-term editTelemetry.editSources.details tracking for local text-model edits and Agent Host file edits in one workbench-owned per-resource stream. Agent Host ChatToolCallComplete file snapshots are normalized, deduplicated against matching reloadFromDisk observations, reconciled with current disk content, and projected through the existing DocumentEditSourceTracker mechanics. The event kind and existing local source fields remain unchanged; Agent Host source rows add origin=agentHost and the canonical provider in harness. Copilot Agent Host rows continue through the existing GitHub edit-telemetry channel.

Follow-up work will evaluate moving 10minFocusWindow and 20minFocusWindow details, editSources.stats, and ARC to the canonical stream. Those existing local paths are deliberately unchanged in this PR.

Why

Tracked in https://github.com/microsoft/vscode-internalbacklog/issues/8247. SDK-driven Agent Host edits occur on disk without passing through ITextModel, so the existing long-term tracker cannot attribute their inserted and retained characters. This restores commit/branch survival analysis for Agent Host edits while preventing duplicate attribution when an open editor later observes the same disk change.


Property-by-property parity

Legend: ✅ = exact / verbatim match, ≈ = close analogue, ⊗ = omitted.

Field Local source Agent Host source Parity
mode Existing long-term window Canonical long-term window longterm
sourceKey Existing TextModelEditSource.toKey(1) Chat.applyEdits plus origin and harness metadata ≈ same key construction with AH identity added
sourceKeyCleaned Existing cleaned source key Same cleaning rules
extensionId Source metadata Not available for AH file tools
extensionVersion Source metadata Not available for AH file tools
modelId Source metadata Not available on the file-edit action
trigger Close, hash, branch, ten-hour boundary Shared resource lifecycle boundary
languageId Open model language Filepath/first-line language inference ≈ inferred when no model exists
statsUuid Generated per window Shared across every source row in the canonical window
conversationId Chat edit session id Agent Host session id ≈ equivalent conversation correlation
requestId Chat request id Agent Host turn id ≈ equivalent request/turn correlation
origin Existing value or absent agentHost ✅ discriminator
harness Existing value or absent Canonical provider id (copilotcli, claude, codex) ✅ provider discriminator

Measurement-by-measurement parity

Metric Local source Agent Host source Parity
modifiedCount Retained attributed ranges Retained attributed ranges after disk reconciliation
deltaModifiedCount Total inserted characters per source Total inserted characters per source
totalModifiedCount Retained characters across the window Retained characters across all local, AH, and external sources in the canonical window

Row-count and dashboard implications

  • Historical rows: local long-term and focus-window rows only.
  • New rows: long-term windows include Agent Host sources in the same statsUuid group as local sources for that resource.
  • A local and Agent Host observation of the same physical edit produces one attributed transition, not duplicate rows.
  • Queries can identify Agent Host rows with origin == "agentHost" and split providers with harness.
  • Source-key groupings will gain Agent Host Chat.applyEdits series containing origin and harness.
  • Focus-window details, stats, and ARC row counts do not change in this PR.

Semantic-shift ledger

Field Shift Impact
languageId Inferred from path/first line when no model is open May differ from an extension-assigned model language id.
conversationId Agent Host session id replaces workbench chat-edit session id Same analytical role, different id namespace.
requestId Agent Host turn id replaces workbench chat request id Same analytical role, different id namespace.
sourceKey AH rows add origin/provider identity New AH source series; local series remain unchanged.

Track local model and Agent Host file edits in one canonical per-resource stream for editSources.details. Deduplicate reload observations, reconcile current disk content, preserve existing focus-window, stats, and ARC paths, and forward Copilot Agent Host rows through the existing GitHub channel.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings July 17, 2026 20:17

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Unifies long-term edit-source telemetry for local model and Agent Host file edits through a canonical per-resource stream.

Changes:

  • Adds Agent Host snapshot ingestion, reconciliation, and deduplication.
  • Projects unified transitions through the existing edit tracker.
  • Adds shared telemetry emission and comprehensive unit coverage.
Show a summary per file
File Description
src/vs/editor/common/textModelEditSource.ts Adds origin and harness metadata.
src/vs/workbench/contrib/editTelemetry/browser/helpers/unifiedDocumentAdapters.ts Adapts model and agent edits.
src/vs/workbench/contrib/editTelemetry/browser/helpers/unifiedDocumentReconciler.ts Reconciles edit observations.
src/vs/workbench/contrib/editTelemetry/browser/helpers/unifiedDocumentRegistry.ts Manages canonical resource state.
src/vs/workbench/contrib/editTelemetry/browser/telemetry/agentHostEditSourceTracking.ts Ingests Agent Host file edits.
src/vs/workbench/contrib/editTelemetry/browser/telemetry/editSourceTelemetry.ts Centralizes telemetry emission.
src/vs/workbench/contrib/editTelemetry/browser/telemetry/editSourceTrackingFeature.ts Wires unified tracking services.
src/vs/workbench/contrib/editTelemetry/browser/telemetry/editSourceTrackingImpl.ts Routes long-term local telemetry.
src/vs/workbench/contrib/editTelemetry/browser/telemetry/editTracker.ts Exposes pending-external-edit application.
src/vs/workbench/contrib/editTelemetry/browser/telemetry/unifiedDocumentTrackerProjection.ts Projects canonical transitions.
src/vs/workbench/contrib/editTelemetry/browser/telemetry/unifiedEditSourceTracking.ts Owns streams and telemetry windows.
src/vs/workbench/contrib/editTelemetry/test/browser/agentHostEditSourceTracking.test.ts Tests Agent Host file tracking.
src/vs/workbench/contrib/editTelemetry/test/browser/editSourceTrackingImpl.test.ts Updates constructor setup.
src/vs/workbench/contrib/editTelemetry/test/browser/editTelemetry.test.ts Updates constructor setup.
src/vs/workbench/contrib/editTelemetry/test/browser/unifiedDocumentAdapters.test.ts Tests adapter behavior.
src/vs/workbench/contrib/editTelemetry/test/browser/unifiedDocumentReconciler.test.ts Tests reconciliation scenarios.
src/vs/workbench/contrib/editTelemetry/test/browser/unifiedDocumentRegistry.test.ts Tests registry identity and transfer.
src/vs/workbench/contrib/editTelemetry/test/browser/unifiedDocumentTrackerProjection.test.ts Tests tracker projection.
src/vs/workbench/contrib/editTelemetry/test/browser/unifiedEditSourceTracking.test.ts Tests end-to-end unified telemetry.

Review details

  • Files reviewed: 19/19 changed files
  • Comments generated: 4
  • Review effort level: Medium

Comment on lines +87 to +88
const edit = await computeDiff(transition.before, transition.after);
document.apply(edit, transition.source);
Comment on lines +296 to +298
const transition = this._createTransition(before, after, source, kind, correlation, agentKind);
this._transitions.push(transition);
return { kind: 'append', transition: { ...transition } };
Comment on lines +93 to +99
if (result.transferResult) {
if (edit.previousResource) {
this._lastResults.delete(this._key(edit.previousResource));
this._transferResourceState(edit.previousResource, edit.resource);
}
this._recordResult(result.transferResult);
}
Comment on lines +228 to +236
this._unifiedTracking.applyAgentEdit({
resource,
previousResource: beforeResource,
before: beforeText,
after: afterText,
source,
correlation: `${session.toString()}:${toolCallId}:${contentIndex}`,
kind: normalized.kind,
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants