Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

.Net Processes: fixing KernelProcessStateMetadata usage #9598

Merged
Original file line number Diff line number Diff line change
@@ -1,47 +1,55 @@
{
"$type": "Process",
"stepsState": {
"FriedFishWithStatefulStepsProcess": {
"$type": "Process",
"stepsState": {
"GatherFriedFishIngredientsWithStockStep": {
"state": {
"IngredientsStock": 4
},
"id": "32301d167a604f7bb1b69663d8feafe6",
"$type": "Step",
"id": "2908f8c88cf0476a8e0075c3a8020d5d",
"name": "GatherFriedFishIngredientsWithStockStep",
"versionInfo": "GatherFishIngredient.V2"
"versionInfo": "GatherFishIngredient.V2",
"state": {
"IngredientsStock": 3
}
},
"CutFoodStep": {
"id": "3be68c614bc44bedb7bce0f002110968",
"$type": "Step",
"id": "014388cf0bbd41119b8730dfc4b0b459",
"name": "CutFoodStep",
"versionInfo": "CutFoodStep.V1"
},
"FryFoodStep": {
"id": "5f80945fafec4a0bbeccf3ff23a8c1a1",
"$type": "Step",
"id": "c55af0425d864c4e97b6ae67bd715480",
"name": "FryFoodStep",
"versionInfo": "FryFoodStep.V1"
}
},
"id": "c9d2e56dcc5a4b5ea73e05ae53635c90",
"id": "cab89a17aeae4b9a97568967dbf1ea47",
"name": "FriedFishWithStatefulStepsProcess",
"versionInfo": "FriedFishProcess.v1"
},
"AddBunsStep": {
"id": "ef113fc874b0473c9c275827effe8dd8",
"$type": "Step",
"id": "35d09b83dea24ddf8e0c24fbe6a3746c",
"name": "AddBunsStep",
"versionInfo": "v1"
},
"AddSpecialSauceStep": {
"id": "65a35f6dec6e45cab9e1b4df7d43a6bd",
"$type": "Step",
"id": "aa0d408976574afea94387e3da7ca111",
"name": "AddSpecialSauceStep",
"versionInfo": "v1"
},
"ExternalFriedFishStep": {
"id": "ab186a81480a45249cfff9e0c56319b8",
"$type": "Step",
"id": "2eda38b8ee8745a4ab8b21f4fa01d173",
"name": "ExternalFriedFishStep",
"versionInfo": "v1"
}
},
"id": "0de6d539-c1bf-44ad-816d-650231cd2034",
"id": "973b06f1-a522-4d2d-9e1c-ec45a07e275c",
"name": "FishSandwichWithStatefulStepsProcess",
"versionInfo": "FishSandwich.V1"
}
Original file line number Diff line number Diff line change
@@ -1,47 +1,55 @@
{
"$type": "Process",
"stepsState": {
"FriedFishWithStatefulStepsProcess": {
"$type": "Process",
"stepsState": {
"GatherFriedFishIngredientsWithStockStep": {
"$type": "Step",
"id": "2908f8c88cf0476a8e0075c3a8020d5d",
"name": "GatherFriedFishIngredientsWithStockStep",
"versionInfo": "GatherFishIngredient.V2",
"state": {
"IngredientsStock": 1
},
"id": "32301d167a604f7bb1b69663d8feafe6",
"name": "GatherFriedFishIngredientsWithStockStep",
"versionInfo": "GatherFishIngredient.V2"
}
},
"CutFoodStep": {
"id": "3be68c614bc44bedb7bce0f002110968",
"$type": "Step",
"id": "014388cf0bbd41119b8730dfc4b0b459",
"name": "CutFoodStep",
"versionInfo": "CutFoodStep.V1"
},
"FryFoodStep": {
"id": "5f80945fafec4a0bbeccf3ff23a8c1a1",
"$type": "Step",
"id": "c55af0425d864c4e97b6ae67bd715480",
"name": "FryFoodStep",
"versionInfo": "FryFoodStep.V1"
}
},
"id": "c9d2e56dcc5a4b5ea73e05ae53635c90",
"id": "cab89a17aeae4b9a97568967dbf1ea47",
"name": "FriedFishWithStatefulStepsProcess",
"versionInfo": "FriedFishProcess.v1"
},
"AddBunsStep": {
"id": "ef113fc874b0473c9c275827effe8dd8",
"$type": "Step",
"id": "35d09b83dea24ddf8e0c24fbe6a3746c",
"name": "AddBunsStep",
"versionInfo": "v1"
},
"AddSpecialSauceStep": {
"id": "65a35f6dec6e45cab9e1b4df7d43a6bd",
"$type": "Step",
"id": "aa0d408976574afea94387e3da7ca111",
"name": "AddSpecialSauceStep",
"versionInfo": "v1"
},
"ExternalFriedFishStep": {
"id": "ab186a81480a45249cfff9e0c56319b8",
"$type": "Step",
"id": "2eda38b8ee8745a4ab8b21f4fa01d173",
"name": "ExternalFriedFishStep",
"versionInfo": "v1"
}
},
"id": "0de6d539-c1bf-44ad-816d-650231cd2034",
"id": "973b06f1-a522-4d2d-9e1c-ec45a07e275c",
"name": "FishSandwichWithStatefulStepsProcess",
"versionInfo": "FishSandwich.V1"
}
Original file line number Diff line number Diff line change
@@ -1,25 +1,29 @@
{
"$type": "Process",
"stepsState": {
"GatherFriedFishIngredientsWithStockStep": {
"state": {
"IngredientsStock": 4
},
"id": "7d492b6c1ea9404b8adb4c9b0c8f7589",
"$type": "Step",
"id": "92a4cda38c7248648b0aa7ffaaa57f21",
"name": "GatherFriedFishIngredientsWithStockStep",
"versionInfo": "GatherFishIngredient.V2"
"versionInfo": "GatherFishIngredient.V2",
"state": {
"IngredientsStock": 3
}
},
"CutFoodStep": {
"id": "7c0d4dce18644abf92941ff2538806dc",
"$type": "Step",
"id": "7ace89e38e1c48b0b3a700b40d160c68",
"name": "CutFoodStep",
"versionInfo": "CutFoodStep.V1"
},
"FryFoodStep": {
"id": "de06bfb72a3d4f05ba3b4fd4ceb43e1f",
"$type": "Step",
"id": "09bc39ba6d9745439c7c792b8dac0af7",
"name": "FryFoodStep",
"versionInfo": "FryFoodStep.V1"
}
},
"id": "412f3ad1-d0fd-42f1-9c74-109cff87c75c",
"id": "669c5850-9efc-4585-b3f0-9291a4471887",
"name": "FriedFishWithStatefulStepsProcess",
"versionInfo": "FriedFishProcess.v1"
}
Original file line number Diff line number Diff line change
@@ -1,25 +1,29 @@
{
"$type": "Process",
"stepsState": {
"GatherFriedFishIngredientsWithStockStep": {
"$type": "Step",
"id": "92a4cda38c7248648b0aa7ffaaa57f21",
"name": "GatherFriedFishIngredientsWithStockStep",
"versionInfo": "GatherFishIngredient.V2",
"state": {
"IngredientsStock": 1
},
"id": "7d492b6c1ea9404b8adb4c9b0c8f7589",
"name": "GatherFriedFishIngredientsWithStockStep",
"versionInfo": "GatherFishIngredient.V2"
}
},
"CutFoodStep": {
"id": "7c0d4dce18644abf92941ff2538806dc",
"$type": "Step",
"id": "7ace89e38e1c48b0b3a700b40d160c68",
"name": "CutFoodStep",
"versionInfo": "CutFoodStep.V1"
},
"FryFoodStep": {
"id": "de06bfb72a3d4f05ba3b4fd4ceb43e1f",
"$type": "Step",
"id": "09bc39ba6d9745439c7c792b8dac0af7",
"name": "FryFoodStep",
"versionInfo": "FryFoodStep.V1"
}
},
"id": "412f3ad1-d0fd-42f1-9c74-109cff87c75c",
"id": "669c5850-9efc-4585-b3f0-9291a4471887",
"name": "FriedFishWithStatefulStepsProcess",
"versionInfo": "FriedFishProcess.v1"
}
Original file line number Diff line number Diff line change
@@ -1,25 +1,29 @@
{
"$type": "Process",
"stepsState": {
"GatherFriedFishIngredientsWithStockStep": {
"$type": "Step",
"id": "92a4cda38c7248648b0aa7ffaaa57f21",
"name": "GatherFriedFishIngredientsWithStockStep",
"versionInfo": "GatherFishIngredient.V2",
"state": {
"IngredientsStock": 0
},
"id": "7d492b6c1ea9404b8adb4c9b0c8f7589",
"name": "GatherFriedFishIngredientsWithStockStep",
"versionInfo": "GatherFishIngredient.V2"
}
},
"CutFoodStep": {
"id": "7c0d4dce18644abf92941ff2538806dc",
"$type": "Step",
"id": "7ace89e38e1c48b0b3a700b40d160c68",
"name": "CutFoodStep",
"versionInfo": "CutFoodStep.V1"
},
"FryFoodStep": {
"id": "de06bfb72a3d4f05ba3b4fd4ceb43e1f",
"$type": "Step",
"id": "09bc39ba6d9745439c7c792b8dac0af7",
"name": "FryFoodStep",
"versionInfo": "FryFoodStep.V1"
}
},
"id": "412f3ad1-d0fd-42f1-9c74-109cff87c75c",
"id": "669c5850-9efc-4585-b3f0-9291a4471887",
"name": "FriedFishWithStatefulStepsProcess",
"versionInfo": "FriedFishProcess.v1"
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public static void DumpProcessStateMetadataLocally(KernelProcessStateMetadata pr

using StreamReader reader = new(filepath);
var content = reader.ReadToEnd();
return JsonSerializer.Deserialize<KernelProcessStateMetadata>(content);
return JsonSerializer.Deserialize<KernelProcessStateMetadata>(content, s_jsonOptions);
}

private static string GetRepositoryProcessStateFilepath(string jsonRelativePath, bool checkFilepathExists = false)
Expand Down Expand Up @@ -62,7 +62,7 @@ private static void StoreProcessStateLocally(KernelProcessStateMetadata processS
throw new KernelException($"Filepath for process {processStateInfo.Name} does not have .json extension");
}

var content = JsonSerializer.Serialize(processStateInfo, s_jsonOptions);
var content = JsonSerializer.Serialize<KernelProcessStepStateMetadata>(processStateInfo, s_jsonOptions);
Console.WriteLine($"Process State: \n{content}");
Console.WriteLine($"Saving Process State Locally: \n{Path.GetFullPath(fullFilepath)}");
File.WriteAllText(fullFilepath, content);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ namespace Microsoft.SemanticKernel.Process.Models;
/// <summary>
/// Process state used for State Persistence serialization
/// </summary>
public record class KernelProcessStateMetadata : KernelProcessStepStateMetadata<object>
public sealed record class KernelProcessStateMetadata : KernelProcessStepStateMetadata
{
/// <summary>
/// Process State of Steps if provided
/// </summary>
[DataMember]
[JsonPropertyName("stepsState")]
public Dictionary<string, KernelProcessStateMetadata>? StepsState { get; set; }
public Dictionary<string, KernelProcessStepStateMetadata>? StepsState { get; set; } = null;
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,16 @@

using System.Runtime.Serialization;
using System.Text.Json.Serialization;
using Microsoft.SemanticKernel.Process.Internal;

namespace Microsoft.SemanticKernel.Process.Models;

/// <summary>
/// Step state used for State Persistence serialization
/// </summary>
[JsonPolymorphic(TypeDiscriminatorPropertyName = "$type", UnknownDerivedTypeHandling = JsonUnknownDerivedTypeHandling.FallBackToNearestAncestor)]
[JsonDerivedType(typeof(KernelProcessStepStateMetadata), typeDiscriminator: nameof(ProcessConstants.SupportedComponents.Step))]
[JsonDerivedType(typeof(KernelProcessStateMetadata), typeDiscriminator: nameof(ProcessConstants.SupportedComponents.Process))]
public record class KernelProcessStepStateMetadata
{
/// <summary>
Expand All @@ -33,17 +37,11 @@ public record class KernelProcessStepStateMetadata
[DataMember]
[JsonPropertyName("versionInfo")]
public string? VersionInfo { get; init; } = null;
}

/// <summary>
/// Step state used for State Persistence serialization for stateful steps
/// </summary>
public record class KernelProcessStepStateMetadata<TState> : KernelProcessStepStateMetadata where TState : class, new()
{
/// <summary>
/// The user-defined state object associated with the Step.
/// The user-defined state object associated with the Step (if the step is stateful)
/// </summary>
[DataMember]
[JsonPropertyName("state")]
public TState? State { get; set; } = null;
public object? State { get; set; } = null;
}
7 changes: 1 addition & 6 deletions dotnet/src/Experimental/Process.Core/Internal/EndStep.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,7 @@ internal override Dictionary<string, KernelFunctionMetadata> GetFunctionMetadata
return [];
}

internal override KernelProcessStepInfo BuildStep()
{
return this.BuildStep(null);
}

internal override KernelProcessStepInfo BuildStep(KernelProcessStepStateMetadata<object>? stateMetadata)
internal override KernelProcessStepInfo BuildStep(KernelProcessStepStateMetadata? stateMetadata = null)
{
// The end step has no state.
return new KernelProcessStepInfo(typeof(KernelProcessStepState), new KernelProcessStepState(ProcessConstants.EndStepName, version: ProcessConstants.InternalStepsVersion), []);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ private static KernelProcessStateMetadata SanitizeProcessStateMetadata(KernelPro
// version mismatch - check if migration logic in place
if (step is ProcessBuilder subprocessBuilder)
{
var sanitizedStepState = SanitizeProcessStateMetadata(savedStateMetadata, subprocessBuilder.Steps.ToList());
var sanitizedStepState = SanitizeProcessStateMetadata((KernelProcessStateMetadata)savedStateMetadata, subprocessBuilder.Steps.ToList());
sanitizedStateMetadata.StepsState[step.Name] = sanitizedStepState;
}
else if (false)
Expand All @@ -80,7 +80,7 @@ private static KernelProcessStateMetadata SanitizeProcessStateMetadata(KernelPro
else
{
// no compatible state found, migrating id only
sanitizedStateMetadata.StepsState[step.Name] = new KernelProcessStateMetadata()
sanitizedStateMetadata.StepsState[step.Name] = new KernelProcessStepStateMetadata()
{
Name = step.Name,
Id = step.Id,
Expand Down
22 changes: 3 additions & 19 deletions dotnet/src/Experimental/Process.Core/ProcessBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -96,31 +96,15 @@ internal override Dictionary<string, KernelFunctionMetadata> GetFunctionMetadata
/// </summary>
/// <param name="stateMetadata">State to apply to the step on the build process</param>
/// <returns></returns>
internal override KernelProcessStepInfo BuildStep(KernelProcessStepStateMetadata<object>? stateMetadata)
internal override KernelProcessStepInfo BuildStep(KernelProcessStepStateMetadata? stateMetadata = null)
{
// The step is a, process so we can return the step info directly.
if (stateMetadata is KernelProcessStateMetadata processState)
esttenorio marked this conversation as resolved.
Show resolved Hide resolved
{
return this.BuildStep(processState);
return this.Build(processState);
}

return this.BuildStep();
}

/// <summary>
/// Build the subprocess step
/// </summary>
/// <param name="stateMetadata">State to apply to the step on the build process</param>
/// <returns></returns>
private KernelProcess BuildStep(KernelProcessStateMetadata? stateMetadata)
{
// The step is a process so we can return the step info directly.
return this.Build(stateMetadata);
}

internal override KernelProcessStepInfo BuildStep()
{
return this.Build(null);
return this.Build();
}

#region Public Interface
Expand Down
Loading
Loading