Python: fix: establish correct span parenting during streaming agent invocation#5098
Open
JasonOA888 wants to merge 1 commit intomicrosoft:mainfrom
Open
Python: fix: establish correct span parenting during streaming agent invocation#5098JasonOA888 wants to merge 1 commit intomicrosoft:mainfrom
JasonOA888 wants to merge 1 commit intomicrosoft:mainfrom
Conversation
When stream=True, agent-invoke spans were not set as the active OTel context, causing child spans (chat completion, execute_tool) to appear as siblings rather than children of invoke_agent. The original code avoided trace.use_span() for streaming spans due to "Failed to detach context" errors when cleanup hooks run in a different async context. Fix: introduce _STREAMING_AGENT_INVOKE_CONTEXT ContextVar that holds the OTel context with the agent-invoke span. Child spans read from this to establish correct parent-child relationships without needing use_span()/attach(). Closes microsoft#5089
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Closes #5089
When
stream=True, theinvoke_agentspan is not activated as the current OTel context. Child spans (chat,execute_tool) are created without a parent reference and appear as siblings instead of children.Root Cause
The streaming path in
_trace_agent_invocationuses bareget_tracer().start_span()without context activation. The original code deliberately avoidedtrace.use_span()because streaming spans are closed in cleanup hooks that run in a different async context, causing "Failed to detach context" errors.Fix
Introduce
_STREAMING_AGENT_INVOKE_CONTEXT— acontextvars.ContextVarthat holds the OTel context with the agent-invoke span set as current.Three changes:
_trace_agent_invocation(streaming path): After creating theinvoke_agentspan, storetrace.set_span_in_context(span)in the ContextVar. Reset in_close_span._trace_chat_response(streaming path): Read the ContextVar and pass ascontext=tostart_span(), so chat spans become children ofinvoke_agent.get_function_span: Read the ContextVar and pass ascontext=tostart_as_current_span(), soexecute_toolspans become children ofinvoke_agent.This avoids
use_span()/attach()entirely — no detach errors — while propagating parent context via Python contextvars.Testing
Files Changed
python/packages/core/agent_framework/observability.py(+32 lines)