* fix: WorkflowAsAgent Sample
* Also makes ChatForwardingExecutor public
* feat: Expand ChatForwardingExecutor handled types
Make ChatForwardingExecutor match the input types of ChatProtocolExecutor.
* fix: Update for the new AgentRunResponseUpdate merge logic
AIAgent always sends out List<ChatMessage> now.
* Fix the ordering of chained resolvers in JsonSerializerOptions
We want the resolvers from AIJsonUtilities to be used before the ones from the source generator, in case the source generator emits its own copy in that assembly for the M.E.AI types.
* Apply suggestions from code review
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Update dotnet/src/Microsoft.Agents.AI/AgentJsonUtilities.cs
* Update dotnet/src/Microsoft.Agents.AI.Mem0/Mem0JsonUtilities.cs
Co-authored-by: westey <164392973+westey-m@users.noreply.github.com>
* Remove unused using directive in Mem0JsonUtilities
Removed unused using directive for Microsoft.Extensions.AI.
---------
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: westey <164392973+westey-m@users.noreply.github.com>
* fix: Workflow Validation
* adds orphan validation to workflow builder
* adds tests for workflow validation
* expands on the underlying reasoning why type validation is not supported
* fixup: CodeGen template
* [BREAKING] refactor: Normalize WorkflowBuilder APIs
* "partitioner" => "assigner"
* normalize ordering so sources always to the left of targets for edges
* normalize parameter ordering so sources and targets are always first arguments
* remove `params` (users should use collection expressions instead)
* refactor: Align name with Python
In #1551 we added a mechanism to open a Streaming workflow run without providing any input. This caused unintuitive behaviour when passing a string as input without providing a runId, resulting in the input being misinterpreted as the runId and the workflow not executing.
As well, the name caused confusion about why the Workflow was not running when using the input-less StreamAsync (since the Workflow cannot run without any messages to drive its execution).
* refactor: Unify ExecutorIsh and ExecutorRegistration => ExecutorBinding
* Switch to more modern Record type-tree for Sum Types
* Unify APIs for getting ExecutorBinding
* Fix an issue where workflows consisting entirely of cross-run shareable executors which are not instance-resettable do not properly clear state when running non-concurrently.
* feat: Simplify function-to-executor pattern
* refactor: Normalize API naming
* Propagate cancellation token down the stack
* Added unit tests to cover workflow cancellation scenarios
* Updated tests based on feedback to simplify assert.
* Create custom AsyncEnumrable to gracefully handle cancellation for Channel reader. Tailor cancellation tests to declarative scenarios.
* Update comment and naming for readability.
* Fixing minor stylistic recommendation.
---------
Co-authored-by: Chris <66376200+crickman@users.noreply.github.com>
Concurrent run support was recently added to workflows, but Orchestrations did not fully update to support it. A few executors were missing Cross-Run Shareable annotations, and the ConcurrentEnd executor needed to be factory-instantiated.
This also ports the fix for #1613 from #1637, to avoid waiting on that PR.
Checkpointing is used by the WorkflowHostAgent to be able to support resume from a provided thread. When a CheckpointManager is not specified, we use the InMemoryCheckpointManager and serialize its state into the thread's Serialize()ed JsonElement.
At some point InMemoryCheckpointManager became not serializable, breaking this behaviour. This change restores serializability, and adds a test.
* Fix handoff function naming
We don't need the agent's name or a guid in the handoff name... we can just use simple numbering. There's a possibility that someone built an agent with a built-in function tool named "handoff_to_x"; if that turns out to be an issue, we could add back some longer bit of randomness.
* Update dotnet/src/Microsoft.Agents.AI.Workflows/Specialized/HandoffAgentExecutor.cs
---------
Co-authored-by: Chris <66376200+crickman@users.noreply.github.com>
Remove input type checking in favour of explicit `.DescribeProtocolAsync()` flow. Also removes `.AsAgentAsync()` as the validation happens at workflow run time. This makes it easier to use Workflows with DI without resorting to async-over-sync.
* refactor: remove unused internals
* feat: Execution Mode for sharing a workflow among concurrent runs
* feat: Update WorkflowHostAgent to support concurrent execution
* Also update AsAgent APIs to support injecting a CheckpointManager and an IWorkflowExecutionEnvironment
* fix: Make Read logic consistent in DeclarativeWorkflowContext
WorkflowHostAgent was initially implemented before Checkpointing was available. This meant that in order to support resuming, the WorkflowHostAgent needed to keep the runs around, which broke it when stricter rules about concurrent sharing of workflows during execution were introduced.
This change updates the hosting logic to release the underlying StreamingRun when the RunStreamingAsync or RunAsync are invoked, in favour of keeping the checkpointing information in the WorkflowThread to enable resumption.
- Added ChatMessage[] handler to ConfigureRoutes to support array dispatch
- Workflow runtime can dispatch messages as either List<ChatMessage> or ChatMessage[]
- Added 10 comprehensive unit tests validating message routing behavior
- Tests ensure functionality and protect against future refactoring (issue #782)
- Updated code comments to reflect exact-type-matching requirement
Fixes issue where raw WorkflowBuilder with AIAgent nodes failed to receive
initial messages due to missing array type handler.
* add workflow edge data properties to the workflow.definition tag.
* use workflow info classes for workflow.definition tag value
* add unit test
* fix test
* fix formatting issue
* remove flaky unit test
* remove unused package dependency
* Updates to async run loop.
* fix: Workflow Onwership can be release by nonowner
* fix: Incorrect handling of blockOnPending in StreamingRun
Depending on whether we are running in streaming on non-streaming mode, we may be using the StreamingRun in different ways. Unfortunately, the only place we can really know what is the actual state of execution is in the RunEventStream implementations.
This resulted in blocking where blocking was unneeded and occasionally not-blocking when blocking was needed.
The fix is to move the logic of handling this blocking into RunEventStream implementations.
* fix: Fix cleanup on error and end run
This ensures we clean up the background resources correctly.
* fix: Ensure we let the run loop proceed when shutting down
* fix: Add timeout for Input Waiting
* fix: Make the samples properly clean up `Run`s and `StreamingRun`s
* fix: Simplify Declarative Workflow Run disposal pattern
* Also fixes missing .Disposal() in Integration tests
---------
Co-authored-by: Ben Thomas <ben.thomas@microsoft.com>
Add optional name and description fields to workflows in both Python and .NET implementations, matching the existing agent API pattern.
Python changes:
- Add name/description parameters to WorkflowBuilder.__init__
- Add name/description attributes to Workflow class
- Include name/description in to_dict() serialization
- Add WORKFLOW_NAME and WORKFLOW_DESCRIPTION OTEL attributes
- Add tests in test_serialization.py and test_workflow_observability.py
.NET changes:
- Add Name and Description properties to Workflow and Workflow<T>
- Add WithName() and WithDescription() fluent methods to WorkflowBuilder
- Add WorkflowName and WorkflowDescription OTEL tags
- Add test in WorkflowBuilderSmokeTests.cs
This enables applications like DevUI to display human-readable workflow names (e.g., 'Data Processing Pipeline') instead of auto-generated UUIDs (e.g., 'Workflow 50fdd917').
Fixes: #1181
* feat: Add support for Workflow-as-Executor
* Fixes routing of 'object' compile-typed variables to properly take in type information
* Fixes a concurrency issue in StepTracer
* fix: Make Subworkflow ExternalRequests work properly
* fix: Threading and Concurrency fixes; prep for OffThread Mode
* refactor: Remove dead code around OffStreamRunEventStream
Currently not used, and will be replaced with a rewrite when brought back, so having it in the change is not valuable.
* ci: Work around issues with dotnet-format not properly analyzing the source
* fix: Fix the logic of AsyncCoordinator and AsyncBarrier
* Prevent individual wait cancellations from canceling the entire barrier
* Propagate information about whether the wait was completed or cancelled, and whether any waiters were present when released
* fix: Remove superfluous acces to .Keys in InProcStepTracer
* refactor: Clean up AsyncCoordinator's use of AsyncBarrier
* Update M.A.AI.OpenAI implementations
- There was only a ChatClient-based agent. Add a Responses one, too.
- Fix the public extension methods to create OpenAI types even when not backed by the right OpenAI client.
- Add reusable AgentRunResponse{Update} to ChatResponse{Update} conversion routines that are then used by the OpenAI agents and elsewhere
* Address feedback
* Adding more test for workflow vizualization.
* Improving README for sample.
* More cleanup.
* Removing rendering of workflow visualization and adding basic support for mermaid format.
* Adding basic mermaid tests.
* Improving sample. Switching to another branch.
* About to merge from main.
* Formatting.
* More fromatting.
* Removng uneeded call to ToUpper.
* Adding README.
* Moving samples under workflow to workflows.
* Removing uneeded README for map-reduce sample.