mirror of
https://github.com/microsoft/semantic-kernel.git
synced 2026-10-12 02:19:06 +00:00
.Net: Add missing directory Plugin in concepts + Warning fixes (#11858)
### Motivation and Context I noted that we don't actually have any Concept in `Plugins` folder showcasing a good and also long available feature from Semantic Kernel for importing File/Directory based Template Plugins. - Added some minor "message level" fixes to this change. --------- Co-authored-by: Mark Wallace <[email protected]>
This commit is contained in:
co-authored by
Mark Wallace
parent
854330ca5f
commit
d4270406c7
@@ -9,6 +9,7 @@
|
||||
<LangVersion>12</LangVersion>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>disable</ImplicitUsings>
|
||||
<NoWarn>$(NoWarn);IDE0290;IDE0079</NoWarn>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
using Microsoft.SemanticKernel;
|
||||
|
||||
namespace Plugins;
|
||||
|
||||
/// <summary>
|
||||
/// This sample shows how to create templated plugins from file directories.
|
||||
/// </summary>
|
||||
public class CreatePromptPluginFromDirectory(ITestOutputHelper output) : BaseTest(output)
|
||||
{
|
||||
[Fact]
|
||||
public async Task ImportAndUsePromptPluginFromDirectoryWithOpenAI()
|
||||
{
|
||||
// Get the current directory of the application
|
||||
var pluginDirectory = Path.Combine(AppContext.BaseDirectory, "Plugins", "FunPlugin");
|
||||
|
||||
var kernel = Kernel.CreateBuilder()
|
||||
.AddOpenAIChatCompletion(
|
||||
modelId: TestConfiguration.OpenAI.ChatModelId,
|
||||
apiKey: TestConfiguration.OpenAI.ApiKey)
|
||||
.Build();
|
||||
|
||||
CreateFileBasedPluginTemplate(pluginDirectory);
|
||||
|
||||
var funPlugin = kernel.ImportPluginFromPromptDirectoryYaml(pluginDirectory, "FunPlugin");
|
||||
|
||||
// Invoke the plugin with a prompt
|
||||
var result = await kernel.InvokeAsync(funPlugin["Joke"], new()
|
||||
{
|
||||
["input"] = "Why did the chicken cross the road?",
|
||||
["style"] = "dad joke"
|
||||
});
|
||||
|
||||
Console.WriteLine(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// After running this method, a new importable plugin directory structure will be created at the application root.
|
||||
/// <code>
|
||||
/// ./Plugins/FunPlugin/
|
||||
/// joke.yml
|
||||
/// </code>
|
||||
/// Within the <c>FunPlugin</c> directory, any yml file will be imported as a distinct prompt function for the <see cref="KernelPlugin"/>.
|
||||
/// </summary>
|
||||
private static void CreateFileBasedPluginTemplate(string pluginRootDirectory)
|
||||
{
|
||||
// Create the sub-directory for the plugin function "Joke"
|
||||
var pluginRelativeDirectory = Path.Combine(pluginRootDirectory, "Joke");
|
||||
|
||||
const string PluginYmlFileContent =
|
||||
"""
|
||||
name: Joke
|
||||
template: |
|
||||
WRITE EXACTLY ONE JOKE or HUMOROUS STORY ABOUT THE TOPIC BELOW
|
||||
|
||||
JOKE MUST BE:
|
||||
- G RATED
|
||||
- WORKPLACE/FAMILY SAFE
|
||||
NO SEXISM, RACISM OR OTHER BIAS/BIGOTRY
|
||||
|
||||
BE CREATIVE AND FUNNY. I WANT TO LAUGH.
|
||||
Incorporate the style suggestion, if provided: {{$style}}
|
||||
+++++
|
||||
|
||||
{{$input}}
|
||||
+++++
|
||||
template_format: semantic-kernel
|
||||
description: A function that generates a story about a topic.
|
||||
input_variables:
|
||||
- name: input
|
||||
description: Joke subject.
|
||||
is_required: true
|
||||
- name: style
|
||||
description: Give a hint about the desired joke style.
|
||||
is_required: true
|
||||
output_variable:
|
||||
description: The generated funny joke.
|
||||
execution_settings:
|
||||
default:
|
||||
temperature: 0.9
|
||||
max_tokens: 1000
|
||||
top_p: 0.0
|
||||
presence_penalty: 0.0
|
||||
frequency_penalty: 0.0
|
||||
""";
|
||||
|
||||
// Create the directory structure
|
||||
if (!Directory.Exists(pluginRootDirectory))
|
||||
{
|
||||
Directory.CreateDirectory(pluginRootDirectory);
|
||||
}
|
||||
|
||||
// Create the config.json file if not exists
|
||||
var ymlFilePath = Path.Combine(pluginRootDirectory, "joke.yml");
|
||||
File.WriteAllText(ymlFilePath, PluginYmlFileContent);
|
||||
}
|
||||
}
|
||||
@@ -170,6 +170,7 @@ dotnet test -l "console;verbosity=detailed" --filter "FullyQualifiedName=ChatCom
|
||||
- [CreatePluginFromOpenApiSpec_Jira](https://github.com/microsoft/semantic-kernel/blob/main/dotnet/samples/Concepts/Plugins/CreatePluginFromOpenApiSpec_Jira.cs)
|
||||
- [CreatePluginFromOpenApiSpec_Klarna](https://github.com/microsoft/semantic-kernel/blob/main/dotnet/samples/Concepts/Plugins/CreatePluginFromOpenApiSpec_Klarna.cs)
|
||||
- [CreatePluginFromOpenApiSpec_RepairService](https://github.com/microsoft/semantic-kernel/blob/main/dotnet/samples/Concepts/Plugins/CreatePluginFromOpenApiSpec_RepairService.cs)
|
||||
- [CreatePromptPluginFromDirectory](https://github.com/microsoft/semantic-kernel/blob/main/dotnet/samples/Concepts/Plugins/CreatePromptPluginFromDirectory.cs)
|
||||
- [CrewAI_Plugin](https://github.com/microsoft/semantic-kernel/blob/main/dotnet/samples/Concepts/Plugins/CrewAI_Plugin.cs)
|
||||
- [OpenApiPlugin_PayloadHandling](https://github.com/microsoft/semantic-kernel/blob/main/dotnet/samples/Concepts/Plugins/OpenApiPlugin_PayloadHandling.cs)
|
||||
- [OpenApiPlugin_CustomHttpContentReader](https://github.com/microsoft/semantic-kernel/blob/main/dotnet/samples/Concepts/Plugins/OpenApiPlugin_CustomHttpContentReader.cs)
|
||||
|
||||
+4
-2
@@ -168,8 +168,10 @@ public sealed class AzureAISearchVectorStoreRecordCollection<TKey, TRecord> :
|
||||
}
|
||||
|
||||
// Create the index.
|
||||
var searchIndex = new SearchIndex(this._collectionName, searchFields);
|
||||
searchIndex.VectorSearch = vectorSearchConfig;
|
||||
var searchIndex = new SearchIndex(this._collectionName, searchFields)
|
||||
{
|
||||
VectorSearch = vectorSearchConfig
|
||||
};
|
||||
|
||||
return this.RunOperationAsync(
|
||||
"CreateIndex",
|
||||
|
||||
@@ -174,7 +174,7 @@ DO UPDATE SET {updateColumnsWithParams};
|
||||
var valuesRows = string.Join(", ",
|
||||
rows.Select((row, rowIndex) =>
|
||||
$"({string.Join(", ",
|
||||
columns.Select((c, colIndex) => $"${rowIndex * columns.Count + colIndex + 1}"))})"));
|
||||
columns.Select((c, colIndex) => $"${(rowIndex * columns.Count) + colIndex + 1}"))})"));
|
||||
|
||||
// Generate the update set clause
|
||||
var updateSetClause = string.Join(", ", columns.Where(c => c != keyColumn).Select(c => $"\"{c}\" = EXCLUDED.\"{c}\""));
|
||||
|
||||
@@ -585,8 +585,10 @@ public sealed class QdrantVectorStoreRecordCollection<TKey, TRecord> : IVectorSt
|
||||
#pragma warning restore CS0618 // Type or member is obsolete
|
||||
|
||||
// Specify whether to include vectors in the search results.
|
||||
var vectorsSelector = new WithVectorsSelector();
|
||||
vectorsSelector.Enable = options.IncludeVectors;
|
||||
var vectorsSelector = new WithVectorsSelector
|
||||
{
|
||||
Enable = options.IncludeVectors
|
||||
};
|
||||
|
||||
var query = new Query
|
||||
{
|
||||
|
||||
+4
-2
@@ -71,8 +71,10 @@ public class OllamaPromptExecutionSettingsTests
|
||||
// Arrange
|
||||
var functionChoiceBehavior = FunctionChoiceBehavior.Auto();
|
||||
|
||||
var originalExecutionSettings = new PromptExecutionSettings();
|
||||
originalExecutionSettings.FunctionChoiceBehavior = functionChoiceBehavior;
|
||||
var originalExecutionSettings = new PromptExecutionSettings
|
||||
{
|
||||
FunctionChoiceBehavior = functionChoiceBehavior
|
||||
};
|
||||
|
||||
// Act
|
||||
var result = OllamaPromptExecutionSettings.FromExecutionSettings(originalExecutionSettings);
|
||||
|
||||
+4
-2
@@ -172,8 +172,10 @@ public class AzureAISearchVectorStoreFixture : IAsyncLifetime
|
||||
searchFields.Add(new VectorSearchField("DescriptionEmbedding", 1536, "my-vector-profile"));
|
||||
|
||||
// Create an index definition with a vectorizer to use when doing vector searches using text.
|
||||
var definition = new SearchIndex(indexName, searchFields);
|
||||
definition.VectorSearch = new VectorSearch();
|
||||
var definition = new SearchIndex(indexName, searchFields)
|
||||
{
|
||||
VectorSearch = new VectorSearch()
|
||||
};
|
||||
definition.VectorSearch.Vectorizers.Add(new AzureOpenAIVectorizer("text-embedding-vectorizer")
|
||||
{
|
||||
Parameters = new AzureOpenAIVectorizerParameters
|
||||
|
||||
@@ -143,10 +143,12 @@ internal sealed class KernelRequestTracer : IDisposable
|
||||
{
|
||||
this.DisposeHttpResources();
|
||||
this._memoryDummyResponse = new MemoryStream(Encoding.UTF8.GetBytes(DummyResponse));
|
||||
this._httpMessageHandlerStub = new HttpMessageHandlerStub();
|
||||
this._httpMessageHandlerStub.ResponseToReturn = new HttpResponseMessage(HttpStatusCode.OK)
|
||||
this._httpMessageHandlerStub = new HttpMessageHandlerStub
|
||||
{
|
||||
Content = new StreamContent(this._memoryDummyResponse)
|
||||
ResponseToReturn = new HttpResponseMessage(HttpStatusCode.OK)
|
||||
{
|
||||
Content = new StreamContent(this._memoryDummyResponse)
|
||||
}
|
||||
};
|
||||
this._httpClient = new HttpClient(this._httpMessageHandlerStub);
|
||||
}
|
||||
|
||||
@@ -9,9 +9,15 @@
|
||||
|
||||
#pragma warning disable RCS1168
|
||||
#pragma warning disable RCS1211
|
||||
#pragma warning disable RCS1220
|
||||
#pragma warning disable IDE0009
|
||||
#pragma warning disable IDE0011
|
||||
#pragma warning disable IDE0038
|
||||
#pragma warning disable IDE0046
|
||||
#pragma warning disable IDE0048
|
||||
#pragma warning disable IDE0090
|
||||
#pragma warning disable IDE0301
|
||||
#pragma warning disable CS8604
|
||||
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
|
||||
@@ -22,4 +22,4 @@
|
||||
"default": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user