You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I've started on this. Branch is python/azure-functions-durable-2x, not pushed yet.
What shipped upstream
azure-functions-durable 2.0.0b2 is a ground-up rewrite that now lives in microsoft/durabletask-python, built on the durabletask gRPC runtime rather than the classic Durable Functions extension protocol. It pulls in durabletask 1.9.0 and azure-functions 2.3.0b3.
Verified against the real package, not the docs
azure.durable_functions.models is gone. That removes TaskBase, CompoundTask, TaskState and NoOpAction, which our _orchestration.py was built on top of.
mcp_tool_trigger still exists in azure-functions 2.3.0b3 with a compatible signature, so sample 08 is fine. This was my main worry going in.
entity_trigger accepts a class-based DurableEntity, so the Functions host can register the same entity class the standalone worker already uses.
The preview extension bundle is reachable and has versions through 4.46.0, so [4.*, 5.0.0) resolves.
Why this is a net simplification
If you take the native path, a two-argument orchestrator receives a real durabletask.task.OrchestrationContext. That is the exact type agent-framework-durabletask already targets, so most of the Azure Functions adapter layer becomes redundant.
I deleted _orchestration.py, _workflow_af_context.py and _entities.py, plus two test files that were duplicating coverage the durabletask package already has. AzureFunctionsAgentExecutor was a line for line duplicate of OrchestrationAgentExecutor, and AgentTask was a duplicate of DurableAgentTask. I also pulled the configured-entity factory into the durabletask package so both hosts register the same implementation.
Worth being honest that _app.py stays big. Its HTTP routing, status endpoints and MCP wiring are not duplicated with durabletask and do not get simpler.
Current state
durabletask is ruff clean, pyright clean, 413 tests passing. azurefunctions is ruff clean with 247 tests passing and 8 pyright errors left, covered below.
Workspace split
2.x requires Python 3.13. uv resolves a workspace to a single lock over the intersection of its members, so keeping both packages in one workspace pulled agent-framework-durabletask up to 3.13 too, which broke three of the four legs in the 3.10 to 3.13 matrix in python-merge-tests.yml.
durabletask has zero references to azure.durable_functions and no technical reason to require 3.13, so dropping three Python versions for its users would have been a real regression. I split the workspace instead. packages/azurefunctions is now a standalone uv project with its own lockfile.
What's left
Migrate the remaining deprecated client calls (get_status, raise_event, read_entity_state). Pyright strict treats them as errors so CI will not pass without it. The catch is that the native status enum renders COMPLETED where the compat wrapper renders Completed, and that string goes on the wire from the workflow status endpoint. It needs an explicit mapping plus tests asserting the JSON shape, otherwise we silently change the public HTTP contract.
14 sample host.json files need the preview bundle, and 5 function_app.py files still import deprecated aliases.
CI needs the job split, with durabletask keeping the four version matrix and azurefunctions on 3.13 only. The integration job also moves from 3.12 to 3.13.
The integration harness needs a virtualenv inside each app directory. Upstream's own E2E harness says the Functions Python worker only prioritizes app dependencies over its bundled copies when it can locate them relative to the app dir, and with the venv outside, both protobuf C extensions load and the worker crashes natively during indexing. Our CI creates a workspace level venv, which is exactly that shape. I suspect this is the real reason behind the 3.12 pin, not just Core Tools.
Breaking changes for the release notes
For agent-framework-azurefunctions:
Minimum Python is now 3.13, up from 3.10. This is forced by 2.x, which requires 3.13 because older Functions Python workers do not isolate worker dependencies from app dependencies and collide with the durable runtime's grpc at load time.
It now depends on prerelease packages, azure-functions-durable>=2.0.0b1 and azure-functions>=2.3.0b2.
Function apps must switch host.json to the preview extension bundle.
Entity names are now lowercased. dafx-TestAgent becomes dafx-testagent. This matches how the standalone DurableTask host has always behaved, but it changes entity addressing, so apps with in-flight orchestrations should drain them or move to a new task hub.
agent-framework-durabletask is unchanged for consumers. Still Python 3.10+, still no Azure Functions dependency. Its durabletask floor moves to 1.9.0.
For contributors, uv sync now has to be run separately inside packages/azurefunctions.
One question
Given the size, I think this wants to be split across a few PRs rather than one. The workspace split, the code migration, and the samples plus CI are all separable. Happy to do it either way.
Activity
[-]Cosume new version of Durable Python SDK.[/-][+]Consume new version of Durable Python SDK.[/+]ahmedmuhsin commentedon Aug 18, 2026
I've started on this. Branch is
python/azure-functions-durable-2x, not pushed yet.What shipped upstream
azure-functions-durable2.0.0b2 is a ground-up rewrite that now lives in microsoft/durabletask-python, built on the durabletask gRPC runtime rather than the classic Durable Functions extension protocol. It pulls indurabletask1.9.0 andazure-functions2.3.0b3.Verified against the real package, not the docs
azure.durable_functions.modelsis gone. That removesTaskBase,CompoundTask,TaskStateandNoOpAction, which our_orchestration.pywas built on top of.mcp_tool_triggerstill exists in azure-functions 2.3.0b3 with a compatible signature, so sample 08 is fine. This was my main worry going in.entity_triggeraccepts a class-basedDurableEntity, so the Functions host can register the same entity class the standalone worker already uses.[4.*, 5.0.0)resolves.Why this is a net simplification
If you take the native path, a two-argument orchestrator receives a real
durabletask.task.OrchestrationContext. That is the exact typeagent-framework-durabletaskalready targets, so most of the Azure Functions adapter layer becomes redundant.I deleted
_orchestration.py,_workflow_af_context.pyand_entities.py, plus two test files that were duplicating coverage the durabletask package already has.AzureFunctionsAgentExecutorwas a line for line duplicate ofOrchestrationAgentExecutor, andAgentTaskwas a duplicate ofDurableAgentTask. I also pulled the configured-entity factory into the durabletask package so both hosts register the same implementation.Worth being honest that
_app.pystays big. Its HTTP routing, status endpoints and MCP wiring are not duplicated with durabletask and do not get simpler.Current state
durabletask is ruff clean, pyright clean, 413 tests passing. azurefunctions is ruff clean with 247 tests passing and 8 pyright errors left, covered below.
Workspace split
2.x requires Python 3.13. uv resolves a workspace to a single lock over the intersection of its members, so keeping both packages in one workspace pulled
agent-framework-durabletaskup to 3.13 too, which broke three of the four legs in the 3.10 to 3.13 matrix in python-merge-tests.yml.durabletask has zero references to
azure.durable_functionsand no technical reason to require 3.13, so dropping three Python versions for its users would have been a real regression. I split the workspace instead.packages/azurefunctionsis now a standalone uv project with its own lockfile.What's left
get_status,raise_event,read_entity_state). Pyright strict treats them as errors so CI will not pass without it. The catch is that the native status enum rendersCOMPLETEDwhere the compat wrapper rendersCompleted, and that string goes on the wire from the workflow status endpoint. It needs an explicit mapping plus tests asserting the JSON shape, otherwise we silently change the public HTTP contract.host.jsonfiles need the preview bundle, and 5function_app.pyfiles still import deprecated aliases.Breaking changes for the release notes
For
agent-framework-azurefunctions:azure-functions-durable>=2.0.0b1andazure-functions>=2.3.0b2.host.jsonto the preview extension bundle.dafx-TestAgentbecomesdafx-testagent. This matches how the standalone DurableTask host has always behaved, but it changes entity addressing, so apps with in-flight orchestrations should drain them or move to a new task hub.agent-framework-durabletaskis unchanged for consumers. Still Python 3.10+, still no Azure Functions dependency. Itsdurabletaskfloor moves to 1.9.0.For contributors,
uv syncnow has to be run separately insidepackages/azurefunctions.One question
Given the size, I think this wants to be split across a few PRs rather than one. The workspace split, the code migration, and the samples plus CI are all separable. Happy to do it either way.