Skip to content

Python: implement ADR-0029 service_session_id lifecycle mapping#6724

Open
eavanvalkenburg wants to merge 5 commits into
microsoft:mainfrom
eavanvalkenburg:python-service-session-id-adr-0029
Open

Python: implement ADR-0029 service_session_id lifecycle mapping#6724
eavanvalkenburg wants to merge 5 commits into
microsoft:mainfrom
eavanvalkenburg:python-service-session-id-adr-0029

Conversation

@eavanvalkenburg

Copy link
Copy Markdown
Member

Motivation & Context

This implements the accepted ADR-0029 decision for Python session identity lifecycles, where durable provider continuation state lives in AgentSession.service_session_id and can be structured when needed (A2A immediate case).

It addresses the current mismatch between lifecycle intent and implementation by separating:

  • durable future-call continuation state,
  • per-run/request identity forwarding,
  • telemetry conversation id extraction.

This work follows the design direction that originated in #4893 and was finalized in ADR-0029.

Description & Review Guide

  • What are the major changes?

  • Extend core session typing so service_session_id supports str | ServiceSessionId | None.

  • Add agent-owned conversation-id extraction hooks in core:

    • _get_chat_conversation_id(...) for generic provider forwarding (string-only; early error on incompatible structured values)
    • _get_otel_conversation_id(...) for telemetry mapping.
  • Update AgentTelemetryLayer to use the agent extraction hook instead of directly reading session.service_session_id.

  • Introduce A2AServiceSessionId and migrate A2A durable state (context_id, task_id, task_state) to structured service_session_id.

  • Keep A2AAgentSession as compatibility shim and emit a deprecation warning.

  • Update lazy exports/stubs and core/a2a tests accordingly.

  • What is the impact of these changes?

  • Aligns Python behavior with ADR-0029 lifecycle rules.

  • Enables structured durable continuation state for A2A without overloading generic chat forwarding.

  • Improves failure mode for incompatible sessions by raising early in generic chat paths.

  • Preserves backward compatibility for existing serialized string sessions and existing A2A usage (with deprecation guidance).

  • What do you want reviewers to focus on?

  • Correctness of lifecycle boundaries between session continuation, request forwarding, and telemetry.

  • A2A mapping semantics for context_id / task_id / task_state and compatibility behavior.

  • Whether early error behavior in generic chat paths is appropriately scoped and actionable.

Related Issue

Fixes #4673
Related to #4893

Contribution Checklist

  • The code builds clean without any errors or warnings
  • All unit tests pass, and I have added new tests where possible
  • The PR follows the Contribution Guidelines
  • This PR is linked to an issue and there is no other open PR for this issue (see Related Issue above).
  • This is not a breaking change. If it is a breaking change, add the breaking change label (or add "[BREAKING]" to the title prefix, before or after any language prefix) — a workflow keeps the label and title prefix in sync automatically.

- Extend AgentSession service_session_id to support structured values
- Add agent-owned conversation id extraction for chat forwarding and telemetry
- Migrate A2A durable continuation state to A2AServiceSessionId
- Keep A2AAgentSession as compatibility shim and mark it deprecated
- Update core/a2a tests and package guidance

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings June 25, 2026 06:47
@moonbox3 moonbox3 added documentation Usage: [Issues, PRs], Target: documentation in the code base and learn docs python Usage: [Issues, PRs], Target: Python labels Jun 25, 2026
@github-actions github-actions Bot changed the title python: implement ADR-0029 service_session_id lifecycle mapping Python: implement ADR-0029 service_session_id lifecycle mapping Jun 25, 2026
@github-actions

github-actions Bot commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Python Test Coverage

Python Test Coverage Report •
FileStmtsMissCoverMissing
packages/a2a/agent_framework_a2a
   _agent.py4213192%159–160, 174–175, 313, 401, 407, 411, 415, 419, 423, 589, 594, 596, 650–651, 681–682, 686, 832, 848, 860, 882, 903, 942, 958, 968, 979, 986–987, 1038
packages/claude/agent_framework_claude
   _agent.py3192891%407–408, 412, 424, 432–434, 436–437, 467–469, 488, 492, 494, 498, 507, 553, 556, 596, 601–602, 676, 763, 789–792
packages/copilotstudio/agent_framework_copilotstudio
   _agent.py94495%174, 182, 252, 284
packages/core/agent_framework
   _agents.py4315188%64, 516, 528, 583, 1083, 1128, 1201–1205, 1302, 1330, 1367, 1389, 1409–1410, 1415, 1504, 1530, 1532, 1545, 1596, 1598, 1607–1612, 1617, 1619, 1625–1626, 1633, 1635–1636, 1644–1645, 1648–1650, 1660–1665, 1669, 1674, 1676
   _sessions.py3963391%106–108, 110–111, 128–129, 131–133, 210–211, 301, 562–566, 615, 621, 655, 726, 730, 740, 873, 889, 1022, 1036–1037, 1060, 1082, 1092, 1134
   observability.py10038791%408, 410–411, 414, 417, 420–421, 426–427, 433–434, 440–441, 448, 450–452, 455–457, 462–463, 469–470, 476–477, 484, 661–662, 861, 865–867, 869, 873–874, 878, 916, 918, 929–931, 933–935, 939, 947, 1071–1072, 1307, 1582–1583, 1694, 1836, 1877–1878, 2027, 2310–2313, 2319, 2345–2346, 2374–2385, 2504, 2507, 2519, 2536, 2540–2541, 2544, 2550, 2659, 2876, 2878
packages/durabletask/agent_framework_durabletask
   _models.py1611193%41, 44, 63, 66, 71, 76, 93, 155, 195–196, 320
   _shim.py45491%48, 122, 143, 165
packages/github_copilot/agent_framework_github_copilot
   _agent.py3441296%46–47, 476, 491–492, 788–789, 827, 830, 879, 902, 941
packages/purview/agent_framework_purview
   _middleware.py1210100% 
TOTAL42276499988% 

Python Unit Test Overview

Tests Skipped Failures Errors Time
8305 37 💤 0 ❌ 0 🔥 2m 11s ⏱️

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Automated Code Review

Reviewers: 5 | Confidence: 85% | Result: All clear

Reviewed: Correctness, Security Reliability, Test Coverage, Failure Modes, Design Approach


Automated review by eavanvalkenburg's agents

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Implements ADR-0029’s Python session identity lifecycle mapping by allowing AgentSession.service_session_id to carry either a simple string (generic provider continuation) or a structured mapping (durable provider continuation state), while separating chat forwarding vs. telemetry conversation-id extraction. Updates A2A to persist context_id/task_id/task_state in a structured service_session_id, and keeps A2AAgentSession as a deprecated compatibility wrapper.

Changes:

  • Extend core session typing to support service_session_id: str | ServiceSessionId | None and introduce agent-owned hooks for extracting (a) provider chat conversation id and (b) OTel conversation id.
  • Update telemetry to use the agent hook for gen_ai.conversation.id instead of directly reading session.service_session_id.
  • Add A2AServiceSessionId and migrate A2A durable continuation state into structured service_session_id, plus update exports/docs/tests and add a deprecation warning for A2AAgentSession.

Reviewed changes

Copilot reviewed 18 out of 18 changed files in this pull request and generated no comments.

Show a summary per file
File Description
python/packages/core/agent_framework/_sessions.py Adds ServiceSessionId alias and broadens service_session_id typing for SessionContext/AgentSession.
python/packages/core/agent_framework/_agents.py Introduces _get_chat_conversation_id and _get_otel_conversation_id; routes chat continuation and per-service-call history logic through the chat-extraction hook.
python/packages/core/agent_framework/observability.py Uses agent-provided OTel conversation-id extraction hook when available (fallback to string service_session_id).
python/packages/core/agent_framework/init.py Re-exports ServiceSessionId from the top-level package.
python/packages/core/agent_framework/a2a/init.py Adds lazy export for A2AServiceSessionId.
python/packages/core/agent_framework/a2a/init.pyi Updates stub exports to include A2AServiceSessionId.
python/packages/core/AGENTS.md Documents ServiceSessionId and its role in AgentSession.service_session_id.
python/packages/a2a/agent_framework_a2a/_agent.py Defines A2AServiceSessionId, persists A2A durable continuation state into structured service_session_id, and adds A2AAgentSession deprecation warning + compatibility syncing.
python/packages/a2a/agent_framework_a2a/init.py Exports A2AServiceSessionId from the A2A package.
python/packages/a2a/AGENTS.md Documents new A2A structured session-id shape and deprecation guidance for A2AAgentSession.
python/packages/a2a/tests/test_a2a_agent.py Updates/extends tests for structured service_session_id persistence, OTel mapping, and deprecation warning behavior.
python/packages/core/tests/core/test_sessions.py Adds coverage for structured service_session_id acceptance and serialization round-trip.
python/packages/core/tests/core/test_agents.py Adds tests for structured get_session input and early rejection of structured ids in generic chat agent runs.
python/packages/core/tests/core/test_harness_agent.py Updates harness test agent get_session typing to accept structured service_session_id.
python/packages/core/tests/core/test_harness_background_agents.py Updates background agent test get_session typing to accept structured service_session_id.
python/packages/core/tests/workflow/test_workflow_agent.py Updates workflow test scaffolding get_session typing to accept structured service_session_id.
python/packages/core/tests/workflow/test_full_conversation.py Updates test private attribute typing to allow structured service_session_id.
python/packages/core/tests/workflow/test_agent_utils.py Updates test agent protocol typing/imports for structured service_session_id.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@eavanvalkenburg eavanvalkenburg requested a review from a team as a code owner June 25, 2026 07:02
eavanvalkenburg and others added 3 commits June 25, 2026 09:21
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Usage: [Issues, PRs], Target: documentation in the code base and learn docs python Usage: [Issues, PRs], Target: Python

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Python: [Bug]: No Native Conversation ID Propagation

3 participants