Skip to content

Commit

Permalink
.Net: Adds Process Framework with Aspire demo (#10614)
Browse files Browse the repository at this point in the history
### Motivation and Context

This demo aims to showcase how the [Semantic Kernel Process
Framework](https://learn.microsoft.com/en-us/semantic-kernel/overview/)
can be used with [.NET
Aspire](https://learn.microsoft.com/en-us/dotnet/aspire/get-started/aspire-overview).
The Process Framework allows developers to create business processes
based on events. Each step of the process can be an agent or native
code.

### Description

In this demo, I have defined the agents as external services, and each
step will call these agents using HTTP requests. This setup allows .NET
Aspire to add value by tracing the process using OpenTelemetry.
Additionally, since each agent is a service, they can be restarted as
needed using the .NET Aspire developer dashboard.


![architecture](https://github.com/user-attachments/assets/e8a570f9-6887-4fa2-8e3d-7a7ec9225c41)

### Why .NET Aspire?

Thanks to .NET Aspire, developers can leverage the developer dashboard
to debug in real time the Process and all the agents running. Since the
agents are single APIs, each can scale independently from each other.


![aspire-dashboard](https://github.com/user-attachments/assets/93a6b043-2b87-4d18-a5e9-929690146443)

![aspire-metrics](https://github.com/user-attachments/assets/1ae308dd-3be0-465d-a4cb-411efd77fd23)

![aspire-traces](https://github.com/user-attachments/assets/86fd9da1-d289-48d9-83ad-c90cdfeaf740)


### Contribution Checklist

<!-- Before submitting this PR, please make sure: -->

- [x] The code builds clean without any errors or warnings
- [x] The PR follows the [SK Contribution
Guidelines](https://github.com/microsoft/semantic-kernel/blob/main/CONTRIBUTING.md)
and the [pre-submission formatting
script](https://github.com/microsoft/semantic-kernel/blob/main/CONTRIBUTING.md#development-scripts)
raises no violations
- [x] All unit tests pass, and I have added new tests where possible
- [x] I didn't break anyone 😄

---------

Co-authored-by: Chris Rickman <crickman@microsoft.com>
Co-authored-by: Chris <66376200+crickman@users.noreply.github.com>
Co-authored-by: Devis Lucato <dluc@users.noreply.github.com>
  • Loading branch information
4 people authored Feb 21, 2025
1 parent f431685 commit 4c91cfd
Show file tree
Hide file tree
Showing 33 changed files with 897 additions and 2 deletions.
4 changes: 3 additions & 1 deletion .github/_typos.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@ extend-exclude = [
"PopulationByAdmin1.csv",
"WomensSuffrage.txt",
"SK-dotnet.sln.DotSettings",
"**/azure_ai_search_hotel_samples/README.md"
"**/azure_ai_search_hotel_samples/README.md",
"**/Demos/ProcessFrameworkWithAspire/ProcessFramework.Aspire/ProcessFramework.Aspire.ProcessOrchestrator/Program.cs",
"**/Demos/ProcessFrameworkWithAspire/**/*.http"
]

[default.extend-words]
Expand Down
13 changes: 12 additions & 1 deletion dotnet/Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
<PackageVersion Include="AWSSDK.BedrockAgentRuntime" Version="4.0.0-preview.5" />
<PackageVersion Include="AWSSDK.BedrockRuntime" Version="4.0.0-preview.5" />
<PackageVersion Include="AWSSDK.Core" Version="4.0.0-preview.5" />
<PackageVersion Include="Aspire.Azure.AI.OpenAI" Version="9.0.0-preview.5.24551.3" />
<PackageVersion Include="Aspire.Hosting.AppHost" Version="9.0.0" />
<PackageVersion Include="Aspire.Hosting.Azure.CognitiveServices" Version="9.0.0" />
<PackageVersion Include="AWSSDK.Extensions.NETCore.Setup" Version="4.0.0-preview.5" />
<PackageVersion Include="Azure.AI.ContentSafety" Version="1.0.0" />
<PackageVersion Include="Azure.AI.Inference" Version="1.0.0-beta.2" />
Expand All @@ -22,6 +25,7 @@
<PackageVersion Include="Dapr.AspNetCore" Version="1.14.0" />
<PackageVersion Include="FastBertTokenizer" Version="1.0.28" />
<PackageVersion Include="Microsoft.AspNetCore.Mvc.Testing" Version="8.0.0" />
<PackageVersion Include="Microsoft.AspNetCore.OpenApi" Version="8.0.13" />
<PackageVersion Include="Microsoft.ML.Tokenizers.Data.Cl100kBase" Version="1.0.0" />
<PackageVersion Include="Microsoft.IdentityModel.JsonWebTokens" Version="7.5.1" />
<PackageVersion Include="Microsoft.VisualStudio.Threading" Version="17.12.19" />
Expand Down Expand Up @@ -53,6 +57,11 @@
<PackageVersion Include="OllamaSharp" Version="5.0.7" />
<PackageVersion Include="OpenAI" Version="[2.2.0-beta.1]" />
<PackageVersion Include="OpenTelemetry.Exporter.Console" Version="1.9.0" />
<PackageVersion Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.9.0" />
<PackageVersion Include="OpenTelemetry.Extensions.Hosting" Version="1.9.0" />
<PackageVersion Include="OpenTelemetry.Instrumentation.AspNetCore" Version="1.9.0" />
<PackageVersion Include="OpenTelemetry.Instrumentation.Http" Version="1.9.0" />
<PackageVersion Include="OpenTelemetry.Instrumentation.Runtime" Version="1.9.0" />
<PackageVersion Include="PdfPig" Version="0.1.9" />
<PackageVersion Include="Pinecone.NET" Version="2.1.1" />
<PackageVersion Include="Prompty.Core" Version="0.0.23-alpha" />
Expand All @@ -78,14 +87,16 @@
<PackageVersion Include="Microsoft.Extensions.Configuration" Version="8.0.0" />
<PackageVersion Include="Microsoft.Extensions.Configuration.Abstractions" Version="8.0.0" />
<PackageVersion Include="Microsoft.Extensions.Configuration.Binder" Version="8.0.2" />
<PackageVersion Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="8.0.0" />
<PackageVersion Include="Microsoft.Extensions.Configuration.EnvironmentVariables"
Version="8.0.0" />
<PackageVersion Include="Microsoft.Extensions.Configuration.Json" Version="8.0.0" />
<PackageVersion Include="Microsoft.Extensions.Configuration.UserSecrets" Version="8.0.0" />
<PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="8.0.1" />
<PackageVersion Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="8.0.2" />
<PackageVersion Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
<PackageVersion Include="Microsoft.Extensions.Http" Version="8.0.1" />
<PackageVersion Include="Microsoft.Extensions.Http.Resilience" Version="8.9.1" />
<PackageVersion Include="Microsoft.Extensions.ServiceDiscovery" Version="9.0.0" />
<PackageVersion Include="Microsoft.Extensions.Logging" Version="8.0.1" />
<PackageVersion Include="Microsoft.Extensions.Logging.Abstractions" Version="8.0.2" />
<PackageVersion Include="Microsoft.Extensions.Logging.Console" Version="8.0.0" />
Expand Down
59 changes: 59 additions & 0 deletions dotnet/SK-dotnet.sln
Original file line number Diff line number Diff line change
Expand Up @@ -445,6 +445,22 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Plugins.AI.UnitTests", "src
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Connectors.Postgres.UnitTests", "src\Connectors\Connectors.Postgres.UnitTests\Connectors.Postgres.UnitTests.csproj", "{2A1EC0DA-AD01-4421-AADC-1DFF65C71CCC}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ProcessFrameworkWithAspire", "ProcessFrameworkWithAspire", "{3F260A77-B6C9-97FD-1304-4B34DA936CF4}"
ProjectSection(SolutionItems) = preProject
samples\Demos\ProcessFrameworkWithAspire\README.md = samples\Demos\ProcessFrameworkWithAspire\README.md
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ProcessFramework.Aspire.AppHost", "samples\Demos\ProcessFrameworkWithAspire\ProcessFramework.Aspire\ProcessFramework.Aspire.AppHost\ProcessFramework.Aspire.AppHost.csproj", "{2756FED3-ABC1-4F58-932E-5DD05A5EE066}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ProcessFramework.Aspire.ProcessOrchestrator", "samples\Demos\ProcessFrameworkWithAspire\ProcessFramework.Aspire\ProcessFramework.Aspire.ProcessOrchestrator\ProcessFramework.Aspire.ProcessOrchestrator.csproj", "{05E102FA-A766-4B10-B95A-54060AB56596}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ProcessFramework.Aspire.ServiceDefaults", "samples\Demos\ProcessFrameworkWithAspire\ProcessFramework.Aspire\ProcessFramework.Aspire.ServiceDefaults\ProcessFramework.Aspire.ServiceDefaults.csproj", "{4FA81B79-85D1-4B5D-B0D3-1EDBEF05A623}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ProcessFramework.Aspire.Shared", "samples\Demos\ProcessFrameworkWithAspire\ProcessFramework.Aspire\ProcessFramework.Aspire.Shared\ProcessFramework.Aspire.Shared.csproj", "{6FE977F6-D508-4DF0-951F-749B0D5C7109}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ProcessFramework.Aspire.SummaryAgent", "samples\Demos\ProcessFrameworkWithAspire\ProcessFramework.Aspire\ProcessFramework.Aspire.SummaryAgent\ProcessFramework.Aspire.SummaryAgent.csproj", "{37381352-4F10-427F-AB8A-51FEAB265201}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ProcessFramework.Aspire.TranslatorAgent", "samples\Demos\ProcessFrameworkWithAspire\ProcessFramework.Aspire\ProcessFramework.Aspire.TranslatorAgent\ProcessFramework.Aspire.TranslatorAgent.csproj", "{DAD5FC6A-8CA0-43AC-87E1-032DFBD6B02A}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Agents.Bedrock", "src\Agents\Bedrock\Agents.Bedrock.csproj", "{8C658E1E-83C8-4127-B8BF-27A638A45DDD}"
EndProject
Global
Expand Down Expand Up @@ -1198,6 +1214,42 @@ Global
{2A1EC0DA-AD01-4421-AADC-1DFF65C71CCC}.Publish|Any CPU.Build.0 = Debug|Any CPU
{2A1EC0DA-AD01-4421-AADC-1DFF65C71CCC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2A1EC0DA-AD01-4421-AADC-1DFF65C71CCC}.Release|Any CPU.Build.0 = Release|Any CPU
{2756FED3-ABC1-4F58-932E-5DD05A5EE066}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2756FED3-ABC1-4F58-932E-5DD05A5EE066}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2756FED3-ABC1-4F58-932E-5DD05A5EE066}.Publish|Any CPU.ActiveCfg = Debug|Any CPU
{2756FED3-ABC1-4F58-932E-5DD05A5EE066}.Publish|Any CPU.Build.0 = Debug|Any CPU
{2756FED3-ABC1-4F58-932E-5DD05A5EE066}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2756FED3-ABC1-4F58-932E-5DD05A5EE066}.Release|Any CPU.Build.0 = Release|Any CPU
{05E102FA-A766-4B10-B95A-54060AB56596}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{05E102FA-A766-4B10-B95A-54060AB56596}.Debug|Any CPU.Build.0 = Debug|Any CPU
{05E102FA-A766-4B10-B95A-54060AB56596}.Publish|Any CPU.ActiveCfg = Debug|Any CPU
{05E102FA-A766-4B10-B95A-54060AB56596}.Publish|Any CPU.Build.0 = Debug|Any CPU
{05E102FA-A766-4B10-B95A-54060AB56596}.Release|Any CPU.ActiveCfg = Release|Any CPU
{05E102FA-A766-4B10-B95A-54060AB56596}.Release|Any CPU.Build.0 = Release|Any CPU
{4FA81B79-85D1-4B5D-B0D3-1EDBEF05A623}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4FA81B79-85D1-4B5D-B0D3-1EDBEF05A623}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4FA81B79-85D1-4B5D-B0D3-1EDBEF05A623}.Publish|Any CPU.ActiveCfg = Debug|Any CPU
{4FA81B79-85D1-4B5D-B0D3-1EDBEF05A623}.Publish|Any CPU.Build.0 = Debug|Any CPU
{4FA81B79-85D1-4B5D-B0D3-1EDBEF05A623}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4FA81B79-85D1-4B5D-B0D3-1EDBEF05A623}.Release|Any CPU.Build.0 = Release|Any CPU
{6FE977F6-D508-4DF0-951F-749B0D5C7109}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6FE977F6-D508-4DF0-951F-749B0D5C7109}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6FE977F6-D508-4DF0-951F-749B0D5C7109}.Publish|Any CPU.ActiveCfg = Debug|Any CPU
{6FE977F6-D508-4DF0-951F-749B0D5C7109}.Publish|Any CPU.Build.0 = Debug|Any CPU
{6FE977F6-D508-4DF0-951F-749B0D5C7109}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6FE977F6-D508-4DF0-951F-749B0D5C7109}.Release|Any CPU.Build.0 = Release|Any CPU
{37381352-4F10-427F-AB8A-51FEAB265201}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{37381352-4F10-427F-AB8A-51FEAB265201}.Debug|Any CPU.Build.0 = Debug|Any CPU
{37381352-4F10-427F-AB8A-51FEAB265201}.Publish|Any CPU.ActiveCfg = Debug|Any CPU
{37381352-4F10-427F-AB8A-51FEAB265201}.Publish|Any CPU.Build.0 = Debug|Any CPU
{37381352-4F10-427F-AB8A-51FEAB265201}.Release|Any CPU.ActiveCfg = Release|Any CPU
{37381352-4F10-427F-AB8A-51FEAB265201}.Release|Any CPU.Build.0 = Release|Any CPU
{DAD5FC6A-8CA0-43AC-87E1-032DFBD6B02A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DAD5FC6A-8CA0-43AC-87E1-032DFBD6B02A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DAD5FC6A-8CA0-43AC-87E1-032DFBD6B02A}.Publish|Any CPU.ActiveCfg = Debug|Any CPU
{DAD5FC6A-8CA0-43AC-87E1-032DFBD6B02A}.Publish|Any CPU.Build.0 = Debug|Any CPU
{DAD5FC6A-8CA0-43AC-87E1-032DFBD6B02A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DAD5FC6A-8CA0-43AC-87E1-032DFBD6B02A}.Release|Any CPU.Build.0 = Release|Any CPU
{8C658E1E-83C8-4127-B8BF-27A638A45DDD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8C658E1E-83C8-4127-B8BF-27A638A45DDD}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8C658E1E-83C8-4127-B8BF-27A638A45DDD}.Publish|Any CPU.ActiveCfg = Publish|Any CPU
Expand Down Expand Up @@ -1368,6 +1420,13 @@ Global
{0C64EC81-8116-4388-87AD-BA14D4B59974} = {D6D598DF-C17C-46F4-B2B9-CDE82E2DE132}
{03ACF9DD-00C9-4F2B-80F1-537E2151AF5F} = {D6D598DF-C17C-46F4-B2B9-CDE82E2DE132}
{2A1EC0DA-AD01-4421-AADC-1DFF65C71CCC} = {5A7028A7-4DDF-4E4F-84A9-37CE8F8D7E89}
{3F260A77-B6C9-97FD-1304-4B34DA936CF4} = {5D4C0700-BBB5-418F-A7B2-F392B9A18263}
{2756FED3-ABC1-4F58-932E-5DD05A5EE066} = {3F260A77-B6C9-97FD-1304-4B34DA936CF4}
{05E102FA-A766-4B10-B95A-54060AB56596} = {3F260A77-B6C9-97FD-1304-4B34DA936CF4}
{4FA81B79-85D1-4B5D-B0D3-1EDBEF05A623} = {3F260A77-B6C9-97FD-1304-4B34DA936CF4}
{6FE977F6-D508-4DF0-951F-749B0D5C7109} = {3F260A77-B6C9-97FD-1304-4B34DA936CF4}
{37381352-4F10-427F-AB8A-51FEAB265201} = {3F260A77-B6C9-97FD-1304-4B34DA936CF4}
{DAD5FC6A-8CA0-43AC-87E1-032DFBD6B02A} = {3F260A77-B6C9-97FD-1304-4B34DA936CF4}
{8C658E1E-83C8-4127-B8BF-27A638A45DDD} = {6823CD5E-2ABE-41EB-B865-F86EC13F0CF9}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<Project Sdk="Microsoft.NET.Sdk">

<Sdk Name="Aspire.AppHost.Sdk" Version="9.0.0" />

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<RollForward>LatestMajor</RollForward>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsAspireHost>true</IsAspireHost>
<UserSecretsId>61efcc24-41eb-4a92-8ebe-64de14ed54dd</UserSecretsId>
<NoWarn>$(NoWarn);CS1591</NoWarn>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Aspire.Hosting.AppHost" />
<PackageReference Include="Aspire.Hosting.Azure.CognitiveServices" />
</ItemGroup>

<ItemGroup>
<ProjectReference
Include="..\..\..\..\..\src\Experimental\Process.LocalRuntime\Process.LocalRuntime.csproj">
<IsAspireProjectResource>false</IsAspireProjectResource>
</ProjectReference>
<ProjectReference
Include="..\ProcessFramework.Aspire.ProcessOrchestrator\ProcessFramework.Aspire.ProcessOrchestrator.csproj" />
<ProjectReference
Include="..\ProcessFramework.Aspire.SummaryAgent\ProcessFramework.Aspire.SummaryAgent.csproj" />
<ProjectReference
Include="..\ProcessFramework.Aspire.TranslatorAgent\ProcessFramework.Aspire.TranslatorAgent.csproj" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Copyright (c) Microsoft. All rights reserved.

var builder = DistributedApplication.CreateBuilder(args);

var openai = builder.AddConnectionString("openAiConnectionName");

var translateAgent = builder.AddProject<Projects.ProcessFramework_Aspire_TranslatorAgent>("translatoragent")
.WithReference(openai);

var summaryAgent = builder.AddProject<Projects.ProcessFramework_Aspire_SummaryAgent>("summaryagent")
.WithReference(openai);

var processOrchestrator = builder.AddProject<Projects.ProcessFramework_Aspire_ProcessOrchestrator>("processorchestrator")
.WithReference(translateAgent)
.WithReference(summaryAgent);

builder.Build().Run();
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning",
"Aspire.Hosting.Dcp": "Warning"
}
},
"ConnectionStrings": {
"openAiConnectionName": "https://{account_name}.openai.azure.com/"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Copyright (c) Microsoft. All rights reserved.

namespace ProcessFramework.Aspire.ProcessOrchestrator.Models;

public static class ProcessEvents
{
public static readonly string TranslateDocument = nameof(TranslateDocument);
public static readonly string DocumentTranslated = nameof(DocumentTranslated);
public static readonly string SummarizeDocument = nameof(SummarizeDocument);
public static readonly string DocumentSummarized = nameof(DocumentSummarized);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<RollForward>LatestMajor</RollForward>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<NoWarn>
$(NoWarn);CS8618,IDE0009,CA1051,CA1050,CA1707,CA1054,CA2007,VSTHRD111,CS1591,RCS1110,RCS1243,CA5394,SKEXP0001,SKEXP0010,SKEXP0020,SKEXP0040,SKEXP0050,SKEXP0060,SKEXP0070,SKEXP0080,SKEXP0101,SKEXP0110,OPENAI001
</NoWarn>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.OpenApi" />
<PackageReference Include="Aspire.Azure.AI.OpenAI" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\..\..\..\src\Experimental\Process.Core\Process.Core.csproj" />
<ProjectReference
Include="..\..\..\..\..\src\Experimental\Process.LocalRuntime\Process.LocalRuntime.csproj" />
<ProjectReference
Include="..\ProcessFramework.Aspire.ServiceDefaults\ProcessFramework.Aspire.ServiceDefaults.csproj" />
<ProjectReference
Include="..\ProcessFramework.Aspire.Shared\ProcessFramework.Aspire.Shared.csproj" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
GET https://localhost:7207/api/processdoc
Accept: application/json

###

Loading

0 comments on commit 4c91cfd

Please sign in to comment.