Skip to content

Commit

Permalink
Created ChatService
Browse files Browse the repository at this point in the history
  • Loading branch information
ChrisIvanov committed Jun 10, 2024
1 parent 8069c6d commit b96d975
Show file tree
Hide file tree
Showing 5 changed files with 124 additions and 31 deletions.
6 changes: 6 additions & 0 deletions src/server/CookingApp/Models/Chat.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@

public class Chat : MongoEntity
{
[BsonElement("title")]
public string Title { get; set; }

[BsonElement("userId")]
public string UserId { get; set; }

[BsonElement("createdTime")]
public DateTime CreatedTime { get; set; }

Expand Down
34 changes: 34 additions & 0 deletions src/server/CookingApp/Services/ChatService/ChatService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
namespace CookingApp.Services.ChatHistory
{
using CookingApp.Infrastructure.Interfaces;

public class ChatService : IChatService
{
private readonly IRepository<Chat> _chatRepository;

public ChatService(IRepository<Chat> chatRepository)
{
_chatRepository = chatRepository;
}

public async Task InsertAsync(Chat chat)
{
await _chatRepository.InsertAsync(chat);
}

public async Task<List<Chat>> GetAllChatsAsync()
=> await _chatRepository.GetAllAsync();

public async Task<List<Tuple<string, string>>> GetAllByUserId(string userId)
{
var result = await _chatRepository.GetAllAsync(c => c.UserId == userId);
return result.OrderBy(c => c.CreatedDateTime).Select(c => Tuple.Create(c.Title, c.Id)).ToList();
}

public async Task<Chat?> GetByIdAsync(string id)
=> await _chatRepository.GetByIdAsync(id);

public async Task UpdateAsync(Chat chat)
=> await _chatRepository.UpdateAsync(chat);
}
}
15 changes: 15 additions & 0 deletions src/server/CookingApp/Services/ChatService/IChatService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
namespace CookingApp.Services.ChatHistory
{
public interface IChatService
{
Task InsertAsync(Chat chat);

Task<List<Chat>> GetAllChatsAsync();

Task<List<Tuple<string, string>>> GetAllByUserId(string userId);

Task<Chat?> GetByIdAsync(string id);

Task UpdateAsync(Chat chat);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
using CookingApp.Common.CompletionConstants;
using CookingApp.Infrastructure.Interfaces;
using System.Linq;
using CookingApp.Services.ChatHistory;
using MongoDB.Bson.Serialization;
using System.Text.Json;

/// <summary>
/// This class it to assist with the personal needs of the user.
Expand All @@ -16,23 +19,31 @@
public class CompletionService : ICompletionService
{
private readonly IRepository<User> _userRepo;
private readonly IRepository<Chat> _chatRepo;
private readonly ILogger _logger;
private readonly IChatService _chatService;
private readonly IOpenAIService _openAIService;

public CompletionService(IOpenAIService openAIService, IRepository<User> userRepo, IRepository<Chat> chatRepo)
public CompletionService(IOpenAIService openAIService,
IRepository<User> userRepo,
IChatService chatService,
ILogger logger)
{
_openAIService = openAIService;
_userRepo = userRepo;
_chatRepo = chatRepo;
_chatService = chatService;
_logger = logger;
}

public async Task<ChatCompletionCreateResponse> CreateCompletion(string request)
{
_logger.LogInformation("Attempting to find user");
//TODO: get the userId through JWT Bearer
var user = await _userRepo.GetByIdAsync("userId");
//TODO: insert try-catch
//var user = await _userRepo.GetByIdAsync("userId");

// Get the user allergies
var userAllergies = user.Allergies;
//var userAllergies = user.Allergies;
var userAllergies = new List<string> { "bananas", "oats", "peanuts" };

// Case if the converstaion is new and the chat doesn't exist
var completionResult = await _openAIService.ChatCompletion.CreateCompletion(new ChatCompletionCreateRequest
Expand All @@ -43,46 +54,61 @@ public async Task<ChatCompletionCreateResponse> CreateCompletion(string request)
ChatMessage.FromSystem(Completions.Instructions
+ userAllergies + "."
+ Completions.PromptEngineeringPrevention),
ChatMessage.FromUser(Completions.Suggestion),
ChatMessage.FromAssistant(Completions.ExampleResponse),
//ChatMessage.FromUser(Completions.Suggestion),
//ChatMessage.FromAssistant(Completions.ExampleResponse),
ChatMessage.FromUser(request)
},
Model = Models.Gpt_4o
Model = Models.Gpt_3_5_Turbo_0125,
MaxTokens = 5,
N = 1,
});

var userChat = CreateNewChat(completionResult.Id);
// Creates a new Chat where later interaction will be stored
//var userChat = CreateNewChat(completionResult.Id);

if (completionResult.Successful)
{
var response = completionResult.Choices[0].Message.Content;
UpdateUserChat(userChat, request, response);
//var response = completionResult.Choices[0].Message.Content;
//UpdateUserChat(userChat, request, response);
return completionResult;
}

return null;

}

public async Task<ChatCompletionCreateResponse> UpdateCompletion(string request, string? chatId = null)
public async Task<ChatCompletionCreateResponse> UpdateCompletion(string request, string? chatId)
{
var userChat = await _chatRepo.GetByIdAsync(chatId);

var completionResult = await _openAIService.ChatCompletion.CreateCompletion(new ChatCompletionCreateRequest
try
{
Messages = new List<ChatMessage>
{
ChatMessage.FromUser(request)
},
Model = Models.Gpt_4o
});
var userChat = await _chatService.GetByIdAsync(chatId);

if (completionResult.Successful)
var completionResult = await _openAIService.ChatCompletion.CreateCompletion(new ChatCompletionCreateRequest
{
Messages = new List<ChatMessage>
{
ChatMessage.FromUser(request)
},
Model = Models.Gpt_3_5_Turbo_0125
});

if (completionResult.Successful)
{
_logger.LogInformation("Successfully received a response from the ChatGPT API.");
// workout if info is needed inside the logger
_logger.LogInformation($"{JsonSerializer.Serialize(completionResult)}");
var response = completionResult.Choices[0].Message.Content;
UpdateUserChat(userChat, request, response);

return completionResult;
}
}
catch (Exception e)
{
var response = completionResult.Choices[0].Message.Content;
UpdateUserChat(userChat, request, response);
return completionResult;
_logger.LogInformation("An error occurred while sending a query to ChatGPT API.");
_logger.LogInformation(e.Message);
}

return null;
}

Expand All @@ -104,7 +130,7 @@ private Response CreateNewResponse(string message)
};

// Creates a new chat using the ID originating from the ChatGPT API
private Chat CreateNewChat(string id)
private async Task<Chat> CreateNewChat(string id)
{
var chat = new Chat()
{
Expand All @@ -113,16 +139,16 @@ private Chat CreateNewChat(string id)
Responses = new List<Response>()
};

_chatRepo.InsertAsync(chat);
await _chatService.InsertAsync(chat);

return chat;
}

private async void UpdateUserChat(Chat? userChat, string? request, string? response)
{
userChat.Requests.Add(CreateNewRequest(request));
userChat.Responses.Add(CreateNewResponse(response));
await _chatRepo.UpdateAsync(userChat);
userChat?.Requests.Add(CreateNewRequest(request));
userChat?.Responses.Add(CreateNewResponse(response));
await _chatService.UpdateAsync(userChat);
}
}
}
12 changes: 12 additions & 0 deletions test/CookingApp.UnitTests/ServiceTests/MongoDB/DbTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
namespace CookingApp.UnitTests.ServiceTests.MongoDB
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

internal class DbTests
{
}
}

0 comments on commit b96d975

Please sign in to comment.