Skip to content

Commit

Permalink
Merge pull request #89 from matthewbolanos/main
Browse files Browse the repository at this point in the history
Update starters for v1.0.0 RC1
  • Loading branch information
matthewbolanos authored Dec 5, 2023
2 parents 4746653 + a648f2b commit 429f610
Show file tree
Hide file tree
Showing 31 changed files with 375 additions and 500 deletions.
4 changes: 2 additions & 2 deletions sk-csharp-console-chat/.vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build",
"program": "${workspaceFolder}/bin/Debug/net6.0/sk-csharp-console-chat.dll",
"program": "${workspaceFolder}/bin/Debug/net8.0/sk-csharp-console-chat.dll",
"args": [],
"cwd": "${workspaceFolder}",
"console": "internalConsole",
"console": "integratedTerminal",
"stopAtEntry": false
},
{
Expand Down
86 changes: 86 additions & 0 deletions sk-csharp-console-chat/ConsoleChat.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
using Microsoft.Extensions.Hosting;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.AI.ChatCompletion;
using Microsoft.SemanticKernel.Connectors.AI.OpenAI;

/// <summary>
/// This is the main application service.
/// This takes console input, then sends it to the configured AI service, and then prints the response.
/// All conversation history is maintained in the chat history.
/// </summary>
internal class ConsoleChat : IHostedService
{
private readonly Kernel _kernel;
private readonly IHostApplicationLifetime _lifeTime;

public ConsoleChat(Kernel kernel, IHostApplicationLifetime lifeTime)
{
this._kernel = kernel;
this._lifeTime = lifeTime;
}

/// <summary>
/// Start the service.
/// </summary>
public Task StartAsync(CancellationToken cancellationToken)
{
Task.Run(() => this.ExecuteAsync(cancellationToken), cancellationToken);
return Task.CompletedTask;
}

/// <summary>
/// Stop a running service.
/// </summary>
public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask;

/// <summary>
/// The main execution loop. It will use any of the available plugins to perform actions
/// </summary>
private async Task ExecuteAsync(CancellationToken cancellationToken)
{
ChatHistory chatMessages = [];
IChatCompletionService chatCompletionService = this._kernel.GetService<IChatCompletionService>();

// Loop till we are cancelled
while (!cancellationToken.IsCancellationRequested)
{
// Get user input
System.Console.Write("User > ");
chatMessages.AddUserMessage(Console.ReadLine()!);

// Get the chat completions
OpenAIPromptExecutionSettings openAIPromptExecutionSettings = new()
{
FunctionCallBehavior = FunctionCallBehavior.AutoInvokeKernelFunctions
};
IAsyncEnumerable<StreamingChatMessageContent> result =
chatCompletionService.GetStreamingChatMessageContentsAsync(
chatMessages,
executionSettings: openAIPromptExecutionSettings,
kernel: this._kernel,
cancellationToken: cancellationToken);

// Print the chat completions
ChatMessageContent? chatMessageContent = null;
await foreach (var content in result)
{
if (content.Role.HasValue)
{
System.Console.Write("Assistant > ");
chatMessageContent = new(
content.Role ?? AuthorRole.Assistant,
content.ModelId!,
content.Content!,
content.InnerContent,
content.Encoding,
content.Metadata
);
}
System.Console.Write(content.Content);
chatMessageContent!.Content += content.Content;
}
System.Console.WriteLine();
chatMessages.AddMessage(chatMessageContent!);
}
}
}
78 changes: 0 additions & 78 deletions sk-csharp-console-chat/ConsoleGPTService.cs

This file was deleted.

44 changes: 17 additions & 27 deletions sk-csharp-console-chat/Program.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
using Microsoft.Extensions.DependencyInjection;
using System.Net;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Http.Resilience;
using Microsoft.Extensions.Logging;
using Microsoft.SemanticKernel;

using Skills;
using Plugins;

// Load the kernel settings
var kernelSettings = KernelSettings.LoadSettings();
Expand All @@ -20,32 +21,21 @@
// Configure the services for the host
builder.ConfigureServices((context, services) =>
{
// Create a logger factory with the log level from the kernel settings.
using var loggerFactory = LoggerFactory.Create(b =>
{
b.SetMinimumLevel(kernelSettings.LogLevel ?? LogLevel.Warning)
.AddConsole()
.AddDebug();
});
// Create a Semantic Kernel using our logger and kernel settings.
var kernel = new KernelBuilder()
.WithLogger(loggerFactory.CreateLogger<IKernel>())
.WithCompletionService(kernelSettings)
.Build();
// Add Semantic Kernel to the host builder
services.AddSingleton<IKernel>(kernel);
// Add kernel settings to the host builder
services.AddSingleton<KernelSettings>(kernelSettings);
// Add Native Skills to the host builder
services.AddSingleton<ConsoleSkill>();
services.AddSingleton<ChatSkill>();
// Add the primary hosted service to the host builder to start the loop.
services.AddHostedService<ConsoleGPTService>();
services
.AddSingleton<KernelSettings>(kernelSettings)
.AddTransient<Kernel>(serviceProvider => new KernelBuilder()
.WithServices(serviceCollection =>
{
serviceCollection
.AddLogging(c => c.AddDebug().SetMinimumLevel(LogLevel.Information))
.AddChatCompletionService(kernelSettings);
})
.WithPlugins(plugins => plugins.AddPluginFromObject<LightPlugin>())
.Build()
)
.AddHostedService<ConsoleChat>();
});

// Build and run the host. This keeps the app running using the HostedService.
Expand Down
11 changes: 3 additions & 8 deletions sk-csharp-console-chat/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ Configure an OpenAI endpoint
cd sk-csharp-console-chat
dotnet user-secrets set "serviceType" "OpenAI"
dotnet user-secrets set "serviceId" "gpt-3.5-turbo"
dotnet user-secrets set "deploymentOrModelId" "gpt-3.5-turbo"
dotnet user-secrets set "modelId" "gpt-3.5-turbo"
dotnet user-secrets set "apiKey" "... your OpenAI key ..."
```

Expand All @@ -36,7 +36,8 @@ Configure an Azure OpenAI endpoint
cd sk-csharp-console-chat
dotnet user-secrets set "serviceType" "AzureOpenAI"
dotnet user-secrets set "serviceId" "gpt-35-turbo"
dotnet user-secrets set "deploymentOrModelId" "gpt-35-turbo"
dotnet user-secrets set "deploymentId" "gpt-35-turbo"
dotnet user-secrets set "modelId" "gpt-3.5-turbo"
dotnet user-secrets set "endpoint" "https:// ... your endpoint ... .openai.azure.com/"
dotnet user-secrets set "apiKey" "... your Azure OpenAI key ..."
```
Expand All @@ -57,12 +58,6 @@ Log levels:
- 5 = Critical
- 6 = None

Configure the system prompt. This is guidance provided to the OpenAI service for the chat completion, and defaults to "You are a friendly, intelligent, and curious assistant who is good at conversation."

```bash
dotnet user-secrets set "systemPrompt" "You are a chatbot that answers all questions using limericks"
```

### Using appsettings.json

Configure an OpenAI endpoint
Expand Down
29 changes: 0 additions & 29 deletions sk-csharp-console-chat/config/KernelBuilderExtensions.cs

This file was deleted.

7 changes: 5 additions & 2 deletions sk-csharp-console-chat/config/KernelSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,11 @@ internal class KernelSettings
[JsonPropertyName("serviceId")]
public string ServiceId { get; set; } = string.Empty;

[JsonPropertyName("deploymentOrModelId")]
public string DeploymentOrModelId { get; set; } = string.Empty;
[JsonPropertyName("deploymentId")]
public string DeploymentId { get; set; } = string.Empty;

[JsonPropertyName("modelId")]
public string ModelId { get; set; } = string.Empty;

[JsonPropertyName("endpoint")]
public string Endpoint { get; set; } = string.Empty;
Expand Down
30 changes: 30 additions & 0 deletions sk-csharp-console-chat/config/ServiceCollectionExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.SemanticKernel;

internal static class ServiceCollectionExtensions
{
/// <summary>
/// Adds a chat completion service to the list. It can be either an OpenAI or Azure OpenAI backend service.
/// </summary>
/// <param name="kernelBuilder"></param>
/// <param name="kernelSettings"></param>
/// <exception cref="ArgumentException"></exception>
internal static IServiceCollection AddChatCompletionService(this IServiceCollection serviceCollection, KernelSettings kernelSettings)
{
switch (kernelSettings.ServiceType.ToUpperInvariant())
{
case ServiceTypes.AzureOpenAI:
serviceCollection = serviceCollection.AddAzureOpenAIChatCompletion(kernelSettings.DeploymentId, kernelSettings.ModelId, endpoint: kernelSettings.Endpoint, apiKey: kernelSettings.ApiKey, serviceId: kernelSettings.ServiceId);
break;

case ServiceTypes.OpenAI:
serviceCollection = serviceCollection.AddOpenAIChatCompletion(modelId: kernelSettings.ModelId, apiKey: kernelSettings.ApiKey, orgId: kernelSettings.OrgId, serviceId: kernelSettings.ServiceId);
break;

default:
throw new ArgumentException($"Invalid service type value: {kernelSettings.ServiceType}");
}

return serviceCollection;
}
}
6 changes: 3 additions & 3 deletions sk-csharp-console-chat/config/appsettings.json.azure-example
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{
"serviceType": "AzureOpenAI",
"serviceId": "gpt-35-turbo",
"deploymentOrModelId": "gpt-35-turbo",
"deploymentId": "gpt-35-turbo",
"modelId": "gpt-35-turbo",
"endpoint": "https:// ... your endpoint ... .openai.azure.com/",
"apiKey": "... your Azure OpenAI key ...",
"systemPrompt": "You are a friendly, intelligent, and curious assistant who is good at conversation."
"apiKey": "... your Azure OpenAI key ..."
}
5 changes: 2 additions & 3 deletions sk-csharp-console-chat/config/appsettings.json.openai-example
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
{
"serviceType": "OpenAI",
"serviceId": "gpt-3.5-turbo",
"deploymentOrModelId": "gpt-3.5-turbo",
"modelId": "gpt-3.5-turbo",
"apiKey": "... your OpenAI key ...",
"orgId": "",
"systemPrompt": "You are a friendly, intelligent, and curious assistant who is good at conversation."
"orgId": ""
}
Loading

0 comments on commit 429f610

Please sign in to comment.