Skip to content

Commit

Permalink
improved fluent syntax and test
Browse files Browse the repository at this point in the history
  • Loading branch information
joslat committed Dec 17, 2024
1 parent 4a21254 commit b15ab00
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,43 +25,21 @@ public async Task UseSimplestProcessAsync()
{
// Create a simple kernel
Kernel kernel = Kernel.CreateBuilder()
.Build();
.Build();

ProcessBuilder processBuilder = new(nameof(Step00_Processes));

// Create a process that will interact with the chat completion service
ProcessBuilder process = new("ChatBot");
var startStep = processBuilder.AddStepFromType<StartStep>();
var doSomeWorkStep = processBuilder.AddStepFromType<DoSomeWorkStep>();
var doMoreWorkStep = processBuilder.AddStepFromType<DoMoreWorkStep>();
var lastStep = processBuilder.AddStepFromType<LastStep>();

// Define the process flow
processBuilder
.OnInputEvent(ProcessEvents.StartProcess)
.SendEventTo(new ProcessFunctionTargetBuilder(startStep));

startStep
.OnFunctionResult()
.SendEventTo(new ProcessFunctionTargetBuilder(doSomeWorkStep));

doSomeWorkStep
.OnFunctionResult()
.SendEventTo(new ProcessFunctionTargetBuilder(doMoreWorkStep));

doMoreWorkStep
.OnFunctionResult()
.SendEventTo(new ProcessFunctionTargetBuilder(lastStep));

lastStep
.OnFunctionResult()
.StopProcess();
.StartWith<StartStep>(ProcessEvents.StartProcess)
.AndThen<DoSomeWorkStep>()
.AndThen<DoMoreWorkStep>()
.AndFinally<LastStep>();

// Build the process to get a handle that can be started
KernelProcess kernelProcess = process.Build();
KernelProcess kernelProcess = processBuilder.Build();

// Start the process with an initial external event
using var runningProcess = await kernelProcess.StartAsync(
using var runningProcess = await kernelProcess!.StartAsync(
kernel,
new KernelProcessEvent()
{
Expand Down
72 changes: 72 additions & 0 deletions dotnet/src/Experimental/Process.Core/ProcessBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -315,5 +315,77 @@ public ProcessBuilder(string name)
{
}

/// <summary>
/// Starts the process with the specified step and binds it to the given input event.
/// </summary>
/// <typeparam name="TStep">The step type to start the process.</typeparam>
/// <param name="eventName">The name of the input event that triggers the start.</param>
/// <param name="name">Optional: The name of the step.</param>
/// <returns>The current ProcessBuilder instance.</returns>
public ProcessBuilder StartWith<TStep>(string eventName, string? name = null) where TStep : KernelProcessStep
{
Verify.NotNullOrWhiteSpace(eventName, nameof(eventName));

// Add the first step
var stepBuilder = this.AddStepFromType<TStep>(name);

// Bind the step to the input event
this.OnInputEvent(eventName)
.SendEventTo(new ProcessFunctionTargetBuilder(stepBuilder));

return this;
}

/// <summary>
/// Chains the next step in the process using an input event or a function result.
/// </summary>
/// <typeparam name="TStep">The step type to add next.</typeparam>
/// <param name="eventOrFunctionName">The event name or function name that triggers this transition.</param>
/// <param name="name">Optional: The name of the step.</param>
/// <returns>The current ProcessBuilder instance.</returns>
public ProcessBuilder AndThen<TStep>(string? eventOrFunctionName = null, string? name = null) where TStep : KernelProcessStep
{
// Ensure there is a previous step
if (this._steps.Count == 0)
{
throw new InvalidOperationException("AndThen cannot be called before StartWith.");
}

// Get the previous step
var previousStepBuilder = this._steps.Last();

// Add the next step
var nextStepBuilder = this.AddStepFromType<TStep>(name);

// Determine the edge builder from the previous step
ProcessStepEdgeBuilder edgeBuilder = string.IsNullOrWhiteSpace(eventOrFunctionName)
? previousStepBuilder.OnFunctionResult() // Default to OnFunctionResult
: previousStepBuilder.OnEvent(eventOrFunctionName); // Use OnEvent if specified

Check failure on line 363 in dotnet/src/Experimental/Process.Core/ProcessBuilder.cs

View workflow job for this annotation

GitHub Actions / dotnet-build-and-test (8.0, ubuntu-latest, Release, true, integration)

Possible null reference argument for parameter 'eventId' in 'ProcessStepEdgeBuilder ProcessStepBuilder.OnEvent(string eventId)'.

Check failure on line 363 in dotnet/src/Experimental/Process.Core/ProcessBuilder.cs

View workflow job for this annotation

GitHub Actions / dotnet-build-and-test (8.0, ubuntu-latest, Release, true, integration)

Possible null reference argument for parameter 'eventId' in 'ProcessStepEdgeBuilder ProcessStepBuilder.OnEvent(string eventId)'.

Check failure on line 363 in dotnet/src/Experimental/Process.Core/ProcessBuilder.cs

View workflow job for this annotation

GitHub Actions / dotnet-build-and-test (8.0, windows-latest, Debug)

Possible null reference argument for parameter 'eventId' in 'ProcessStepEdgeBuilder ProcessStepBuilder.OnEvent(string eventId)'.

Check failure on line 363 in dotnet/src/Experimental/Process.Core/ProcessBuilder.cs

View workflow job for this annotation

GitHub Actions / dotnet-build-and-test (8.0, windows-latest, Debug)

Possible null reference argument for parameter 'eventId' in 'ProcessStepEdgeBuilder ProcessStepBuilder.OnEvent(string eventId)'.

Check failure on line 363 in dotnet/src/Experimental/Process.Core/ProcessBuilder.cs

View workflow job for this annotation

GitHub Actions / dotnet-build-and-test (8.0, windows-latest, Release)

Possible null reference argument for parameter 'eventId' in 'ProcessStepEdgeBuilder ProcessStepBuilder.OnEvent(string eventId)'.

Check failure on line 363 in dotnet/src/Experimental/Process.Core/ProcessBuilder.cs

View workflow job for this annotation

GitHub Actions / dotnet-build-and-test (8.0, windows-latest, Release)

Possible null reference argument for parameter 'eventId' in 'ProcessStepEdgeBuilder ProcessStepBuilder.OnEvent(string eventId)'.

// Link the edge to the next step
edgeBuilder.SendEventTo(new ProcessFunctionTargetBuilder(nextStepBuilder));

return this;
}

/// <summary>
/// Marks the final step in the process and stops the process automatically.
/// </summary>
/// <typeparam name="TStep">The step type to add as the final step.</typeparam>
/// <param name="eventOrFunctionName">The event name or function name that triggers this transition.</param>
/// <param name="name">Optional: The name of the step.</param>
/// <returns>The current ProcessBuilder instance.</returns>
public ProcessBuilder AndFinally<TStep>(string? eventOrFunctionName = null, string? name = null) where TStep : KernelProcessStep
{
this.AndThen<TStep>(eventOrFunctionName, name);

// Get the final step
var finalStepBuilder = this._steps.Last();

finalStepBuilder.OnFunctionResult().StopProcess();

return this;
}

#endregion
}

0 comments on commit b15ab00

Please sign in to comment.