Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhance conversation extract foods #64

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using Mediator.Net.Context;
using Mediator.Net.Contracts;
using SmartTalk.Core.Services.Restaurants;
using SmartTalk.Messages.Commands.Restaurant;
using SmartTalk.Messages.Commands.Restaurants;

namespace SmartTalk.Core.Handlers.CommandHandlers.Restaurant;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using Hangfire;
using Mediator.Net;
using SmartTalk.Messages.Commands.Restaurants;

namespace SmartTalk.Core.Jobs.RecurringJobs;

public class ExtractFoodItemsFromConversationRecurringJob : IRecurringJob
{
private readonly IMediator _mediator;

public ExtractFoodItemsFromConversationRecurringJob(IMediator mediator)
{
_mediator = mediator;
}

public async Task Execute()
{
await _mediator.SendAsync(new ExtractFoodItemsFromConversationCommand()).ConfigureAwait(false);
}

public string JobId => nameof(ExtractFoodItemsFromConversationCommand);

public string CronExpression => Cron.Never();
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using Hangfire;
using Mediator.Net;
using SmartTalk.Messages.Commands.Restaurant;
using SmartTalk.Messages.Commands.Restaurants;

namespace SmartTalk.Core.Jobs.RecurringJobs;

Expand All @@ -21,4 +21,6 @@ public async Task Execute()
public string JobId => nameof(SchedulingSyncRestaurantMenuRecurringJob);

public string CronExpression => Cron.Daily();

public TimeZoneInfo TimeZone => TimeZoneInfo.FindSystemTimeZoneById("Asia/Shanghai");
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ public partial interface IPhoneOrderDataProvider
Task<List<PhoneOrderConversation>> AddPhoneOrderConversationsAsync(List<PhoneOrderConversation> conversations, bool forceSave = true, CancellationToken cancellationToken = default);

Task DeletePhoneOrderConversationsAsync(int recordId, CancellationToken cancellationToken);

Task<List<PhoneOrderConversation>> GetPhoneOrderConversationsWithSpecificFieldAsync(CancellationToken cancellationToken);
}

public partial class PhoneOrderDataProvider
Expand All @@ -36,4 +38,12 @@ public async Task DeletePhoneOrderConversationsAsync(int recordId, CancellationT

if (conversations.Any()) await _repository.DeleteAllAsync(conversations, cancellationToken).ConfigureAwait(false);
}

public async Task<List<PhoneOrderConversation>> GetPhoneOrderConversationsWithSpecificFieldAsync(CancellationToken cancellationToken)
{
return await _repository.Query<PhoneOrderConversation>()
.Where(x => (x.Intent == PhoneOrderIntent.AddOrder || x.Intent == PhoneOrderIntent.AskDishes)
&& (string.IsNullOrEmpty(x.ExtractFoodItem) || x.ExtractFoodItem == "[]"))
.ToListAsync(cancellationToken).ConfigureAwait(false);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
using Serilog;
using Smarties.Messages.Enums.System;
using SmartTalk.Core.Constants;
using SmartTalk.Core.Domain.PhoneOrder;
using SmartTalk.Core.Ioc;
using SmartTalk.Core.Services.Jobs;
using SmartTalk.Messages.Commands.Restaurants;
using SmartTalk.Messages.Dto.WebSocket;
using SmartTalk.Messages.Enums.PhoneOrder;

namespace SmartTalk.Core.Services.PhoneOrder;

public interface IPhoneOrderProcessJobService : IScopedDependency
{
Task ExtractFoodItemsFromConversationAsync(ExtractFoodItemsFromConversationCommand command, CancellationToken cancellationToken);
}

public class PhoneOrderProcessJobService : IPhoneOrderProcessJobService
{
private readonly IPhoneOrderService _phoneOrderService;
private readonly IPhoneOrderDataProvider _phoneOrderDataProvider;
private readonly ISmartTalkBackgroundJobClient _smartTalkBackgroundJobClient;

public PhoneOrderProcessJobService(IPhoneOrderService phoneOrderService, IPhoneOrderDataProvider phoneOrderDataProvider, ISmartTalkBackgroundJobClient smartTalkBackgroundJobClient)
{
_phoneOrderService = phoneOrderService;
_phoneOrderDataProvider = phoneOrderDataProvider;
_smartTalkBackgroundJobClient = smartTalkBackgroundJobClient;
}

public async Task ExtractFoodItemsFromConversationAsync(ExtractFoodItemsFromConversationCommand command, CancellationToken cancellationToken)
{
var conversations = await _phoneOrderDataProvider.GetPhoneOrderConversationsWithSpecificFieldAsync(cancellationToken).ConfigureAwait(false);

Log.Information("Get the specific conversations : {@Conversations}", conversations);

if (conversations == null || conversations.Count == 0) return;

var record = await _phoneOrderDataProvider.GetPhoneOrderRecordByIdAsync(conversations.First().RecordId, cancellationToken).ConfigureAwait(false);

Log.Information("Get the record by conversation: {@Record}", record);

if (record == null) return;

foreach (var conversation in conversations)
_smartTalkBackgroundJobClient.Enqueue(() => EnhanceConversationAsync(conversation, record, cancellationToken), HangfireConstants.InternalHostingPhoneOrder);
}

public async Task EnhanceConversationAsync(PhoneOrderConversation conversation, PhoneOrderRecord record, CancellationToken cancellationToken)
{
var extractFoods = await _phoneOrderService.ExtractMenuItemsAsync(
conversation.Intent!.Value, record, new PhoneOrderDetailDto(), conversation.Answer, cancellationToken).ConfigureAwait(false);

var items = extractFoods.FoodDetails.Select(x => new PhoneOrderOrderItem
{
RecordId = record.Id,
FoodName = x.FoodName,
Quantity = x.Count ?? 0,
Price = x.Price,
Note = x.Remark
}).ToList();

if (items.Any())
await _phoneOrderDataProvider.AddPhoneOrderItemAsync(items, true, cancellationToken).ConfigureAwait(false);
}
}
42 changes: 27 additions & 15 deletions src/SmartTalk.Core/Services/PhoneOrder/PhoneOrderService.Record.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ public partial interface IPhoneOrderService
Task ReceivePhoneOrderRecordAsync(ReceivePhoneOrderRecordCommand command, CancellationToken cancellationToken);

Task ExtractPhoneOrderRecordAiMenuAsync(List<SpeechMaticsSpeakInfoDto> phoneOrderInfo, PhoneOrderRecord record, byte[] audioContent, CancellationToken cancellationToken);

Task<PhoneOrderDetailDto> ExtractMenuItemsAsync(
PhoneOrderIntent intent, PhoneOrderRecord record, PhoneOrderDetailDto shoppingCart, string originText, CancellationToken cancellationToken);
}

public partial class PhoneOrderService
Expand Down Expand Up @@ -196,24 +199,11 @@ private async Task<List<SpeechMaticsSpeakInfoDto>> HandlerConversationFirstSente
{
var intent = await RecognizeIntentAsync(originText, cancellationToken).ConfigureAwait(false);

PhoneOrderDetailDto extractFoods = null;

switch (intent)
{
case PhoneOrderIntent.AddOrder:
extractFoods = await AddOrderDetailAsync(originText, cancellationToken).ConfigureAwait(false);
extractFoods = await GetSimilarRestaurantByRecordAsync(record, extractFoods, cancellationToken).ConfigureAwait(false);
CheckOrAddToShoppingCart(shoppingCart.FoodDetails, extractFoods.FoodDetails);
break;
case PhoneOrderIntent.ReduceOrder:
extractFoods = await ReduceOrderDetailAsync(shoppingCart.FoodDetails, originText, cancellationToken).ConfigureAwait(false);
extractFoods = await GetSimilarRestaurantByRecordAsync(record, extractFoods, cancellationToken).ConfigureAwait(false);
CheckOrReduceFromShoppingCart(shoppingCart.FoodDetails, extractFoods.FoodDetails);
break;
}
var extractFoods = await ExtractMenuItemsAsync(intent, record, shoppingCart, originText, cancellationToken).ConfigureAwait(false);

conversations[conversationIndex].Intent = intent;
conversations[conversationIndex].Answer = originText;

if (extractFoods != null)
conversations[conversationIndex].ExtractFoodItem = JsonConvert.SerializeObject(extractFoods.FoodDetails);

Expand All @@ -234,6 +224,28 @@ private async Task<List<SpeechMaticsSpeakInfoDto>> HandlerConversationFirstSente
return (goalTexts, shoppingCart, conversations);
}

public async Task<PhoneOrderDetailDto> ExtractMenuItemsAsync(
PhoneOrderIntent intent, PhoneOrderRecord record, PhoneOrderDetailDto shoppingCart, string originText, CancellationToken cancellationToken)
{
PhoneOrderDetailDto extractFoods = null;

switch (intent)
{
case PhoneOrderIntent.AddOrder:
extractFoods = await AddOrderDetailAsync(originText, cancellationToken).ConfigureAwait(false);
extractFoods = await GetSimilarRestaurantByRecordAsync(record, extractFoods, cancellationToken).ConfigureAwait(false);
CheckOrAddToShoppingCart(shoppingCart.FoodDetails, extractFoods.FoodDetails);
break;
case PhoneOrderIntent.ReduceOrder:
extractFoods = await ReduceOrderDetailAsync(shoppingCart.FoodDetails, originText, cancellationToken).ConfigureAwait(false);
extractFoods = await GetSimilarRestaurantByRecordAsync(record, extractFoods, cancellationToken).ConfigureAwait(false);
CheckOrReduceFromShoppingCart(shoppingCart.FoodDetails, extractFoods.FoodDetails);
break;
}

return extractFoods;
}

private async Task<bool> CheckAudioFirstSentenceIsRestaurantAsync(string query, CancellationToken cancellationToken)
{
var completionResult = await _smartiesClient.PerformQueryAsync( new AskGptRequest
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
using SmartTalk.Core.Services.Http.Clients;
using SmartTalk.Core.Services.Jobs;
using SmartTalk.Core.Services.RetrievalDb.VectorDb;
using SmartTalk.Messages.Commands.Restaurant;
using SmartTalk.Messages.Commands.Restaurants;
using SmartTalk.Messages.Constants;
using SmartTalk.Messages.Dto.EasyPos;
using SmartTalk.Messages.Dto.Embedding;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
using Mediator.Net.Contracts;

namespace SmartTalk.Messages.Commands.Restaurants;

public class ExtractFoodItemsFromConversationCommand : ICommand
{
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using Mediator.Net.Contracts;

namespace SmartTalk.Messages.Commands.Restaurant;
namespace SmartTalk.Messages.Commands.Restaurants;

public class SchedulingSyncRestaurantMenuCommand : ICommand
{
Expand Down