src/vs/platform/assignment/common/assignment.ts

200 LOC · 135 covered · 65 uncovered · 6 ranges · 198 concepts · 1 introducers · 76 tests

File neighbourhood

The centred file is linked to every concept that introduces one of its ranges, every test that runs code from the file, and the gray connector concepts standing between those tests and the file's own introducer concepts. Undirected links join concepts to every file where they introduce source and concepts to the tests they introduce; arrows show specialization between the displayed concepts and bridge only concepts omitted from this view. Concept colors match the source ranges below; connector concepts have no source color and are shown in gray.

Focused file, its introducer and connector concepts, their introduced files, and tests that run code from the file

In the embedded map, ordinary wheel input scrolls the page; use the visible controls to zoom and drag to pan. Open the full-screen map for canvas navigation: wheel pans, Ctrl/Command plus wheel zooms, and arrow keys pan when this region is focused. On touch screens, open the full-screen map to pan or pinch. If JavaScript or WebGL is unavailable, use the related-file, concept, and source links on this page.

Graph controls are ready.

Interactive rendering requires JavaScript and WebGL. Use the related-file, concept, and source links on this page while the interactive map is unavailable.

1 > /*--------------------------------------------------------------------------------------------- chatServiceImpl.ts ×75
2 > * Copyright (c) Microsoft Corporation. All rights reserved.
3 > * Licensed under the MIT License. See License.txt in the project root for license information.
4 > *--------------------------------------------------------------------------------------------*/
5 >
6 > import { Event } from '../../../base/common/event.js';
7 > import * as platform from '../../../base/common/platform.js';
8 > import type { IExperimentationFilterProvider } from 'tas-client';
9 >
10 > export const ASSIGNMENT_STORAGE_KEY = 'VSCode.ABExp.FeatureData';
11 > export const ASSIGNMENT_REFETCH_INTERVAL = 60 * 60 * 1000; // 1 hour
12 >
13 > export interface IAssignmentService {
14 > readonly _serviceBrand: undefined;
15 >
16 > readonly onDidRefetchAssignments: Event<void>;
17 > getTreatment<T extends string | number | boolean>(name: string): Promise<T | undefined>;
18 > }
19 >
20 > export enum TargetPopulation {
21 > Insiders = 'insider',
22 > Public = 'public',
23 > Exploration = 'exploration'
24 > }
25 >
26 > /*
27 > Based upon the official VSCode currently existing filters in the
28 > ExP backend for the VSCode cluster.
29 > https://experimentation.visualstudio.com/Analysis%20and%20Experimentation/_git/AnE.ExP.TAS.TachyonHost.Configuration?path=%2FConfigurations%2Fvscode%2Fvscode.json&version=GBmaster
30 > "X-MSEdge-Market": "detection.market",
31 > "X-FD-Corpnet": "detection.corpnet",
32 > "X-VSCode-AppVersion": "appversion",
33 > "X-VSCode-Build": "build",
34 > "X-MSEdge-ClientId": "clientid",
35 > "X-VSCode-ExtensionName": "extensionname",
36 > "X-VSCode-ExtensionVersion": "extensionversion",
37 > "X-VSCode-TargetPopulation": "targetpopulation",
38 > "X-VSCode-Language": "language",
39 > "X-VSCode-Platform": "platform",
40 > "X-VSCode-ReleaseDate": "releasedate",
41 > "X-VSCode-WindowKind": "windowkind"
42 > */
43 > export enum Filters {
44 > /**
45 > * The market in which the extension is distributed.
46 > */
47 > Market = 'X-MSEdge-Market',
48 >
49 > /**
50 > * The corporation network.
51 > */
52 > CorpNet = 'X-FD-Corpnet',
53 >
54 > /**
55 > * Version of the application which uses experimentation service.
56 > */
57 > ApplicationVersion = 'X-VSCode-AppVersion',
58 >
59 > /**
60 > * Insiders vs Stable.
61 > */
62 > Build = 'X-VSCode-Build',
63 >
64 > /**
65 > * Client Id which is used as primary unit for the experimentation.
66 > */
67 > ClientId = 'X-MSEdge-ClientId',
68 >
69 > /**
70 > * Developer Device Id which can be used as an alternate unit for experimentation.
71 > */
72 > DeveloperDeviceId = 'X-VSCode-DevDeviceId',
73 >
74 > /**
75 > * Extension header.
76 > */
77 > ExtensionName = 'X-VSCode-ExtensionName',
78 >
79 > /**
80 > * The version of the extension.
81 > */
82 > ExtensionVersion = 'X-VSCode-ExtensionVersion',
83 >
84 > /**
85 > * The language in use by VS Code
86 > */
87 > Language = 'X-VSCode-Language',
88 >
89 > /**
90 > * The target population.
91 > * This is used to separate internal, early preview, GA, etc.
92 > */
93 > TargetPopulation = 'X-VSCode-TargetPopulation',
94 >
95 > /**
96 > * The platform (OS) on which VS Code is running.
97 > */
98 > Platform = 'X-VSCode-Platform',
99 >
100 > /**
101 > * The release/build date of VS Code (UTC) in the format yyyymmddHH.
102 > */
103 > ReleaseDate = 'X-VSCode-ReleaseDate',
104 >
105 > /**
106 > * The kind of window VS Code is running in (`editor` or `agents`).
107 > */
108 > WindowKind = 'X-VSCode-WindowKind',
109 > }
110 >
111 > export const enum WindowKind {
112 > Editor = 'editor',
113 > Agents = 'agents',
114 > }
115 >
116 > export class AssignmentFilterProvider implements IExperimentationFilterProvider {
117 > constructor(
118 private version: string,
119 private appName: string,
120 private machineId: string,
121 private devDeviceId: string,
122 private targetPopulation: TargetPopulation,
123 private releaseDate: string,
124 private windowKind: WindowKind
125 ) { }
127 > /**
128 > * Returns a version string that can be parsed by the TAS client.
129 > * The tas client cannot handle suffixes lke "-insider"
130 > * Ref: https://github.com/microsoft/tas-client/blob/30340d5e1da37c2789049fcf45928b954680606f/vscode-tas-client/src/vscode-tas-client/VSCodeFilterProvider.ts#L35
131 > *
132 > * @param version Version string to be trimmed.
133 > */
134 > private static trimVersionSuffix(version: string): string {
135 const regex = /\-[a-zA-Z0-9]+$/;
136 const result = version.split(regex);
137
138 return result[0];
139 }
141 > getFilterValue(filter: string): string | null {
142 switch (filter) {
143 case Filters.ApplicationVersion:
144 return AssignmentFilterProvider.trimVersionSuffix(this.version); // productService.version
145 case Filters.Build:
146 return this.appName; // productService.nameLong
147 case Filters.ClientId:
148 return this.machineId;
149 case Filters.DeveloperDeviceId:
150 return this.devDeviceId;
151 case Filters.Language:
152 return platform.language;
153 case Filters.ExtensionName:
154 return 'vscode-core'; // always return vscode-core for exp service
155 case Filters.ExtensionVersion:
156 return '999999.0'; // always return a very large number for cross-extension experimentation
157 case Filters.TargetPopulation:
158 return this.targetPopulation;
159 case Filters.Platform:
160 return platform.PlatformToString(platform.platform);
161 case Filters.ReleaseDate:
162 return AssignmentFilterProvider.formatReleaseDate(this.releaseDate);
163 case Filters.WindowKind:
164 return this.windowKind;
165 default:
166 return '';
167 }
168 }
170 > private static formatReleaseDate(iso: string): string {
171 // Expect ISO format, fall back to empty string if not provided
172 if (!iso) {
173 return '';
174 }
175 // Remove separators and milliseconds: YYYY-MM-DDTHH:MM:SS.sssZ -> YYYYMMDDHH
176 // Trimmed to 10 digits to fit within int32 bounds (ExP requirement)
177 const match = /^([0-9]{4})-([0-9]{2})-([0-9]{2})T([0-9]{2})/.exec(iso);
178 if (!match) {
179 return '';
180 }
181 return match.slice(1, 5).join('');
182 }
184 > getFilters(): Map<string, unknown> {
185 const filters: Map<string, unknown> = new Map<string, unknown>();
186 const filterValues = Object.values(Filters);
187 for (const value of filterValues) {
188 filters.set(value, this.getFilterValue(value));
189 }
190
191 return filters;
192 }
194 >
195 > export function getInternalOrg(organisations: string[] | undefined): 'vscode' | 'github' | 'microsoft' | undefined {
196 const isVSCodeInternal = organisations?.includes('Visual-Studio-Code');
197 const isGitHubInternal = organisations?.includes('github');
198 const isMicrosoftInternal = organisations?.includes('microsoft') || organisations?.includes('ms-copilot') || organisations?.includes('MicrosoftCopilot');
199 return isVSCodeInternal ? 'vscode' : isGitHubInternal ? 'github' : isMicrosoftInternal ? 'microsoft' : undefined;
200 }