-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add support for agent service providers and discovery
Introduce interfaces and implementations for agent service providers and service discovery. Updated `KernelFactory` to integrate the new service discovery mechanism and restructured plugin discoverer naming for consistency.
- Loading branch information
1 parent
7e4ddab
commit 81cbe2f
Showing
14 changed files
with
176 additions
and
40 deletions.
There are no files selected for viewing
7 changes: 7 additions & 0 deletions
7
src/modules/Elsa.Agents.Core/Contracts/IAgentServiceProvider.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
namespace Elsa.Agents; | ||
|
||
public interface IAgentServiceProvider | ||
{ | ||
string Name { get; } | ||
void ConfigureKernel(KernelBuilderContext context); | ||
} |
2 changes: 1 addition & 1 deletion
2
...ents.Core/Contracts/IPluginsDiscoverer.cs → ...gents.Core/Contracts/IPluginDiscoverer.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
namespace Elsa.Agents; | ||
|
||
public interface IPluginsDiscoverer | ||
public interface IPluginDiscoverer | ||
{ | ||
IEnumerable<PluginDescriptor> GetPluginDescriptors(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
namespace Elsa.Agents; | ||
|
||
public interface IServiceDiscoverer | ||
{ | ||
IEnumerable<IAgentServiceProvider> Discover(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
20 changes: 20 additions & 0 deletions
20
src/modules/Elsa.Agents.Core/Models/KernelBuilderContext.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
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}"); | ||
} | ||
} |
14 changes: 14 additions & 0 deletions
14
src/modules/Elsa.Agents.Core/ServiceProviders/OpenAIChatCompletionProvider.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
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); | ||
} | ||
} |
16 changes: 16 additions & 0 deletions
16
src/modules/Elsa.Agents.Core/ServiceProviders/OpenAITextToImageProvider.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
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); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 1 addition & 1 deletion
2
...ules/Elsa.Agents.Core/Services/Plugins.cs → ....Agents.Core/Services/PluginDiscoverer.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
namespace Elsa.Agents; | ||
|
||
public class ServiceDiscoverer(IEnumerable<IAgentServiceProvider> providers) : IServiceDiscoverer | ||
{ | ||
public IEnumerable<IAgentServiceProvider> Discover() | ||
{ | ||
return providers; | ||
} | ||
} |
12 changes: 10 additions & 2 deletions
12
src/modules/Elsa.Agents.Persistence.EntityFrameworkCore/JsonValueConverterHelper.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,16 +1,24 @@ | ||
using System.Text.Json; | ||
using Elsa.Extensions; | ||
|
||
namespace Elsa.Agents.Persistence.EntityFrameworkCore; | ||
|
||
internal static class JsonValueConverterHelper | ||
{ | ||
private static readonly JsonSerializerOptions JsonSerializerOptions = CreateJsonSerializerOptions(); | ||
|
||
public static T Deserialize<T>(string json) where T : class | ||
{ | ||
return string.IsNullOrWhiteSpace(json) ? null : JsonSerializer.Deserialize<T>(json); | ||
return (string.IsNullOrWhiteSpace(json) ? null : JsonSerializer.Deserialize<T>(json, JsonSerializerOptions))!; | ||
} | ||
|
||
public static string Serialize<T>(T obj) where T : class | ||
{ | ||
return obj == null ? null : JsonSerializer.Serialize(obj); | ||
return (obj == null ? null : JsonSerializer.Serialize(obj, JsonSerializerOptions))!; | ||
} | ||
|
||
private static JsonSerializerOptions CreateJsonSerializerOptions() | ||
{ | ||
return new JsonSerializerOptions().WithConverters(new PrimitiveDictionaryConverter()); | ||
} | ||
} |
69 changes: 69 additions & 0 deletions
69
src/modules/Elsa.Agents.Persistence.EntityFrameworkCore/PrimitiveDictionaryConverter.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
using System.Text.Json; | ||
using System.Text.Json.Serialization; | ||
|
||
namespace Elsa.Agents.Persistence.EntityFrameworkCore; | ||
|
||
public class PrimitiveDictionaryConverter : JsonConverter<IDictionary<string, object>> | ||
{ | ||
public override IDictionary<string, object> Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) | ||
{ | ||
if (reader.TokenType != JsonTokenType.StartObject) | ||
throw new JsonException("Expected start of object."); | ||
|
||
var dictionary = new Dictionary<string, object>(); | ||
|
||
while (reader.Read()) | ||
{ | ||
if (reader.TokenType == JsonTokenType.EndObject) | ||
return dictionary; | ||
|
||
var key = reader.GetString()!; | ||
reader.Read(); | ||
var value = ReadValue(ref reader, options); | ||
dictionary.Add(key, value); | ||
} | ||
|
||
throw new JsonException("Expected end of object."); | ||
} | ||
|
||
private object ReadValue(ref Utf8JsonReader reader, JsonSerializerOptions options) | ||
{ | ||
switch (reader.TokenType) | ||
{ | ||
case JsonTokenType.String: | ||
return reader.GetString()!; | ||
case JsonTokenType.Number: | ||
if (reader.TryGetInt64(out var l)) | ||
return l; | ||
return reader.GetDouble(); | ||
case JsonTokenType.True: | ||
return true; | ||
case JsonTokenType.False: | ||
return false; | ||
case JsonTokenType.Null: | ||
return null!; | ||
case JsonTokenType.StartObject: | ||
return JsonSerializer.Deserialize<Dictionary<string, object>>(ref reader, options)!; | ||
case JsonTokenType.StartArray: | ||
return JsonSerializer.Deserialize<List<object>>(ref reader, options)!; | ||
default: | ||
using (var document = JsonDocument.ParseValue(ref reader)) | ||
{ | ||
return document.RootElement.Clone().ToString(); | ||
} | ||
} | ||
} | ||
|
||
public override void Write(Utf8JsonWriter writer, IDictionary<string, object> value, JsonSerializerOptions options) | ||
{ | ||
writer.WriteStartObject(); | ||
|
||
foreach (var kvp in value) | ||
{ | ||
writer.WritePropertyName(kvp.Key); | ||
JsonSerializer.Serialize(writer, kvp.Value, options); | ||
} | ||
|
||
writer.WriteEndObject(); | ||
} | ||
} |