Skip to content

.NET: feat: add WorkflowCompletedEvent and WorkflowFailedEvent (#4063)#4554

Draft
max-montes wants to merge 3 commits intomicrosoft:mainfrom
max-montes:feature/workflow-completed-failed-events
Draft

.NET: feat: add WorkflowCompletedEvent and WorkflowFailedEvent (#4063)#4554
max-montes wants to merge 3 commits intomicrosoft:mainfrom
max-montes:feature/workflow-completed-failed-events

Conversation

@max-montes
Copy link

.NET: Add WorkflowCompletedEvent and WorkflowFailedEvent to core Workflows library

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 #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:

  • WorkflowCompletedEvent.cs — sealed class with optional object? result, extends WorkflowEvent
  • WorkflowFailedEvent.cs — sealed class with string ErrorMessage, extends WorkflowEvent

Modified files:

  • WorkflowEvent.cs — added [JsonDerivedType] attributes for both new types
  • StreamingRunEventStream.cs — emit WorkflowCompletedEvent before yield break on both RequestHaltEvent and InternalHaltSignal(Idle/Ended) termination paths
  • LockstepRunEventStream.cs — emit WorkflowCompletedEvent before yield break on halt and after natural do-while completion

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

)

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>
Copilot AI review requested due to automatic review settings March 9, 2026 04:37
@markwallace-microsoft markwallace-microsoft added .NET workflows Related to Workflows in agent-framework labels Mar 9, 2026
@github-actions github-actions bot changed the title feat: add WorkflowCompletedEvent and WorkflowFailedEvent (#4063) .NET: feat: add WorkflowCompletedEvent and WorkflowFailedEvent (#4063) Mar 9, 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

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: WorkflowCompletedEvent and WorkflowFailedEvent.
  • Updates workflow event polymorphic serialization metadata to include the new event types.
  • Emits WorkflowCompletedEvent as 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.

@max-montes max-montes marked this pull request as draft March 9, 2026 05:01
- 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>
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 6 out of 6 changed files in this pull request and generated 1 comment.

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>
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 6 out of 6 changed files in this pull request and generated no new comments.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

.NET workflows Related to Workflows in agent-framework

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: Add expose WorkflowCompletedEvent, RequestHaltEvent and WorkflowFailedEvent

3 participants