From b489d1174c471ad6cba0681ff0bc72d8902c6a15 Mon Sep 17 00:00:00 2001 From: "j.foucher" Date: Thu, 19 Feb 2026 13:49:03 +0100 Subject: [PATCH] Add SendTextMessage to agent component and WebSocket proxy Sends {"type":"user_message","text":"..."} to the ElevenLabs API. Agent responds with audio + text exactly as if it heard spoken input. Useful for testing without a microphone and for text-only NPC interactions. Available in Blueprint on UElevenLabsConversationalAgentComponent. Compiles cleanly on UE 5.5 Win64. Co-Authored-By: Claude Opus 4.6 --- .../ElevenLabsConversationalAgentComponent.cpp | 10 ++++++++++ .../Private/ElevenLabsWebSocketProxy.cpp | 16 ++++++++++++++++ .../ElevenLabsConversationalAgentComponent.h | 8 ++++++++ .../Public/ElevenLabsWebSocketProxy.h | 8 ++++++++ 4 files changed, 42 insertions(+) diff --git a/Unreal/PS_AI_Agent/Plugins/PS_AI_Agent_ElevenLabs/Source/PS_AI_Agent_ElevenLabs/Private/ElevenLabsConversationalAgentComponent.cpp b/Unreal/PS_AI_Agent/Plugins/PS_AI_Agent_ElevenLabs/Source/PS_AI_Agent_ElevenLabs/Private/ElevenLabsConversationalAgentComponent.cpp index 3148608..5276d6a 100644 --- a/Unreal/PS_AI_Agent/Plugins/PS_AI_Agent_ElevenLabs/Source/PS_AI_Agent_ElevenLabs/Private/ElevenLabsConversationalAgentComponent.cpp +++ b/Unreal/PS_AI_Agent/Plugins/PS_AI_Agent_ElevenLabs/Source/PS_AI_Agent_ElevenLabs/Private/ElevenLabsConversationalAgentComponent.cpp @@ -155,6 +155,16 @@ void UElevenLabsConversationalAgentComponent::StopListening() UE_LOG(LogElevenLabsAgent, Log, TEXT("Microphone capture stopped.")); } +void UElevenLabsConversationalAgentComponent::SendTextMessage(const FString& Text) +{ + if (!IsConnected()) + { + UE_LOG(LogElevenLabsAgent, Warning, TEXT("SendTextMessage: not connected. Call StartConversation() first.")); + return; + } + WebSocketProxy->SendTextMessage(Text); +} + void UElevenLabsConversationalAgentComponent::InterruptAgent() { if (WebSocketProxy) WebSocketProxy->SendInterrupt(); diff --git a/Unreal/PS_AI_Agent/Plugins/PS_AI_Agent_ElevenLabs/Source/PS_AI_Agent_ElevenLabs/Private/ElevenLabsWebSocketProxy.cpp b/Unreal/PS_AI_Agent/Plugins/PS_AI_Agent_ElevenLabs/Source/PS_AI_Agent_ElevenLabs/Private/ElevenLabsWebSocketProxy.cpp index 268e9e2..67e9541 100644 --- a/Unreal/PS_AI_Agent/Plugins/PS_AI_Agent_ElevenLabs/Source/PS_AI_Agent_ElevenLabs/Private/ElevenLabsWebSocketProxy.cpp +++ b/Unreal/PS_AI_Agent/Plugins/PS_AI_Agent_ElevenLabs/Source/PS_AI_Agent_ElevenLabs/Private/ElevenLabsWebSocketProxy.cpp @@ -126,6 +126,22 @@ void UElevenLabsWebSocketProxy::SendUserTurnEnd() UE_LOG(LogElevenLabsWS, Log, TEXT("User turn ended (client mode) — stopped sending user_activity.")); } +void UElevenLabsWebSocketProxy::SendTextMessage(const FString& Text) +{ + if (!IsConnected()) + { + UE_LOG(LogElevenLabsWS, Warning, TEXT("SendTextMessage: not connected.")); + return; + } + if (Text.IsEmpty()) return; + + // API: { "type": "user_message", "text": "Hello agent" } + TSharedPtr Msg = MakeShareable(new FJsonObject()); + Msg->SetStringField(TEXT("type"), ElevenLabsMessageType::UserMessage); + Msg->SetStringField(TEXT("text"), Text); + SendJsonMessage(Msg); +} + void UElevenLabsWebSocketProxy::SendInterrupt() { if (!IsConnected()) return; diff --git a/Unreal/PS_AI_Agent/Plugins/PS_AI_Agent_ElevenLabs/Source/PS_AI_Agent_ElevenLabs/Public/ElevenLabsConversationalAgentComponent.h b/Unreal/PS_AI_Agent/Plugins/PS_AI_Agent_ElevenLabs/Source/PS_AI_Agent_ElevenLabs/Public/ElevenLabsConversationalAgentComponent.h index d3f5b0a..759e1d9 100644 --- a/Unreal/PS_AI_Agent/Plugins/PS_AI_Agent_ElevenLabs/Source/PS_AI_Agent_ElevenLabs/Public/ElevenLabsConversationalAgentComponent.h +++ b/Unreal/PS_AI_Agent/Plugins/PS_AI_Agent_ElevenLabs/Source/PS_AI_Agent_ElevenLabs/Public/ElevenLabsConversationalAgentComponent.h @@ -135,6 +135,14 @@ public: UFUNCTION(BlueprintCallable, Category = "ElevenLabs") void StopListening(); + /** + * Send a plain text message to the agent without using the microphone. + * The agent will respond with audio and text just as if it heard you speak. + * Useful for testing in the Editor or for text-based interaction. + */ + UFUNCTION(BlueprintCallable, Category = "ElevenLabs") + void SendTextMessage(const FString& Text); + /** Interrupt the agent's current utterance. */ UFUNCTION(BlueprintCallable, Category = "ElevenLabs") void InterruptAgent(); diff --git a/Unreal/PS_AI_Agent/Plugins/PS_AI_Agent_ElevenLabs/Source/PS_AI_Agent_ElevenLabs/Public/ElevenLabsWebSocketProxy.h b/Unreal/PS_AI_Agent/Plugins/PS_AI_Agent_ElevenLabs/Source/PS_AI_Agent_ElevenLabs/Public/ElevenLabsWebSocketProxy.h index f9d545a..f03a54d 100644 --- a/Unreal/PS_AI_Agent/Plugins/PS_AI_Agent_ElevenLabs/Source/PS_AI_Agent_ElevenLabs/Public/ElevenLabsWebSocketProxy.h +++ b/Unreal/PS_AI_Agent/Plugins/PS_AI_Agent_ElevenLabs/Source/PS_AI_Agent_ElevenLabs/Public/ElevenLabsWebSocketProxy.h @@ -136,6 +136,14 @@ public: UFUNCTION(BlueprintCallable, Category = "ElevenLabs") void SendUserTurnEnd(); + /** + * Send a text message to the agent (no microphone needed). + * Useful for testing or text-only interaction. + * Sends: { "type": "user_message", "text": "..." } + */ + UFUNCTION(BlueprintCallable, Category = "ElevenLabs") + void SendTextMessage(const FString& Text); + /** Ask the agent to stop the current utterance. */ UFUNCTION(BlueprintCallable, Category = "ElevenLabs") void SendInterrupt();