Skip to content

Commit

Permalink
Enable bidirectional adapters between SK interfaces and Microsoft.Ext…
Browse files Browse the repository at this point in the history
…ensions.AI

This is part 1 of replatforming Semantic Kernel on top of Microsoft.Extensions.AI, making it possible to use IChatCompletionService instances as IChatClient instances, and vice versa, and similarly for IEmbeddingGenerationService and IEmbeddingGenerator. The next step after this is refactoring the connectors to use M.E.AI internally where relevant.
  • Loading branch information
stephentoub committed Oct 9, 2024
1 parent 4364ad1 commit 9d7c4fc
Show file tree
Hide file tree
Showing 8 changed files with 905 additions and 8 deletions.
12 changes: 7 additions & 5 deletions dotnet/Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
<PackageVersion Include="Microsoft.Azure.Kusto.Data" Version="12.2.6" />
<PackageVersion Include="Microsoft.Azure.WebJobs.Extensions.OpenApi" Version="1.5.1" />
<PackageVersion Include="Microsoft.Bcl.HashCode" Version="1.1.1" />
<PackageVersion Include="Microsoft.Bcl.AsyncInterfaces" Version="8.0.0" />
<PackageVersion Include="Microsoft.Bcl.AsyncInterfaces" Version="9.0.0-rc.2.24473.5" />
<PackageVersion Include="Microsoft.Bcl.Numerics" Version="8.0.0" />
<PackageVersion Include="Microsoft.CodeAnalysis.Common" Version="4.3.0" />
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="4.3.0" />
Expand All @@ -33,29 +33,31 @@
<PackageVersion Include="Microsoft.ML.OnnxRuntime" Version="1.19.2" />
<PackageVersion Include="FastBertTokenizer" Version="1.0.28" />
<PackageVersion Include="Pinecone.NET" Version="2.1.1" />
<PackageVersion Include="System.Diagnostics.DiagnosticSource" Version="8.0.1" />
<PackageVersion Include="System.Diagnostics.DiagnosticSource" Version="9.0.0-rc.2.24473.5" />
<PackageVersion Include="System.Linq.Async" Version="6.0.1" />
<PackageVersion Include="System.Memory.Data" Version="8.0.0" />
<PackageVersion Include="System.Numerics.Tensors" Version="8.0.0" />
<PackageVersion Include="System.Text.Json" Version="8.0.5" />
<PackageVersion Include="System.Text.Json" Version="9.0.0-rc.2.24473.5" />
<PackageVersion Include="OllamaSharp" Version="3.0.10" />
<!-- Tokenizers -->
<PackageVersion Include="Microsoft.ML.Tokenizers" Version="0.22.0-preview.24378.1" />
<PackageVersion Include="Microsoft.DeepDev.TokenizerLib" Version="1.3.3" />
<PackageVersion Include="SharpToken" Version="2.0.3" />
<!-- Microsoft.Extensions.* -->
<PackageVersion Include="Microsoft.Extensions.AI.Abstractions" Version="9.0.0-preview.9.24507.7" />
<PackageVersion Include="Microsoft.Extensions.AI" Version="9.0.0-preview.9.24507.7" />
<PackageVersion Include="Microsoft.Extensions.Configuration" Version="8.0.0" />
<PackageVersion Include="Microsoft.Extensions.Configuration.Binder" Version="8.0.2" />
<PackageVersion Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="8.0.0" />
<PackageVersion Include="Microsoft.Extensions.Configuration.Json" Version="8.0.0" />
<PackageVersion Include="Microsoft.Extensions.Configuration.UserSecrets" Version="8.0.0" />
<PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" />
<PackageVersion Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="8.0.1" />
<PackageVersion Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="9.0.0-rc.2.24473.5" />
<PackageVersion Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
<PackageVersion Include="Microsoft.Extensions.Http" Version="8.0.0" />
<PackageVersion Include="Microsoft.Extensions.Http.Resilience" Version="8.9.1" />
<PackageVersion Include="Microsoft.Extensions.Logging" Version="8.0.0" />
<PackageVersion Include="Microsoft.Extensions.Logging.Abstractions" Version="8.0.1" />
<PackageVersion Include="Microsoft.Extensions.Logging.Abstractions" Version="9.0.0-rc.2.24473.5" />
<PackageVersion Include="Microsoft.Extensions.Logging.Console" Version="8.0.0" />
<PackageVersion Include="Microsoft.Extensions.Options.DataAnnotations" Version="8.0.0" />
<PackageVersion Include="Microsoft.Extensions.TimeProvider.Testing" Version="8.9.1" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,16 @@ namespace Microsoft.SemanticKernel.Diagnostics;
[ExcludeFromCodeCoverage]
internal static class ModelDiagnostics
{
private static readonly string s_namespace = typeof(ModelDiagnostics).Namespace!;
internal static readonly string s_namespace = typeof(ModelDiagnostics).Namespace!;
private static readonly ActivitySource s_activitySource = new(s_namespace);

private const string EnableDiagnosticsSwitch = "Microsoft.SemanticKernel.Experimental.GenAI.EnableOTelDiagnostics";
private const string EnableSensitiveEventsSwitch = "Microsoft.SemanticKernel.Experimental.GenAI.EnableOTelDiagnosticsSensitive";
private const string EnableDiagnosticsEnvVar = "SEMANTICKERNEL_EXPERIMENTAL_GENAI_ENABLE_OTEL_DIAGNOSTICS";
private const string EnableSensitiveEventsEnvVar = "SEMANTICKERNEL_EXPERIMENTAL_GENAI_ENABLE_OTEL_DIAGNOSTICS_SENSITIVE";

private static readonly bool s_enableDiagnostics = AppContextSwitchHelper.GetConfigValue(EnableDiagnosticsSwitch, EnableDiagnosticsEnvVar);
private static readonly bool s_enableSensitiveEvents = AppContextSwitchHelper.GetConfigValue(EnableSensitiveEventsSwitch, EnableSensitiveEventsEnvVar);
internal static readonly bool s_enableDiagnostics = AppContextSwitchHelper.GetConfigValue(EnableDiagnosticsSwitch, EnableDiagnosticsEnvVar);
internal static readonly bool s_enableSensitiveEvents = AppContextSwitchHelper.GetConfigValue(EnableSensitiveEventsSwitch, EnableSensitiveEventsEnvVar);

/// <summary>
/// Start a text completion activity for a given model.
Expand Down
69 changes: 69 additions & 0 deletions dotnet/src/SemanticKernel.Abstractions/Functions/KernelFunction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,14 @@
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Diagnostics.Metrics;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.AI;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.SemanticKernel.Diagnostics;
Expand Down Expand Up @@ -441,4 +444,70 @@ private static void HandleException(
throw kernelEx;
}
}

/// <summary>Creates an <see cref="AIFunction"/> for this <see cref="KernelFunction"/>.</summary>
/// <param name="kernel">
/// The <see cref="Kernel"/> instance to pass to the <see cref="KernelFunction"/> when it's invoked as part of the <see cref="AIFunction"/>'s invocation.
/// </param>
/// <returns>An instance of <see cref="AIFunction"/> that, when invoked, will in turn invoke the current <see cref="KernelFunction"/>.</returns>
[Experimental("SKEXP0001")]
public AIFunction AsAIFunction(Kernel? kernel = null)
{
return new KernelAIFunction(this, kernel);
}

/// <summary>An <see cref="AIFunction"/> wrapper around a <see cref="KernelFunction"/>.</summary>
private sealed class KernelAIFunction : AIFunction
{
private readonly KernelFunction _kernelFunction;
private readonly Kernel? _kernel;

public KernelAIFunction(KernelFunction kernelFunction, Kernel? kernel)
{
this._kernelFunction = kernelFunction;
this._kernel = kernel;

string name = string.IsNullOrWhiteSpace(kernelFunction.PluginName) ?
kernelFunction.Name :
$"{kernelFunction.PluginName}_{kernelFunction.Name}";

this.Metadata = new AIFunctionMetadata(name)
{
Description = kernelFunction.Description,

Parameters = kernelFunction.Metadata.Parameters.Select(p => new AIFunctionParameterMetadata(p.Name)
{
Description = p.Description,
ParameterType = p.ParameterType,
IsRequired = p.IsRequired,
HasDefaultValue = p.DefaultValue is not null,
DefaultValue = p.DefaultValue,
Schema = p.Schema?.RootElement,
}).ToList(),

ReturnParameter = new AIFunctionReturnParameterMetadata()
{
Description = kernelFunction.Metadata.ReturnParameter.Description,
ParameterType = kernelFunction.Metadata.ReturnParameter.ParameterType,
Schema = kernelFunction.Metadata.ReturnParameter.Schema?.RootElement,
},
};
}

public override AIFunctionMetadata Metadata { get; }

protected override async Task<object?> InvokeCoreAsync(IEnumerable<KeyValuePair<string, object?>> arguments, CancellationToken cancellationToken)
{
Verify.NotNull(arguments);

KernelArguments args = [];
foreach (var argument in arguments)
{
args[argument.Key] = argument.Value;
}

var functionResult = await this._kernelFunction.InvokeAsync(this._kernel ?? new(), args, cancellationToken).ConfigureAwait(false);
return functionResult.Value is object value ? JsonSerializer.SerializeToElement(value) : null;
}
}
}
12 changes: 12 additions & 0 deletions dotnet/src/SemanticKernel.Abstractions/Functions/KernelPlugin.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using Microsoft.Extensions.AI;

#pragma warning disable CA1716 // Identifiers should not match keywords

Expand Down Expand Up @@ -92,6 +93,17 @@ public IList<KernelFunctionMetadata> GetFunctionsMetadata()
/// <inheritdoc/>
public abstract IEnumerator<KernelFunction> GetEnumerator();

/// <summary>Produces an <see cref="AIFunction"/> for every <see cref="KernelFunction"/> in this plugin.</summary>
/// <returns>An enumerable of <see cref="AIFunction"/> instances, one for each <see cref="KernelFunction"/> in this plugin.</returns>
[Experimental("SKEXP0001")]
public IEnumerable<AIFunction> AsAIFunctions()
{
foreach (KernelFunction function in this)
{
yield return function.AsAIFunction();
}
}

/// <inheritdoc/>
IEnumerator IEnumerable.GetEnumerator() => this.GetEnumerator();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
<RootNamespace>Microsoft.SemanticKernel</RootNamespace>
<TargetFrameworks>net8.0;netstandard2.0</TargetFrameworks>
<NoWarn>$(NoWarn);SKEXP0001</NoWarn>
<NoWarn>$(NoWarn);NU5104</NoWarn> <!-- temporary -->
<EnablePackageValidation>true</EnablePackageValidation>
</PropertyGroup>

Expand All @@ -24,6 +25,7 @@
<ItemGroup>
<PackageReference Include="Microsoft.Bcl.AsyncInterfaces" />
<PackageReference Include="Microsoft.Bcl.HashCode" />
<PackageReference Include="Microsoft.Extensions.AI.Abstractions" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" />
<PackageReference Include="System.Diagnostics.DiagnosticSource" />
Expand Down
2 changes: 2 additions & 0 deletions dotnet/src/SemanticKernel.Core/SemanticKernel.Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<NoWarn>$(NoWarn);SKEXP0001</NoWarn>
<NoWarn>$(NoWarn);NU5104</NoWarn> <!-- temporary -->
<EnablePackageValidation>true</EnablePackageValidation>
</PropertyGroup>

Expand All @@ -33,6 +34,7 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.AI" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" />
<PackageReference Include="System.Numerics.Tensors" />
<PackageReference Include="System.Text.Json" />
Expand Down
Loading

0 comments on commit 9d7c4fc

Please sign in to comment.