Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

.Net: Change Agents.Abstractions to depend on SemanticKernel.Abstractions instead of SemanticKernel.Core #10574

Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\SemanticKernel.Core\SemanticKernel.Core.csproj" />
<ProjectReference Include="..\..\SemanticKernel.Abstractions\SemanticKernel.Abstractions.csproj" />
</ItemGroup>

<ItemGroup>
Expand Down
13 changes: 2 additions & 11 deletions dotnet/src/Agents/Abstractions/KernelAgent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,6 @@ public abstract class KernelAgent : Agent
/// <summary>
/// Gets the instructions for the agent (optional).
/// </summary>
/// <remarks>
/// Instructions can be formatted in "semantic-kernel" template format (<see cref="KernelPromptTemplateFactory"/>).
/// </remarks>
public string? Instructions { get; init; }

/// <summary>
Expand All @@ -49,16 +46,10 @@ public abstract class KernelAgent : Agent
/// <returns>The formatted system instructions for the agent.</returns>
protected async Task<string?> FormatInstructionsAsync(Kernel kernel, KernelArguments? arguments, CancellationToken cancellationToken)
{
// If <see cref="Template"/> is not set, default instructions may be treated as "semantic-kernel" template.
// If <see cref="Template"/> is not set, use the default instructions.
if (this.Template == null)
{
if (string.IsNullOrWhiteSpace(this.Instructions))
{
return null;
}

KernelPromptTemplateFactory templateFactory = new(this.LoggerFactory);
this.Template = templateFactory.Create(new PromptTemplateConfig(this.Instructions!));
return Task.FromResult<string?>(this.Instructions).Result;
}

return await this.Template.RenderAsync(kernel, arguments, cancellationToken).ConfigureAwait(false);
Expand Down
1 change: 1 addition & 0 deletions dotnet/src/Agents/Core/Agents.Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@

<ItemGroup>
<ProjectReference Include="..\Abstractions\Agents.Abstractions.csproj" />
<ProjectReference Include="..\..\SemanticKernel.Core\SemanticKernel.Core.csproj" />
</ItemGroup>

<ItemGroup>
Expand Down
4 changes: 1 addition & 3 deletions dotnet/src/Agents/Core/ChatCompletionAgent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -88,12 +88,10 @@ protected override Task<AgentChannel> RestoreChannelAsync(string channelState, C

internal static (IChatCompletionService service, PromptExecutionSettings? executionSettings) GetChatCompletionService(Kernel kernel, KernelArguments? arguments)
{
// Need to provide a KernelFunction to the service selector as a container for the execution-settings.
KernelFunction nullPrompt = KernelFunctionFactory.CreateFromPrompt("placeholder", arguments?.ExecutionSettings?.Values);
(IChatCompletionService chatCompletionService, PromptExecutionSettings? executionSettings) =
kernel.ServiceSelector.SelectAIService<IChatCompletionService>(
kernel,
nullPrompt,
arguments?.ExecutionSettings,
arguments ?? []);

return (chatCompletionService, executionSettings);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// Copyright (c) Microsoft. All rights reserved.

using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace Microsoft.SemanticKernel;

/// <summary>
/// Represents a kernel function that performs no operation.
/// </summary>
[RequiresUnreferencedCode("Uses reflection to handle various aspects of the function creation and invocation, making it incompatible with AOT scenarios.")]
[RequiresDynamicCode("Uses reflection to handle various aspects of the function creation and invocation, making it incompatible with AOT scenarios.")]
internal sealed class KernelFunctionNoop : KernelFunction
{
/// <summary>
/// Creates a new instance of the <see cref="KernelFunctionNoop"/> class.
/// </summary>
/// <param name="executionSettings">Option: Prompt execution settings.</param>
internal KernelFunctionNoop(IReadOnlyDictionary<string, PromptExecutionSettings>? executionSettings) :
base($"Function_{Guid.NewGuid():N}", string.Empty, [], null, executionSettings?.ToDictionary(static kv => kv.Key, static kv => kv.Value))
{
}

/// <inheritdoc/>
public override KernelFunction Clone(string pluginName)
{
Dictionary<string, PromptExecutionSettings>? executionSettings = this.ExecutionSettings?.ToDictionary(kv => kv.Key, kv => kv.Value);
return new KernelFunctionNoop(executionSettings);
}

/// <inheritdoc/>
protected override ValueTask<FunctionResult> InvokeCoreAsync(Kernel kernel, KernelArguments arguments, CancellationToken cancellationToken)
{
return new(new FunctionResult(this));
}

/// <inheritdoc/>
protected override IAsyncEnumerable<TResult> InvokeStreamingCoreAsync<TResult>(Kernel kernel, KernelArguments arguments, CancellationToken cancellationToken)
{
return AsyncEnumerable.Empty<TResult>();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

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

using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Text;
using Microsoft.Extensions.DependencyInjection;
Expand Down Expand Up @@ -109,4 +111,32 @@ public static (T, PromptExecutionSettings?) SelectAIService<T>(

throw new KernelException(message.ToString());
}

/// <summary>
/// Resolves an <see cref="IAIService"/> and associated <see cref="PromptExecutionSettings"/> from the specified
/// <see cref="Kernel"/> based on a <see cref="KernelFunction"/> and associated <see cref="KernelArguments"/>.
/// </summary>
/// <typeparam name="T">
/// Specifies the type of the <see cref="IAIService"/> required. This must be the same type
/// with which the service was registered in the <see cref="IServiceCollection"/> orvia
/// the <see cref="IKernelBuilder"/>.
/// </typeparam>
/// <param name="selector">The <see cref="IAIServiceSelector"/> to use to select a service from the <see cref="Kernel"/>.</param>
/// <param name="kernel">The <see cref="Kernel"/> containing services, plugins, and other state for use throughout the operation.</param>
/// <param name="executionSettings">The dictionary of <see cref="PromptExecutionSettings"/> to use to select a service from the <see cref="Kernel"/>.</param>
/// <param name="arguments">The function arguments.</param>
/// <returns>A tuple of the selected service and the settings associated with the service (the settings may be null).</returns>
/// <exception cref="KernelException">An appropriate service could not be found.</exception>
[RequiresUnreferencedCode("Uses reflection to handle various aspects of the function creation and invocation, making it incompatible with AOT scenarios.")]
[RequiresDynamicCode("Uses reflection to handle various aspects of the function creation and invocation, making it incompatible with AOT scenarios.")]
public static (T, PromptExecutionSettings?) SelectAIService<T>(
this IAIServiceSelector selector,
Kernel kernel,
IReadOnlyDictionary<string, PromptExecutionSettings>? executionSettings,
KernelArguments arguments) where T : class, IAIService
{
// Need to provide a KernelFunction to the service selector as a container for the execution-settings.
KernelFunction nullPrompt = new KernelFunctionNoop(executionSettings);
return selector.SelectAIService<T>(kernel, nullPrompt, arguments);
}
}
Loading