Skip to content

feat(server-utils): Rewrite SentryLangGraphInstrumentation to orchestrion#22268

Open
logaretm wants to merge 2 commits into
developfrom
feat/langgraph-orchestrion
Open

feat(server-utils): Rewrite SentryLangGraphInstrumentation to orchestrion#22268
logaretm wants to merge 2 commits into
developfrom
feat/langgraph-orchestrion

Conversation

@logaretm

@logaretm logaretm commented Jul 14, 2026

Copy link
Copy Markdown
Member

Rewrites the LangGraph integration to a node:diagnostics_channel listener instead of InstrumentationBase, with orchestrion injecting the channels. The vendored OTel path stays as the fallback when orchestrion isn't injected.

closes #20916

Rewrites the LangGraph integration to a diagnostics-channel listener
instead of `InstrumentationBase`, with orchestrion injecting the channels
into `@langchain/langgraph`'s `StateGraph.compile` and `createReactAgent`.

The subscriber creates the `create_agent` span around `compile`, wraps the
returned compiled graph's `invoke` with the shared `invoke_agent`
instrumentation, and wraps react-agent tools, reusing the existing core
span builders so span output is identical. The OTel path stays as the
fallback when orchestrion isn't injected.
@github-actions

github-actions Bot commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

size-limit report 📦

Path Size % Change Change
@sentry/browser 27.65 kB - -
@sentry/browser - with treeshaking flags 26.1 kB - -
@sentry/browser (incl. Tracing) 46.42 kB - -
@sentry/browser (incl. Tracing + Span Streaming) 48.21 kB - -
@sentry/browser (incl. Tracing, Profiling) 51.2 kB - -
@sentry/browser (incl. Tracing, Replay) 85.67 kB - -
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags 75.31 kB - -
@sentry/browser (incl. Tracing, Replay with Canvas) 90.38 kB - -
@sentry/browser (incl. Tracing, Replay, Feedback) 103.04 kB - -
@sentry/browser (incl. Feedback) 44.83 kB - -
@sentry/browser (incl. sendFeedback) 32.45 kB - -
@sentry/browser (incl. FeedbackAsync) 37.58 kB - -
@sentry/browser (incl. Metrics) 28.74 kB - -
@sentry/browser (incl. Logs) 28.98 kB - -
@sentry/browser (incl. Metrics & Logs) 29.67 kB - -
@sentry/react 29.45 kB - -
@sentry/react (incl. Tracing) 48.68 kB - -
@sentry/vue 33.08 kB - -
@sentry/vue (incl. Tracing) 48.4 kB - -
@sentry/svelte 27.67 kB - -
CDN Bundle 30.05 kB - -
CDN Bundle (incl. Tracing) 48.41 kB - -
CDN Bundle (incl. Logs, Metrics) 31.64 kB - -
CDN Bundle (incl. Tracing, Logs, Metrics) 49.71 kB - -
CDN Bundle (incl. Replay, Logs, Metrics) 70.87 kB - -
CDN Bundle (incl. Tracing, Replay) 85.9 kB - -
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) 87.21 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback) 91.7 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) 92.97 kB - -
CDN Bundle - uncompressed 89.58 kB - -
CDN Bundle (incl. Tracing) - uncompressed 146.33 kB - -
CDN Bundle (incl. Logs, Metrics) - uncompressed 94.29 kB - -
CDN Bundle (incl. Tracing, Logs, Metrics) - uncompressed 150.31 kB - -
CDN Bundle (incl. Replay, Logs, Metrics) - uncompressed 219.02 kB - -
CDN Bundle (incl. Tracing, Replay) - uncompressed 265.54 kB - -
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) - uncompressed 269.5 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed 279.24 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) - uncompressed 283.19 kB - -
@sentry/nextjs (client) 51.22 kB - -
@sentry/sveltekit (client) 46.86 kB - -
@sentry/core/server 78.59 kB +0.12% +89 B 🔺
@sentry/core/browser 64.95 kB +0.15% +95 B 🔺
@sentry/node-core 62.79 kB - -
@sentry/node 125.19 kB - -
@sentry/node (incl. diagnostics channel injection) 140.47 kB +0.36% +492 B 🔺
@sentry/node/import (ESM hook with diagnostics-channel injection) 69.96 kB - -
@sentry/node/light 50.8 kB - -
@sentry/node - without tracing 74.17 kB - -
@sentry/aws-serverless 83.38 kB -0.01% -4 B 🔽
@sentry/cloudflare (withSentry) - minified 181.79 kB - -
@sentry/cloudflare (withSentry) 449.98 kB - -

View base workflow run

@logaretm logaretm marked this pull request as ready for review July 14, 2026 21:05
@logaretm logaretm requested a review from a team as a code owner July 14, 2026 21:05
@logaretm logaretm requested review from isaacs, mydea and nicohrubec and removed request for a team July 14, 2026 21:05
Comment thread packages/server-utils/src/integrations/tracing-channel/langgraph.ts
* injected into `@langchain/langgraph`'s `StateGraph.compile` and `createReactAgent`, so it requires
* the orchestrion runtime hook or bundler plugin.
*/
export const langGraphChannelIntegration = defineIntegration(_langGraphChannelIntegration);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Missing feat integration tests

Medium Severity

This is a feat PR that adds a new orchestrion diagnostics-channel LangGraph integration, but the diff includes no integration or E2E test covering the new channel path (StateGraph.compile / createReactAgent subscribe + invoke wrapping). Existing OTel suite coverage does not validate this rewrite. Flagged because the review rules require at least one integration or E2E test on feat PRs.

Fix in Cursor Fix in Web

Triggered by project rule: PR Review Guidelines for Cursor Bot

Reviewed by Cursor Bugbot for commit 5b8c0af. Configure here.

Comment thread packages/core/src/tracing/langgraph/index.ts
- Set the createReactAgent suppression flag only after wrapping tools, so a
  throw there can't leave it stuck on and permanently suppress create_agent spans.
- Route instrumentStateGraphCompile through _INTERNAL_getLangGraphCreateAgentSpanOptions
  so the create_agent span options have a single source of truth.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

There are 2 total unresolved issues (including 1 from previous review).

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 90d1118. Configure here.

}
// Set only after tool wrapping so a throw there can't leave the flag stuck on and permanently
// suppress `create_agent` spans. The flag must be on before the body runs its internal compile.
insideCreateReactAgent = true;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Flag unset if tool wrap throws

Low Severity

insideCreateReactAgent is set only after wrapToolsWithSpans. If that call throws, diagnostics_channel still runs createReactAgent, so the suppress flag stays off. The nested compile then opens a create_agent span and wraps invoke, and the end handler wraps invoke again, producing duplicate invoke_agent spans. The OTel path aborts before the original call when tool wrapping throws.

Fix in Cursor Fix in Web

Triggered by project rule: PR Review Guidelines for Cursor Bot

Reviewed by Cursor Bugbot for commit 90d1118. Configure here.

@linear-code

linear-code Bot commented Jul 14, 2026

Copy link
Copy Markdown

JS-2489


// `createReactAgent` compiles a `StateGraph` internally; suppress the `create_agent` span for that
// nested compile so a react agent gets a single `invoke_agent` span, matching the OTel path.
let insideCreateReactAgent = false;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Bug: The module-level insideCreateReactAgent flag is not concurrency-safe, leading to race conditions where one request's state can cause incorrect span suppression in another unrelated request.
Severity: HIGH

Suggested Fix

Replace the module-level insideCreateReactAgent flag with a request-scoped state management solution, such as AsyncLocalStorage. This will ensure that the flag's state is isolated to the specific asynchronous context of each request, preventing interference between concurrent operations.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.

Location: packages/server-utils/src/integrations/tracing-channel/langgraph.ts#L39

Potential issue: The `insideCreateReactAgent` flag, declared as a module-level
singleton, is modified by event subscribers for `reactAgentChannel`. In a concurrent
environment like a Node.js server, this creates a race condition. If one request calls
`createReactAgent` and sets the flag, a simultaneous, unrelated request to
`StateGraph.compile` will read the globally set flag and incorrectly suppress its
`create_agent` span. This happens because the event callbacks operate in a shared module
context, unlike the OTel path which uses a synchronous `try/finally` block to scope the
flag's state.

Also affects:

  • packages/server-utils/src/integrations/tracing-channel/langgraph.ts:63~63
  • packages/server-utils/src/integrations/tracing-channel/langgraph.ts:99~99
  • packages/server-utils/src/integrations/tracing-channel/langgraph.ts:102~102
  • packages/server-utils/src/integrations/tracing-channel/langgraph.ts:110~110

Did we get this right? 👍 / 👎 to inform future reviews.

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.

Rewrite SentryLangGraphInstrumentation to orchestrion

1 participant