Skip to content

feat(utils): always announce as Convert SDK via ConvertAgent User-Agent#387

Merged
JosephSamirL merged 2 commits into
main-convertfrom
feat/inject-convert-agent-user-agent
May 25, 2026
Merged

feat(utils): always announce as Convert SDK via ConvertAgent User-Agent#387
JosephSamirL merged 2 commits into
main-convertfrom
feat/inject-convert-agent-user-agent

Conversation

@abbaseya
Copy link
Copy Markdown
Contributor

@abbaseya abbaseya commented May 22, 2026

Summary

  • Force User-Agent: ConvertAgent/1.0 on every outbound HTTP request from HttpClient when running server-side.
  • Browser path stays untouched (browsers strip User-Agent per the W3C forbidden-header list, and the browser's natural UA does not trigger isbot anyway).
  • Two branches updated: fetch (gated on runtimeResult.runtime !== 'browser') and old-nodejs (unconditional, always server-side).

Why now

The May 19 metrics-endpoint isbot regression exposed that ApiManager's _trackingSource (network.source on the wire) is customer-configurable. Combined with the CI source-stamping pattern (rollup writes js<version> at build time), the wire-side source value is in two ways out of our control — customer config and CI environment. Either could silently break the metrics-endpoint's source-field bypass and re-create the May 19 outage shape.

Baking the UA at the lowest transport layer (HttpClient.request() in packages/utils/src/http-client.ts) makes the announcement an SDK invariant — not config-driven, not env-driven, not customer-overridable. Metrics-endpoint code stays untouched (the isConvertAgentUA bypass has been in place since 2026-05-20 17:06 UTC).

What stays in place

The source-field bypass at the metrics endpoint remains as legacy fallback for already-deployed SDK versions. Customers on older SDKs continue to work via the /^js\d+\.\d+\.\d+/ regex path.

Test plan

  • CI green on existing jest / tsc / ESLint pipelines
  • Targeted unit test in packages/utils to verify User-Agent: ConvertAgent/1.0 is present on HttpClient.request() outputs when determineRuntime() returns server-with-fetch or old-nodejs, and absent (or rather, left to whatever caller set) when browser
  • Smoke against staging metrics endpoint from a Node runtime to confirm botCheckSkipped events fire with the ConvertAgent UA bypass path

🤖 Generated with Claude Code


Set the User-Agent header to ConvertAgent/1.0 on every outbound HTTP
request from HttpClient when running server-side. Browser path stays
untouched (browsers strip User-Agent per the W3C forbidden-header list,
and the browser's natural UA does not trigger isbot anyway).

Two branches updated:
- fetch path (server-with-fetch + browser): conditional on
  runtimeResult.runtime !== 'browser'
- old-nodejs path: unconditional (always server-side)

Why this matters: ApiManager's _trackingSource (network.source on the
wire) is customer-configurable and could be overridden via SDK config,
or via a CI VERSION-stamping pattern. Either could silently break the
metrics-endpoint's source-field bypass. The UA is now an SDK invariant:
applied at the lowest HTTP transport layer, after any caller-provided
headers, so neither config nor higher-layer headers can override it.

Matches the metrics-endpoint's isConvertAgentUA bypass that has been
in place since 2026-05-20. Source-field bypass at the metrics endpoint
stays in place as legacy fallback for already-deployed SDK versions.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@abbaseya abbaseya self-assigned this May 22, 2026
@abbaseya abbaseya requested a review from JosephSamirL May 22, 2026 23:48
Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request updates the HttpClient to include a custom User-Agent header (ConvertAgent/1.0) for server-side requests to ensure traffic is correctly identified by bot filters. This change is implemented in both the fetch and Node.js request paths. The review feedback highlights that the current implementation mutates the headers object directly, which can cause side effects if the caller reuses the configuration object. It is recommended to use object spread to create a shallow copy of the headers instead.

Comment thread packages/utils/src/http-client.ts Outdated
Comment thread packages/utils/src/http-client.ts Outdated
Replaces the two hard-coded 'ConvertAgent/1.0' literals in the
http-client with a single named const declared near the imports, so
the value is named once and the two injection sites reference it.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@sonarqubecloud
Copy link
Copy Markdown

@JosephSamirL JosephSamirL merged commit 0c68a45 into main-convert May 25, 2026
5 checks passed
@JosephSamirL JosephSamirL deleted the feat/inject-convert-agent-user-agent branch May 25, 2026 10:52
@github-actions github-actions Bot mentioned this pull request May 25, 2026
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