[opentelemetry-instrumentation-genai-langchain] Set gen_ai.agent.name on child execute_tool spans - #512
Conversation
2fb06f5 to
4f416f3
Compare
There was a problem hiding this comment.
Pull request overview
This PR improves trace correlation for LangChain agent workflows by ensuring gen_ai.agent.name is present not only on invoke_agent spans but also on child chat and execute_tool spans, enabling downstream systems to reliably associate those child operations with the enclosing agent.
Changes:
- Added an optional
agent_namekwarg toTelemetryHandler.inference()andTelemetryHandler.tool()and plumbed it into the corresponding invocation types so spans can carrygen_ai.agent.name. - Updated the LangChain callback handler to resolve the nearest enclosing agent via
_find_nearest_agent(...)and pass its name intoinference(...)andtool(...). - Added targeted tests in util-genai and langchain to validate span attributes and to ensure metric attribute sets remain unchanged.
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| util/opentelemetry-util-genai/src/opentelemetry/util/genai/handler.py | Extends the util’s public factory APIs (inference, tool) with agent_name and forwards it into invocations. |
| util/opentelemetry-util-genai/src/opentelemetry/util/genai/_inference_invocation.py | Stores agent_name and applies gen_ai.agent.name to chat spans (without affecting metrics). |
| util/opentelemetry-util-genai/src/opentelemetry/util/genai/_tool_invocation.py | Stores agent_name and includes gen_ai.agent.name in tool span start attributes. |
| instrumentation/opentelemetry-instrumentation-genai-langchain/src/opentelemetry/instrumentation/genai/langchain/callback_handler.py | Resolves nearest agent context and propagates agent_name onto child chat and execute_tool invocations. |
| util/opentelemetry-util-genai/tests/test_toolcall.py | Adds unit coverage for execute_tool spans carrying/omitting gen_ai.agent.name, including sampler-time visibility. |
| util/opentelemetry-util-genai/tests/test_handler_metrics.py | Verifies gen_ai.agent.name is present on spans but does not leak into existing metric attribute sets. |
| instrumentation/opentelemetry-instrumentation-genai-langchain/tests/test_tools.py | Adds LangChain callback tests for agent-name propagation (single agent, nested agents, and no-agent baselines). |
| util/opentelemetry-util-genai/.changelog/512.added | Documents the new optional agent_name kwarg on util-genai APIs. |
| instrumentation/opentelemetry-instrumentation-genai-langchain/.changelog/512.fixed | Documents the LangChain fix for propagating agent name to child spans. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
…ame` on child `execute_tool` spans
4f416f3 to
36fb43c
Compare
opentelemetry-instrumentation-genai-langchain] Set gen_ai.agent.name on child chat and execute_tool spansopentelemetry-instrumentation-genai-langchain] Set gen_ai.agent.name on child execute_tool spans
Pull request dashboard statusWaiting on the author · refreshed 2026-08-31 23:18 UTC Respond to 2 review items (e.g. link a commit, explain why not, ask a follow-up): Status above doesn't look right?
|
| tool_call_id: str | None = None, | ||
| tool_type: str | None = None, | ||
| tool_description: str | None = None, | ||
| agent_name: str | None = None, |
There was a problem hiding this comment.
this is not one of the sampling-relevant attributes according to semconv https://github.com/open-telemetry/semantic-conventions-genai/blob/67dff024110be5bd9f318006e733f4078e0f4c97/docs/gen-ai/gen-ai-spans.md?plain=1#L1190-L1195, so it should not be set at the start time.
I can see why it should be one of them, mind sending a PR to semantic-conventions-genai to fix it?
| self.assertAlmostEqual(duration_point.sum, 1.5, places=3) | ||
| self.assertNotIn("gen_ai.client.token.usage", metrics) | ||
|
|
||
| def test_stop_tool_does_not_leak_agent_name_to_duration_metric( |
There was a problem hiding this comment.
why so?
it's an attribute on duration metric https://github.com/open-telemetry/semantic-conventions-genai/blob/main/docs/gen-ai/gen-ai-metrics.md#metric-gen_aiexecute_toolduration
Or maybe we didn't update this repo yet to report relatively new gen_ai.execute_tool.duration metric
rads-1996
left a comment
There was a problem hiding this comment.
I am thinking if it would be a good idea to also add the agent.id attribute. I can take it up in a separate PR, if it can't be part of this one.
Description
gen_ai.agent.nameis listed as Conditionally Required — "When applicable" on theexecute_toolspan in semconv, but the LangChain callback never set it, so tool spans running under aninvoke_agentcould not be joined back to their agent. Add anagent_namekwarg onTelemetryHandler.tool(); the LangChain callback resolves it via the existing_find_nearest_agent. Metric attribute sets are unchanged (the sharedgen_ai.client.operation.durationmetric does not listgen_ai.agent.nametoday, and util-genai does not emitgen_ai.execute_tool.duration).Type of change
How has this been tested?
New unit tests in
tests/test_tools.py(langchain) cover single agent, nested agents (nearest wins), and no-agent baseline. Tests intest_toolcall.pyandtest_handler_metrics.py(util-genai) assert the attribute lands on the span but not ongen_ai.client.operation.duration.util-genaisuite: 334 passedlangchainsuite: 237 passedtox -e precommit(ruff, ruff-format) andpyrightcleanChecklist