diff --git a/dotnet/samples/Concepts/PromptTemplates/SafeChatPrompts.cs b/dotnet/samples/Concepts/PromptTemplates/SafeChatPrompts.cs index 7f81c3a0ff2e..99a07662b4b1 100644 --- a/dotnet/samples/Concepts/PromptTemplates/SafeChatPrompts.cs +++ b/dotnet/samples/Concepts/PromptTemplates/SafeChatPrompts.cs @@ -4,11 +4,12 @@ namespace PromptTemplates; -public sealed class SafeChatPrompts : BaseTest, IDisposable +public sealed class SafeChatPrompts : BaseTest { private readonly LoggingHandler _handler; private readonly HttpClient _httpClient; private readonly Kernel _kernel; + private bool _isDisposed; public SafeChatPrompts(ITestOutputHelper output) : base(output) { @@ -25,10 +26,19 @@ public SafeChatPrompts(ITestOutputHelper output) : base(output) .Build(); } - public void Dispose() + protected override void Dispose(bool disposing) { - this._handler.Dispose(); - this._httpClient.Dispose(); + if (!this._isDisposed) + { + if (disposing) + { + this._handler.Dispose(); + this._httpClient.Dispose(); + } + + this._isDisposed = true; + } + base.Dispose(disposing); } /// diff --git a/dotnet/samples/GettingStartedWithProcesses/Step01_Processes.cs b/dotnet/samples/GettingStartedWithProcesses/Step01_Processes.cs index 84ac65689d1a..ebfa7e31c87d 100644 --- a/dotnet/samples/GettingStartedWithProcesses/Step01_Processes.cs +++ b/dotnet/samples/GettingStartedWithProcesses/Step01_Processes.cs @@ -10,7 +10,7 @@ namespace GettingStartedWithProcesses; /// Demonstrate creation of and /// eliciting its response to three explicit user messages. /// -public class Step01_Processes(ITestOutputHelper output) : BaseTest(output) +public class Step01_Processes(ITestOutputHelper output) : BaseTest(output, redirectSystemConsoleOutput: true) { /// /// Demonstrates the creation of a simple process that has multiple steps, takes @@ -103,7 +103,9 @@ public override ValueTask ActivateAsync(KernelProcessStepState s _state = state.State; _state.UserInputs.Add("Hello"); - _state.UserInputs.Add("How are you?"); + _state.UserInputs.Add("How tall is the tallest mountain?"); + _state.UserInputs.Add("How low is the lowest valley?"); + _state.UserInputs.Add("How wide is the widest river?"); _state.UserInputs.Add("exit"); return ValueTask.CompletedTask; @@ -121,6 +123,8 @@ public async ValueTask GetUserInputAsync(KernelProcessStepContext context) var input = _state!.UserInputs[_state.CurrentInputIndex]; _state.CurrentInputIndex++; + System.Console.WriteLine($"User: {input}"); + if (input.Equals("exit", StringComparison.OrdinalIgnoreCase)) { // Emit the exit event @@ -168,11 +172,16 @@ public async Task GetChatResponseAsync(KernelProcessStepContext context, string _state!.ChatMessages.Add(new(AuthorRole.User, userMessage)); IChatCompletionService chatService = _kernel.Services.GetRequiredService(); ChatMessageContent response = await chatService.GetChatMessageContentAsync(_state.ChatMessages).ConfigureAwait(false); - if (response != null) + if (response == null) { - _state.ChatMessages.Add(response!); + throw new InvalidOperationException("Failed to get a response from the chat completion service."); } + System.Console.WriteLine($"Assistant: {response.Content}"); + + // Update state with the response + _state.ChatMessages.Add(response); + // emit event: assistantResponse await context.EmitEventAsync(new KernelProcessEvent { Id = ChatBotEvents.AssistantResponseGenerated, Data = response }); } diff --git a/dotnet/src/InternalUtilities/samples/InternalUtilities/BaseTest.cs b/dotnet/src/InternalUtilities/samples/InternalUtilities/BaseTest.cs index 5b1916984d30..3b5c8841226f 100644 --- a/dotnet/src/InternalUtilities/samples/InternalUtilities/BaseTest.cs +++ b/dotnet/src/InternalUtilities/samples/InternalUtilities/BaseTest.cs @@ -1,12 +1,13 @@ // Copyright (c) Microsoft. All rights reserved. using System.Reflection; +using System.Text; using System.Text.Json; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; using Microsoft.SemanticKernel; using Microsoft.SemanticKernel.ChatCompletion; -public abstract class BaseTest +public abstract class BaseTest : TextWriter { /// /// Flag to force usage of OpenAI configuration if both @@ -59,7 +60,7 @@ protected Kernel CreateKernelWithChatCompletion() return builder.Build(); } - protected BaseTest(ITestOutputHelper output) + protected BaseTest(ITestOutputHelper output, bool redirectSystemConsoleOutput = false) { this.Output = output; this.LoggerFactory = new XunitLogger(output); @@ -71,36 +72,32 @@ protected BaseTest(ITestOutputHelper output) .Build(); TestConfiguration.Initialize(configRoot); + + // Redirect System.Console output to the test output if requested + if (redirectSystemConsoleOutput) + { + System.Console.SetOut(this); + } } - /// - /// This method can be substituted by Console.WriteLine when used in Console apps. - /// - /// Target object to write - public void WriteLine(object? target = null) - => this.Output.WriteLine(target ?? string.Empty); + /// + public override void WriteLine(object? value = null) + => this.Output.WriteLine(value ?? string.Empty); - /// - /// This method can be substituted by Console.WriteLine when used in Console apps. - /// - /// Format string - /// Arguments - public void WriteLine(string? format, params object?[] args) - => this.Output.WriteLine(format ?? string.Empty, args); + /// + public override void WriteLine(string? format, params object?[] arg) + => this.Output.WriteLine(format ?? string.Empty, arg); - /// - /// This method can be substituted by Console.WriteLine when used in Console apps. - /// - /// The message - public void WriteLine(string? message) - => this.Output.WriteLine(message ?? string.Empty); + /// + public override void WriteLine(string? value) + => this.Output.WriteLine(value ?? string.Empty); - /// - /// Current interface ITestOutputHelper does not have a Write method. This extension method adds it to make it analogous to Console.Write when used in Console apps. - /// - /// Target object to write - public void Write(object? target = null) - => this.Output.WriteLine(target ?? string.Empty); + /// + public override void Write(object? value = null) + => this.Output.WriteLine(value ?? string.Empty); + + /// + public override Encoding Encoding => Encoding.UTF8; /// /// Outputs the last message in the chat history.