Skip to content

.NET: Add durable workflow support#4436

Merged
kshyju merged 41 commits intomainfrom
feat/durable_task
Mar 16, 2026
Merged

.NET: Add durable workflow support#4436
kshyju merged 41 commits intomainfrom
feat/durable_task

Conversation

@kshyju
Copy link
Contributor

@kshyju kshyju commented Mar 3, 2026

Motivation and Context

The Agent Framework needs support for long-running, reliable agent orchestrations that can survive process restarts, scale across machines, and handle complex multi-step workflows. This PR brings durable workflow support backed by the Durable Task framework, enabling scenarios like multi-agent pipelines, fan-out/fan-in patterns, and human-in-the-loop approvals.

Description

This PR merges the feat/durable_task feature branch, adding comprehensive durable workflow support across two packages. The feature was developed across 5 PRs into the feature branch:

  • Basic durable workflow support (#3648) — Core workflow engine including IWorkflowClient, IWorkflowRun, DurableWorkflowRunner, DurableWorkflowContext, edge routers (direct and fan-out), activity executors, workflow analyzer, and streaming
    support via IStreamingWorkflowRun.

  • Azure Functions hosting (#3935) — Hosting layer for running durable workflows in Azure Functions, including WorkflowOrchestrator, DurableWorkflowsFunctionMetadataTransformer, and DI extensions.

  • Events & shared state (#4020) — Support for publishing and subscribing to workflow events, and sharing state across workflow executors.

  • Nested sub-workflows (#4190) — Ability to compose workflows by nesting sub-workflows within a parent workflow.

  • Human-in-the-loop (HITL) (#4358) — Support for pausing workflow execution to wait for human input, including DurableWorkflowWaitingForInputEvent, PendingRequestPortStatus, and DurableHaltRequestedEvent.

Packages changed:

Package Files changed Diff
Microsoft.Agents.AI.DurableTask 49 +4,488 / −318
Microsoft.Agents.AI.Hosting.AzureFunctions 12 +778 / −51

Key new types:

  • IWorkflowClient / DurableWorkflowClient — Client for starting and managing workflow runs
  • IWorkflowRun / IStreamingWorkflowRun — Handles for monitoring workflow execution
  • DurableWorkflowRunner — Core orchestration runner
  • DurableWorkflowContext — Execution context available to workflow steps
  • DurableExecutorDispatcher — Routes execution to registered executors
  • IDurableEdgeRouter — Abstraction for routing between workflow nodes (direct, fan-out)
  • WorkflowAnalyzer / WorkflowGraphInfo — Static analysis of workflow graphs
  • WorkflowOrchestrator — Azure Functions orchestrator for durable workflows

Contribution Checklist

  • The code builds clean without any errors or warnings
  • The PR follows the Contribution Guidelines
  • All unit tests pass, and I have added new tests where possible
  • Is this a breaking change? If yes, add "[BREAKING]" prefix to the title of the PR.

kshyju and others added 5 commits February 6, 2026 16:02
* Add basic durable workflow support.

* PR feedback fixes

* Add conditional edge sample.

* PR feedback fixes.

* Minor cleanup.

* Minor cleanup

* Minor formatting improvements.

* Improve comments/documentation on the execution flow.
…e workflows (#3935)

* Adding azure functions workflow support.

* - PR feedback fixes.
- Add example to demonstrate complex Object as payload.

* rename instanceId to runId.

* Use custom ITaskOrchestrator to run orchestrator function.
…rable workflows (#4020)

* Adding support for events & shared state in durable workflows.

* PR feedback fixes

* PR feedback fixes.

* Add YieldOutputAsync calls to 05_WorkflowEvents sample executors

The integration test asserts that WorkflowOutputEvent is found in the
stream, but the sample executors only used AddEventAsync for custom
events and never called YieldOutputAsync. Since WorkflowOutputEvent is
only emitted via explicit YieldOutputAsync calls, the assertion would
fail. Added YieldOutputAsync to each executor to match the test
expectation and demonstrate the API in the sample.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Fix deserialization to use shared serializer options.

* PR feedback updates.

* Sample cleanup

* PR feedback fixes

* Addressing PR review feedback for DurableStreamingWorkflowRun

   - Use -1 instead of 0 for taskId in TaskFailedException when task ID is not relevant.
   - Add [NotNullWhen(true)] to TryParseWorkflowResult out parameter following .NET TryXXX conventions.

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…rkflows (#4190)

* .NET: [Feature Branch] Add nested sub-workflow support for durable workflows

* fix readme path

* Switch Orchestration output from string to DurableWorkflowResult.

* PR feedback fixes

* Minor cleanup based on PR feedback.
…flows (#4358)

* Add Azure Functions HITL workflow sample

Add 06_WorkflowHITL Azure Functions sample demonstrating Human-in-the-Loop
workflow support with HTTP endpoints for status checking and approval responses.

The sample includes:
- ExpenseReimbursement workflow with RequestPort for manager approval
- Custom HTTP endpoint to check workflow status and pending approvals
- Custom HTTP endpoint to send approval responses via RaiseEventAsync
- demo.http file with step-by-step interaction examples

* PR feedback fixes

* Minor comment cleanup

* Minor comment clReverted the `!context.IsReplaying` guards on `PendingEvents.Add`/`RemoveAll` and `SetCustomStatus` in `ExecuteRequestPortAsync`. The guards broke fan-out scenarios where parallel RequestPorts      need to be discoverable after replay. `SetCustomStatus` is idempotent metadata that doesn't affect replay determinism.eanup

* fix  for PR feedback

* PR feedback updates

* Improvements to samples

* Improvements to README

* Update samples to use parallel request ports.

* Unit tests

* Introduce local variables to improve readability of Workflows.Workflows access patter

* Use GitHub-style callouts and add PowerShell command variants in HITL sample README
@markwallace-microsoft markwallace-microsoft added documentation Improvements or additions to documentation .NET workflows Related to Workflows in agent-framework labels Mar 3, 2026
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
kshyju added a commit that referenced this pull request Mar 3, 2026
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Microsoft.Azure.Functions.Worker.Extensions.DurableTask 1.13.1 requires
Microsoft.DurableTask.Worker >= 1.19.1 via its transitive dependency on
Microsoft.DurableTask.Worker.Grpc 1.19.1.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
kshyju and others added 3 commits March 3, 2026 13:00
- Create Workflow/README.md with environment setup docs
- Fix ../README.md -> ../../README.md in ConsoleApps 01, 02, 03, 08
- Fix SubWorkflows relative path (3 levels -> 4 levels up)
- Fix dead Durable Task Scheduler URL

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…, GetNewSessionAsync rename

- Remove InjectSharedThrow from DurableTask csproj (uses Workflows' internal Throw via InternalsVisibleTo)
- Update ExecuteAsync -> ExecuteCoreAsync with WorkflowTelemetryContext.Disabled
- Update GetNewSessionAsync -> CreateSessionAsync

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Aligns with main branch sample reorganization where durable samples
live under 04-hosting/ (alongside DurableAgents/).

- Move samples/Durable/Workflow/ -> samples/04-hosting/DurableWorkflows/
- Add Directory.Build.props matching DurableAgents pattern
- Update slnx project paths
- Update integration test sample paths
- Update README cd paths and cross-references

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
… APIs

- Remove duplicate OutputLog, WriteInputAsync, CreateTestTimeoutCts, etc. from
  ConsoleAppSamplesValidation (already in SamplesValidationBase)
- Update AddFanInEdge -> AddFanInBarrierEdge in workflow samples
- Update GetNewSessionAsync -> CreateSessionAsync in workflow samples
- Update SourceId -> ExecutorId (obsolete) in workflow samples

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 122 out of 122 changed files in this pull request and generated 1 comment.

@kshyju kshyju added this pull request to the merge queue Mar 12, 2026
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 122 out of 122 changed files in this pull request and generated no new comments.

kshyju added 7 commits March 12, 2026 11:18
ValidateOrder and EnrichOrder call YieldOutputAsync with string messages,
but only their TOutput (OrderDetails) was in the allowed yield types.
This caused TargetInvocationException in the WorkflowSharedState sample
validation integration test.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation .NET workflows Related to Workflows in agent-framework

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants