diff --git a/src/elevenlabs/conversational_ai/conversation.py b/src/elevenlabs/conversational_ai/conversation.py index 03cb9ed4..8a7cea48 100644 --- a/src/elevenlabs/conversational_ai/conversation.py +++ b/src/elevenlabs/conversational_ai/conversation.py @@ -391,6 +391,7 @@ def __init__( config: Optional[ConversationInitiationData] = None, client_tools: Optional[ClientTools] = None, on_prem_config: Optional[OnPremInitiationData] = None, + environment: Optional[str] = None, ): self.client = client self.agent_id = agent_id @@ -399,6 +400,7 @@ def __init__( self.config = config or ConversationInitiationData() self.client_tools = client_tools or ClientTools() self.on_prem_config = on_prem_config + self.environment = environment self.client_tools.start() @@ -418,10 +420,16 @@ def _get_wss_url(self): # Ensure base URL ends with '/' for proper joining if not base_ws_url.endswith("/"): base_ws_url += "/" - return f"{base_ws_url}v1/convai/conversation?agent_id={self.agent_id}&source=python_sdk&version={__version__}" + url = f"{base_ws_url}v1/convai/conversation?agent_id={self.agent_id}&source=python_sdk&version={__version__}" + if self.environment: + url += f"&environment={self.environment}" + return url def _get_signed_url(self): - response = self.client.conversational_ai.conversations.get_signed_url(agent_id=self.agent_id) + response = self.client.conversational_ai.conversations.get_signed_url( + agent_id=self.agent_id, + environment=self.environment, + ) signed_url = response.signed_url # Append source and version query parameters to the signed URL separator = "&" if "?" in signed_url else "?" @@ -633,6 +641,7 @@ def __init__( callback_audio_alignment: Optional[Callable[[AudioEventAlignment], None]] = None, callback_end_session: Optional[Callable] = None, on_prem_config: Optional[OnPremInitiationData] = None, + environment: Optional[str] = None, ): """Conversational AI session. @@ -654,6 +663,7 @@ def __init__( callback_user_transcript: Callback for user transcripts. callback_latency_measurement: Callback for latency measurements (in milliseconds). callback_audio_alignment: Callback for audio alignment data with character-level timing. + environment: The environment to use. Defaults to "production" on the server. """ super().__init__( @@ -664,6 +674,7 @@ def __init__( config=config, client_tools=client_tools, on_prem_config=on_prem_config, + environment=environment, ) self.audio_interface = audio_interface @@ -925,6 +936,7 @@ def __init__( callback_audio_alignment: Optional[Callable[[AudioEventAlignment], Awaitable[None]]] = None, callback_end_session: Optional[Callable[[], Awaitable[None]]] = None, on_prem_config: Optional[OnPremInitiationData] = None, + environment: Optional[str] = None, ): """Async Conversational AI session. @@ -947,6 +959,7 @@ def __init__( callback_latency_measurement: Async callback for latency measurements (in milliseconds). callback_audio_alignment: Async callback for audio alignment data with character-level timing. callback_end_session: Async callback for when session ends. + environment: The environment to use. Defaults to "production" on the server. """ super().__init__( @@ -957,6 +970,7 @@ def __init__( config=config, client_tools=client_tools, on_prem_config=on_prem_config, + environment=environment, ) self.audio_interface = audio_interface diff --git a/src/elevenlabs/conversational_ai/conversations/client.py b/src/elevenlabs/conversational_ai/conversations/client.py index d44d0691..6dc0c41a 100644 --- a/src/elevenlabs/conversational_ai/conversations/client.py +++ b/src/elevenlabs/conversational_ai/conversations/client.py @@ -48,6 +48,7 @@ def get_signed_url( agent_id: str, include_conversation_id: typing.Optional[bool] = None, branch_id: typing.Optional[str] = None, + environment: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> ConversationSignedUrlResponseModel: """ @@ -64,6 +65,9 @@ def get_signed_url( branch_id : typing.Optional[str] The ID of the branch to use + environment : typing.Optional[str] + The environment to use. Defaults to "production" on the server. + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -89,6 +93,7 @@ def get_signed_url( agent_id=agent_id, include_conversation_id=include_conversation_id, branch_id=branch_id, + environment=environment, request_options=request_options, ) return _response.data @@ -99,6 +104,7 @@ def get_webrtc_token( agent_id: str, participant_name: typing.Optional[str] = None, branch_id: typing.Optional[str] = None, + environment: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> TokenResponseModel: """ @@ -115,6 +121,9 @@ def get_webrtc_token( branch_id : typing.Optional[str] The ID of the branch to use + environment : typing.Optional[str] + The environment to use. Defaults to "production" on the server. + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -137,7 +146,7 @@ def get_webrtc_token( ) """ _response = self._raw_client.get_webrtc_token( - agent_id=agent_id, participant_name=participant_name, branch_id=branch_id, request_options=request_options + agent_id=agent_id, participant_name=participant_name, branch_id=branch_id, environment=environment, request_options=request_options ) return _response.data @@ -412,6 +421,7 @@ async def get_signed_url( agent_id: str, include_conversation_id: typing.Optional[bool] = None, branch_id: typing.Optional[str] = None, + environment: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> ConversationSignedUrlResponseModel: """ @@ -428,6 +438,9 @@ async def get_signed_url( branch_id : typing.Optional[str] The ID of the branch to use + environment : typing.Optional[str] + The environment to use. Defaults to "production" on the server. + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -461,6 +474,7 @@ async def main() -> None: agent_id=agent_id, include_conversation_id=include_conversation_id, branch_id=branch_id, + environment=environment, request_options=request_options, ) return _response.data @@ -471,6 +485,7 @@ async def get_webrtc_token( agent_id: str, participant_name: typing.Optional[str] = None, branch_id: typing.Optional[str] = None, + environment: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> TokenResponseModel: """ @@ -487,6 +502,9 @@ async def get_webrtc_token( branch_id : typing.Optional[str] The ID of the branch to use + environment : typing.Optional[str] + The environment to use. Defaults to "production" on the server. + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -517,7 +535,7 @@ async def main() -> None: asyncio.run(main()) """ _response = await self._raw_client.get_webrtc_token( - agent_id=agent_id, participant_name=participant_name, branch_id=branch_id, request_options=request_options + agent_id=agent_id, participant_name=participant_name, branch_id=branch_id, environment=environment, request_options=request_options ) return _response.data diff --git a/src/elevenlabs/conversational_ai/conversations/raw_client.py b/src/elevenlabs/conversational_ai/conversations/raw_client.py index b5c79500..b9a1be87 100644 --- a/src/elevenlabs/conversational_ai/conversations/raw_client.py +++ b/src/elevenlabs/conversational_ai/conversations/raw_client.py @@ -30,6 +30,7 @@ def get_signed_url( agent_id: str, include_conversation_id: typing.Optional[bool] = None, branch_id: typing.Optional[str] = None, + environment: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[ConversationSignedUrlResponseModel]: """ @@ -46,6 +47,9 @@ def get_signed_url( branch_id : typing.Optional[str] The ID of the branch to use + environment : typing.Optional[str] + The environment to use. Defaults to "production" on the server. + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -61,6 +65,7 @@ def get_signed_url( "agent_id": agent_id, "include_conversation_id": include_conversation_id, "branch_id": branch_id, + "environment": environment, }, request_options=request_options, ) @@ -96,6 +101,7 @@ def get_webrtc_token( agent_id: str, participant_name: typing.Optional[str] = None, branch_id: typing.Optional[str] = None, + environment: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[TokenResponseModel]: """ @@ -112,6 +118,9 @@ def get_webrtc_token( branch_id : typing.Optional[str] The ID of the branch to use + environment : typing.Optional[str] + The environment to use. Defaults to "production" on the server. + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -127,6 +136,7 @@ def get_webrtc_token( "agent_id": agent_id, "participant_name": participant_name, "branch_id": branch_id, + "environment": environment, }, request_options=request_options, ) @@ -419,6 +429,7 @@ async def get_signed_url( agent_id: str, include_conversation_id: typing.Optional[bool] = None, branch_id: typing.Optional[str] = None, + environment: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[ConversationSignedUrlResponseModel]: """ @@ -435,6 +446,9 @@ async def get_signed_url( branch_id : typing.Optional[str] The ID of the branch to use + environment : typing.Optional[str] + The environment to use. Defaults to "production" on the server. + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -450,6 +464,7 @@ async def get_signed_url( "agent_id": agent_id, "include_conversation_id": include_conversation_id, "branch_id": branch_id, + "environment": environment, }, request_options=request_options, ) @@ -485,6 +500,7 @@ async def get_webrtc_token( agent_id: str, participant_name: typing.Optional[str] = None, branch_id: typing.Optional[str] = None, + environment: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[TokenResponseModel]: """ @@ -501,6 +517,9 @@ async def get_webrtc_token( branch_id : typing.Optional[str] The ID of the branch to use + environment : typing.Optional[str] + The environment to use. Defaults to "production" on the server. + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -516,6 +535,7 @@ async def get_webrtc_token( "agent_id": agent_id, "participant_name": participant_name, "branch_id": branch_id, + "environment": environment, }, request_options=request_options, ) diff --git a/tests/test_async_convai.py b/tests/test_async_convai.py index b6a4d702..364b90eb 100644 --- a/tests/test_async_convai.py +++ b/tests/test_async_convai.py @@ -141,7 +141,7 @@ async def test_async_conversation_with_auth(): await conversation.wait_for_session_end() # Assertions - mock_client.conversational_ai.conversations.get_signed_url.assert_called_once_with(agent_id=TEST_AGENT_ID) + mock_client.conversational_ai.conversations.get_signed_url.assert_called_once_with(agent_id=TEST_AGENT_ID, environment=None) @pytest.mark.asyncio diff --git a/tests/test_convai.py b/tests/test_convai.py index 248b475a..69a30719 100644 --- a/tests/test_convai.py +++ b/tests/test_convai.py @@ -129,7 +129,7 @@ def test_conversation_with_auth(): conversation.wait_for_session_end() # Assertions - mock_client.conversational_ai.conversations.get_signed_url.assert_called_once_with(agent_id=TEST_AGENT_ID) + mock_client.conversational_ai.conversations.get_signed_url.assert_called_once_with(agent_id=TEST_AGENT_ID, environment=None) def test_conversation_with_dynamic_variables(): diff --git a/tests/utils.py b/tests/utils.py index f2061ef0..3b0d48d3 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -6,7 +6,7 @@ IN_GITHUB = "GITHUB_ACTIONS" in os.environ -DEFAULT_VOICE = "21m00Tcm4TlvDq8ikWAM" +DEFAULT_VOICE = "IRHApOXLvnW57QJPQH2P" DEFAULT_TEXT = "Hello" DEFAULT_MODEL = "eleven_multilingual_v2" DEFAULT_VOICE_FILE = "tests/fixtures/voice_sample.mp3"