{"id":15897,"library":"vscode-tas-client","title":"VS Code Treatment Assignment Service (TAS) Client","description":"The `vscode-tas-client` package facilitates A/B experimentation within Visual Studio Code extensions by providing an interface to query and store experiment information from the Microsoft Treatment Assignment Service (TAS). As of version 0.1.86, it is specifically designed for integration with VS Code's extension host environment, leveraging `vscode.Memento` for caching experiment data and `IExperimentationTelemetry` for structured telemetry reporting, including GDPR-classified counterfactual logging. The package manages background refreshes of treatment variables every 30 minutes and offers both synchronous and asynchronous methods for service initialization and variable retrieval, allowing extensions to control data freshness and startup performance. Its core differentiation lies in its tight integration with the VS Code ecosystem, handling aspects like user population targeting, telemetry, and persistence seamlessly for extension developers. The release cadence is typically tied to internal Microsoft development cycles, often aligning with VS Code's own updates.","status":"active","version":"0.1.86","language":"javascript","source_language":"en","source_url":null,"tags":["javascript","vscode-tas-client","typescript"],"install":[{"cmd":"npm install vscode-tas-client","lang":"bash","label":"npm"},{"cmd":"yarn add vscode-tas-client","lang":"bash","label":"yarn"},{"cmd":"pnpm add vscode-tas-client","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"Initializes the experimentation service synchronously. For most cases, `getExperimentationServiceAsync` is preferred to ensure cached data is loaded.","wrong":"const getExperimentationService = require('vscode-tas-client').getExperimentationService;","symbol":"getExperimentationService","correct":"import { getExperimentationService } from 'vscode-tas-client';"},{"note":"Asynchronous initialization; recommended as it awaits the internal `initializePromise` to ensure cached experiment data is loaded before the service instance is returned.","wrong":"const getExperimentationServiceAsync = require('vscode-tas-client').getExperimentationServiceAsync;","symbol":"getExperimentationServiceAsync","correct":"import { getExperimentationServiceAsync } from 'vscode-tas-client';"},{"note":"TypeScript interface representing the experimentation service instance, providing methods like `getTreatmentVariable`.","wrong":"import IExperimentationService from 'vscode-tas-client';","symbol":"IExperimentationService","correct":"import { IExperimentationService } from 'vscode-tas-client';"},{"note":"An enum used to specify the target user ring (e.g., `TargetPopulation.Public`, `TargetPopulation.Insiders`).","wrong":"const TargetPopulation = require('vscode-tas-client').TargetPopulation;","symbol":"TargetPopulation","correct":"import { TargetPopulation } from 'vscode-tas-client';"},{"note":"TypeScript interface for the telemetry service, which must be implemented and passed during service initialization to enable experiment analysis and counterfactual logging.","wrong":"type IExperimentationTelemetry = any;","symbol":"IExperimentationTelemetry","correct":"import { IExperimentationTelemetry } from 'vscode-tas-client';"}],"quickstart":{"code":"import * as vscode from 'vscode';\nimport {\n  getExperimentationServiceAsync,\n  TargetPopulation,\n  IExperimentationService,\n  IExperimentationTelemetry,\n} from 'vscode-tas-client';\n\n// A mock implementation for IExperimentationTelemetry to satisfy the interface.\n// In a real extension, you would likely use VS Code's built-in telemetry reporter.\nclass MockTelemetry implements IExperimentationTelemetry {\n  public commonProperties: Record<string, string> = {};\n\n  setCommonProperties(properties: Record<string, string>): void {\n    this.commonProperties = { ...this.commonProperties, ...properties };\n  }\n\n  postEvent(eventName: string, props?: Record<string, any>): void {\n    console.log(`Telemetry Event: ${eventName}`, { ...this.commonProperties, ...props });\n  }\n\n  dispose(): void {\n    // No-op for mock telemetry\n  }\n}\n\nexport async function activate(context: vscode.ExtensionContext) {\n  console.log('Extension \"my-experiment-extension\" is active!');\n\n  const extensionName = 'my-experiment-extension';\n  const extensionVersion = '1.0.0';\n  // Determine the target population based on user settings or environment\n  const targetPopulation = process.env.VSCODE_INSIDERS === 'true' ? TargetPopulation.Insiders : TargetPopulation.Public;\n  const telemetry = new MockTelemetry();\n  const memento = context.globalState;\n\n  let experimentationService: IExperimentationService;\n\n  try {\n    // Initialize the experimentation service asynchronously to ensure cached data is loaded.\n    experimentationService = await getExperimentationServiceAsync(\n      extensionName,\n      extensionVersion,\n      targetPopulation,\n      telemetry,\n      memento\n    );\n    console.log('Experimentation service initialized.');\n\n    // Query a treatment variable. 'vscode' is the standard configId.\n    const myFeatureToggleValue = experimentationService.getTreatmentVariable('vscode', 'myFeatureToggle');\n    console.log(`Value for 'myFeatureToggle': ${myFeatureToggleValue}`);\n\n    // If you need to force a refresh and get the very latest value from TAS,\n    // use getTreatmentVariableAsync. This will trigger a network request.\n    const latestMyFeatureToggleValue = await experimentationService.getTreatmentVariableAsync('vscode', 'myFeatureToggle');\n    console.log(`Latest value for 'myFeatureToggle' after refresh: ${latestMyFeatureToggleValue}`);\n\n  } catch (error) {\n    console.error('Failed to initialize experimentation service:', error);\n  }\n}\n\n// Standard VS Code extension deactivate function.\nexport function deactivate() {\n  console.log('Extension \"my-experiment-extension\" is deactivating!');\n}","lang":"typescript","description":"This quickstart initializes the `vscode-tas-client` experimentation service within a VS Code extension's `activate` function and demonstrates how to retrieve treatment variable values, including forcing a refresh for the latest data. It also includes a mock telemetry implementation."},"warnings":[{"fix":"Always prefer `getExperimentationServiceAsync` for initial service acquisition. This method awaits the internal `initializePromise`, ensuring cached data is loaded before the service is used for querying treatment variables.","message":"Using `getExperimentationService` (synchronous) instead of `getExperimentationServiceAsync` for initial service acquisition might lead to experiment values not being immediately available from cache, potentially serving default values until a background refresh or manual initialization completion. This can result in users not being assigned to the correct experiment group on first run.","severity":"gotcha","affected_versions":">=0.1.0"},{"fix":"To explicitly force a refresh and retrieve the very latest treatment variable value from the TAS, use `await experimentationService.getTreatmentVariableAsync(configId, name)`. Be mindful that this might cause a network request and could alter the user experience mid-session.","message":"Subsequent calls to `experimentationService.getTreatmentVariable(configId, name)` within the same user session will consistently return the *cached* value obtained during the first call or initialization. This design choice prevents unexpected mid-session user experience changes, even if a background refresh has occurred and new values are available in the cache.","severity":"gotcha","affected_versions":">=0.1.0"},{"fix":"Ensure that the VS Code process (and by extension, the extension host) has appropriate network access to reach the TAS endpoints. For testing scenarios that require offline operation, consider mocking the `IExperimentationService`.","message":"The `vscode-tas-client` package makes HTTP requests to the TAS server initially upon service acquisition and then periodically every 30 minutes for background refreshes. Extensions operating in environments with strict network policies, offline modes, or limited connectivity should account for this network activity.","severity":"gotcha","affected_versions":">=0.1.0"},{"fix":"Develop and use this package exclusively within a VS Code extension. For unit testing, mock the `vscode.Memento` and `IExperimentationTelemetry` interfaces to simulate the VS Code environment.","message":"This package is specifically designed for use within the VS Code extension host environment. It relies heavily on VS Code API objects like `vscode.Memento` (via `context.globalState`) and expects an `IExperimentationTelemetry` implementation. Attempting to use it in a standalone Node.js application, browser, or other non-VS Code contexts will lead to runtime errors.","severity":"gotcha","affected_versions":">=0.1.0"}],"env_vars":null,"last_verified":"2026-04-21T00:00:00.000Z","next_check":"2026-07-20T00:00:00.000Z","problems":[{"fix":"Ensure your extension's `activate` function correctly receives `vscode.ExtensionContext` and that `context.globalState` is passed as the `memento` argument to the experimentation service initialization function.","cause":"The `memento` argument passed to `getExperimentationService` or `getExperimentationServiceAsync` was `undefined` or not a valid `vscode.Memento` instance. This typically occurs when the package is used outside of a VS Code extension's `activate` context or `context.globalState` is not properly provided.","error":"TypeError: Cannot read properties of undefined (reading 'globalState')"},{"fix":"Always use `await getExperimentationServiceAsync(...)` to get the service instance. Ensure you are calling `getTreatmentVariableAsync` on the `IExperimentationService` instance, not a raw promise or an uninitialized object. Verify your package version supports the async method.","cause":"Attempting to call `getTreatmentVariableAsync` on an `IExperimentationService` instance that was not properly awaited during its acquisition, or attempting to use `getTreatmentVariableAsync` on an outdated version of the service.","error":"TypeError: experimentationService.getTreatmentVariableAsync is not a function"},{"fix":"Verify that `getExperimentationServiceAsync` was used for initialization. Check network connectivity to TAS and ensure your `extensionName`, `extensionVersion`, and `targetPopulation` are correctly configured, as these are used for traffic filtering.","cause":"The telemetry event `query-expfeature` is sent, but the associated common properties (`vscode.abexp.features` or `abexp.assignmentcontext`) or the expected treatment variable values are missing or are default values, indicating the experiment data was not successfully loaded.","error":"Telemetry Event: query-expfeature {...} (but no expected experiment data)"}],"ecosystem":"npm"}