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: Refactor PromptyKernelExtensions.CreateFunctionFromPrompty #6107

Merged
Show file tree
Hide file tree
Changes from all 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
2 changes: 2 additions & 0 deletions dotnet/samples/Concepts/Concepts.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,11 @@
<ProjectReference Include="..\..\src\Experimental\Agents\Experimental.Agents.csproj" />
<ProjectReference Include="..\..\src\Experimental\Orchestration.Flow\Experimental.Orchestration.Flow.csproj" />
<ProjectReference Include="..\..\src\Extensions\PromptTemplates.Handlebars\PromptTemplates.Handlebars.csproj" />
<ProjectReference Include="..\..\src\Extensions\PromptTemplates.Liquid\PromptTemplates.Liquid.csproj" />
<ProjectReference Include="..\..\src\Functions\Functions.Grpc\Functions.Grpc.csproj" />
<ProjectReference Include="..\..\src\Functions\Functions.OpenApi.Extensions\Functions.OpenApi.Extensions.csproj" />
<ProjectReference Include="..\..\src\Functions\Functions.OpenApi\Functions.OpenApi.csproj" />
<ProjectReference Include="..\..\src\Functions\Functions.Prompty\Functions.Prompty.csproj" />
<ProjectReference Include="..\..\src\Planners\Planners.Handlebars\Planners.Handlebars.csproj" />
<ProjectReference Include="..\..\src\Planners\Planners.OpenAI\Planners.OpenAI.csproj" />
<ProjectReference Include="..\..\src\Plugins\Plugins.Core\Plugins.Core.csproj" />
Expand Down
41 changes: 41 additions & 0 deletions dotnet/samples/Concepts/Prompty/PromptyFunction.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Copyright (c) Microsoft. All rights reserved.

using Microsoft.SemanticKernel;

namespace Prompty;
markwallace-microsoft marked this conversation as resolved.
Show resolved Hide resolved

public class PromptyFunction(ITestOutputHelper output) : BaseTest(output)
{
[Fact]
public async Task InlineFunctionAsync()
{
Kernel kernel = Kernel.CreateBuilder()
.AddOpenAIChatCompletion(
modelId: TestConfiguration.OpenAI.ChatModelId,
apiKey: TestConfiguration.OpenAI.ApiKey)
.Build();

string promptTemplate = """
---
name: Contoso_Chat_Prompt
description: A sample prompt that responds with what Seattle is.
authors:
- ????
model:
api: chat
configuration:
type: openai
---
system:
You are a helpful assistant who knows all about cities in the USA

user:
What is Seattle?
""";

var function = kernel.CreateFunctionFromPrompty(promptTemplate);

var result = await kernel.InvokeAsync(function);
Console.WriteLine(result);
}
}
markwallace-microsoft marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,10 @@ public void ChatPromptyTest()

var cwd = Directory.GetCurrentDirectory();
var chatPromptyPath = Path.Combine(cwd, "TestData", "chat.prompty");
var promptyTemplate = File.ReadAllText(chatPromptyPath);

// Act
var kernelFunction = kernel.CreateFunctionFromPrompty(chatPromptyPath);
var kernelFunction = kernel.CreateFunctionFromPrompty(promptyTemplate);

// Assert
Assert.Equal("Contoso_Chat_Prompt", kernelFunction.Name);
Expand All @@ -40,7 +41,7 @@ public void ChatPromptyShouldSupportCreatingOpenAIExecutionSettings()
var chatPromptyPath = Path.Combine(cwd, "TestData", "chat.prompty");

// Act
var kernelFunction = kernel.CreateFunctionFromPrompty(chatPromptyPath);
var kernelFunction = kernel.CreateFunctionFromPromptyFile(chatPromptyPath);

// Assert
// kernel function created from chat.prompty should have a single execution setting
Expand Down Expand Up @@ -75,7 +76,7 @@ public void ItShouldCreateFunctionFromPromptYamlWithNoExecutionSettings()
var promptyPath = Path.Combine(cwd, "TestData", "chatNoExecutionSettings.prompty");

// Act
var kernelFunction = kernel.CreateFunctionFromPrompty(promptyPath);
var kernelFunction = kernel.CreateFunctionFromPromptyFile(promptyPath);

// Assert
Assert.NotNull(kernelFunction);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,29 +12,57 @@
namespace Microsoft.SemanticKernel;

/// <summary>
/// Extension methods for <see cref="Kernel"/> to create a <see cref="KernelFunction"/> from a prompty file.
/// Extension methods for <see cref="Kernel"/> to create a <see cref="KernelFunction"/> from a Prompty file.
/// </summary>
public static class PromptyKernelExtensions
{
/// <summary>
/// Create a <see cref="KernelFunction"/> from a prompty file.
/// </summary>
/// <param name="kernel">kernel</param>
/// <param name="promptyPath">path to prompty file.</param>
/// <param name="promptTemplateFactory">prompty template factory, if not provided, a <see cref="LiquidPromptTemplateFactory"/> will be used.</param>
/// <param name="loggerFactory">logger factory</param>
/// <param name="kernel">The <see cref="Kernel"/> containing services, plugins, and other state for use throughout the operation.</param>
/// <param name="promptyFilePath">Path to the file containing the Prompty representation of a prompt based <see cref="KernelFunction"/>.</param>
/// <param name="promptTemplateFactory">
/// The <see cref="IPromptTemplateFactory"/> to use when interpreting the prompt template configuration into a <see cref="IPromptTemplate"/>.
/// If null, a <see cref="AggregatorPromptTemplateFactory"/> will be used with support for Liquid and Handlebars prompt templates.
/// </param>
/// <param name="loggerFactory">The <see cref="ILoggerFactory"/> to use.</param>
/// <returns><see cref="KernelFunction"/></returns>
/// <exception cref="ArgumentNullException"></exception>
/// <exception cref="NotSupportedException"></exception>
public static KernelFunction CreateFunctionFromPrompty(
public static KernelFunction CreateFunctionFromPromptyFile(
this Kernel kernel,
string promptyPath,
string promptyFilePath,
IPromptTemplateFactory? promptTemplateFactory = null,
ILoggerFactory? loggerFactory = null)
{
Verify.NotNull(kernel);
Verify.NotNullOrWhiteSpace(promptyFilePath);

var promptyTemplate = File.ReadAllText(promptyFilePath);
markwallace-microsoft marked this conversation as resolved.
Show resolved Hide resolved
return kernel.CreateFunctionFromPrompty(promptyTemplate, promptTemplateFactory, loggerFactory);
}

var text = File.ReadAllText(promptyPath);
/// <summary>
/// Create a <see cref="KernelFunction"/> from a prompty file.
/// </summary>
/// <param name="kernel">The <see cref="Kernel"/> containing services, plugins, and other state for use throughout the operation.</param>
/// <param name="promptyTemplate">Prompty representation of a prompt based <see cref="KernelFunction"/>.</param>
/// <param name="promptTemplateFactory">
/// The <see cref="IPromptTemplateFactory"/> to use when interpreting the prompt template configuration into a <see cref="IPromptTemplate"/>.
/// If null, a <see cref="AggregatorPromptTemplateFactory"/> will be used with support for Liquid and Handlebars prompt templates.
/// </param>
/// <param name="loggerFactory">The <see cref="ILoggerFactory"/> to use.</param>
/// <returns><see cref="KernelFunction"/></returns>
/// <exception cref="ArgumentNullException"></exception>
/// <exception cref="NotSupportedException"></exception>
public static KernelFunction CreateFunctionFromPrompty(
this Kernel kernel,
string promptyTemplate,
IPromptTemplateFactory? promptTemplateFactory = null,
ILoggerFactory? loggerFactory = null)
{
Verify.NotNull(kernel);
markwallace-microsoft marked this conversation as resolved.
Show resolved Hide resolved
Verify.NotNullOrWhiteSpace(promptyTemplate);

promptTemplateFactory ??= new AggregatorPromptTemplateFactory(new HandlebarsPromptTemplateFactory(), new LiquidPromptTemplateFactory());

Expand Down Expand Up @@ -70,7 +98,7 @@ public static KernelFunction CreateFunctionFromPrompty(
// ---
// ... (rest of the prompty content)

var splits = text.Split(["---"], StringSplitOptions.RemoveEmptyEntries);
var splits = promptyTemplate.Split(["---"], StringSplitOptions.RemoveEmptyEntries);
var yaml = splits[0];
var content = splits[1];

Expand Down
Loading