Skip to content

Commit 615f5ab

Browse files
authored
Add support for sending contextual_update events (elevenlabs#553)
1 parent 24daf9b commit 615f5ab

File tree

2 files changed

+44
-1
lines changed

2 files changed

+44
-1
lines changed

src/elevenlabs/conversational_ai/conversation.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import asyncio
77
from concurrent.futures import ThreadPoolExecutor
88

9-
from websockets.sync.client import connect
9+
from websockets.sync.client import connect, ClientConnection
1010
from websockets.exceptions import ConnectionClosedOK
1111

1212
from ..base_client import BaseElevenLabs
@@ -240,6 +240,7 @@ def __init__(
240240
self.client_tools.start()
241241

242242
self._thread = None
243+
self._ws: Optional[ClientConnection] = None
243244
self._should_stop = threading.Event()
244245
self._conversation_id = None
245246
self._last_interrupt_id = 0
@@ -257,6 +258,7 @@ def end_session(self):
257258
"""Ends the conversation session and cleans up resources."""
258259
self.audio_interface.stop()
259260
self.client_tools.stop()
261+
self._ws = None
260262
self._should_stop.set()
261263

262264
def wait_for_session_end(self) -> Optional[str]:
@@ -283,6 +285,7 @@ def _run(self, ws_url: str):
283285
}
284286
)
285287
)
288+
self._ws = ws
286289

287290
def input_callback(audio):
288291
try:
@@ -369,6 +372,16 @@ def send_response(response):
369372
else:
370373
pass # Ignore all other message types.
371374

375+
def send_contextual_update(self, text: str):
376+
if not self._ws:
377+
raise RuntimeError("WebSocket is not connected")
378+
379+
payload = {
380+
"type": "contextual_update",
381+
"text": text,
382+
}
383+
self._ws.send(json.dumps(payload))
384+
372385
def _get_wss_url(self):
373386
base_ws_url = self.client._client_wrapper.get_environment().wss
374387
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)