Skip to content

Enable SDK Stats and route to the SDK Stats ingestion endpoint#2741

Open
JacksonWeber wants to merge 26 commits into
microsoft:mainfrom
JacksonWeber:jacksonweber/enable-sdk-stats
Open

Enable SDK Stats and route to the SDK Stats ingestion endpoint#2741
JacksonWeber wants to merge 26 commits into
microsoft:mainfrom
JacksonWeber:jacksonweber/enable-sdk-stats

Conversation

@JacksonWeber

@JacksonWeber JacksonWeber commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

Summary

Re-enables the SDK Stats manager (createStatsMgr) and routes its events to the distro-owned SDK Stats ingestion endpoint used by opentelemetry-distro-dotnet, instead of piggy-backing on the customer's breeze endpoint.

Endpoints (from Azure/azure-sdk-for-net StatsbeatConstants.cs

  • Non-EU -> https://stats.monitor.azure.com/v2/track
  • EU -> https://eu.stats.monitor.azure.com/v2/track
  • Placeholder iKey 00000000-0000-0000-0000-000000000000, same Breeze envelope, no auth. EU vs non-EU chosen from the customer endpoint region.

Configurable Destination (new stats.monitor endpoint vs. legacy breeze)

The SDK Stats destination is now selectable at runtime via the CDN / dynamic config:

  • New config field config.stats (IStatsBeatConfig), overridable via the CDN / cfgSync dynamic config.
  • config.stats.mode (eStatsEndpointType): SdkStats (default) sends to stats.monitor.azure.com / eu.stats.monitor.azure.com; Breeze sends to the legacy breeze endpoint (the customer's own breeze host, using the Microsoft-owned SDK Stats iKey c4a29126… / 7dc56bab… by region).
  • The destination iKey and ingestion endpoint are resolved per-event in _track from the live config, so CDN changes take effect at runtime. A full endCfg key map (with explicit key and new url) can also be supplied via config.stats.endCfg to fully override routing.

Note: in Breeze mode the events flow through the normal channel to the customer's breeze endpoint (legacy behaviour); in SdkStats mode they bypass the customer buffer and are excluded from request counting.

Changes

  • StatsBeat.ts — SDK Stats endpoint constants, EU/non-EU region detection (getStatsEndpoint), per-event destination + placeholder-iKey stamping, enabled-by-default feature gate (opt-out via featureOptIn: "sdkStats"), createSdkStatsMgrConfig() helper, and configurable mode + key map support.
  • AppInsightsCore.ts / IAppInsightsCore.ts / index.ts — restore getStatsBeat/setStatsMgr, fields, unload cleanup, stubs, interface methods, and exports.
  • Sender.ts — restore request-counting hooks + statsBeatData; redirect SDK Stats items to the SDK Stats endpoint via a per-item URL override on _doSend/_getPayload, bypassing the customer buffer; SDK Stats sends are excluded from counting (no feedback loop); optimized property access for minification efficiency.
  • AISku.ts — create + init + set the manager after core init (kept out of core/AISKULight for bundle size).
  • IConfiguration.ts — added stats?: IStatsBeatConfig field for dynamic config.
  • StatsType.ts — added eStatsEndpointType enum (SdkStats / Breeze).
  • IStatsBeat.ts — added IStatsBeatConfig.mode and IStatsBeatKeyMap.url fields.
  • Tests — re-enabled all SDK Stats unit tests (StatsBeat.Tests.ts in both core and channel-js), fixed import paths, updated terminology from "statsbeat" to "SDK Stats" in test names and assertions.

Architecture note

createStatsMgr lives in core, which cannot depend on the channel's Breeze EnvelopeCreator. So SDK Stats events flow through _core.track() (reusing the channel's envelope creation) and the redirect to the SDK Stats endpoint happens in the Sender via a per-item endpoint override.

Verification

  • Verified with tsc --noEmit from source using the repo's exact compiler settings — core, channel, and AISKU compile with 0 errors.
  • Reviewed for minification efficiency — no spread operators, optional chaining, or nullish coalescing; optimized repeated property access.
  • Unit tests uncommented and updated with proper terminology.

Follow-ups (left for review)

  • Update bundle-size test thresholds (AISKULightSize, AppInsightsCoreSize) if needed.
  • Run npm run lint-fix + npm run fullCleanBuild before marking ready (requires environment outside VS Code due to Rush/ESLint plugin version conflicts).

Co-authored-by: Copilot 223556219+Copilot@users.noreply.github.com

JacksonWeber and others added 4 commits June 16, 2026 17:09
Completes and enables the SDK Stats manager (createStatsMgr) and routes
the resulting events to the distro-owned SDK Stats ingestion endpoint
(stats.monitor.azure.com / eu.stats.monitor.azure.com) instead of the
customer's breeze endpoint, matching the Microsoft OpenTelemetry distro.

- StatsBeat.ts: add SDK Stats endpoint constants, EU/non-EU region
  detection, per-event destination + placeholder iKey stamping,
  enabled-by-default feature gate, and createSdkStatsMgrConfig().
- AppInsightsCore / IAppInsightsCore / index: restore getStatsBeat,
  setStatsMgr, fields, unload cleanup, stubs, and exports.
- Sender.ts: restore request-counting hooks and statsBeatData; redirect
  SDK Stats items to the SDK Stats endpoint via a per-item URL override,
  bypassing the customer buffer; exclude SDK Stats sends from counting.
- AISku.ts: create, init and set the SDK Stats manager after core init.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Adds support for sending SDK Stats to either the new SDK Stats endpoint
(stats.monitor.azure.com) or the legacy breeze endpoints, selectable at
runtime via config.stats (IStatsBeatConfig), which is overridable through
the CDN / dynamic config.

- StatsType.ts: add eStatsEndpointType (SdkStats / Breeze) enum.
- IStatsBeat.ts: add IStatsBeatConfig.mode and IStatsBeatKeyMap.url.
- IConfiguration.ts: add stats?: IStatsBeatConfig (dynamic-config surface).
- StatsBeat.ts: factor EU detection into _isEuEndpoint; add
  getStatsBreezeIKey + breeze SDK Stats iKey constants; resolve the
  destination iKey/endpoint per-event in _track based on the (dynamic)
  mode; createSdkStatsMgrConfig now reads config.stats so the endpoint
  and key map can be overridden via the CDN at runtime. Defaults to the
  SDK Stats endpoint.
- index.ts: export the new enum, helper and constants.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Cache telemetryItem.data reference to avoid repeated property lookups.
Reduces minified output size in hot path (runs for every telemetry item).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Uncommented all SDK Stats test files
- Updated test case names from 'StatsBeat' to 'SDK Stats'
- Updated test assertions to use 'SDK Stats' terminology
- Fixed import paths for relocated modules
- Tests now reference the feature as 'SDK Stats' in all user-facing messages

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@JacksonWeber
JacksonWeber marked this pull request as ready for review June 17, 2026 22:43
@JacksonWeber
JacksonWeber requested a review from a team as a code owner June 17, 2026 22:43
Copilot AI review requested due to automatic review settings June 17, 2026 22:43

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

This PR re-enables the SDK Stats (StatsBeat) manager in the Application Insights JavaScript SDK and adds support for routing SDK Stats telemetry to a distro-owned ingestion endpoint (EU vs non-EU), rather than piggy-backing on the customer’s Breeze endpoint. It introduces a runtime-selectable destination mode via config/dynamic config, restores core APIs for stats manager access, and updates the Sender channel to redirect per-item sends when the SDK Stats endpoint override marker is present.

Changes:

  • Added SDK Stats endpoint + iKey resolution (EU vs non-EU), plus configurable routing mode (SDK Stats endpoint vs legacy Breeze) and per-event destination stamping.
  • Restored core APIs (getStatsBeat / setStatsMgr) and exports to support enabling SDK Stats from AISKU without increasing core bundle size.
  • Updated Sender to detect SDK Stats endpoint overrides, bypass the customer buffer for SDK Stats sends, and re-enabled associated unit tests.

Reviewed changes

Copilot reviewed 13 out of 13 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
shared/AppInsightsCore/Tests/Unit/src/aiunittests.ts Re-enabled SDK Stats unit test suite execution.
shared/AppInsightsCore/Tests/Unit/src/ai/StatsBeat.Tests.ts Re-enabled and updated core SDK Stats unit tests.
shared/AppInsightsCore/src/interfaces/ai/IStatsBeat.ts Added SDK Stats routing config surface (mode, per-keymap url).
shared/AppInsightsCore/src/interfaces/ai/IConfiguration.ts Added stats?: IStatsBeatConfig for runtime/dynamic config control.
shared/AppInsightsCore/src/interfaces/ai/IAppInsightsCore.ts Restored getStatsBeat / setStatsMgr APIs on the core interface.
shared/AppInsightsCore/src/index.ts Re-exported SDK Stats enums, interfaces, and core helper APIs/constants.
shared/AppInsightsCore/src/enums/ai/StatsType.ts Added eStatsEndpointType / StatsEndpointType for routing mode selection.
shared/AppInsightsCore/src/core/StatsBeat.ts Implemented SDK Stats endpoint/iKey resolution, routing mode support, and default manager config helper.
shared/AppInsightsCore/src/core/AppInsightsCore.ts Restored core state + lifecycle cleanup for stats manager / stats beat instance.
channels/applicationinsights-channel-js/Tests/Unit/src/StatsBeat.tests.ts Re-enabled channel-level SDK Stats tests for Sender request counting / emission.
channels/applicationinsights-channel-js/Tests/Unit/src/aichannel.tests.ts Re-enabled channel SDK Stats tests in the channel test runner.
channels/applicationinsights-channel-js/src/Sender.ts Added per-item SDK Stats endpoint override handling + direct send path, and restored request counting hooks.
AISKU/src/AISku.ts Enabled SDK Stats from AISKU after core init via createSdkStatsMgrConfig().

Comment thread channels/applicationinsights-channel-js/Tests/Unit/src/StatsBeat.tests.ts Outdated
Comment thread channels/applicationinsights-channel-js/Tests/Unit/src/StatsBeat.tests.ts Outdated
Comment thread shared/AppInsightsCore/Tests/Unit/src/ai/InternalSdkStats.Tests.ts
Comment thread shared/AppInsightsCore/Tests/Unit/src/ai/StatsBeat.Tests.ts Outdated
JacksonWeber and others added 6 commits June 18, 2026 13:47
- Initialize the core before init-ing the stats manager against the same core instance so the manager actually enables (channel + core tests)
- Match the stats endCfg to the Sender's endpoint so metrics are tracked
- Pass an IStatsBeatState to getStatsBeat() when wiring the count spy
- Fix the xhr test config built with '&&' that discarded the Sender config
- Guard the dynamic-config test against double core initialization

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
IConfiguration exposes 'stats' (IStatsBeatConfig) at the top level, not under a '_sdk' wrapper. Update the SDK Stats unit tests to set config.stats and read cfg.stats so they compile against IConfiguration.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…size budget

- Tick the real short interval (shrtInt*1000 ms) so the stats timer fires in the count/countException tests
- FeatureOptInMode.none and a null mode fall back to the SDK default (enabled), so assert SDK Stats stays enabled rather than being removed
- Bump core size budget to 135 KB raw / 55 KB deflate to cover the re-enabled getStatsBeat/setStatsMgr core APIs (was 133/54)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The 'SDK Stats initializes when stats is true' test initialized the stats manager but never called core.setStatsMgr(), so core.getStatsBeat() returned null. Register the manager with the core so the instance is created.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Enabling SDK Stats from AISKU pulls in the re-enabled core getStatsBeat/setStatsMgr APIs and stats manager wiring, growing the AISKU bundle. Bump the budget to 178 KB / 72 KB deflate (was 175/71).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Comment thread shared/AppInsightsCore/src/core/StatsBeat.ts Outdated
JacksonWeber and others added 4 commits June 26, 2026 10:39
…-sdk-stats

# Conflicts:
#	AISKU/Tests/Unit/src/AISKUSize.Tests.ts
#	AISKU/src/AISku.ts
#	channels/applicationinsights-channel-js/src/Sender.ts
#	shared/AppInsightsCore/Tests/Unit/src/ai/AppInsightsCoreSize.Tests.ts
#	shared/AppInsightsCore/src/index.ts
The new SDK Stats code in AppInsightsCore pushes the core bundle past
its 135 KB budget and the AISKU bundle past its 178 KB / 72 KB budgets.
Bump core to 137 KB and AISKU to 181 KB / 73 KB to match measured sizes.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…g support

Replace the detached config snapshot in createSdkStatsMgrConfig with the
setDf/ref pattern so SDK Stats defaults live in the single global config
(overridable via CDN/dynamic config and the SKUs) and runtime changes are
tracked. Updates IStatsMgrConfig.getCfg to receive IWatchDetails.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…g refactor

The setDf/ref refactor in createSdkStatsMgrConfig pushes the core deflate
size just past 55 KB (55.01 KB) and the AISKU deflate budget; bump core
deflate 55 -> 56 KB and AISKU deflate 73 -> 74 KB to match.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@JacksonWeber
JacksonWeber requested a review from MSNev June 29, 2026 21:33
…g from the global config

The SDK Stats manager now references the single global config (config.stats) directly and picks up dynamic/CDN changes at runtime, gated behind the sdkStats feature flag (enabled by default, opt-out via featureOptIn). Removes the createSdkStatsMgrConfig factory and IStatsMgrConfig interface; init is now init(core, featureName?). Updates AISKU and StatsBeat tests accordingly.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

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

Copilot reviewed 16 out of 16 changed files in this pull request and generated 2 comments.

Comment thread shared/AppInsightsCore/src/core/StatsBeat.ts Outdated
Comment thread shared/AppInsightsCore/Tests/Unit/src/ai/StatsBeat.Tests.ts
Comment thread shared/AppInsightsCore/src/core/StatsBeat.ts Outdated
import { INetworkStatsbeat } from "../interfaces/ai/INetworkStatsbeat";
import { IStatsBeat, IStatsBeatConfig, IStatsBeatState, IStatsEndpointConfig } from "../interfaces/ai/IStatsBeat";
import { IStatsMgr, IStatsMgrConfig } from "../interfaces/ai/IStatsMgr";
import { IStatsBeat, IStatsBeatConfig, IStatsBeatKeyMap, IStatsBeatState, IStatsEndpointConfig } from "../interfaces/ai/IStatsBeat";

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

We should rename all of the "StatsBeat" to SdkStats something that represents that this is the internal SdkStats (as we already have the customer SdkStats using sdkStats...

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Changed to InternalSdkStats. Doesn't look like it impacted bundle sizes negatively, but let me know what you think.

Comment thread shared/AppInsightsCore/src/core/StatsBeat.ts Outdated
Comment thread shared/AppInsightsCore/src/core/StatsBeat.ts Outdated
Comment thread shared/AppInsightsCore/src/core/InternalSdkStats.ts Outdated
Comment thread shared/AppInsightsCore/src/interfaces/ai/IInternalSdkStats.ts Outdated
Comment thread shared/AppInsightsCore/src/core/AppInsightsCore.ts Outdated
Comment thread shared/AppInsightsCore/src/core/AppInsightsCore.ts Outdated
JacksonWeber and others added 9 commits July 17, 2026 10:29
Instead of embedding the ingestion URL, fetch the runtime SDK Stats config
(data.stats.monitor.azure.com / eu-data.stats.monitor.azure.com cfg/v1.json),
check the enabled flag, and route events to the returned url + /v2/track when
enabled. Adds the OneCollector path constant as scaffolding for future 1DS.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Eliminate the legacy 'StatsBeat' name in favor of 'Internal SDK Stats' to
distinguish it from the customer-facing SdkStats feature. Interfaces, types,
enum members, locals and private functions rename freely (erased or mangled);
the two surviving property names were shortened (getStatsBeat -> getSdkStats,
statsBeatData -> statsData), so the minified bundle size is unchanged.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…tination

Remove the breeze-endpoint mode and key-map/endCfg routing so SDK Stats
collection is gated solely on the remote cfg enabled flag and sent to the
cfg-provided host. Parsing is fail-closed (enabled === true, url must be a
string).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…d config + ref()

Address PR review: drop the persistent _internalSdkStatsConfig field and the
details.ref() hack. Copy the override fetch fn and interval into local vars in
the config-change handler, making the override fetch fn a dynamic leaf so merged
runtime updates still re-run the handler. Seed the stats default via a plain
object (not cfgDfMerge) so setDf no longer marks stats as a reference.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Address PR review: the setDf cast was only needed because the generic CfgType
propagated into onConfigChange. Pin onConfigChange to IConfiguration (we only
touch IConfiguration-level config) so setDf infers IConfiguration and the cast
is no longer required.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The type field was never read for logic (getSdkStats isolates instances
by endpoint, not type) and customer stats are handled separately via
createSdkStatsNotifCbk, so the enum is no longer needed.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…zipped)

Refactor InternalSdkStats and SdkStatsNotificationCbk to shrink the core
minified bundle: objForEachKey merge, shared count/inc helpers, hoisted
repeated string literals, arrIndexOf for EU lookup, reuse MetricDataType.

Core min.js: raw 139595 -> 139218 (-377 B), gzip 56693 -> 56566 (-127 B).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Comment thread shared/AppInsightsCore/src/core/SdkStatsNotificationCbk.ts Fixed
JacksonWeber and others added 2 commits July 21, 2026 13:04
testCleanup nulled the initialized AppInsightsCore without unloading it,
leaking hooks/timers/config watchers into subsequent tests. Call
core.unload(false) when initialized, matching the core test convention.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Revert the _incCounts extraction so success/bucket counts assign directly
to their objCreate(null) counters. The extracted target parameter hid the
null-prototype provenance, causing CodeQL js/prototype-polluting-assignment
to flag target[t]. Direct assignment restores the safe-sink recognition.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

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

Copilot reviewed 27 out of 27 changed files in this pull request and generated 3 comments.

}

/** Default SDK Stats config fetch (fetch, else XHR); calls oncomplete with the parsed config or null. */
function _defaultStatsCfgFetch(cfgUrl: string, oncomplete: (result: IInternalSdkStatsCfgResult) => void): void {
Comment on lines 1129 to 1136
if (isArray(payload) && payload.length > 0) {
let batch = _self._buffer.batchPayloads(payload);
let headers = _getHeaders();
let payloadData: IInternalPayloadData = {
data: batch,
urlString: _endpointUrl,
urlString: urlOverride || _endpointUrl,
headers: headers,
disableXhrSync: _disableXhr,
timeout: 0,
disableXhrSync: false,
statsData: {
startTime: "2023-10-01T00:00:00Z" // Simulated start time
* gate collection and resolve the ingestion host. EU endpoint is used for EU data-boundary regions.
*/
export const STATS_SDK_CFG_URL_NON_EU = "https://data.stats.monitor.azure.com/cfg/v1.json";
export const STATS_SDK_CFG_URL_EU = "https://eu-data.stats.monitor.azure.com/cfg/v1.json";

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

We should minimize the duplication here as strings can't be compressed.
We should have a
const scheme = "https://";
const baseUrl = "data.stats.monitor.azure.com/cfg/v1.json";
and then create the above from these :-)

* The placeholder instrumentation key used when reporting SDK statistics to the distro-owned
* SDK Stats ingestion endpoint. The endpoint does not require authentication, the placeholder
* key only satisfies the connection-string / envelope iKey requirement and is ignored
* server-side. This matches the convention used by the Microsoft OpenTelemetry distros.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

"ignored server-side" is not always true.

If the config returns breeze as the URL then no stats will be collected, so we should not send any telemetry (regardless of the backend) without a instrumentation key -- this can be in the config and we can have dynamic config provide / replace the value.

import { getResponseText, isFeatureEnabled, openXhr } from "../utils/HelperFuncs";

const STATS_COLLECTION_SHORT_INTERVAL: number = 900000; // 15 minutes
const STATS_MIN_INTERVAL_SECONDS = 60; // 1 minute

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Do we really want to send the events every minute (assuming the SDK is actively sending data)?
I believe that .Net only sends every 30/60 minutes...
Which means we would need to cache this in session / local storage or something.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Let's discuss this further, my understanding was that we can't expect the session to live that long so lowering the timing threshold would give us a better chance of collecting telemetry. Let's discuss further in the meeting Monday.

export const STATS_SDK_FEATURE = "sdkStats";

// EU data-boundary regions, mirrors the EU region set used by the Azure Monitor OpenTelemetry exporter
const STATS_EU_REGIONS = [

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

We can probably reduce this eg.
"france" vs "francecentral", "francesouth" etc.

or we extract the duplicate portions "south", "central", "east", "west" and the countries and then create the merge strings within the array.

* Returns the SDK Stats config URL (`cfg/v1.json`) for the endpoint (EU vs non-EU).
*/
export function getStatsCfgUrl(endpoint: string): string {
return _isEuEndpoint(endpoint) ? STATS_SDK_CFG_URL_EU : STATS_SDK_CFG_URL_NON_EU;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

We should cache the "endpoint" resolution to avoid running the _isEuEndpoint for every time _track is called.

"language": STATS_LANGUAGE,
"version": internalSdkStatsStats.sdkVer || "unknown",
"endpoint": "breeze",
"host": _networkCounter.host

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Some additional properties that are web specific that would be good to have reported as part of the SDK Stats is whether the SDK was loaded via the snippet and what version ( ai.context.internal.snippetVer``) and if it was loaded via CDN or npm (ai.context.internal.sdkSrc<- the CDN name it was loaded from) Set via the_findSdkSourceFile()` in AISku.ts (not currently setfor 1DS) -- we just have not have anywhere to report this before

@JacksonWeber JacksonWeber Jul 25, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

That's a great idea. Happy to brainstorm some more values that we could pass here. I can propose a spec PR for SDK Stats from there. How would you feel about that coming as a part of a follow up PR since any change should be additive?

internalSdkStatsEvent.data = internalSdkStatsEvent.data || {};
internalSdkStatsEvent.data[STATS_SDK_ENDPOINT_KEY] = url;

_core.track(internalSdkStatsEvent);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I don't think this is going to work??

As it looks like you are passing in the core from the AISku instance (which is the users configured instance), which will be batched and sent to the users endpoint (channel control).

It also means that when the end-users have their own telemetry initializers attached to the core to add / remove properties they may add / remove PII to the internal SDK events, also if they have not written their initializer correctly (they expect fields / properties that don't exist for a metric (the sdk stats event) it could cause an unhandled JavaScript exception. And I've seen some sites throw a complete page load failure error (causing their site to be declared "offline") on any unhandled exception.

While we need the root _core instance to monitor it for any changed config (loaded via the dynamic config or users changes their endpoint url), we should create instance and initialize our own instance of the SDK configured with the cfg.json endpoint.

which means that the init function should have an additional callback to support the creating of the SDK Instance (as not everyone uses core, properties and sender), so that for the main operation (SKU) we can control what is included (so AISku Lite there is no properties, for 1DS there is no Sender or AI Properties, so the SKU's in 1DS have to initialize themselves) etc.

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.

4 participants