Skip to content

Commit 47cf938

Browse files
Added feedback submission mechanism
1 parent 4846dec commit 47cf938

4 files changed

Lines changed: 309 additions & 2 deletions

File tree

Source/Convai/Private/ConvaiChatbotComponent.cpp

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -588,6 +588,7 @@ void UConvaiChatbotComponent::Bind_GRPC_Request_Delegates()
588588
ConvaiGRPCGetResponseProxy->OnSessionIDReceived.BindUObject(this, &UConvaiChatbotComponent::onSessionIDReceived);
589589
ConvaiGRPCGetResponseProxy->OnActionsReceived.BindUObject(this, &UConvaiChatbotComponent::onActionSequenceReceived);
590590
ConvaiGRPCGetResponseProxy->OnNarrativeDataReceived.BindUObject(this, &UConvaiChatbotComponent::OnNarrativeSectionReceived);
591+
ConvaiGRPCGetResponseProxy->OnInteractionIDReceived.BindUObject(this, &UConvaiChatbotComponent::onInteractionIDReceived);
591592
ConvaiGRPCGetResponseProxy->OnEmotionReceived.BindUObject(this, &UConvaiChatbotComponent::onEmotionReceived);
592593
ConvaiGRPCGetResponseProxy->OnFinish.BindUObject(this, &UConvaiChatbotComponent::onFinishedReceivingData);
593594
ConvaiGRPCGetResponseProxy->OnFailure.BindUObject(this, &UConvaiChatbotComponent::onFailure);
@@ -605,6 +606,7 @@ void UConvaiChatbotComponent::Unbind_GRPC_Request_Delegates()
605606
ConvaiGRPCGetResponseProxy->OnFaceDataReceived.Unbind();
606607
ConvaiGRPCGetResponseProxy->OnSessionIDReceived.Unbind();
607608
ConvaiGRPCGetResponseProxy->OnActionsReceived.Unbind();
609+
ConvaiGRPCGetResponseProxy->OnInteractionIDReceived.Unbind();
608610
ConvaiGRPCGetResponseProxy->OnEmotionReceived.Unbind();
609611
ConvaiGRPCGetResponseProxy->OnFinish.Unbind();
610612
ConvaiGRPCGetResponseProxy->OnFailure.Unbind();
@@ -671,6 +673,14 @@ void UConvaiChatbotComponent::Broadcast_onSessionIDReceived_Implementation(const
671673
}
672674
}
673675

676+
void UConvaiChatbotComponent::Broadcast_onInteractionIDReceived_Implementation(const FString& ReceivedInteractionID)
677+
{
678+
if (!UKismetSystemLibrary::IsServer(this))
679+
{
680+
onInteractionIDReceived(ReceivedInteractionID);
681+
}
682+
}
683+
674684
void UConvaiChatbotComponent::Broadcast_onActionSequenceReceived_Implementation(const TArray<FConvaiResultAction>& ReceivedSequenceOfActions)
675685
{
676686
if (!UKismetSystemLibrary::IsServer(this))
@@ -840,6 +850,39 @@ void UConvaiChatbotComponent::onSessionIDReceived(const FString ReceivedSessionI
840850
SessionID = ReceivedSessionID;
841851
}
842852

853+
void UConvaiChatbotComponent::onInteractionIDReceived(FString ReceivedInteractionID)
854+
{
855+
// Broadcast to clients
856+
if (UKismetSystemLibrary::IsServer(this) && ReplicateVoiceToNetwork)
857+
{
858+
if (IsInGameThread())
859+
{
860+
Broadcast_onInteractionIDReceived(ReceivedInteractionID);
861+
}
862+
else
863+
{
864+
AsyncTask(ENamedThreads::GameThread, [this, ReceivedInteractionID]
865+
{
866+
Broadcast_onInteractionIDReceived(ReceivedInteractionID);
867+
});
868+
}
869+
}
870+
871+
if (IsInGameThread())
872+
{
873+
// Send Interaction ID to blueprint event
874+
OnInteractionIDReceivedEvent.Broadcast(this, CurrentConvaiPlayerComponent, ReceivedInteractionID);
875+
}
876+
else
877+
{
878+
AsyncTask(ENamedThreads::GameThread, [this, ReceivedInteractionID]
879+
{
880+
// Send Interaction ID to blueprint event
881+
OnInteractionIDReceivedEvent.Broadcast(this, CurrentConvaiPlayerComponent, ReceivedInteractionID);
882+
});
883+
}
884+
}
885+
843886
void UConvaiChatbotComponent::onActionSequenceReceived(const TArray<FConvaiResultAction>& ReceivedSequenceOfActions)
844887
{
845888
// Broadcast to clients

Source/Convai/Private/ConvaiGRPC.cpp

Lines changed: 177 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ THIRD_PARTY_INCLUDES_END
2222
//#pragma comment (lib, "crypt32.lib")
2323

2424
DEFINE_LOG_CATEGORY(ConvaiGRPCLog);
25+
DEFINE_LOG_CATEGORY(ConvaiGRPCFeedBackLog);
2526

2627
using ::service::GetResponseRequest_GetResponseConfig;
2728
using ::service::TriggerConfig;
@@ -32,6 +33,9 @@ using ::service::ActionConfig_Character;
3233
using ::service::GetResponseRequest_GetResponseData;
3334
using ::service::FaceModel;
3435

36+
using ::service::FeedbackRequest;
37+
using ::service::FeedbackRequest_Feedback;
38+
3539
using grpc::Channel;
3640
using grpc::ClientAsyncResponseReader;
3741
using grpc::ClientContext;
@@ -603,7 +607,13 @@ void UConvaiGRPCGetResponseProxy::OnStreamRead(bool ok)
603607
ConvaiGRPCGetResponseParams.SessionID = FString(SessionID_std.c_str());
604608
// Broadcast the Session ID
605609
OnSessionIDReceived.ExecuteIfBound(ConvaiGRPCGetResponseParams.SessionID);
610+
}
606611

612+
std::string InteractionID_std = reply->interaction_id();
613+
if (InteractionID_std.size())
614+
{
615+
// Broadcast the Interaction ID
616+
OnInteractionIDReceived.ExecuteIfBound(FString(InteractionID_std.c_str()));
607617
}
608618

609619
if (reply->has_user_query()) // Is there transcription ready
@@ -884,4 +894,170 @@ void UConvaiGRPCGetResponseProxy::OnStreamFinish(bool ok)
884894

885895

886896
OnFinish.ExecuteIfBound();
887-
}
897+
}
898+
899+
900+
901+
902+
UConvaiGRPCSubmitFeedbackProxy* UConvaiGRPCSubmitFeedbackProxy::CreateConvaiGRPCSubmitFeedbackProxy(UObject* WorldContextObject, FString InteractionID, bool ThumbsUp, FString FeedbackText)
903+
{
904+
UConvaiGRPCSubmitFeedbackProxy* Proxy = NewObject<UConvaiGRPCSubmitFeedbackProxy>();
905+
Proxy->WorldPtr = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull);
906+
Proxy->InteractionID = InteractionID;
907+
Proxy->ThumbsUp = ThumbsUp;
908+
Proxy->FeedbackText = FeedbackText;
909+
return Proxy;
910+
}
911+
912+
void UConvaiGRPCSubmitFeedbackProxy::Activate()
913+
{
914+
OnStreamFinishDelegate = FgRPC_Delegate::CreateUObject(this, &ThisClass::OnStreamFinish);
915+
916+
reply = std::unique_ptr<service::FeedbackResponse>(new service::FeedbackResponse());
917+
918+
// Form Validation
919+
if (!(UConvaiFormValidation::ValidateSessionID(InteractionID)))
920+
{
921+
LogAndEcecuteFailure("Activate");
922+
return;
923+
}
924+
925+
if (!WorldPtr.IsValid())
926+
{
927+
UE_LOG(ConvaiGRPCFeedBackLog, Warning, TEXT("WorldPtr not valid"));
928+
LogAndEcecuteFailure("Activate");
929+
return;
930+
}
931+
932+
UConvaiSubsystem* ConvaiSubsystem = UConvaiUtils::GetConvaiSubsystem(WorldPtr.Get());
933+
if (!ConvaiSubsystem)
934+
{
935+
UE_LOG(ConvaiGRPCFeedBackLog, Warning, TEXT("Convai Subsystem is not valid"));
936+
LogAndEcecuteFailure("Activate");
937+
return;
938+
}
939+
940+
// Create a new stub instance
941+
stub_ = ConvaiSubsystem->gRPC_Runnable->GetNewStub();
942+
if (!stub_)
943+
{
944+
UE_LOG(ConvaiGRPCFeedBackLog, Warning, TEXT("Could not aquire a new stub instance"));
945+
LogAndEcecuteFailure("Activate");
946+
return;
947+
}
948+
949+
// Aquire the completion queue instance
950+
cq_ = ConvaiSubsystem->gRPC_Runnable->GetCompletionQueue();
951+
if (!cq_)
952+
{
953+
UE_LOG(ConvaiGRPCFeedBackLog, Warning, TEXT("Got an invalid completion queue instance"));
954+
LogAndEcecuteFailure("Activate");
955+
return;
956+
}
957+
958+
bool Found;
959+
FString VersionName;
960+
FString EngineVersion;
961+
FString PlatformName;
962+
FString PluginEngineVersion;
963+
FString FriendlyName;
964+
965+
UConvaiUtils::GetPluginInfo(FString("Convai"), Found, VersionName, FriendlyName, PluginEngineVersion);
966+
UConvaiUtils::GetPlatformInfo(EngineVersion, PlatformName);
967+
968+
// Add metadata
969+
client_context.AddMetadata("engine", "Unreal Engine");
970+
client_context.AddMetadata("engine_version", TCHAR_TO_UTF8(*EngineVersion));
971+
client_context.AddMetadata("platform_name", TCHAR_TO_UTF8(*PlatformName));
972+
973+
if (Found)
974+
{
975+
client_context.AddMetadata("plugin_engine_version", TCHAR_TO_UTF8(*PluginEngineVersion));
976+
client_context.AddMetadata("plugin_version", TCHAR_TO_UTF8(*VersionName));
977+
client_context.AddMetadata("plugin_base_name", TCHAR_TO_UTF8(*FriendlyName));
978+
}
979+
else
980+
{
981+
client_context.AddMetadata("plugin_engine_version", "Unknown");
982+
client_context.AddMetadata("plugin_version", "Unknown");
983+
client_context.AddMetadata("plugin_base_name", "Unknown");
984+
}
985+
986+
FeedbackRequest_Feedback* feedbackRequest_Feedback = new FeedbackRequest_Feedback();
987+
feedbackRequest_Feedback->set_feedback_text(TCHAR_TO_UTF8(*FeedbackText));
988+
feedbackRequest_Feedback->set_thumbs_up(ThumbsUp);
989+
990+
request.set_allocated_text_feedback(feedbackRequest_Feedback);
991+
request.set_interaction_id(TCHAR_TO_UTF8(*InteractionID));
992+
993+
994+
stream_handler = stub_->AsyncSubmitFeedback(&client_context, request, cq_);
995+
stream_handler->Finish(reply.get(), &status, (void*)&OnStreamFinishDelegate);
996+
}
997+
998+
void UConvaiGRPCSubmitFeedbackProxy::OnStreamFinish(bool ok)
999+
{
1000+
if (!ok || !status.ok())
1001+
{
1002+
LogAndEcecuteFailure("OnStreamFinish");
1003+
return;
1004+
}
1005+
1006+
Response = FString(reply->feedback_response().c_str());
1007+
1008+
#if ConvaiDebugMode
1009+
UE_LOG(ConvaiGRPCFeedBackLog, Log,
1010+
TEXT("On Stream Finish | Interaction ID : %s | Feedback Text : %s | ThumbsUp: %s"),
1011+
*InteractionID,
1012+
*FeedbackText,
1013+
ThumbsUp? *FString("True") : *FString("False"));
1014+
#endif
1015+
1016+
1017+
success();
1018+
}
1019+
1020+
void UConvaiGRPCSubmitFeedbackProxy::BeginDestroy()
1021+
{
1022+
client_context.TryCancel();
1023+
stub_.reset();
1024+
UE_LOG(ConvaiGRPCFeedBackLog, Log,
1025+
TEXT("On Stream Finish | Interaction ID : %s | Feedback Text : %s | ThumbsUp: %s"),
1026+
*InteractionID,
1027+
*FeedbackText,
1028+
ThumbsUp ? "True" : "False");
1029+
Super::BeginDestroy();
1030+
}
1031+
1032+
void UConvaiGRPCSubmitFeedbackProxy::LogAndEcecuteFailure(FString FuncName)
1033+
{
1034+
UE_LOG(ConvaiGRPCFeedBackLog, Warning,
1035+
TEXT("%s: Status:%s | Debug Log:%s | Error message:%s | Error Details:%s | Error Code:%i | Interaction ID : %s | Feedback Text : %s | ThumbsUp: %s"),
1036+
*FString(FuncName),
1037+
*FString(status.ok() ? "Ok" : "Not Ok"),
1038+
*FString(reply->DebugString().c_str()),
1039+
*FString(status.error_message().c_str()),
1040+
*FString(status.error_details().c_str()),
1041+
status.error_code(),
1042+
*InteractionID,
1043+
*FeedbackText,
1044+
ThumbsUp ? "True" : "False");
1045+
1046+
failed();
1047+
}
1048+
1049+
void UConvaiGRPCSubmitFeedbackProxy::failed()
1050+
{
1051+
OnFailure.Broadcast(Response);
1052+
finish();
1053+
}
1054+
1055+
void UConvaiGRPCSubmitFeedbackProxy::success()
1056+
{
1057+
OnSuccess.Broadcast(Response);
1058+
finish();
1059+
}
1060+
1061+
void UConvaiGRPCSubmitFeedbackProxy::finish()
1062+
{
1063+
}

Source/Convai/Public/ConvaiChatbotComponent.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_SixParams(FOnTranscriptionReceivedSign
1717
DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_FourParams(FOnTextReceivedSignature_Deprecated, UConvaiChatbotComponent, OnTextReceivedEvent, FString, CharacterName, FString, BotText, float, AudioDuration, bool, IsFinal);
1818
DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_SixParams(FOnTextReceivedSignature_V2, UConvaiChatbotComponent, OnTextReceivedEvent_V2, UConvaiChatbotComponent*, ChatbotComponent, UConvaiPlayerComponent*, InteractingPlayerComponent, FString, CharacterName, FString, BotText, float, AudioDuration, bool, IsFinal);
1919

20-
2120
DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_OneParam(FOnActionReceivedSignature_Deprecated, UConvaiChatbotComponent, OnActionReceivedEvent, const TArray<FConvaiResultAction>&, SequenceOfActions);
2221
DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_ThreeParams(FOnActionReceivedSignature_V2, UConvaiChatbotComponent, OnActionReceivedEvent_V2, UConvaiChatbotComponent*, ChatbotComponent, UConvaiPlayerComponent*, InteractingPlayerComponent, const TArray<FConvaiResultAction>&, SequenceOfActions);
2322

@@ -28,6 +27,8 @@ DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_TwoParams(FOnCharacterDataLoadSignatur
2827

2928
DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_TwoParams(FOnNarrativeSectionReceivedSignature, UConvaiChatbotComponent, OnNarrativeSectionReceivedEvent, UConvaiChatbotComponent*, ChatbotComponent, FString, NarrativeSectionID);
3029

30+
DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_ThreeParams(FOnInteractionIDReceivedSignature, UConvaiChatbotComponent, OnInteractionIDReceivedEvent, UConvaiChatbotComponent*, ChatbotComponent, UConvaiPlayerComponent*, InteractingPlayerComponent, FString, InteractionID);
31+
3132
DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE(FOnFailureSignature, UConvaiChatbotComponent, OnFailureEvent);
3233
DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_TwoParams(FOnInterruptedSignature, UConvaiChatbotComponent, OnInterruptedEvent, UConvaiChatbotComponent*, ChatbotComponent, UConvaiPlayerComponent*, InteractingPlayerComponent);
3334

@@ -290,6 +291,9 @@ class CONVAI_API UConvaiChatbotComponent : public UConvaiAudioStreamer
290291
UPROPERTY(BlueprintAssignable, Category = "Convai", meta = (DisplayName = "On Narrative Section Received"))
291292
FOnNarrativeSectionReceivedSignature OnNarrativeSectionReceivedEvent;
292293

294+
UPROPERTY(BlueprintAssignable, Category = "Convai", meta = (DisplayName = "On Interaction ID Received"))
295+
FOnInteractionIDReceivedSignature OnInteractionIDReceivedEvent;
296+
293297
/** Called when the character is interrupted */
294298
UPROPERTY(BlueprintAssignable, Category = "Convai", meta = (DisplayName = "On Interrupted"))
295299
FOnInterruptedSignature OnInterruptedEvent;
@@ -383,12 +387,15 @@ class CONVAI_API UConvaiChatbotComponent : public UConvaiAudioStreamer
383387
UFUNCTION(NetMulticast, Reliable, Category = "Convai")
384388
void Broadcast_OnNarrativeSectionReceived(const FString& BT_Code, const FString& BT_Constants, const FString& ReceivedNarrativeSectionID);
385389
UFUNCTION(NetMulticast, Reliable, Category = "Convai")
390+
void Broadcast_onInteractionIDReceived(const FString& ReceivedInteractionID);
391+
UFUNCTION(NetMulticast, Reliable, Category = "Convai")
386392
void Broadcast_onEmotionReceived(const FString& ReceivedEmotionResponse, bool MultipleEmotions);
387393

388394
void OnTranscriptionReceived(FString Transcription, bool IsTranscriptionReady, bool IsFinal);
389395
void onResponseDataReceived(const FString ReceivedText, const TArray<uint8>& ReceivedAudio, uint32 SampleRate, bool IsFinal);
390396
void OnFaceDataReceived(FAnimationSequence FaceDataAnimation);
391397
void onSessionIDReceived(FString ReceivedSessionID);
398+
void onInteractionIDReceived(FString ReceivedInteractionID);
392399
void onActionSequenceReceived(const TArray<FConvaiResultAction>& ReceivedSequenceOfActions);
393400
void onEmotionReceived(FString ReceivedEmotionResponse, FAnimationFrame EmotionBlendshapesFrame, bool MultipleEmotions);
394401
void onFinishedReceivingData();

0 commit comments

Comments
 (0)