feat(core): Instrument langgraph createReactAgent#20344
Conversation
6aa24b0 to
09a4132
Compare
size-limit report 📦
|
09a4132 to
e2d8d45
Compare
e2d8d45 to
7bcbcae
Compare
2dc7fd2 to
fcaa34b
Compare
fcaa34b to
b86d7cc
Compare
b86d7cc to
d4c61a2
Compare
Add instrumentation for LangGraph's `createReactAgent` API with full span hierarchy: invoke_agent, gen_ai.chat, and execute_tool. createReactAgent wrapping: - Extract agent name, LLM model, and tools from params - Wrap compiled graph's invoke() with invoke_agent span - Wrap tool invoke() with execute_tool spans (name, type, description, arguments, result) - Inject LangChain callback handler + lc_agent_name metadata at invoke level for chat span creation and agent name propagation to all child spans - Suppress StateGraph.compile instrumentation inside createReactAgent to avoid duplicate spans LangChain callback handler improvements: - Read gen_ai.agent.name from metadata.lc_agent_name - Suppress chain and tool callback spans inside agent context to avoid duplicates with our direct instrumentation - Extract tool definitions from extraParams in handleChatModelStart - Use runName for tool name (set by LangChain's StructuredTool) - Add gen_ai.operation.name to tool spans - Extract ToolMessage .content in handleToolEnd BREAKING: addToolCallsAttributes now reads from message.tool_calls (LangChain's normalized format) instead of scanning message.content for Anthropic-style tool_use items. This fixes duplicate tool calls on Anthropic chat spans but changes the tool call format in gen_ai.response.tool_calls from Anthropic-native to LangChain- normalized (args instead of input, type: tool_call instead of tool_use). OTel module patching: - Patch @langchain/langgraph/prebuilt for createReactAgent (ESM + CJS file patches for dist/prebuilt/index.cjs) Exports: - instrumentCreateReactAgent from core, browser, cloudflare Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
5412f98 to
0da2278
Compare
| export { LANGCHAIN_INTEGRATION_NAME } from './tracing/langchain/constants'; | ||
| export type { LangChainOptions, LangChainIntegration } from './tracing/langchain/types'; | ||
| export { instrumentStateGraphCompile, instrumentLangGraph } from './tracing/langgraph'; | ||
| export { instrumentStateGraphCompile, instrumentCreateReactAgent, instrumentLangGraph } from './tracing/langgraph'; |
There was a problem hiding this comment.
h: So if I understand correctly right now users need instrumentCreateReactAgent for the agent and instrumentLangGraph for the StateGraph, right? I think now that we have the separate API instrumentLangGraph for the StateGraph might actually be a bit confusing, wdyt? I guess ideally what we would probably do is to merge this into one, detect what we are given and then handle the patching internally. Can we do this with the current approach?
There was a problem hiding this comment.
This is certainly valid and a bit confusing. I do think it's better to have two functions here, these are for manual instrumenting, so it's clearer what they both do.
That being said, let's rename instrumentLangGraph to instrumentStateGraph as you suggested in #20584.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 565b49f. Configure here.
nicohrubec
left a comment
There was a problem hiding this comment.
nice! thanks for the updates, lgtm

This PR adds instrumentation for LangGraph's
createReactAgentAPI.createReactAgent wrapping
invoke()withinvoke_agentspaninvoke()withexecute_toolspans (name, type, description, arguments, result)lc_agent_name+__sentry_langgraph__metadata at invoke level for chat span creation and agent name propagation to all child spansStateGraph.compileinstrumentation insidecreateReactAgentto avoid duplicate spansLangChain callback handler improvements
gen_ai.agent.namefrommetadata.lc_agent_name(convention from newer LangGraphcreateAgent, adopted for our supported versions)metadata.__sentry_langgraph__presence) to avoid duplicates with our direct instrumentationextraParamsinhandleChatModelStartand setsgen_ai.request.available_toolson chat spansrunNamefor tool name inhandleToolStart(set by LangChain'sStructuredTool.call()) — fixesunknown_toolissuegen_ai.operation.nameto tool spans.contentfrom ToolMessage objects inhandleToolEndinstead of serializing the full wrapperaddToolCallsAttributesnow prefersmessage.tool_calls(LangChain's normalized format) over scanningmessage.contentfor Anthropic-styletool_useitems, fixing duplicate tool calls on Anthropic chat spans. Falls back tomessage.contentscanning for older LangChain versions.OTel module patching
@langchain/langgraph/prebuiltforcreateReactAgent(ESM + CJS file patches fordist/prebuilt/index.cjs)Exports
instrumentCreateReactAgentfrom core, browser, cloudflareCloses: #19372