Skip to content

Commit

Permalink
.Net: [dev] Improve KernelSyntaxExamples ability to filter examples. (#…
Browse files Browse the repository at this point in the history
…2764)

### Motivation and Context

Make it easier to run individual examples in the KernelSyntaxExamples
project.

### Description
This commit combines the updates to launch.json, tasks.json, and
Program.cs to allow passing arguments to the main method and running
examples based on the provided filter. The list of examples in
Program.cs has also been updated to include new examples and ensure
proper execution. These changes make it easier to run specific examples
without having to run all of them and improve the organization and
readability of the code.

### Contribution Checklist

<!-- Before submitting this PR, please make sure: -->

- [x] The code builds clean without any errors or warnings
- [x] The PR follows the [SK Contribution
Guidelines](https://github.com/microsoft/semantic-kernel/blob/main/CONTRIBUTING.md)
and the [pre-submission formatting
script](https://github.com/microsoft/semantic-kernel/blob/main/CONTRIBUTING.md#development-scripts)
raises no violations
- [x] All unit tests pass, and I have added new tests where possible
- [x] I didn't break anyone 😄

---------

Co-authored-by: Dmytro Struk <[email protected]>
  • Loading branch information
lemillermicrosoft and dmytrostruk authored Sep 12, 2023
1 parent 596761a commit a5eb820
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 56 deletions.
4 changes: 3 additions & 1 deletion .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@
"preLaunchTask": "build (KernelSyntaxExamples)",
// If you have changed target frameworks, make sure to update the program path.
"program": "${workspaceFolder}/dotnet/samples/KernelSyntaxExamples/bin/Debug/net6.0/KernelSyntaxExamples.dll",
"args": [],
"args": [
/*"example0"*/
],
"cwd": "${workspaceFolder}/dotnet/samples/KernelSyntaxExamples",
// For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console
"console": "internalConsole",
Expand Down
6 changes: 4 additions & 2 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
Expand Up @@ -360,7 +360,9 @@
"args": [
"run",
"--project",
"${workspaceFolder}/dotnet/samples/KernelSyntaxExamples/KernelSyntaxExamples.csproj"
"${workspaceFolder}/dotnet/samples/KernelSyntaxExamples/KernelSyntaxExamples.csproj",
"--args",
"${input:filter}"
],
"problemMatcher": "$msCompile",
"group": "test",
Expand Down Expand Up @@ -440,7 +442,7 @@
"id": "filter",
"type": "promptString",
"default": "",
"description": "Enter a filter for the tests"
"description": "Enter a filter to pass as argument or filter"
}
]
}
103 changes: 52 additions & 51 deletions dotnet/samples/KernelSyntaxExamples/Program.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// Copyright (c) Microsoft. All rights reserved.

using System;
using System.Linq;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Configuration;
Expand All @@ -10,7 +12,7 @@
public static class Program
{
// ReSharper disable once InconsistentNaming
public static async Task Main()
public static async Task Main(string[] args)
{
// Load configuration from environment variables or user secrets.
LoadUserSecrets();
Expand All @@ -19,56 +21,55 @@ public static async Task Main()
using CancellationTokenSource cancellationTokenSource = new();
CancellationToken cancelToken = cancellationTokenSource.ConsoleCancellationToken();

// Run examples
await Example01_NativeFunctions.RunAsync().SafeWaitAsync(cancelToken);
await Example02_Pipeline.RunAsync().SafeWaitAsync(cancelToken);
await Example03_Variables.RunAsync().SafeWaitAsync(cancelToken);
await Example04_CombineLLMPromptsAndNativeCode.RunAsync().SafeWaitAsync(cancelToken);
await Example05_InlineFunctionDefinition.RunAsync().SafeWaitAsync(cancelToken);
await Example06_TemplateLanguage.RunAsync().SafeWaitAsync(cancelToken);
await Example07_BingAndGoogleSkills.RunAsync().SafeWaitAsync(cancelToken);
await Example08_RetryHandler.RunAsync().SafeWaitAsync(cancelToken);
await Example09_FunctionTypes.RunAsync().SafeWaitAsync(cancelToken);
await Example10_DescribeAllSkillsAndFunctions.RunAsync().SafeWaitAsync(cancelToken);
await Example11_WebSearchQueries.RunAsync().SafeWaitAsync(cancelToken);
await Example12_SequentialPlanner.RunAsync().SafeWaitAsync(cancelToken);
await Example13_ConversationSummarySkill.RunAsync().SafeWaitAsync(cancelToken);
await Example14_SemanticMemory.RunAsync().SafeWaitAsync(cancelToken);
await Example15_TextMemorySkill.RunAsync(cancelToken).SafeWaitAsync(cancelToken);
await Example16_CustomLLM.RunAsync().SafeWaitAsync(cancelToken);
await Example17_ChatGPT.RunAsync().SafeWaitAsync(cancelToken);
await Example18_DallE.RunAsync().SafeWaitAsync(cancelToken);
await Example20_HuggingFace.RunAsync().SafeWaitAsync(cancelToken);
await Example21_ChatGptPlugins.RunAsync().SafeWaitAsync(cancelToken);
await Example22_OpenApiSkill_AzureKeyVault.RunAsync().SafeWaitAsync(cancelToken);
await Example23_OpenApiSkill_GitHub.RunAsync().SafeWaitAsync(cancelToken);
await Example24_OpenApiSkill_Jira.RunAsync().SafeWaitAsync(cancelToken);
await Example25_ReadOnlyMemoryStore.RunAsync().SafeWaitAsync(cancelToken);
await Example26_AADAuth.RunAsync().SafeWaitAsync(cancelToken);
await Example27_SemanticFunctionsUsingChatGPT.RunAsync().SafeWaitAsync(cancelToken);
await Example28_ActionPlanner.RunAsync().SafeWaitAsync(cancelToken);
await Example29_Tokenizer.RunAsync().SafeWaitAsync(cancelToken);
await Example30_ChatWithPrompts.RunAsync().SafeWaitAsync(cancelToken);
await Example31_CustomPlanner.RunAsync().SafeWaitAsync(cancelToken);
await Example32_StreamingCompletion.RunAsync().SafeWaitAsync(cancelToken);
await Example33_StreamingChat.RunAsync().SafeWaitAsync(cancelToken);
await Example34_CustomChatModel.RunAsync().SafeWaitAsync(cancelToken);
await Example35_GrpcSkills.RunAsync().SafeWaitAsync(cancelToken);
await Example36_MultiCompletion.RunAsync().SafeWaitAsync(cancelToken);
await Example37_MultiStreamingCompletion.RunAsync().SafeWaitAsync(cancelToken);
await Example40_DIContainer.RunAsync().SafeWaitAsync(cancelToken);
await Example41_HttpClientUsage.RunAsync().SafeWaitAsync(cancelToken);
await Example42_KernelBuilder.RunAsync().SafeWaitAsync(cancelToken);
await Example43_GetModelResult.RunAsync().SafeWaitAsync(cancelToken);
await Example44_MultiChatCompletion.RunAsync().SafeWaitAsync(cancelToken);
await Example45_MultiStreamingChatCompletion.RunAsync().SafeWaitAsync(cancelToken);
await Example48_GroundednessChecks.RunAsync().SafeWaitAsync(cancelToken);
await Example49_LogitBias.RunAsync().SafeWaitAsync(cancelToken);
await Example51_StepwisePlanner.RunAsync().SafeWaitAsync(cancelToken);
await Example52_ApimAuth.RunAsync().SafeWaitAsync(cancelToken);
await Example54_AzureChatCompletionWithData.RunAsync().SafeWaitAsync(cancelToken);
await Example55_TextChunker.RunAsync().SafeWaitAsync(cancelToken);
await Example56_TemplateNativeFunctionsWithMultipleArguments.RunAsync().SafeWaitAsync(cancelToken);
string? defaultFilter = null; // Modify to filter examples

// Check if args[0] is provided
string? filter = args.Length > 0 ? args[0] : defaultFilter;

// Run examples based on the filter
await RunExamplesAsync(filter, cancelToken);
}

private static async Task RunExamplesAsync(string? filter, CancellationToken cancellationToken)
{
var examples = (Assembly.GetExecutingAssembly().GetTypes())
.Where(type => type.Name.StartsWith("Example", StringComparison.OrdinalIgnoreCase))
.Select(type => type.Name).ToList();

// Filter and run examples
foreach (var example in examples)
{
if (string.IsNullOrEmpty(filter) || example.Contains(filter, StringComparison.OrdinalIgnoreCase))
{
try
{
Console.WriteLine($"Running {example}...");

var method = Assembly.GetExecutingAssembly().GetType(example)?.GetMethod("RunAsync");
if (method == null)
{
Console.WriteLine($"Example {example} not found");
continue;
}

bool hasCancellationToken = method.GetParameters().Any(param => param.ParameterType == typeof(CancellationToken));

var taskParameters = hasCancellationToken ? new object[] { cancellationToken } : null;
if (method.Invoke(null, taskParameters) is Task t)
{
await t.SafeWaitAsync(cancellationToken);
}
else
{
method.Invoke(null, null);
}
}
catch (ConfigurationNotFoundException ex)
{
Console.WriteLine($"{ex.Message}. Skipping example {example}.");
}
}
}
}

private static void LoadUserSecrets()
Expand Down
36 changes: 34 additions & 2 deletions dotnet/samples/KernelSyntaxExamples/README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,44 @@
# Semantic Kernel syntax examples

This project contains a collection of semi-random examples about various scenarios
using SK components.
using SK components.

The examples are ordered by number, starting with very basic examples.

## Running Examples with Filters

You can run individual examples in the KernelSyntaxExamples project using various methods to specify a filter. This allows you to execute specific examples without running all of them. Choose one of the following options to apply a filter:

### Option 1: Set the Default Filter in Program.cs

In your code, you can set a default filter by modifying the appropriate variable or parameter. Look for the section in your code where the filter is applied or where the examples are defined, and change the filter value accordingly.

```csharp
// Example of setting a default filter in code
string defaultFilter = "Example0"; // will run all examples that contain 'example0' in the name
```

### Option 2: Set Command-Line Arguments
Right-click on your console application project in the Solution Explorer.

Choose "Properties" from the context menu.

In the project properties window, navigate to the "Debug" tab on the left.

Supply Command-Line Arguments:

In the "Command line arguments" field, enter the command-line arguments that your console application expects. Separate multiple arguments with spaces.

### Option 3: Use Visual Studio Code Filters
If you are using Visual Studio Code, you can specify a filter using the built-in filter options provided by the IDE. These options can be helpful when running your code in a debugging environment. Consult the documentation for Visual Studio Code or the specific extension you're using for information on applying filters.

### Option 4: Modify launch.json
If you are using Visual Studio or a similar IDE that utilizes launch configurations, you can specify the filter in your launch.json configuration file. Edit the configuration for your project to include the filter parameter.


## Configuring Secrets
Most of the examples will require secrets and credentials, to access OpenAI, Azure OpenAI,
Bing and other resources. We suggest using .NET
Bing and other resources. We suggest using .NET
[Secret Manager](https://learn.microsoft.com/en-us/aspnet/core/security/app-secrets)
to avoid the risk of leaking secrets into the repository, branches and pull requests.
You can also use environment variables if you prefer.
Expand Down

0 comments on commit a5eb820

Please sign in to comment.