Skip to content

fix(typescript): enable ADOT instrumentation for TypeScript agents - #1893

Open
jariy17 wants to merge 1 commit into
mainfrom
fix/adot-typescript-observability
Open

fix(typescript): enable ADOT instrumentation for TypeScript agents#1893
jariy17 wants to merge 1 commit into
mainfrom
fix/adot-typescript-observability

Conversation

@jariy17

Copy link
Copy Markdown
Contributor

Fixes#1892
Depends on aws/agentcore-l3-cdk-constructs#311 (CodeZip path)

Problem

agentcore deploy sets up no ADOT/OpenTelemetry instrumentation for TypeScript agents. Spans from any third-party instrumentation library are silently dropped and nothing appears in CloudWatch. Three independent gaps, each sufficient on its own:

  1. enableOtel hardcoded off for TypeScriptschema-mapper.ts:
    constenableOtel=!isMcp&&config.language!=='TypeScript';
  2. The TypeScript Dockerfile had no instrumentation branch at all. The Python one branches on {{#if enableOtel}}; the TS one ended unconditionally at CMD ["npx", "tsx", "main.ts"]. So setting instrumentation.enableOtel: true on a TS agent was a silent no-op — there was nothing for it to render — while the schema documents it as wrapping the entrypoint.
  3. No OTel SDK in either TS template. Strands carried only @opentelemetry/api (the no-op API surface, which discards spans unless a provider is registered); Vercel AI carried nothing.

This is a regression

580cd10"fix(templates): remove OTEL, session storage, and gateway from TS templates", merged in #981 — deleted the working implementation: both otel-register.ts files, their imports from main.ts, seven @opentelemetry/* dependencies, and it flipped schema-mapper.ts to exclude TypeScript. The OTel removal was one commit inside a broader TS template PR, so it isn't visible from the PR title.

Changes

  • schema-mapper.ts — stop excluding TypeScript from enableOtel
  • container/typescript/Dockerfile — add the {{#if enableOtel}} branch. Node has no opentelemetry-instrument equivalent, so it preloads the ADOT distro via NODE_OPTIONS rather than wrapping the entrypoint
  • both TS templates — add @aws/aws-distro-opentelemetry-node-autoinstrumentation
  • vercelai/base/main.ts — force-enable the Vercel AI SDK's own telemetry (see below)
  • dockerfile-render.test.ts — extend to cover TypeScript

The CodeZip path needs a different mechanism (no Dockerfile to hook) and lives in aws/agentcore-l3-cdk-constructs#311.

Why the Vercel template needs an explicit telemetry toggle

Turning on ADOT was necessary but not sufficient for Vercel AI. With instrumentation loaded and traces flowing, Vercel agents still produced only network-level spans — no model spans, no gen_ai.* attributes — while Strands produced a full GenAI tree from the same runtime.

Two compounding causes:

  • ADOT's Vercel instrumentation patches the ai module at import time. Both templates are "type": "module" and load instrumentation via --require (a CJS hook), which never observes an ESM import ... from 'ai'.
  • Under CodeZip it cannot work at all: esbuild inlines ai into the bundle, so there is no module resolution event left to intercept. An ESM loader hook would have fixed Container and silently missed CodeZip.

Setting experimental_telemetry on the call site sidesteps both. ai@6 resolves the global tracer (trace.getTracer('ai') from @opentelemetry/api, shared via globalThis), which ADOT registers at startup — so it works regardless of bundling or module system. Gated on AGENT_OBSERVABILITY_ENABLED === 'true', matching ADOT's own gate.

Strands needs no equivalent: its template self-instruments via @opentelemetry/api.

Verification

Deployed all four TypeScript agent shapes to a live account, invoked each 5 times, waited for ingestion, and queried X-Ray.

All four log AWS Distro of OpenTelemetry automatic instrumentation started successfully and produce X-Ray spans including downstream Bedrock calls.

Vercel AI, before vs after:

before: SdkVercelZip.DEFAULT
- bedrock-runtime.us-east-1.amazonaws.com:443
- 169.254.169.254:80
after: SdkVercelZip.DEFAULT
- chat us.anthropic.claude-sonnet-4-5-20250929-v1:0
- chat us.anthropic.claude-sonnet-4-5-...
- bedrock-runtime.us-east-1.amazonaws.com:443

Attributes now present: gen_ai.request.model, gen_ai.response.model, gen_ai.response.finish_reasons, gen_ai.operation.name, gen_ai.provider.name, gen_ai.system. Confirmed on both CodeZip and Container.

Tests: asset suite green (141), including the new TS Dockerfile render cases.

Known cosmetic issue, not addressed here

Runtime logs show @aws/...-instrumentation-vercel-ai Failed to register VercelAISpanProcessor. It is harmless and unrelated: ADOT's setTracerProvider is called once before the real provider exists (logged at warn) and again after, when it succeeds (logged at debug, so invisible in production). It also appears for Strands agents, which have no ai package installed at all. Worth an upstream log-level fix on aws-observability/aws-otel-js-instrumentation; nothing is lost.

Follow-up

If LangChain or OpenAI-Agents TypeScript templates are added later, they will hit the same ESM/bundling wall — their ADOT instrumentation patches modules identically and will be equally inert. Each will need a per-SDK telemetry toggle, or an --import-based ESM loader hook on the Container path.

TypeScript agents received no OpenTelemetry instrumentation, so spans from any
third-party instrumentation library were silently dropped and nothing appeared
in CloudWatch. Three gaps, each sufficient on its own:
- `enableOtel` was hardcoded off for TypeScript in the render config
- the TypeScript Dockerfile had no instrumentation branch at all, so setting
`instrumentation.enableOtel` on a TS agent was a silent no-op
- neither TS template depended on an OTel SDK — only the no-op
`@opentelemetry/api`, which discards spans unless a provider is registered
This is a regression: 580cd10 ("remove OTEL, session storage, and gateway from
TS templates", #981) deleted the previous working implementation.
Node has no `opentelemetry-instrument` equivalent, so the Dockerfile preloads
the ADOT distro via NODE_OPTIONS instead of wrapping the entrypoint. The CodeZip
path is handled in @aws/agentcore-cdk.
Also force-enables the Vercel AI SDK's own telemetry. ADOT's Vercel
instrumentation patches the `ai` module at import time, which never fires under
CodeZip because esbuild inlines `ai` into the bundle, leaving no import to
intercept. Toggling the SDK's telemetry works regardless of bundling: ai@6 pulls
the global tracer that ADOT registers. Without this, Vercel agents produced only
network-level spans — no model spans, no gen_ai.* attributes. Strands is
unaffected because its template self-instruments via @opentelemetry/api.
Extends the Dockerfile render test to cover TypeScript; it previously only
exercised the Python Dockerfile, which is why this regressed unnoticed.
Verified on a live account: all four agent shapes (Strands/VercelAI x
CodeZip/Container) produce X-Ray spans, and both Vercel shapes now emit
`chat <model>` spans carrying gen_ai.request.model, gen_ai.response.model,
and gen_ai.response.finish_reasons.
@github-actions

Copy link
Copy Markdown
Contributor

Package Tarball

aws-agentcore-0.25.0.tgz

How to install

gh release download pr-1893-tarball --repo aws/agentcore-cli --pattern "*.tgz" --dir /tmp/pr-tarball
npm install -g /tmp/pr-tarball/aws-agentcore-0.25.0.tgz

@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automationagentcore-devx-automationBot removed the claude-security-reviewing Claude Code /security-review in progress label Aug 3, 2026
@github-actionsgithub-actionsBot removed the agentcore-harness-reviewing AgentCore Harness review in progress label Aug 3, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Coverage Report

StatusCategoryPercentageCovered / Total
🔵Lines40.44%15151 / 37462
🔵Statements39.71%16158 / 40680
🔵Functions34.69%2596 / 7482
🔵Branches33.82%10106 / 29880
Generated in workflow #4292 for commit f0efe1e by the Vitest Coverage Report Action

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

Labels

size/sPR size: S

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug(typescript): agentcore deploy sets up no ADOT/OTel instrumentation for TypeScript agents, silently dropping all 3p telemetry

1 participant

@jariy17
, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
fix(typescript): enable ADOT instrumentation for TypeScript agents by jariy17 · Pull Request #1893 · aws/agentcore-cli · GitHub
Skip to content

fix(typescript): enable ADOT instrumentation for TypeScript agents - #1893

Open
jariy17 wants to merge 1 commit into
mainfrom
fix/adot-typescript-observability
Open

fix(typescript): enable ADOT instrumentation for TypeScript agents#1893
jariy17 wants to merge 1 commit into
mainfrom
fix/adot-typescript-observability

Conversation

@jariy17

Copy link
Copy Markdown
Contributor

Fixes#1892
Depends on aws/agentcore-l3-cdk-constructs#311 (CodeZip path)

Problem

agentcore deploy sets up no ADOT/OpenTelemetry instrumentation for TypeScript agents. Spans from any third-party instrumentation library are silently dropped and nothing appears in CloudWatch. Three independent gaps, each sufficient on its own:

  1. enableOtel hardcoded off for TypeScriptschema-mapper.ts:
    constenableOtel=!isMcp&&config.language!=='TypeScript';
  2. The TypeScript Dockerfile had no instrumentation branch at all. The Python one branches on {{#if enableOtel}}; the TS one ended unconditionally at CMD ["npx", "tsx", "main.ts"]. So setting instrumentation.enableOtel: true on a TS agent was a silent no-op — there was nothing for it to render — while the schema documents it as wrapping the entrypoint.
  3. No OTel SDK in either TS template. Strands carried only @opentelemetry/api (the no-op API surface, which discards spans unless a provider is registered); Vercel AI carried nothing.

This is a regression

580cd10"fix(templates): remove OTEL, session storage, and gateway from TS templates", merged in #981 — deleted the working implementation: both otel-register.ts files, their imports from main.ts, seven @opentelemetry/* dependencies, and it flipped schema-mapper.ts to exclude TypeScript. The OTel removal was one commit inside a broader TS template PR, so it isn't visible from the PR title.

Changes

  • schema-mapper.ts — stop excluding TypeScript from enableOtel
  • container/typescript/Dockerfile — add the {{#if enableOtel}} branch. Node has no opentelemetry-instrument equivalent, so it preloads the ADOT distro via NODE_OPTIONS rather than wrapping the entrypoint
  • both TS templates — add @aws/aws-distro-opentelemetry-node-autoinstrumentation
  • vercelai/base/main.ts — force-enable the Vercel AI SDK's own telemetry (see below)
  • dockerfile-render.test.ts — extend to cover TypeScript

The CodeZip path needs a different mechanism (no Dockerfile to hook) and lives in aws/agentcore-l3-cdk-constructs#311.

Why the Vercel template needs an explicit telemetry toggle

Turning on ADOT was necessary but not sufficient for Vercel AI. With instrumentation loaded and traces flowing, Vercel agents still produced only network-level spans — no model spans, no gen_ai.* attributes — while Strands produced a full GenAI tree from the same runtime.

Two compounding causes:

  • ADOT's Vercel instrumentation patches the ai module at import time. Both templates are "type": "module" and load instrumentation via --require (a CJS hook), which never observes an ESM import ... from 'ai'.
  • Under CodeZip it cannot work at all: esbuild inlines ai into the bundle, so there is no module resolution event left to intercept. An ESM loader hook would have fixed Container and silently missed CodeZip.

Setting experimental_telemetry on the call site sidesteps both. ai@6 resolves the global tracer (trace.getTracer('ai') from @opentelemetry/api, shared via globalThis), which ADOT registers at startup — so it works regardless of bundling or module system. Gated on AGENT_OBSERVABILITY_ENABLED === 'true', matching ADOT's own gate.

Strands needs no equivalent: its template self-instruments via @opentelemetry/api.

Verification

Deployed all four TypeScript agent shapes to a live account, invoked each 5 times, waited for ingestion, and queried X-Ray.

All four log AWS Distro of OpenTelemetry automatic instrumentation started successfully and produce X-Ray spans including downstream Bedrock calls.

Vercel AI, before vs after:

before: SdkVercelZip.DEFAULT
- bedrock-runtime.us-east-1.amazonaws.com:443
- 169.254.169.254:80
after: SdkVercelZip.DEFAULT
- chat us.anthropic.claude-sonnet-4-5-20250929-v1:0
- chat us.anthropic.claude-sonnet-4-5-...
- bedrock-runtime.us-east-1.amazonaws.com:443

Attributes now present: gen_ai.request.model, gen_ai.response.model, gen_ai.response.finish_reasons, gen_ai.operation.name, gen_ai.provider.name, gen_ai.system. Confirmed on both CodeZip and Container.

Tests: asset suite green (141), including the new TS Dockerfile render cases.

Known cosmetic issue, not addressed here

Runtime logs show @aws/...-instrumentation-vercel-ai Failed to register VercelAISpanProcessor. It is harmless and unrelated: ADOT's setTracerProvider is called once before the real provider exists (logged at warn) and again after, when it succeeds (logged at debug, so invisible in production). It also appears for Strands agents, which have no ai package installed at all. Worth an upstream log-level fix on aws-observability/aws-otel-js-instrumentation; nothing is lost.

Follow-up

If LangChain or OpenAI-Agents TypeScript templates are added later, they will hit the same ESM/bundling wall — their ADOT instrumentation patches modules identically and will be equally inert. Each will need a per-SDK telemetry toggle, or an --import-based ESM loader hook on the Container path.

TypeScript agents received no OpenTelemetry instrumentation, so spans from any
third-party instrumentation library were silently dropped and nothing appeared
in CloudWatch. Three gaps, each sufficient on its own:
- `enableOtel` was hardcoded off for TypeScript in the render config
- the TypeScript Dockerfile had no instrumentation branch at all, so setting
`instrumentation.enableOtel` on a TS agent was a silent no-op
- neither TS template depended on an OTel SDK — only the no-op
`@opentelemetry/api`, which discards spans unless a provider is registered
This is a regression: 580cd10 ("remove OTEL, session storage, and gateway from
TS templates", #981) deleted the previous working implementation.
Node has no `opentelemetry-instrument` equivalent, so the Dockerfile preloads
the ADOT distro via NODE_OPTIONS instead of wrapping the entrypoint. The CodeZip
path is handled in @aws/agentcore-cdk.
Also force-enables the Vercel AI SDK's own telemetry. ADOT's Vercel
instrumentation patches the `ai` module at import time, which never fires under
CodeZip because esbuild inlines `ai` into the bundle, leaving no import to
intercept. Toggling the SDK's telemetry works regardless of bundling: ai@6 pulls
the global tracer that ADOT registers. Without this, Vercel agents produced only
network-level spans — no model spans, no gen_ai.* attributes. Strands is
unaffected because its template self-instruments via @opentelemetry/api.
Extends the Dockerfile render test to cover TypeScript; it previously only
exercised the Python Dockerfile, which is why this regressed unnoticed.
Verified on a live account: all four agent shapes (Strands/VercelAI x
CodeZip/Container) produce X-Ray spans, and both Vercel shapes now emit
`chat <model>` spans carrying gen_ai.request.model, gen_ai.response.model,
and gen_ai.response.finish_reasons.
@github-actions

Copy link
Copy Markdown
Contributor

Package Tarball

aws-agentcore-0.25.0.tgz

How to install

gh release download pr-1893-tarball --repo aws/agentcore-cli --pattern "*.tgz" --dir /tmp/pr-tarball
npm install -g /tmp/pr-tarball/aws-agentcore-0.25.0.tgz

@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automationagentcore-devx-automationBot removed the claude-security-reviewing Claude Code /security-review in progress label Aug 3, 2026
@github-actionsgithub-actionsBot removed the agentcore-harness-reviewing AgentCore Harness review in progress label Aug 3, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Coverage Report

StatusCategoryPercentageCovered / Total
🔵Lines40.44%15151 / 37462
🔵Statements39.71%16158 / 40680
🔵Functions34.69%2596 / 7482
🔵Branches33.82%10106 / 29880
Generated in workflow #4292 for commit f0efe1e by the Vitest Coverage Report Action

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

Labels

size/sPR size: S

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug(typescript): agentcore deploy sets up no ADOT/OTel instrumentation for TypeScript agents, silently dropping all 3p telemetry

1 participant

@jariy17
, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' fix(typescript): enable ADOT instrumentation for TypeScript agents by jariy17 · Pull Request #1893 · aws/agentcore-cli · GitHub
Skip to content

fix(typescript): enable ADOT instrumentation for TypeScript agents - #1893

Open
jariy17 wants to merge 1 commit into
mainfrom
fix/adot-typescript-observability
Open

fix(typescript): enable ADOT instrumentation for TypeScript agents#1893
jariy17 wants to merge 1 commit into
mainfrom
fix/adot-typescript-observability

Conversation

@jariy17

Copy link
Copy Markdown
Contributor

Fixes#1892
Depends on aws/agentcore-l3-cdk-constructs#311 (CodeZip path)

Problem

agentcore deploy sets up no ADOT/OpenTelemetry instrumentation for TypeScript agents. Spans from any third-party instrumentation library are silently dropped and nothing appears in CloudWatch. Three independent gaps, each sufficient on its own:

  1. enableOtel hardcoded off for TypeScriptschema-mapper.ts:
    constenableOtel=!isMcp&&config.language!=='TypeScript';
  2. The TypeScript Dockerfile had no instrumentation branch at all. The Python one branches on {{#if enableOtel}}; the TS one ended unconditionally at CMD ["npx", "tsx", "main.ts"]. So setting instrumentation.enableOtel: true on a TS agent was a silent no-op — there was nothing for it to render — while the schema documents it as wrapping the entrypoint.
  3. No OTel SDK in either TS template. Strands carried only @opentelemetry/api (the no-op API surface, which discards spans unless a provider is registered); Vercel AI carried nothing.

This is a regression

580cd10"fix(templates): remove OTEL, session storage, and gateway from TS templates", merged in #981 — deleted the working implementation: both otel-register.ts files, their imports from main.ts, seven @opentelemetry/* dependencies, and it flipped schema-mapper.ts to exclude TypeScript. The OTel removal was one commit inside a broader TS template PR, so it isn't visible from the PR title.

Changes

  • schema-mapper.ts — stop excluding TypeScript from enableOtel
  • container/typescript/Dockerfile — add the {{#if enableOtel}} branch. Node has no opentelemetry-instrument equivalent, so it preloads the ADOT distro via NODE_OPTIONS rather than wrapping the entrypoint
  • both TS templates — add @aws/aws-distro-opentelemetry-node-autoinstrumentation
  • vercelai/base/main.ts — force-enable the Vercel AI SDK's own telemetry (see below)
  • dockerfile-render.test.ts — extend to cover TypeScript

The CodeZip path needs a different mechanism (no Dockerfile to hook) and lives in aws/agentcore-l3-cdk-constructs#311.

Why the Vercel template needs an explicit telemetry toggle

Turning on ADOT was necessary but not sufficient for Vercel AI. With instrumentation loaded and traces flowing, Vercel agents still produced only network-level spans — no model spans, no gen_ai.* attributes — while Strands produced a full GenAI tree from the same runtime.

Two compounding causes:

  • ADOT's Vercel instrumentation patches the ai module at import time. Both templates are "type": "module" and load instrumentation via --require (a CJS hook), which never observes an ESM import ... from 'ai'.
  • Under CodeZip it cannot work at all: esbuild inlines ai into the bundle, so there is no module resolution event left to intercept. An ESM loader hook would have fixed Container and silently missed CodeZip.

Setting experimental_telemetry on the call site sidesteps both. ai@6 resolves the global tracer (trace.getTracer('ai') from @opentelemetry/api, shared via globalThis), which ADOT registers at startup — so it works regardless of bundling or module system. Gated on AGENT_OBSERVABILITY_ENABLED === 'true', matching ADOT's own gate.

Strands needs no equivalent: its template self-instruments via @opentelemetry/api.

Verification

Deployed all four TypeScript agent shapes to a live account, invoked each 5 times, waited for ingestion, and queried X-Ray.

All four log AWS Distro of OpenTelemetry automatic instrumentation started successfully and produce X-Ray spans including downstream Bedrock calls.

Vercel AI, before vs after:

before: SdkVercelZip.DEFAULT
- bedrock-runtime.us-east-1.amazonaws.com:443
- 169.254.169.254:80
after: SdkVercelZip.DEFAULT
- chat us.anthropic.claude-sonnet-4-5-20250929-v1:0
- chat us.anthropic.claude-sonnet-4-5-...
- bedrock-runtime.us-east-1.amazonaws.com:443

Attributes now present: gen_ai.request.model, gen_ai.response.model, gen_ai.response.finish_reasons, gen_ai.operation.name, gen_ai.provider.name, gen_ai.system. Confirmed on both CodeZip and Container.

Tests: asset suite green (141), including the new TS Dockerfile render cases.

Known cosmetic issue, not addressed here

Runtime logs show @aws/...-instrumentation-vercel-ai Failed to register VercelAISpanProcessor. It is harmless and unrelated: ADOT's setTracerProvider is called once before the real provider exists (logged at warn) and again after, when it succeeds (logged at debug, so invisible in production). It also appears for Strands agents, which have no ai package installed at all. Worth an upstream log-level fix on aws-observability/aws-otel-js-instrumentation; nothing is lost.

Follow-up

If LangChain or OpenAI-Agents TypeScript templates are added later, they will hit the same ESM/bundling wall — their ADOT instrumentation patches modules identically and will be equally inert. Each will need a per-SDK telemetry toggle, or an --import-based ESM loader hook on the Container path.

TypeScript agents received no OpenTelemetry instrumentation, so spans from any
third-party instrumentation library were silently dropped and nothing appeared
in CloudWatch. Three gaps, each sufficient on its own:
- `enableOtel` was hardcoded off for TypeScript in the render config
- the TypeScript Dockerfile had no instrumentation branch at all, so setting
`instrumentation.enableOtel` on a TS agent was a silent no-op
- neither TS template depended on an OTel SDK — only the no-op
`@opentelemetry/api`, which discards spans unless a provider is registered
This is a regression: 580cd10 ("remove OTEL, session storage, and gateway from
TS templates", #981) deleted the previous working implementation.
Node has no `opentelemetry-instrument` equivalent, so the Dockerfile preloads
the ADOT distro via NODE_OPTIONS instead of wrapping the entrypoint. The CodeZip
path is handled in @aws/agentcore-cdk.
Also force-enables the Vercel AI SDK's own telemetry. ADOT's Vercel
instrumentation patches the `ai` module at import time, which never fires under
CodeZip because esbuild inlines `ai` into the bundle, leaving no import to
intercept. Toggling the SDK's telemetry works regardless of bundling: ai@6 pulls
the global tracer that ADOT registers. Without this, Vercel agents produced only
network-level spans — no model spans, no gen_ai.* attributes. Strands is
unaffected because its template self-instruments via @opentelemetry/api.
Extends the Dockerfile render test to cover TypeScript; it previously only
exercised the Python Dockerfile, which is why this regressed unnoticed.
Verified on a live account: all four agent shapes (Strands/VercelAI x
CodeZip/Container) produce X-Ray spans, and both Vercel shapes now emit
`chat <model>` spans carrying gen_ai.request.model, gen_ai.response.model,
and gen_ai.response.finish_reasons.
@github-actions

Copy link
Copy Markdown
Contributor

Package Tarball

aws-agentcore-0.25.0.tgz

How to install

gh release download pr-1893-tarball --repo aws/agentcore-cli --pattern "*.tgz" --dir /tmp/pr-tarball
npm install -g /tmp/pr-tarball/aws-agentcore-0.25.0.tgz

@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automationagentcore-devx-automationBot removed the claude-security-reviewing Claude Code /security-review in progress label Aug 3, 2026
@github-actionsgithub-actionsBot removed the agentcore-harness-reviewing AgentCore Harness review in progress label Aug 3, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Coverage Report

StatusCategoryPercentageCovered / Total
🔵Lines40.44%15151 / 37462
🔵Statements39.71%16158 / 40680
🔵Functions34.69%2596 / 7482
🔵Branches33.82%10106 / 29880
Generated in workflow #4292 for commit f0efe1e by the Vitest Coverage Report Action

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

Labels

size/sPR size: S

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug(typescript): agentcore deploy sets up no ADOT/OTel instrumentation for TypeScript agents, silently dropping all 3p telemetry

1 participant

@jariy17
, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' fix(typescript): enable ADOT instrumentation for TypeScript agents by jariy17 · Pull Request #1893 · aws/agentcore-cli · GitHub
Skip to content

fix(typescript): enable ADOT instrumentation for TypeScript agents - #1893

Open
jariy17 wants to merge 1 commit into
mainfrom
fix/adot-typescript-observability
Open

fix(typescript): enable ADOT instrumentation for TypeScript agents#1893
jariy17 wants to merge 1 commit into
mainfrom
fix/adot-typescript-observability

Conversation

@jariy17

Copy link
Copy Markdown
Contributor

Fixes#1892
Depends on aws/agentcore-l3-cdk-constructs#311 (CodeZip path)

Problem

agentcore deploy sets up no ADOT/OpenTelemetry instrumentation for TypeScript agents. Spans from any third-party instrumentation library are silently dropped and nothing appears in CloudWatch. Three independent gaps, each sufficient on its own:

  1. enableOtel hardcoded off for TypeScriptschema-mapper.ts:
    constenableOtel=!isMcp&&config.language!=='TypeScript';
  2. The TypeScript Dockerfile had no instrumentation branch at all. The Python one branches on {{#if enableOtel}}; the TS one ended unconditionally at CMD ["npx", "tsx", "main.ts"]. So setting instrumentation.enableOtel: true on a TS agent was a silent no-op — there was nothing for it to render — while the schema documents it as wrapping the entrypoint.
  3. No OTel SDK in either TS template. Strands carried only @opentelemetry/api (the no-op API surface, which discards spans unless a provider is registered); Vercel AI carried nothing.

This is a regression

580cd10"fix(templates): remove OTEL, session storage, and gateway from TS templates", merged in #981 — deleted the working implementation: both otel-register.ts files, their imports from main.ts, seven @opentelemetry/* dependencies, and it flipped schema-mapper.ts to exclude TypeScript. The OTel removal was one commit inside a broader TS template PR, so it isn't visible from the PR title.

Changes

  • schema-mapper.ts — stop excluding TypeScript from enableOtel
  • container/typescript/Dockerfile — add the {{#if enableOtel}} branch. Node has no opentelemetry-instrument equivalent, so it preloads the ADOT distro via NODE_OPTIONS rather than wrapping the entrypoint
  • both TS templates — add @aws/aws-distro-opentelemetry-node-autoinstrumentation
  • vercelai/base/main.ts — force-enable the Vercel AI SDK's own telemetry (see below)
  • dockerfile-render.test.ts — extend to cover TypeScript

The CodeZip path needs a different mechanism (no Dockerfile to hook) and lives in aws/agentcore-l3-cdk-constructs#311.

Why the Vercel template needs an explicit telemetry toggle

Turning on ADOT was necessary but not sufficient for Vercel AI. With instrumentation loaded and traces flowing, Vercel agents still produced only network-level spans — no model spans, no gen_ai.* attributes — while Strands produced a full GenAI tree from the same runtime.

Two compounding causes:

  • ADOT's Vercel instrumentation patches the ai module at import time. Both templates are "type": "module" and load instrumentation via --require (a CJS hook), which never observes an ESM import ... from 'ai'.
  • Under CodeZip it cannot work at all: esbuild inlines ai into the bundle, so there is no module resolution event left to intercept. An ESM loader hook would have fixed Container and silently missed CodeZip.

Setting experimental_telemetry on the call site sidesteps both. ai@6 resolves the global tracer (trace.getTracer('ai') from @opentelemetry/api, shared via globalThis), which ADOT registers at startup — so it works regardless of bundling or module system. Gated on AGENT_OBSERVABILITY_ENABLED === 'true', matching ADOT's own gate.

Strands needs no equivalent: its template self-instruments via @opentelemetry/api.

Verification

Deployed all four TypeScript agent shapes to a live account, invoked each 5 times, waited for ingestion, and queried X-Ray.

All four log AWS Distro of OpenTelemetry automatic instrumentation started successfully and produce X-Ray spans including downstream Bedrock calls.

Vercel AI, before vs after:

before: SdkVercelZip.DEFAULT
- bedrock-runtime.us-east-1.amazonaws.com:443
- 169.254.169.254:80
after: SdkVercelZip.DEFAULT
- chat us.anthropic.claude-sonnet-4-5-20250929-v1:0
- chat us.anthropic.claude-sonnet-4-5-...
- bedrock-runtime.us-east-1.amazonaws.com:443

Attributes now present: gen_ai.request.model, gen_ai.response.model, gen_ai.response.finish_reasons, gen_ai.operation.name, gen_ai.provider.name, gen_ai.system. Confirmed on both CodeZip and Container.

Tests: asset suite green (141), including the new TS Dockerfile render cases.

Known cosmetic issue, not addressed here

Runtime logs show @aws/...-instrumentation-vercel-ai Failed to register VercelAISpanProcessor. It is harmless and unrelated: ADOT's setTracerProvider is called once before the real provider exists (logged at warn) and again after, when it succeeds (logged at debug, so invisible in production). It also appears for Strands agents, which have no ai package installed at all. Worth an upstream log-level fix on aws-observability/aws-otel-js-instrumentation; nothing is lost.

Follow-up

If LangChain or OpenAI-Agents TypeScript templates are added later, they will hit the same ESM/bundling wall — their ADOT instrumentation patches modules identically and will be equally inert. Each will need a per-SDK telemetry toggle, or an --import-based ESM loader hook on the Container path.

TypeScript agents received no OpenTelemetry instrumentation, so spans from any
third-party instrumentation library were silently dropped and nothing appeared
in CloudWatch. Three gaps, each sufficient on its own:
- `enableOtel` was hardcoded off for TypeScript in the render config
- the TypeScript Dockerfile had no instrumentation branch at all, so setting
`instrumentation.enableOtel` on a TS agent was a silent no-op
- neither TS template depended on an OTel SDK — only the no-op
`@opentelemetry/api`, which discards spans unless a provider is registered
This is a regression: 580cd10 ("remove OTEL, session storage, and gateway from
TS templates", #981) deleted the previous working implementation.
Node has no `opentelemetry-instrument` equivalent, so the Dockerfile preloads
the ADOT distro via NODE_OPTIONS instead of wrapping the entrypoint. The CodeZip
path is handled in @aws/agentcore-cdk.
Also force-enables the Vercel AI SDK's own telemetry. ADOT's Vercel
instrumentation patches the `ai` module at import time, which never fires under
CodeZip because esbuild inlines `ai` into the bundle, leaving no import to
intercept. Toggling the SDK's telemetry works regardless of bundling: ai@6 pulls
the global tracer that ADOT registers. Without this, Vercel agents produced only
network-level spans — no model spans, no gen_ai.* attributes. Strands is
unaffected because its template self-instruments via @opentelemetry/api.
Extends the Dockerfile render test to cover TypeScript; it previously only
exercised the Python Dockerfile, which is why this regressed unnoticed.
Verified on a live account: all four agent shapes (Strands/VercelAI x
CodeZip/Container) produce X-Ray spans, and both Vercel shapes now emit
`chat <model>` spans carrying gen_ai.request.model, gen_ai.response.model,
and gen_ai.response.finish_reasons.
@github-actions

Copy link
Copy Markdown
Contributor

Package Tarball

aws-agentcore-0.25.0.tgz

How to install

gh release download pr-1893-tarball --repo aws/agentcore-cli --pattern "*.tgz" --dir /tmp/pr-tarball
npm install -g /tmp/pr-tarball/aws-agentcore-0.25.0.tgz

@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automationagentcore-devx-automationBot removed the claude-security-reviewing Claude Code /security-review in progress label Aug 3, 2026
@github-actionsgithub-actionsBot removed the agentcore-harness-reviewing AgentCore Harness review in progress label Aug 3, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Coverage Report

StatusCategoryPercentageCovered / Total
🔵Lines40.44%15151 / 37462
🔵Statements39.71%16158 / 40680
🔵Functions34.69%2596 / 7482
🔵Branches33.82%10106 / 29880
Generated in workflow #4292 for commit f0efe1e by the Vitest Coverage Report Action

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

Labels

size/sPR size: S

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug(typescript): agentcore deploy sets up no ADOT/OTel instrumentation for TypeScript agents, silently dropping all 3p telemetry

1 participant

@jariy17
, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' fix(typescript): enable ADOT instrumentation for TypeScript agents by jariy17 · Pull Request #1893 · aws/agentcore-cli · GitHub
Skip to content

fix(typescript): enable ADOT instrumentation for TypeScript agents - #1893

Open
jariy17 wants to merge 1 commit into
mainfrom
fix/adot-typescript-observability
Open

fix(typescript): enable ADOT instrumentation for TypeScript agents#1893
jariy17 wants to merge 1 commit into
mainfrom
fix/adot-typescript-observability

Conversation

@jariy17

Copy link
Copy Markdown
Contributor

Fixes#1892
Depends on aws/agentcore-l3-cdk-constructs#311 (CodeZip path)

Problem

agentcore deploy sets up no ADOT/OpenTelemetry instrumentation for TypeScript agents. Spans from any third-party instrumentation library are silently dropped and nothing appears in CloudWatch. Three independent gaps, each sufficient on its own:

  1. enableOtel hardcoded off for TypeScriptschema-mapper.ts:
    constenableOtel=!isMcp&&config.language!=='TypeScript';
  2. The TypeScript Dockerfile had no instrumentation branch at all. The Python one branches on {{#if enableOtel}}; the TS one ended unconditionally at CMD ["npx", "tsx", "main.ts"]. So setting instrumentation.enableOtel: true on a TS agent was a silent no-op — there was nothing for it to render — while the schema documents it as wrapping the entrypoint.
  3. No OTel SDK in either TS template. Strands carried only @opentelemetry/api (the no-op API surface, which discards spans unless a provider is registered); Vercel AI carried nothing.

This is a regression

580cd10"fix(templates): remove OTEL, session storage, and gateway from TS templates", merged in #981 — deleted the working implementation: both otel-register.ts files, their imports from main.ts, seven @opentelemetry/* dependencies, and it flipped schema-mapper.ts to exclude TypeScript. The OTel removal was one commit inside a broader TS template PR, so it isn't visible from the PR title.

Changes

  • schema-mapper.ts — stop excluding TypeScript from enableOtel
  • container/typescript/Dockerfile — add the {{#if enableOtel}} branch. Node has no opentelemetry-instrument equivalent, so it preloads the ADOT distro via NODE_OPTIONS rather than wrapping the entrypoint
  • both TS templates — add @aws/aws-distro-opentelemetry-node-autoinstrumentation
  • vercelai/base/main.ts — force-enable the Vercel AI SDK's own telemetry (see below)
  • dockerfile-render.test.ts — extend to cover TypeScript

The CodeZip path needs a different mechanism (no Dockerfile to hook) and lives in aws/agentcore-l3-cdk-constructs#311.

Why the Vercel template needs an explicit telemetry toggle

Turning on ADOT was necessary but not sufficient for Vercel AI. With instrumentation loaded and traces flowing, Vercel agents still produced only network-level spans — no model spans, no gen_ai.* attributes — while Strands produced a full GenAI tree from the same runtime.

Two compounding causes:

  • ADOT's Vercel instrumentation patches the ai module at import time. Both templates are "type": "module" and load instrumentation via --require (a CJS hook), which never observes an ESM import ... from 'ai'.
  • Under CodeZip it cannot work at all: esbuild inlines ai into the bundle, so there is no module resolution event left to intercept. An ESM loader hook would have fixed Container and silently missed CodeZip.

Setting experimental_telemetry on the call site sidesteps both. ai@6 resolves the global tracer (trace.getTracer('ai') from @opentelemetry/api, shared via globalThis), which ADOT registers at startup — so it works regardless of bundling or module system. Gated on AGENT_OBSERVABILITY_ENABLED === 'true', matching ADOT's own gate.

Strands needs no equivalent: its template self-instruments via @opentelemetry/api.

Verification

Deployed all four TypeScript agent shapes to a live account, invoked each 5 times, waited for ingestion, and queried X-Ray.

All four log AWS Distro of OpenTelemetry automatic instrumentation started successfully and produce X-Ray spans including downstream Bedrock calls.

Vercel AI, before vs after:

before: SdkVercelZip.DEFAULT
- bedrock-runtime.us-east-1.amazonaws.com:443
- 169.254.169.254:80
after: SdkVercelZip.DEFAULT
- chat us.anthropic.claude-sonnet-4-5-20250929-v1:0
- chat us.anthropic.claude-sonnet-4-5-...
- bedrock-runtime.us-east-1.amazonaws.com:443

Attributes now present: gen_ai.request.model, gen_ai.response.model, gen_ai.response.finish_reasons, gen_ai.operation.name, gen_ai.provider.name, gen_ai.system. Confirmed on both CodeZip and Container.

Tests: asset suite green (141), including the new TS Dockerfile render cases.

Known cosmetic issue, not addressed here

Runtime logs show @aws/...-instrumentation-vercel-ai Failed to register VercelAISpanProcessor. It is harmless and unrelated: ADOT's setTracerProvider is called once before the real provider exists (logged at warn) and again after, when it succeeds (logged at debug, so invisible in production). It also appears for Strands agents, which have no ai package installed at all. Worth an upstream log-level fix on aws-observability/aws-otel-js-instrumentation; nothing is lost.

Follow-up

If LangChain or OpenAI-Agents TypeScript templates are added later, they will hit the same ESM/bundling wall — their ADOT instrumentation patches modules identically and will be equally inert. Each will need a per-SDK telemetry toggle, or an --import-based ESM loader hook on the Container path.

TypeScript agents received no OpenTelemetry instrumentation, so spans from any
third-party instrumentation library were silently dropped and nothing appeared
in CloudWatch. Three gaps, each sufficient on its own:
- `enableOtel` was hardcoded off for TypeScript in the render config
- the TypeScript Dockerfile had no instrumentation branch at all, so setting
`instrumentation.enableOtel` on a TS agent was a silent no-op
- neither TS template depended on an OTel SDK — only the no-op
`@opentelemetry/api`, which discards spans unless a provider is registered
This is a regression: 580cd10 ("remove OTEL, session storage, and gateway from
TS templates", #981) deleted the previous working implementation.
Node has no `opentelemetry-instrument` equivalent, so the Dockerfile preloads
the ADOT distro via NODE_OPTIONS instead of wrapping the entrypoint. The CodeZip
path is handled in @aws/agentcore-cdk.
Also force-enables the Vercel AI SDK's own telemetry. ADOT's Vercel
instrumentation patches the `ai` module at import time, which never fires under
CodeZip because esbuild inlines `ai` into the bundle, leaving no import to
intercept. Toggling the SDK's telemetry works regardless of bundling: ai@6 pulls
the global tracer that ADOT registers. Without this, Vercel agents produced only
network-level spans — no model spans, no gen_ai.* attributes. Strands is
unaffected because its template self-instruments via @opentelemetry/api.
Extends the Dockerfile render test to cover TypeScript; it previously only
exercised the Python Dockerfile, which is why this regressed unnoticed.
Verified on a live account: all four agent shapes (Strands/VercelAI x
CodeZip/Container) produce X-Ray spans, and both Vercel shapes now emit
`chat <model>` spans carrying gen_ai.request.model, gen_ai.response.model,
and gen_ai.response.finish_reasons.
@github-actions

Copy link
Copy Markdown
Contributor

Package Tarball

aws-agentcore-0.25.0.tgz

How to install

gh release download pr-1893-tarball --repo aws/agentcore-cli --pattern "*.tgz" --dir /tmp/pr-tarball
npm install -g /tmp/pr-tarball/aws-agentcore-0.25.0.tgz

@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automationagentcore-devx-automationBot removed the claude-security-reviewing Claude Code /security-review in progress label Aug 3, 2026
@github-actionsgithub-actionsBot removed the agentcore-harness-reviewing AgentCore Harness review in progress label Aug 3, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Coverage Report

StatusCategoryPercentageCovered / Total
🔵Lines40.44%15151 / 37462
🔵Statements39.71%16158 / 40680
🔵Functions34.69%2596 / 7482
🔵Branches33.82%10106 / 29880
Generated in workflow #4292 for commit f0efe1e by the Vitest Coverage Report Action

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

Labels

size/sPR size: S

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug(typescript): agentcore deploy sets up no ADOT/OTel instrumentation for TypeScript agents, silently dropping all 3p telemetry

1 participant

@jariy17
, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' fix(typescript): enable ADOT instrumentation for TypeScript agents by jariy17 · Pull Request #1893 · aws/agentcore-cli · GitHub
Skip to content

fix(typescript): enable ADOT instrumentation for TypeScript agents - #1893

Open
jariy17 wants to merge 1 commit into
mainfrom
fix/adot-typescript-observability
Open

fix(typescript): enable ADOT instrumentation for TypeScript agents#1893
jariy17 wants to merge 1 commit into
mainfrom
fix/adot-typescript-observability

Conversation

@jariy17

Copy link
Copy Markdown
Contributor

Fixes#1892
Depends on aws/agentcore-l3-cdk-constructs#311 (CodeZip path)

Problem

agentcore deploy sets up no ADOT/OpenTelemetry instrumentation for TypeScript agents. Spans from any third-party instrumentation library are silently dropped and nothing appears in CloudWatch. Three independent gaps, each sufficient on its own:

  1. enableOtel hardcoded off for TypeScriptschema-mapper.ts:
    constenableOtel=!isMcp&&config.language!=='TypeScript';
  2. The TypeScript Dockerfile had no instrumentation branch at all. The Python one branches on {{#if enableOtel}}; the TS one ended unconditionally at CMD ["npx", "tsx", "main.ts"]. So setting instrumentation.enableOtel: true on a TS agent was a silent no-op — there was nothing for it to render — while the schema documents it as wrapping the entrypoint.
  3. No OTel SDK in either TS template. Strands carried only @opentelemetry/api (the no-op API surface, which discards spans unless a provider is registered); Vercel AI carried nothing.

This is a regression

580cd10"fix(templates): remove OTEL, session storage, and gateway from TS templates", merged in #981 — deleted the working implementation: both otel-register.ts files, their imports from main.ts, seven @opentelemetry/* dependencies, and it flipped schema-mapper.ts to exclude TypeScript. The OTel removal was one commit inside a broader TS template PR, so it isn't visible from the PR title.

Changes

  • schema-mapper.ts — stop excluding TypeScript from enableOtel
  • container/typescript/Dockerfile — add the {{#if enableOtel}} branch. Node has no opentelemetry-instrument equivalent, so it preloads the ADOT distro via NODE_OPTIONS rather than wrapping the entrypoint
  • both TS templates — add @aws/aws-distro-opentelemetry-node-autoinstrumentation
  • vercelai/base/main.ts — force-enable the Vercel AI SDK's own telemetry (see below)
  • dockerfile-render.test.ts — extend to cover TypeScript

The CodeZip path needs a different mechanism (no Dockerfile to hook) and lives in aws/agentcore-l3-cdk-constructs#311.

Why the Vercel template needs an explicit telemetry toggle

Turning on ADOT was necessary but not sufficient for Vercel AI. With instrumentation loaded and traces flowing, Vercel agents still produced only network-level spans — no model spans, no gen_ai.* attributes — while Strands produced a full GenAI tree from the same runtime.

Two compounding causes:

  • ADOT's Vercel instrumentation patches the ai module at import time. Both templates are "type": "module" and load instrumentation via --require (a CJS hook), which never observes an ESM import ... from 'ai'.
  • Under CodeZip it cannot work at all: esbuild inlines ai into the bundle, so there is no module resolution event left to intercept. An ESM loader hook would have fixed Container and silently missed CodeZip.

Setting experimental_telemetry on the call site sidesteps both. ai@6 resolves the global tracer (trace.getTracer('ai') from @opentelemetry/api, shared via globalThis), which ADOT registers at startup — so it works regardless of bundling or module system. Gated on AGENT_OBSERVABILITY_ENABLED === 'true', matching ADOT's own gate.

Strands needs no equivalent: its template self-instruments via @opentelemetry/api.

Verification

Deployed all four TypeScript agent shapes to a live account, invoked each 5 times, waited for ingestion, and queried X-Ray.

All four log AWS Distro of OpenTelemetry automatic instrumentation started successfully and produce X-Ray spans including downstream Bedrock calls.

Vercel AI, before vs after:

before: SdkVercelZip.DEFAULT
- bedrock-runtime.us-east-1.amazonaws.com:443
- 169.254.169.254:80
after: SdkVercelZip.DEFAULT
- chat us.anthropic.claude-sonnet-4-5-20250929-v1:0
- chat us.anthropic.claude-sonnet-4-5-...
- bedrock-runtime.us-east-1.amazonaws.com:443

Attributes now present: gen_ai.request.model, gen_ai.response.model, gen_ai.response.finish_reasons, gen_ai.operation.name, gen_ai.provider.name, gen_ai.system. Confirmed on both CodeZip and Container.

Tests: asset suite green (141), including the new TS Dockerfile render cases.

Known cosmetic issue, not addressed here

Runtime logs show @aws/...-instrumentation-vercel-ai Failed to register VercelAISpanProcessor. It is harmless and unrelated: ADOT's setTracerProvider is called once before the real provider exists (logged at warn) and again after, when it succeeds (logged at debug, so invisible in production). It also appears for Strands agents, which have no ai package installed at all. Worth an upstream log-level fix on aws-observability/aws-otel-js-instrumentation; nothing is lost.

Follow-up

If LangChain or OpenAI-Agents TypeScript templates are added later, they will hit the same ESM/bundling wall — their ADOT instrumentation patches modules identically and will be equally inert. Each will need a per-SDK telemetry toggle, or an --import-based ESM loader hook on the Container path.

TypeScript agents received no OpenTelemetry instrumentation, so spans from any
third-party instrumentation library were silently dropped and nothing appeared
in CloudWatch. Three gaps, each sufficient on its own:
- `enableOtel` was hardcoded off for TypeScript in the render config
- the TypeScript Dockerfile had no instrumentation branch at all, so setting
`instrumentation.enableOtel` on a TS agent was a silent no-op
- neither TS template depended on an OTel SDK — only the no-op
`@opentelemetry/api`, which discards spans unless a provider is registered
This is a regression: 580cd10 ("remove OTEL, session storage, and gateway from
TS templates", #981) deleted the previous working implementation.
Node has no `opentelemetry-instrument` equivalent, so the Dockerfile preloads
the ADOT distro via NODE_OPTIONS instead of wrapping the entrypoint. The CodeZip
path is handled in @aws/agentcore-cdk.
Also force-enables the Vercel AI SDK's own telemetry. ADOT's Vercel
instrumentation patches the `ai` module at import time, which never fires under
CodeZip because esbuild inlines `ai` into the bundle, leaving no import to
intercept. Toggling the SDK's telemetry works regardless of bundling: ai@6 pulls
the global tracer that ADOT registers. Without this, Vercel agents produced only
network-level spans — no model spans, no gen_ai.* attributes. Strands is
unaffected because its template self-instruments via @opentelemetry/api.
Extends the Dockerfile render test to cover TypeScript; it previously only
exercised the Python Dockerfile, which is why this regressed unnoticed.
Verified on a live account: all four agent shapes (Strands/VercelAI x
CodeZip/Container) produce X-Ray spans, and both Vercel shapes now emit
`chat <model>` spans carrying gen_ai.request.model, gen_ai.response.model,
and gen_ai.response.finish_reasons.
@github-actions

Copy link
Copy Markdown
Contributor

Package Tarball

aws-agentcore-0.25.0.tgz

How to install

gh release download pr-1893-tarball --repo aws/agentcore-cli --pattern "*.tgz" --dir /tmp/pr-tarball
npm install -g /tmp/pr-tarball/aws-agentcore-0.25.0.tgz

@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automationagentcore-devx-automationBot removed the claude-security-reviewing Claude Code /security-review in progress label Aug 3, 2026
@github-actionsgithub-actionsBot removed the agentcore-harness-reviewing AgentCore Harness review in progress label Aug 3, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Coverage Report

StatusCategoryPercentageCovered / Total
🔵Lines40.44%15151 / 37462
🔵Statements39.71%16158 / 40680
🔵Functions34.69%2596 / 7482
🔵Branches33.82%10106 / 29880
Generated in workflow #4292 for commit f0efe1e by the Vitest Coverage Report Action

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

Labels

size/sPR size: S

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug(typescript): agentcore deploy sets up no ADOT/OTel instrumentation for TypeScript agents, silently dropping all 3p telemetry

1 participant

@jariy17
, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' fix(typescript): enable ADOT instrumentation for TypeScript agents by jariy17 · Pull Request #1893 · aws/agentcore-cli · GitHub
Skip to content

fix(typescript): enable ADOT instrumentation for TypeScript agents - #1893

Open
jariy17 wants to merge 1 commit into
mainfrom
fix/adot-typescript-observability
Open

fix(typescript): enable ADOT instrumentation for TypeScript agents#1893
jariy17 wants to merge 1 commit into
mainfrom
fix/adot-typescript-observability

Conversation

@jariy17

Copy link
Copy Markdown
Contributor

Fixes#1892
Depends on aws/agentcore-l3-cdk-constructs#311 (CodeZip path)

Problem

agentcore deploy sets up no ADOT/OpenTelemetry instrumentation for TypeScript agents. Spans from any third-party instrumentation library are silently dropped and nothing appears in CloudWatch. Three independent gaps, each sufficient on its own:

  1. enableOtel hardcoded off for TypeScriptschema-mapper.ts:
    constenableOtel=!isMcp&&config.language!=='TypeScript';
  2. The TypeScript Dockerfile had no instrumentation branch at all. The Python one branches on {{#if enableOtel}}; the TS one ended unconditionally at CMD ["npx", "tsx", "main.ts"]. So setting instrumentation.enableOtel: true on a TS agent was a silent no-op — there was nothing for it to render — while the schema documents it as wrapping the entrypoint.
  3. No OTel SDK in either TS template. Strands carried only @opentelemetry/api (the no-op API surface, which discards spans unless a provider is registered); Vercel AI carried nothing.

This is a regression

580cd10"fix(templates): remove OTEL, session storage, and gateway from TS templates", merged in #981 — deleted the working implementation: both otel-register.ts files, their imports from main.ts, seven @opentelemetry/* dependencies, and it flipped schema-mapper.ts to exclude TypeScript. The OTel removal was one commit inside a broader TS template PR, so it isn't visible from the PR title.

Changes

  • schema-mapper.ts — stop excluding TypeScript from enableOtel
  • container/typescript/Dockerfile — add the {{#if enableOtel}} branch. Node has no opentelemetry-instrument equivalent, so it preloads the ADOT distro via NODE_OPTIONS rather than wrapping the entrypoint
  • both TS templates — add @aws/aws-distro-opentelemetry-node-autoinstrumentation
  • vercelai/base/main.ts — force-enable the Vercel AI SDK's own telemetry (see below)
  • dockerfile-render.test.ts — extend to cover TypeScript

The CodeZip path needs a different mechanism (no Dockerfile to hook) and lives in aws/agentcore-l3-cdk-constructs#311.

Why the Vercel template needs an explicit telemetry toggle

Turning on ADOT was necessary but not sufficient for Vercel AI. With instrumentation loaded and traces flowing, Vercel agents still produced only network-level spans — no model spans, no gen_ai.* attributes — while Strands produced a full GenAI tree from the same runtime.

Two compounding causes:

  • ADOT's Vercel instrumentation patches the ai module at import time. Both templates are "type": "module" and load instrumentation via --require (a CJS hook), which never observes an ESM import ... from 'ai'.
  • Under CodeZip it cannot work at all: esbuild inlines ai into the bundle, so there is no module resolution event left to intercept. An ESM loader hook would have fixed Container and silently missed CodeZip.

Setting experimental_telemetry on the call site sidesteps both. ai@6 resolves the global tracer (trace.getTracer('ai') from @opentelemetry/api, shared via globalThis), which ADOT registers at startup — so it works regardless of bundling or module system. Gated on AGENT_OBSERVABILITY_ENABLED === 'true', matching ADOT's own gate.

Strands needs no equivalent: its template self-instruments via @opentelemetry/api.

Verification

Deployed all four TypeScript agent shapes to a live account, invoked each 5 times, waited for ingestion, and queried X-Ray.

All four log AWS Distro of OpenTelemetry automatic instrumentation started successfully and produce X-Ray spans including downstream Bedrock calls.

Vercel AI, before vs after:

before: SdkVercelZip.DEFAULT
- bedrock-runtime.us-east-1.amazonaws.com:443
- 169.254.169.254:80
after: SdkVercelZip.DEFAULT
- chat us.anthropic.claude-sonnet-4-5-20250929-v1:0
- chat us.anthropic.claude-sonnet-4-5-...
- bedrock-runtime.us-east-1.amazonaws.com:443

Attributes now present: gen_ai.request.model, gen_ai.response.model, gen_ai.response.finish_reasons, gen_ai.operation.name, gen_ai.provider.name, gen_ai.system. Confirmed on both CodeZip and Container.

Tests: asset suite green (141), including the new TS Dockerfile render cases.

Known cosmetic issue, not addressed here

Runtime logs show @aws/...-instrumentation-vercel-ai Failed to register VercelAISpanProcessor. It is harmless and unrelated: ADOT's setTracerProvider is called once before the real provider exists (logged at warn) and again after, when it succeeds (logged at debug, so invisible in production). It also appears for Strands agents, which have no ai package installed at all. Worth an upstream log-level fix on aws-observability/aws-otel-js-instrumentation; nothing is lost.

Follow-up

If LangChain or OpenAI-Agents TypeScript templates are added later, they will hit the same ESM/bundling wall — their ADOT instrumentation patches modules identically and will be equally inert. Each will need a per-SDK telemetry toggle, or an --import-based ESM loader hook on the Container path.

TypeScript agents received no OpenTelemetry instrumentation, so spans from any
third-party instrumentation library were silently dropped and nothing appeared
in CloudWatch. Three gaps, each sufficient on its own:
- `enableOtel` was hardcoded off for TypeScript in the render config
- the TypeScript Dockerfile had no instrumentation branch at all, so setting
`instrumentation.enableOtel` on a TS agent was a silent no-op
- neither TS template depended on an OTel SDK — only the no-op
`@opentelemetry/api`, which discards spans unless a provider is registered
This is a regression: 580cd10 ("remove OTEL, session storage, and gateway from
TS templates", #981) deleted the previous working implementation.
Node has no `opentelemetry-instrument` equivalent, so the Dockerfile preloads
the ADOT distro via NODE_OPTIONS instead of wrapping the entrypoint. The CodeZip
path is handled in @aws/agentcore-cdk.
Also force-enables the Vercel AI SDK's own telemetry. ADOT's Vercel
instrumentation patches the `ai` module at import time, which never fires under
CodeZip because esbuild inlines `ai` into the bundle, leaving no import to
intercept. Toggling the SDK's telemetry works regardless of bundling: ai@6 pulls
the global tracer that ADOT registers. Without this, Vercel agents produced only
network-level spans — no model spans, no gen_ai.* attributes. Strands is
unaffected because its template self-instruments via @opentelemetry/api.
Extends the Dockerfile render test to cover TypeScript; it previously only
exercised the Python Dockerfile, which is why this regressed unnoticed.
Verified on a live account: all four agent shapes (Strands/VercelAI x
CodeZip/Container) produce X-Ray spans, and both Vercel shapes now emit
`chat <model>` spans carrying gen_ai.request.model, gen_ai.response.model,
and gen_ai.response.finish_reasons.
@github-actions

Copy link
Copy Markdown
Contributor

Package Tarball

aws-agentcore-0.25.0.tgz

How to install

gh release download pr-1893-tarball --repo aws/agentcore-cli --pattern "*.tgz" --dir /tmp/pr-tarball
npm install -g /tmp/pr-tarball/aws-agentcore-0.25.0.tgz

@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automationagentcore-devx-automationBot removed the claude-security-reviewing Claude Code /security-review in progress label Aug 3, 2026
@github-actionsgithub-actionsBot removed the agentcore-harness-reviewing AgentCore Harness review in progress label Aug 3, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Coverage Report

StatusCategoryPercentageCovered / Total
🔵Lines40.44%15151 / 37462
🔵Statements39.71%16158 / 40680
🔵Functions34.69%2596 / 7482
🔵Branches33.82%10106 / 29880
Generated in workflow #4292 for commit f0efe1e by the Vitest Coverage Report Action

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

Labels

size/sPR size: S

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug(typescript): agentcore deploy sets up no ADOT/OTel instrumentation for TypeScript agents, silently dropping all 3p telemetry

1 participant

@jariy17
, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); fix(typescript): enable ADOT instrumentation for TypeScript agents by jariy17 · Pull Request #1893 · aws/agentcore-cli · GitHub
Skip to content

fix(typescript): enable ADOT instrumentation for TypeScript agents - #1893

Open
jariy17 wants to merge 1 commit into
mainfrom
fix/adot-typescript-observability
Open

fix(typescript): enable ADOT instrumentation for TypeScript agents#1893
jariy17 wants to merge 1 commit into
mainfrom
fix/adot-typescript-observability

Conversation

@jariy17

Copy link
Copy Markdown
Contributor

Fixes#1892
Depends on aws/agentcore-l3-cdk-constructs#311 (CodeZip path)

Problem

agentcore deploy sets up no ADOT/OpenTelemetry instrumentation for TypeScript agents. Spans from any third-party instrumentation library are silently dropped and nothing appears in CloudWatch. Three independent gaps, each sufficient on its own:

  1. enableOtel hardcoded off for TypeScriptschema-mapper.ts:
    constenableOtel=!isMcp&&config.language!=='TypeScript';
  2. The TypeScript Dockerfile had no instrumentation branch at all. The Python one branches on {{#if enableOtel}}; the TS one ended unconditionally at CMD ["npx", "tsx", "main.ts"]. So setting instrumentation.enableOtel: true on a TS agent was a silent no-op — there was nothing for it to render — while the schema documents it as wrapping the entrypoint.
  3. No OTel SDK in either TS template. Strands carried only @opentelemetry/api (the no-op API surface, which discards spans unless a provider is registered); Vercel AI carried nothing.

This is a regression

580cd10"fix(templates): remove OTEL, session storage, and gateway from TS templates", merged in #981 — deleted the working implementation: both otel-register.ts files, their imports from main.ts, seven @opentelemetry/* dependencies, and it flipped schema-mapper.ts to exclude TypeScript. The OTel removal was one commit inside a broader TS template PR, so it isn't visible from the PR title.

Changes

  • schema-mapper.ts — stop excluding TypeScript from enableOtel
  • container/typescript/Dockerfile — add the {{#if enableOtel}} branch. Node has no opentelemetry-instrument equivalent, so it preloads the ADOT distro via NODE_OPTIONS rather than wrapping the entrypoint
  • both TS templates — add @aws/aws-distro-opentelemetry-node-autoinstrumentation
  • vercelai/base/main.ts — force-enable the Vercel AI SDK's own telemetry (see below)
  • dockerfile-render.test.ts — extend to cover TypeScript

The CodeZip path needs a different mechanism (no Dockerfile to hook) and lives in aws/agentcore-l3-cdk-constructs#311.

Why the Vercel template needs an explicit telemetry toggle

Turning on ADOT was necessary but not sufficient for Vercel AI. With instrumentation loaded and traces flowing, Vercel agents still produced only network-level spans — no model spans, no gen_ai.* attributes — while Strands produced a full GenAI tree from the same runtime.

Two compounding causes:

  • ADOT's Vercel instrumentation patches the ai module at import time. Both templates are "type": "module" and load instrumentation via --require (a CJS hook), which never observes an ESM import ... from 'ai'.
  • Under CodeZip it cannot work at all: esbuild inlines ai into the bundle, so there is no module resolution event left to intercept. An ESM loader hook would have fixed Container and silently missed CodeZip.

Setting experimental_telemetry on the call site sidesteps both. ai@6 resolves the global tracer (trace.getTracer('ai') from @opentelemetry/api, shared via globalThis), which ADOT registers at startup — so it works regardless of bundling or module system. Gated on AGENT_OBSERVABILITY_ENABLED === 'true', matching ADOT's own gate.

Strands needs no equivalent: its template self-instruments via @opentelemetry/api.

Verification

Deployed all four TypeScript agent shapes to a live account, invoked each 5 times, waited for ingestion, and queried X-Ray.

All four log AWS Distro of OpenTelemetry automatic instrumentation started successfully and produce X-Ray spans including downstream Bedrock calls.

Vercel AI, before vs after:

before: SdkVercelZip.DEFAULT
- bedrock-runtime.us-east-1.amazonaws.com:443
- 169.254.169.254:80
after: SdkVercelZip.DEFAULT
- chat us.anthropic.claude-sonnet-4-5-20250929-v1:0
- chat us.anthropic.claude-sonnet-4-5-...
- bedrock-runtime.us-east-1.amazonaws.com:443

Attributes now present: gen_ai.request.model, gen_ai.response.model, gen_ai.response.finish_reasons, gen_ai.operation.name, gen_ai.provider.name, gen_ai.system. Confirmed on both CodeZip and Container.

Tests: asset suite green (141), including the new TS Dockerfile render cases.

Known cosmetic issue, not addressed here

Runtime logs show @aws/...-instrumentation-vercel-ai Failed to register VercelAISpanProcessor. It is harmless and unrelated: ADOT's setTracerProvider is called once before the real provider exists (logged at warn) and again after, when it succeeds (logged at debug, so invisible in production). It also appears for Strands agents, which have no ai package installed at all. Worth an upstream log-level fix on aws-observability/aws-otel-js-instrumentation; nothing is lost.

Follow-up

If LangChain or OpenAI-Agents TypeScript templates are added later, they will hit the same ESM/bundling wall — their ADOT instrumentation patches modules identically and will be equally inert. Each will need a per-SDK telemetry toggle, or an --import-based ESM loader hook on the Container path.

TypeScript agents received no OpenTelemetry instrumentation, so spans from any
third-party instrumentation library were silently dropped and nothing appeared
in CloudWatch. Three gaps, each sufficient on its own:
- `enableOtel` was hardcoded off for TypeScript in the render config
- the TypeScript Dockerfile had no instrumentation branch at all, so setting
`instrumentation.enableOtel` on a TS agent was a silent no-op
- neither TS template depended on an OTel SDK — only the no-op
`@opentelemetry/api`, which discards spans unless a provider is registered
This is a regression: 580cd10 ("remove OTEL, session storage, and gateway from
TS templates", #981) deleted the previous working implementation.
Node has no `opentelemetry-instrument` equivalent, so the Dockerfile preloads
the ADOT distro via NODE_OPTIONS instead of wrapping the entrypoint. The CodeZip
path is handled in @aws/agentcore-cdk.
Also force-enables the Vercel AI SDK's own telemetry. ADOT's Vercel
instrumentation patches the `ai` module at import time, which never fires under
CodeZip because esbuild inlines `ai` into the bundle, leaving no import to
intercept. Toggling the SDK's telemetry works regardless of bundling: ai@6 pulls
the global tracer that ADOT registers. Without this, Vercel agents produced only
network-level spans — no model spans, no gen_ai.* attributes. Strands is
unaffected because its template self-instruments via @opentelemetry/api.
Extends the Dockerfile render test to cover TypeScript; it previously only
exercised the Python Dockerfile, which is why this regressed unnoticed.
Verified on a live account: all four agent shapes (Strands/VercelAI x
CodeZip/Container) produce X-Ray spans, and both Vercel shapes now emit
`chat <model>` spans carrying gen_ai.request.model, gen_ai.response.model,
and gen_ai.response.finish_reasons.
@github-actions

Copy link
Copy Markdown
Contributor

Package Tarball

aws-agentcore-0.25.0.tgz

How to install

gh release download pr-1893-tarball --repo aws/agentcore-cli --pattern "*.tgz" --dir /tmp/pr-tarball
npm install -g /tmp/pr-tarball/aws-agentcore-0.25.0.tgz

@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automationagentcore-devx-automationBot removed the claude-security-reviewing Claude Code /security-review in progress label Aug 3, 2026
@github-actionsgithub-actionsBot removed the agentcore-harness-reviewing AgentCore Harness review in progress label Aug 3, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Coverage Report

StatusCategoryPercentageCovered / Total
🔵Lines40.44%15151 / 37462
🔵Statements39.71%16158 / 40680
🔵Functions34.69%2596 / 7482
🔵Branches33.82%10106 / 29880
Generated in workflow #4292 for commit f0efe1e by the Vitest Coverage Report Action

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

Labels

size/sPR size: S

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug(typescript): agentcore deploy sets up no ADOT/OTel instrumentation for TypeScript agents, silently dropping all 3p telemetry

1 participant

@jariy17