microsoft / microsoft/agent-framework
Python: [Bug]: Streaming Agent telemetry fails across FastAPI/Azure Functions response context
@moonbox3 is already working on this.
Since Aug 19, 2026.
- Dominant language
- Python
- Stars
- 13.6k
- Forks
- 2.3k
- Avg merge
- 2d 45m
- Merged PRs (30d)
- 358
Description
### Description
### What happened?
With native Microsoft Agent Framework telemetry enabled, consuming an `Agent.run(..., stream=True)` response through a FastAPI/Azure Functions `StreamingResponse` fails during telemetry finalization.
The response stream is created in the request context and consumed by the ASGI response task. MAF stores a `ContextVar` token when creating the stream and later resets it while finalizing in the consuming context. Python rejects that reset because the token was created in a different context.
The model response may stream successfully, but cleanup then raises `ValueError`. This can terminate the SSE response and means native MAF telemetry cannot be safely enabled.
Disabling MAF instrumentation makes the same streaming execution complete normally.
### Expected behavior
The stream should complete normally and MAF should export its agent/model/tool spans. Telemetry must not change or fail agent execution when an ASGI host consumes a stream in another task or copied context.
### Steps to reproduce
1. Enable native MAF instrumentation.
2. Create an agent response with `agent.run("Hello", stream=True)` during an HTTP request.
3. Return an ASGI/FastAPI `StreamingResponse` that consumes that response.
4. Exhaust/finalize the stream.
5. Observe the `ContextVar` token-reset exception during MAF telemetry cleanup.
### Code Sample
```markdown
from fastapi import FastAPI
from fastapi.responses import StreamingResponse
from agent_framework.observability import configure_otel_providers
app = FastAPI()
configure_otel_providers()
# agent is a normally configured Microsoft Agent Framework Agent.
@app.post("/agent")
async def run_agent():
# Created in the request context.
stream = agent.run("Hello", stream=True)
# StreamingResponse consumes this iterator in the ASGI response context.
async def consume():
async for update in stream:
yield f"data: {update.text}\n\n"
return StreamingResponse(consume(), media_type="text/event-stream")
A reduced cross-task lifecycle has the same shape:
stream = agent.run("Hello", stream=True)
async def consume():
return [update async for update in stream]
updates = await asyncio.create_task(consume())
```
### Error Messages / Stack Traces
```markdown
ValueError: >
was created in a different Context
The relevant stack terminates in:
agent_framework/_types.py ResponseStream cleanup hooks
agent_framework/observability.py _finalize_stream
INNER_RESPONSE_TELEMETRY_CAPTURED_FIELDS.reset(token)
```
### Package Versions
agent-framework-core: 1.13.0agent-framework-openai: 1.12.0agent-framework-orchestrations: 1.0.2azure-functions: 1.25.0azurefunctions-extensions-http-fastapi: 1.0.1fastapi: 0.141.1starlette: 1.6.0opentelemetry-api/sdk: 1.43.0
### Python Version
Python 3.11.13
### Additional Context
This appears related to:
- #6762
- #6764
PR #6764 fixed the non-streaming/background-agent path by moving `ContextVar` creation into the awaited coroutine. The streaming path was explicitly left unchanged, and review discussion noted that streaming cleanup could run in a different consuming context. This report covers that remaining streaming variant.
This usage also matches the framework's documented streaming API and the repository's ChatKit/FastAPI `StreamingResponse` integration pattern.
Suggested regression coverage:
1. Create an instrumented `Agent.run(..., stream=True)` response.
2. Consume it inside `asyncio.create_task()` or an ASGI `StreamingResponse`.
3. Exhaust and finalize the stream.
4. Verify no `ContextVar` reset exception occurs and the telemetry span completes.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.