diff --git a/.release-please-manifest.json b/.release-please-manifest.json
index ba2c94bf..a95c8527 100644
--- a/.release-please-manifest.json
+++ b/.release-please-manifest.json
@@ -1,3 +1,3 @@
{
- ".": "4.30.0"
+ ".": "4.31.0"
}
\ No newline at end of file
diff --git a/.stats.yml b/.stats.yml
index 30033785..5d83c560 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
-configured_endpoints: 34
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/retell%2Ftoddlzt-633b45cdafc58dc79176efac962c92d1ccd20ce82aebf4bb2ceae65954fbc9da.yml
-openapi_spec_hash: ac81b4183a73b711bb9e646027f2998c
-config_hash: 9d9a24bf8bb4553cbb30ce59eb910b2f
+configured_endpoints: 39
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/retell%2Ftoddlzt-33c92a2f7908f82088c3cad1076ac008f22cc41d25cbdbcd23b005bfd5e5ab3d.yml
+openapi_spec_hash: 3df26020335431e67fdaa9c3865a6a81
+config_hash: f4bc63f2350a2a4988750b41a0737f9d
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4656c76f..8e7d4995 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,18 @@
# Changelog
+## 4.31.0 (2025-05-22)
+
+Full Changelog: [v4.30.0...v4.31.0](https://github.com/RetellAI/retell-python-sdk/compare/v4.30.0...v4.31.0)
+
+### Features
+
+* **api:** api update ([23a1a74](https://github.com/RetellAI/retell-python-sdk/commit/23a1a741da36c5507778680f56589600434e6f2b))
+
+
+### Chores
+
+* **docs:** grammar improvements ([1150ae2](https://github.com/RetellAI/retell-python-sdk/commit/1150ae23ac16b8753db1b460848b568b6dbb7f98))
+
## 4.30.0 (2025-05-15)
Full Changelog: [v4.29.0...v4.30.0](https://github.com/RetellAI/retell-python-sdk/compare/v4.29.0...v4.30.0)
diff --git a/SECURITY.md b/SECURITY.md
index d1d63ece..139038e4 100644
--- a/SECURITY.md
+++ b/SECURITY.md
@@ -16,11 +16,11 @@ before making any information public.
## Reporting Non-SDK Related Security Issues
If you encounter security issues that are not directly related to SDKs but pertain to the services
-or products provided by Retell please follow the respective company's security reporting guidelines.
+or products provided by Retell, please follow the respective company's security reporting guidelines.
### Retell Terms and Policies
-Please contact support@retellai.com for any questions or concerns regarding security of our services.
+Please contact support@retellai.com for any questions or concerns regarding the security of our services.
---
diff --git a/api.md b/api.md
index 6ca6e62b..10223ae6 100644
--- a/api.md
+++ b/api.md
@@ -16,6 +16,22 @@ Methods:
- client.call.create_web_call(\*\*params) -> WebCallResponse
- client.call.register_phone_call(\*\*params) -> PhoneCallResponse
+# Chat
+
+Types:
+
+```python
+from retell.types import ChatResponse, ChatListResponse, ChatCreateChatCompletionResponse
+```
+
+Methods:
+
+- client.chat.create(\*\*params) -> ChatResponse
+- client.chat.retrieve(chat_id) -> ChatResponse
+- client.chat.list() -> ChatListResponse
+- client.chat.create_chat_completion(\*\*params) -> ChatCreateChatCompletionResponse
+- client.chat.end(chat_id) -> None
+
# PhoneNumber
Types:
diff --git a/pyproject.toml b/pyproject.toml
index 759cd47b..f0a64608 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
[project]
name = "retell-sdk"
-version = "4.30.0"
+version = "4.31.0"
description = "The official Python library for the retell API"
dynamic = ["readme"]
license = "Apache-2.0"
diff --git a/src/retell/_client.py b/src/retell/_client.py
index c9519b1d..909697b9 100644
--- a/src/retell/_client.py
+++ b/src/retell/_client.py
@@ -21,7 +21,7 @@
)
from ._utils import is_given, get_async_library
from ._version import __version__
-from .resources import llm, call, agent, voice, batch_call, concurrency, phone_number, knowledge_base
+from .resources import llm, call, chat, agent, voice, batch_call, concurrency, phone_number, knowledge_base
from ._streaming import Stream as Stream, AsyncStream as AsyncStream
from ._exceptions import APIStatusError
from ._base_client import (
@@ -36,6 +36,7 @@
class Retell(SyncAPIClient):
call: call.CallResource
+ chat: chat.ChatResource
phone_number: phone_number.PhoneNumberResource
agent: agent.AgentResource
llm: llm.LlmResource
@@ -92,6 +93,7 @@ def __init__(
)
self.call = call.CallResource(self)
+ self.chat = chat.ChatResource(self)
self.phone_number = phone_number.PhoneNumberResource(self)
self.agent = agent.AgentResource(self)
self.llm = llm.LlmResource(self)
@@ -211,6 +213,7 @@ def _make_status_error(
class AsyncRetell(AsyncAPIClient):
call: call.AsyncCallResource
+ chat: chat.AsyncChatResource
phone_number: phone_number.AsyncPhoneNumberResource
agent: agent.AsyncAgentResource
llm: llm.AsyncLlmResource
@@ -267,6 +270,7 @@ def __init__(
)
self.call = call.AsyncCallResource(self)
+ self.chat = chat.AsyncChatResource(self)
self.phone_number = phone_number.AsyncPhoneNumberResource(self)
self.agent = agent.AsyncAgentResource(self)
self.llm = llm.AsyncLlmResource(self)
@@ -385,6 +389,7 @@ def _make_status_error(
class RetellWithRawResponse:
def __init__(self, client: Retell) -> None:
self.call = call.CallResourceWithRawResponse(client.call)
+ self.chat = chat.ChatResourceWithRawResponse(client.chat)
self.phone_number = phone_number.PhoneNumberResourceWithRawResponse(client.phone_number)
self.agent = agent.AgentResourceWithRawResponse(client.agent)
self.llm = llm.LlmResourceWithRawResponse(client.llm)
@@ -397,6 +402,7 @@ def __init__(self, client: Retell) -> None:
class AsyncRetellWithRawResponse:
def __init__(self, client: AsyncRetell) -> None:
self.call = call.AsyncCallResourceWithRawResponse(client.call)
+ self.chat = chat.AsyncChatResourceWithRawResponse(client.chat)
self.phone_number = phone_number.AsyncPhoneNumberResourceWithRawResponse(client.phone_number)
self.agent = agent.AsyncAgentResourceWithRawResponse(client.agent)
self.llm = llm.AsyncLlmResourceWithRawResponse(client.llm)
@@ -409,6 +415,7 @@ def __init__(self, client: AsyncRetell) -> None:
class RetellWithStreamedResponse:
def __init__(self, client: Retell) -> None:
self.call = call.CallResourceWithStreamingResponse(client.call)
+ self.chat = chat.ChatResourceWithStreamingResponse(client.chat)
self.phone_number = phone_number.PhoneNumberResourceWithStreamingResponse(client.phone_number)
self.agent = agent.AgentResourceWithStreamingResponse(client.agent)
self.llm = llm.LlmResourceWithStreamingResponse(client.llm)
@@ -421,6 +428,7 @@ def __init__(self, client: Retell) -> None:
class AsyncRetellWithStreamedResponse:
def __init__(self, client: AsyncRetell) -> None:
self.call = call.AsyncCallResourceWithStreamingResponse(client.call)
+ self.chat = chat.AsyncChatResourceWithStreamingResponse(client.chat)
self.phone_number = phone_number.AsyncPhoneNumberResourceWithStreamingResponse(client.phone_number)
self.agent = agent.AsyncAgentResourceWithStreamingResponse(client.agent)
self.llm = llm.AsyncLlmResourceWithStreamingResponse(client.llm)
diff --git a/src/retell/_version.py b/src/retell/_version.py
index f8b21fac..8be660c9 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.30.0" # x-release-please-version
+__version__ = "4.31.0" # x-release-please-version
diff --git a/src/retell/resources/__init__.py b/src/retell/resources/__init__.py
index cdf93c2a..4853c11f 100644
--- a/src/retell/resources/__init__.py
+++ b/src/retell/resources/__init__.py
@@ -16,6 +16,14 @@
CallResourceWithStreamingResponse,
AsyncCallResourceWithStreamingResponse,
)
+from .chat import (
+ ChatResource,
+ AsyncChatResource,
+ ChatResourceWithRawResponse,
+ AsyncChatResourceWithRawResponse,
+ ChatResourceWithStreamingResponse,
+ AsyncChatResourceWithStreamingResponse,
+)
from .agent import (
AgentResource,
AsyncAgentResource,
@@ -72,6 +80,12 @@
"AsyncCallResourceWithRawResponse",
"CallResourceWithStreamingResponse",
"AsyncCallResourceWithStreamingResponse",
+ "ChatResource",
+ "AsyncChatResource",
+ "ChatResourceWithRawResponse",
+ "AsyncChatResourceWithRawResponse",
+ "ChatResourceWithStreamingResponse",
+ "AsyncChatResourceWithStreamingResponse",
"PhoneNumberResource",
"AsyncPhoneNumberResource",
"PhoneNumberResourceWithRawResponse",
diff --git a/src/retell/resources/chat.py b/src/retell/resources/chat.py
new file mode 100644
index 00000000..0589378a
--- /dev/null
+++ b/src/retell/resources/chat.py
@@ -0,0 +1,519 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Dict
+
+import httpx
+
+from ..types import chat_create_params, chat_create_chat_completion_params
+from .._types import NOT_GIVEN, Body, Query, Headers, NoneType, NotGiven
+from .._utils import maybe_transform, async_maybe_transform
+from .._compat import cached_property
+from .._resource import SyncAPIResource, AsyncAPIResource
+from .._response import (
+ to_raw_response_wrapper,
+ to_streamed_response_wrapper,
+ async_to_raw_response_wrapper,
+ async_to_streamed_response_wrapper,
+)
+from .._base_client import make_request_options
+from ..types.chat_response import ChatResponse
+from ..types.chat_list_response import ChatListResponse
+from ..types.chat_create_chat_completion_response import ChatCreateChatCompletionResponse
+
+__all__ = ["ChatResource", "AsyncChatResource"]
+
+
+class ChatResource(SyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> ChatResourceWithRawResponse:
+ """
+ This property can be used as a prefix for any HTTP method call to return
+ the raw response object instead of the parsed content.
+
+ For more information, see https://www.github.com/RetellAI/retell-python-sdk#accessing-raw-response-data-eg-headers
+ """
+ return ChatResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> ChatResourceWithStreamingResponse:
+ """
+ An alternative to `.with_raw_response` that doesn't eagerly read the response body.
+
+ For more information, see https://www.github.com/RetellAI/retell-python-sdk#with_streaming_response
+ """
+ return ChatResourceWithStreamingResponse(self)
+
+ def create(
+ self,
+ *,
+ agent_id: str,
+ agent_version: int | NotGiven = NOT_GIVEN,
+ metadata: object | NotGiven = NOT_GIVEN,
+ retell_llm_dynamic_variables: Dict[str, object] | NotGiven = NOT_GIVEN,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
+ ) -> ChatResponse:
+ """
+ Create a chat session
+
+ Args:
+ agent_id: The chat agent to use for the call.
+
+ agent_version: The version of the chat agent to use for the call.
+
+ metadata: An arbitrary object for storage purpose only. You can put anything here like
+ your internal customer id associated with the chat. Not used for processing. You
+ can later get this field from the chat object.
+
+ retell_llm_dynamic_variables: Add optional dynamic variables in key value pairs of string that injects into
+ your Response Engine prompt and tool description. Only applicable for Response
+ Engine.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ return self._post(
+ "/create-chat",
+ body=maybe_transform(
+ {
+ "agent_id": agent_id,
+ "agent_version": agent_version,
+ "metadata": metadata,
+ "retell_llm_dynamic_variables": retell_llm_dynamic_variables,
+ },
+ chat_create_params.ChatCreateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=ChatResponse,
+ )
+
+ def retrieve(
+ self,
+ chat_id: str,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
+ ) -> ChatResponse:
+ """
+ Retrieve details of a specific chat
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not chat_id:
+ raise ValueError(f"Expected a non-empty value for `chat_id` but received {chat_id!r}")
+ return self._get(
+ f"/get-chat/{chat_id}",
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=ChatResponse,
+ )
+
+ def list(
+ self,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
+ ) -> ChatListResponse:
+ """List all chats"""
+ return self._get(
+ "/list-chat",
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=ChatListResponse,
+ )
+
+ def create_chat_completion(
+ self,
+ *,
+ chat_id: str,
+ content: str,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
+ ) -> ChatCreateChatCompletionResponse:
+ """
+ Create a chat completion message
+
+ Args:
+ chat_id: Unique id of the chat to create completion.
+
+ content: user message to generate agent chat completion.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ return self._post(
+ "/create-chat-completion",
+ body=maybe_transform(
+ {
+ "chat_id": chat_id,
+ "content": content,
+ },
+ chat_create_chat_completion_params.ChatCreateChatCompletionParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=ChatCreateChatCompletionResponse,
+ )
+
+ def end(
+ self,
+ chat_id: str,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
+ ) -> None:
+ """
+ End an ongoing chat
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not chat_id:
+ raise ValueError(f"Expected a non-empty value for `chat_id` but received {chat_id!r}")
+ extra_headers = {"Accept": "*/*", **(extra_headers or {})}
+ return self._patch(
+ f"/end-chat/{chat_id}",
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=NoneType,
+ )
+
+
+class AsyncChatResource(AsyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> AsyncChatResourceWithRawResponse:
+ """
+ This property can be used as a prefix for any HTTP method call to return
+ the raw response object instead of the parsed content.
+
+ For more information, see https://www.github.com/RetellAI/retell-python-sdk#accessing-raw-response-data-eg-headers
+ """
+ return AsyncChatResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncChatResourceWithStreamingResponse:
+ """
+ An alternative to `.with_raw_response` that doesn't eagerly read the response body.
+
+ For more information, see https://www.github.com/RetellAI/retell-python-sdk#with_streaming_response
+ """
+ return AsyncChatResourceWithStreamingResponse(self)
+
+ async def create(
+ self,
+ *,
+ agent_id: str,
+ agent_version: int | NotGiven = NOT_GIVEN,
+ metadata: object | NotGiven = NOT_GIVEN,
+ retell_llm_dynamic_variables: Dict[str, object] | NotGiven = NOT_GIVEN,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
+ ) -> ChatResponse:
+ """
+ Create a chat session
+
+ Args:
+ agent_id: The chat agent to use for the call.
+
+ agent_version: The version of the chat agent to use for the call.
+
+ metadata: An arbitrary object for storage purpose only. You can put anything here like
+ your internal customer id associated with the chat. Not used for processing. You
+ can later get this field from the chat object.
+
+ retell_llm_dynamic_variables: Add optional dynamic variables in key value pairs of string that injects into
+ your Response Engine prompt and tool description. Only applicable for Response
+ Engine.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ return await self._post(
+ "/create-chat",
+ body=await async_maybe_transform(
+ {
+ "agent_id": agent_id,
+ "agent_version": agent_version,
+ "metadata": metadata,
+ "retell_llm_dynamic_variables": retell_llm_dynamic_variables,
+ },
+ chat_create_params.ChatCreateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=ChatResponse,
+ )
+
+ async def retrieve(
+ self,
+ chat_id: str,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
+ ) -> ChatResponse:
+ """
+ Retrieve details of a specific chat
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not chat_id:
+ raise ValueError(f"Expected a non-empty value for `chat_id` but received {chat_id!r}")
+ return await self._get(
+ f"/get-chat/{chat_id}",
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=ChatResponse,
+ )
+
+ async def list(
+ self,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
+ ) -> ChatListResponse:
+ """List all chats"""
+ return await self._get(
+ "/list-chat",
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=ChatListResponse,
+ )
+
+ async def create_chat_completion(
+ self,
+ *,
+ chat_id: str,
+ content: str,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
+ ) -> ChatCreateChatCompletionResponse:
+ """
+ Create a chat completion message
+
+ Args:
+ chat_id: Unique id of the chat to create completion.
+
+ content: user message to generate agent chat completion.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ return await self._post(
+ "/create-chat-completion",
+ body=await async_maybe_transform(
+ {
+ "chat_id": chat_id,
+ "content": content,
+ },
+ chat_create_chat_completion_params.ChatCreateChatCompletionParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=ChatCreateChatCompletionResponse,
+ )
+
+ async def end(
+ self,
+ chat_id: str,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
+ ) -> None:
+ """
+ End an ongoing chat
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not chat_id:
+ raise ValueError(f"Expected a non-empty value for `chat_id` but received {chat_id!r}")
+ extra_headers = {"Accept": "*/*", **(extra_headers or {})}
+ return await self._patch(
+ f"/end-chat/{chat_id}",
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=NoneType,
+ )
+
+
+class ChatResourceWithRawResponse:
+ def __init__(self, chat: ChatResource) -> None:
+ self._chat = chat
+
+ self.create = to_raw_response_wrapper(
+ chat.create,
+ )
+ self.retrieve = to_raw_response_wrapper(
+ chat.retrieve,
+ )
+ self.list = to_raw_response_wrapper(
+ chat.list,
+ )
+ self.create_chat_completion = to_raw_response_wrapper(
+ chat.create_chat_completion,
+ )
+ self.end = to_raw_response_wrapper(
+ chat.end,
+ )
+
+
+class AsyncChatResourceWithRawResponse:
+ def __init__(self, chat: AsyncChatResource) -> None:
+ self._chat = chat
+
+ self.create = async_to_raw_response_wrapper(
+ chat.create,
+ )
+ self.retrieve = async_to_raw_response_wrapper(
+ chat.retrieve,
+ )
+ self.list = async_to_raw_response_wrapper(
+ chat.list,
+ )
+ self.create_chat_completion = async_to_raw_response_wrapper(
+ chat.create_chat_completion,
+ )
+ self.end = async_to_raw_response_wrapper(
+ chat.end,
+ )
+
+
+class ChatResourceWithStreamingResponse:
+ def __init__(self, chat: ChatResource) -> None:
+ self._chat = chat
+
+ self.create = to_streamed_response_wrapper(
+ chat.create,
+ )
+ self.retrieve = to_streamed_response_wrapper(
+ chat.retrieve,
+ )
+ self.list = to_streamed_response_wrapper(
+ chat.list,
+ )
+ self.create_chat_completion = to_streamed_response_wrapper(
+ chat.create_chat_completion,
+ )
+ self.end = to_streamed_response_wrapper(
+ chat.end,
+ )
+
+
+class AsyncChatResourceWithStreamingResponse:
+ def __init__(self, chat: AsyncChatResource) -> None:
+ self._chat = chat
+
+ self.create = async_to_streamed_response_wrapper(
+ chat.create,
+ )
+ self.retrieve = async_to_streamed_response_wrapper(
+ chat.retrieve,
+ )
+ self.list = async_to_streamed_response_wrapper(
+ chat.list,
+ )
+ self.create_chat_completion = async_to_streamed_response_wrapper(
+ chat.create_chat_completion,
+ )
+ self.end = async_to_streamed_response_wrapper(
+ chat.end,
+ )
diff --git a/src/retell/types/__init__.py b/src/retell/types/__init__.py
index 2bf8324c..37049118 100644
--- a/src/retell/types/__init__.py
+++ b/src/retell/types/__init__.py
@@ -4,6 +4,7 @@
from .llm_response import LlmResponse as LlmResponse
from .call_response import CallResponse as CallResponse
+from .chat_response import ChatResponse as ChatResponse
from .agent_response import AgentResponse as AgentResponse
from .voice_response import VoiceResponse as VoiceResponse
from .call_list_params import CallListParams as CallListParams
@@ -13,6 +14,8 @@
from .web_call_response import WebCallResponse as WebCallResponse
from .call_list_response import CallListResponse as CallListResponse
from .call_update_params import CallUpdateParams as CallUpdateParams
+from .chat_create_params import ChatCreateParams as ChatCreateParams
+from .chat_list_response import ChatListResponse as ChatListResponse
from .agent_create_params import AgentCreateParams as AgentCreateParams
from .agent_list_response import AgentListResponse as AgentListResponse
from .agent_update_params import AgentUpdateParams as AgentUpdateParams
@@ -35,4 +38,6 @@
from .concurrency_retrieve_response import ConcurrencyRetrieveResponse as ConcurrencyRetrieveResponse
from .call_register_phone_call_params import CallRegisterPhoneCallParams as CallRegisterPhoneCallParams
from .knowledge_base_add_sources_params import KnowledgeBaseAddSourcesParams as KnowledgeBaseAddSourcesParams
+from .chat_create_chat_completion_params import ChatCreateChatCompletionParams as ChatCreateChatCompletionParams
from .batch_call_create_batch_call_params import BatchCallCreateBatchCallParams as BatchCallCreateBatchCallParams
+from .chat_create_chat_completion_response import ChatCreateChatCompletionResponse as ChatCreateChatCompletionResponse
diff --git a/src/retell/types/chat_create_chat_completion_params.py b/src/retell/types/chat_create_chat_completion_params.py
new file mode 100644
index 00000000..eadfb846
--- /dev/null
+++ b/src/retell/types/chat_create_chat_completion_params.py
@@ -0,0 +1,15 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import Required, TypedDict
+
+__all__ = ["ChatCreateChatCompletionParams"]
+
+
+class ChatCreateChatCompletionParams(TypedDict, total=False):
+ chat_id: Required[str]
+ """Unique id of the chat to create completion."""
+
+ content: Required[str]
+ """user message to generate agent chat completion."""
diff --git a/src/retell/types/chat_create_chat_completion_response.py b/src/retell/types/chat_create_chat_completion_response.py
new file mode 100644
index 00000000..161c43d3
--- /dev/null
+++ b/src/retell/types/chat_create_chat_completion_response.py
@@ -0,0 +1,121 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import List, Union, Optional
+from typing_extensions import Literal, TypeAlias
+
+from .._models import BaseModel
+
+__all__ = [
+ "ChatCreateChatCompletionResponse",
+ "Message",
+ "MessageMessage",
+ "MessageToolCallInvocationMessage",
+ "MessageToolCallResultMessage",
+ "MessageNodeTransitionMessage",
+ "MessageStateTransitionMessage",
+]
+
+
+class MessageMessage(BaseModel):
+ content: str
+ """Content of the message"""
+
+ created_timestamp: int
+ """Create timestamp of the message"""
+
+ message_id: str
+ """Unique id ot the message"""
+
+ role: Literal["agent", "user"]
+ """Documents whether this message is sent by agent or user."""
+
+
+class MessageToolCallInvocationMessage(BaseModel):
+ arguments: str
+ """Arguments for this tool call, it's a stringified JSON object."""
+
+ message_id: str
+ """Unique id ot the message"""
+
+ name: str
+ """Name of the function in this tool call."""
+
+ role: Literal["tool_call_invocation"]
+ """This is a tool call invocation."""
+
+ tool_call_id: str
+ """Tool call id, globally unique."""
+
+ created_timestamp: Optional[int] = None
+ """Create timestamp of the message"""
+
+
+class MessageToolCallResultMessage(BaseModel):
+ content: str
+ """Result of the tool call, can be a string, a stringified json, etc."""
+
+ created_timestamp: int
+ """Create timestamp of the message"""
+
+ message_id: str
+ """Unique id ot the message"""
+
+ role: Literal["tool_call_result"]
+ """This is result of a tool call."""
+
+ tool_call_id: str
+ """Tool call id, globally unique."""
+
+
+class MessageNodeTransitionMessage(BaseModel):
+ created_timestamp: int
+ """Create timestamp of the message"""
+
+ message_id: str
+ """Unique id ot the message"""
+
+ role: Literal["node_transition"]
+ """This is node transition."""
+
+ former_node_id: Optional[str] = None
+ """Former node id"""
+
+ former_node_name: Optional[str] = None
+ """Former node name"""
+
+ new_node_id: Optional[str] = None
+ """New node id"""
+
+ new_node_name: Optional[str] = None
+ """New node name"""
+
+
+class MessageStateTransitionMessage(BaseModel):
+ created_timestamp: int
+ """Create timestamp of the message"""
+
+ message_id: str
+ """Unique id ot the message"""
+
+ role: Literal["state_transition"]
+ """This is state transition for ."""
+
+ former_state_name: Optional[str] = None
+ """Former state name"""
+
+ new_state_name: Optional[str] = None
+ """New state name"""
+
+
+Message: TypeAlias = Union[
+ MessageMessage,
+ MessageToolCallInvocationMessage,
+ MessageToolCallResultMessage,
+ MessageNodeTransitionMessage,
+ MessageStateTransitionMessage,
+]
+
+
+class ChatCreateChatCompletionResponse(BaseModel):
+ messages: List[Message]
+ """Transcript of the chat completion weaved with tool call invocation and results."""
diff --git a/src/retell/types/chat_create_params.py b/src/retell/types/chat_create_params.py
new file mode 100644
index 00000000..61a59ae9
--- /dev/null
+++ b/src/retell/types/chat_create_params.py
@@ -0,0 +1,31 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Dict
+from typing_extensions import Required, TypedDict
+
+__all__ = ["ChatCreateParams"]
+
+
+class ChatCreateParams(TypedDict, total=False):
+ agent_id: Required[str]
+ """The chat agent to use for the call."""
+
+ agent_version: int
+ """The version of the chat agent to use for the call."""
+
+ metadata: object
+ """An arbitrary object for storage purpose only.
+
+ You can put anything here like your internal customer id associated with the
+ chat. Not used for processing. You can later get this field from the chat
+ object.
+ """
+
+ retell_llm_dynamic_variables: Dict[str, object]
+ """
+ Add optional dynamic variables in key value pairs of string that injects into
+ your Response Engine prompt and tool description. Only applicable for Response
+ Engine.
+ """
diff --git a/src/retell/types/chat_list_response.py b/src/retell/types/chat_list_response.py
new file mode 100644
index 00000000..2135f413
--- /dev/null
+++ b/src/retell/types/chat_list_response.py
@@ -0,0 +1,10 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import List
+from typing_extensions import TypeAlias
+
+from .chat_response import ChatResponse
+
+__all__ = ["ChatListResponse"]
+
+ChatListResponse: TypeAlias = List[ChatResponse]
diff --git a/src/retell/types/chat_response.py b/src/retell/types/chat_response.py
new file mode 100644
index 00000000..53eaa8c2
--- /dev/null
+++ b/src/retell/types/chat_response.py
@@ -0,0 +1,221 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import Dict, List, Union, Optional
+from typing_extensions import Literal, TypeAlias
+
+from pydantic import Field as FieldInfo
+
+from .._models import BaseModel
+
+__all__ = [
+ "ChatResponse",
+ "ChatAnalysis",
+ "ChatCost",
+ "ChatCostProductCost",
+ "MessageWithToolCall",
+ "MessageWithToolCallMessage",
+ "MessageWithToolCallToolCallInvocationMessage",
+ "MessageWithToolCallToolCallResultMessage",
+ "MessageWithToolCallNodeTransitionMessage",
+ "MessageWithToolCallStateTransitionMessage",
+]
+
+
+class ChatAnalysis(BaseModel):
+ chat_successful: Optional[bool] = None
+ """
+ Whether the agent seems to have a successful chat with the user, where the agent
+ finishes the task, and the call was complete without being cutoff.
+ """
+
+ chat_summary: Optional[str] = None
+ """A high level summary of the chat."""
+
+ custom_analysis_data: Optional[object] = None
+ """
+ Custom analysis data that was extracted based on the schema defined in chat
+ agent post chat analysis data. Can be empty if nothing is specified.
+ """
+
+ user_sentiment: Optional[Literal["Negative", "Positive", "Neutral", "Unknown"]] = None
+ """Sentiment of the user in the chat."""
+
+
+class ChatCostProductCost(BaseModel):
+ cost: float
+ """Cost for the product in cents for the duration of the call."""
+
+ product: str
+ """Product name that has a cost associated with it."""
+
+ unit_price: float = FieldInfo(alias="unitPrice")
+ """Unit price of the product in cents per second."""
+
+
+class ChatCost(BaseModel):
+ combined_cost: Optional[float] = None
+ """Combined cost of all individual costs in cents"""
+
+ product_costs: Optional[List[ChatCostProductCost]] = None
+ """List of products with their unit prices and costs in cents"""
+
+
+class MessageWithToolCallMessage(BaseModel):
+ content: str
+ """Content of the message"""
+
+ created_timestamp: int
+ """Create timestamp of the message"""
+
+ message_id: str
+ """Unique id ot the message"""
+
+ role: Literal["agent", "user"]
+ """Documents whether this message is sent by agent or user."""
+
+
+class MessageWithToolCallToolCallInvocationMessage(BaseModel):
+ arguments: str
+ """Arguments for this tool call, it's a stringified JSON object."""
+
+ message_id: str
+ """Unique id ot the message"""
+
+ name: str
+ """Name of the function in this tool call."""
+
+ role: Literal["tool_call_invocation"]
+ """This is a tool call invocation."""
+
+ tool_call_id: str
+ """Tool call id, globally unique."""
+
+ created_timestamp: Optional[int] = None
+ """Create timestamp of the message"""
+
+
+class MessageWithToolCallToolCallResultMessage(BaseModel):
+ content: str
+ """Result of the tool call, can be a string, a stringified json, etc."""
+
+ created_timestamp: int
+ """Create timestamp of the message"""
+
+ message_id: str
+ """Unique id ot the message"""
+
+ role: Literal["tool_call_result"]
+ """This is result of a tool call."""
+
+ tool_call_id: str
+ """Tool call id, globally unique."""
+
+
+class MessageWithToolCallNodeTransitionMessage(BaseModel):
+ created_timestamp: int
+ """Create timestamp of the message"""
+
+ message_id: str
+ """Unique id ot the message"""
+
+ role: Literal["node_transition"]
+ """This is node transition."""
+
+ former_node_id: Optional[str] = None
+ """Former node id"""
+
+ former_node_name: Optional[str] = None
+ """Former node name"""
+
+ new_node_id: Optional[str] = None
+ """New node id"""
+
+ new_node_name: Optional[str] = None
+ """New node name"""
+
+
+class MessageWithToolCallStateTransitionMessage(BaseModel):
+ created_timestamp: int
+ """Create timestamp of the message"""
+
+ message_id: str
+ """Unique id ot the message"""
+
+ role: Literal["state_transition"]
+ """This is state transition for ."""
+
+ former_state_name: Optional[str] = None
+ """Former state name"""
+
+ new_state_name: Optional[str] = None
+ """New state name"""
+
+
+MessageWithToolCall: TypeAlias = Union[
+ MessageWithToolCallMessage,
+ MessageWithToolCallToolCallInvocationMessage,
+ MessageWithToolCallToolCallResultMessage,
+ MessageWithToolCallNodeTransitionMessage,
+ MessageWithToolCallStateTransitionMessage,
+]
+
+
+class ChatResponse(BaseModel):
+ agent_id: str
+ """Corresponding chat agent id of this chat."""
+
+ chat_id: str
+ """Unique id of the chat."""
+
+ chat_status: Literal["ongoing", "ended", "error"]
+ """Status of chat.
+
+ - `ongoing`: Chat session is ongoing, chat agent can receive new message and
+ generate response.
+
+ - `ended`: Chat session has ended can not generate new response.
+
+ - `error`: Chat encountered error.
+ """
+
+ chat_analysis: Optional[ChatAnalysis] = None
+ """
+ Post chat analysis that includes information such as sentiment, status, summary,
+ and custom defined data to extract. Available after chat ends. Subscribe to
+ `chat_analyzed` webhook event type to receive it once ready.
+ """
+
+ chat_cost: Optional[ChatCost] = None
+
+ end_timestamp: Optional[int] = None
+ """End timestamp (milliseconds since epoch) of the chat.
+
+ Available after chat ends.
+ """
+
+ message_with_tool_calls: Optional[List[MessageWithToolCall]] = None
+ """Transcript of the chat weaved with tool call invocation and results."""
+
+ metadata: Optional[object] = None
+ """An arbitrary object for storage purpose only.
+
+ You can put anything here like your internal customer id associated with the
+ chat. Not used for processing. You can later get this field from the chat
+ object.
+ """
+
+ retell_llm_dynamic_variables: Optional[Dict[str, object]] = None
+ """
+ Add optional dynamic variables in key value pairs of string that injects into
+ your Response Engine prompt and tool description. Only applicable for Response
+ Engine.
+ """
+
+ start_timestamp: Optional[int] = None
+ """Begin timestamp (milliseconds since epoch) of the chat.
+
+ Available after chat starts.
+ """
+
+ transcript: Optional[str] = None
+ """Transcription of the chat."""
diff --git a/tests/api_resources/test_chat.py b/tests/api_resources/test_chat.py
new file mode 100644
index 00000000..67c52f1e
--- /dev/null
+++ b/tests/api_resources/test_chat.py
@@ -0,0 +1,378 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+import os
+from typing import Any, cast
+
+import pytest
+
+from retell import Retell, AsyncRetell
+from tests.utils import assert_matches_type
+from retell.types import (
+ ChatResponse,
+ ChatListResponse,
+ ChatCreateChatCompletionResponse,
+)
+
+base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
+
+
+class TestChat:
+ parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
+
+ @parametrize
+ def test_method_create(self, client: Retell) -> None:
+ chat = client.chat.create(
+ agent_id="oBeDLoLOeuAbiuaMFXRtDOLriTJ5tSxD",
+ )
+ assert_matches_type(ChatResponse, chat, path=["response"])
+
+ @parametrize
+ def test_method_create_with_all_params(self, client: Retell) -> None:
+ chat = client.chat.create(
+ agent_id="oBeDLoLOeuAbiuaMFXRtDOLriTJ5tSxD",
+ agent_version=1,
+ metadata={},
+ retell_llm_dynamic_variables={"customer_name": "bar"},
+ )
+ assert_matches_type(ChatResponse, chat, path=["response"])
+
+ @parametrize
+ def test_raw_response_create(self, client: Retell) -> None:
+ response = client.chat.with_raw_response.create(
+ agent_id="oBeDLoLOeuAbiuaMFXRtDOLriTJ5tSxD",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ chat = response.parse()
+ assert_matches_type(ChatResponse, chat, path=["response"])
+
+ @parametrize
+ def test_streaming_response_create(self, client: Retell) -> None:
+ with client.chat.with_streaming_response.create(
+ agent_id="oBeDLoLOeuAbiuaMFXRtDOLriTJ5tSxD",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ chat = response.parse()
+ assert_matches_type(ChatResponse, chat, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_method_retrieve(self, client: Retell) -> None:
+ chat = client.chat.retrieve(
+ "16b980523634a6dc504898cda492e939",
+ )
+ assert_matches_type(ChatResponse, chat, path=["response"])
+
+ @parametrize
+ def test_raw_response_retrieve(self, client: Retell) -> None:
+ response = client.chat.with_raw_response.retrieve(
+ "16b980523634a6dc504898cda492e939",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ chat = response.parse()
+ assert_matches_type(ChatResponse, chat, path=["response"])
+
+ @parametrize
+ def test_streaming_response_retrieve(self, client: Retell) -> None:
+ with client.chat.with_streaming_response.retrieve(
+ "16b980523634a6dc504898cda492e939",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ chat = response.parse()
+ assert_matches_type(ChatResponse, chat, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_path_params_retrieve(self, client: Retell) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `chat_id` but received ''"):
+ client.chat.with_raw_response.retrieve(
+ "",
+ )
+
+ @parametrize
+ def test_method_list(self, client: Retell) -> None:
+ chat = client.chat.list()
+ assert_matches_type(ChatListResponse, chat, path=["response"])
+
+ @parametrize
+ def test_raw_response_list(self, client: Retell) -> None:
+ response = client.chat.with_raw_response.list()
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ chat = response.parse()
+ assert_matches_type(ChatListResponse, chat, path=["response"])
+
+ @parametrize
+ def test_streaming_response_list(self, client: Retell) -> None:
+ with client.chat.with_streaming_response.list() as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ chat = response.parse()
+ assert_matches_type(ChatListResponse, chat, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_method_create_chat_completion(self, client: Retell) -> None:
+ chat = client.chat.create_chat_completion(
+ chat_id="oBeDLoLOeuAbiuaMFXRtDOLriTJ5tSxD",
+ content="hi how are you doing?",
+ )
+ assert_matches_type(ChatCreateChatCompletionResponse, chat, path=["response"])
+
+ @parametrize
+ def test_raw_response_create_chat_completion(self, client: Retell) -> None:
+ response = client.chat.with_raw_response.create_chat_completion(
+ chat_id="oBeDLoLOeuAbiuaMFXRtDOLriTJ5tSxD",
+ content="hi how are you doing?",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ chat = response.parse()
+ assert_matches_type(ChatCreateChatCompletionResponse, chat, path=["response"])
+
+ @parametrize
+ def test_streaming_response_create_chat_completion(self, client: Retell) -> None:
+ with client.chat.with_streaming_response.create_chat_completion(
+ chat_id="oBeDLoLOeuAbiuaMFXRtDOLriTJ5tSxD",
+ content="hi how are you doing?",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ chat = response.parse()
+ assert_matches_type(ChatCreateChatCompletionResponse, chat, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_method_end(self, client: Retell) -> None:
+ chat = client.chat.end(
+ "16b980523634a6dc504898cda492e939",
+ )
+ assert chat is None
+
+ @parametrize
+ def test_raw_response_end(self, client: Retell) -> None:
+ response = client.chat.with_raw_response.end(
+ "16b980523634a6dc504898cda492e939",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ chat = response.parse()
+ assert chat is None
+
+ @parametrize
+ def test_streaming_response_end(self, client: Retell) -> None:
+ with client.chat.with_streaming_response.end(
+ "16b980523634a6dc504898cda492e939",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ chat = response.parse()
+ assert chat is None
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_path_params_end(self, client: Retell) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `chat_id` but received ''"):
+ client.chat.with_raw_response.end(
+ "",
+ )
+
+
+class TestAsyncChat:
+ parametrize = pytest.mark.parametrize("async_client", [False, True], indirect=True, ids=["loose", "strict"])
+
+ @parametrize
+ async def test_method_create(self, async_client: AsyncRetell) -> None:
+ chat = await async_client.chat.create(
+ agent_id="oBeDLoLOeuAbiuaMFXRtDOLriTJ5tSxD",
+ )
+ assert_matches_type(ChatResponse, chat, path=["response"])
+
+ @parametrize
+ async def test_method_create_with_all_params(self, async_client: AsyncRetell) -> None:
+ chat = await async_client.chat.create(
+ agent_id="oBeDLoLOeuAbiuaMFXRtDOLriTJ5tSxD",
+ agent_version=1,
+ metadata={},
+ retell_llm_dynamic_variables={"customer_name": "bar"},
+ )
+ assert_matches_type(ChatResponse, chat, path=["response"])
+
+ @parametrize
+ async def test_raw_response_create(self, async_client: AsyncRetell) -> None:
+ response = await async_client.chat.with_raw_response.create(
+ agent_id="oBeDLoLOeuAbiuaMFXRtDOLriTJ5tSxD",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ chat = await response.parse()
+ assert_matches_type(ChatResponse, chat, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_create(self, async_client: AsyncRetell) -> None:
+ async with async_client.chat.with_streaming_response.create(
+ agent_id="oBeDLoLOeuAbiuaMFXRtDOLriTJ5tSxD",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ chat = await response.parse()
+ assert_matches_type(ChatResponse, chat, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_method_retrieve(self, async_client: AsyncRetell) -> None:
+ chat = await async_client.chat.retrieve(
+ "16b980523634a6dc504898cda492e939",
+ )
+ assert_matches_type(ChatResponse, chat, path=["response"])
+
+ @parametrize
+ async def test_raw_response_retrieve(self, async_client: AsyncRetell) -> None:
+ response = await async_client.chat.with_raw_response.retrieve(
+ "16b980523634a6dc504898cda492e939",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ chat = await response.parse()
+ assert_matches_type(ChatResponse, chat, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_retrieve(self, async_client: AsyncRetell) -> None:
+ async with async_client.chat.with_streaming_response.retrieve(
+ "16b980523634a6dc504898cda492e939",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ chat = await response.parse()
+ assert_matches_type(ChatResponse, chat, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_path_params_retrieve(self, async_client: AsyncRetell) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `chat_id` but received ''"):
+ await async_client.chat.with_raw_response.retrieve(
+ "",
+ )
+
+ @parametrize
+ async def test_method_list(self, async_client: AsyncRetell) -> None:
+ chat = await async_client.chat.list()
+ assert_matches_type(ChatListResponse, chat, path=["response"])
+
+ @parametrize
+ async def test_raw_response_list(self, async_client: AsyncRetell) -> None:
+ response = await async_client.chat.with_raw_response.list()
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ chat = await response.parse()
+ assert_matches_type(ChatListResponse, chat, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_list(self, async_client: AsyncRetell) -> None:
+ async with async_client.chat.with_streaming_response.list() as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ chat = await response.parse()
+ assert_matches_type(ChatListResponse, chat, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_method_create_chat_completion(self, async_client: AsyncRetell) -> None:
+ chat = await async_client.chat.create_chat_completion(
+ chat_id="oBeDLoLOeuAbiuaMFXRtDOLriTJ5tSxD",
+ content="hi how are you doing?",
+ )
+ assert_matches_type(ChatCreateChatCompletionResponse, chat, path=["response"])
+
+ @parametrize
+ async def test_raw_response_create_chat_completion(self, async_client: AsyncRetell) -> None:
+ response = await async_client.chat.with_raw_response.create_chat_completion(
+ chat_id="oBeDLoLOeuAbiuaMFXRtDOLriTJ5tSxD",
+ content="hi how are you doing?",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ chat = await response.parse()
+ assert_matches_type(ChatCreateChatCompletionResponse, chat, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_create_chat_completion(self, async_client: AsyncRetell) -> None:
+ async with async_client.chat.with_streaming_response.create_chat_completion(
+ chat_id="oBeDLoLOeuAbiuaMFXRtDOLriTJ5tSxD",
+ content="hi how are you doing?",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ chat = await response.parse()
+ assert_matches_type(ChatCreateChatCompletionResponse, chat, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_method_end(self, async_client: AsyncRetell) -> None:
+ chat = await async_client.chat.end(
+ "16b980523634a6dc504898cda492e939",
+ )
+ assert chat is None
+
+ @parametrize
+ async def test_raw_response_end(self, async_client: AsyncRetell) -> None:
+ response = await async_client.chat.with_raw_response.end(
+ "16b980523634a6dc504898cda492e939",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ chat = await response.parse()
+ assert chat is None
+
+ @parametrize
+ async def test_streaming_response_end(self, async_client: AsyncRetell) -> None:
+ async with async_client.chat.with_streaming_response.end(
+ "16b980523634a6dc504898cda492e939",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ chat = await response.parse()
+ assert chat is None
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_path_params_end(self, async_client: AsyncRetell) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `chat_id` but received ''"):
+ await async_client.chat.with_raw_response.end(
+ "",
+ )