How Microsoft Agent Framework Connects
The measurements and Angular compatibility details below describe the canonical Angular/provider example. The bounded React expense preview instead uses the native Session and top-level resume against the generated service directly, preserving current pause correlation and requiring a literal tool result plus successful root terminal outcome for confirmation. It does not claim wrapped specialist streaming. The native packages remain private source-build artifacts.
This page records the AG-UI wire behavior measured for the Microsoft Agent Framework bridge on 2026-08-31. It describes what the runtime emitted, not what the protocol permits in general. The captured Server-Sent Events are committed at libs/ag-ui/fixtures/runtime-transcripts/ and replayed by the adapter test suite on every run.
Transport
The example serves a single AG-UI endpoint from FastAPI.
| Route | Method | Notes |
|---|---|---|
/agent | POST | RunAgentInput JSON in, Server-Sent Events out. |
/ok | GET | Health check. No route in the local example is authenticated; the token gate belongs to the shared deployment, not to the FastAPI app. |
In your own application that is an ordinary provideAgent({ url: '/agent' }). The example in this repository passes a factory instead, only because it resolves its endpoint at runtime. Nothing about the adapter configuration is Microsoft-specific either way.
Interrupts use the outcome convention
A tool declares approval_mode="always_require", and the bridge finishes the run with the protocol-standard outcome:
{
"type": "RUN_FINISHED",
"outcome": {
"type": "interrupt",
"interrupts": [{ "interruptId": "...", "value": { } }]
}
}This matches AWS Strands and differs from the LangGraph bridge, which signals interrupts only through a CUSTOM event named on_interrupt. The adapter retains both conventions in one session; native batches take precedence in auto mode regardless of arrival order.
Resume must address every pending interrupt
Like Strands, this runtime reads the protocol-standard top-level resume array of { interruptId, status, payload } entries. The adapter requires an entry for every pending interrupt on either native backend. Cancelled entries must omit payload.
For one pending interrupt, submit({ resume: decision }) is shorthand for one resolved entry. For a batch, pass a resume array with a decision for every observed interrupt ID. The adapter validates correlation; it does not invent answers for outstanding interrupts.
State streams predictively
predict_state_config maps a tool argument onto a state key:
predict_state_config={
"expense": {"tool": "submit_expense", "tool_argument": "expense"},
}The bridge emits STATE_SNAPSHOT followed by real STATE_DELTA events as the argument is generated, so the frontend sees the expense fill in before submit_expense has been called or approved.
This is the meaningful contrast with AWS Strands, whose bridge emits snapshots only and requires each hook to return the complete state object. On Microsoft Agent Framework, ordinary delta application is enough.
Subagents stream through a queue-merge wrapper
An in-tree emitter wraps the bridge agent's run: the delegation tool streams the specialist's updates into a queue, and a pump task merges that queue with the bridge's own event stream.
The merged stream carries SUBAGENT_STARTED, the specialist's tokens as TEXT_MESSAGE_* deltas attributed with subagentRunId, and SUBAGENT_FINISHED, delivered live while the bridge generator is still suspended inside the tool.
Next steps
- Overview — what the integration supports.
- AWS Strands — How It Connects — the same outcome convention, snapshot-only state.
- Choosing an adapter — the full matrix and its cause analysis.