Skip to content

feat(server-utils): Emit low-cardinality gen_ai agent span names when streaming - #23582

Merged
RulaKhaled merged 11 commits into
developfrom
rolaabuhasna/js-3409-emit-low-cardinality-gen_ai-agent-span-names
Aug 28, 2026
Merged

RulaKhaled merged 11 commits into
developfrom
rolaabuhasna/js-3409-emit-low-cardinality-gen_ai-agent-span-names

Conversation

@RulaKhaled

@RulaKhaled RulaKhaled commented Aug 25, 2026

Copy link
Copy Markdown
Collaborator

With span streaming enabled (the default), gen_ai.invoke_agent names follow the agent span name conventions: {operation} {name} from gen_ai.agent.name, gen_ai.pipeline.name or gen_ai.function_id, otherwise {operation}.

In practice this only changes LangChain chain spans, and only their prefix. They were named chain format_prompt, which does not lead with the operation like every other agent span; they are now invoke_agent format_prompt. The chain name itself is bounded, so it stays in the name. A chain the SDK cannot name falls back to invoke_agent rather than carrying the unknown_chain sentinel, the same way a missing model is dropped in #23573.

LangGraph agent names and Vercel AI functionIds are unchanged in both lifecycles — both are bounded, low-cardinality values.

The pipeline.name and function_id templates are added in getsentry/sentry-conventions#593. LangChain still emits its chain name on langchain.chain.name; moving it to gen_ai.pipeline.name is tracked in JS-3452 and should land before v11 ships, so the emitted name matches a published template. Span names are unaffected by that move — they are built from the local chain name, not read back off the attribute.

The other two ops in the agent rule need nothing: the SDK emits no gen_ai.handoff spans, and gen_ai.create_agent was dropped in v11. Neither is listed in the migration table.

The migration entry lives in MIGRATION.md rather than docs/migration/v11-end-state.md, which was removed by #23623.

Fixes #23524

… streaming

Fixes #23524

Co-Authored-By: Cursor <cursoragent@cursor.com>
@linear-code

linear-code Bot commented Aug 25, 2026

Copy link
Copy Markdown

JS-3409

JS-3452

@github-actions

github-actions Bot commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

size-limit report 📦

⚠️ Warning: Base artifact is not the latest one, because the latest workflow run is not done yet. This may lead to incorrect results. Try to re-run all tests to get up to date results.

Path Size % Change Change
@sentry/browser 28.57 kB - -
@sentry/browser - with treeshaking flags 26.92 kB - -
@sentry/browser - with treeshaking flags tracing without tracing 26.82 kB - -
@sentry/browser (incl. Tracing) 48.63 kB - -
@sentry/browser (incl. Tracing + Span Streaming) 48.65 kB - -
@sentry/browser (incl. Tracing, Profiling) 51.56 kB - -
@sentry/browser (incl. Tracing, Replay) 88.11 kB - -
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags 77.51 kB - -
@sentry/browser (incl. Tracing, Replay with Canvas) 92.82 kB - -
@sentry/browser (incl. Tracing, Replay, Feedback) 105.51 kB - -
@sentry/browser (incl. Feedback) 45.79 kB - -
@sentry/browser (incl. sendFeedback) 33.35 kB - -
@sentry/browser (incl. FeedbackAsync) 38.46 kB - -
@sentry/browser (incl. Metrics) 29.51 kB - -
@sentry/browser (incl. Logs) 29.8 kB - -
@sentry/browser (incl. Metrics & Logs) 30.43 kB - -
@sentry/react 30.31 kB - -
@sentry/react (incl. Tracing) 50.84 kB - -
@sentry/vue 35.69 kB - -
@sentry/vue (incl. Tracing) 50.88 kB - -
@sentry/svelte 28.59 kB - -
CDN Bundle 30.36 kB - -
CDN Bundle (incl. Tracing) 49.12 kB - -
CDN Bundle (incl. Logs, Metrics) 32.56 kB - -
CDN Bundle (incl. Tracing, Logs, Metrics) 51.01 kB - -
CDN Bundle (incl. Replay, Logs, Metrics) 73 kB - -
CDN Bundle (incl. Tracing, Replay) 86.62 kB - -
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) 88.52 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback) 92.4 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) 94.33 kB - -
CDN Bundle - uncompressed 89.97 kB - -
CDN Bundle (incl. Tracing) - uncompressed 146.82 kB - -
CDN Bundle (incl. Logs, Metrics) - uncompressed 96.26 kB - -
CDN Bundle (incl. Tracing, Logs, Metrics) - uncompressed 152.51 kB - -
CDN Bundle (incl. Replay, Logs, Metrics) - uncompressed 225.42 kB - -
CDN Bundle (incl. Tracing, Replay) - uncompressed 266.32 kB - -
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) - uncompressed 272 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed 280.01 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) - uncompressed 285.68 kB - -
@sentry/nextjs (client) 53.41 kB - -
@sentry/sveltekit (client) 49.08 kB - -
@sentry/core/server 65.15 kB - -
@sentry/core/browser 52 kB - -
@sentry/node 122.72 kB +0.04% +46 B 🔺
@sentry/node/import (ESM hook with diagnostics-channel injection) 85.22 kB - -
@sentry/node - without tracing 87.73 kB +0.03% +25 B 🔺
@sentry/node - without channel injection 102.39 kB +0.05% +48 B 🔺
@sentry/aws-serverless 95.88 kB +0.03% +27 B 🔺
@sentry/cloudflare (withSentry) - minified 199.61 kB - -
@sentry/cloudflare (withSentry) 495.94 kB - -

View base workflow run

RulaKhaled and others added 3 commits August 25, 2026 16:03
Streamed invoke_agent names should be derivable from attributes, not only from the span name.

Co-Authored-By: Cursor <cursoragent@cursor.com>
…09-emit-low-cardinality-gen_ai-agent-span-names

# Conflicts:
#	docs/migration/v11-end-state.md
#	packages/server-utils/src/ai/langchain/index.ts
@RulaKhaled
RulaKhaled marked this pull request as ready for review August 27, 2026 11:03
@RulaKhaled
RulaKhaled requested review from a team as code owners August 27, 2026 11:03
@RulaKhaled
RulaKhaled requested review from JPeer264 and isaacs and removed request for a team August 27, 2026 11:03

@Lms24 Lms24 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.

Had one last question, otherwise LGTM!

expect(span.data?.[GEN_AI_FUNCTION_ID]).toBe('weather_agent');
});

it('uses `invoke_agent` when span streaming is enabled', () => {

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.

q: is gen_ai.function.id the same as gen_ai.agent.name? Just wondering if we can preserve the name here as well, similarly to the execute tool one.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

they're different, gen_ai.agent.name is the name of the agent but gen_ai.function.id is more of a tracing label. i guess we can treat it same as execute tool

RulaKhaled and others added 3 commits August 27, 2026 13:10
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…t` span names

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…agent` names

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
RulaKhaled added a commit that referenced this pull request Aug 27, 2026
…eaming (#23573)

When span streaming is enabled, gen_ai inference span names follow the
inference templates: `{operation} {model}` when a model is known,
`{operation}` when it is not. Instrumented methods always have an
operation, so the convention fallback `Generative AI model operation` is
not emitted today.

`traceLifecycle: 'static'` keeps the previous names (`chat unknown`).
Known models stay in the name in both lifecycles (`chat gpt-4`).

The inference ops the SDK emits are `gen_ai.chat`, `gen_ai.embeddings`,
`gen_ai.generate_content` and `gen_ai.rerank` — the last three were only
added to the conventions' inference rule in
[sentry-conventions#579](getsentry/sentry-conventions#579),
but the naming here is derived from the operation rather than hardcoded
per op, so they were already covered. The Vercel AI channel path never
emitted an `unknown` model sentinel, so its names were already
conformant; a test now locks that in. The SDK emits no
`gen_ai.responses` or `gen_ai.text_completion` spans.

`gen_ai.execute_tool` spans keep the tool name in their name
(`execute_tool getWeather`) — the tool name is a bounded, resolved
value, so it behaves like a known model rather than a high-cardinality
identifier. Agent ops (`gen_ai.invoke_agent`, `gen_ai.create_agent`,
`gen_ai.handoff`) are out of scope here and handled in #23582
(`JS-3409`).

Fixes #23525
…09-emit-low-cardinality-gen_ai-agent-span-names

# Conflicts:
#	MIGRATION.md
@RulaKhaled
RulaKhaled requested a review from Lms24 August 27, 2026 13:17
RulaKhaled and others added 2 commits August 28, 2026 10:22
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@RulaKhaled
RulaKhaled merged commit 184b45a into develop Aug 28, 2026
278 checks passed
@RulaKhaled
RulaKhaled deleted the rolaabuhasna/js-3409-emit-low-cardinality-gen_ai-agent-span-names branch August 28, 2026 09:36
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.

Emit low cardinality gen_ai agent span names

2 participants