Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Python: ADR: Unifying Context Management with ContextMiddleware (Python)#3609

Merged
eavanvalkenburg merged 19 commits into
microsoft:mainfrom
eavanvalkenburg:adr-python-context-middleware
Feb 10, 2026
Merged

Python: ADR: Unifying Context Management with ContextMiddleware (Python)#3609
eavanvalkenburg merged 19 commits into
microsoft:mainfrom
eavanvalkenburg:adr-python-context-middleware

Conversation

@eavanvalkenburg

@eavanvalkenburg eavanvalkenburg commented Feb 2, 2026

Copy link
Copy Markdown
Member

Summary

This ADR proposes unifying \ContextProvider, \ChatMessageStore, and \AgentThread\ into a single \ContextMiddleware\ concept for the Python SDK.

Problem

Currently, developers doing 'Context Engineering' must understand multiple abstractions:

  • \ContextProvider\ - Injects instructions, messages, and tools
  • \ChatMessageStore\ - Stores and retrieves conversation history
  • \AgentThread\ - Coordinates between them

Proposed Solution

A unified \ContextMiddleware\ using the onion/wrapper pattern (like existing \AgentMiddleware):

\\python
class RAGMiddleware(ContextMiddleware):
async def process(self, context: SessionContext, next) -> None:
# Pre-processing: add context
docs = await self.retrieve_documents(context.input_messages[-1].text)
context.add_messages(self.source_id, [ChatMessage.system(f'Context: {docs}')])

    await next(context)

    # Post-processing: store/audit
    await self.store_interaction(context.input_messages, context.response_messages)

agent = ChatAgent(
chat_client=client,
context_middleware=[
InMemoryStorageMiddleware('memory'),
RAGMiddleware('rag'),
]
)
\\

Key Decisions

Decision Rationale
Onion/wrapper pattern Familiar from existing middleware, natural pre/post processing
Agent owns config, Session owns pipeline Enables per-session factories
Mandatory \source_id\ Attribution in \context_messages\ dict
Default \InMemoryStorageMiddleware\ Zero-config conversation history
Single \StorageContextMiddleware\ class Configure for memory/audit/evaluation
Clean break (no shims) We're in preview

Migration Impact

Current New
\ContextProvider\ \ContextMiddleware\
\ChatMessageStore\ \StorageContextMiddleware\
\AgentThread\ \AgentSession\

See the full ADR in \docs/decisions/00XX-python-context-middleware.md\ for detailed design, code examples, and implementation workplan.

Related Issues

This ADR addresses the following issues:

Copilot AI review requested due to automatic review settings February 2, 2026 09:24
@markwallace-microsoft markwallace-microsoft added the documentation Usage: [Issues, PRs], Target: documentation in the code base and learn docs label Feb 2, 2026

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

Adds a new ADR proposing a unified ContextMiddleware abstraction for Python to replace ContextProvider, ChatMessageStore, and AgentThread, using an onion/wrapper middleware pipeline pattern.

Changes:

  • Introduces a proposed ContextMiddleware + SessionContext + pipeline design for composable context engineering.
  • Describes a StorageContextMiddleware approach for loading/storing conversation history and optional auditing.
  • Outlines migration impact and a phased implementation/testing plan.

Comment thread docs/decisions/00XX-python-context-middleware.md Outdated
Comment thread docs/decisions/00XX-python-context-middleware.md Outdated
Comment thread docs/decisions/00XX-python-context-middleware.md Outdated
Comment thread docs/decisions/00XX-python-context-middleware.md Outdated
Comment thread docs/decisions/00XX-python-context-middleware.md Outdated
Comment thread docs/decisions/00XX-python-context-middleware.md Outdated
Comment thread docs/decisions/00XX-python-context-middleware.md Outdated
Comment thread docs/decisions/00XX-python-context-middleware.md Outdated
Comment thread docs/decisions/00XX-python-context-middleware.md
Comment thread docs/decisions/00XX-python-context-middleware.md Outdated
Comment thread docs/decisions/00XX-python-context-middleware.md Outdated
Comment thread docs/decisions/00XX-python-context-middleware.md Outdated
@eavanvalkenburg eavanvalkenburg force-pushed the adr-python-context-middleware branch from e005fc3 to 761f2bf Compare February 4, 2026 11:12
@eavanvalkenburg eavanvalkenburg added the python Usage: [Issues, PRs], Target: Python label Feb 4, 2026
@github-actions github-actions Bot changed the title ADR: Unifying Context Management with ContextMiddleware (Python) Python: ADR: Unifying Context Management with ContextMiddleware (Python) Feb 4, 2026
@eavanvalkenburg eavanvalkenburg force-pushed the adr-python-context-middleware branch from ae59218 to fed0e4a Compare February 5, 2026 13:34
…dback

- Add Option 3: ContextHooks with before_run/after_run pattern
- Add detailed pros/cons for both wrapper and hooks approaches
- Add Open Discussion section on context compaction strategies
- Clarify response_messages is read-only (use AgentMiddleware for modifications)
- Add SimpleRAG examples showing input-only filtering
- Clarify default storage only added when NO middleware configured
- Add RAGWithBuffer examples for self-managed history
- Rename hook methods to before_run/after_run
- Add class hierarchy clarification for both options
- Merge detailed design sections (side-by-side comparison)
- Move detailed design before decision outcome
- Move compaction discussion after decision
- Add .NET implementation comparison (feature equivalence)
- Update .NET method names to match actual implementation
- Rename hook methods to before_run/after_run
- Fix storage context table for injected context
- Note that class and method names are open for discussion
- Add alternative method naming options table
- Include invoking/invoked as option matching current Python and .NET
…filtering

- Remove smart mode for load_messages (now explicit bool, default True)
- Add attribution marker in additional_properties for message filtering
- Update validation to warn on multiple or zero storage loaders
- Add note about ChatReducer naming from .NET
- Note that attribution should not be propagated to storage
- Option A: Instances in Session (current proposal)
- Option B: Instances in Agent, State in Session
  - B1: Simple dict state with optional return
  - B2: SessionState object with mutable wrapper
- Updated examples to use Hooks pattern (before_run/after_run)
- Added open discussion on hook factories in Option B model
Decision outcomes:
- Option 3 (Hooks pattern) with ContextPlugin class name
- Methods: before_run/after_run
- Option B1: Instances in Agent, State in Session (simple dict)
- Whole state dict passed to plugins (mutable, no return needed)
- Added trust note: plugins reason over messages, so they're trusted by default

Status changed from proposed to accepted.
Signature now: before_run(agent, session, context, state)
Simpler design: agent stores Sequence[ContextPlugin] and calls
before_run/after_run directly in the run method.
@eavanvalkenburg eavanvalkenburg force-pushed the adr-python-context-middleware branch from 2bc78ee to 1372be3 Compare February 9, 2026 10:26
…ports

- Add to_dict()/from_dict() on AgentSession with 'type' discriminator
- Present serialization as Option A (direct) vs Option B (through agent)
- Rewrite ownership section as 2x2 matrix (orthogonal decision)
- Move Instance Ownership Options before Decision Outcome
- Fix get_session to use service_session_id, split from create_session
- Add decorator-based provider convenience API (@before_run/@after_run)
- Add _ prefix naming strategy for all PR1 types (core + external)
- Constructor compatibility table for existing providers
- Add load_messages=False skip logic to all agent run loops
- Clarify abstract vs non-abstract in execution pattern samples
- Update auto-provision: trigger on conversation_id or store=True
- Document root package exports (ContextProvider, HistoryProvider, etc.)
- Rename section heading to 'Key Design Considerations'
Comment thread docs/decisions/0016-python-context-middleware.md
@eavanvalkenburg eavanvalkenburg added this pull request to the merge queue Feb 10, 2026
Merged via the queue into microsoft:main with commit 9f14a0f Feb 10, 2026
11 of 13 checks passed
@eavanvalkenburg eavanvalkenburg deleted the adr-python-context-middleware branch June 30, 2026 09:01
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.

6 participants