Python: Fix AG-UI conversation correlation across runs - #7430
Open
moonbox3 wants to merge 3 commits into
Open
Conversation
Contributor
Contributor
There was a problem hiding this comment.
Pull request overview
This PR fixes AG-UI trace/snapshot correlation in the Python adapter by keeping client-supplied threadId/runId as the authoritative lifecycle identifiers, while introducing a scoped OpenTelemetry conversation override so spans can still correlate across runs. It also adds an end-to-end single-agent AG-UI sample (FastAPI backend + React frontend) demonstrating stable thread IDs and per-turn run IDs.
Changes:
- Add a scoped, application-managed OTel conversation-id override and apply it from AG-UI agent/workflow streaming paths so
gen_ai.conversation.idcan remain stable across runs. - Update AG-UI adapter logic so provider
conversation_id/response_idonly become fallbacks when the request omittedthreadId/runId. - Add a complete single-agent sample app (backend + frontend) plus regression tests validating snapshot keying and span correlation.
Reviewed changes
Copilot reviewed 18 out of 20 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| python/packages/core/agent_framework/observability.py | Introduces scoped conversation-id override and applies it to agent/workflow span attributes. |
| python/packages/core/tests/core/test_observability.py | Adds unit tests validating override scoping and workflow span behavior. |
| python/packages/ag-ui/agent_framework_ag_ui/_run_common.py | Adds helper to iterate async streams while re-establishing execution context per pull. |
| python/packages/ag-ui/agent_framework_ag_ui/_agent_run.py | Preserves supplied AG-UI IDs, scopes telemetry override across stream construction and pulls, and keeps provider IDs as fallbacks. |
| python/packages/ag-ui/agent_framework_ag_ui/_workflow_run.py | Applies telemetry override and iterates workflow stream with per-pull context. |
| python/packages/ag-ui/tests/ag_ui/test_endpoint.py | Adds regression tests ensuring snapshots and spans correlate to supplied thread_id. |
| python/packages/ag-ui/tests/ag_ui/test_workflow_run.py | Adds regression test ensuring workflow + nested agent spans use supplied thread_id. |
| python/samples/05-end-to-end/ag_ui_single_agent/README.md | Documents the new single-agent demo, expected flow, and trace correlation behavior. |
| python/samples/05-end-to-end/ag_ui_single_agent/backend/server.py | Adds FastAPI backend hosting a Foundry-backed Agent via the AG-UI endpoint with snapshot storage. |
| python/samples/05-end-to-end/ag_ui_single_agent/frontend/package.json | Adds React/Vite frontend package definition for the demo. |
| python/samples/05-end-to-end/ag_ui_single_agent/frontend/package-lock.json | Locks frontend dependencies for the demo. |
| python/samples/05-end-to-end/ag_ui_single_agent/frontend/vite.config.ts | Vite dev server config for the demo frontend. |
| python/samples/05-end-to-end/ag_ui_single_agent/frontend/tsconfig.json | Frontend TS config for app sources. |
| python/samples/05-end-to-end/ag_ui_single_agent/frontend/tsconfig.node.json | Frontend TS config for Vite/node-side config compilation. |
| python/samples/05-end-to-end/ag_ui_single_agent/frontend/index.html | Frontend HTML entrypoint. |
| python/samples/05-end-to-end/ag_ui_single_agent/frontend/.gitignore | Ignores node_modules and build artifacts for the demo frontend. |
| python/samples/05-end-to-end/ag_ui_single_agent/frontend/src/vite-env.d.ts | Vite client type reference for TS. |
| python/samples/05-end-to-end/ag_ui_single_agent/frontend/src/main.tsx | React entrypoint wiring the App and CSS. |
| python/samples/05-end-to-end/ag_ui_single_agent/frontend/src/styles.css | Styling for the demo chat UI. |
| python/samples/05-end-to-end/ag_ui_single_agent/frontend/src/App.tsx | Implements AG-UI SSE streaming client with stable thread IDs and per-run IDs. |
Files not reviewed (1)
- python/samples/05-end-to-end/ag_ui_single_agent/frontend/package-lock.json: Generated file
moonbox3
marked this pull request as ready for review
July 30, 2026 09:55
eavanvalkenburg
approved these changes
Jul 30, 2026
moonbox3
enabled auto-merge
July 30, 2026 10:34
Contributor
Author
|
/review |
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.
Motivation & Context
AG-UI clients use one stable thread identifier for a conversation and a new run identifier for each interaction. The Python agent adapter could replace those request identifiers with conversation or response identifiers returned by the chat provider. With
FoundryChatClient, this split turns from one AG-UI thread across separate Foundry trace conversations and could key thread snapshots by a provider identifier instead of the AG-UI thread.This change keeps protocol lifecycle identity separate from provider-side continuation identity and adds a complete single-agent sample that demonstrates multi-turn FoundryChatClient usage with trace correlation.
Description & Review Guide
threadIdandrunIdas the authoritative AG-UI lifecycle identifiers, while retaining provider identifiers as fallbacks and for provider-side continuation. Propagate the stable AG-UI thread through agent and workflow telemetry, including async stream pulls, and add regression coverage for snapshots and spans. Add a FoundryChatClient FastAPI and React sample with stable thread IDs, per-turn run IDs, snapshot storage, and optional Azure Monitor setup.gen_ai.conversation.idin traces, while each run keeps its own trace. Existing callers that omit AG-UI identifiers retain provider-ID fallback behavior. This is not a breaking API or protocol change.Related Issue
Fixes #7429
Contribution Checklist
breaking changelabel (or add "[BREAKING]" to the title prefix, before or after any language prefix) — a workflow keeps the label and the title prefix in sync automatically.