.NET: feat: add WorkflowCompletedEvent and WorkflowFailedEvent (#4063)#4554
Draft
max-montes wants to merge 3 commits intomicrosoft:mainfrom
Draft
.NET: feat: add WorkflowCompletedEvent and WorkflowFailedEvent (#4063)#4554max-montes wants to merge 3 commits intomicrosoft:mainfrom
max-montes wants to merge 3 commits intomicrosoft:mainfrom
Conversation
) Add two new public workflow event types to the core Workflows library: - WorkflowCompletedEvent: emitted when a workflow completes execution, providing the natural counterpart to WorkflowStartedEvent. Consumers can now observe workflow completion through the event stream instead of inferring it from stream termination. - WorkflowFailedEvent: supports string-based failure scenarios where no Exception object is available (e.g., errors from external orchestrators or deserialized error responses). Complements the existing WorkflowErrorEvent which requires an Exception. WorkflowCompletedEvent is automatically emitted in both streaming (StreamingRunEventStream) and lockstep (LockstepRunEventStream) execution modes before the event stream terminates. RequestHaltEvent remains internal as it serves as infrastructure plumbing for stream termination signaling. Closes microsoft#4063 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Contributor
There was a problem hiding this comment.
Pull request overview
Adds explicit terminal workflow events to the .NET Workflows core library so consumers can observe workflow completion and string-based failures via the workflow event stream, aligning with existing workflow observability patterns.
Changes:
- Introduces new public workflow event types:
WorkflowCompletedEventandWorkflowFailedEvent. - Updates workflow event polymorphic serialization metadata to include the new event types.
- Emits
WorkflowCompletedEventas a terminal event in both streaming (off-thread) and lockstep event-stream implementations, with new unit tests validating behavior.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/WorkflowCompletedEventTests.cs | Adds unit tests for the new events and verifies completion event is last in both execution modes. |
| dotnet/src/Microsoft.Agents.AI.Workflows/WorkflowFailedEvent.cs | Adds a string-based failure event type for scenarios without an Exception. |
| dotnet/src/Microsoft.Agents.AI.Workflows/WorkflowEvent.cs | Registers the new event types for polymorphic JSON serialization. |
| dotnet/src/Microsoft.Agents.AI.Workflows/WorkflowCompletedEvent.cs | Adds a workflow completion event type carrying an optional result payload. |
| dotnet/src/Microsoft.Agents.AI.Workflows/Execution/StreamingRunEventStream.cs | Emits WorkflowCompletedEvent before terminating the streaming event stream. |
| dotnet/src/Microsoft.Agents.AI.Workflows/Execution/LockstepRunEventStream.cs | Emits WorkflowCompletedEvent before terminating the lockstep event stream. |
dotnet/src/Microsoft.Agents.AI.Workflows/WorkflowCompletedEvent.cs
Outdated
Show resolved
Hide resolved
dotnet/src/Microsoft.Agents.AI.Workflows/Execution/LockstepRunEventStream.cs
Outdated
Show resolved
Hide resolved
dotnet/src/Microsoft.Agents.AI.Workflows/Execution/LockstepRunEventStream.cs
Outdated
Show resolved
Hide resolved
- Update XML doc to clarify event fires on any terminal state, not just success - Add telemetry (ActivityEvent) on the RequestHaltEvent early-exit path to match the natural-completion path - Guard post-loop WorkflowCompletedEvent emission with RunStatus check: only emit when Idle or Ended, not when paused (PendingRequests) or cancelled — matching StreamingRunEventStream behavior - Add tests verifying WorkflowCompletedEvent is not emitted when the workflow is paused with pending external requests (both lockstep and off-thread modes) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
dotnet/src/Microsoft.Agents.AI.Workflows/Execution/LockstepRunEventStream.cs
Outdated
Show resolved
Hide resolved
Capture RequestHaltEvent.Data and pass it to WorkflowCompletedEvent, matching StreamingRunEventStream behavior where halt result data is forwarded to the completion event. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
.NET: Add WorkflowCompletedEvent and WorkflowFailedEvent to core Workflows library
Add two new public workflow event types to the core Workflows library:
WorkflowStartedEvent. Consumers can now observe workflow completion through the event stream instead of inferring it from stream termination.
external orchestrators or deserialized error responses). Complements the existing WorkflowErrorEvent which requires an Exception.
WorkflowCompletedEvent is automatically emitted in both streaming (StreamingRunEventStream) and lockstep (
LockstepRunEventStream) execution modes before the event stream terminates.
RequestHaltEvent remains internal as it serves as infrastructure plumbing for stream termination signaling.
Closes #4063
Motivation and Context
Issue #4063 identified that when consuming workflow events via WatchStreamAsync(), there was no way to observe workflow
completion or string-based failures through the event stream. This change adds that observability, following the patterns
established by @kshyju's durable workflow events in PR #4020.
Description
New files:
Modified files:
Tests: 6 new tests covering construction, both execution modes (OffThread + Lockstep), and executor-emitted failure events.
All 252 tests pass.
Note: Adding ExecutorId to RequestHaltEvent (item 3 of the issue) would require changes to InProcessRunnerContext internals —
noted as a potential follow-up.
Contribution Checklist