Merge pull request #6461 from elsa-workflows/task/remove-agents

Remove Agents
This commit is contained in:
Sipke Schoorstra 2025-03-02 16:11:02 +01:00 committed by GitHub
commit e0c1dafbbb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
166 changed files with 20 additions and 4864 deletions

View file

@ -64,7 +64,6 @@
<PackageVersion Include="Microsoft.Data.SqlClient" Version="5.2.2" />
<PackageVersion Include="Microsoft.Identity.Client" Version="4.67.2" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
<PackageVersion Include="Microsoft.SemanticKernel" Version="1.34.0" />
<PackageVersion Include="Microsoft.SourceLink.GitHub" Version="8.0.0" />
<PackageVersion Include="MongoDB.Driver" Version="3.1.0" />
<PackageVersion Include="MongoDB.Driver.Core.Extensions.DiagnosticSources" Version="2.0.0" />

View file

@ -298,16 +298,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "trace-lens", "trace-lens",
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "integrations", "integrations", "{EBD0CF78-C5D7-4B4B-94C9-C5D8C20B6F59}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "agents", "agents", "{50470834-4CD8-479A-8B58-0A1869BA5D37}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Elsa.Agents.Core", "src\modules\Elsa.Agents.Core\Elsa.Agents.Core.csproj", "{5BD671F0-9603-4C2F-8364-54B02986EAA2}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Elsa.Agents.Api", "src\modules\Elsa.Agents.Api\Elsa.Agents.Api.csproj", "{154525CD-3726-45B7-9A9C-553BBC60EB10}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Elsa.Agents.Activities", "src\modules\Elsa.Agents.Activities\Elsa.Agents.Activities.csproj", "{F620D7DC-B58D-4BD0-81A2-E88A2C1E4833}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Elsa.Agents.Persistence.EntityFrameworkCore", "src\modules\Elsa.Agents.Persistence.EntityFrameworkCore\Elsa.Agents.Persistence.EntityFrameworkCore.csproj", "{6FE60BB4-DE6A-485C-A38A-1317C56AF2DA}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Elsa.Secrets.Core", "src\modules\Elsa.Secrets.Core\Elsa.Secrets.Core.csproj", "{34FAB60D-7259-47B9-B50E-B533C7C3CFEC}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "secrets", "secrets", "{8CEEC194-820A-4C8D-AB9E-E51E6D3E9CC1}"
@ -316,10 +306,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Elsa.Secrets.Management", "
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Elsa.Secrets.Api", "src\modules\Elsa.Secrets.Api\Elsa.Secrets.Api.csproj", "{37D16EAF-ACD8-4105-8BD3-B2745819CFF8}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Elsa.Agents.Persistence", "src\modules\Elsa.Agents.Persistence\Elsa.Agents.Persistence.csproj", "{CFEC357F-0863-4458-A6C4-5D7AA0E44759}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Elsa.Agents.Persistence.EntityFrameworkCore.Sqlite", "src\modules\Elsa.Agents.Persistence.EntityFrameworkCore.Sqlite\Elsa.Agents.Persistence.EntityFrameworkCore.Sqlite.csproj", "{E75762D2-FD12-4165-810B-628C28CB2562}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "migrations", "migrations", "{3666CF13-1353-4620-9472-506670214A6A}"
ProjectSection(SolutionItems) = preProject
scripts\migrations\efcore-3.0.sh = scripts\migrations\efcore-3.0.sh
@ -344,16 +330,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "elsa-studio", "elsa-studio"
scripts\k8s\elsa-studio\service.yaml = scripts\k8s\elsa-studio\service.yaml
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Elsa.Agents.Models", "src\modules\Elsa.Agents.Models\Elsa.Agents.Models.csproj", "{052C4F97-5909-4D88-AA49-4B0D9058A0A9}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Elsa.Secrets.Persistence.EntityFrameworkCore", "src\modules\Elsa.Secrets.Persistence.EntityFrameworkCore\Elsa.Secrets.Persistence.EntityFrameworkCore.csproj", "{9A6D67DE-51B1-456D-B25D-19E0356C8F60}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Elsa.Secrets.Persistence.EntityFrameworkCore.Sqlite", "src\modules\Elsa.Secrets.Persistence.EntityFrameworkCore.Sqlite\Elsa.Secrets.Persistence.EntityFrameworkCore.Sqlite.csproj", "{44A03CF6-4EB6-434C-90D1-FF8142FE394E}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Elsa.Agents.Persistence.EntityFrameworkCore.SqlServer", "src\modules\Elsa.Agents.Persistence.EntityFrameworkCore.SqlServer\Elsa.Agents.Persistence.EntityFrameworkCore.SqlServer.csproj", "{A9140976-DFF9-432A-B1DC-E188A07C49E5}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Elsa.Agents.Persistence.EntityFrameworkCore.MySql", "src\modules\Elsa.Agents.Persistence.EntityFrameworkCore.MySql\Elsa.Agents.Persistence.EntityFrameworkCore.MySql.csproj", "{B3046301-6F00-4885-8B01-080BD489055C}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Elsa.Secrets.Models", "src\modules\Elsa.Secrets.Models\Elsa.Secrets.Models.csproj", "{29D12ADC-55E9-40D0-9E4C-F0EBB6E098EC}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Elsa.Secrets.Scripting", "src\modules\Elsa.Secrets.Scripting\Elsa.Secrets.Scripting.csproj", "{6C606FEB-9A1F-4816-ABE4-22AFA8CEE771}"
@ -368,8 +348,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "multitenancy", "multitenanc
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Elsa.Tenants.AspNetCore", "src\modules\Elsa.Tenants.AspNetCore\Elsa.Tenants.AspNetCore.csproj", "{D5720DBC-8C2B-42D5-9D9F-2FF6EAD4001C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Agents.Persistence.EntityFrameworkCore.PostgreSql", "src\modules\Elsa.Agents.Persistence.EntityFrameworkCore.PostgreSql\Elsa.Agents.Persistence.EntityFrameworkCore.PostgreSql.csproj", "{2B939AC9-03A4-479E-AA0D-CB58F4A7F480}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Kafka", "src\modules\Elsa.Kafka\Elsa.Kafka.csproj", "{BF934627-F531-44FB-BEC2-ECA801FF31E7}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "sql", "sql", "{A0DC5F8E-5D7F-4E8A-A5DF-B1FC31F7336E}"
@ -735,22 +713,6 @@ Global
{47FBCB04-0C2D-453C-BE2F-7052CAC22524}.Debug|Any CPU.Build.0 = Debug|Any CPU
{47FBCB04-0C2D-453C-BE2F-7052CAC22524}.Release|Any CPU.ActiveCfg = Release|Any CPU
{47FBCB04-0C2D-453C-BE2F-7052CAC22524}.Release|Any CPU.Build.0 = Release|Any CPU
{5BD671F0-9603-4C2F-8364-54B02986EAA2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5BD671F0-9603-4C2F-8364-54B02986EAA2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5BD671F0-9603-4C2F-8364-54B02986EAA2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5BD671F0-9603-4C2F-8364-54B02986EAA2}.Release|Any CPU.Build.0 = Release|Any CPU
{154525CD-3726-45B7-9A9C-553BBC60EB10}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{154525CD-3726-45B7-9A9C-553BBC60EB10}.Debug|Any CPU.Build.0 = Debug|Any CPU
{154525CD-3726-45B7-9A9C-553BBC60EB10}.Release|Any CPU.ActiveCfg = Release|Any CPU
{154525CD-3726-45B7-9A9C-553BBC60EB10}.Release|Any CPU.Build.0 = Release|Any CPU
{F620D7DC-B58D-4BD0-81A2-E88A2C1E4833}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F620D7DC-B58D-4BD0-81A2-E88A2C1E4833}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F620D7DC-B58D-4BD0-81A2-E88A2C1E4833}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F620D7DC-B58D-4BD0-81A2-E88A2C1E4833}.Release|Any CPU.Build.0 = Release|Any CPU
{6FE60BB4-DE6A-485C-A38A-1317C56AF2DA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6FE60BB4-DE6A-485C-A38A-1317C56AF2DA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6FE60BB4-DE6A-485C-A38A-1317C56AF2DA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6FE60BB4-DE6A-485C-A38A-1317C56AF2DA}.Release|Any CPU.Build.0 = Release|Any CPU
{34FAB60D-7259-47B9-B50E-B533C7C3CFEC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{34FAB60D-7259-47B9-B50E-B533C7C3CFEC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{34FAB60D-7259-47B9-B50E-B533C7C3CFEC}.Release|Any CPU.ActiveCfg = Release|Any CPU
@ -763,18 +725,6 @@ Global
{37D16EAF-ACD8-4105-8BD3-B2745819CFF8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{37D16EAF-ACD8-4105-8BD3-B2745819CFF8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{37D16EAF-ACD8-4105-8BD3-B2745819CFF8}.Release|Any CPU.Build.0 = Release|Any CPU
{CFEC357F-0863-4458-A6C4-5D7AA0E44759}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{CFEC357F-0863-4458-A6C4-5D7AA0E44759}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CFEC357F-0863-4458-A6C4-5D7AA0E44759}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CFEC357F-0863-4458-A6C4-5D7AA0E44759}.Release|Any CPU.Build.0 = Release|Any CPU
{E75762D2-FD12-4165-810B-628C28CB2562}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E75762D2-FD12-4165-810B-628C28CB2562}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E75762D2-FD12-4165-810B-628C28CB2562}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E75762D2-FD12-4165-810B-628C28CB2562}.Release|Any CPU.Build.0 = Release|Any CPU
{052C4F97-5909-4D88-AA49-4B0D9058A0A9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{052C4F97-5909-4D88-AA49-4B0D9058A0A9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{052C4F97-5909-4D88-AA49-4B0D9058A0A9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{052C4F97-5909-4D88-AA49-4B0D9058A0A9}.Release|Any CPU.Build.0 = Release|Any CPU
{9A6D67DE-51B1-456D-B25D-19E0356C8F60}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9A6D67DE-51B1-456D-B25D-19E0356C8F60}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9A6D67DE-51B1-456D-B25D-19E0356C8F60}.Release|Any CPU.ActiveCfg = Release|Any CPU
@ -783,14 +733,6 @@ Global
{44A03CF6-4EB6-434C-90D1-FF8142FE394E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{44A03CF6-4EB6-434C-90D1-FF8142FE394E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{44A03CF6-4EB6-434C-90D1-FF8142FE394E}.Release|Any CPU.Build.0 = Release|Any CPU
{A9140976-DFF9-432A-B1DC-E188A07C49E5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A9140976-DFF9-432A-B1DC-E188A07C49E5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A9140976-DFF9-432A-B1DC-E188A07C49E5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A9140976-DFF9-432A-B1DC-E188A07C49E5}.Release|Any CPU.Build.0 = Release|Any CPU
{B3046301-6F00-4885-8B01-080BD489055C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B3046301-6F00-4885-8B01-080BD489055C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B3046301-6F00-4885-8B01-080BD489055C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B3046301-6F00-4885-8B01-080BD489055C}.Release|Any CPU.Build.0 = Release|Any CPU
{29D12ADC-55E9-40D0-9E4C-F0EBB6E098EC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{29D12ADC-55E9-40D0-9E4C-F0EBB6E098EC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{29D12ADC-55E9-40D0-9E4C-F0EBB6E098EC}.Release|Any CPU.ActiveCfg = Release|Any CPU
@ -815,10 +757,6 @@ Global
{D5720DBC-8C2B-42D5-9D9F-2FF6EAD4001C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D5720DBC-8C2B-42D5-9D9F-2FF6EAD4001C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D5720DBC-8C2B-42D5-9D9F-2FF6EAD4001C}.Release|Any CPU.Build.0 = Release|Any CPU
{2B939AC9-03A4-479E-AA0D-CB58F4A7F480}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2B939AC9-03A4-479E-AA0D-CB58F4A7F480}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2B939AC9-03A4-479E-AA0D-CB58F4A7F480}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2B939AC9-03A4-479E-AA0D-CB58F4A7F480}.Release|Any CPU.Build.0 = Release|Any CPU
{BF934627-F531-44FB-BEC2-ECA801FF31E7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BF934627-F531-44FB-BEC2-ECA801FF31E7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BF934627-F531-44FB-BEC2-ECA801FF31E7}.Release|Any CPU.ActiveCfg = Release|Any CPU
@ -978,25 +916,15 @@ Global
{6DDB9ECF-D454-4894-A262-A6BB3026E61E} = {B32DB9B2-AD6C-48A5-8682-4373CB045185}
{16B570BC-E293-4A19-B20E-5C97BAF8476B} = {B32DB9B2-AD6C-48A5-8682-4373CB045185}
{EBD0CF78-C5D7-4B4B-94C9-C5D8C20B6F59} = {5BA4A8FA-F7F4-45B3-AEC8-8886D35AAC79}
{50470834-4CD8-479A-8B58-0A1869BA5D37} = {5BA4A8FA-F7F4-45B3-AEC8-8886D35AAC79}
{5BD671F0-9603-4C2F-8364-54B02986EAA2} = {50470834-4CD8-479A-8B58-0A1869BA5D37}
{154525CD-3726-45B7-9A9C-553BBC60EB10} = {50470834-4CD8-479A-8B58-0A1869BA5D37}
{F620D7DC-B58D-4BD0-81A2-E88A2C1E4833} = {50470834-4CD8-479A-8B58-0A1869BA5D37}
{6FE60BB4-DE6A-485C-A38A-1317C56AF2DA} = {50470834-4CD8-479A-8B58-0A1869BA5D37}
{34FAB60D-7259-47B9-B50E-B533C7C3CFEC} = {8CEEC194-820A-4C8D-AB9E-E51E6D3E9CC1}
{8CEEC194-820A-4C8D-AB9E-E51E6D3E9CC1} = {5BA4A8FA-F7F4-45B3-AEC8-8886D35AAC79}
{19329441-2A59-4BAC-A1BE-BBAB70C93CA0} = {8CEEC194-820A-4C8D-AB9E-E51E6D3E9CC1}
{37D16EAF-ACD8-4105-8BD3-B2745819CFF8} = {8CEEC194-820A-4C8D-AB9E-E51E6D3E9CC1}
{CFEC357F-0863-4458-A6C4-5D7AA0E44759} = {50470834-4CD8-479A-8B58-0A1869BA5D37}
{E75762D2-FD12-4165-810B-628C28CB2562} = {50470834-4CD8-479A-8B58-0A1869BA5D37}
{3666CF13-1353-4620-9472-506670214A6A} = {C80C8231-D35C-4ACC-9ED6-9F3DB221535E}
{AA5ACF15-8647-4AC9-B9F5-73FCB92BE7E3} = {C80C8231-D35C-4ACC-9ED6-9F3DB221535E}
{DFFE6199-B5A7-4BA8-A5E1-77D0426C6468} = {B32DB9B2-AD6C-48A5-8682-4373CB045185}
{052C4F97-5909-4D88-AA49-4B0D9058A0A9} = {50470834-4CD8-479A-8B58-0A1869BA5D37}
{9A6D67DE-51B1-456D-B25D-19E0356C8F60} = {8CEEC194-820A-4C8D-AB9E-E51E6D3E9CC1}
{44A03CF6-4EB6-434C-90D1-FF8142FE394E} = {8CEEC194-820A-4C8D-AB9E-E51E6D3E9CC1}
{A9140976-DFF9-432A-B1DC-E188A07C49E5} = {50470834-4CD8-479A-8B58-0A1869BA5D37}
{B3046301-6F00-4885-8B01-080BD489055C} = {50470834-4CD8-479A-8B58-0A1869BA5D37}
{29D12ADC-55E9-40D0-9E4C-F0EBB6E098EC} = {8CEEC194-820A-4C8D-AB9E-E51E6D3E9CC1}
{6C606FEB-9A1F-4816-ABE4-22AFA8CEE771} = {8CEEC194-820A-4C8D-AB9E-E51E6D3E9CC1}
{5F80663C-B072-49DE-9A67-FD804BAD787E} = {6EF07978-A6D2-40EB-891D-7D70C5F37E76}
@ -1004,7 +932,6 @@ Global
{59E7614A-3630-4C39-9C7F-9E12BC95D37E} = {8CEEC194-820A-4C8D-AB9E-E51E6D3E9CC1}
{2F3E1026-5054-4E1F-899B-F1A7F70F9912} = {5BA4A8FA-F7F4-45B3-AEC8-8886D35AAC79}
{D5720DBC-8C2B-42D5-9D9F-2FF6EAD4001C} = {2F3E1026-5054-4E1F-899B-F1A7F70F9912}
{2B939AC9-03A4-479E-AA0D-CB58F4A7F480} = {50470834-4CD8-479A-8B58-0A1869BA5D37}
{BF934627-F531-44FB-BEC2-ECA801FF31E7} = {DD089B8B-DA73-492A-9010-F772D1C178DA}
{A0DC5F8E-5D7F-4E8A-A5DF-B1FC31F7336E} = {5BA4A8FA-F7F4-45B3-AEC8-8886D35AAC79}
{FD3CD5A8-E9B3-467F-90EB-2B7D5B83F348} = {A0DC5F8E-5D7F-4E8A-A5DF-B1FC31F7336E}

View file

@ -1,10 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<ItemGroup>
<ProjectReference Include="..\..\modules\Elsa.Agents.Activities\Elsa.Agents.Activities.csproj" />
<ProjectReference Include="..\..\modules\Elsa.Agents.Api\Elsa.Agents.Api.csproj" />
<ProjectReference Include="..\..\modules\Elsa.Agents.Persistence.EntityFrameworkCore.MySql\Elsa.Agents.Persistence.EntityFrameworkCore.MySql.csproj" Condition=" '$(TargetFramework)' != 'net9.0' " />
<ProjectReference Include="..\..\modules\Elsa.Agents.Persistence.EntityFrameworkCore.Sqlite\Elsa.Agents.Persistence.EntityFrameworkCore.Sqlite.csproj" />
<ProjectReference Include="..\..\modules\Elsa.Caching.Distributed.MassTransit\Elsa.Caching.Distributed.MassTransit.csproj" />
<ProjectReference Include="..\..\modules\Elsa.Caching.Distributed.ProtoActor\Elsa.Caching.Distributed.ProtoActor.csproj" />
<ProjectReference Include="..\..\modules\Elsa.EntityFrameworkCore.MySql\Elsa.EntityFrameworkCore.MySql.csproj" Condition=" '$(TargetFramework)' != 'net9.0' " />

View file

@ -1,5 +1,4 @@
using System.Text.Encodings.Web;
using Elsa.Agents;
using Elsa.Alterations.Extensions;
using Elsa.Alterations.MassTransit.Extensions;
using Elsa.Caching.Options;
@ -94,7 +93,6 @@ const DistributedCachingTransport distributedCachingTransport = DistributedCachi
const MassTransitBroker massTransitBroker = MassTransitBroker.Memory;
const bool useMultitenancy = false;
const bool useTenantsFromConfiguration = true;
const bool useAgents = false;
const bool useSecrets = false;
const bool disableVariableWrappers = false;
const bool disableVariableCopying = false;
@ -213,7 +211,8 @@ services
else if (sqlDatabaseProvider == SqlDatabaseProvider.CockroachDb)
ef.UsePostgreSql(cockroachDbConnectionString!);
else if (sqlDatabaseProvider == SqlDatabaseProvider.Oracle)
ef.UseOracle(oracleConnectionString, new ElsaDbContextOptions{ SchemaName = "ELSA"});
ef.UseOracle(oracleConnectionString, new()
{ SchemaName = "ELSA"});
else
ef.UseSqlite(sp => sp.GetSqliteConnectionString());
@ -256,7 +255,8 @@ services
else if (sqlDatabaseProvider == SqlDatabaseProvider.CockroachDb)
ef.UsePostgreSql(cockroachDbConnectionString!);
else if (sqlDatabaseProvider == SqlDatabaseProvider.Oracle)
ef.UseOracle(oracleConnectionString, new ElsaDbContextOptions{ SchemaName = "ELSA"});
ef.UseOracle(oracleConnectionString, new()
{ SchemaName = "ELSA"});
else
ef.UseSqlite(sp => sp.GetSqliteConnectionString());
@ -304,7 +304,8 @@ services
else if (sqlDatabaseProvider == SqlDatabaseProvider.CockroachDb)
ef.UsePostgreSql(cockroachDbConnectionString);
else if (sqlDatabaseProvider == SqlDatabaseProvider.Oracle)
ef.UseOracle(oracleConnectionString, new ElsaDbContextOptions{ SchemaName = "ELSA"});
ef.UseOracle(oracleConnectionString, new()
{ SchemaName = "ELSA"});
else
ef.UseSqlite(sp => sp.GetSqliteConnectionString());
@ -354,7 +355,7 @@ services
return new RedisDistributedSynchronizationProvider(database);
}
case "File":
return new FileDistributedSynchronizationProvider(new DirectoryInfo(Path.Combine(Directory.GetCurrentDirectory(), "App_Data", "locks")));
return new FileDistributedSynchronizationProvider(new(Path.Combine(Directory.GetCurrentDirectory(), "App_Data", "locks")));
case "Noop":
default:
return new NoopDistributedSynchronizationProvider();
@ -451,7 +452,8 @@ services
else if (sqlDatabaseProvider == SqlDatabaseProvider.CockroachDb)
ef.UsePostgreSql(cockroachDbConnectionString);
else if (sqlDatabaseProvider == SqlDatabaseProvider.Oracle)
ef.UseOracle(oracleConnectionString, new ElsaDbContextOptions{ SchemaName = "ELSA"});
ef.UseOracle(oracleConnectionString, new()
{ SchemaName = "ELSA"});
else
ef.UseSqlite(sp => sp.GetSqliteConnectionString());
@ -536,7 +538,7 @@ services
{
if (sqlDatabaseProvider == SqlDatabaseProvider.SqlServer)
return new SqlServerProvider(sqlServerConnectionString!, true, "", "proto_actor");
return new SqliteProvider(new SqliteConnectionStringBuilder(sqliteConnectionString));
return new SqliteProvider(new(sqliteConnectionString));
};
if (configuration["KUBERNETES_SERVICE_HOST"] != null)
@ -562,18 +564,7 @@ services
kafka.ConfigureOptions(options => configuration.GetSection("Kafka").Bind(options));
});
}
if (useAgents)
{
elsa
.UseAgentActivities()
.UseAgentPersistence(persistence => persistence.UseEntityFrameworkCore(ef => ef.UseSqlite(sp => sp.GetSqliteConnectionString())))
.UseAgentsApi()
;
services.Configure<AgentsOptions>(options => builder.Configuration.GetSection("Agents").Bind(options));
}
if (useSecrets)
{
elsa
@ -647,7 +638,8 @@ services
if (sqlDatabaseProvider == SqlDatabaseProvider.Sqlite) ef.UseSqlite(sqliteConnectionString);
if (sqlDatabaseProvider == SqlDatabaseProvider.SqlServer) ef.UseSqlServer(sqlServerConnectionString);
if (sqlDatabaseProvider == SqlDatabaseProvider.PostgreSql) ef.UsePostgreSql(postgresConnectionString);
if (sqlDatabaseProvider == SqlDatabaseProvider.Oracle) ef.UseOracle(oracleConnectionString, new ElsaDbContextOptions{ SchemaName = "ELSA"});
if (sqlDatabaseProvider == SqlDatabaseProvider.Oracle) ef.UseOracle(oracleConnectionString, new()
{ SchemaName = "ELSA"});
#if !NET9_0
if (sqlDatabaseProvider == SqlDatabaseProvider.MySql)
ef.UseMySql(mySqlConnectionString);

View file

@ -254,82 +254,6 @@
"SweepInterval": "04:00:00"
}
},
"Agents": {
"ApiKeys": [
{
"Name": "MyApiKey",
"Value": "my-api-key"
}
],
"Services": [
{
"Name": "ChatCompletion",
"Type": "OpenAIChatCompletion",
"Settings": {
"ModelId": "gpt-4o",
"ApiKeyRef": "MyApiKey"
}
},
{
"Name": "TextToImage",
"Type": "OpenAITextToImage",
"Settings": {
"ModelId": "dall-e-3",
"ApiKeyRef": "MyApiKey"
}
}
],
"Agents": [
{
"Name": "Copywriter",
"Description": "A persona that writes articles on any topic.",
"Services": [
"ChatCompletion"
],
"FunctionName": "WriteArticle",
"PromptTemplate": "You are a writer of articles about any topic and any additional instructions given to you. The syntax of the article content will be markdown, and your response will be in JSON format containing a \"title\" field and a \"markdown\" field using the following JSON structure: { \"title\": \"The title of the Article\", \"markdown\": \"The article content in markdown syntax.\" }. This is the topic: {{$Topic}}. The article consists of around {{$ParagraphCount}} paragraphs. The article must be written in the language {{$Language}} using the following style: {{$WritingStyle}}. Additional instructions (if any): {{$AdditionalInstructions}}.",
"InputVariables": [
{
"Name": "Topic",
"Description": "The topic to write an article about.",
"Type": "string"
},
{
"Name": "ParagraphCount",
"Description": "The number of paragraphs to write.",
"Type": "int"
},
{
"Name": "Language",
"Description": "The language to write the text in.",
"Type": "string"
},
{
"Name": "WritingStyle",
"Description": "The style to write the text in.",
"Type": "string"
},
{
"Name": "AdditionalInstructions",
"Description": "Any additional instructions.",
"Type": "string"
}
],
"OutputVariable": {
"Name": "Article",
"Description": "The article consisting of a title and markdown text."
},
"ExecutionSettings": {
"MaxTokens": null,
"Temperature": 0.5,
"TopP": 0.9,
"PresencePenalty": 0.5,
"FrequencyPenalty": 0.5,
"ResponseFormat": "json_object"
}
}
]
},
"Webhooks": {
"Sinks": [
{

View file

@ -7,12 +7,7 @@
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\modules\Elsa.Agents.Activities\Elsa.Agents.Activities.csproj" />
<ProjectReference Include="..\..\modules\Elsa.Agents.Api\Elsa.Agents.Api.csproj" />
<ProjectReference Include="..\..\modules\Elsa.Agents.Persistence.EntityFrameworkCore.MySql\Elsa.Agents.Persistence.EntityFrameworkCore.MySql.csproj" Condition=" '$(TargetFramework)' != 'net9.0' " />
<ProjectReference Include="..\..\modules\Elsa.Agents.Persistence.EntityFrameworkCore.PostgreSql\Elsa.Agents.Persistence.EntityFrameworkCore.PostgreSql.csproj" />
<ProjectReference Include="..\..\modules\Elsa.Agents.Persistence.EntityFrameworkCore.Sqlite\Elsa.Agents.Persistence.EntityFrameworkCore.Sqlite.csproj" />
<ProjectReference Include="..\..\modules\Elsa.Agents.Persistence.EntityFrameworkCore.SqlServer\Elsa.Agents.Persistence.EntityFrameworkCore.SqlServer.csproj" />
<ProjectReference Include="..\..\modules\Elsa.Connections.Api\Elsa.Connections.Api.csproj" />
<ProjectReference Include="..\..\modules\Elsa.Connections.Core\Elsa.Connections.Core.csproj" />
<ProjectReference Include="..\..\modules\Elsa.Connections.Persistence.EntityFrameworkCore.Sqlite\Elsa.Connections.Persistence.EntityFrameworkCore.Sqlite.csproj" />

View file

@ -11,9 +11,9 @@ using Elsa.ServerAndStudio.Web.Enums;
using Medallion.Threading.FileSystem;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Data.Sqlite;
using Proto.Persistence.Sqlite;
using WebhooksCore.Options;
using Elsa.Connections.Middleware;
using Proto.Persistence.Sqlite;
const bool useMassTransit = true;
const bool useProtoActor = true;
@ -140,21 +140,6 @@ services
.UseEmail(email => email.ConfigureOptions = options => configuration.GetSection("Smtp").Bind(options))
.UseWebhooks(webhooks => webhooks.ConfigureSinks = options => builder.Configuration.GetSection("Webhooks:Sinks").Bind(options))
.UseWorkflowsApi()
.UseAgentsApi()
.UseAgentPersistence(persistence => persistence.UseEntityFrameworkCore(ef =>
{
if (sqlDatabaseProvider == SqlDatabaseProvider.SqlServer)
ef.UseSqlServer(sqlServerConnectionString);
else if (sqlDatabaseProvider == SqlDatabaseProvider.PostgreSql)
ef.UsePostgreSql(postgreSqlConnectionString);
else if (sqlDatabaseProvider == SqlDatabaseProvider.Sqlite)
ef.UseSqlite(sqliteConnectionString);
#if !NET9_0
else if (sqlDatabaseProvider == SqlDatabaseProvider.MySql)
ef.UseMySql(mySqlConnectionString);
#endif
}))
.UseAgentActivities()
.AddActivitiesFrom<Program>()
.AddWorkflowsFrom<Program>();
@ -195,9 +180,9 @@ services
});
}
elsa.UseConnections(
configure=> configure.AddConnectionsFrom<Program>());
elsa.UseConnectionPersistence(ef=> ef.UseEntityFrameworkCore(f=>f.UseSqlite()));
elsa.UseConnections(
configure=> configure.AddConnectionsFrom<Program>());
elsa.UseConnectionPersistence(ef=> ef.UseEntityFrameworkCore(f=>f.UseSqlite()));
elsa.UseConnectionsApi();
});

View file

@ -1,62 +0,0 @@
using System.ComponentModel;
using System.Dynamic;
using System.Text.Encodings.Web;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Text.Unicode;
using Elsa.Agents.Activities.ActivityProviders;
using Elsa.Expressions.Helpers;
using Elsa.Extensions;
using Elsa.Workflows;
using Elsa.Workflows.Models;
using Elsa.Workflows.Serialization.Converters;
namespace Elsa.Agents.Activities;
/// <summary>
/// An activity that executes a function of a skilled agent. This is an internal activity that is used by <see cref="AgentActivityProvider"/>.
/// </summary>
[Browsable(false)]
public class AgentActivity : CodeActivity
{
private static JsonSerializerOptions? _serializerOptions;
private static JsonSerializerOptions SerializerOptions =>
_serializerOptions ??= new JsonSerializerOptions
{
Encoder = JavaScriptEncoder.Create(UnicodeRanges.All),
PropertyNameCaseInsensitive = true
}.WithConverters(new ExpandoObjectConverterFactory());
[JsonIgnore] internal string AgentName { get; set; } = default!;
/// <inheritdoc />
protected override async ValueTask ExecuteAsync(ActivityExecutionContext context)
{
var activityDescriptor = context.ActivityDescriptor;
var inputDescriptors = activityDescriptor.Inputs;
var functionInput = new Dictionary<string, object?>();
foreach (var inputDescriptor in inputDescriptors)
{
var input = (Input?)inputDescriptor.ValueGetter(this);
var inputValue = input != null ? context.Get(input.MemoryBlockReference()) : default;
functionInput[inputDescriptor.Name] = inputValue;
}
var agentInvoker = context.GetRequiredService<AgentInvoker>();
var result = await agentInvoker.InvokeAgentAsync(AgentName, functionInput, context.CancellationToken);
var json = result.FunctionResult.GetValue<string>();
var outputType = context.ActivityDescriptor.Outputs.Single().Type;
// If the target type is object, we want the JSON to be deserialized into an ExpandoObject for dynamic field access.
if (outputType == typeof(object))
outputType = typeof(ExpandoObject);
var converterOptions = new ObjectConverterOptions(SerializerOptions);
var outputValue = json.ConvertTo(outputType, converterOptions);
var outputDescriptor = activityDescriptor.Outputs.Single();
var output = (Output)outputDescriptor.ValueGetter(this);
context.Set(output, outputValue);
}
}

View file

@ -1,93 +0,0 @@
using Elsa.Expressions.Contracts;
using Elsa.Expressions.Extensions;
using Elsa.Extensions;
using Elsa.Workflows;
using Elsa.Workflows.Models;
using Humanizer;
using JetBrains.Annotations;
namespace Elsa.Agents.Activities.ActivityProviders;
/// <summary>
/// Provides activities for each function of registered agents.
/// </summary>
[UsedImplicitly]
public class AgentActivityProvider(
IKernelConfigProvider kernelConfigProvider,
IActivityDescriber activityDescriber,
IActivityFactory activityFactory,
IWellKnownTypeRegistry wellKnownTypeRegistry
) : IActivityProvider
{
/// <inheritdoc />
public async ValueTask<IEnumerable<ActivityDescriptor>> GetDescriptorsAsync(CancellationToken cancellationToken = default)
{
var kernelConfig = await kernelConfigProvider.GetKernelConfigAsync(cancellationToken);
var agents = kernelConfig.Agents;
var activityDescriptors = new List<ActivityDescriptor>();
foreach (var kvp in agents)
{
var agentConfig = kvp.Value;
var activityDescriptor = await activityDescriber.DescribeActivityAsync(typeof(AgentActivity), cancellationToken);
var activityTypeName = $"Elsa.Agents.{agentConfig.Name.Pascalize()}";
activityDescriptor.Name = agentConfig.Name.Pascalize();
activityDescriptor.TypeName = activityTypeName;
activityDescriptor.Description = agentConfig.Description;
activityDescriptor.DisplayName = agentConfig.Name.Humanize().Transform(To.TitleCase);
activityDescriptor.IsBrowsable = true;
activityDescriptor.Category = "Agents";
activityDescriptor.Kind = ActivityKind.Job;
activityDescriptor.CustomProperties["RootType"] = nameof(AgentActivity);
activityDescriptor.Constructor = context =>
{
var activity = (AgentActivity)activityFactory.Create(typeof(AgentActivity), context);
activity.Type = activityTypeName;
activity.AgentName = agentConfig.Name;
return activity;
};
activityDescriptors.Add(activityDescriptor);
activityDescriptor.Inputs.Clear();
foreach (var inputVariable in agentConfig.InputVariables)
{
var inputName = inputVariable.Name;
var inputType = inputVariable.Type == null! ? "object" : inputVariable.Type;
var nakedInputType = wellKnownTypeRegistry.GetTypeOrDefault(inputType);
var inputDescriptor = new InputDescriptor
{
Name = inputVariable.Name,
DisplayName = inputVariable.Name.Humanize(),
Description = inputVariable.Description,
Type = nakedInputType,
ValueGetter = activity => activity.SyntheticProperties.GetValueOrDefault(inputName),
ValueSetter = (activity, value) => activity.SyntheticProperties[inputName] = value!,
IsSynthetic = true,
IsWrapped = true,
UIHint = ActivityDescriber.GetUIHint(nakedInputType)
};
activityDescriptor.Inputs.Add(inputDescriptor);
}
activityDescriptor.Outputs.Clear();
var outputVariable = agentConfig.OutputVariable;
var outputType = outputVariable.Type == null! ? "object" : outputVariable.Type;
var nakedOutputType = wellKnownTypeRegistry.GetTypeOrDefault(outputType);
var outputName = "Output";
var outputDescriptor = new OutputDescriptor
{
Name = outputName,
Description = agentConfig.OutputVariable.Description,
Type = nakedOutputType,
IsSynthetic = true,
ValueGetter = activity => activity.SyntheticProperties.GetValueOrDefault(outputName),
ValueSetter = (activity, value) => activity.SyntheticProperties[outputName] = value!,
};
activityDescriptor.Outputs.Add(outputDescriptor);
}
return activityDescriptors;
}
}

View file

@ -1,14 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Description>Provides Agent activities</Description>
<PackageTags>elsa module agents semantic kernel llm ai</PackageTags>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Elsa.Agents.Persistence\Elsa.Agents.Persistence.csproj" />
<ProjectReference Include="..\Elsa.Workflows.Management\Elsa.Workflows.Management.csproj" />
<ProjectReference Include="..\Elsa.Agents.Core\Elsa.Agents.Core.csproj" />
</ItemGroup>
</Project>

View file

@ -1,2 +0,0 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=activities/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>

View file

@ -1,22 +0,0 @@
using Elsa.Agents.Activities.Features;
using Elsa.Extensions;
using Elsa.Features.Services;
using JetBrains.Annotations;
// ReSharper disable once CheckNamespace
namespace Elsa.Agents;
/// <summary>
/// An extension class that installs the Agents feature.
/// </summary>
[PublicAPI]
public static class AgentActivitiesFeatureModuleExtensions
{
/// <summary>
/// Installs the Agents feature.
/// </summary>
public static IModule UseAgentActivities(this IModule module, Action<AgentActivitiesFeature>? configure = null)
{
return module.Use(configure);
}
}

View file

@ -1,29 +0,0 @@
using Elsa.Agents.Activities.ActivityProviders;
using Elsa.Agents.Activities.Handlers;
using Elsa.Agents.Features;
using Elsa.Features.Abstractions;
using Elsa.Features.Attributes;
using Elsa.Features.Services;
using Elsa.Workflows.Management.Features;
using JetBrains.Annotations;
using Microsoft.Extensions.DependencyInjection;
namespace Elsa.Agents.Activities.Features;
/// <summary>
/// A feature that installs Semantic Kernel functionality.
/// </summary>
[DependsOn(typeof(WorkflowManagementFeature))]
[DependsOn(typeof(AgentsFeature))]
[UsedImplicitly]
public class AgentActivitiesFeature(IModule module) : FeatureBase(module)
{
/// <inheritdoc />
public override void Apply()
{
Services
.AddActivityProvider<AgentActivityProvider>()
.AddNotificationHandler<RefreshActivityRegistry>()
;
}
}

View file

@ -1,3 +0,0 @@
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
<ConfigureAwait />
</Weavers>

View file

@ -1,21 +0,0 @@
using Elsa.Agents.Activities.ActivityProviders;
using Elsa.Agents.Persistence.Notifications;
using Elsa.Mediator.Contracts;
using Elsa.Workflows;
using JetBrains.Annotations;
namespace Elsa.Agents.Activities.Handlers;
[UsedImplicitly]
public class RefreshActivityRegistry(IActivityRegistry activityRegistry, AgentActivityProvider agentActivityProvider) :
INotificationHandler<AgentDefinitionCreated>,
INotificationHandler<AgentDefinitionUpdated>,
INotificationHandler<AgentDefinitionDeleted>,
INotificationHandler<AgentDefinitionsDeletedInBulk>
{
public Task HandleAsync(AgentDefinitionCreated notification, CancellationToken cancellationToken) => RefreshRegistryAsync(cancellationToken);
public Task HandleAsync(AgentDefinitionUpdated notification, CancellationToken cancellationToken) => RefreshRegistryAsync(cancellationToken);
public Task HandleAsync(AgentDefinitionDeleted notification, CancellationToken cancellationToken) => RefreshRegistryAsync(cancellationToken);
public Task HandleAsync(AgentDefinitionsDeletedInBulk notification, CancellationToken cancellationToken) => RefreshRegistryAsync(cancellationToken);
private Task RefreshRegistryAsync(CancellationToken cancellationToken) => activityRegistry.RefreshDescriptorsAsync(agentActivityProvider, cancellationToken);
}

View file

@ -1,14 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Description>Provides Agents API endpoints</Description>
<PackageTags>elsa module agents semantic kernel api llm ai</PackageTags>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\common\Elsa.Api.Common\Elsa.Api.Common.csproj" />
<ProjectReference Include="..\Elsa.Agents.Activities\Elsa.Agents.Activities.csproj" />
<ProjectReference Include="..\Elsa.Agents.Persistence\Elsa.Agents.Persistence.csproj" />
</ItemGroup>
</Project>

View file

@ -1,2 +0,0 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=models/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>

View file

@ -1,32 +0,0 @@
using Elsa.Abstractions;
using Elsa.Agents.Persistence.Contracts;
using Elsa.Agents.Persistence.Filters;
using JetBrains.Annotations;
namespace Elsa.Agents.Api.Endpoints.Agents.BulkDelete;
/// <summary>
/// Deletes an agent.
/// </summary>
[UsedImplicitly]
public class Endpoint(IAgentManager agentManager) : ElsaEndpoint<BulkDeleteRequest, BulkDeleteResponse>
{
/// <inheritdoc />
public override void Configure()
{
Post("/ai/bulk-actions/agents/delete");
ConfigurePermissions("ai/agents:delete");
}
/// <inheritdoc />
public override async Task<BulkDeleteResponse> ExecuteAsync(BulkDeleteRequest req, CancellationToken ct)
{
var ids = req.Ids;
var filter = new AgentDefinitionFilter
{
Ids = ids
};
var count = await agentManager.DeleteManyAsync(filter, ct);
return new BulkDeleteResponse(count);
}
}

View file

@ -1,68 +0,0 @@
using Elsa.Abstractions;
using Elsa.Agents.Persistence.Contracts;
using Elsa.Agents.Persistence.Entities;
using Elsa.Agents.Persistence.Filters;
using Elsa.Extensions;
using Elsa.Workflows;
using JetBrains.Annotations;
namespace Elsa.Agents.Api.Endpoints.Agents.Create;
/// <summary>
/// Lists all registered agents.
/// </summary>
[UsedImplicitly]
public class Endpoint(IAgentManager agentManager, IIdentityGenerator identityGenerator) : ElsaEndpoint<AgentInputModel, AgentModel>
{
/// <inheritdoc />
public override void Configure()
{
Post("/ai/agents");
ConfigurePermissions("ai/agents:write");
}
/// <inheritdoc />
public override async Task<AgentModel> ExecuteAsync(AgentInputModel req, CancellationToken ct)
{
var isNameUnique = await IsNameUniqueAsync(req.Name, ct);
if (!isNameUnique)
{
AddError("An Agent already exists with the specified name");
await SendErrorsAsync(cancellation: ct);
return null!;
}
var newEntity = new AgentDefinition
{
Id = identityGenerator.GenerateId(),
Name = req.Name.Trim(),
Description = req.Description.Trim(),
AgentConfig = new AgentConfig
{
Description = req.Description.Trim(),
Name = req.Name.Trim(),
Agents = req.Agents,
ExecutionSettings = req.ExecutionSettings,
InputVariables = req.InputVariables,
OutputVariable = req.OutputVariable,
Services = req.Services,
Plugins = req.Plugins,
FunctionName = req.FunctionName,
PromptTemplate = req.PromptTemplate
}
};
await agentManager.AddAsync(newEntity, ct);
return newEntity.ToModel();
}
private async Task<bool> IsNameUniqueAsync(string name, CancellationToken ct)
{
var filter = new AgentDefinitionFilter
{
Name = name
};
return await agentManager.FindAsync(filter, ct) == null;
}
}

View file

@ -1,33 +0,0 @@
using Elsa.Abstractions;
using Elsa.Agents.Persistence.Contracts;
using JetBrains.Annotations;
namespace Elsa.Agents.Api.Endpoints.Agents.Delete;
/// <summary>
/// Deletes an Agent.
/// </summary>
[UsedImplicitly]
public class Endpoint(IAgentManager agentManager) : ElsaEndpoint<Request>
{
/// <inheritdoc />
public override void Configure()
{
Delete("/ai/agents/{id}");
ConfigurePermissions("ai/agents:delete");
}
/// <inheritdoc />
public override async Task HandleAsync(Request req, CancellationToken ct)
{
var entity = await agentManager.GetAsync(req.Id, ct);
if(entity == null)
{
await SendNotFoundAsync(ct);
return;
}
await agentManager.DeleteAsync(entity, ct);
}
}

View file

@ -1,8 +0,0 @@
using System.ComponentModel.DataAnnotations;
namespace Elsa.Agents.Api.Endpoints.Agents.Delete;
public class Request
{
[Required] public string Id { get; set; } = default!;
}

View file

@ -1,26 +0,0 @@
using Elsa.Abstractions;
using Elsa.Agents.Persistence.Contracts;
using JetBrains.Annotations;
namespace Elsa.Agents.Api.Endpoints.Agents.GenerateUniqueName;
/// <summary>
/// Generates a unique name for an agent.
/// </summary>
[UsedImplicitly]
public class Endpoint(IAgentManager agentManager) : ElsaEndpointWithoutRequest<GenerateUniqueNameResponse>
{
/// <inheritdoc />
public override void Configure()
{
Post("/ai/actions/agents/generate-unique-name");
ConfigurePermissions("ai/agents:write");
}
/// <inheritdoc />
public override async Task<GenerateUniqueNameResponse> ExecuteAsync(CancellationToken ct)
{
var newName = await agentManager.GenerateUniqueNameAsync(ct);
return new(newName);
}
}

View file

@ -1,34 +0,0 @@
using Elsa.Abstractions;
using Elsa.Agents.Persistence.Contracts;
using Elsa.Extensions;
using JetBrains.Annotations;
namespace Elsa.Agents.Api.Endpoints.Agents.Get;
/// <summary>
/// Gets an agent.
/// </summary>
[UsedImplicitly]
public class Endpoint(IAgentManager agentManager) : ElsaEndpoint<Request, AgentModel>
{
/// <inheritdoc />
public override void Configure()
{
Get("/ai/agents/{id}");
ConfigurePermissions("ai/agents:read");
}
/// <inheritdoc />
public override async Task<AgentModel> ExecuteAsync(Request req, CancellationToken ct)
{
var entity = await agentManager.GetAsync(req.Id, ct);
if(entity == null)
{
await SendNotFoundAsync(ct);
return null!;
}
return entity.ToModel();
}
}

View file

@ -1,8 +0,0 @@
using System.ComponentModel.DataAnnotations;
namespace Elsa.Agents.Api.Endpoints.Agents.Get;
public class Request
{
[Required] public string Id { get; set; } = default!;
}

View file

@ -1,26 +0,0 @@
using System.Text.Json;
using Elsa.Abstractions;
using JetBrains.Annotations;
namespace Elsa.Agents.Api.Endpoints.Agents.Invoke;
/// <summary>
/// Invokes an agent.
/// </summary>
[UsedImplicitly]
public class Execute(AgentInvoker agentInvoker) : ElsaEndpoint<Request, JsonElement>
{
/// <inheritdoc />
public override void Configure()
{
Post("/ai/agents/{agent}/invoke");
ConfigurePermissions("ai/agents:invoke");
}
/// <inheritdoc />
public override async Task<JsonElement> ExecuteAsync(Request req, CancellationToken ct)
{
var result = await agentInvoker.InvokeAgentAsync(req.Agent, req.Inputs, ct).AsJsonElementAsync();
return result;
}
}

View file

@ -1,7 +0,0 @@
namespace Elsa.Agents.Api.Endpoints.Agents.Invoke;
public class Request
{
public string Agent { get; set; }
public IDictionary<string, object?> Inputs { get; set; }
}

View file

@ -1,26 +0,0 @@
using Elsa.Abstractions;
using Elsa.Agents.Persistence.Contracts;
using JetBrains.Annotations;
namespace Elsa.Agents.Api.Endpoints.Agents.IsUniqueName;
/// <summary>
/// Checks if a name is unique.
/// </summary>
[UsedImplicitly]
public class Endpoint(IAgentManager agentManager) : ElsaEndpoint<IsUniqueNameRequest, IsUniqueNameResponse>
{
/// <inheritdoc />
public override void Configure()
{
Post("/ai/queries/agents/is-unique-name");
ConfigurePermissions("ai/agents:read");
}
/// <inheritdoc />
public override async Task<IsUniqueNameResponse> ExecuteAsync(IsUniqueNameRequest req, CancellationToken ct)
{
var isUnique = await agentManager.IsNameUniqueAsync(req.Name, req.Id, ct);
return new(isUnique);
}
}

View file

@ -1,29 +0,0 @@
using Elsa.Abstractions;
using Elsa.Agents.Persistence.Contracts;
using Elsa.Extensions;
using Elsa.Models;
using JetBrains.Annotations;
namespace Elsa.Agents.Api.Endpoints.Agents.List;
/// <summary>
/// Lists all agents.
/// </summary>
[UsedImplicitly]
public class Endpoint(IAgentManager agentManager) : ElsaEndpointWithoutRequest<ListResponse<AgentModel>>
{
/// <inheritdoc />
public override void Configure()
{
Get("/ai/agents");
ConfigurePermissions("ai/agents:read");
}
/// <inheritdoc />
public override async Task<ListResponse<AgentModel>> ExecuteAsync(CancellationToken ct)
{
var entities = await agentManager.ListAsync(ct);
var models = entities.Select(x => x.ToModel()).ToList();
return new ListResponse<AgentModel>(models);
}
}

View file

@ -1,66 +0,0 @@
using Elsa.Abstractions;
using Elsa.Agents.Persistence.Contracts;
using Elsa.Extensions;
using JetBrains.Annotations;
namespace Elsa.Agents.Api.Endpoints.Agents.Update;
/// <summary>
/// Updates an agent.
/// </summary>
[UsedImplicitly]
public class Endpoint(IAgentManager agentManager) : ElsaEndpoint<AgentInputModel, AgentModel>
{
/// <inheritdoc />
public override void Configure()
{
Post("/ai/agents/{id}");
ConfigurePermissions("ai/agents:write");
}
/// <inheritdoc />
public override async Task<AgentModel> ExecuteAsync(AgentInputModel req, CancellationToken ct)
{
var id = Route<string>("id")!;
var entity = await agentManager.GetAsync(id, ct);
if (entity == null)
{
await SendNotFoundAsync(ct);
return null!;
}
var isNameDuplicate = await IsNameDuplicateAsync(req.Name, id, ct);
if (isNameDuplicate)
{
AddError("Another agent already exists with the specified name");
await SendErrorsAsync(cancellation: ct);
return entity.ToModel();
}
entity.Name = req.Name.Trim();
entity.Description = req.Description.Trim();
entity.AgentConfig = new AgentConfig
{
Name = req.Name.Trim(),
Description = req.Description.Trim(),
FunctionName = req.FunctionName.Trim(),
Services = req.Services,
PromptTemplate = req.PromptTemplate.Trim(),
InputVariables = req.InputVariables,
OutputVariable = req.OutputVariable,
ExecutionSettings = req.ExecutionSettings,
Plugins = req.Plugins,
Agents = req.Agents
};
await agentManager.UpdateAsync(entity, ct);
return entity.ToModel();
}
private async Task<bool> IsNameDuplicateAsync(string name, string id, CancellationToken cancellationToken)
{
return !await agentManager.IsNameUniqueAsync(name, id, cancellationToken);
}
}

View file

@ -1,32 +0,0 @@
using Elsa.Abstractions;
using Elsa.Agents.Persistence.Contracts;
using Elsa.Agents.Persistence.Filters;
using JetBrains.Annotations;
namespace Elsa.Agents.Api.Endpoints.ApiKeys.BulkDelete;
/// <summary>
/// Deletes an API key.
/// </summary>
[UsedImplicitly]
public class Endpoint(IApiKeyStore store) : ElsaEndpoint<BulkDeleteRequest, BulkDeleteResponse>
{
/// <inheritdoc />
public override void Configure()
{
Post("/ai/bulk-actions/api-keys/delete");
ConfigurePermissions("ai/api-keys:delete");
}
/// <inheritdoc />
public override async Task<BulkDeleteResponse> ExecuteAsync(BulkDeleteRequest req, CancellationToken ct)
{
var ids = req.Ids;
var filter = new ApiKeyDefinitionFilter
{
Ids = ids
};
var count = await store.DeleteManyAsync(filter, ct);
return new BulkDeleteResponse(count);
}
}

View file

@ -1,49 +0,0 @@
using Elsa.Abstractions;
using Elsa.Agents.Persistence.Contracts;
using Elsa.Agents.Persistence.Entities;
using Elsa.Agents.Persistence.Filters;
using Elsa.Workflows;
using JetBrains.Annotations;
namespace Elsa.Agents.Api.Endpoints.ApiKeys.Create;
/// <summary>
/// Lists all registered API keys.
/// </summary>
[UsedImplicitly]
public class Endpoint(IApiKeyStore store, IIdentityGenerator identityGenerator) : ElsaEndpoint<ApiKeyInputModel, ApiKeyModel>
{
/// <inheritdoc />
public override void Configure()
{
Post("/ai/api-keys");
ConfigurePermissions("ai/api-keys:write");
}
/// <inheritdoc />
public override async Task<ApiKeyModel> ExecuteAsync(ApiKeyInputModel req, CancellationToken ct)
{
var existingEntityFilter = new ApiKeyDefinitionFilter
{
Name = req.Name
};
var existingEntity = await store.FindAsync(existingEntityFilter, ct);
if (existingEntity != null)
{
AddError("An API key already exists with the specified name");
await SendErrorsAsync(cancellation: ct);
return existingEntity.ToModel();
}
var newEntity = new ApiKeyDefinition
{
Id = identityGenerator.GenerateId(),
Name = req.Name.Trim(),
Value = req.Value.Trim()
};
await store.AddAsync(newEntity, ct);
return newEntity.ToModel();
}
}

View file

@ -1,33 +0,0 @@
using Elsa.Abstractions;
using Elsa.Agents.Persistence.Contracts;
using JetBrains.Annotations;
namespace Elsa.Agents.Api.Endpoints.ApiKeys.Delete;
/// <summary>
/// Delete an API key.
/// </summary>
[UsedImplicitly]
public class Endpoint(IApiKeyStore store) : ElsaEndpoint<Request>
{
/// <inheritdoc />
public override void Configure()
{
Delete("/ai/api-keys/{id}");
ConfigurePermissions("ai/api-keys:delete");
}
/// <inheritdoc />
public override async Task HandleAsync(Request req, CancellationToken ct)
{
var entity = await store.GetAsync(req.Id, ct);
if(entity == null)
{
await SendNotFoundAsync(ct);
return;
}
await store.DeleteAsync(entity, ct);
}
}

View file

@ -1,8 +0,0 @@
using System.ComponentModel.DataAnnotations;
namespace Elsa.Agents.Api.Endpoints.ApiKeys.Delete;
public class Request
{
[Required] public string Id { get; set; } = default!;
}

View file

@ -1,33 +0,0 @@
using Elsa.Abstractions;
using Elsa.Agents.Persistence.Contracts;
using JetBrains.Annotations;
namespace Elsa.Agents.Api.Endpoints.ApiKeys.Get;
/// <summary>
/// Lists all registered API keys.
/// </summary>
[UsedImplicitly]
public class Endpoint(IApiKeyStore store) : ElsaEndpoint<Request, ApiKeyModel>
{
/// <inheritdoc />
public override void Configure()
{
Get("/ai/api-keys/{id}");
ConfigurePermissions("ai/api-keys:read");
}
/// <inheritdoc />
public override async Task<ApiKeyModel> ExecuteAsync(Request req, CancellationToken ct)
{
var entity = await store.GetAsync(req.Id, ct);
if(entity == null)
{
await SendNotFoundAsync(ct);
return null!;
}
return entity.ToModel();
}
}

View file

@ -1,8 +0,0 @@
using System.ComponentModel.DataAnnotations;
namespace Elsa.Agents.Api.Endpoints.ApiKeys.Get;
public class Request
{
[Required] public string Id { get; set; } = default!;
}

View file

@ -1,28 +0,0 @@
using Elsa.Abstractions;
using Elsa.Agents.Persistence.Contracts;
using Elsa.Models;
using JetBrains.Annotations;
namespace Elsa.Agents.Api.Endpoints.ApiKeys.List;
/// <summary>
/// Lists all registered API keys.
/// </summary>
[UsedImplicitly]
public class Endpoint(IApiKeyStore store) : ElsaEndpointWithoutRequest<ListResponse<ApiKeyModel>>
{
/// <inheritdoc />
public override void Configure()
{
Get("/ai/api-keys");
ConfigurePermissions("ai/api-keys:read");
}
/// <inheritdoc />
public override async Task<ListResponse<ApiKeyModel>> ExecuteAsync(CancellationToken ct)
{
var entities = await store.ListAsync(ct);
var models = entities.Select(x => x.ToModel()).ToList();
return new ListResponse<ApiKeyModel>(models);
}
}

View file

@ -1,60 +0,0 @@
using Elsa.Abstractions;
using Elsa.Agents.Persistence.Contracts;
using Elsa.Agents.Persistence.Entities;
using Elsa.Agents.Persistence.Filters;
using JetBrains.Annotations;
namespace Elsa.Agents.Api.Endpoints.ApiKeys.Update;
/// <summary>
/// Lists all registered API keys.
/// </summary>
[UsedImplicitly]
public class Endpoint(IApiKeyStore store) : ElsaEndpoint<ApiKeyModel, ApiKeyDefinition>
{
/// <inheritdoc />
public override void Configure()
{
Post("/ai/api-keys/{id}");
ConfigurePermissions("ai/api-keys:write");
}
/// <inheritdoc />
public override async Task<ApiKeyDefinition> ExecuteAsync(ApiKeyModel req, CancellationToken ct)
{
var entity = await store.GetAsync(req.Id, ct);
if(entity == null)
{
await SendNotFoundAsync(ct);
return null!;
}
var isNameDuplicate = await IsNameDuplicateAsync(req.Name, req.Id, ct);
if (isNameDuplicate)
{
AddError("Another API key already exists with the specified name");
await SendErrorsAsync(cancellation: ct);
return entity;
}
entity.Name = req.Name.Trim();
entity.Value = req.Value.Trim();
await store.UpdateAsync(entity, ct);
return entity;
}
private async Task<bool> IsNameDuplicateAsync(string name, string id, CancellationToken cancellationToken)
{
var filter = new ApiKeyDefinitionFilter
{
Name = name,
NotId = id
};
var entity = await store.FindAsync(filter, cancellationToken);
return entity != null;
}
}

View file

@ -1,27 +0,0 @@
using Elsa.Abstractions;
using Elsa.Models;
using JetBrains.Annotations;
namespace Elsa.Agents.Api.Endpoints.Plugins.List;
/// <summary>
/// Lists all registered plugins.
/// </summary>
[UsedImplicitly]
public class Endpoint(IPluginDiscoverer pluginDiscoverer) : ElsaEndpointWithoutRequest<ListResponse<PluginDescriptorModel>>
{
/// <inheritdoc />
public override void Configure()
{
Get("/ai/plugins");
ConfigurePermissions("ai/plugins:read");
}
/// <inheritdoc />
public override Task<ListResponse<PluginDescriptorModel>> ExecuteAsync(CancellationToken ct)
{
var descriptors = pluginDiscoverer.GetPluginDescriptors();
var models = descriptors.Select(x => x.ToModel()).ToList();
return Task.FromResult(new ListResponse<PluginDescriptorModel>(models));
}
}

View file

@ -1,32 +0,0 @@
using Elsa.Abstractions;
using Elsa.Agents.Persistence.Contracts;
using Elsa.Agents.Persistence.Filters;
using JetBrains.Annotations;
namespace Elsa.Agents.Api.Endpoints.Services.BulkDelete;
/// <summary>
/// Deletes an API key.
/// </summary>
[UsedImplicitly]
public class Endpoint(IServiceStore store) : ElsaEndpoint<BulkDeleteRequest, BulkDeleteResponse>
{
/// <inheritdoc />
public override void Configure()
{
Post("/ai/bulk-actions/services/delete");
ConfigurePermissions("ai/api-keys:delete");
}
/// <inheritdoc />
public override async Task<BulkDeleteResponse> ExecuteAsync(BulkDeleteRequest req, CancellationToken ct)
{
var ids = req.Ids;
var filter = new ServiceDefinitionFilter
{
Ids = ids
};
var count = await store.DeleteManyAsync(filter, ct);
return new BulkDeleteResponse(count);
}
}

View file

@ -1,50 +0,0 @@
using Elsa.Abstractions;
using Elsa.Agents.Persistence.Contracts;
using Elsa.Agents.Persistence.Entities;
using Elsa.Agents.Persistence.Filters;
using Elsa.Workflows;
using JetBrains.Annotations;
namespace Elsa.Agents.Api.Endpoints.Services.Create;
/// <summary>
/// Lists all registered API keys.
/// </summary>
[UsedImplicitly]
public class Endpoint(IServiceStore store, IIdentityGenerator identityGenerator) : ElsaEndpoint<ServiceInputModel, ServiceModel>
{
/// <inheritdoc />
public override void Configure()
{
Post("/ai/services");
ConfigurePermissions("ai/services:write");
}
/// <inheritdoc />
public override async Task<ServiceModel> ExecuteAsync(ServiceInputModel req, CancellationToken ct)
{
var existingEntityFilter = new ServiceDefinitionFilter
{
Name = req.Name
};
var existingEntity = await store.FindAsync(existingEntityFilter, ct);
if (existingEntity != null)
{
AddError("A Service already exists with the specified name");
await SendErrorsAsync(cancellation: ct);
return existingEntity.ToModel();
}
var newEntity = new ServiceDefinition
{
Id = identityGenerator.GenerateId(),
Name = req.Name.Trim(),
Type = req.Type,
Settings = req.Settings
};
await store.AddAsync(newEntity, ct);
return newEntity.ToModel();
}
}

View file

@ -1,33 +0,0 @@
using Elsa.Abstractions;
using Elsa.Agents.Persistence.Contracts;
using JetBrains.Annotations;
namespace Elsa.Agents.Api.Endpoints.Services.Delete;
/// <summary>
/// Delete an API key.
/// </summary>
[UsedImplicitly]
public class Endpoint(IServiceStore store) : ElsaEndpoint<Request>
{
/// <inheritdoc />
public override void Configure()
{
Delete("/ai/services/{id}");
ConfigurePermissions("ai/services:delete");
}
/// <inheritdoc />
public override async Task HandleAsync(Request req, CancellationToken ct)
{
var entity = await store.GetAsync(req.Id, ct);
if(entity == null)
{
await SendNotFoundAsync(ct);
return;
}
await store.DeleteAsync(entity, ct);
}
}

View file

@ -1,8 +0,0 @@
using System.ComponentModel.DataAnnotations;
namespace Elsa.Agents.Api.Endpoints.Services.Delete;
public class Request
{
[Required] public string Id { get; set; } = default!;
}

View file

@ -1,33 +0,0 @@
using Elsa.Abstractions;
using Elsa.Agents.Persistence.Contracts;
using JetBrains.Annotations;
namespace Elsa.Agents.Api.Endpoints.Services.Get;
/// <summary>
/// Lists all registered API keys.
/// </summary>
[UsedImplicitly]
public class Endpoint(IServiceStore store) : ElsaEndpoint<Request, ServiceModel>
{
/// <inheritdoc />
public override void Configure()
{
Get("/ai/services/{id}");
ConfigurePermissions("ai/services:read");
}
/// <inheritdoc />
public override async Task<ServiceModel> ExecuteAsync(Request req, CancellationToken ct)
{
var entity = await store.GetAsync(req.Id, ct);
if(entity == null)
{
await SendNotFoundAsync(ct);
return null!;
}
return entity.ToModel();
}
}

View file

@ -1,8 +0,0 @@
using System.ComponentModel.DataAnnotations;
namespace Elsa.Agents.Api.Endpoints.Services.Get;
public class Request
{
[Required] public string Id { get; set; } = default!;
}

View file

@ -1,28 +0,0 @@
using Elsa.Abstractions;
using Elsa.Agents.Persistence.Contracts;
using Elsa.Models;
using JetBrains.Annotations;
namespace Elsa.Agents.Api.Endpoints.Services.List;
/// <summary>
/// Lists all registered API keys.
/// </summary>
[UsedImplicitly]
public class Endpoint(IServiceStore store) : ElsaEndpointWithoutRequest<ListResponse<ServiceModel>>
{
/// <inheritdoc />
public override void Configure()
{
Get("/ai/services");
ConfigurePermissions("ai/services:read");
}
/// <inheritdoc />
public override async Task<ListResponse<ServiceModel>> ExecuteAsync(CancellationToken ct)
{
var entities = await store.ListAsync(ct);
var models = entities.Select(x => x.ToModel()).ToList();
return new ListResponse<ServiceModel>(models);
}
}

View file

@ -1,60 +0,0 @@
using Elsa.Abstractions;
using Elsa.Agents.Persistence.Contracts;
using Elsa.Agents.Persistence.Filters;
using JetBrains.Annotations;
namespace Elsa.Agents.Api.Endpoints.Services.Update;
/// <summary>
/// Lists all registered API keys.
/// </summary>
[UsedImplicitly]
public class Endpoint(IServiceStore store) : ElsaEndpoint<ServiceModel, ServiceModel>
{
/// <inheritdoc />
public override void Configure()
{
Post("/ai/services/{id}");
ConfigurePermissions("ai/services:write");
}
/// <inheritdoc />
public override async Task<ServiceModel> ExecuteAsync(ServiceModel req, CancellationToken ct)
{
var entity = await store.GetAsync(req.Id, ct);
if(entity == null)
{
await SendNotFoundAsync(ct);
return null!;
}
var isNameDuplicate = await IsNameDuplicateAsync(req.Name, req.Id, ct);
if (isNameDuplicate)
{
AddError("Another service already exists with the specified name");
await SendErrorsAsync(cancellation: ct);
return entity.ToModel();
}
entity.Name = req.Name.Trim();
entity.Type = req.Type.Trim();
entity.Settings = req.Settings;
await store.UpdateAsync(entity, ct);
return entity.ToModel();
}
private async Task<bool> IsNameDuplicateAsync(string name, string id, CancellationToken cancellationToken)
{
var filter = new ServiceDefinitionFilter
{
Name = name,
NotId = id
};
var entity = await store.FindAsync(filter, cancellationToken);
return entity != null;
}
}

View file

@ -1,26 +0,0 @@
using Elsa.Agents;
using Elsa.Agents.Persistence.Entities;
// ReSharper disable once CheckNamespace
namespace Elsa.Extensions;
public static class AgentDefinitionExtensions
{
public static AgentModel ToModel(this AgentDefinition agentDefinition)
{
return new AgentModel
{
Id = agentDefinition.Id,
Name = agentDefinition.Name,
Description = agentDefinition.Description,
Agents = agentDefinition.AgentConfig.Agents,
ExecutionSettings = agentDefinition.AgentConfig.ExecutionSettings,
InputVariables = agentDefinition.AgentConfig.InputVariables,
OutputVariable = agentDefinition.AgentConfig.OutputVariable,
Services = agentDefinition.AgentConfig.Services,
Plugins = agentDefinition.AgentConfig.Plugins,
FunctionName = agentDefinition.AgentConfig.FunctionName,
PromptTemplate = agentDefinition.AgentConfig.PromptTemplate
};
}
}

View file

@ -1,19 +0,0 @@
using Elsa.Agents.Api.Features;
using Elsa.Features.Services;
// ReSharper disable once CheckNamespace
namespace Elsa.Extensions;
/// <summary>
/// Extends <see cref="IModule"/> with methods to install Semantic Kernel API endpoints.
/// </summary>
public static class ModuleExtensions
{
/// <summary>
/// Installs the Semantic Kernel API feature.
/// </summary>
public static IModule UseAgentsApi(this IModule module, Action<AgentsApiFeature>? configure = null)
{
return module.Use(configure);
}
}

View file

@ -1,22 +0,0 @@
using Elsa.Agents.Persistence.Features;
using Elsa.Extensions;
using Elsa.Features.Abstractions;
using Elsa.Features.Attributes;
using Elsa.Features.Services;
using JetBrains.Annotations;
namespace Elsa.Agents.Api.Features;
/// <summary>
/// A feature that installs API endpoints to interact with skilled agents.
/// </summary>
[DependsOn(typeof(AgentPersistenceFeature))]
[UsedImplicitly]
public class AgentsApiFeature(IModule module) : FeatureBase(module)
{
/// <inheritdoc />
public override void Configure()
{
Module.AddFastEndpointsAssembly<AgentsApiFeature>();
}
}

View file

@ -1,3 +0,0 @@
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
<ConfigureAwait />
</Weavers>

View file

@ -1,6 +0,0 @@
namespace Elsa.Agents;
public abstract class PluginProvider : IPluginProvider
{
public virtual IEnumerable<PluginDescriptor> GetPlugins() => [];
}

View file

@ -1,7 +0,0 @@
namespace Elsa.Agents;
public interface IAgentServiceProvider
{
string Name { get; }
void ConfigureKernel(KernelBuilderContext context);
}

View file

@ -1,6 +0,0 @@
namespace Elsa.Agents;
public interface IKernelConfigProvider
{
Task<KernelConfig> GetKernelConfigAsync(CancellationToken cancellationToken = default);
}

View file

@ -1,6 +0,0 @@
namespace Elsa.Agents;
public interface IPluginDiscoverer
{
IEnumerable<PluginDescriptor> GetPluginDescriptors();
}

View file

@ -1,9 +0,0 @@
namespace Elsa.Agents;
/// <summary>
/// Implementations of this interface are responsible for providing plugins.
/// </summary>
public interface IPluginProvider
{
IEnumerable<PluginDescriptor> GetPlugins();
}

View file

@ -1,6 +0,0 @@
namespace Elsa.Agents;
public interface IServiceDiscoverer
{
IEnumerable<IAgentServiceProvider> Discover();
}

View file

@ -1,21 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Description>Provides an agentic framework using Semantic Kernel</Description>
<PackageTags>elsa module agents semantic kernel llm ai</PackageTags>
<RootNamespace>Elsa.Agents</RootNamespace>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" />
<PackageReference Include="Microsoft.Extensions.Logging"/>
<PackageReference Include="Microsoft.Extensions.Logging.Console"/>
<PackageReference Include="Microsoft.SemanticKernel"/>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Elsa.Agents.Models\Elsa.Agents.Models.csproj" />
<ProjectReference Include="..\Elsa.Common\Elsa.Common.csproj" />
</ItemGroup>
</Project>

View file

@ -1,9 +0,0 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=abstractions/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=contracts/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=entities/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=extensions/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=models/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=options/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=serviceproviders/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=services/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>

View file

@ -1,49 +0,0 @@
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Connectors.OpenAI;
#pragma warning disable SKEXP0001
#pragma warning disable SKEXP0010
namespace Elsa.Agents;
public static class AgentConfigExtensions
{
public static OpenAIPromptExecutionSettings ToOpenAIPromptExecutionSettings(this AgentConfig agentConfig)
{
return new OpenAIPromptExecutionSettings
{
Temperature = agentConfig.ExecutionSettings.Temperature,
TopP = agentConfig.ExecutionSettings.TopP,
MaxTokens = agentConfig.ExecutionSettings.MaxTokens,
PresencePenalty = agentConfig.ExecutionSettings.PresencePenalty,
FrequencyPenalty = agentConfig.ExecutionSettings.FrequencyPenalty,
ToolCallBehavior = ToolCallBehavior.AutoInvokeKernelFunctions,
ResponseFormat = agentConfig.ExecutionSettings.ResponseFormat,
ChatSystemPrompt = agentConfig.PromptTemplate,
};
}
public static PromptTemplateConfig ToPromptTemplateConfig(this AgentConfig agentConfig)
{
var promptExecutionSettingsDictionary = new Dictionary<string, PromptExecutionSettings>
{
[PromptExecutionSettings.DefaultServiceId] = agentConfig.ToOpenAIPromptExecutionSettings(),
};
return new PromptTemplateConfig
{
Name = agentConfig.FunctionName,
Description = agentConfig.Description,
Template = agentConfig.PromptTemplate,
ExecutionSettings = promptExecutionSettingsDictionary,
AllowDangerouslySetContent = true,
InputVariables = agentConfig.InputVariables.Select(x => new InputVariable
{
Name = x.Name,
Description = x.Description,
IsRequired = true,
AllowDangerouslySetContent = true
}).ToList()
};
}
}

View file

@ -1,25 +0,0 @@
using System.Text.Json;
using Microsoft.SemanticKernel;
namespace Elsa.Agents;
public static class FunctionResultExtensions
{
public static async Task<JsonElement> AsJsonElementAsync(this Task<InvokeAgentResult> resultTask)
{
var result = await resultTask;
return result.FunctionResult.AsJsonElement();
}
public static async Task<JsonElement> AsJsonElementAsync(this Task<FunctionResult> resultTask)
{
var result = await resultTask;
return result.AsJsonElement();
}
public static JsonElement AsJsonElement(this FunctionResult result)
{
var response = result.GetValue<string>()!;
return JsonSerializer.Deserialize<JsonElement>(response);
}
}

View file

@ -1,19 +0,0 @@
using Elsa.Agents.Features;
using Elsa.Features.Services;
// ReSharper disable once CheckNamespace
namespace Elsa.Extensions;
/// <summary>
/// Extends <see cref="IModule"/> with methods to install Semantic Kernel API endpoints.
/// </summary>
public static class ModuleExtensions
{
/// <summary>
/// Installs the Semantic Kernel API feature.
/// </summary>
public static IModule UseAgents(this IModule module, Action<AgentsFeature>? configure = null)
{
return module.Use(configure);
}
}

View file

@ -1,16 +0,0 @@
using Microsoft.Extensions.DependencyInjection;
namespace Elsa.Agents;
public static class ServiceCollectionExtensions
{
public static IServiceCollection AddPluginProvider<T>(this IServiceCollection services) where T: class, IPluginProvider
{
return services.AddScoped<IPluginProvider, T>();
}
public static IServiceCollection AddAgentServiceProvider<T>(this IServiceCollection services) where T: class, IAgentServiceProvider
{
return services.AddScoped<IAgentServiceProvider, T>();
}
}

View file

@ -1,40 +0,0 @@
using Elsa.Agents.Plugins;
using Elsa.Features.Abstractions;
using Elsa.Features.Services;
using JetBrains.Annotations;
using Microsoft.Extensions.DependencyInjection;
namespace Elsa.Agents.Features;
/// <summary>
/// A feature that installs API endpoints to interact with skilled agents.
/// </summary>
[UsedImplicitly]
public class AgentsFeature(IModule module) : FeatureBase(module)
{
private Func<IServiceProvider, IKernelConfigProvider> _kernelConfigProviderFactory = sp => sp.GetRequiredService<ConfigurationKernelConfigProvider>();
public AgentsFeature UseKernelConfigProvider(Func<IServiceProvider, IKernelConfigProvider> factory)
{
_kernelConfigProviderFactory = factory;
return this;
}
/// <inheritdoc />
public override void Apply()
{
Services.AddOptions<AgentsOptions>();
Services
.AddScoped<KernelFactory>()
.AddScoped<AgentInvoker>()
.AddScoped<IPluginDiscoverer, PluginDiscoverer>()
.AddScoped<IServiceDiscoverer, ServiceDiscoverer>()
.AddScoped(_kernelConfigProviderFactory)
.AddScoped<ConfigurationKernelConfigProvider>()
.AddPluginProvider<ImageGeneratorPluginProvider>()
.AddAgentServiceProvider<OpenAIChatCompletionProvider>()
.AddAgentServiceProvider<OpenAITextToImageProvider>()
;
}
}

View file

@ -1,3 +0,0 @@
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
<ConfigureAwait />
</Weavers>

View file

@ -1,14 +0,0 @@
using System.Text.Json;
using Microsoft.SemanticKernel;
namespace Elsa.Agents;
public record InvokeAgentResult(AgentConfig Function, FunctionResult FunctionResult)
{
public object? ParseResult()
{
var targetType = Type.GetType(Function.OutputVariable.Type) ?? typeof(JsonElement);
var json = FunctionResult.GetValue<string>();
return JsonSerializer.Deserialize(json, targetType);
}
}

View file

@ -1,20 +0,0 @@
using JetBrains.Annotations;
using Microsoft.SemanticKernel;
namespace Elsa.Agents;
[UsedImplicitly]
public record KernelBuilderContext(IKernelBuilder KernelBuilder, KernelConfig KernelConfig, ServiceConfig ServiceConfig)
{
public string GetApiKey()
{
var settings = ServiceConfig.Settings;
if (settings.TryGetValue("ApiKey", out var apiKey))
return (string)apiKey;
if (settings.TryGetValue("ApiKeyRef", out var apiKeyRef))
return KernelConfig.ApiKeys[(string)apiKeyRef].Value;
throw new KeyNotFoundException($"No api key found for service {ServiceConfig.Type}");
}
}

View file

@ -1,33 +0,0 @@
using System.ComponentModel;
using System.Reflection;
namespace Elsa.Agents;
/// <summary>
/// A descriptor for a plugin.
/// </summary>
public class PluginDescriptor
{
public string Name { get; set; }
public string Description { get; set; }
public Type PluginType { get; set; }
public PluginDescriptorModel ToModel() => new()
{
Name = Name,
Description = Description,
PluginType = PluginType.AssemblyQualifiedName!
};
public static PluginDescriptor From<TPlugin>(string? name = null)
{
var pluginType = typeof(TPlugin);
var description = pluginType.GetCustomAttribute<DescriptionAttribute>()?.Description ?? string.Empty;
return new PluginDescriptor
{
Name = name ?? pluginType.Name.Replace("Plugin", ""),
Description = description,
PluginType = pluginType
};
}
}

View file

@ -1,8 +0,0 @@
namespace Elsa.Agents;
public class AgentsOptions
{
public ICollection<ApiKeyConfig> ApiKeys { get; set; }
public ICollection<ServiceConfig> Services { get; set; }
public ICollection<AgentConfig> Agents { get; set; }
}

View file

@ -1,39 +0,0 @@
using System.ComponentModel;
using JetBrains.Annotations;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.TextToImage;
#pragma warning disable SKEXP0001
namespace Elsa.Agents.Plugins;
[Description("Generates an image from text")]
[UsedImplicitly]
public class ImageGeneratorPlugin
{
[KernelFunction("generate_image_from_text")]
[Description("Generates an image from text")]
[return: Description("The URL to the generated image")]
public async Task<string> GenerateImage(
Kernel kernel,
[Description("The text to generate an image from")]
string description,
[Description("The width of the image to generate. When not specified, a default size will be used.")]
int width = 1024,
[Description("The height of the image to generate. When not specified, a default size will be used.")]
int height = 1024)
{
var dallE = kernel.GetRequiredService<ITextToImageService>();
var imageUrl = await dallE.GenerateImageAsync(description.Trim(), width, height);
return imageUrl;
}
}
[UsedImplicitly]
public class ImageGeneratorPluginProvider : PluginProvider
{
public override IEnumerable<PluginDescriptor> GetPlugins()
{
yield return PluginDescriptor.From<ImageGeneratorPlugin>();
}
}

View file

@ -1,14 +0,0 @@
using Microsoft.SemanticKernel;
namespace Elsa.Agents;
public class OpenAIChatCompletionProvider : IAgentServiceProvider
{
public string Name => "OpenAIChatCompletion";
public void ConfigureKernel(KernelBuilderContext context)
{
var modelId = (string)context.ServiceConfig.Settings["ModelId"];
var apiKey = context.GetApiKey();
context.KernelBuilder.AddOpenAIChatCompletion(modelId, apiKey);
}
}

View file

@ -1,16 +0,0 @@
using Microsoft.SemanticKernel;
#pragma warning disable SKEXP0010
namespace Elsa.Agents;
public class OpenAITextToImageProvider : IAgentServiceProvider
{
public string Name => "OpenAITextToImage";
public void ConfigureKernel(KernelBuilderContext context)
{
var modelId = (string)context.ServiceConfig.Settings["ModelId"];
var apiKey = context.GetApiKey();
context.KernelBuilder.AddOpenAITextToImage(apiKey, modelId: modelId);
}
}

View file

@ -1,55 +0,0 @@
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Connectors.OpenAI;
#pragma warning disable SKEXP0010
#pragma warning disable SKEXP0001
namespace Elsa.Agents;
public class AgentInvoker(KernelFactory kernelFactory, IKernelConfigProvider kernelConfigProvider)
{
public async Task<InvokeAgentResult> InvokeAgentAsync(string agentName, IDictionary<string, object?> input, CancellationToken cancellationToken = default)
{
var kernelConfig = await kernelConfigProvider.GetKernelConfigAsync(cancellationToken);
var kernel = kernelFactory.CreateKernel(kernelConfig, agentName);
var agentConfig = kernelConfig.Agents[agentName];
var executionSettings = agentConfig.ExecutionSettings;
var promptExecutionSettings = new OpenAIPromptExecutionSettings
{
Temperature = executionSettings.Temperature,
TopP = executionSettings.TopP,
MaxTokens = executionSettings.MaxTokens,
PresencePenalty = executionSettings.PresencePenalty,
FrequencyPenalty = executionSettings.FrequencyPenalty,
ToolCallBehavior = ToolCallBehavior.AutoInvokeKernelFunctions,
ResponseFormat = executionSettings.ResponseFormat,
ChatSystemPrompt = agentConfig.PromptTemplate,
};
var promptExecutionSettingsDictionary = new Dictionary<string, PromptExecutionSettings>
{
[PromptExecutionSettings.DefaultServiceId] = promptExecutionSettings,
};
var promptTemplateConfig = new PromptTemplateConfig
{
Name = agentConfig.FunctionName,
Description = agentConfig.Description,
Template = agentConfig.PromptTemplate,
ExecutionSettings = promptExecutionSettingsDictionary,
AllowDangerouslySetContent = true,
InputVariables = agentConfig.InputVariables.Select(x => new InputVariable
{
Name = x.Name,
Description = x.Description,
IsRequired = true,
AllowDangerouslySetContent = true
}).ToList()
};
var kernelFunction = kernel.CreateFunctionFromPrompt(promptTemplateConfig);
var kernelArguments = new KernelArguments(input);
var result = await kernelFunction.InvokeAsync(kernel, kernelArguments, cancellationToken: cancellationToken);
return new(agentConfig, result);
}
}

View file

@ -1,17 +0,0 @@
using JetBrains.Annotations;
using Microsoft.Extensions.Options;
namespace Elsa.Agents;
[UsedImplicitly]
public class ConfigurationKernelConfigProvider(IOptions<AgentsOptions> options) : IKernelConfigProvider
{
public Task<KernelConfig> GetKernelConfigAsync(CancellationToken cancellationToken = default)
{
var kernelConfig = new KernelConfig();
foreach (var apiKey in options.Value.ApiKeys) kernelConfig.ApiKeys[apiKey.Name] = apiKey;
foreach (var service in options.Value.Services) kernelConfig.Services[service.Name] = service;
foreach (var agent in options.Value.Agents) kernelConfig.Agents[agent.Name] = agent;
return Task.FromResult(kernelConfig);
}
}

View file

@ -1,113 +0,0 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.SemanticKernel;
#pragma warning disable SKEXP0001
#pragma warning disable SKEXP0010
namespace Elsa.Agents;
public class KernelFactory(IPluginDiscoverer pluginDiscoverer, IServiceDiscoverer serviceDiscoverer, ILoggerFactory loggerFactory, IServiceProvider serviceProvider, ILogger<KernelFactory> logger)
{
public Kernel CreateKernel(KernelConfig kernelConfig, string agentName)
{
var agent = kernelConfig.Agents[agentName];
return CreateKernel(kernelConfig, agent);
}
public Kernel CreateKernel(KernelConfig kernelConfig, AgentConfig agentConfig)
{
var builder = Kernel.CreateBuilder();
builder.Services.AddLogging(services => services.AddConsole().SetMinimumLevel(LogLevel.Trace));
builder.Services.AddSingleton(agentConfig);
ApplyAgentConfig(builder, kernelConfig, agentConfig);
return builder.Build();
}
private void ApplyAgentConfig(IKernelBuilder builder, KernelConfig kernelConfig, AgentConfig agentConfig)
{
var services = serviceDiscoverer.Discover().ToDictionary(x => x.Name);
foreach (string serviceName in agentConfig.Services)
{
if (!kernelConfig.Services.TryGetValue(serviceName, out var serviceConfig))
{
logger.LogWarning($"Service {serviceName} not found");
continue;
}
AddService(builder, kernelConfig, serviceConfig, services);
}
AddPlugins(builder, agentConfig);
AddAgents(builder, kernelConfig, agentConfig);
}
private void AddService(IKernelBuilder builder, KernelConfig kernelConfig, ServiceConfig serviceConfig, Dictionary<string, IAgentServiceProvider> services)
{
if (!services.TryGetValue(serviceConfig.Type, out var serviceProvider))
{
logger.LogWarning($"Service provider {serviceConfig.Type} not found");
return;
}
var context = new KernelBuilderContext(builder, kernelConfig, serviceConfig);
serviceProvider.ConfigureKernel(context);
}
private void AddPlugins(IKernelBuilder builder, AgentConfig agent)
{
var plugins = pluginDiscoverer.GetPluginDescriptors().ToDictionary(x => x.Name);
foreach (var pluginName in agent.Plugins)
{
if (!plugins.TryGetValue(pluginName, out var pluginDescriptor))
{
logger.LogWarning($"Plugin {pluginName} not found");
continue;
}
var pluginType = pluginDescriptor.PluginType;
var pluginInstance = ActivatorUtilities.GetServiceOrCreateInstance(serviceProvider, pluginType);
builder.Plugins.AddFromObject(pluginInstance, pluginName);
}
}
private void AddAgents(IKernelBuilder builder, KernelConfig kernelConfig, AgentConfig agent)
{
foreach (var agentName in agent.Agents)
{
if (!kernelConfig.Agents.TryGetValue(agentName, out var subAgent))
{
logger.LogWarning($"Agent {agentName} not found");
continue;
}
var promptExecutionSettings = subAgent.ToOpenAIPromptExecutionSettings();
var promptExecutionSettingsDictionary = new Dictionary<string, PromptExecutionSettings>
{
[PromptExecutionSettings.DefaultServiceId] = promptExecutionSettings,
};
var promptTemplateConfig = new PromptTemplateConfig
{
Name = subAgent.FunctionName,
Description = subAgent.Description,
Template = subAgent.PromptTemplate,
ExecutionSettings = promptExecutionSettingsDictionary,
AllowDangerouslySetContent = true,
InputVariables = subAgent.InputVariables.Select(x => new InputVariable
{
Name = x.Name,
Description = x.Description,
IsRequired = true,
AllowDangerouslySetContent = true
}).ToList()
};
var subAgentFunction = KernelFunctionFactory.CreateFromPrompt(promptTemplateConfig, loggerFactory: loggerFactory);
var agentPlugin = KernelPluginFactory.CreateFromFunctions(subAgent.Name, subAgent.Description, [subAgentFunction]);
builder.Plugins.Add(agentPlugin);
}
}
}

View file

@ -1,9 +0,0 @@
namespace Elsa.Agents;
public class PluginDiscoverer(IEnumerable<IPluginProvider> providers) : IPluginDiscoverer
{
public IEnumerable<PluginDescriptor> GetPluginDescriptors()
{
return providers.SelectMany(x => x.GetPlugins());
}
}

View file

@ -1,9 +0,0 @@
namespace Elsa.Agents;
public class ServiceDiscoverer(IEnumerable<IAgentServiceProvider> providers) : IServiceDiscoverer
{
public IEnumerable<IAgentServiceProvider> Discover()
{
return providers;
}
}

View file

@ -1,17 +0,0 @@
using System.ComponentModel.DataAnnotations;
namespace Elsa.Agents;
public class AgentInputModel
{
[Required] public string Name { get; set; } = "";
[Required] public string Description { get; set; } = "";
public ICollection<string> Services { get; set; } = [];
[Required] public string FunctionName { get; set; } = "";
[Required] public string PromptTemplate { get; set; } = "";
public ICollection<InputVariableConfig> InputVariables { get; set; } = [];
[Required] public OutputVariableConfig OutputVariable { get; set; } = new();
public ExecutionSettingsConfig ExecutionSettings { get; set; } = new();
public ICollection<string> Plugins { get; set; } = [];
public ICollection<string> Agents { get; set; } = [];
}

View file

@ -1,8 +0,0 @@
using System.ComponentModel.DataAnnotations;
namespace Elsa.Agents;
public class AgentModel : AgentInputModel
{
[Required] public string Id { get; set; } = default!;
}

View file

@ -1,9 +0,0 @@
using System.ComponentModel.DataAnnotations;
namespace Elsa.Agents;
public class ApiKeyInputModel
{
[Required] public string Name { get; set; } = default!;
[Required] public string Value { get; set; } = default!;
}

View file

@ -1,8 +0,0 @@
using System.ComponentModel.DataAnnotations;
namespace Elsa.Agents;
public class ApiKeyModel : ApiKeyInputModel
{
[Required] public string Id { get; set; } = default!;
}

View file

@ -1,8 +0,0 @@
using System.ComponentModel.DataAnnotations;
namespace Elsa.Agents;
public class BulkDeleteRequest
{
[Required] public ICollection<string> Ids { get; set; } = default!;
}

View file

@ -1,3 +0,0 @@
namespace Elsa.Agents;
public record BulkDeleteResponse(long DeletedCount);

View file

@ -1,17 +0,0 @@
namespace Elsa.Agents;
public class AgentConfig
{
public string Name { get; set; } = "";
public string Description { get; set; } = "";
public ICollection<string> Services { get; set; } = [];
public string FunctionName { get; set; } = default!;
public string PromptTemplate { get; set; } = default!;
public ICollection<InputVariableConfig> InputVariables { get; set; } = [];
public OutputVariableConfig OutputVariable { get; set; } = new();
public ExecutionSettingsConfig ExecutionSettings { get; set; } = new();
public ICollection<string> Plugins { get; set; } = [];
public ICollection<string> Agents { get; set; } = [];
}

View file

@ -1,10 +0,0 @@
using JetBrains.Annotations;
namespace Elsa.Agents;
[UsedImplicitly]
public class ApiKeyConfig
{
public string Name { get; set; }
public string Value { get; set; }
}

View file

@ -1,13 +0,0 @@
#pragma warning disable SKEXP0010
namespace Elsa.Agents;
public class ExecutionSettingsConfig
{
public int? MaxTokens { get; set; }
public double Temperature { get; set; }
public double TopP { get; set; }
public double PresencePenalty { get; set; }
public double FrequencyPenalty { get; set; }
public string? ResponseFormat { get; set; }
}

View file

@ -1,7 +0,0 @@
namespace Elsa.Agents;
public class FunctionConfig
{
}

View file

@ -1,8 +0,0 @@
namespace Elsa.Agents;
public class InputVariableConfig
{
public string Name { get; set; } = "";
public string Description { get; set; } = "";
public string Type { get; set; } = "";
}

View file

@ -1,8 +0,0 @@
namespace Elsa.Agents;
public class KernelConfig
{
public IDictionary<string, ApiKeyConfig> ApiKeys { get; set; } = new Dictionary<string, ApiKeyConfig>();
public IDictionary<string, ServiceConfig> Services { get; } = new Dictionary<string, ServiceConfig>();
public IDictionary<string, AgentConfig> Agents { get; } = new Dictionary<string, AgentConfig>();
}

View file

@ -1,7 +0,0 @@
namespace Elsa.Agents;
public class OutputVariableConfig
{
public string Description { get; set; } = "";
public string Type { get; set; } = "";
}

View file

@ -1,8 +0,0 @@
namespace Elsa.Agents;
public class ServiceConfig
{
public string Name { get; set; }
public string Type { get; set; }
public IDictionary<string, object> Settings { get; set; } = new Dictionary<string, object>();
}

View file

@ -1,9 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Description>Provides models that can be shared between the API and API clients</Description>
<PackageTags>elsa module agents semantic kernel llm ai api</PackageTags>
<RootNamespace>Elsa.Agents</RootNamespace>
</PropertyGroup>
</Project>

View file

@ -1,8 +0,0 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=agents/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=apikeys/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=bulkactions/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=configs/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=plugins/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=services/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=uniquename/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>

View file

@ -1,3 +0,0 @@
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
<ConfigureAwait />
</Weavers>

View file

@ -1,11 +0,0 @@
namespace Elsa.Agents;
/// <summary>
/// A descriptor for a plugin.
/// </summary>
public class PluginDescriptorModel
{
public string Name { get; set; }
public string Description { get; set; }
public string PluginType { get; set; }
}

View file

@ -1,10 +0,0 @@
using System.ComponentModel.DataAnnotations;
namespace Elsa.Agents;
public class ServiceInputModel
{
[Required] public string Name { get; set; } = default!;
[Required] public string Type { get; set; } = default!;
public IDictionary<string, object> Settings { get; set; } = new Dictionary<string, object>();
}

View file

@ -1,8 +0,0 @@
using System.ComponentModel.DataAnnotations;
namespace Elsa.Agents;
public class ServiceModel : ServiceInputModel
{
[Required] public string Id { get; set; } = default!;
}

View file

@ -1,3 +0,0 @@
namespace Elsa.Agents;
public record GenerateUniqueNameResponse(string Name);

View file

@ -1,11 +0,0 @@
using System.ComponentModel.DataAnnotations;
using JetBrains.Annotations;
namespace Elsa.Agents;
[UsedImplicitly]
public class IsUniqueNameRequest
{
[Required] public string Name { get; set; } = default!;
public string? Id { get; set; }
}

View file

@ -1,5 +0,0 @@
using JetBrains.Annotations;
namespace Elsa.Agents;
[UsedImplicitly] public record IsUniqueNameResponse(bool IsUnique);

View file

@ -1,22 +0,0 @@
using System.Reflection;
using Elsa.Agents.Persistence.EntityFrameworkCore;
// ReSharper disable once CheckNamespace
namespace Elsa.EntityFrameworkCore.Extensions;
/// <summary>
/// Provides extensions to configure EF Core to use MySQL.
/// </summary>
public static class AgentsMySqlProvidersExtensions
{
private static Assembly Assembly => typeof(AgentsMySqlProvidersExtensions).Assembly;
/// <summary>
/// Configures the feature to use MySQL.
/// </summary>
public static EFCoreAgentPersistenceFeature UseMySql(this EFCoreAgentPersistenceFeature feature, string connectionString, ElsaDbContextOptions? options = null)
{
feature.UseMySql(Assembly, connectionString, options);
return feature;
}
}

Some files were not shown because too many files have changed in this diff Show more