diff --git a/UI/ChatGPT/src/ChatGPT/App.xaml.cs b/UI/ChatGPT/src/ChatGPT/App.xaml.cs index 430c03f37..81d7520df 100644 --- a/UI/ChatGPT/src/ChatGPT/App.xaml.cs +++ b/UI/ChatGPT/src/ChatGPT/App.xaml.cs @@ -42,17 +42,15 @@ protected override void OnLaunched(LaunchActivatedEventArgs args) { var section = context.Configuration.GetSection(nameof(AppConfig)); var apiKey = section[nameof(AppConfig.ApiKey)]; - var useMockService = apiKey is null or { Length: 0 }; - if (useMockService) + if (apiKey is null or { Length: 0 }) { services.AddSingleton(); } else { services - .AddSingleton() - .AddSingleton() + .AddSingleton(new ChatClient("gpt-3.5-turbo", apiKey)) .AddSingleton(); } diff --git a/UI/ChatGPT/src/ChatGPT/Business/Models/ChatAiOptions.cs b/UI/ChatGPT/src/ChatGPT/Business/Models/ChatAiOptions.cs deleted file mode 100644 index fc09c9d8f..000000000 --- a/UI/ChatGPT/src/ChatGPT/Business/Models/ChatAiOptions.cs +++ /dev/null @@ -1,11 +0,0 @@ -using OpenAI; - -namespace ChatGPT.Business.Models; - -public class ChatAiOptions : OpenAiOptions -{ - public ChatAiOptions(IOptions appConfig) - { - this.ApiKey = appConfig.Value.ApiKey ?? throw new InvalidOperationException("You must define an OpenAI API key in appsettings.json file."); - } -} \ No newline at end of file diff --git a/UI/ChatGPT/src/ChatGPT/ChatGPT.csproj b/UI/ChatGPT/src/ChatGPT/ChatGPT.csproj index db304301f..05da2bcfe 100644 --- a/UI/ChatGPT/src/ChatGPT/ChatGPT.csproj +++ b/UI/ChatGPT/src/ChatGPT/ChatGPT.csproj @@ -29,8 +29,7 @@ Configuration; - - - - + + + diff --git a/UI/ChatGPT/src/ChatGPT/GlobalUsings.cs b/UI/ChatGPT/src/ChatGPT/GlobalUsings.cs index d097e6542..83a46751e 100644 --- a/UI/ChatGPT/src/ChatGPT/GlobalUsings.cs +++ b/UI/ChatGPT/src/ChatGPT/GlobalUsings.cs @@ -6,8 +6,7 @@ global using ChatGPT.Business.Models; global using ChatGPT.Presentation; global using ChatGPT.Services; +global using ChatGPT.Business; +global using OpenAI.Chat; global using ApplicationExecutionState = Windows.ApplicationModel.Activation.ApplicationExecutionState; -global using Color = Windows.UI.Color; -global using OpenAI; -global using OpenAI.Interfaces; -global using OpenAI.Managers; \ No newline at end of file +global using Color = Windows.UI.Color; \ No newline at end of file diff --git a/UI/ChatGPT/src/ChatGPT/Presentation/MainModel.cs b/UI/ChatGPT/src/ChatGPT/Presentation/MainModel.cs index a18c56e42..99cff6689 100644 --- a/UI/ChatGPT/src/ChatGPT/Presentation/MainModel.cs +++ b/UI/ChatGPT/src/ChatGPT/Presentation/MainModel.cs @@ -1,7 +1,4 @@ -using ChatGPT.Business; -using ChatGPT.Services; - -namespace ChatGPT.Presentation; +namespace ChatGPT.Presentation; public partial record MainModel { diff --git a/UI/ChatGPT/src/ChatGPT/Presentation/Message.cs b/UI/ChatGPT/src/ChatGPT/Presentation/Message.cs index 12e1dc00c..657ea82c7 100644 --- a/UI/ChatGPT/src/ChatGPT/Presentation/Message.cs +++ b/UI/ChatGPT/src/ChatGPT/Presentation/Message.cs @@ -1,6 +1,4 @@ -using ChatGPT.Business; - -namespace ChatGPT.Presentation; +namespace ChatGPT.Presentation; public partial record Message(Guid Id, Source Source, Status Status, string? Content) { diff --git a/UI/ChatGPT/src/ChatGPT/Services/ChatService.cs b/UI/ChatGPT/src/ChatGPT/Services/ChatService.cs index d24f2b812..390441550 100644 --- a/UI/ChatGPT/src/ChatGPT/Services/ChatService.cs +++ b/UI/ChatGPT/src/ChatGPT/Services/ChatService.cs @@ -1,39 +1,37 @@ -using ChatGPT.Business; -using OpenAI.Interfaces; -using OpenAI.ObjectModels; -using OpenAI.ObjectModels.RequestModels; -using OpenAI.ObjectModels.ResponseModels; +using System.ClientModel; using System.Runtime.CompilerServices; using System.Text; namespace ChatGPT.Services; -public class ChatService(IChatCompletionService client) : IChatService +public class ChatService : IChatService { - private readonly IChatCompletionService _client = client; - private const string systemPrompt = "You are Uno ChatGPT Sample, a helpful assistant helping users to learn more about how to develop using Uno Platform."; + private readonly ChatClient _client; + + public ChatService(ChatClient client) + { + _client = client; + } + public async ValueTask AskAsync(ChatRequest chatRequest, CancellationToken ct = default) { try { var request = ToCompletionRequest(chatRequest); - var result = await _client.CreateCompletion(request, cancellationToken: ct); + ChatCompletion result = await _client.CompleteChatAsync(request); - if (result.Successful) + return result.FinishReason switch { - var response = result.Choices.Select(choice => choice.Message.Content); - - return new ChatResponse(string.Join("", response)); - } - else - { - return new ChatResponse(result.Error?.Message, IsError: true); - } + ChatFinishReason.Stop => new ChatResponse(result.ToString()), + ChatFinishReason.Length => new ChatResponse("Incomplete model output due to MaxTokens parameter or token limit exceeded.", IsError: true), + ChatFinishReason.ContentFilter => new ChatResponse("Omitted content due to a content filter flag.", IsError: true), + _ => new ChatResponse(result.FinishReason.ToString()) + }; } - catch (Exception) + catch (Exception ex) { - return new ChatResponse(IsError: true); + return new ChatResponse($"Something went wrong: {ex.Message}", IsError: true); } } @@ -43,56 +41,46 @@ public async IAsyncEnumerable AskAsStream(ChatRequest chatRequest, var response = new ChatResponse(); var content = new StringBuilder(); - IAsyncEnumerator? responseStream = default; + IAsyncEnumerator? responseStream = default; + while (!response.IsError) { try { - responseStream ??= _client.CreateCompletionAsStream(request).GetAsyncEnumerator(ct); + responseStream ??= _client.CompleteChatStreamingAsync(request).GetAsyncEnumerator(ct); + if (await responseStream.MoveNextAsync()) { - if (responseStream.Current.Successful) + foreach (var updatePart in responseStream.Current.ContentUpdate) { - foreach (var choice in responseStream.Current.Choices) - { - content.Append(choice.Message.Content); - } - response = response with { Message = content.ToString() }; - } - else - { - response = response with { Message = responseStream.Current.Error?.Message, IsError = true }; + content.Append(updatePart.Text); } + + response = response with { Message = content.ToString() }; } else { yield break; } } - catch (Exception) + catch (Exception ex) { - response = response with { IsError = true }; + response = response with { Message = $"Something went wrong: {ex.Message}", IsError = true }; } yield return response; } } - private ChatCompletionCreateRequest ToCompletionRequest(ChatRequest request) - { - var history = request.History; - var requestMessages = new List(history.Count + 1) - { - ChatMessage.FromSystem(systemPrompt) - }; - requestMessages.AddRange(history.Select(entry => entry.IsUser - ? ChatMessage.FromUser(entry.Message) - : ChatMessage.FromAssistant(entry.Message))); + private ChatMessage[] ToCompletionRequest(ChatRequest request) + => request.History + .Select(ConvertMessage) + .Prepend(ChatMessage.CreateSystemMessage(systemPrompt)) + .ToArray(); + - return new ChatCompletionCreateRequest() - { - Messages = requestMessages, - Model = Models.Gpt_3_5_Turbo - }; - } + private ChatMessage ConvertMessage(ChatEntry entry) + => entry.IsUser + ? ChatMessage.CreateUserMessage(entry.Message) + : ChatMessage.CreateAssistantMessage(entry.Message); } \ No newline at end of file diff --git a/UI/ChatGPT/src/ChatGPT/Services/IChatService.cs b/UI/ChatGPT/src/ChatGPT/Services/IChatService.cs index ff3f9f090..282dc6f4e 100644 --- a/UI/ChatGPT/src/ChatGPT/Services/IChatService.cs +++ b/UI/ChatGPT/src/ChatGPT/Services/IChatService.cs @@ -1,6 +1,4 @@ -using ChatGPT.Business; - -namespace ChatGPT.Services; +namespace ChatGPT.Services; public interface IChatService { ValueTask AskAsync(ChatRequest request, CancellationToken ct = default); diff --git a/UI/ChatGPT/src/ChatGPT/Services/MockChatService.cs b/UI/ChatGPT/src/ChatGPT/Services/MockChatService.cs index 2162f2e49..c3f6053c0 100644 --- a/UI/ChatGPT/src/ChatGPT/Services/MockChatService.cs +++ b/UI/ChatGPT/src/ChatGPT/Services/MockChatService.cs @@ -1,5 +1,4 @@ -using ChatGPT.Business; -using System.Runtime.CompilerServices; +using System.Runtime.CompilerServices; using System.Text; namespace ChatGPT.Services; diff --git a/UI/ChatGPT/src/Directory.Packages.props b/UI/ChatGPT/src/Directory.Packages.props index e09a9ed9e..69f91f524 100644 --- a/UI/ChatGPT/src/Directory.Packages.props +++ b/UI/ChatGPT/src/Directory.Packages.props @@ -5,6 +5,8 @@ See https://aka.platform.uno/using-uno-sdk for more information. --> - - + + + + \ No newline at end of file