made an implementation for request for recommendations and tested it

This commit is contained in:
stasex 2023-10-20 23:46:55 +03:00
parent fc6ce2e6a9
commit 60484e4a6e
3 changed files with 33 additions and 20 deletions

View File

@ -11,6 +11,7 @@ public interface IProductService
IAsyncEnumerable<(List<ProductName> ProductNames, WishlistDto Wishlist)> StartNewSearchAndReturnWishlist(Message message, CancellationToken cancellationToken);
Task<List<string>> GetProductFromSearch(Message message, CancellationToken cancellationToken);
Task<List<string>> GetRecommendationsForProductFromSearch(Message message, CancellationToken cancellationToken);
IAsyncEnumerable<string> GetRecommendationsForProductFromSearchStream(Message message,
CancellationToken cancellationToken);
}

View File

@ -83,7 +83,7 @@ public class ProductService : IProductService
return productNames.Select(productName => productName.Name).ToList();
}
public async Task<List<string>> GetRecommendationsForProductFromSearch(Message message, CancellationToken cancellationToken)
public async IAsyncEnumerable<string> GetRecommendationsForProductFromSearchStream(Message message, CancellationToken cancellationToken)
{
List<OpenAiMessage> messages = new List<OpenAiMessage>()
{
@ -93,18 +93,22 @@ public class ProductService : IProductService
Content = PromptForRecommendationsForProductSearch(message.Text)
}
};
var chatRequest = new ChatCompletionRequest
{
Messages = messages
};
var openAiMessage = await _openAiService.GetChatCompletion(chatRequest, cancellationToken);
await foreach (var response in _openAiService.GetChatCompletionStream(chatRequest, cancellationToken))
{
var openAiContent = JObject.Parse(response);
var recommendations = openAiContent["Recommendation"]?.ToObject<List<string>>() ?? new List<string>();
var openAiContent = JObject.Parse(openAiMessage.Content);
var recommendations = openAiContent["Recommendation"]?.ToObject<List<string>>() ?? new List<string>();
return recommendations;
foreach (var recommendation in recommendations)
{
yield return recommendation;
}
}
}
public string PromptForProductSearch(string message)

View File

@ -46,17 +46,14 @@ public class ProductTests
Content = "{ \"Name\": [{ \"Name\": \"NVIDIA GeForce RTX 3080\" }, { \"Name\": \"AMD Radeon RX 6900 XT\" }] }"
};
var openAiServiceMock = new Mock<IOpenAiService>();
var wishlistsServiceMock = new Mock<IWishlistsService>();
openAiServiceMock.Setup(x => x.GetChatCompletionStream(It.IsAny<ChatCompletionRequest>(), cancellationToken))
_openAiServiceMock.Setup(x => x.GetChatCompletionStream(It.IsAny<ChatCompletionRequest>(), cancellationToken))
.Returns((ChatCompletionRequest request, CancellationToken token) =>
{
var asyncEnumerable = new List<string> { expectedOpenAiMessage.Content }.ToAsyncEnumerable();
return asyncEnumerable;
});
wishlistsServiceMock.Setup(x => x.StartPersonalWishlistAsync(It.IsAny<WishlistCreateDto>(), cancellationToken))
_wishListServiceMock.Setup(x => x.StartPersonalWishlistAsync(It.IsAny<WishlistCreateDto>(), cancellationToken))
.ReturnsAsync(new WishlistDto
{
Id = "someID",
@ -65,7 +62,7 @@ public class ProductTests
CreatedById = "someId"
});
var productService = new ProductService(openAiServiceMock.Object, wishlistsServiceMock.Object);
var productService = new ProductService(_openAiServiceMock.Object, _wishListServiceMock.Object);
List<ProductName> productNames = null;
WishlistDto createdWishList = null;
@ -128,20 +125,31 @@ public class ProductTests
Role = "user"
};
var cancellationToken = CancellationToken.None;
var expectedOpenAiMessage = new OpenAiMessage
{
Role = OpenAiRole.User,
Content = "{ \"Recommendation\": [\"Recommendation 1\", \"Recommendation 2\"] }"
};
_openAiServiceMock.Setup(x => x.GetChatCompletion(It.IsAny<ChatCompletionRequest>(), cancellationToken))
.ReturnsAsync(expectedOpenAiMessage);
var recommendations = await _productServiceMock.Object.GetRecommendationsForProductFromSearch(message, cancellationToken);
_openAiServiceMock.Setup(x => x.GetChatCompletionStream(It.IsAny<ChatCompletionRequest>(), cancellationToken))
.Returns((ChatCompletionRequest request, CancellationToken token) =>
{
var asyncEnumerable = new List<string> { expectedOpenAiMessage.Content }.ToAsyncEnumerable();
return asyncEnumerable;
});
var recommendations = new List<string>();
var productService = new ProductService(_openAiServiceMock.Object, _wishListServiceMock.Object);
await foreach (var recommendation in productService.GetRecommendationsForProductFromSearchStream(message, cancellationToken))
{
recommendations.Add(recommendation);
}
var openAiContent = JObject.Parse(expectedOpenAiMessage.Content);
Assert.NotNull(openAiContent);
Assert.True(openAiContent.ContainsKey("Recommendation"));
Assert.Equal(new List<string> { "Recommendation 1", "Recommendation 2" }, recommendations);
}
}