Implementation:Microsoft Semantic kernel AddStepFromProcess
| Knowledge Sources | |
|---|---|
| Domains | Process_Orchestration, Composite_Pattern |
| Last Updated | 2026-02-11 19:00 GMT |
Overview
Pattern for nesting processes within processes using AddStepFromProcess and WhereInputEventIs to create modular, reusable workflow compositions.
Description
AddStepFromProcess is a method on ProcessBuilder that adds a child ProcessBuilder as a step within a parent process. The child process is treated as a single step from the parent's perspective, but internally contains its own graph of steps and event routes. The WhereInputEventIs method on the returned sub-process builder maps parent-level events to the child's declared input events, creating the event boundary bridge between the two scopes.
When a child process is added, the builder marks it with HasParentProcess = true, signaling that the child's lifecycle is managed by the parent. The child process's entry steps become accessible through the WhereInputEventIs method, which returns a ProcessFunctionTargetBuilder scoped to the parent process, allowing seamless routing from parent events to child input events.
Usage
Use AddStepFromProcess whenever you want to embed a reusable sub-workflow within a larger process. Define the child process independently using its own ProcessBuilder, then add it as a step to the parent and map events using WhereInputEventIs.
Code Reference
Source Location
- Repository: semantic-kernel
- Sample:
dotnet/samples/GettingStartedWithProcesses/Step02/Step02b_AccountOpening.cs:L30-31
Key Signatures
// On ProcessBuilder - adds a child process as a step
public ProcessBuilder AddStepFromProcess(
ProcessBuilder kernelProcess,
IReadOnlyList<string>? aliases = null);
// On the returned ProcessBuilder - maps parent events to child input events
public ProcessFunctionTargetBuilder WhereInputEventIs(string eventId);
Import
using Microsoft.SemanticKernel;
I/O Contract
AddStepFromProcess Inputs
| Name | Type | Required | Description |
|---|---|---|---|
| kernelProcess | ProcessBuilder |
Yes | The child process builder to add as a step. Its HasParentProcess is set to true. |
| aliases | IReadOnlyList<string>? |
No | Previous step names for backward compatibility with saved state. |
AddStepFromProcess Output
| Name | Type | Description |
|---|---|---|
| return | ProcessBuilder |
The child process builder, now registered as a step. Use WhereInputEventIs to map events. |
WhereInputEventIs Inputs
| Name | Type | Required | Description |
|---|---|---|---|
| eventId | string |
Yes | The input event Id declared by the child process via OnInputEvent. Must match exactly. |
WhereInputEventIs Output
| Name | Type | Description |
|---|---|---|
| return | ProcessFunctionTargetBuilder |
A target builder scoped to the parent process that routes events into the child's input event. |
Usage Examples
Defining a Reusable Child Process
A child process is defined independently as a static factory method. It has its own steps, its own OnInputEvent entry points, and its own internal routing.
public static class NewAccountVerificationProcess
{
public static ProcessBuilder CreateProcess()
{
ProcessBuilder process = new("AccountVerificationProcess");
var creditCheckStep = process.AddStepFromType<CreditScoreCheckStep>();
var fraudDetectionStep = process.AddStepFromType<FraudDetectionStep>();
// Child process declares its input events
process
.OnInputEvent(AccountOpeningEvents.NewCustomerFormCompleted)
.SendEventTo(new ProcessFunctionTargetBuilder(
creditCheckStep,
functionName: CreditScoreCheckStep.ProcessStepFunctions.DetermineCreditScore,
parameterName: "customerDetails"))
.SendEventTo(new ProcessFunctionTargetBuilder(
fraudDetectionStep,
functionName: FraudDetectionStep.ProcessStepFunctions.FraudDetectionCheck,
parameterName: "customerDetails"));
// Internal routing between child steps
creditCheckStep
.OnEvent(AccountOpeningEvents.CreditScoreCheckApproved)
.SendEventTo(new ProcessFunctionTargetBuilder(
fraudDetectionStep,
functionName: FraudDetectionStep.ProcessStepFunctions.FraudDetectionCheck,
parameterName: "previousCheckSucceeded"));
return process;
}
}
Adding Child Processes to a Parent
The parent process adds child processes as steps and maps its events to the child's input events using WhereInputEventIs.
ProcessBuilder process = new("AccountOpeningProcessWithSubprocesses");
// Add atomic steps
var formStep = process.AddStepFromType<CompleteNewCustomerFormStep>();
var userInputStep = process.AddStepFromType<UserInputStep>();
var mailServiceStep = process.AddStepFromType<MailServiceStep>();
// Add child processes as steps
var accountVerificationStep =
process.AddStepFromProcess(NewAccountVerificationProcess.CreateProcess());
var accountCreationStep =
process.AddStepFromProcess(NewAccountCreationProcess.CreateProcess());
// Route a parent event to multiple child processes simultaneously
formStep
.OnEvent(AccountOpeningEvents.NewCustomerFormCompleted)
.SendEventTo(
accountVerificationStep.WhereInputEventIs(
AccountOpeningEvents.NewCustomerFormCompleted))
.SendEventTo(
accountCreationStep.WhereInputEventIs(
AccountOpeningEvents.NewCustomerFormCompleted));
// Route transcript to the creation subprocess
formStep
.OnEvent(AccountOpeningEvents.CustomerInteractionTranscriptReady)
.SendEventTo(
accountCreationStep.WhereInputEventIs(
AccountOpeningEvents.CustomerInteractionTranscriptReady));
Routing Child Process Output Events to Parent Steps
Events emitted by child processes with Public visibility bubble up to the parent. The parent routes them like any other step event.
// Child process emits public events that the parent can capture
accountVerificationStep
.OnEvent(AccountOpeningEvents.CreditScoreCheckRejected)
.SendEventTo(new ProcessFunctionTargetBuilder(mailServiceStep));
accountVerificationStep
.OnEvent(AccountOpeningEvents.FraudDetectionCheckFailed)
.SendEventTo(new ProcessFunctionTargetBuilder(mailServiceStep));
accountVerificationStep
.OnEvent(AccountOpeningEvents.FraudDetectionCheckPassed)
.SendEventTo(
accountCreationStep.WhereInputEventIs(
AccountOpeningEvents.NewAccountVerificationCheckPassed));
// Child process output leads to parent process completion
accountCreationStep
.OnEvent(AccountOpeningEvents.WelcomePacketCreated)
.SendEventTo(new ProcessFunctionTargetBuilder(mailServiceStep));
mailServiceStep
.OnEvent(AccountOpeningEvents.MailServiceSent)
.StopProcess();