diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 263d47d2..5304d0ac 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "4.32.0" + ".": "4.33.0" } \ No newline at end of file diff --git a/.stats.yml b/.stats.yml index b29f59ec..955caa25 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 39 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/retell%2Ftoddlzt-01ccd56ecde0b5e2e742326f26f3cf2c0bbafef856e1b032110be4880e162106.yml -openapi_spec_hash: 8b1688d1e66812ccafbe5fcf26faa67a +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/retell%2Ftoddlzt-6f9abd242d6ae2ff1402a11e59ee5c26fcac97bb4a3780fb9e12096d542c6b61.yml +openapi_spec_hash: f5995d0f2a7ce0b2a88777b75dd6823f config_hash: f4bc63f2350a2a4988750b41a0737f9d diff --git a/CHANGELOG.md b/CHANGELOG.md index af760276..b44d706d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,25 @@ # Changelog +## 4.33.0 (2025-06-04) + +Full Changelog: [v4.32.0...v4.33.0](https://github.com/RetellAI/retell-python-sdk/compare/v4.32.0...v4.33.0) + +### Features + +* **api:** api update ([dd7af99](https://github.com/RetellAI/retell-python-sdk/commit/dd7af99acba77ffed717d0e5011e57e92ce9debd)) +* **api:** api update ([fb2e772](https://github.com/RetellAI/retell-python-sdk/commit/fb2e7725c80906892687f2b78c4fdcfa659fe984)) +* **api:** api update ([323a83f](https://github.com/RetellAI/retell-python-sdk/commit/323a83f10f58d907ba1efc8fabdb4fb3a9ccbdc2)) +* **api:** api update ([c642329](https://github.com/RetellAI/retell-python-sdk/commit/c6423291f5d23bfa14e652216489828c484ee94f)) +* **api:** api update ([b4a0386](https://github.com/RetellAI/retell-python-sdk/commit/b4a03868e6fddb84c6e8188d9726f89b451cb0ce)) +* **api:** api update ([792c706](https://github.com/RetellAI/retell-python-sdk/commit/792c706eafe63afbe41406a658d1f905a233d0b4)) +* **client:** add follow_redirects request option ([2588c21](https://github.com/RetellAI/retell-python-sdk/commit/2588c217e52353aa446fa8ac4afb02f41a561c01)) + + +### Chores + +* **docs:** remove reference to rye shell ([8b4f0b8](https://github.com/RetellAI/retell-python-sdk/commit/8b4f0b804bbcede54c53e8ae63600fd6058f47e4)) +* **docs:** remove unnecessary param examples ([b07cd50](https://github.com/RetellAI/retell-python-sdk/commit/b07cd50231c2da29ec2ec1a6fadee50b19ad0186)) + ## 4.32.0 (2025-05-26) Full Changelog: [v4.31.0...v4.32.0](https://github.com/RetellAI/retell-python-sdk/compare/v4.31.0...v4.32.0) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 614ae552..ffcd16de 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -17,8 +17,7 @@ $ rye sync --all-features You can then run scripts using `rye run python script.py` or by activating the virtual environment: ```sh -$ rye shell -# or manually activate - https://docs.python.org/3/library/venv.html#how-venvs-work +# Activate the virtual environment - https://docs.python.org/3/library/venv.html#how-venvs-work $ source .venv/bin/activate # now you can omit the `rye run` prefix diff --git a/README.md b/README.md index ef9b8568..72084bde 100644 --- a/README.md +++ b/README.md @@ -91,11 +91,7 @@ agent_response = client.agent.create( "type": "retell-llm", }, voice_id="11labs-Adrian", - user_dtmf_options={ - "digit_limit": 1, - "termination_key": "#", - "timeout_ms": 1000, - }, + user_dtmf_options={}, ) print(agent_response.user_dtmf_options) ``` diff --git a/pyproject.toml b/pyproject.toml index 96029fd1..24789f3f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "retell-sdk" -version = "4.32.0" +version = "4.33.0" description = "The official Python library for the retell API" dynamic = ["readme"] license = "Apache-2.0" diff --git a/src/retell/_base_client.py b/src/retell/_base_client.py index 9bb962e0..d4ef906f 100644 --- a/src/retell/_base_client.py +++ b/src/retell/_base_client.py @@ -955,6 +955,9 @@ def request( if self.custom_auth is not None: kwargs["auth"] = self.custom_auth + if options.follow_redirects is not None: + kwargs["follow_redirects"] = options.follow_redirects + log.debug("Sending HTTP Request: %s %s", request.method, request.url) response = None @@ -1455,6 +1458,9 @@ async def request( if self.custom_auth is not None: kwargs["auth"] = self.custom_auth + if options.follow_redirects is not None: + kwargs["follow_redirects"] = options.follow_redirects + log.debug("Sending HTTP Request: %s %s", request.method, request.url) response = None diff --git a/src/retell/_models.py b/src/retell/_models.py index 798956f1..4f214980 100644 --- a/src/retell/_models.py +++ b/src/retell/_models.py @@ -737,6 +737,7 @@ class FinalRequestOptionsInput(TypedDict, total=False): idempotency_key: str json_data: Body extra_json: AnyMapping + follow_redirects: bool @final @@ -750,6 +751,7 @@ class FinalRequestOptions(pydantic.BaseModel): files: Union[HttpxRequestFiles, None] = None idempotency_key: Union[str, None] = None post_parser: Union[Callable[[Any], Any], NotGiven] = NotGiven() + follow_redirects: Union[bool, None] = None # It should be noted that we cannot use `json` here as that would override # a BaseModel method in an incompatible fashion. diff --git a/src/retell/_types.py b/src/retell/_types.py index 55420ded..c10a893d 100644 --- a/src/retell/_types.py +++ b/src/retell/_types.py @@ -100,6 +100,7 @@ class RequestOptions(TypedDict, total=False): params: Query extra_json: AnyMapping idempotency_key: str + follow_redirects: bool # Sentinel class used until PEP 0661 is accepted @@ -215,3 +216,4 @@ class _GenericAlias(Protocol): class HttpxSendArgs(TypedDict, total=False): auth: httpx.Auth + follow_redirects: bool diff --git a/src/retell/_version.py b/src/retell/_version.py index 1be0e816..d1b7898c 100644 --- a/src/retell/_version.py +++ b/src/retell/_version.py @@ -1,4 +1,4 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. __title__ = "retell" -__version__ = "4.32.0" # x-release-please-version +__version__ = "4.33.0" # x-release-please-version diff --git a/src/retell/resources/call.py b/src/retell/resources/call.py index 53a19741..ded37327 100644 --- a/src/retell/resources/call.py +++ b/src/retell/resources/call.py @@ -103,7 +103,7 @@ def update( timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, ) -> CallResponse: """ - Update metadata and sensitive data storage settings for an existing call + Update metadata and sensitive data storage settings for an existing call. Args: metadata: An arbitrary object for storage purpose only. You can put anything here like @@ -494,7 +494,7 @@ async def update( timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, ) -> CallResponse: """ - Update metadata and sensitive data storage settings for an existing call + Update metadata and sensitive data storage settings for an existing call. Args: metadata: An arbitrary object for storage purpose only. You can put anything here like diff --git a/src/retell/types/chat_create_chat_completion_response.py b/src/retell/types/chat_create_chat_completion_response.py index 161c43d3..c681dca3 100644 --- a/src/retell/types/chat_create_chat_completion_response.py +++ b/src/retell/types/chat_create_chat_completion_response.py @@ -118,4 +118,8 @@ class MessageStateTransitionMessage(BaseModel): class ChatCreateChatCompletionResponse(BaseModel): messages: List[Message] - """Transcript of the chat completion weaved with tool call invocation and results.""" + """ + New messages generated by the agent during this completion, including any tool + call invocations and their results. Does not include the original input + messages. + """ diff --git a/src/retell/types/llm_create_params.py b/src/retell/types/llm_create_params.py index beeb76f2..cbc3dd1a 100644 --- a/src/retell/types/llm_create_params.py +++ b/src/retell/types/llm_create_params.py @@ -13,9 +13,12 @@ "GeneralToolTransferCallToolTransferDestination", "GeneralToolTransferCallToolTransferDestinationTransferDestinationPredefined", "GeneralToolTransferCallToolTransferDestinationTransferDestinationInferred", - "GeneralToolTransferCallToolWarmTransferOption", - "GeneralToolTransferCallToolWarmTransferOptionWarmTransferPrompt", - "GeneralToolTransferCallToolWarmTransferOptionWarmTransferStaticMessage", + "GeneralToolTransferCallToolTransferOption", + "GeneralToolTransferCallToolTransferOptionTransferOptionColdTransfer", + "GeneralToolTransferCallToolTransferOptionTransferOptionWarmTransfer", + "GeneralToolTransferCallToolTransferOptionTransferOptionWarmTransferPublicHandoffOption", + "GeneralToolTransferCallToolTransferOptionTransferOptionWarmTransferPublicHandoffOptionWarmTransferPrompt", + "GeneralToolTransferCallToolTransferOptionTransferOptionWarmTransferPublicHandoffOptionWarmTransferStaticMessage", "GeneralToolCheckAvailabilityCalTool", "GeneralToolBookAppointmentCalTool", "GeneralToolPressDigitTool", @@ -30,9 +33,12 @@ "StateToolTransferCallToolTransferDestination", "StateToolTransferCallToolTransferDestinationTransferDestinationPredefined", "StateToolTransferCallToolTransferDestinationTransferDestinationInferred", - "StateToolTransferCallToolWarmTransferOption", - "StateToolTransferCallToolWarmTransferOptionWarmTransferPrompt", - "StateToolTransferCallToolWarmTransferOptionWarmTransferStaticMessage", + "StateToolTransferCallToolTransferOption", + "StateToolTransferCallToolTransferOptionTransferOptionColdTransfer", + "StateToolTransferCallToolTransferOptionTransferOptionWarmTransfer", + "StateToolTransferCallToolTransferOptionTransferOptionWarmTransferPublicHandoffOption", + "StateToolTransferCallToolTransferOptionTransferOptionWarmTransferPublicHandoffOptionWarmTransferPrompt", + "StateToolTransferCallToolTransferOptionTransferOptionWarmTransferPublicHandoffOptionWarmTransferStaticMessage", "StateToolCheckAvailabilityCalTool", "StateToolBookAppointmentCalTool", "StateToolPressDigitTool", @@ -190,23 +196,58 @@ class GeneralToolTransferCallToolTransferDestinationTransferDestinationInferred( ] -class GeneralToolTransferCallToolWarmTransferOptionWarmTransferPrompt(TypedDict, total=False): +class GeneralToolTransferCallToolTransferOptionTransferOptionColdTransfer(TypedDict, total=False): + show_transferee_as_caller: Required[bool] + """ + If set to true, will show transferee (the user, not the AI agent) as caller when + transferring, requires the telephony side to support SIP REFER to PSTN. This is + only applicable for cold transfer, so if warm transfer option is specified, this + field will be ignored. Default to false (default to show AI agent as caller). + """ + + type: Required[Literal["cold_transfer"]] + """The type of the transfer.""" + + +class GeneralToolTransferCallToolTransferOptionTransferOptionWarmTransferPublicHandoffOptionWarmTransferPrompt( + TypedDict, total=False +): prompt: str """The prompt to be used for warm handoff. Can contain dynamic variables.""" type: Literal["prompt"] -class GeneralToolTransferCallToolWarmTransferOptionWarmTransferStaticMessage(TypedDict, total=False): +class GeneralToolTransferCallToolTransferOptionTransferOptionWarmTransferPublicHandoffOptionWarmTransferStaticMessage( + TypedDict, total=False +): message: str """The static message to be used for warm handoff. Can contain dynamic variables.""" type: Literal["static_message"] -GeneralToolTransferCallToolWarmTransferOption: TypeAlias = Union[ - GeneralToolTransferCallToolWarmTransferOptionWarmTransferPrompt, - GeneralToolTransferCallToolWarmTransferOptionWarmTransferStaticMessage, +GeneralToolTransferCallToolTransferOptionTransferOptionWarmTransferPublicHandoffOption: TypeAlias = Union[ + GeneralToolTransferCallToolTransferOptionTransferOptionWarmTransferPublicHandoffOptionWarmTransferPrompt, + GeneralToolTransferCallToolTransferOptionTransferOptionWarmTransferPublicHandoffOptionWarmTransferStaticMessage, +] + + +class GeneralToolTransferCallToolTransferOptionTransferOptionWarmTransfer(TypedDict, total=False): + type: Required[Literal["warm_transfer"]] + """The type of the transfer.""" + + public_handoff_option: GeneralToolTransferCallToolTransferOptionTransferOptionWarmTransferPublicHandoffOption + """ + If set, when transfer is successful, will say the handoff message to both the + transferee and the agent receiving the transfer. Can leave either a static + message or a dynamic one based on prompt. Set to null to disable warm handoff. + """ + + +GeneralToolTransferCallToolTransferOption: TypeAlias = Union[ + GeneralToolTransferCallToolTransferOptionTransferOptionColdTransfer, + GeneralToolTransferCallToolTransferOptionTransferOptionWarmTransfer, ] @@ -220,6 +261,8 @@ class GeneralToolTransferCallTool(TypedDict, total=False): transfer_destination: Required[GeneralToolTransferCallToolTransferDestination] + transfer_option: Required[GeneralToolTransferCallToolTransferOption] + type: Required[Literal["transfer_call"]] description: str @@ -228,21 +271,6 @@ class GeneralToolTransferCallTool(TypedDict, total=False): to call the tool. """ - show_transferee_as_caller: Optional[bool] - """ - If set to true, will show transferee (the user, not the AI agent) as caller when - transferring, requires the telephony side to support SIP REFER to PSTN. This is - only applicable for cold transfer, so if warm transfer option is specified, this - field will be ignored. Default to false (default to show AI agent as caller). - """ - - warm_transfer_option: Optional[GeneralToolTransferCallToolWarmTransferOption] - """If set, when transfer is successful, will perform a warm handoff. - - Can leave either a static message or a dynamic one based on prompt. Set to null - to disable warm handoff. - """ - class GeneralToolCheckAvailabilityCalTool(TypedDict, total=False): cal_api_key: Required[str] @@ -525,23 +553,58 @@ class StateToolTransferCallToolTransferDestinationTransferDestinationInferred(Ty ] -class StateToolTransferCallToolWarmTransferOptionWarmTransferPrompt(TypedDict, total=False): +class StateToolTransferCallToolTransferOptionTransferOptionColdTransfer(TypedDict, total=False): + show_transferee_as_caller: Required[bool] + """ + If set to true, will show transferee (the user, not the AI agent) as caller when + transferring, requires the telephony side to support SIP REFER to PSTN. This is + only applicable for cold transfer, so if warm transfer option is specified, this + field will be ignored. Default to false (default to show AI agent as caller). + """ + + type: Required[Literal["cold_transfer"]] + """The type of the transfer.""" + + +class StateToolTransferCallToolTransferOptionTransferOptionWarmTransferPublicHandoffOptionWarmTransferPrompt( + TypedDict, total=False +): prompt: str """The prompt to be used for warm handoff. Can contain dynamic variables.""" type: Literal["prompt"] -class StateToolTransferCallToolWarmTransferOptionWarmTransferStaticMessage(TypedDict, total=False): +class StateToolTransferCallToolTransferOptionTransferOptionWarmTransferPublicHandoffOptionWarmTransferStaticMessage( + TypedDict, total=False +): message: str """The static message to be used for warm handoff. Can contain dynamic variables.""" type: Literal["static_message"] -StateToolTransferCallToolWarmTransferOption: TypeAlias = Union[ - StateToolTransferCallToolWarmTransferOptionWarmTransferPrompt, - StateToolTransferCallToolWarmTransferOptionWarmTransferStaticMessage, +StateToolTransferCallToolTransferOptionTransferOptionWarmTransferPublicHandoffOption: TypeAlias = Union[ + StateToolTransferCallToolTransferOptionTransferOptionWarmTransferPublicHandoffOptionWarmTransferPrompt, + StateToolTransferCallToolTransferOptionTransferOptionWarmTransferPublicHandoffOptionWarmTransferStaticMessage, +] + + +class StateToolTransferCallToolTransferOptionTransferOptionWarmTransfer(TypedDict, total=False): + type: Required[Literal["warm_transfer"]] + """The type of the transfer.""" + + public_handoff_option: StateToolTransferCallToolTransferOptionTransferOptionWarmTransferPublicHandoffOption + """ + If set, when transfer is successful, will say the handoff message to both the + transferee and the agent receiving the transfer. Can leave either a static + message or a dynamic one based on prompt. Set to null to disable warm handoff. + """ + + +StateToolTransferCallToolTransferOption: TypeAlias = Union[ + StateToolTransferCallToolTransferOptionTransferOptionColdTransfer, + StateToolTransferCallToolTransferOptionTransferOptionWarmTransfer, ] @@ -555,6 +618,8 @@ class StateToolTransferCallTool(TypedDict, total=False): transfer_destination: Required[StateToolTransferCallToolTransferDestination] + transfer_option: Required[StateToolTransferCallToolTransferOption] + type: Required[Literal["transfer_call"]] description: str @@ -563,21 +628,6 @@ class StateToolTransferCallTool(TypedDict, total=False): to call the tool. """ - show_transferee_as_caller: Optional[bool] - """ - If set to true, will show transferee (the user, not the AI agent) as caller when - transferring, requires the telephony side to support SIP REFER to PSTN. This is - only applicable for cold transfer, so if warm transfer option is specified, this - field will be ignored. Default to false (default to show AI agent as caller). - """ - - warm_transfer_option: Optional[StateToolTransferCallToolWarmTransferOption] - """If set, when transfer is successful, will perform a warm handoff. - - Can leave either a static message or a dynamic one based on prompt. Set to null - to disable warm handoff. - """ - class StateToolCheckAvailabilityCalTool(TypedDict, total=False): cal_api_key: Required[str] diff --git a/src/retell/types/llm_response.py b/src/retell/types/llm_response.py index 0096d4e7..7e912da6 100644 --- a/src/retell/types/llm_response.py +++ b/src/retell/types/llm_response.py @@ -15,9 +15,12 @@ "GeneralToolTransferCallToolTransferDestination", "GeneralToolTransferCallToolTransferDestinationTransferDestinationPredefined", "GeneralToolTransferCallToolTransferDestinationTransferDestinationInferred", - "GeneralToolTransferCallToolWarmTransferOption", - "GeneralToolTransferCallToolWarmTransferOptionWarmTransferPrompt", - "GeneralToolTransferCallToolWarmTransferOptionWarmTransferStaticMessage", + "GeneralToolTransferCallToolTransferOption", + "GeneralToolTransferCallToolTransferOptionTransferOptionColdTransfer", + "GeneralToolTransferCallToolTransferOptionTransferOptionWarmTransfer", + "GeneralToolTransferCallToolTransferOptionTransferOptionWarmTransferPublicHandoffOption", + "GeneralToolTransferCallToolTransferOptionTransferOptionWarmTransferPublicHandoffOptionWarmTransferPrompt", + "GeneralToolTransferCallToolTransferOptionTransferOptionWarmTransferPublicHandoffOptionWarmTransferStaticMessage", "GeneralToolCheckAvailabilityCalTool", "GeneralToolBookAppointmentCalTool", "GeneralToolPressDigitTool", @@ -32,9 +35,12 @@ "StateToolTransferCallToolTransferDestination", "StateToolTransferCallToolTransferDestinationTransferDestinationPredefined", "StateToolTransferCallToolTransferDestinationTransferDestinationInferred", - "StateToolTransferCallToolWarmTransferOption", - "StateToolTransferCallToolWarmTransferOptionWarmTransferPrompt", - "StateToolTransferCallToolWarmTransferOptionWarmTransferStaticMessage", + "StateToolTransferCallToolTransferOption", + "StateToolTransferCallToolTransferOptionTransferOptionColdTransfer", + "StateToolTransferCallToolTransferOptionTransferOptionWarmTransfer", + "StateToolTransferCallToolTransferOptionTransferOptionWarmTransferPublicHandoffOption", + "StateToolTransferCallToolTransferOptionTransferOptionWarmTransferPublicHandoffOptionWarmTransferPrompt", + "StateToolTransferCallToolTransferOptionTransferOptionWarmTransferPublicHandoffOptionWarmTransferStaticMessage", "StateToolCheckAvailabilityCalTool", "StateToolBookAppointmentCalTool", "StateToolPressDigitTool", @@ -91,24 +97,60 @@ class GeneralToolTransferCallToolTransferDestinationTransferDestinationInferred( ] -class GeneralToolTransferCallToolWarmTransferOptionWarmTransferPrompt(BaseModel): +class GeneralToolTransferCallToolTransferOptionTransferOptionColdTransfer(BaseModel): + show_transferee_as_caller: bool + """ + If set to true, will show transferee (the user, not the AI agent) as caller when + transferring, requires the telephony side to support SIP REFER to PSTN. This is + only applicable for cold transfer, so if warm transfer option is specified, this + field will be ignored. Default to false (default to show AI agent as caller). + """ + + type: Literal["cold_transfer"] + """The type of the transfer.""" + + +class GeneralToolTransferCallToolTransferOptionTransferOptionWarmTransferPublicHandoffOptionWarmTransferPrompt( + BaseModel +): prompt: Optional[str] = None """The prompt to be used for warm handoff. Can contain dynamic variables.""" type: Optional[Literal["prompt"]] = None -class GeneralToolTransferCallToolWarmTransferOptionWarmTransferStaticMessage(BaseModel): +class GeneralToolTransferCallToolTransferOptionTransferOptionWarmTransferPublicHandoffOptionWarmTransferStaticMessage( + BaseModel +): message: Optional[str] = None """The static message to be used for warm handoff. Can contain dynamic variables.""" type: Optional[Literal["static_message"]] = None -GeneralToolTransferCallToolWarmTransferOption: TypeAlias = Union[ - GeneralToolTransferCallToolWarmTransferOptionWarmTransferPrompt, - GeneralToolTransferCallToolWarmTransferOptionWarmTransferStaticMessage, - None, +GeneralToolTransferCallToolTransferOptionTransferOptionWarmTransferPublicHandoffOption: TypeAlias = Union[ + GeneralToolTransferCallToolTransferOptionTransferOptionWarmTransferPublicHandoffOptionWarmTransferPrompt, + GeneralToolTransferCallToolTransferOptionTransferOptionWarmTransferPublicHandoffOptionWarmTransferStaticMessage, +] + + +class GeneralToolTransferCallToolTransferOptionTransferOptionWarmTransfer(BaseModel): + type: Literal["warm_transfer"] + """The type of the transfer.""" + + public_handoff_option: Optional[ + GeneralToolTransferCallToolTransferOptionTransferOptionWarmTransferPublicHandoffOption + ] = None + """ + If set, when transfer is successful, will say the handoff message to both the + transferee and the agent receiving the transfer. Can leave either a static + message or a dynamic one based on prompt. Set to null to disable warm handoff. + """ + + +GeneralToolTransferCallToolTransferOption: TypeAlias = Union[ + GeneralToolTransferCallToolTransferOptionTransferOptionColdTransfer, + GeneralToolTransferCallToolTransferOptionTransferOptionWarmTransfer, ] @@ -122,6 +164,8 @@ class GeneralToolTransferCallTool(BaseModel): transfer_destination: GeneralToolTransferCallToolTransferDestination + transfer_option: GeneralToolTransferCallToolTransferOption + type: Literal["transfer_call"] description: Optional[str] = None @@ -130,21 +174,6 @@ class GeneralToolTransferCallTool(BaseModel): to call the tool. """ - show_transferee_as_caller: Optional[bool] = None - """ - If set to true, will show transferee (the user, not the AI agent) as caller when - transferring, requires the telephony side to support SIP REFER to PSTN. This is - only applicable for cold transfer, so if warm transfer option is specified, this - field will be ignored. Default to false (default to show AI agent as caller). - """ - - warm_transfer_option: Optional[GeneralToolTransferCallToolWarmTransferOption] = None - """If set, when transfer is successful, will perform a warm handoff. - - Can leave either a static message or a dynamic one based on prompt. Set to null - to disable warm handoff. - """ - class GeneralToolCheckAvailabilityCalTool(BaseModel): cal_api_key: str @@ -427,24 +456,58 @@ class StateToolTransferCallToolTransferDestinationTransferDestinationInferred(Ba ] -class StateToolTransferCallToolWarmTransferOptionWarmTransferPrompt(BaseModel): +class StateToolTransferCallToolTransferOptionTransferOptionColdTransfer(BaseModel): + show_transferee_as_caller: bool + """ + If set to true, will show transferee (the user, not the AI agent) as caller when + transferring, requires the telephony side to support SIP REFER to PSTN. This is + only applicable for cold transfer, so if warm transfer option is specified, this + field will be ignored. Default to false (default to show AI agent as caller). + """ + + type: Literal["cold_transfer"] + """The type of the transfer.""" + + +class StateToolTransferCallToolTransferOptionTransferOptionWarmTransferPublicHandoffOptionWarmTransferPrompt(BaseModel): prompt: Optional[str] = None """The prompt to be used for warm handoff. Can contain dynamic variables.""" type: Optional[Literal["prompt"]] = None -class StateToolTransferCallToolWarmTransferOptionWarmTransferStaticMessage(BaseModel): +class StateToolTransferCallToolTransferOptionTransferOptionWarmTransferPublicHandoffOptionWarmTransferStaticMessage( + BaseModel +): message: Optional[str] = None """The static message to be used for warm handoff. Can contain dynamic variables.""" type: Optional[Literal["static_message"]] = None -StateToolTransferCallToolWarmTransferOption: TypeAlias = Union[ - StateToolTransferCallToolWarmTransferOptionWarmTransferPrompt, - StateToolTransferCallToolWarmTransferOptionWarmTransferStaticMessage, - None, +StateToolTransferCallToolTransferOptionTransferOptionWarmTransferPublicHandoffOption: TypeAlias = Union[ + StateToolTransferCallToolTransferOptionTransferOptionWarmTransferPublicHandoffOptionWarmTransferPrompt, + StateToolTransferCallToolTransferOptionTransferOptionWarmTransferPublicHandoffOptionWarmTransferStaticMessage, +] + + +class StateToolTransferCallToolTransferOptionTransferOptionWarmTransfer(BaseModel): + type: Literal["warm_transfer"] + """The type of the transfer.""" + + public_handoff_option: Optional[ + StateToolTransferCallToolTransferOptionTransferOptionWarmTransferPublicHandoffOption + ] = None + """ + If set, when transfer is successful, will say the handoff message to both the + transferee and the agent receiving the transfer. Can leave either a static + message or a dynamic one based on prompt. Set to null to disable warm handoff. + """ + + +StateToolTransferCallToolTransferOption: TypeAlias = Union[ + StateToolTransferCallToolTransferOptionTransferOptionColdTransfer, + StateToolTransferCallToolTransferOptionTransferOptionWarmTransfer, ] @@ -458,6 +521,8 @@ class StateToolTransferCallTool(BaseModel): transfer_destination: StateToolTransferCallToolTransferDestination + transfer_option: StateToolTransferCallToolTransferOption + type: Literal["transfer_call"] description: Optional[str] = None @@ -466,21 +531,6 @@ class StateToolTransferCallTool(BaseModel): to call the tool. """ - show_transferee_as_caller: Optional[bool] = None - """ - If set to true, will show transferee (the user, not the AI agent) as caller when - transferring, requires the telephony side to support SIP REFER to PSTN. This is - only applicable for cold transfer, so if warm transfer option is specified, this - field will be ignored. Default to false (default to show AI agent as caller). - """ - - warm_transfer_option: Optional[StateToolTransferCallToolWarmTransferOption] = None - """If set, when transfer is successful, will perform a warm handoff. - - Can leave either a static message or a dynamic one based on prompt. Set to null - to disable warm handoff. - """ - class StateToolCheckAvailabilityCalTool(BaseModel): cal_api_key: str diff --git a/src/retell/types/llm_update_params.py b/src/retell/types/llm_update_params.py index 152c20b9..28057e80 100644 --- a/src/retell/types/llm_update_params.py +++ b/src/retell/types/llm_update_params.py @@ -15,9 +15,12 @@ "GeneralToolTransferCallToolTransferDestination", "GeneralToolTransferCallToolTransferDestinationTransferDestinationPredefined", "GeneralToolTransferCallToolTransferDestinationTransferDestinationInferred", - "GeneralToolTransferCallToolWarmTransferOption", - "GeneralToolTransferCallToolWarmTransferOptionWarmTransferPrompt", - "GeneralToolTransferCallToolWarmTransferOptionWarmTransferStaticMessage", + "GeneralToolTransferCallToolTransferOption", + "GeneralToolTransferCallToolTransferOptionTransferOptionColdTransfer", + "GeneralToolTransferCallToolTransferOptionTransferOptionWarmTransfer", + "GeneralToolTransferCallToolTransferOptionTransferOptionWarmTransferPublicHandoffOption", + "GeneralToolTransferCallToolTransferOptionTransferOptionWarmTransferPublicHandoffOptionWarmTransferPrompt", + "GeneralToolTransferCallToolTransferOptionTransferOptionWarmTransferPublicHandoffOptionWarmTransferStaticMessage", "GeneralToolCheckAvailabilityCalTool", "GeneralToolBookAppointmentCalTool", "GeneralToolPressDigitTool", @@ -32,9 +35,12 @@ "StateToolTransferCallToolTransferDestination", "StateToolTransferCallToolTransferDestinationTransferDestinationPredefined", "StateToolTransferCallToolTransferDestinationTransferDestinationInferred", - "StateToolTransferCallToolWarmTransferOption", - "StateToolTransferCallToolWarmTransferOptionWarmTransferPrompt", - "StateToolTransferCallToolWarmTransferOptionWarmTransferStaticMessage", + "StateToolTransferCallToolTransferOption", + "StateToolTransferCallToolTransferOptionTransferOptionColdTransfer", + "StateToolTransferCallToolTransferOptionTransferOptionWarmTransfer", + "StateToolTransferCallToolTransferOptionTransferOptionWarmTransferPublicHandoffOption", + "StateToolTransferCallToolTransferOptionTransferOptionWarmTransferPublicHandoffOptionWarmTransferPrompt", + "StateToolTransferCallToolTransferOptionTransferOptionWarmTransferPublicHandoffOptionWarmTransferStaticMessage", "StateToolCheckAvailabilityCalTool", "StateToolBookAppointmentCalTool", "StateToolPressDigitTool", @@ -195,23 +201,58 @@ class GeneralToolTransferCallToolTransferDestinationTransferDestinationInferred( ] -class GeneralToolTransferCallToolWarmTransferOptionWarmTransferPrompt(TypedDict, total=False): +class GeneralToolTransferCallToolTransferOptionTransferOptionColdTransfer(TypedDict, total=False): + show_transferee_as_caller: Required[bool] + """ + If set to true, will show transferee (the user, not the AI agent) as caller when + transferring, requires the telephony side to support SIP REFER to PSTN. This is + only applicable for cold transfer, so if warm transfer option is specified, this + field will be ignored. Default to false (default to show AI agent as caller). + """ + + type: Required[Literal["cold_transfer"]] + """The type of the transfer.""" + + +class GeneralToolTransferCallToolTransferOptionTransferOptionWarmTransferPublicHandoffOptionWarmTransferPrompt( + TypedDict, total=False +): prompt: str """The prompt to be used for warm handoff. Can contain dynamic variables.""" type: Literal["prompt"] -class GeneralToolTransferCallToolWarmTransferOptionWarmTransferStaticMessage(TypedDict, total=False): +class GeneralToolTransferCallToolTransferOptionTransferOptionWarmTransferPublicHandoffOptionWarmTransferStaticMessage( + TypedDict, total=False +): message: str """The static message to be used for warm handoff. Can contain dynamic variables.""" type: Literal["static_message"] -GeneralToolTransferCallToolWarmTransferOption: TypeAlias = Union[ - GeneralToolTransferCallToolWarmTransferOptionWarmTransferPrompt, - GeneralToolTransferCallToolWarmTransferOptionWarmTransferStaticMessage, +GeneralToolTransferCallToolTransferOptionTransferOptionWarmTransferPublicHandoffOption: TypeAlias = Union[ + GeneralToolTransferCallToolTransferOptionTransferOptionWarmTransferPublicHandoffOptionWarmTransferPrompt, + GeneralToolTransferCallToolTransferOptionTransferOptionWarmTransferPublicHandoffOptionWarmTransferStaticMessage, +] + + +class GeneralToolTransferCallToolTransferOptionTransferOptionWarmTransfer(TypedDict, total=False): + type: Required[Literal["warm_transfer"]] + """The type of the transfer.""" + + public_handoff_option: GeneralToolTransferCallToolTransferOptionTransferOptionWarmTransferPublicHandoffOption + """ + If set, when transfer is successful, will say the handoff message to both the + transferee and the agent receiving the transfer. Can leave either a static + message or a dynamic one based on prompt. Set to null to disable warm handoff. + """ + + +GeneralToolTransferCallToolTransferOption: TypeAlias = Union[ + GeneralToolTransferCallToolTransferOptionTransferOptionColdTransfer, + GeneralToolTransferCallToolTransferOptionTransferOptionWarmTransfer, ] @@ -225,6 +266,8 @@ class GeneralToolTransferCallTool(TypedDict, total=False): transfer_destination: Required[GeneralToolTransferCallToolTransferDestination] + transfer_option: Required[GeneralToolTransferCallToolTransferOption] + type: Required[Literal["transfer_call"]] description: str @@ -233,21 +276,6 @@ class GeneralToolTransferCallTool(TypedDict, total=False): to call the tool. """ - show_transferee_as_caller: Optional[bool] - """ - If set to true, will show transferee (the user, not the AI agent) as caller when - transferring, requires the telephony side to support SIP REFER to PSTN. This is - only applicable for cold transfer, so if warm transfer option is specified, this - field will be ignored. Default to false (default to show AI agent as caller). - """ - - warm_transfer_option: Optional[GeneralToolTransferCallToolWarmTransferOption] - """If set, when transfer is successful, will perform a warm handoff. - - Can leave either a static message or a dynamic one based on prompt. Set to null - to disable warm handoff. - """ - class GeneralToolCheckAvailabilityCalTool(TypedDict, total=False): cal_api_key: Required[str] @@ -530,23 +558,58 @@ class StateToolTransferCallToolTransferDestinationTransferDestinationInferred(Ty ] -class StateToolTransferCallToolWarmTransferOptionWarmTransferPrompt(TypedDict, total=False): +class StateToolTransferCallToolTransferOptionTransferOptionColdTransfer(TypedDict, total=False): + show_transferee_as_caller: Required[bool] + """ + If set to true, will show transferee (the user, not the AI agent) as caller when + transferring, requires the telephony side to support SIP REFER to PSTN. This is + only applicable for cold transfer, so if warm transfer option is specified, this + field will be ignored. Default to false (default to show AI agent as caller). + """ + + type: Required[Literal["cold_transfer"]] + """The type of the transfer.""" + + +class StateToolTransferCallToolTransferOptionTransferOptionWarmTransferPublicHandoffOptionWarmTransferPrompt( + TypedDict, total=False +): prompt: str """The prompt to be used for warm handoff. Can contain dynamic variables.""" type: Literal["prompt"] -class StateToolTransferCallToolWarmTransferOptionWarmTransferStaticMessage(TypedDict, total=False): +class StateToolTransferCallToolTransferOptionTransferOptionWarmTransferPublicHandoffOptionWarmTransferStaticMessage( + TypedDict, total=False +): message: str """The static message to be used for warm handoff. Can contain dynamic variables.""" type: Literal["static_message"] -StateToolTransferCallToolWarmTransferOption: TypeAlias = Union[ - StateToolTransferCallToolWarmTransferOptionWarmTransferPrompt, - StateToolTransferCallToolWarmTransferOptionWarmTransferStaticMessage, +StateToolTransferCallToolTransferOptionTransferOptionWarmTransferPublicHandoffOption: TypeAlias = Union[ + StateToolTransferCallToolTransferOptionTransferOptionWarmTransferPublicHandoffOptionWarmTransferPrompt, + StateToolTransferCallToolTransferOptionTransferOptionWarmTransferPublicHandoffOptionWarmTransferStaticMessage, +] + + +class StateToolTransferCallToolTransferOptionTransferOptionWarmTransfer(TypedDict, total=False): + type: Required[Literal["warm_transfer"]] + """The type of the transfer.""" + + public_handoff_option: StateToolTransferCallToolTransferOptionTransferOptionWarmTransferPublicHandoffOption + """ + If set, when transfer is successful, will say the handoff message to both the + transferee and the agent receiving the transfer. Can leave either a static + message or a dynamic one based on prompt. Set to null to disable warm handoff. + """ + + +StateToolTransferCallToolTransferOption: TypeAlias = Union[ + StateToolTransferCallToolTransferOptionTransferOptionColdTransfer, + StateToolTransferCallToolTransferOptionTransferOptionWarmTransfer, ] @@ -560,6 +623,8 @@ class StateToolTransferCallTool(TypedDict, total=False): transfer_destination: Required[StateToolTransferCallToolTransferDestination] + transfer_option: Required[StateToolTransferCallToolTransferOption] + type: Required[Literal["transfer_call"]] description: str @@ -568,21 +633,6 @@ class StateToolTransferCallTool(TypedDict, total=False): to call the tool. """ - show_transferee_as_caller: Optional[bool] - """ - If set to true, will show transferee (the user, not the AI agent) as caller when - transferring, requires the telephony side to support SIP REFER to PSTN. This is - only applicable for cold transfer, so if warm transfer option is specified, this - field will be ignored. Default to false (default to show AI agent as caller). - """ - - warm_transfer_option: Optional[StateToolTransferCallToolWarmTransferOption] - """If set, when transfer is successful, will perform a warm handoff. - - Can leave either a static message or a dynamic one based on prompt. Set to null - to disable warm handoff. - """ - class StateToolCheckAvailabilityCalTool(TypedDict, total=False): cal_api_key: Required[str] diff --git a/src/retell/types/phone_call_response.py b/src/retell/types/phone_call_response.py index ba02a004..18b65bfc 100644 --- a/src/retell/types/phone_call_response.py +++ b/src/retell/types/phone_call_response.py @@ -497,6 +497,16 @@ class PhoneCallResponse(BaseModel): Available after call ends. """ + knowledge_base_retrieved_contents_url: Optional[str] = None + """URL to the knowledge base retrieved contents of the call. + + Available after call ends if the call utilizes knowledge base feature. It + consists of the respond id and the retrieved contents related to that response. + It's already rendered in call history tab of dashboard, and you can also + manually download and check against the transcript to view the knowledge base + retrieval results. + """ + latency: Optional[Latency] = None """Latency tracking of the call, available after call ends. diff --git a/src/retell/types/web_call_response.py b/src/retell/types/web_call_response.py index 161cf968..54758acd 100644 --- a/src/retell/types/web_call_response.py +++ b/src/retell/types/web_call_response.py @@ -488,6 +488,16 @@ class WebCallResponse(BaseModel): Available after call ends. """ + knowledge_base_retrieved_contents_url: Optional[str] = None + """URL to the knowledge base retrieved contents of the call. + + Available after call ends if the call utilizes knowledge base feature. It + consists of the respond id and the retrieved contents related to that response. + It's already rendered in call history tab of dashboard, and you can also + manually download and check against the transcript to view the knowledge base + retrieval results. + """ + latency: Optional[Latency] = None """Latency tracking of the call, available after call ends. diff --git a/tests/api_resources/test_llm.py b/tests/api_resources/test_llm.py index 4f03c13f..6d92e509 100644 --- a/tests/api_resources/test_llm.py +++ b/tests/api_resources/test_llm.py @@ -59,17 +59,8 @@ def test_method_create_with_all_params(self, client: Retell) -> None: "tools": [ { "name": "transfer_to_support", - "transfer_destination": { - "number": "16175551212", - "type": "predefined", - }, - "type": "transfer_call", + "type": "end_call", "description": "Transfer to the support team.", - "show_transferee_as_caller": True, - "warm_transfer_option": { - "prompt": "Summarize the call in one sentence for the warn handoff.", - "type": "prompt", - }, } ], }, @@ -216,17 +207,8 @@ def test_method_update_with_all_params(self, client: Retell) -> None: "tools": [ { "name": "transfer_to_support", - "transfer_destination": { - "number": "16175551212", - "type": "predefined", - }, - "type": "transfer_call", + "type": "end_call", "description": "Transfer to the support team.", - "show_transferee_as_caller": True, - "warm_transfer_option": { - "prompt": "Summarize the call in one sentence for the warn handoff.", - "type": "prompt", - }, } ], }, @@ -401,17 +383,8 @@ async def test_method_create_with_all_params(self, async_client: AsyncRetell) -> "tools": [ { "name": "transfer_to_support", - "transfer_destination": { - "number": "16175551212", - "type": "predefined", - }, - "type": "transfer_call", + "type": "end_call", "description": "Transfer to the support team.", - "show_transferee_as_caller": True, - "warm_transfer_option": { - "prompt": "Summarize the call in one sentence for the warn handoff.", - "type": "prompt", - }, } ], }, @@ -558,17 +531,8 @@ async def test_method_update_with_all_params(self, async_client: AsyncRetell) -> "tools": [ { "name": "transfer_to_support", - "transfer_destination": { - "number": "16175551212", - "type": "predefined", - }, - "type": "transfer_call", + "type": "end_call", "description": "Transfer to the support team.", - "show_transferee_as_caller": True, - "warm_transfer_option": { - "prompt": "Summarize the call in one sentence for the warn handoff.", - "type": "prompt", - }, } ], }, diff --git a/tests/test_client.py b/tests/test_client.py index aa7d0af4..528a649c 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -846,6 +846,33 @@ def retry_handler(_request: httpx.Request) -> httpx.Response: assert response.http_request.headers.get("x-stainless-retry-count") == "42" + @pytest.mark.respx(base_url=base_url) + def test_follow_redirects(self, respx_mock: MockRouter) -> None: + # Test that the default follow_redirects=True allows following redirects + respx_mock.post("/redirect").mock( + return_value=httpx.Response(302, headers={"Location": f"{base_url}/redirected"}) + ) + respx_mock.get("/redirected").mock(return_value=httpx.Response(200, json={"status": "ok"})) + + response = self.client.post("/redirect", body={"key": "value"}, cast_to=httpx.Response) + assert response.status_code == 200 + assert response.json() == {"status": "ok"} + + @pytest.mark.respx(base_url=base_url) + def test_follow_redirects_disabled(self, respx_mock: MockRouter) -> None: + # Test that follow_redirects=False prevents following redirects + respx_mock.post("/redirect").mock( + return_value=httpx.Response(302, headers={"Location": f"{base_url}/redirected"}) + ) + + with pytest.raises(APIStatusError) as exc_info: + self.client.post( + "/redirect", body={"key": "value"}, options={"follow_redirects": False}, cast_to=httpx.Response + ) + + assert exc_info.value.response.status_code == 302 + assert exc_info.value.response.headers["Location"] == f"{base_url}/redirected" + class TestAsyncRetell: client = AsyncRetell(base_url=base_url, api_key=api_key, _strict_response_validation=True) @@ -1704,3 +1731,30 @@ async def test_main() -> None: raise AssertionError("calling get_platform using asyncify resulted in a hung process") time.sleep(0.1) + + @pytest.mark.respx(base_url=base_url) + async def test_follow_redirects(self, respx_mock: MockRouter) -> None: + # Test that the default follow_redirects=True allows following redirects + respx_mock.post("/redirect").mock( + return_value=httpx.Response(302, headers={"Location": f"{base_url}/redirected"}) + ) + respx_mock.get("/redirected").mock(return_value=httpx.Response(200, json={"status": "ok"})) + + response = await self.client.post("/redirect", body={"key": "value"}, cast_to=httpx.Response) + assert response.status_code == 200 + assert response.json() == {"status": "ok"} + + @pytest.mark.respx(base_url=base_url) + async def test_follow_redirects_disabled(self, respx_mock: MockRouter) -> None: + # Test that follow_redirects=False prevents following redirects + respx_mock.post("/redirect").mock( + return_value=httpx.Response(302, headers={"Location": f"{base_url}/redirected"}) + ) + + with pytest.raises(APIStatusError) as exc_info: + await self.client.post( + "/redirect", body={"key": "value"}, options={"follow_redirects": False}, cast_to=httpx.Response + ) + + assert exc_info.value.response.status_code == 302 + assert exc_info.value.response.headers["Location"] == f"{base_url}/redirected"