Skip to content

Commit 8b1ebe7

Browse files
authored
Merge branch 'main' into angelo/text-messages
2 parents 0cccb2a + 615f5ab commit 8b1ebe7

2 files changed

Lines changed: 43 additions & 0 deletions

File tree

src/elevenlabs/conversational_ai/conversation.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,7 @@ def __init__(
296296
self.client_tools.start()
297297

298298
self._thread = None
299+
self._ws: Optional[ClientConnection] = None
299300
self._should_stop = threading.Event()
300301
self._conversation_id = None
301302
self._last_interrupt_id = 0
@@ -314,6 +315,7 @@ def end_session(self):
314315
"""Ends the conversation session and cleans up resources."""
315316
self.audio_interface.stop()
316317
self.client_tools.stop()
318+
self._ws = None
317319
self._should_stop.set()
318320

319321
def wait_for_session_end(self) -> Optional[str]:
@@ -400,6 +402,7 @@ def _run(self, ws_url: str):
400402
}
401403
)
402404
)
405+
self._ws = ws
403406

404407
def input_callback(audio):
405408
try:
@@ -488,6 +491,16 @@ def send_response(response):
488491
else:
489492
pass # Ignore all other message types.
490493

494+
def send_contextual_update(self, text: str):
495+
if not self._ws:
496+
raise RuntimeError("WebSocket is not connected")
497+
498+
payload = {
499+
"type": "contextual_update",
500+
"text": text,
501+
}
502+
self._ws.send(json.dumps(payload))
503+
491504
def _get_wss_url(self):
492505
base_ws_url = self.client._client_wrapper.get_environment().wss
493506
return f"{base_ws_url}/v1/convai/conversation?agent_id={self.agent_id}"

tests/test_convai.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,3 +163,33 @@ def test_conversation_with_dynamic_variables():
163163
mock_ws.send.assert_any_call(json.dumps(expected_init_message))
164164
agent_response_callback.assert_called_once_with("Hello there!")
165165
assert conversation._conversation_id == TEST_CONVERSATION_ID
166+
167+
def test_conversation_with_contextual_update():
168+
# Mock setup
169+
mock_ws = create_mock_websocket([])
170+
mock_client = MagicMock()
171+
172+
# Setup the conversation
173+
conversation = Conversation(
174+
client=mock_client,
175+
agent_id=TEST_AGENT_ID,
176+
requires_auth=False,
177+
audio_interface=MockAudioInterface(),
178+
)
179+
180+
# Run the test
181+
with patch("elevenlabs.conversational_ai.conversation.connect") as mock_connect:
182+
mock_connect.return_value.__enter__.return_value = mock_ws
183+
184+
conversation.start_session()
185+
time.sleep(0.1)
186+
187+
conversation.send_contextual_update("User appears to be looking at pricing page")
188+
189+
# Teardown
190+
conversation.end_session()
191+
conversation.wait_for_session_end()
192+
193+
# Assertions
194+
expected = json.dumps({"type": "contextual_update", "text": "User appears to be looking at pricing page"})
195+
mock_ws.send.assert_any_call(expected)

0 commit comments

Comments
 (0)