AAEP integration for agents built on Microsoft Agent Framework
Project description
Python Microsoft Agent Framework Producer Example
AAEP integration with Microsoft Agent Framework (MAF), Microsoft's official agent framework that succeeded Semantic Kernel as the recommended path for building production agents on Azure and beyond.
If you're building agents with Microsoft's stack and want AAEP support — especially with Narrator integration in view — this is the example to copy.
What this example demonstrates
- Direct integration with
microsoft.agentsand the MAF agent lifecycle - Native handling of MAF's tool/function calling system
- MAF middleware pattern for intercepting agent steps
- Streaming output via MAF's async response iterators
- Tool invocation with safety-gated confirmation for irreversible operations
- All 12 core AAEP event types emitted from MAF-driven agents
- Compatible with Azure OpenAI, Azure AI Foundry, and OpenAI-compatible models
This example reuses the AAEPEmitter from python-minimal — same machinery, MAF-specific adapter. Everything follows the same safety contract.
When to use this pattern
Pick this pattern when:
- You build agents with Microsoft Agent Framework
- You target Azure AI Foundry, Azure OpenAI, or any MAF-compatible model
- You need Narrator/Microsoft Accessibility compatibility in the long term
- You want AAEP support that aligns with Microsoft's official agent stack
Pick python-anthropic-sdk when: you call Anthropic models directly without MAF.
Pick python-langchain when: you use LangChain rather than MAF.
Pick python-minimal when: you build agents from scratch without framework.
Installation
cd examples/producers/python-microsoft-agent-framework
pip install -e .
You'll need Microsoft Agent Framework installed (the microsoft-agents package or compatible). For Azure model access:
export AZURE_OPENAI_ENDPOINT="https://your-resource.openai.azure.com"
export AZURE_OPENAI_API_KEY="..."
The example also runs in mock mode without any credentials, so the conformance suite can verify it in CI.
Requires Python 3.10 or newer.
Quick start
from microsoft.agents import Agent, AgentBuilder
from aaep_maf import MAFAAEPMiddleware
# Step 1: build your MAF agent normally
agent = (AgentBuilder()
.with_model("gpt-4o")
.with_tools(your_tools)
.build())
# Step 2: create the AAEP middleware
def my_transport(event):
"""Send AAEP events to subscribers (HTTP/SSE, WebSocket, etc.)"""
print(event) # in production: serialize and send
middleware = MAFAAEPMiddleware(send_event=my_transport)
# Step 3: attach the middleware to your agent
agent.add_middleware(middleware)
# Step 4: run sessions normally — AAEP events emit automatically
result = await agent.invoke("What's my Azure budget status?")
The middleware observes agent execution and emits AAEP events without modifying the agent's behavior. Pure addition, no friction.
Running the included demo
python -m aaep_maf.example_agent
Drives a MAF-style agent through three scenarios: a basic query, a tool call, and a high-risk tool that triggers confirmation. Uses mock mode if MAF or Azure credentials aren't installed/configured.
Running the conformance suite against it
# Terminal 1: start the server (port 8083)
python -m aaep_maf.server --port 8083
# Terminal 2: run conformance
aaep-conformance producer --endpoint http://localhost:8083 --level 2
The server uses mock MAF mode by default for CI portability.
Project layout
python-microsoft-agent-framework/
├── README.md
├── pyproject.toml
├── aaep_maf/
│ ├── __init__.py
│ ├── middleware.py # MAFAAEPMiddleware (the core integration)
│ ├── example_agent.py # Runnable demo
│ └── server.py # HTTP/SSE wrapper for conformance testing
└── tests/
├── __init__.py
└── test_middleware.py
Key design decisions
1. Middleware pattern, not callback handler
MAF uses a middleware pattern (similar to ASP.NET Core or Express.js) where steps in the agent loop pass through a chain of middleware. Our MAFAAEPMiddleware slots into this chain, observing each step and emitting the appropriate AAEP event.
This is different from python-langchain's callback handler — MAF didn't choose the callback pattern, so we follow MAF's pattern instead. Both produce identical AAEP events; the integration shape differs.
2. Safety gates for tools fire BEFORE execution
When MAF prepares to invoke a tool, our middleware:
- Inspects the tool's metadata (name, irreversibility, risk)
- If irreversible or high-risk: emits
agent.awaiting.confirmation(urgency=critical, default_decision=reject) - Blocks the middleware chain until reply arrives (or timeout default)
- Only allows MAF to proceed on
accept
MAF doesn't natively block on user input mid-execution. We achieve it via asyncio.Future synchronization, the same pattern used in the python-anthropic-sdk adapter.
3. Azure AI Foundry compatible
The example respects MAF's content-filter and grounding annotations. When MAF reports a content filter blocked output, our middleware emits a session.errored with error_category: "policy" and proper remediation hints — preserving the safety signal for AT.
4. Same emitter as python-minimal
Imports AAEPEmitter from the python-minimal package. Bug fixes propagate. Safety guarantees are uniform.
Microsoft Narrator forward compatibility
This example is positioned for eventual Narrator integration. Key alignments:
- UIA-friendly summaries —
summary_normalfields are written for screen reader announcement, not for visual display - Speech rate compliance — events respect the subscriber's negotiated
pace_wpmandcognitive_loadcapabilities - NaviSync-ready — the streaming output format works with Narrator's natural-pause heuristics
When AAEP eventually integrates with Narrator (whether via direct adoption or a community bridge), this example will be the canonical Python reference.
See also
../python-minimal/— manual loop pattern with the same emitter../python-anthropic-sdk/— Anthropic SDK direct integration- Implementer's Guide §3.5 — Microsoft Agent Framework specifics
- Microsoft Agent Framework documentation — upstream reference
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file aaep_maf_producer-1.0.0.tar.gz.
File metadata
- Download URL: aaep_maf_producer-1.0.0.tar.gz
- Upload date:
- Size: 19.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a030049675ed7f54d2e83708ff3140f7e8f58af23ac6d1ff359f3d3be8181fe0
|
|
| MD5 |
f5be83b9556622733a41d70e585ca200
|
|
| BLAKE2b-256 |
4c9800311307955034b9720fe75870bbb7a796bfba5c11aeee9e3108f1d774b4
|
File details
Details for the file aaep_maf_producer-1.0.0-py3-none-any.whl.
File metadata
- Download URL: aaep_maf_producer-1.0.0-py3-none-any.whl
- Upload date:
- Size: 16.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fd08f22b8222090bca9e9f160e933b2ea986689b1b551976b7e341636aa522d5
|
|
| MD5 |
ff9a3527ff763faba00b2fee2d06d751
|
|
| BLAKE2b-256 |
90cbbe36cfc3bb18040234cc2d211e3185e07b8f8f4fd04522b96c6b2828b053
|