Skip to content

fix(typespec-ts): simplify SDK User-Agent telemetry prefix#4817

Open
lirenhe wants to merge 5 commits into
mainfrom
js-useragent-update
Open

fix(typespec-ts): simplify SDK User-Agent telemetry prefix#4817
lirenhe wants to merge 5 commits into
mainfrom
js-useragent-update

Conversation

@lirenhe

@lirenhe lirenhe commented Jul 6, 2026

Copy link
Copy Markdown
Member

Fixes #4774

Simplify the generated SDK User-Agent telemetry prefix to follow the Azure Core telemetry policy.

Problem

Generated modular clients emit a stacked User-Agent such as:

azsdk-js-client azsdk-js-api azsdk-js-ai-projects/2.0.0-beta.4 core-rest-pipeline/1.22.2 Node/22.14.0 (...)

The azsdk-js-client and azsdk-js-api tokens were added in autorest.typescript#2616 to distinguish the classic-client / modular-API / REST layers. They are not real packages, carry no /version, and do not match the policy format azsdk-<lang>-<package>/<version> — confusing downstream service teams (#4774).

Change

  • client-helpers.ts buildUserAgentOptions now builds the prefix from azsdk-js-<package>/<version> only (plus any caller-supplied application id); dropped the static token and the .includes("api") gate. Returns no override when package name/version is unavailable.
  • build-classical-client.ts forwards options untouched, so the application id still flows down and is prepended exactly once.

Resulting User-Agent:

[<application_id> ]azsdk-js-<package>/<version> core-rest-pipeline/x Node/y (...)

Validation

  • pnpm build clean; modular unit suite passing.
  • New test/modular-unit/userAgent.test.ts covers the azsdk-js-<pkg>/<version> output, application-id forwarding, and the no-package fallback.
  • Updated 10 modular-unit scenario snapshots.

Note

The @azure/ai-projects team already ships a scripts/post-emitter.mjs that strips these tokens as a workaround; this emitter fix makes such workarounds redundant.

Follow the Azure Core telemetry policy by removing the legacy internal
layering tokens `azsdk-js-client` and `azsdk-js-api` from the generated
User-Agent. The prefix is now `[<application_id> ]azsdk-js-<package>/<version>`.
Any caller-supplied application id is still forwarded and prepended.

Fixes #4774

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

Copy link
Copy Markdown
Contributor

All changed packages have been documented.

  • @azure-tools/typespec-ts
Show changes

@azure-tools/typespec-ts - fix ✏️

Simplify the generated SDK User-Agent telemetry prefix to follow the Azure Core telemetry policy. The legacy internal layering tokens azsdk-js-client and azsdk-js-api are no longer emitted, so the user agent is now [<application_id> ]azsdk-js-<package>/<version> <platform_info>. Any caller-supplied application id is still forwarded and prepended.

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

Copy link
Copy Markdown
Contributor

You can try these changes here

🛝 Playground 🌐 Website

@pkg-pr-new

pkg-pr-new Bot commented Jul 6, 2026

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/@azure-tools/typespec-ts@4817

commit: cef5608

@github-actions

github-actions Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

⚡ Benchmark Results

⚠️ 23 metric(s) regressed above the +5% threshold:

Metric Baseline Current Change
total 🔴 969.5ms 🔴 1.06s +9.0% 🔴
loader 🟡 292.3ms 🟡 325.6ms +11.4% 🔴
checker 🟡 349.1ms 🟡 379.1ms +8.6% 🔴
validation 🟢 82.8ms 🟢 88.0ms +6.3% 🔴
 ↳ validation/@azure-tools/typespec-azure-core 🟡 12.1ms 🟡 13.4ms +11.2% 🔴
 ↳ validation/@typespec/http 🟡 14.9ms 🟡 16.3ms +9.1% 🔴
linter 🟡 206.3ms 🟡 224.1ms +8.6% 🔴
 ↳ linter/@azure-tools/typespec-azure-core/no-header-explode 🔴 25.5ms 🔴 28.4ms +11.5% 🔴
 ↳ linter/@azure-tools/typespec-azure-core/no-query-explode 🔴 26.7ms 🔴 29.6ms +11.0% 🔴
 ↳ linter/@azure-tools/typespec-azure-core/no-response-body 🔴 32.0ms 🔴 34.2ms +7.0% 🔴
 ↳ linter/@azure-tools/typespec-azure-core/response-schema-problem 🔴 31.3ms 🔴 34.2ms +9.2% 🔴
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-agent-base-type-child-resources 🔴 20.2ms 🔴 22.7ms +12.2% 🔴
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-common-types-version 🟡 11.6ms 🟡 12.8ms +9.9% 🔴
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-no-path-casing-conflicts 🟡 16.5ms 🟡 18.1ms +9.8% 🔴
 ↳ linter/@azure-tools/typespec-azure-resource-manager/lro-location-header 🟡 18.8ms 🔴 20.7ms +10.4% 🔴
 ↳ linter/@azure-tools/typespec-azure-resource-manager/no-response-body 🔴 28.5ms 🔴 31.3ms +10.1% 🔴
emit 🔴 5.87s 🔴 6.25s +6.5% 🔴
 ↳ emit/@azure-tools/typespec-autorest 🟢 120.4ms 🟢 128.4ms +6.6% 🔴
 ↳ emit/@azure-tools/typespec-python 🔴 2.19s 🔴 2.34s +6.5% 🔴
 ↳ emit/@typespec/http-client-js 🔴 552.2ms 🔴 586.4ms +6.2% 🔴
 ↳ emit/@typespec/openapi3 🟢 103.4ms 🟢 111.7ms +8.0% 🔴
 ↳ emit/@typespec/openapi3/compute 🟢 89.7ms 🟢 97.0ms +8.1% 🔴
 ↳ emit/@typespec/openapi3/write 🟢 13.4ms 🟢 14.4ms +7.5% 🔴
Full details – comparing 5db8c7d vs baseline rolling-baseline-609e362-a18f78b (rolling baseline (20 main runs))
Metric Baseline Current Change
total 🔴 969.5ms 🔴 1.06s +9.0% 🔴
loader 🟡 292.3ms 🟡 325.6ms +11.4% 🔴
resolver 🟢 38.9ms 🟢 40.3ms +3.6%
checker 🟡 349.1ms 🟡 379.1ms +8.6% 🔴
validation 🟢 82.8ms 🟢 88.0ms +6.3% 🔴
 ↳ validation/@azure-tools/typespec-azure-core 🟡 12.1ms 🟡 13.4ms +11.2% 🔴
 ↳ validation/@typespec/http 🟡 14.9ms 🟡 16.3ms +9.1% 🔴
 ↳ validation/@typespec/rest 🟢 1.6ms 🟢 1.7ms +6.7%
 ↳ validation/@typespec/versioning 🔴 50.3ms 🔴 52.6ms +4.7%
 ↳ validation/compiler 🟢 3.8ms 🟢 3.9ms +4.3%
linter 🟡 206.3ms 🟡 224.1ms +8.6% 🔴
 ↳ linter/@azure-tools/typespec-azure-core/auth-required 🟢 0.1ms 🟢 0.1ms +9.6%
 ↳ linter/@azure-tools/typespec-azure-core/bad-record-type 🟢 0.6ms 🟢 0.6ms +1.3%
 ↳ linter/@azure-tools/typespec-azure-core/byos 🟢 8.0ms 🟢 8.5ms +6.0%
 ↳ linter/@azure-tools/typespec-azure-core/casing-style 🟢 1.4ms 🟢 1.5ms +5.0%
 ↳ linter/@azure-tools/typespec-azure-core/composition-over-inheritance 🟢 0.2ms 🟢 0.2ms +5.0%
 ↳ linter/@azure-tools/typespec-azure-core/documentation-required 🟢 1.9ms 🟢 2.0ms +6.4%
 ↳ linter/@azure-tools/typespec-azure-core/friendly-name 🟢 1.4ms 🟢 1.4ms +5.1%
 ↳ linter/@azure-tools/typespec-azure-core/key-visibility-required 🟢 0.4ms 🟢 0.4ms +7.4%
 ↳ linter/@azure-tools/typespec-azure-core/known-encoding 🟢 0.5ms 🟢 0.5ms +12.0%
 ↳ linter/@azure-tools/typespec-azure-core/long-running-polling-operation-required 🟢 0.8ms 🟢 0.8ms +5.0%
 ↳ linter/@azure-tools/typespec-azure-core/no-case-mismatch 🟢 0.7ms 🟢 0.7ms +4.7%
 ↳ linter/@azure-tools/typespec-azure-core/no-closed-literal-union 🟢 1.0ms 🟢 1.0ms +3.4%
 ↳ linter/@azure-tools/typespec-azure-core/no-enum 🟢 0.2ms 🟢 0.3ms +6.8%
 ↳ linter/@azure-tools/typespec-azure-core/no-error-status-codes 🟢 0.3ms 🟢 0.3ms +4.6%
 ↳ linter/@azure-tools/typespec-azure-core/no-explicit-routes-resource-ops 🟢 0.2ms 🟢 0.2ms +6.8%
 ↳ linter/@azure-tools/typespec-azure-core/no-format 🟢 0.8ms 🟢 0.8ms +4.3%
 ↳ linter/@azure-tools/typespec-azure-core/no-generic-numeric 🟢 0.8ms 🟢 0.8ms +4.5%
 ↳ linter/@azure-tools/typespec-azure-core/no-header-explode 🔴 25.5ms 🔴 28.4ms +11.5% 🔴
 ↳ linter/@azure-tools/typespec-azure-core/no-legacy-usage 🟢 1.9ms 🟢 2.2ms +11.3%
 ↳ linter/@azure-tools/typespec-azure-core/no-multiple-discriminator 🟢 0.2ms 🟢 0.3ms +15.0%
 ↳ linter/@azure-tools/typespec-azure-core/no-nullable 🟢 0.4ms 🟢 0.4ms +6.8%
 ↳ linter/@azure-tools/typespec-azure-core/no-offsetdatetime 🟢 1.9ms 🟢 2.0ms +8.3%
 ↳ linter/@azure-tools/typespec-azure-core/no-openapi 🟢 2.3ms 🟢 2.3ms +2.9%
 ↳ linter/@azure-tools/typespec-azure-core/no-private-usage 🟢 3.0ms 🟢 3.2ms +8.4%
 ↳ linter/@azure-tools/typespec-azure-core/no-query-explode 🔴 26.7ms 🔴 29.6ms +11.0% 🔴
 ↳ linter/@azure-tools/typespec-azure-core/no-response-body 🔴 32.0ms 🔴 34.2ms +7.0% 🔴
 ↳ linter/@azure-tools/typespec-azure-core/no-rest-library-interfaces 🟢 0.1ms 🟢 0.1ms +9.3%
 ↳ linter/@azure-tools/typespec-azure-core/no-route-parameter-name-mismatch 🟢 7.3ms 🟢 8.0ms +9.8%
 ↳ linter/@azure-tools/typespec-azure-core/no-rpc-path-params 🟢 0.4ms 🟢 0.4ms +6.6%
 ↳ linter/@azure-tools/typespec-azure-core/no-string-discriminator 🟢 0.1ms 🟢 0.2ms +10.6%
 ↳ linter/@azure-tools/typespec-azure-core/no-unknown 🟢 0.3ms 🟢 0.4ms +9.0%
 ↳ linter/@azure-tools/typespec-azure-core/no-unnamed-union 🟢 0.8ms 🟢 0.8ms +4.3%
 ↳ linter/@azure-tools/typespec-azure-core/operation-missing-api-version 🟢 0.4ms 🟢 0.4ms +1.6%
 ↳ linter/@azure-tools/typespec-azure-core/request-body-problem 🟢 0.4ms 🟢 0.5ms +2.6%
 ↳ linter/@azure-tools/typespec-azure-core/require-versioned 🟢 0.1ms 🟢 0.1ms +9.4%
 ↳ linter/@azure-tools/typespec-azure-core/response-schema-problem 🔴 31.3ms 🔴 34.2ms +9.2% 🔴
 ↳ linter/@azure-tools/typespec-azure-core/rpc-operation-request-body 🟢 0.7ms 🟢 0.7ms +8.8%
 ↳ linter/@azure-tools/typespec-azure-core/spread-discriminated-model 🟢 0.4ms 🟢 0.5ms +8.1%
 ↳ linter/@azure-tools/typespec-azure-core/use-standard-names 🟢 7.3ms 🟢 8.0ms +8.8%
 ↳ linter/@azure-tools/typespec-azure-core/use-standard-operations 🟢 0.2ms 🟢 0.3ms +5.2%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-agent-base-type-child-resources 🔴 20.2ms 🔴 22.7ms +12.2% 🔴
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-agent-base-type-lifecycle-operations 🟢 0.2ms 🟢 0.3ms +4.0%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-common-types-version 🟡 11.6ms 🟡 12.8ms +9.9% 🔴
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-custom-resource-no-key 🟢 0.2ms 🟢 0.2ms +10.8%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-custom-resource-usage-discourage 🟢 0.1ms 🟢 0.1ms +5.8%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-delete-operation-response-codes 🟢 5.4ms 🟢 4.4ms -18.3%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-no-path-casing-conflicts 🟡 16.5ms 🟡 18.1ms +9.8% 🔴
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-no-record 🟢 0.6ms 🟢 0.6ms +6.1%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-post-operation-response-codes 🟢 1.4ms 🟢 1.4ms +1.4%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-put-operation-response-codes 🟢 0.2ms 🟢 0.2ms -4.6%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-action-no-segment 🟢 0.4ms 🟢 0.4ms +5.2%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-duplicate-property 🟢 0.4ms 🟢 0.4ms +9.9%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-interface-requires-decorator 🟢 0.1ms 🟢 0.1ms +6.1%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-invalid-action-verb 🟢 0.2ms 🟢 0.2ms +4.1%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-invalid-envelope-property 🟢 0.3ms 🟢 0.3ms +10.4%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-invalid-version-format 🟢 0.2ms 🟢 0.2ms +2.8%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-key-invalid-chars 🟢 0.5ms 🟢 0.5ms +13.6%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-name-pattern 🟢 0.1ms 🟢 0.1ms +0.8%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-operation 🟢 0.5ms 🟢 0.6ms +10.5%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-operation-response 🟢 8.5ms 🟢 9.1ms +6.0%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-patch 🟢 0.8ms 🟢 0.8ms +2.6%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-path-segment-invalid-chars 🟢 0.4ms 🟢 0.4ms +5.0%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-provisioning-state 🟢 0.4ms 🟢 0.4ms +5.0%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/beyond-nesting-levels 🟢 0.2ms 🟢 0.2ms +13.4%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/empty-updateable-properties 🟢 0.4ms 🟢 0.4ms +10.3%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/improper-subscription-list-operation 🟢 0.1ms 🟢 0.1ms +0.9%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/lro-location-header 🟡 18.8ms 🔴 20.7ms +10.4% 🔴
 ↳ linter/@azure-tools/typespec-azure-resource-manager/missing-operations-endpoint 🟢 0.1ms 🟢 0.1ms +8.8%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/missing-x-ms-identifiers 🟢 1.0ms 🟢 1.0ms +0.0%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/no-empty-model 🟢 0.2ms 🟢 0.3ms +12.6%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/no-override-props 🟢 0.3ms 🟢 0.3ms +5.6%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/no-resource-delete-operation 🟢 0.4ms 🟢 0.5ms +13.1%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/no-response-body 🔴 28.5ms 🔴 31.3ms +10.1% 🔴
 ↳ linter/@azure-tools/typespec-azure-resource-manager/patch-envelope 🟢 0.4ms 🟢 0.4ms +10.5%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/resource-name 🟢 0.4ms 🟢 0.5ms +6.0%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/secret-prop 🟢 5.2ms 🟢 5.5ms +6.0%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/unsupported-type 🟢 0.7ms 🟢 0.7ms +5.5%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/version-progression 🟢 0.3ms 🟢 0.3ms -0.8%
 ↳ linter/@azure-tools/typespec-client-generator-core/property-name-conflict 🟢 2.2ms 🟢 2.4ms +8.3%
 ↳ linter/@azure-tools/typespec-client-generator-core/require-client-suffix 🟢 1.6ms 🟢 1.7ms +7.5%
emit 🔴 5.87s 🔴 6.25s +6.5% 🔴
 ↳ emit/@Azure-Tools 🟢 0.0ms 🟢 0.0ms +0.0%
 ↳ emit/@azure-tools/typespec-autorest 🟢 120.4ms 🟢 128.4ms +6.6% 🔴
 ↳ emit/@azure-tools/typespec-python 🔴 2.19s 🔴 2.34s +6.5% 🔴
 ↳ emit/@typespec 🟢 0.0ms 🟢 0.0ms +0.0%
 ↳ emit/@typespec/http-client-js 🔴 552.2ms 🔴 586.4ms +6.2% 🔴
 ↳ emit/@typespec/openapi3 🟢 103.4ms 🟢 111.7ms +8.0% 🔴
 ↳ emit/@typespec/openapi3/compute 🟢 89.7ms 🟢 97.0ms +8.1% 🔴
 ↳ emit/@typespec/openapi3/write 🟢 13.4ms 🟢 14.4ms +7.5% 🔴

Averaged across 3 specs (azure-arm-resource-manager, azure-core-dataplane, azure-full).
Threshold: changes > ±5% are highlighted.
🟢 Fast · 🟡 Moderate (stages >200ms, rules >10ms) · 🔴 Slow (stages >400ms, rules >20ms)

lirenhe and others added 3 commits July 6, 2026 11:18
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The updated http-specs (core) added a model operation to the query
parameters queryExpansion/explode group, introducing the ExpandParameters
model. Regenerate the routes modular integration baseline accordingly.

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

dargilco commented Jul 6, 2026

Copy link
Copy Markdown
Member

Thank you @lirenhe for doing this work! Looking forward to see this PR completed. FYI @glharper @bobogogo1990

Comment on lines +321 to +325
* Historically (autorest.typescript PR #2616) the emitter also prepended per-layer
* tokens `azsdk-js-client` and `azsdk-js-api` to distinguish the classic-client,
* modular-API and REST layers. Those tokens have no `/version`, are not real packages,
* and confused service teams, so they were removed (see Azure/typespec-azure#4774).
*/

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

As this is already captured in the PR description, I suggest that we remove the historical content from the source comment.

@JialinHuang803 JialinHuang803 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Overall the code looks good to me, and I left a small comment. I'm not sure whether azsdk-js-api and azsdk-js-client were added in Azure/autorest.typescript#2616 because we wanted to track traffic from the API layer and client layer separately. I may need @qiaozha to help confirm if this change impacts anything else.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

emitter:typescript Issues for @azure-tools/typespec-ts emitter

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[typespec-ts] SDK User-Agent prefixes feel confusing / outdated

3 participants