Skip to content

Python: [BREAKING] PR2 — Wire context provider pipeline, remove old types, update all consumers - #3850

Merged
Eduard van Valkenburg (eavanvalkenburg) merged 28 commits into
microsoft:mainfrom
eavanvalkenburg:edvan/pr2-context-provider-pipeline
Feb 12, 2026
Merged

Python: [BREAKING] PR2 — Wire context provider pipeline, remove old types, update all consumers#3850
Eduard van Valkenburg (eavanvalkenburg) merged 28 commits into
microsoft:mainfrom
eavanvalkenburg:edvan/pr2-context-provider-pipeline

Conversation

@eavanvalkenburg

Copy link
Copy Markdown
Member

Summary

Completes the context provider migration from ADR 0016. PR1 (#3763) added the new types side-by-side; this PR wires them into the agent execution flow, removes all old types, and updates every consumer.

What changed

Core agent wiring (_agents.py)

  • run() now accepts session: AgentSession | None instead of thread: AgentThread | None
  • New _prepare_session_and_messages() runs before_run on all context providers (forward order), assembles messages from SessionContext
  • New _finalize_response() / _run_after_providers() runs after_run on all providers (reverse order)
  • Auto-injects InMemoryHistoryProvider(source_id="memory") when: session is passed, no context providers on agent, no service_session_id, no response_id, store not True
  • create_session() and get_session(*, service_session_id=) (keyword-only) on SupportsAgentRun protocol
  • _RunContext uses session_messages (renamed from thread_messages)

Old types removed

  • Deleted: _threads.py (AgentThread), _memory.py (ContextProvider, ChatMessageStore, Context)
  • Deleted: old external provider files (_provider.py in redis/mem0, _search_provider.py in azure-ai-search, _chat_message_store.py in redis)
  • Deleted: corresponding old test files

External providers renamed

  • _RedisContextProviderRedisContextProvider, _RedisHistoryProviderRedisHistoryProvider
  • _Mem0ContextProviderMem0ContextProvider
  • _AzureAISearchContextProviderAzureAISearchContextProvider

Lazy-loader stubs updated

  • redis/__init__.pyi: RedisChatMessageStore/RedisProviderRedisContextProvider/RedisHistoryProvider
  • mem0/__init__.pyi: Mem0ProviderMem0ContextProvider
  • redis/__init__.py_IMPORTS list updated

Session state serialization

  • Added Pydantic BaseModel support: models stored in session.state are auto-serialized via model_dump() and restored via model_validate() during to_dict()/from_dict() round-trips
  • New public API: register_state_type() for pre-registering types for cold-start deserialization

Lab/tau2

  • SlidingWindowChatMessageStoreSlidingWindowHistoryProvider(InMemoryHistoryProvider) with token-based truncation
  • runner.py reads full history from session.state["memory"]["messages"] instead of reaching into provider internals

DevUI

  • Migrated from AgentThread to plain list[Message] for internal message storage

Samples

  • Merged context_providers/ and sessions/ (née threads/) into single sessions/ folder
  • Removed aggregate_context_provider.py
  • Updated all ~54 sample files: AgentThreadAgentSession, get_new_thread()create_session(), context_provider=context_providers=[...], etc.
  • Fixed stale message_store, _notify_thread_of_new_messages, session_id.key references
  • UserInfoMemory sample refactored to use session.state instead of instance attributes
  • Updated all READMEs with new terminology

Tests

  • All tests updated for new API
  • Old test files removed
  • 1597 core tests pass, 2969+ total pass

Fixes

Fixes#3587 — Rename AgentThread to AgentSession
Fixes#3588 — Add session management methods (create_session, get_session)
Fixes#3589 — Move serialize into the agent (AgentSession.to_dict()/from_dict())
Fixes#3590 — Orthogonal ChatMessageStore for service vs local (BaseHistoryProvider with load_messages/store_* flags)
Fixes#3601 — Rename ChatMessageStore to ChatHistoryProvider (BaseHistoryProvider)

Breaking changes

  • AgentThread removed — use AgentSession
  • ContextProvider / ChatMessageStore / Context removed — use BaseContextProvider / BaseHistoryProvider
  • agent.get_new_thread()agent.create_session()
  • agent.get_new_thread(service_thread_id=X)agent.get_session(service_session_id=X)
  • context_provider= (singular) → context_providers= (list)
  • chat_message_store_factory=context_providers=[...]

Related

CopilotAI review requested due to automatic review settings February 11, 2026 15:06
@eavanvalkenburgEduard van Valkenburg (eavanvalkenburg) added the python Usage: [Issues, PRs], Target: Python label Feb 11, 2026
@markwallace-microsoftMark Wallace (markwallace-microsoft) added documentation Usage: [Issues, PRs], Target: documentation in the code base and learn docs lab labels Feb 11, 2026
@markwallace-microsoft

Mark Wallace (markwallace-microsoft) commented Feb 11, 2026

Copy link
Copy Markdown
Contributor

Python Test Coverage

Python Test Coverage Report •
FileStmtsMissCoverMissing
packages/a2a/agent_framework_a2a
_agent.py169994%357, 378, 451–452, 493–494, 523–525
packages/ag-ui/agent_framework_ag_ui
_agent.py36197%62
_client.py1511788%85–86, 90–94, 98–102, 265, 295, 464–466
_run.py48212174%156–163, 306, 325–326, 341–342, 357, 385–387, 412, 415–418, 420–421, 424–430, 433–435, 438, 454–456, 463, 469–471, 475, 480–482, 484–485, 501–505, 516, 529, 531–532, 548, 569–570, 625–627, 639–641, 839, 850–851, 858, 876–878, 912–914, 931, 937, 945, 947, 983–989, 992–995, 997–1006, 1009, 1017–1020, 1027, 1030–1031, 1036, 1042–1044, 1048, 1053–1056, 1070–1072
packages/azure-ai-search/agent_framework_azure_ai_search
_context_provider.py26513150%103–104, 224, 226, 230, 257–258, 260, 269–270, 273–274, 290, 300, 341–342, 355, 363–368, 371–373, 380–382, 387–390, 392–397, 399–405, 409, 413–418, 422, 424, 427–428, 430, 438–440, 443–445, 451, 453–455, 458, 471–472, 474–475, 477, 479–481, 487–488, 490–497, 499–503, 510, 512, 519, 524, 529, 531, 539–540, 542–543, 552, 554, 559, 561, 567–570, 577, 585, 592–594, 596–604, 606, 616–620, 623
packages/azure-ai/agent_framework_azure_ai
_agent_provider.py116199%251
_chat_client.py4767584%387–388, 390, 573, 578–579, 581–582, 585, 588, 590, 595, 856–857, 859, 862, 865, 868–873, 876, 878, 886, 898–900, 904, 907–908, 916–919, 929, 937–940, 942–943, 945–946, 953, 961–962, 970–971, 976–977, 981–988, 993, 996, 1004, 1010, 1018–1020, 1023, 1045–1046, 1179, 1207, 1222, 1338, 1464
_client.py2122289%372, 374, 423, 452–457, 500, 535, 537, 570, 778, 781, 784–785, 787–790, 837
_project_provider.py114496%212, 310, 354, 387
packages/azurefunctions/agent_framework_azurefunctions
_app.py3698576%204–205, 210–211, 322–323, 431, 439–440, 460–462, 468–470, 476–478, 511–512, 572–573, 622–623, 628, 710, 713, 722–724, 726–728, 730, 732, 743, 745–748, 750, 752–753, 755, 762–763, 765–766, 768–769, 771, 775, 785–787, 789–790, 792–794, 801, 803–804, 806, 827, 832, 844, 919, 929, 936–938, 983, 997, 1008–1010, 1012–1015, 1040, 1047, 1049, 1052
_orchestration.py60493%129–130, 134, 149
packages/copilotstudio/agent_framework_copilotstudio
_agent.py79396%169, 177, 294
packages/core/agent_framework
_agents.py2994186%476, 876, 912, 922–926, 1033–1035, 1105, 1147, 1160, 1173, 1179, 1215, 1217, 1226–1231, 1237, 1239, 1249–1250, 1257, 1259–1260, 1268–1272, 1280–1281, 1283, 1288, 1290
_clients.py73494%307, 442, 505, 507
_mcp.py4066484%104–105, 115–120, 131, 136, 182–183, 193–198, 208–209, 261, 270, 333, 341, 362, 476, 543, 578, 580, 584–585, 587–588, 642, 657, 675, 716, 822, 835–840, 862, 899–900, 906–908, 927, 952–953, 957–961, 978–982, 1126
_middleware.py3291695%80, 83, 88, 795, 797, 799, 920, 947, 949, 974, 1055, 1059, 1183, 1187, 1248, 1322
_serialization.py106595%291, 495, 511, 521, 589
_sessions.py1681690%77–79, 81–84, 101–102, 104–108, 549, 563
_settings.py1071189%93, 100, 116, 127, 143–144, 146, 149, 245–246, 251
_tools.py7558688%175–176, 306, 308, 326–328, 335, 353, 367, 379, 384, 386, 393, 430, 453–455, 504–506, 569, 591, 613–641, 676, 684, 925, 1187, 1244, 1248, 1327–1331, 1349, 1351–1352, 1464, 1468, 1518, 1520, 1536, 1538, 1602, 1629, 1686, 1754, 1933–1934, 1961, 1969, 1982, 1992–1993, 2028, 2084, 2116
_types.py10269690%82, 91–92, 146, 151, 170, 172, 176, 180, 182, 184, 186, 204, 208, 234, 256, 261, 266, 270, 296, 300, 646–647, 1018, 1080, 1097, 1115, 1120, 1138, 1148, 1165–1166, 1168, 1186–1187, 1189, 1196–1197, 1199, 1234, 1245–1246, 1248, 1286, 1513, 1566, 1573, 1595, 1601, 1649, 1692–1697, 1719, 1724, 1890, 1902, 2145, 2154, 2175, 2270, 2495, 2702, 2772, 2784, 2791, 2802, 3006–3008, 3011–3013, 3017, 3022, 3026, 3138–3140, 3168, 3222, 3226–3228, 3230, 3241–3242, 3245–3249, 3255
exceptions.py500100%
observability.py6188486%335, 337–339, 342–344, 349–350, 356–357, 363–364, 371, 373–375, 378–380, 385–386, 392–393, 399–400, 407, 676, 679, 687–688, 691–694, 696, 699–701, 704–705, 733, 735, 746–748, 750–753, 757, 765, 866, 868, 1017, 1019, 1023–1028, 1030, 1033–1037, 1039, 1151–1152, 1154, 1211–1212, 1347, 1401–1402, 1518–1520, 1579, 1747, 1901, 1903
packages/core/agent_framework/_workflows
_agent.py3437279%59, 67–73, 109–110, 190, 233–235, 289–291, 336–337, 343–344, 350, 352, 357, 417–418, 427, 434, 460, 493–495, 497, 499, 501, 506, 511, 558, 588, 605, 644–647, 653, 659, 663–664, 667–673, 677–678, 684, 745, 752, 758–759, 770, 802, 809, 830, 839, 843, 845–847, 854
_agent_executor.py1842486%97, 145, 163–164, 216–217, 219–220, 250–252, 260–262, 270–272, 274, 278, 282, 286–287, 414, 432
packages/core/agent_framework/azure
_responses_client.py51688%189, 221, 287–290
packages/core/agent_framework/openai
_assistant_provider.py109991%172, 297, 363, 478–483
_responses_client.py6128086%294–297, 301–302, 305–306, 312–313, 318, 331–337, 358, 366, 389, 552, 555, 610, 614, 616, 618, 620, 696, 706, 711, 754, 813, 827, 844, 857, 913, 1006, 1011, 1015–1017, 1021–1022, 1045, 1114, 1136–1137, 1152–1153, 1171–1172, 1303–1304, 1320, 1322, 1401–1409, 1504, 1559, 1574, 1610–1611, 1613–1615, 1629–1631, 1641–1642, 1648, 1663
packages/mem0/agent_framework_mem0
_context_provider.py79198%128
packages/orchestrations/agent_framework_orchestrations
_group_chat.py3287078%173, 336, 343, 372, 383–384, 390, 395, 416, 420, 433–434, 447, 462–463, 465, 481, 508–513, 515, 548–551, 553, 558–562, 650, 653, 692, 695, 698, 701, 709, 721–722, 724–725, 727–728, 730, 735, 738, 747, 753, 797–798, 802–803, 817–818, 820–821, 852–853, 919, 938, 946, 951–953, 960, 970
_handoff.py3265682%104–105, 107, 136–137, 159–169, 171, 173, 175, 180, 278, 331, 356, 384, 392–393, 407, 458–459, 491, 531–533, 538–540, 656, 659, 666, 671, 733, 738, 745, 755, 757, 776, 778, 860–861, 893–894, 976, 983, 1055–1056, 1058
_magentic.py5859683%63–72, 77, 81–92, 257, 268, 272, 292, 353, 362, 364, 406, 423, 432–433, 435–437, 439, 450, 592, 594, 634, 682, 718–720, 722, 730–733, 737–740, 801–804, 895, 901, 907, 949, 987, 1019, 1036, 1047, 1102–1103, 1107–1109, 1133, 1157–1158, 1171, 1187, 1209, 1257–1258, 1296–1297, 1460, 1463, 1472, 1475, 1480, 1531–1532, 1573–1574, 1622, 1652, 1710, 1724, 1735
packages/purview/agent_framework_purview
_middleware.py1120100%
packages/redis/agent_framework_redis
_context_provider.py1785668%220, 238, 241, 247–248, 250–251, 253–255, 257–259, 261–263, 265–276, 278–279, 281–287, 315, 317, 321–326, 347, 358, 368–369, 382–383, 407, 409–410, 414–415
_history_provider.py58198%174
TOTAL20417324884%

Python Unit Test Overview

TestsSkippedFailuresErrorsTime
3903225 💤0 ❌0 🔥1m 9s ⏱️

CopilotAI 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.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

@TaoChenOSU

Copy link
Copy Markdown
Contributor

Is this a breaking change?

@eavanvalkenburgEduard van Valkenburg (eavanvalkenburg) changed the title Python: PR2 — Wire context provider pipeline, remove old types, update all consumersPython: [BREAKING] PR2 — Wire context provider pipeline, remove old types, update all consumersFeb 11, 2026
@eavanvalkenburgEduard van Valkenburg (eavanvalkenburg) added the breaking change Usage: [PRs], Target: all PRs that introduce changes that are not backward compatible label Feb 11, 2026
Comment threadpython/packages/core/agent_framework/_agents.py
Comment threadpython/packages/orchestrations/agent_framework_orchestrations/_handoff.py Outdated
Comment threadpython/packages/core/agent_framework/_agents.py Outdated
- Replace AgentThread with AgentSession across all packages
- Replace ContextProvider with BaseContextProvider across all packages
- Replace context_provider param with context_providers (Sequence)
- Replace thread= with session= in run() signatures
- Replace get_new_thread() with create_session()
- Add get_session(service_session_id) to agent interface
- DurableAgentThread -> DurableAgentSession
- Remove _notify_thread_of_new_messages from WorkflowAgent
- Wire before_run/after_run context provider pipeline in RawAgent
- Auto-inject InMemoryHistoryProvider when no providers configured
…tThread→AgentSession, ContextProvider→BaseContextProvider)
Pydantic models stored in session.state are now automatically serialized
via model_dump() and restored via model_validate() during to_dict()/from_dict()
round-trips. Models are auto-registered on first serialization; use
register_state_type() for cold-start deserialization.
Also export register_state_type as a public API.
AsyncMemory (OSS) expects user_id/agent_id/run_id as direct kwargs,
while AsyncMemoryClient (Platform) expects them in a filters dict.
Adds tests for both client types.
Port of fix from microsoft#3844 to new Mem0ContextProvider.
…int decode logic
- Add back _conversation_state.py (encode/decode_chat_messages) lost in rebase
- Fix on_checkpoint_restore to decode cache/conversation with decode_chat_messages
- Fix on_checkpoint_restore to use decode_checkpoint_value for pending requests
- Add tests/workflow/__init__.py for relative import support
- Fix test_agent_executor checkpoint selection (checkpoints[1] not superstep)
…der injection
Chat clients that store history server-side by default (OpenAI Responses API,
Azure AI Agent) now declare STORES_BY_DEFAULT = True. The agent checks this
during auto-injection and skips InMemoryHistoryProvider unless the user
explicitly sets store=False.
Comment threadpython/packages/core/agent_framework/_workflows/_agent.py Outdated
Comment threadpython/packages/core/agent_framework/_workflows/_conversation_state.py Outdated
Comment threadpython/packages/core/agent_framework/_workflows/_agent_executor.py Outdated
Comment threadpython/packages/core/agent_framework/_workflows/_agent.py
… remove stale AGUIThread
- Fix: Propagate conversation_id from ChatResponse back to session.service_session_id
in both streaming and non-streaming paths in _agents.py
- Rename AgentThreadException → AgentSessionException
- Remove stale AGUIThread from ag_ui lazy-loader
- Rename use_service_thread → use_service_session in ag-ui package
- Rename test functions from *_thread_* to *_session_*
- Rename sample files from *_thread* to *_session*
- Update docstrings and comments: thread → session
- Update _mcp.py kwargs filter: add 'session' alongside 'thread'
- Fix ContinuationToken docstring example: thread=thread → session=session
- Fix _clients.py docstring: 'Agent threads' → 'Agent sessions'
@github-merge-queue
github-merge-queueBot removed this pull request from the merge queue due to failed status checks Feb 12, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

breaking changeUsage: [PRs], Target: all PRs that introduce changes that are not backward compatibledocumentationUsage: [Issues, PRs], Target: documentation in the code base and learn docspythonUsage: [Issues, PRs], Target: Python

Projects

None yet

7 participants

@eavanvalkenburg@markwallace-microsoft@TaoChenOSU@dmytrostruk@giles17@moonbox3