diff --git a/.github/workflows/release-pr-guard.yml b/.github/workflows/release-pr-guard.yml deleted file mode 100644 index 68c3cc541..000000000 --- a/.github/workflows/release-pr-guard.yml +++ /dev/null @@ -1,40 +0,0 @@ -name: Release PR Guard - -# Generated release PRs are tree-replaced from prod 'next' (promoted staging -# content). They must NEVER modify prod-owned machinery: a diff touching these -# paths means staging content leaked through the promote's restore step (as -# happened with bin/check-release-environment on 2026-07-03/04). Passes -# trivially for human PRs, which may legitimately edit workflows. - -on: - pull_request: - branches: [master] - -permissions: - contents: read - -jobs: - protected-paths: - name: protected-paths - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - name: Block prod-owned changes in generated release PRs - env: - HEAD_REF: ${{ github.head_ref }} - BASE_REF: ${{ github.base_ref }} - run: | - if [[ "$HEAD_REF" != release-please--* ]]; then - echo "Not a generated release PR; nothing to guard." - exit 0 - fi - changed=$(git diff --name-only "origin/$BASE_REF"...HEAD) - bad=$(printf '%s\n' "$changed" | grep -E '^(\.github/|bin/|release-please-config\.json)' | grep -v '^\.github/workflows/create-releases\.yml$' || true) - if [ -n "$bad" ]; then - echo "::error::Generated release PR modifies prod-owned machinery (staging leak through promote?):" - printf '%s\n' "$bad" - exit 1 - fi - echo "No prod-owned paths touched." diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 05d878ea7..a018f01dd 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "4.167.0" + ".": "4.168.0" } \ No newline at end of file diff --git a/.stats.yml b/.stats.yml index fb8dd977c..8b890b04d 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1 +1 @@ -configured_endpoints: 1100 +configured_endpoints: 1096 diff --git a/CHANGELOG.md b/CHANGELOG.md index 7c4f37dc3..774e28971 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## [4.168.0](https://github.com/team-telnyx/telnyx-python/compare/v4.167.0...v4.168.0) (2026-07-07) + + +### Bug Fixes + +* **release:** ghost guard also verifies the GitHub Release exists ([#393](https://github.com/team-telnyx/telnyx-python/issues/393)) ([81acd42](https://github.com/team-telnyx/telnyx-python/commit/81acd426b7b036b30144949f58ce672698624854)) +* **release:** scan next's commits in release-pr (stop depending on master hotfixes) ([#390](https://github.com/team-telnyx/telnyx-python/issues/390)) ([73db53e](https://github.com/team-telnyx/telnyx-python/commit/73db53e071b2a1c0b014a1504882b33d6bd55b3d)) + ## 4.167.0 (2026-07-03) Full Changelog: [v4.166.0...v4.167.0](https://github.com/team-telnyx/telnyx-python/compare/v4.166.0...v4.167.0) diff --git a/api.md b/api.md index 533e025d5..fbb8c8a51 100644 --- a/api.md +++ b/api.md @@ -569,7 +569,6 @@ Types: from telnyx.types import ( ModelMetadata, ModelsResponse, - AICreateResponseDeprecatedResponse, AIRetrieveConversationHistoriesResponse, AISummarizeResponse, ) @@ -577,9 +576,7 @@ from telnyx.types import ( Methods: -- client.ai.create_response_deprecated(\*\*params) -> AICreateResponseDeprecatedResponse - client.ai.retrieve_conversation_histories(\*\*params) -> AIRetrieveConversationHistoriesResponse -- client.ai.retrieve_models() -> ModelsResponse - client.ai.summarize(\*\*params) -> AISummarizeResponse ## Assistants @@ -830,13 +827,9 @@ Methods: Types: ```python -from telnyx.types.ai import BucketIDs, ChatCompletionRequest, ChatCreateCompletionResponse +from telnyx.types.ai import BucketIDs, ChatCompletionRequest ``` -Methods: - -- client.ai.chat.create_completion(\*\*params) -> ChatCreateCompletionResponse - ## Clusters Types: @@ -2491,7 +2484,6 @@ from telnyx.types import ( MessageSendLongCodeResponse, MessageSendNumberPoolResponse, MessageSendShortCodeResponse, - MessageSendWhatsappResponse, MessageSendWithAlphanumericSenderResponse, ) ``` @@ -2507,7 +2499,6 @@ Methods: - client.messages.send_long_code(\*\*params) -> MessageSendLongCodeResponse - client.messages.send_number_pool(\*\*params) -> MessageSendNumberPoolResponse - client.messages.send_short_code(\*\*params) -> MessageSendShortCodeResponse -- client.messages.send_whatsapp(\*\*params) -> MessageSendWhatsappResponse - client.messages.send_with_alphanumeric_sender(\*\*params) -> MessageSendWithAlphanumericSenderResponse ## Rcs diff --git a/pyproject.toml b/pyproject.toml index b31bcb8b3..fd8c2120d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "telnyx" -version = "4.167.0" +version = "4.168.0" description = "The official Python library for the telnyx API" dynamic = ["readme"] license = "MIT" diff --git a/src/telnyx/_client.py b/src/telnyx/_client.py index 670454d89..6ab8ecb60 100644 --- a/src/telnyx/_client.py +++ b/src/telnyx/_client.py @@ -993,6 +993,7 @@ def media(self) -> MediaResource: @cached_property def messages(self) -> MessagesResource: + """Messages""" from .resources.messages import MessagesResource return MessagesResource(self) @@ -2399,6 +2400,7 @@ def media(self) -> AsyncMediaResource: @cached_property def messages(self) -> AsyncMessagesResource: + """Messages""" from .resources.messages import AsyncMessagesResource return AsyncMessagesResource(self) @@ -3725,6 +3727,7 @@ def media(self) -> media.MediaResourceWithRawResponse: @cached_property def messages(self) -> messages.MessagesResourceWithRawResponse: + """Messages""" from .resources.messages import MessagesResourceWithRawResponse return MessagesResourceWithRawResponse(self._client.messages) @@ -4926,6 +4929,7 @@ def media(self) -> media.AsyncMediaResourceWithRawResponse: @cached_property def messages(self) -> messages.AsyncMessagesResourceWithRawResponse: + """Messages""" from .resources.messages import AsyncMessagesResourceWithRawResponse return AsyncMessagesResourceWithRawResponse(self._client.messages) @@ -6139,6 +6143,7 @@ def media(self) -> media.MediaResourceWithStreamingResponse: @cached_property def messages(self) -> messages.MessagesResourceWithStreamingResponse: + """Messages""" from .resources.messages import MessagesResourceWithStreamingResponse return MessagesResourceWithStreamingResponse(self._client.messages) @@ -7362,6 +7367,7 @@ def media(self) -> media.AsyncMediaResourceWithStreamingResponse: @cached_property def messages(self) -> messages.AsyncMessagesResourceWithStreamingResponse: + """Messages""" from .resources.messages import AsyncMessagesResourceWithStreamingResponse return AsyncMessagesResourceWithStreamingResponse(self._client.messages) diff --git a/src/telnyx/_version.py b/src/telnyx/_version.py index dc467d429..0edb848ab 100644 --- a/src/telnyx/_version.py +++ b/src/telnyx/_version.py @@ -1,4 +1,4 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. __title__ = "telnyx" -__version__ = "4.167.0" # x-release-please-version +__version__ = "4.168.0" # x-release-please-version diff --git a/src/telnyx/resources/ai/__init__.py b/src/telnyx/resources/ai/__init__.py index 3ea9a19dd..ebc918230 100644 --- a/src/telnyx/resources/ai/__init__.py +++ b/src/telnyx/resources/ai/__init__.py @@ -8,14 +8,6 @@ AIResourceWithStreamingResponse, AsyncAIResourceWithStreamingResponse, ) -from .chat import ( - ChatResource, - AsyncChatResource, - ChatResourceWithRawResponse, - AsyncChatResourceWithRawResponse, - ChatResourceWithStreamingResponse, - AsyncChatResourceWithStreamingResponse, -) from .audio import ( AudioResource, AsyncAudioResource, @@ -118,12 +110,6 @@ "AsyncAudioResourceWithRawResponse", "AudioResourceWithStreamingResponse", "AsyncAudioResourceWithStreamingResponse", - "ChatResource", - "AsyncChatResource", - "ChatResourceWithRawResponse", - "AsyncChatResourceWithRawResponse", - "ChatResourceWithStreamingResponse", - "AsyncChatResourceWithStreamingResponse", "ClustersResource", "AsyncClustersResource", "ClustersResourceWithRawResponse", diff --git a/src/telnyx/resources/ai/ai.py b/src/telnyx/resources/ai/ai.py index 8c21ba15b..6ca6eb7bc 100644 --- a/src/telnyx/resources/ai/ai.py +++ b/src/telnyx/resources/ai/ai.py @@ -2,21 +2,12 @@ from __future__ import annotations -import typing_extensions -from typing import Dict, Union +from typing import Union from datetime import datetime from typing_extensions import Literal import httpx -from .chat import ( - ChatResource, - AsyncChatResource, - ChatResourceWithRawResponse, - AsyncChatResourceWithRawResponse, - ChatResourceWithStreamingResponse, - AsyncChatResourceWithStreamingResponse, -) from .audio import ( AudioResource, AsyncAudioResource, @@ -33,11 +24,7 @@ ToolsResourceWithStreamingResponse, AsyncToolsResourceWithStreamingResponse, ) -from ...types import ( - ai_summarize_params, - ai_create_response_deprecated_params, - ai_retrieve_conversation_histories_params, -) +from ...types import ai_summarize_params, ai_retrieve_conversation_histories_params from ..._types import Body, Omit, Query, Headers, NotGiven, omit, not_given from ..._utils import maybe_transform, async_maybe_transform from .clusters import ( @@ -97,7 +84,6 @@ EmbeddingsResourceWithStreamingResponse, AsyncEmbeddingsResourceWithStreamingResponse, ) -from ...types.models_response import ModelsResponse from .fine_tuning.fine_tuning import ( FineTuningResource, AsyncFineTuningResource, @@ -123,7 +109,6 @@ AsyncConversationsResourceWithStreamingResponse, ) from ...types.ai_summarize_response import AISummarizeResponse -from ...types.ai_create_response_deprecated_response import AICreateResponseDeprecatedResponse from ...types.ai_retrieve_conversation_histories_response import AIRetrieveConversationHistoriesResponse __all__ = ["AIResource", "AsyncAIResource"] @@ -139,11 +124,6 @@ def assistants(self) -> AssistantsResource: def audio(self) -> AudioResource: return AudioResource(self._client) - @cached_property - def chat(self) -> ChatResource: - """Generate text with LLMs""" - return ChatResource(self._client) - @cached_property def clusters(self) -> ClustersResource: """Identify common themes and patterns in your embedded documents""" @@ -203,47 +183,6 @@ def with_streaming_response(self) -> AIResourceWithStreamingResponse: """ return AIResourceWithStreamingResponse(self) - @typing_extensions.deprecated("deprecated") - def create_response_deprecated( - self, - *, - response_request: Dict[str, object], - # 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, - ) -> AICreateResponseDeprecatedResponse: - """**Deprecated**: Use `POST /v2/ai/openai/responses` instead. - - This endpoint is - compatible with the - [OpenAI Responses API](https://developers.openai.com/api/reference/responses/overview) - and may be used with the OpenAI JS or Python SDK. Response id parameter is not - supported at the moment. Use the `conversation` parameter with a Telnyx - Conversation ID to leverage persistent conversations. - - 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 - """ - return self._post( - "/ai/responses", - body=maybe_transform( - response_request, ai_create_response_deprecated_params.AICreateResponseDeprecatedParams - ), - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - cast_to=AICreateResponseDeprecatedResponse, - ) - def retrieve_conversation_histories( self, *, @@ -394,36 +333,6 @@ def retrieve_conversation_histories( cast_to=AIRetrieveConversationHistoriesResponse, ) - @typing_extensions.deprecated("deprecated") - def retrieve_models( - 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, - ) -> ModelsResponse: - """ - **Deprecated**: Use `GET /v2/ai/openai/models` instead. - - Returns the same `ModelsResponse` payload as the OpenAI-compatible endpoint — - open-source LLMs hosted on Telnyx (e.g. `moonshotai/Kimi-K2.6`, - `zai-org/GLM-5.1-FP8`, `MiniMaxAI/MiniMax-M2.7`), embedding models, and - fine-tuned models — kept around for backwards compatibility. New integrations - should use `/v2/ai/openai/models`. - - Model ids follow the `{organization}/{model_name}` convention from Hugging Face. - """ - return self._get( - "/ai/models", - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - cast_to=ModelsResponse, - ) - def summarize( self, *, @@ -492,11 +401,6 @@ def assistants(self) -> AsyncAssistantsResource: def audio(self) -> AsyncAudioResource: return AsyncAudioResource(self._client) - @cached_property - def chat(self) -> AsyncChatResource: - """Generate text with LLMs""" - return AsyncChatResource(self._client) - @cached_property def clusters(self) -> AsyncClustersResource: """Identify common themes and patterns in your embedded documents""" @@ -556,47 +460,6 @@ def with_streaming_response(self) -> AsyncAIResourceWithStreamingResponse: """ return AsyncAIResourceWithStreamingResponse(self) - @typing_extensions.deprecated("deprecated") - async def create_response_deprecated( - self, - *, - response_request: Dict[str, object], - # 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, - ) -> AICreateResponseDeprecatedResponse: - """**Deprecated**: Use `POST /v2/ai/openai/responses` instead. - - This endpoint is - compatible with the - [OpenAI Responses API](https://developers.openai.com/api/reference/responses/overview) - and may be used with the OpenAI JS or Python SDK. Response id parameter is not - supported at the moment. Use the `conversation` parameter with a Telnyx - Conversation ID to leverage persistent conversations. - - 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 - """ - return await self._post( - "/ai/responses", - body=await async_maybe_transform( - response_request, ai_create_response_deprecated_params.AICreateResponseDeprecatedParams - ), - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - cast_to=AICreateResponseDeprecatedResponse, - ) - async def retrieve_conversation_histories( self, *, @@ -747,36 +610,6 @@ async def retrieve_conversation_histories( cast_to=AIRetrieveConversationHistoriesResponse, ) - @typing_extensions.deprecated("deprecated") - async def retrieve_models( - 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, - ) -> ModelsResponse: - """ - **Deprecated**: Use `GET /v2/ai/openai/models` instead. - - Returns the same `ModelsResponse` payload as the OpenAI-compatible endpoint — - open-source LLMs hosted on Telnyx (e.g. `moonshotai/Kimi-K2.6`, - `zai-org/GLM-5.1-FP8`, `MiniMaxAI/MiniMax-M2.7`), embedding models, and - fine-tuned models — kept around for backwards compatibility. New integrations - should use `/v2/ai/openai/models`. - - Model ids follow the `{organization}/{model_name}` convention from Hugging Face. - """ - return await self._get( - "/ai/models", - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - cast_to=ModelsResponse, - ) - async def summarize( self, *, @@ -839,19 +672,9 @@ class AIResourceWithRawResponse: def __init__(self, ai: AIResource) -> None: self._ai = ai - self.create_response_deprecated = ( # pyright: ignore[reportDeprecated] - to_raw_response_wrapper( - ai.create_response_deprecated, # pyright: ignore[reportDeprecated], - ) - ) self.retrieve_conversation_histories = to_raw_response_wrapper( ai.retrieve_conversation_histories, ) - self.retrieve_models = ( # pyright: ignore[reportDeprecated] - to_raw_response_wrapper( - ai.retrieve_models, # pyright: ignore[reportDeprecated], - ) - ) self.summarize = to_raw_response_wrapper( ai.summarize, ) @@ -865,11 +688,6 @@ def assistants(self) -> AssistantsResourceWithRawResponse: def audio(self) -> AudioResourceWithRawResponse: return AudioResourceWithRawResponse(self._ai.audio) - @cached_property - def chat(self) -> ChatResourceWithRawResponse: - """Generate text with LLMs""" - return ChatResourceWithRawResponse(self._ai.chat) - @cached_property def clusters(self) -> ClustersResourceWithRawResponse: """Identify common themes and patterns in your embedded documents""" @@ -915,19 +733,9 @@ class AsyncAIResourceWithRawResponse: def __init__(self, ai: AsyncAIResource) -> None: self._ai = ai - self.create_response_deprecated = ( # pyright: ignore[reportDeprecated] - async_to_raw_response_wrapper( - ai.create_response_deprecated, # pyright: ignore[reportDeprecated], - ) - ) self.retrieve_conversation_histories = async_to_raw_response_wrapper( ai.retrieve_conversation_histories, ) - self.retrieve_models = ( # pyright: ignore[reportDeprecated] - async_to_raw_response_wrapper( - ai.retrieve_models, # pyright: ignore[reportDeprecated], - ) - ) self.summarize = async_to_raw_response_wrapper( ai.summarize, ) @@ -941,11 +749,6 @@ def assistants(self) -> AsyncAssistantsResourceWithRawResponse: def audio(self) -> AsyncAudioResourceWithRawResponse: return AsyncAudioResourceWithRawResponse(self._ai.audio) - @cached_property - def chat(self) -> AsyncChatResourceWithRawResponse: - """Generate text with LLMs""" - return AsyncChatResourceWithRawResponse(self._ai.chat) - @cached_property def clusters(self) -> AsyncClustersResourceWithRawResponse: """Identify common themes and patterns in your embedded documents""" @@ -991,19 +794,9 @@ class AIResourceWithStreamingResponse: def __init__(self, ai: AIResource) -> None: self._ai = ai - self.create_response_deprecated = ( # pyright: ignore[reportDeprecated] - to_streamed_response_wrapper( - ai.create_response_deprecated, # pyright: ignore[reportDeprecated], - ) - ) self.retrieve_conversation_histories = to_streamed_response_wrapper( ai.retrieve_conversation_histories, ) - self.retrieve_models = ( # pyright: ignore[reportDeprecated] - to_streamed_response_wrapper( - ai.retrieve_models, # pyright: ignore[reportDeprecated], - ) - ) self.summarize = to_streamed_response_wrapper( ai.summarize, ) @@ -1017,11 +810,6 @@ def assistants(self) -> AssistantsResourceWithStreamingResponse: def audio(self) -> AudioResourceWithStreamingResponse: return AudioResourceWithStreamingResponse(self._ai.audio) - @cached_property - def chat(self) -> ChatResourceWithStreamingResponse: - """Generate text with LLMs""" - return ChatResourceWithStreamingResponse(self._ai.chat) - @cached_property def clusters(self) -> ClustersResourceWithStreamingResponse: """Identify common themes and patterns in your embedded documents""" @@ -1067,19 +855,9 @@ class AsyncAIResourceWithStreamingResponse: def __init__(self, ai: AsyncAIResource) -> None: self._ai = ai - self.create_response_deprecated = ( # pyright: ignore[reportDeprecated] - async_to_streamed_response_wrapper( - ai.create_response_deprecated, # pyright: ignore[reportDeprecated], - ) - ) self.retrieve_conversation_histories = async_to_streamed_response_wrapper( ai.retrieve_conversation_histories, ) - self.retrieve_models = ( # pyright: ignore[reportDeprecated] - async_to_streamed_response_wrapper( - ai.retrieve_models, # pyright: ignore[reportDeprecated], - ) - ) self.summarize = async_to_streamed_response_wrapper( ai.summarize, ) @@ -1093,11 +871,6 @@ def assistants(self) -> AsyncAssistantsResourceWithStreamingResponse: def audio(self) -> AsyncAudioResourceWithStreamingResponse: return AsyncAudioResourceWithStreamingResponse(self._ai.audio) - @cached_property - def chat(self) -> AsyncChatResourceWithStreamingResponse: - """Generate text with LLMs""" - return AsyncChatResourceWithStreamingResponse(self._ai.chat) - @cached_property def clusters(self) -> AsyncClustersResourceWithStreamingResponse: """Identify common themes and patterns in your embedded documents""" diff --git a/src/telnyx/resources/ai/chat.py b/src/telnyx/resources/ai/chat.py deleted file mode 100644 index f7b64ba81..000000000 --- a/src/telnyx/resources/ai/chat.py +++ /dev/null @@ -1,455 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -import typing_extensions -from typing import Dict, Union, Iterable -from typing_extensions import Literal - -import httpx - -from ..._types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, omit, not_given -from ..._utils import maybe_transform, async_maybe_transform -from ..._compat import cached_property -from ...types.ai import chat_create_completion_params -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.ai.chat_create_completion_response import ChatCreateCompletionResponse - -__all__ = ["ChatResource", "AsyncChatResource"] - - -class ChatResource(SyncAPIResource): - """Generate text with LLMs""" - - @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/team-telnyx/telnyx-python#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/team-telnyx/telnyx-python#with_streaming_response - """ - return ChatResourceWithStreamingResponse(self) - - @typing_extensions.deprecated("deprecated") - def create_completion( - self, - *, - messages: Iterable[chat_create_completion_params.Message], - api_key_ref: str | Omit = omit, - best_of: int | Omit = omit, - early_stopping: bool | Omit = omit, - enable_thinking: bool | Omit = omit, - frequency_penalty: float | Omit = omit, - guided_choice: SequenceNotStr[str] | Omit = omit, - guided_json: Dict[str, object] | Omit = omit, - guided_regex: str | Omit = omit, - length_penalty: float | Omit = omit, - logprobs: bool | Omit = omit, - max_tokens: int | Omit = omit, - min_p: float | Omit = omit, - model: str | Omit = omit, - n: float | Omit = omit, - presence_penalty: float | Omit = omit, - response_format: chat_create_completion_params.ResponseFormat | Omit = omit, - seed: int | Omit = omit, - stop: Union[str, SequenceNotStr[str]] | Omit = omit, - stream: bool | Omit = omit, - temperature: float | Omit = omit, - tool_choice: Literal["none", "auto", "required"] | Omit = omit, - tools: Iterable[chat_create_completion_params.Tool] | Omit = omit, - top_logprobs: int | Omit = omit, - top_p: float | Omit = omit, - use_beam_search: bool | Omit = omit, - # 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, - ) -> ChatCreateCompletionResponse: - """**Deprecated**: Use `POST /v2/ai/openai/chat/completions` instead. - - Chat with a - language model. This endpoint is consistent with the - [OpenAI Chat Completions API](https://platform.openai.com/docs/api-reference/chat) - and may be used with the OpenAI JS or Python SDK. - - Args: - messages: A list of the previous chat messages for context. - - api_key_ref: If you are using an external inference provider like xAI or OpenAI, this field - allows you to pass along a reference to your API key. After creating an - [integration secret](https://developers.telnyx.com/api-reference/integration-secrets/create-a-secret) - for you API key, pass the secret's `identifier` in this field. - - best_of: This is used with `use_beam_search` to determine how many candidate beams to - explore. - - early_stopping: This is used with `use_beam_search`. If `true`, generation stops as soon as - there are `best_of` complete candidates; if `false`, a heuristic is applied and - the generation stops when is it very unlikely to find better candidates. - - enable_thinking: Whether to enable the thinking/reasoning phase for models that support it (e.g., - QwQ, Qwen3). When set to false, the model will skip the internal reasoning step - and respond directly, which can reduce latency. Defaults to true. - - frequency_penalty: Higher values will penalize the model from repeating the same output tokens. - - guided_choice: If specified, the output will be exactly one of the choices. - - guided_json: Must be a valid JSON schema. If specified, the output will follow the JSON - schema. - - guided_regex: If specified, the output will follow the regex pattern. - - length_penalty: This is used with `use_beam_search` to prefer shorter or longer completions. - - logprobs: Whether to return log probabilities of the output tokens or not. If true, - returns the log probabilities of each output token returned in the `content` of - `message`. - - max_tokens: Maximum number of completion tokens the model should generate. - - min_p: This is an alternative to `top_p` that - [many prefer](https://github.com/huggingface/transformers/issues/27670). Must be - in [0, 1]. - - model: The language model to chat with. - - n: This will return multiple choices for you instead of a single chat completion. - - presence_penalty: Higher values will penalize the model from repeating the same output tokens. - - response_format: Use this is you want to guarantee a JSON output without defining a schema. For - control over the schema, use `guided_json`. - - seed: If specified, the system will make a best effort to sample deterministically, - such that repeated requests with the same `seed` and parameters should return - the same result. - - stop: Up to 4 sequences where the API will stop generating further tokens. The - returned text will not contain the stop sequence. - - stream: Whether or not to stream data-only server-sent events as they become available. - - temperature: Adjusts the "creativity" of the model. Lower values make the model more - deterministic and repetitive, while higher values make the model more random and - creative. - - tools: The `function` tool type follows the same schema as the - [OpenAI Chat Completions API](https://platform.openai.com/docs/api-reference/chat). - The `retrieval` tool type is unique to Telnyx. You may pass a list of - [embedded storage buckets](https://developers.telnyx.com/api-reference/embeddings/embed-documents) - for retrieval-augmented generation. - - top_logprobs: This is used with `logprobs`. An integer between 0 and 20 specifying the number - of most likely tokens to return at each token position, each with an associated - log probability. - - top_p: An alternative or complement to `temperature`. This adjusts how many of the top - possibilities to consider. - - use_beam_search: Setting this to `true` will allow the model to - [explore more completion options](https://huggingface.co/blog/how-to-generate#beam-search). - This is not supported by OpenAI. - - 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( - "/ai/chat/completions", - body=maybe_transform( - { - "messages": messages, - "api_key_ref": api_key_ref, - "best_of": best_of, - "early_stopping": early_stopping, - "enable_thinking": enable_thinking, - "frequency_penalty": frequency_penalty, - "guided_choice": guided_choice, - "guided_json": guided_json, - "guided_regex": guided_regex, - "length_penalty": length_penalty, - "logprobs": logprobs, - "max_tokens": max_tokens, - "min_p": min_p, - "model": model, - "n": n, - "presence_penalty": presence_penalty, - "response_format": response_format, - "seed": seed, - "stop": stop, - "stream": stream, - "temperature": temperature, - "tool_choice": tool_choice, - "tools": tools, - "top_logprobs": top_logprobs, - "top_p": top_p, - "use_beam_search": use_beam_search, - }, - chat_create_completion_params.ChatCreateCompletionParams, - ), - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - cast_to=ChatCreateCompletionResponse, - ) - - -class AsyncChatResource(AsyncAPIResource): - """Generate text with LLMs""" - - @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/team-telnyx/telnyx-python#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/team-telnyx/telnyx-python#with_streaming_response - """ - return AsyncChatResourceWithStreamingResponse(self) - - @typing_extensions.deprecated("deprecated") - async def create_completion( - self, - *, - messages: Iterable[chat_create_completion_params.Message], - api_key_ref: str | Omit = omit, - best_of: int | Omit = omit, - early_stopping: bool | Omit = omit, - enable_thinking: bool | Omit = omit, - frequency_penalty: float | Omit = omit, - guided_choice: SequenceNotStr[str] | Omit = omit, - guided_json: Dict[str, object] | Omit = omit, - guided_regex: str | Omit = omit, - length_penalty: float | Omit = omit, - logprobs: bool | Omit = omit, - max_tokens: int | Omit = omit, - min_p: float | Omit = omit, - model: str | Omit = omit, - n: float | Omit = omit, - presence_penalty: float | Omit = omit, - response_format: chat_create_completion_params.ResponseFormat | Omit = omit, - seed: int | Omit = omit, - stop: Union[str, SequenceNotStr[str]] | Omit = omit, - stream: bool | Omit = omit, - temperature: float | Omit = omit, - tool_choice: Literal["none", "auto", "required"] | Omit = omit, - tools: Iterable[chat_create_completion_params.Tool] | Omit = omit, - top_logprobs: int | Omit = omit, - top_p: float | Omit = omit, - use_beam_search: bool | Omit = omit, - # 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, - ) -> ChatCreateCompletionResponse: - """**Deprecated**: Use `POST /v2/ai/openai/chat/completions` instead. - - Chat with a - language model. This endpoint is consistent with the - [OpenAI Chat Completions API](https://platform.openai.com/docs/api-reference/chat) - and may be used with the OpenAI JS or Python SDK. - - Args: - messages: A list of the previous chat messages for context. - - api_key_ref: If you are using an external inference provider like xAI or OpenAI, this field - allows you to pass along a reference to your API key. After creating an - [integration secret](https://developers.telnyx.com/api-reference/integration-secrets/create-a-secret) - for you API key, pass the secret's `identifier` in this field. - - best_of: This is used with `use_beam_search` to determine how many candidate beams to - explore. - - early_stopping: This is used with `use_beam_search`. If `true`, generation stops as soon as - there are `best_of` complete candidates; if `false`, a heuristic is applied and - the generation stops when is it very unlikely to find better candidates. - - enable_thinking: Whether to enable the thinking/reasoning phase for models that support it (e.g., - QwQ, Qwen3). When set to false, the model will skip the internal reasoning step - and respond directly, which can reduce latency. Defaults to true. - - frequency_penalty: Higher values will penalize the model from repeating the same output tokens. - - guided_choice: If specified, the output will be exactly one of the choices. - - guided_json: Must be a valid JSON schema. If specified, the output will follow the JSON - schema. - - guided_regex: If specified, the output will follow the regex pattern. - - length_penalty: This is used with `use_beam_search` to prefer shorter or longer completions. - - logprobs: Whether to return log probabilities of the output tokens or not. If true, - returns the log probabilities of each output token returned in the `content` of - `message`. - - max_tokens: Maximum number of completion tokens the model should generate. - - min_p: This is an alternative to `top_p` that - [many prefer](https://github.com/huggingface/transformers/issues/27670). Must be - in [0, 1]. - - model: The language model to chat with. - - n: This will return multiple choices for you instead of a single chat completion. - - presence_penalty: Higher values will penalize the model from repeating the same output tokens. - - response_format: Use this is you want to guarantee a JSON output without defining a schema. For - control over the schema, use `guided_json`. - - seed: If specified, the system will make a best effort to sample deterministically, - such that repeated requests with the same `seed` and parameters should return - the same result. - - stop: Up to 4 sequences where the API will stop generating further tokens. The - returned text will not contain the stop sequence. - - stream: Whether or not to stream data-only server-sent events as they become available. - - temperature: Adjusts the "creativity" of the model. Lower values make the model more - deterministic and repetitive, while higher values make the model more random and - creative. - - tools: The `function` tool type follows the same schema as the - [OpenAI Chat Completions API](https://platform.openai.com/docs/api-reference/chat). - The `retrieval` tool type is unique to Telnyx. You may pass a list of - [embedded storage buckets](https://developers.telnyx.com/api-reference/embeddings/embed-documents) - for retrieval-augmented generation. - - top_logprobs: This is used with `logprobs`. An integer between 0 and 20 specifying the number - of most likely tokens to return at each token position, each with an associated - log probability. - - top_p: An alternative or complement to `temperature`. This adjusts how many of the top - possibilities to consider. - - use_beam_search: Setting this to `true` will allow the model to - [explore more completion options](https://huggingface.co/blog/how-to-generate#beam-search). - This is not supported by OpenAI. - - 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( - "/ai/chat/completions", - body=await async_maybe_transform( - { - "messages": messages, - "api_key_ref": api_key_ref, - "best_of": best_of, - "early_stopping": early_stopping, - "enable_thinking": enable_thinking, - "frequency_penalty": frequency_penalty, - "guided_choice": guided_choice, - "guided_json": guided_json, - "guided_regex": guided_regex, - "length_penalty": length_penalty, - "logprobs": logprobs, - "max_tokens": max_tokens, - "min_p": min_p, - "model": model, - "n": n, - "presence_penalty": presence_penalty, - "response_format": response_format, - "seed": seed, - "stop": stop, - "stream": stream, - "temperature": temperature, - "tool_choice": tool_choice, - "tools": tools, - "top_logprobs": top_logprobs, - "top_p": top_p, - "use_beam_search": use_beam_search, - }, - chat_create_completion_params.ChatCreateCompletionParams, - ), - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - cast_to=ChatCreateCompletionResponse, - ) - - -class ChatResourceWithRawResponse: - def __init__(self, chat: ChatResource) -> None: - self._chat = chat - - self.create_completion = ( # pyright: ignore[reportDeprecated] - to_raw_response_wrapper( - chat.create_completion, # pyright: ignore[reportDeprecated], - ) - ) - - -class AsyncChatResourceWithRawResponse: - def __init__(self, chat: AsyncChatResource) -> None: - self._chat = chat - - self.create_completion = ( # pyright: ignore[reportDeprecated] - async_to_raw_response_wrapper( - chat.create_completion, # pyright: ignore[reportDeprecated], - ) - ) - - -class ChatResourceWithStreamingResponse: - def __init__(self, chat: ChatResource) -> None: - self._chat = chat - - self.create_completion = ( # pyright: ignore[reportDeprecated] - to_streamed_response_wrapper( - chat.create_completion, # pyright: ignore[reportDeprecated], - ) - ) - - -class AsyncChatResourceWithStreamingResponse: - def __init__(self, chat: AsyncChatResource) -> None: - self._chat = chat - - self.create_completion = ( # pyright: ignore[reportDeprecated] - async_to_streamed_response_wrapper( - chat.create_completion, # pyright: ignore[reportDeprecated], - ) - ) diff --git a/src/telnyx/resources/ai/tools.py b/src/telnyx/resources/ai/tools.py index 6a194dc9a..9f06225da 100644 --- a/src/telnyx/resources/ai/tools.py +++ b/src/telnyx/resources/ai/tools.py @@ -51,6 +51,7 @@ def create( *, display_name: str, type: str, + client_side_tool: Dict[str, object] | Omit = omit, function: Dict[str, object] | Omit = omit, handoff: Dict[str, object] | Omit = omit, invite: Dict[str, object] | Omit = omit, @@ -82,6 +83,7 @@ def create( { "display_name": display_name, "type": type, + "client_side_tool": client_side_tool, "function": function, "handoff": handoff, "invite": invite, @@ -134,6 +136,7 @@ def update( self, tool_id: str, *, + client_side_tool: Dict[str, object] | Omit = omit, display_name: str | Omit = omit, function: Dict[str, object] | Omit = omit, handoff: Dict[str, object] | Omit = omit, @@ -167,6 +170,7 @@ def update( path_template("/ai/tools/{tool_id}", tool_id=tool_id), body=maybe_transform( { + "client_side_tool": client_side_tool, "display_name": display_name, "function": function, "handoff": handoff, @@ -300,6 +304,7 @@ async def create( *, display_name: str, type: str, + client_side_tool: Dict[str, object] | Omit = omit, function: Dict[str, object] | Omit = omit, handoff: Dict[str, object] | Omit = omit, invite: Dict[str, object] | Omit = omit, @@ -331,6 +336,7 @@ async def create( { "display_name": display_name, "type": type, + "client_side_tool": client_side_tool, "function": function, "handoff": handoff, "invite": invite, @@ -383,6 +389,7 @@ async def update( self, tool_id: str, *, + client_side_tool: Dict[str, object] | Omit = omit, display_name: str | Omit = omit, function: Dict[str, object] | Omit = omit, handoff: Dict[str, object] | Omit = omit, @@ -416,6 +423,7 @@ async def update( path_template("/ai/tools/{tool_id}", tool_id=tool_id), body=await async_maybe_transform( { + "client_side_tool": client_side_tool, "display_name": display_name, "function": function, "handoff": handoff, diff --git a/src/telnyx/resources/calls/actions.py b/src/telnyx/resources/calls/actions.py index b9c4d5815..6d5f5d1a0 100644 --- a/src/telnyx/resources/calls/actions.py +++ b/src/telnyx/resources/calls/actions.py @@ -889,6 +889,9 @@ def gather_using_ai( - **Inworld:** Use `Inworld..` (e.g., `Inworld.Mini.Loretta`, `Inworld.Max.Oliver`, `Inworld.TTS2.Loretta`). Supported models: `Mini`, `Max`, `TTS2`. + - **Fish Audio:** Use `FishAudio..` (e.g., + `FishAudio.s2.1-pro.`). Supported models: `s2.1-pro`, `s2-pro`, + `s1`. `VoiceId` is a Fish Voice-Library reference ID. - **xAI:** Use `xAI.` (e.g., `xAI.eve`). Available voices: `eve`, `ara`, `rex`, `sal`, `leo`. @@ -1154,6 +1157,9 @@ def gather_using_speak( [available voices](https://elevenlabs.io/docs/api-reference/get-voices). - **Telnyx:** Use `Telnyx..` (e.g., `Telnyx.KokoroTTS.af`). Use `voice_settings` to configure voice_speed and other synthesis parameters. + `Bayan` provides Arabic (multiple dialects) and English voices (e.g., + `Telnyx.Bayan.Ahmed`, `Telnyx.Bayan.Amanda`). `Sukhan` provides Urdu voices + (e.g., `Telnyx.Sukhan.urdu-professor`); `voice_speed` is not supported. - **Minimax:** Use `Minimax..` (e.g., `Minimax.speech-02-hd.Wise_Woman`). Supported models: `speech-02-turbo`, `speech-02-hd`, `speech-2.6-turbo`, `speech-2.8-turbo`. Use `voice_settings` @@ -1168,6 +1174,9 @@ def gather_using_speak( `Inworld.Max.Oliver`, `Inworld.TTS2.Loretta`). Supported models: `Mini`, `Max`, `TTS2`. Use `voice_settings` to configure `delivery_mode` (`STABLE`, `BALANCED`, `CREATIVE`), supported by `TTS2` only. + - **Fish Audio:** Use `FishAudio..` (e.g., + `FishAudio.s2.1-pro.`). Supported models: `s2.1-pro`, `s2-pro`, + `s1`. `VoiceId` is a Fish Voice-Library reference ID. - **xAI:** Use `xAI.` (e.g., `xAI.eve`). Available voices: `eve`, `ara`, `rex`, `sal`, `leo`. @@ -1879,6 +1888,9 @@ def speak( [available voices](https://elevenlabs.io/docs/api-reference/get-voices). - **Telnyx:** Use `Telnyx..` (e.g., `Telnyx.KokoroTTS.af`). Use `voice_settings` to configure voice_speed and other synthesis parameters. + `Bayan` provides Arabic (multiple dialects) and English voices (e.g., + `Telnyx.Bayan.Ahmed`, `Telnyx.Bayan.Amanda`). `Sukhan` provides Urdu voices + (e.g., `Telnyx.Sukhan.urdu-professor`); `voice_speed` is not supported. - **Minimax:** Use `Minimax..` (e.g., `Minimax.speech-02-hd.Wise_Woman`). Supported models: `speech-02-turbo`, `speech-02-hd`, `speech-2.6-turbo`, `speech-2.8-turbo`. Use `voice_settings` @@ -1893,6 +1905,9 @@ def speak( `Inworld.Max.Oliver`, `Inworld.TTS2.Loretta`). Supported models: `Mini`, `Max`, `TTS2`. Use `voice_settings` to configure `delivery_mode` (`STABLE`, `BALANCED`, `CREATIVE`), supported by `TTS2` only. + - **Fish Audio:** Use `FishAudio..` (e.g., + `FishAudio.s2.1-pro.`). Supported models: `s2.1-pro`, `s2-pro`, + `s1`. `VoiceId` is a Fish Voice-Library reference ID. - **xAI:** Use `xAI.` (e.g., `xAI.eve`). Available voices: `eve`, `ara`, `rex`, `sal`, `leo`. @@ -2045,6 +2060,9 @@ def start_ai_assistant( - **Inworld:** Use `Inworld..` (e.g., `Inworld.Mini.Loretta`, `Inworld.Max.Oliver`, `Inworld.TTS2.Loretta`). Supported models: `Mini`, `Max`, `TTS2`. + - **Fish Audio:** Use `FishAudio..` (e.g., + `FishAudio.s2.1-pro.`). Supported models: `s2.1-pro`, `s2-pro`, + `s1`. `VoiceId` is a Fish Voice-Library reference ID. - **xAI:** Use `xAI.` (e.g., `xAI.eve`). Available voices: `eve`, `ara`, `rex`, `sal`, `leo`. @@ -2228,6 +2246,9 @@ def start_conversation_relay( - **Inworld:** Use `Inworld..` (e.g., `Inworld.Mini.Loretta`, `Inworld.Max.Oliver`, `Inworld.TTS2.Loretta`). Supported models: `Mini`, `Max`, `TTS2`. + - **Fish Audio:** Use `FishAudio..` (e.g., + `FishAudio.s2.1-pro.`). Supported models: `s2.1-pro`, `s2-pro`, + `s1`. `VoiceId` is a Fish Voice-Library reference ID. - **xAI:** Use `xAI.` (e.g., `xAI.eve`). Available voices: `eve`, `ara`, `rex`, `sal`, `leo`. @@ -4817,6 +4838,9 @@ async def gather_using_ai( - **Inworld:** Use `Inworld..` (e.g., `Inworld.Mini.Loretta`, `Inworld.Max.Oliver`, `Inworld.TTS2.Loretta`). Supported models: `Mini`, `Max`, `TTS2`. + - **Fish Audio:** Use `FishAudio..` (e.g., + `FishAudio.s2.1-pro.`). Supported models: `s2.1-pro`, `s2-pro`, + `s1`. `VoiceId` is a Fish Voice-Library reference ID. - **xAI:** Use `xAI.` (e.g., `xAI.eve`). Available voices: `eve`, `ara`, `rex`, `sal`, `leo`. @@ -5082,6 +5106,9 @@ async def gather_using_speak( [available voices](https://elevenlabs.io/docs/api-reference/get-voices). - **Telnyx:** Use `Telnyx..` (e.g., `Telnyx.KokoroTTS.af`). Use `voice_settings` to configure voice_speed and other synthesis parameters. + `Bayan` provides Arabic (multiple dialects) and English voices (e.g., + `Telnyx.Bayan.Ahmed`, `Telnyx.Bayan.Amanda`). `Sukhan` provides Urdu voices + (e.g., `Telnyx.Sukhan.urdu-professor`); `voice_speed` is not supported. - **Minimax:** Use `Minimax..` (e.g., `Minimax.speech-02-hd.Wise_Woman`). Supported models: `speech-02-turbo`, `speech-02-hd`, `speech-2.6-turbo`, `speech-2.8-turbo`. Use `voice_settings` @@ -5096,6 +5123,9 @@ async def gather_using_speak( `Inworld.Max.Oliver`, `Inworld.TTS2.Loretta`). Supported models: `Mini`, `Max`, `TTS2`. Use `voice_settings` to configure `delivery_mode` (`STABLE`, `BALANCED`, `CREATIVE`), supported by `TTS2` only. + - **Fish Audio:** Use `FishAudio..` (e.g., + `FishAudio.s2.1-pro.`). Supported models: `s2.1-pro`, `s2-pro`, + `s1`. `VoiceId` is a Fish Voice-Library reference ID. - **xAI:** Use `xAI.` (e.g., `xAI.eve`). Available voices: `eve`, `ara`, `rex`, `sal`, `leo`. @@ -5807,6 +5837,9 @@ async def speak( [available voices](https://elevenlabs.io/docs/api-reference/get-voices). - **Telnyx:** Use `Telnyx..` (e.g., `Telnyx.KokoroTTS.af`). Use `voice_settings` to configure voice_speed and other synthesis parameters. + `Bayan` provides Arabic (multiple dialects) and English voices (e.g., + `Telnyx.Bayan.Ahmed`, `Telnyx.Bayan.Amanda`). `Sukhan` provides Urdu voices + (e.g., `Telnyx.Sukhan.urdu-professor`); `voice_speed` is not supported. - **Minimax:** Use `Minimax..` (e.g., `Minimax.speech-02-hd.Wise_Woman`). Supported models: `speech-02-turbo`, `speech-02-hd`, `speech-2.6-turbo`, `speech-2.8-turbo`. Use `voice_settings` @@ -5821,6 +5854,9 @@ async def speak( `Inworld.Max.Oliver`, `Inworld.TTS2.Loretta`). Supported models: `Mini`, `Max`, `TTS2`. Use `voice_settings` to configure `delivery_mode` (`STABLE`, `BALANCED`, `CREATIVE`), supported by `TTS2` only. + - **Fish Audio:** Use `FishAudio..` (e.g., + `FishAudio.s2.1-pro.`). Supported models: `s2.1-pro`, `s2-pro`, + `s1`. `VoiceId` is a Fish Voice-Library reference ID. - **xAI:** Use `xAI.` (e.g., `xAI.eve`). Available voices: `eve`, `ara`, `rex`, `sal`, `leo`. @@ -5973,6 +6009,9 @@ async def start_ai_assistant( - **Inworld:** Use `Inworld..` (e.g., `Inworld.Mini.Loretta`, `Inworld.Max.Oliver`, `Inworld.TTS2.Loretta`). Supported models: `Mini`, `Max`, `TTS2`. + - **Fish Audio:** Use `FishAudio..` (e.g., + `FishAudio.s2.1-pro.`). Supported models: `s2.1-pro`, `s2-pro`, + `s1`. `VoiceId` is a Fish Voice-Library reference ID. - **xAI:** Use `xAI.` (e.g., `xAI.eve`). Available voices: `eve`, `ara`, `rex`, `sal`, `leo`. @@ -6156,6 +6195,9 @@ async def start_conversation_relay( - **Inworld:** Use `Inworld..` (e.g., `Inworld.Mini.Loretta`, `Inworld.Max.Oliver`, `Inworld.TTS2.Loretta`). Supported models: `Mini`, `Max`, `TTS2`. + - **Fish Audio:** Use `FishAudio..` (e.g., + `FishAudio.s2.1-pro.`). Supported models: `s2.1-pro`, `s2-pro`, + `s1`. `VoiceId` is a Fish Voice-Library reference ID. - **xAI:** Use `xAI.` (e.g., `xAI.eve`). Available voices: `eve`, `ara`, `rex`, `sal`, `leo`. diff --git a/src/telnyx/resources/conferences/actions.py b/src/telnyx/resources/conferences/actions.py index a31ea931f..2632eb8ad 100644 --- a/src/telnyx/resources/conferences/actions.py +++ b/src/telnyx/resources/conferences/actions.py @@ -1043,6 +1043,9 @@ def speak( [available voices](https://elevenlabs.io/docs/api-reference/get-voices). - **Telnyx:** Use `Telnyx..` (e.g., `Telnyx.KokoroTTS.af`). Use `voice_settings` to configure voice_speed and other synthesis parameters. + `Bayan` provides Arabic (multiple dialects) and English voices (e.g., + `Telnyx.Bayan.Ahmed`, `Telnyx.Bayan.Amanda`). `Sukhan` provides Urdu voices + (e.g., `Telnyx.Sukhan.urdu-professor`); `voice_speed` is not supported. - **Minimax:** Use `Minimax..` (e.g., `Minimax.speech-02-hd.Wise_Woman`). Supported models: `speech-02-turbo`, `speech-02-hd`, `speech-2.6-turbo`, `speech-2.8-turbo`. Use `voice_settings` @@ -1057,6 +1060,9 @@ def speak( `Inworld.Max.Oliver`, `Inworld.TTS2.Loretta`). Supported models: `Mini`, `Max`, `TTS2`. Use `voice_settings` to configure `delivery_mode` (`STABLE`, `BALANCED`, `CREATIVE`), supported by `TTS2` only. + - **Fish Audio:** Use `FishAudio..` (e.g., + `FishAudio.s2.1-pro.`). Supported models: `s2.1-pro`, `s2-pro`, + `s1`. `VoiceId` is a Fish Voice-Library reference ID. - **xAI:** Use `xAI.` (e.g., `xAI.eve`). Available voices: `eve`, `ara`, `rex`, `sal`, `leo`. @@ -2242,6 +2248,9 @@ async def speak( [available voices](https://elevenlabs.io/docs/api-reference/get-voices). - **Telnyx:** Use `Telnyx..` (e.g., `Telnyx.KokoroTTS.af`). Use `voice_settings` to configure voice_speed and other synthesis parameters. + `Bayan` provides Arabic (multiple dialects) and English voices (e.g., + `Telnyx.Bayan.Ahmed`, `Telnyx.Bayan.Amanda`). `Sukhan` provides Urdu voices + (e.g., `Telnyx.Sukhan.urdu-professor`); `voice_speed` is not supported. - **Minimax:** Use `Minimax..` (e.g., `Minimax.speech-02-hd.Wise_Woman`). Supported models: `speech-02-turbo`, `speech-02-hd`, `speech-2.6-turbo`, `speech-2.8-turbo`. Use `voice_settings` @@ -2256,6 +2265,9 @@ async def speak( `Inworld.Max.Oliver`, `Inworld.TTS2.Loretta`). Supported models: `Mini`, `Max`, `TTS2`. Use `voice_settings` to configure `delivery_mode` (`STABLE`, `BALANCED`, `CREATIVE`), supported by `TTS2` only. + - **Fish Audio:** Use `FishAudio..` (e.g., + `FishAudio.s2.1-pro.`). Supported models: `s2.1-pro`, `s2-pro`, + `s1`. `VoiceId` is a Fish Voice-Library reference ID. - **xAI:** Use `xAI.` (e.g., `xAI.eve`). Available voices: `eve`, `ara`, `rex`, `sal`, `leo`. diff --git a/src/telnyx/resources/messages/messages.py b/src/telnyx/resources/messages/messages.py index 21a77ee78..8696fe3e2 100644 --- a/src/telnyx/resources/messages/messages.py +++ b/src/telnyx/resources/messages/messages.py @@ -19,7 +19,6 @@ from ...types import ( message_send_params, message_schedule_params, - message_send_whatsapp_params, message_send_group_mms_params, message_send_long_code_params, message_send_short_code_params, @@ -40,8 +39,6 @@ from ...types.message_send_response import MessageSendResponse from ...types.message_retrieve_response import MessageRetrieveResponse from ...types.message_schedule_response import MessageScheduleResponse -from ...types.message_send_whatsapp_response import MessageSendWhatsappResponse -from ...types.whatsapp_message_content_param import WhatsappMessageContentParam from ...types.message_send_group_mms_response import MessageSendGroupMmsResponse from ...types.message_send_long_code_response import MessageSendLongCodeResponse from ...types.message_send_short_code_response import MessageSendShortCodeResponse @@ -54,6 +51,8 @@ class MessagesResource(SyncAPIResource): + """Messages""" + @cached_property def rcs(self) -> RcsResource: """Send RCS messages""" @@ -739,63 +738,6 @@ def send_short_code( cast_to=MessageSendShortCodeResponse, ) - def send_whatsapp( - self, - *, - from_: str, - to: str, - whatsapp_message: WhatsappMessageContentParam, - messaging_profile_id: str | Omit = omit, - type: Literal["WHATSAPP"] | Omit = omit, - webhook_url: str | Omit = omit, - # 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, - ) -> MessageSendWhatsappResponse: - """ - Send a Whatsapp message - - Args: - from_: Phone number in +E.164 format associated with Whatsapp account - - to: Phone number in +E.164 format - - messaging_profile_id: Messaging profile ID - required if the 'from' number is not SMS-enabled - - type: Message type - must be set to "WHATSAPP" - - webhook_url: The URL where webhooks related to this message will be sent. - - 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( - "/messages/whatsapp", - body=maybe_transform( - { - "from_": from_, - "to": to, - "whatsapp_message": whatsapp_message, - "messaging_profile_id": messaging_profile_id, - "type": type, - "webhook_url": webhook_url, - }, - message_send_whatsapp_params.MessageSendWhatsappParams, - ), - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - cast_to=MessageSendWhatsappResponse, - ) - def send_with_alphanumeric_sender( self, *, @@ -862,6 +804,8 @@ def send_with_alphanumeric_sender( class AsyncMessagesResource(AsyncAPIResource): + """Messages""" + @cached_property def rcs(self) -> AsyncRcsResource: """Send RCS messages""" @@ -1547,63 +1491,6 @@ async def send_short_code( cast_to=MessageSendShortCodeResponse, ) - async def send_whatsapp( - self, - *, - from_: str, - to: str, - whatsapp_message: WhatsappMessageContentParam, - messaging_profile_id: str | Omit = omit, - type: Literal["WHATSAPP"] | Omit = omit, - webhook_url: str | Omit = omit, - # 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, - ) -> MessageSendWhatsappResponse: - """ - Send a Whatsapp message - - Args: - from_: Phone number in +E.164 format associated with Whatsapp account - - to: Phone number in +E.164 format - - messaging_profile_id: Messaging profile ID - required if the 'from' number is not SMS-enabled - - type: Message type - must be set to "WHATSAPP" - - webhook_url: The URL where webhooks related to this message will be sent. - - 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( - "/messages/whatsapp", - body=await async_maybe_transform( - { - "from_": from_, - "to": to, - "whatsapp_message": whatsapp_message, - "messaging_profile_id": messaging_profile_id, - "type": type, - "webhook_url": webhook_url, - }, - message_send_whatsapp_params.MessageSendWhatsappParams, - ), - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - cast_to=MessageSendWhatsappResponse, - ) - async def send_with_alphanumeric_sender( self, *, @@ -1700,9 +1587,6 @@ def __init__(self, messages: MessagesResource) -> None: self.send_short_code = to_raw_response_wrapper( messages.send_short_code, ) - self.send_whatsapp = to_raw_response_wrapper( - messages.send_whatsapp, - ) self.send_with_alphanumeric_sender = to_raw_response_wrapper( messages.send_with_alphanumeric_sender, ) @@ -1744,9 +1628,6 @@ def __init__(self, messages: AsyncMessagesResource) -> None: self.send_short_code = async_to_raw_response_wrapper( messages.send_short_code, ) - self.send_whatsapp = async_to_raw_response_wrapper( - messages.send_whatsapp, - ) self.send_with_alphanumeric_sender = async_to_raw_response_wrapper( messages.send_with_alphanumeric_sender, ) @@ -1788,9 +1669,6 @@ def __init__(self, messages: MessagesResource) -> None: self.send_short_code = to_streamed_response_wrapper( messages.send_short_code, ) - self.send_whatsapp = to_streamed_response_wrapper( - messages.send_whatsapp, - ) self.send_with_alphanumeric_sender = to_streamed_response_wrapper( messages.send_with_alphanumeric_sender, ) @@ -1832,9 +1710,6 @@ def __init__(self, messages: AsyncMessagesResource) -> None: self.send_short_code = async_to_streamed_response_wrapper( messages.send_short_code, ) - self.send_whatsapp = async_to_streamed_response_wrapper( - messages.send_whatsapp, - ) self.send_with_alphanumeric_sender = async_to_streamed_response_wrapper( messages.send_with_alphanumeric_sender, ) diff --git a/src/telnyx/types/__init__.py b/src/telnyx/types/__init__.py index 9753370dd..feb74c81c 100644 --- a/src/telnyx/types/__init__.py +++ b/src/telnyx/types/__init__.py @@ -118,7 +118,6 @@ from .sim_card_order import SimCardOrder as SimCardOrder from .uac_connection import UacConnection as UacConnection from .verify_profile import VerifyProfile as VerifyProfile -from .whatsapp_media import WhatsappMedia as WhatsappMedia from .wireguard_peer import WireguardPeer as WireguardPeer from .wireless_error import WirelessError as WirelessError from .access_ip_range import AccessIPRange as AccessIPRange @@ -160,7 +159,6 @@ from .user_requirement import UserRequirement as UserRequirement from .voice_clone_data import VoiceCloneData as VoiceCloneData from .webhook_delivery import WebhookDelivery as WebhookDelivery -from .whatsapp_contact import WhatsappContact as WhatsappContact from .available_service import AvailableService as AvailableService from .call_fork_started import CallForkStarted as CallForkStarted from .call_fork_stopped import CallForkStopped as CallForkStopped @@ -178,8 +176,6 @@ from .requirement_group import RequirementGroup as RequirementGroup from .texml_application import TexmlApplication as TexmlApplication from .voice_design_data import VoiceDesignData as VoiceDesignData -from .whatsapp_location import WhatsappLocation as WhatsappLocation -from .whatsapp_reaction import WhatsappReaction as WhatsappReaction from .call_dial_response import CallDialResponse as CallDialResponse from .call_dtmf_received import CallDtmfReceived as CallDtmfReceived from .call_refer_started import CallReferStarted as CallReferStarted @@ -272,8 +268,6 @@ from .usage_payment_method import UsagePaymentMethod as UsagePaymentMethod from .user_tag_list_params import UserTagListParams as UserTagListParams from .voice_clone_response import VoiceCloneResponse as VoiceCloneResponse -from .whatsapp_interactive import WhatsappInteractive as WhatsappInteractive -from .whatsapp_media_param import WhatsappMediaParam as WhatsappMediaParam from .wireguard_peer_param import WireguardPeerParam as WireguardPeerParam from .address_create_params import AddressCreateParams as AddressCreateParams from .ai_summarize_response import AISummarizeResponse as AISummarizeResponse @@ -339,7 +333,6 @@ ReconnectingEvent as ReconnectingEvent, ReconnectingOverrides as ReconnectingOverrides, ) -from .whatsapp_contact_param import WhatsappContactParam as WhatsappContactParam from .address_create_response import AddressCreateResponse as AddressCreateResponse from .address_delete_response import AddressDeleteResponse as AddressDeleteResponse from .audit_event_list_params import AuditEventListParams as AuditEventListParams @@ -381,8 +374,6 @@ from .transcribe_client_event import TranscribeClientEvent as TranscribeClientEvent from .transcribe_server_event import TranscribeServerEvent as TranscribeServerEvent from .voice_clone_list_params import VoiceCloneListParams as VoiceCloneListParams -from .whatsapp_location_param import WhatsappLocationParam as WhatsappLocationParam -from .whatsapp_reaction_param import WhatsappReactionParam as WhatsappReactionParam from .azure_configuration_data import AzureConfigurationData as AzureConfigurationData from .call_control_application import CallControlApplication as CallControlApplication from .call_event_list_response import CallEventListResponse as CallEventListResponse @@ -414,7 +405,6 @@ from .usage_report_list_params import UsageReportListParams as UsageReportListParams from .user_address_list_params import UserAddressListParams as UserAddressListParams from .voice_design_list_params import VoiceDesignListParams as VoiceDesignListParams -from .whatsapp_message_content import WhatsappMessageContent as WhatsappMessageContent from .wireguard_interface_read import WireguardInterfaceRead as WireguardInterfaceRead from .address_retrieve_response import AddressRetrieveResponse as AddressRetrieveResponse from .audit_event_list_response import AuditEventListResponse as AuditEventListResponse @@ -485,7 +475,6 @@ from .verify_profile_list_params import VerifyProfileListParams as VerifyProfileListParams from .voice_design_create_params import VoiceDesignCreateParams as VoiceDesignCreateParams from .voice_design_rename_params import VoiceDesignRenameParams as VoiceDesignRenameParams -from .whatsapp_interactive_param import WhatsappInteractiveParam as WhatsappInteractiveParam from .wireguard_peer_list_params import WireguardPeerListParams as WireguardPeerListParams from .access_ip_range_list_params import AccessIPRangeListParams as AccessIPRangeListParams from .billing_group_create_params import BillingGroupCreateParams as BillingGroupCreateParams @@ -529,7 +518,6 @@ from .create_verification_response import CreateVerificationResponse as CreateVerificationResponse from .custom_storage_configuration import CustomStorageConfiguration as CustomStorageConfiguration from .gcs_configuration_data_param import GcsConfigurationDataParam as GcsConfigurationDataParam -from .message_send_whatsapp_params import MessageSendWhatsappParams as MessageSendWhatsappParams from .messaging_metrics_time_frame import MessagingMetricsTimeFrame as MessagingMetricsTimeFrame from .messaging_optout_list_params import MessagingOptoutListParams as MessagingOptoutListParams from .network_coverage_list_params import NetworkCoverageListParams as NetworkCoverageListParams @@ -627,7 +615,6 @@ from .inventory_coverage_list_params import InventoryCoverageListParams as InventoryCoverageListParams from .list_retrieve_by_zone_response import ListRetrieveByZoneResponse as ListRetrieveByZoneResponse from .message_send_short_code_params import MessageSendShortCodeParams as MessageSendShortCodeParams -from .message_send_whatsapp_response import MessageSendWhatsappResponse as MessageSendWhatsappResponse from .messaging_optout_list_response import MessagingOptoutListResponse as MessagingOptoutListResponse from .network_coverage_list_response import NetworkCoverageListResponse as NetworkCoverageListResponse from .network_interface_region_param import NetworkInterfaceRegionParam as NetworkInterfaceRegionParam @@ -659,7 +646,6 @@ from .user_address_retrieve_response import UserAddressRetrieveResponse as UserAddressRetrieveResponse from .verification_retrieve_response import VerificationRetrieveResponse as VerificationRetrieveResponse from .virtual_cross_connect_combined import VirtualCrossConnectCombined as VirtualCrossConnectCombined -from .whatsapp_message_content_param import WhatsappMessageContentParam as WhatsappMessageContentParam from .wireguard_peer_create_response import WireguardPeerCreateResponse as WireguardPeerCreateResponse from .wireguard_peer_delete_response import WireguardPeerDeleteResponse as WireguardPeerDeleteResponse from .wireguard_peer_update_response import WireguardPeerUpdateResponse as WireguardPeerUpdateResponse @@ -865,7 +851,6 @@ from .voice_design_download_sample_params import VoiceDesignDownloadSampleParams as VoiceDesignDownloadSampleParams from .wireguard_interface_create_response import WireguardInterfaceCreateResponse as WireguardInterfaceCreateResponse from .wireguard_interface_delete_response import WireguardInterfaceDeleteResponse as WireguardInterfaceDeleteResponse -from .ai_create_response_deprecated_params import AICreateResponseDeprecatedParams as AICreateResponseDeprecatedParams from .alphanumeric_sender_id_create_params import AlphanumericSenderIDCreateParams as AlphanumericSenderIDCreateParams from .available_phone_number_list_response import AvailablePhoneNumberListResponse as AvailablePhoneNumberListResponse from .call_control_application_list_params import CallControlApplicationListParams as CallControlApplicationListParams @@ -997,9 +982,6 @@ from .wireguard_interface_retrieve_response import ( WireguardInterfaceRetrieveResponse as WireguardInterfaceRetrieveResponse, ) -from .ai_create_response_deprecated_response import ( - AICreateResponseDeprecatedResponse as AICreateResponseDeprecatedResponse, -) from .alphanumeric_sender_id_create_response import ( AlphanumericSenderIDCreateResponse as AlphanumericSenderIDCreateResponse, ) diff --git a/src/telnyx/types/ai/__init__.py b/src/telnyx/types/ai/__init__.py index 704f64d74..d7d8adcca 100644 --- a/src/telnyx/types/ai/__init__.py +++ b/src/telnyx/types/ai/__init__.py @@ -63,10 +63,8 @@ from .assistant_get_texml_response import AssistantGetTexmlResponse as AssistantGetTexmlResponse from .transcription_settings_param import TranscriptionSettingsParam as TranscriptionSettingsParam from .audio_visualizer_config_param import AudioVisualizerConfigParam as AudioVisualizerConfigParam -from .chat_create_completion_params import ChatCreateCompletionParams as ChatCreateCompletionParams from .mission_update_mission_params import MissionUpdateMissionParams as MissionUpdateMissionParams from .openai_create_response_params import OpenAICreateResponseParams as OpenAICreateResponseParams -from .chat_create_completion_response import ChatCreateCompletionResponse as ChatCreateCompletionResponse from .conversation_add_message_params import ConversationAddMessageParams as ConversationAddMessageParams from .openai_create_response_response import OpenAICreateResponseResponse as OpenAICreateResponseResponse from .embedding_similarity_search_params import EmbeddingSimilaritySearchParams as EmbeddingSimilaritySearchParams diff --git a/src/telnyx/types/ai/assistant_tool.py b/src/telnyx/types/ai/assistant_tool.py index 6772d6487..549d51a50 100644 --- a/src/telnyx/types/ai/assistant_tool.py +++ b/src/telnyx/types/ai/assistant_tool.py @@ -15,6 +15,9 @@ __all__ = [ "AssistantTool", + "ClientSideTool", + "ClientSideToolClientSideTool", + "ClientSideToolClientSideToolParameters", "Handoff", "HandoffHandoff", "HandoffHandoffAIAssistant", @@ -45,6 +48,43 @@ ] +class ClientSideToolClientSideToolParameters(BaseModel): + """The parameters the tool accepts, described as a JSON Schema object. + + See the [JSON Schema reference](https://json-schema.org/understanding-json-schema) for documentation about the format + """ + + properties: Optional[Dict[str, object]] = None + """The properties of the parameters.""" + + required: Optional[List[str]] = None + """The required properties of the parameters.""" + + type: Optional[Literal["object"]] = None + + +class ClientSideToolClientSideTool(BaseModel): + description: str + """The description of the tool.""" + + name: str + """The name of the tool.""" + + parameters: ClientSideToolClientSideToolParameters + """The parameters the tool accepts, described as a JSON Schema object. + + See the + [JSON Schema reference](https://json-schema.org/understanding-json-schema) for + documentation about the format + """ + + +class ClientSideTool(BaseModel): + client_side_tool: ClientSideToolClientSideTool + + type: Literal["client_side_tool"] + + class HandoffHandoffAIAssistant(BaseModel): id: str """The ID of the assistant to hand off to.""" @@ -438,6 +478,7 @@ class SkipTurn(BaseModel): AssistantTool: TypeAlias = Annotated[ Union[ InferenceEmbeddingWebhookToolParams, + ClientSideTool, RetrievalTool, Handoff, HangupTool, diff --git a/src/telnyx/types/ai/assistant_tool_param.py b/src/telnyx/types/ai/assistant_tool_param.py index f2ad8bc6d..a57687473 100644 --- a/src/telnyx/types/ai/assistant_tool_param.py +++ b/src/telnyx/types/ai/assistant_tool_param.py @@ -5,12 +5,16 @@ from typing import Dict, Union, Iterable, Optional from typing_extensions import Literal, Required, TypeAlias, TypedDict +from ..._types import SequenceNotStr from .hangup_tool_param import HangupToolParam from .retrieval_tool_param import RetrievalToolParam from .inference_embedding_webhook_tool_params_param import InferenceEmbeddingWebhookToolParamsParam __all__ = [ "AssistantToolParam", + "ClientSideTool", + "ClientSideToolClientSideTool", + "ClientSideToolClientSideToolParameters", "Handoff", "HandoffHandoff", "HandoffHandoffAIAssistant", @@ -41,6 +45,43 @@ ] +class ClientSideToolClientSideToolParameters(TypedDict, total=False): + """The parameters the tool accepts, described as a JSON Schema object. + + See the [JSON Schema reference](https://json-schema.org/understanding-json-schema) for documentation about the format + """ + + properties: Dict[str, object] + """The properties of the parameters.""" + + required: SequenceNotStr[str] + """The required properties of the parameters.""" + + type: Literal["object"] + + +class ClientSideToolClientSideTool(TypedDict, total=False): + description: Required[str] + """The description of the tool.""" + + name: Required[str] + """The name of the tool.""" + + parameters: Required[ClientSideToolClientSideToolParameters] + """The parameters the tool accepts, described as a JSON Schema object. + + See the + [JSON Schema reference](https://json-schema.org/understanding-json-schema) for + documentation about the format + """ + + +class ClientSideTool(TypedDict, total=False): + client_side_tool: Required[ClientSideToolClientSideTool] + + type: Required[Literal["client_side_tool"]] + + class HandoffHandoffAIAssistant(TypedDict, total=False): id: Required[str] """The ID of the assistant to hand off to.""" @@ -433,6 +474,7 @@ class SkipTurn(TypedDict, total=False): AssistantToolParam: TypeAlias = Union[ InferenceEmbeddingWebhookToolParamsParam, + ClientSideTool, RetrievalToolParam, Handoff, HangupToolParam, diff --git a/src/telnyx/types/ai/chat_create_completion_params.py b/src/telnyx/types/ai/chat_create_completion_params.py deleted file mode 100644 index 815c28b2d..000000000 --- a/src/telnyx/types/ai/chat_create_completion_params.py +++ /dev/null @@ -1,204 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing import Dict, Union, Iterable -from typing_extensions import Literal, Required, TypeAlias, TypedDict - -from ..._types import SequenceNotStr -from .bucket_ids_param import BucketIDsParam - -__all__ = [ - "ChatCreateCompletionParams", - "Message", - "MessageContentTextAndImageArray", - "ResponseFormat", - "Tool", - "ToolFunction", - "ToolFunctionFunction", - "ToolRetrieval", -] - - -class ChatCreateCompletionParams(TypedDict, total=False): - messages: Required[Iterable[Message]] - """A list of the previous chat messages for context.""" - - api_key_ref: str - """ - If you are using an external inference provider like xAI or OpenAI, this field - allows you to pass along a reference to your API key. After creating an - [integration secret](https://developers.telnyx.com/api-reference/integration-secrets/create-a-secret) - for you API key, pass the secret's `identifier` in this field. - """ - - best_of: int - """ - This is used with `use_beam_search` to determine how many candidate beams to - explore. - """ - - early_stopping: bool - """This is used with `use_beam_search`. - - If `true`, generation stops as soon as there are `best_of` complete candidates; - if `false`, a heuristic is applied and the generation stops when is it very - unlikely to find better candidates. - """ - - enable_thinking: bool - """ - Whether to enable the thinking/reasoning phase for models that support it (e.g., - QwQ, Qwen3). When set to false, the model will skip the internal reasoning step - and respond directly, which can reduce latency. Defaults to true. - """ - - frequency_penalty: float - """Higher values will penalize the model from repeating the same output tokens.""" - - guided_choice: SequenceNotStr[str] - """If specified, the output will be exactly one of the choices.""" - - guided_json: Dict[str, object] - """Must be a valid JSON schema. - - If specified, the output will follow the JSON schema. - """ - - guided_regex: str - """If specified, the output will follow the regex pattern.""" - - length_penalty: float - """This is used with `use_beam_search` to prefer shorter or longer completions.""" - - logprobs: bool - """Whether to return log probabilities of the output tokens or not. - - If true, returns the log probabilities of each output token returned in the - `content` of `message`. - """ - - max_tokens: int - """Maximum number of completion tokens the model should generate.""" - - min_p: float - """ - This is an alternative to `top_p` that - [many prefer](https://github.com/huggingface/transformers/issues/27670). Must be - in [0, 1]. - """ - - model: str - """The language model to chat with.""" - - n: float - """This will return multiple choices for you instead of a single chat completion.""" - - presence_penalty: float - """Higher values will penalize the model from repeating the same output tokens.""" - - response_format: ResponseFormat - """Use this is you want to guarantee a JSON output without defining a schema. - - For control over the schema, use `guided_json`. - """ - - seed: int - """ - If specified, the system will make a best effort to sample deterministically, - such that repeated requests with the same `seed` and parameters should return - the same result. - """ - - stop: Union[str, SequenceNotStr[str]] - """Up to 4 sequences where the API will stop generating further tokens. - - The returned text will not contain the stop sequence. - """ - - stream: bool - """Whether or not to stream data-only server-sent events as they become available.""" - - temperature: float - """Adjusts the "creativity" of the model. - - Lower values make the model more deterministic and repetitive, while higher - values make the model more random and creative. - """ - - tool_choice: Literal["none", "auto", "required"] - - tools: Iterable[Tool] - """ - The `function` tool type follows the same schema as the - [OpenAI Chat Completions API](https://platform.openai.com/docs/api-reference/chat). - The `retrieval` tool type is unique to Telnyx. You may pass a list of - [embedded storage buckets](https://developers.telnyx.com/api-reference/embeddings/embed-documents) - for retrieval-augmented generation. - """ - - top_logprobs: int - """This is used with `logprobs`. - - An integer between 0 and 20 specifying the number of most likely tokens to - return at each token position, each with an associated log probability. - """ - - top_p: float - """An alternative or complement to `temperature`. - - This adjusts how many of the top possibilities to consider. - """ - - use_beam_search: bool - """ - Setting this to `true` will allow the model to - [explore more completion options](https://huggingface.co/blog/how-to-generate#beam-search). - This is not supported by OpenAI. - """ - - -class MessageContentTextAndImageArray(TypedDict, total=False): - type: Required[Literal["text", "image_url"]] - - image_url: str - - text: str - - -class Message(TypedDict, total=False): - content: Required[Union[str, Iterable[MessageContentTextAndImageArray]]] - - role: Required[Literal["system", "user", "assistant", "tool"]] - - -class ResponseFormat(TypedDict, total=False): - """Use this is you want to guarantee a JSON output without defining a schema. - - For control over the schema, use `guided_json`. - """ - - type: Required[Literal["text", "json_object"]] - - -class ToolFunctionFunction(TypedDict, total=False): - name: Required[str] - - description: str - - parameters: Dict[str, object] - - -class ToolFunction(TypedDict, total=False): - function: Required[ToolFunctionFunction] - - type: Required[Literal["function"]] - - -class ToolRetrieval(TypedDict, total=False): - retrieval: Required[BucketIDsParam] - - type: Required[Literal["retrieval"]] - - -Tool: TypeAlias = Union[ToolFunction, ToolRetrieval] diff --git a/src/telnyx/types/ai/chat_create_completion_response.py b/src/telnyx/types/ai/chat_create_completion_response.py deleted file mode 100644 index 299a23f01..000000000 --- a/src/telnyx/types/ai/chat_create_completion_response.py +++ /dev/null @@ -1,10 +0,0 @@ -# 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 TypeAlias - -__all__ = ["ChatCreateCompletionResponse"] - -ChatCreateCompletionResponse: TypeAlias = Dict[str, object] diff --git a/src/telnyx/types/ai/tool_create_params.py b/src/telnyx/types/ai/tool_create_params.py index 62f944ac5..8c28139d6 100644 --- a/src/telnyx/types/ai/tool_create_params.py +++ b/src/telnyx/types/ai/tool_create_params.py @@ -13,6 +13,8 @@ class ToolCreateParams(TypedDict, total=False): type: Required[str] + client_side_tool: Dict[str, object] + function: Dict[str, object] handoff: Dict[str, object] diff --git a/src/telnyx/types/ai/tool_update_params.py b/src/telnyx/types/ai/tool_update_params.py index 5bfbd0659..3d9f765d8 100644 --- a/src/telnyx/types/ai/tool_update_params.py +++ b/src/telnyx/types/ai/tool_update_params.py @@ -9,6 +9,8 @@ class ToolUpdateParams(TypedDict, total=False): + client_side_tool: Dict[str, object] + display_name: str function: Dict[str, object] diff --git a/src/telnyx/types/ai_create_response_deprecated_params.py b/src/telnyx/types/ai_create_response_deprecated_params.py deleted file mode 100644 index 152e58d90..000000000 --- a/src/telnyx/types/ai_create_response_deprecated_params.py +++ /dev/null @@ -1,12 +0,0 @@ -# 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__ = ["AICreateResponseDeprecatedParams"] - - -class AICreateResponseDeprecatedParams(TypedDict, total=False): - response_request: Required[Dict[str, object]] diff --git a/src/telnyx/types/ai_create_response_deprecated_response.py b/src/telnyx/types/ai_create_response_deprecated_response.py deleted file mode 100644 index a4de8eb9e..000000000 --- a/src/telnyx/types/ai_create_response_deprecated_response.py +++ /dev/null @@ -1,10 +0,0 @@ -# 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 TypeAlias - -__all__ = ["AICreateResponseDeprecatedResponse"] - -AICreateResponseDeprecatedResponse: TypeAlias = Dict[str, object] diff --git a/src/telnyx/types/calls/action_gather_using_ai_params.py b/src/telnyx/types/calls/action_gather_using_ai_params.py index ab2c8c280..1e0ddc772 100644 --- a/src/telnyx/types/calls/action_gather_using_ai_params.py +++ b/src/telnyx/types/calls/action_gather_using_ai_params.py @@ -128,6 +128,9 @@ class ActionGatherUsingAIParams(TypedDict, total=False): - **Inworld:** Use `Inworld..` (e.g., `Inworld.Mini.Loretta`, `Inworld.Max.Oliver`, `Inworld.TTS2.Loretta`). Supported models: `Mini`, `Max`, `TTS2`. + - **Fish Audio:** Use `FishAudio..` (e.g., + `FishAudio.s2.1-pro.`). Supported models: `s2.1-pro`, `s2-pro`, + `s1`. `VoiceId` is a Fish Voice-Library reference ID. - **xAI:** Use `xAI.` (e.g., `xAI.eve`). Available voices: `eve`, `ara`, `rex`, `sal`, `leo`. """ diff --git a/src/telnyx/types/calls/action_gather_using_speak_params.py b/src/telnyx/types/calls/action_gather_using_speak_params.py index f6028e269..71a6dc7cd 100644 --- a/src/telnyx/types/calls/action_gather_using_speak_params.py +++ b/src/telnyx/types/calls/action_gather_using_speak_params.py @@ -50,6 +50,9 @@ class ActionGatherUsingSpeakParams(TypedDict, total=False): [available voices](https://elevenlabs.io/docs/api-reference/get-voices). - **Telnyx:** Use `Telnyx..` (e.g., `Telnyx.KokoroTTS.af`). Use `voice_settings` to configure voice_speed and other synthesis parameters. + `Bayan` provides Arabic (multiple dialects) and English voices (e.g., + `Telnyx.Bayan.Ahmed`, `Telnyx.Bayan.Amanda`). `Sukhan` provides Urdu voices + (e.g., `Telnyx.Sukhan.urdu-professor`); `voice_speed` is not supported. - **Minimax:** Use `Minimax..` (e.g., `Minimax.speech-02-hd.Wise_Woman`). Supported models: `speech-02-turbo`, `speech-02-hd`, `speech-2.6-turbo`, `speech-2.8-turbo`. Use `voice_settings` @@ -64,6 +67,9 @@ class ActionGatherUsingSpeakParams(TypedDict, total=False): `Inworld.Max.Oliver`, `Inworld.TTS2.Loretta`). Supported models: `Mini`, `Max`, `TTS2`. Use `voice_settings` to configure `delivery_mode` (`STABLE`, `BALANCED`, `CREATIVE`), supported by `TTS2` only. + - **Fish Audio:** Use `FishAudio..` (e.g., + `FishAudio.s2.1-pro.`). Supported models: `s2.1-pro`, `s2-pro`, + `s1`. `VoiceId` is a Fish Voice-Library reference ID. - **xAI:** Use `xAI.` (e.g., `xAI.eve`). Available voices: `eve`, `ara`, `rex`, `sal`, `leo`. diff --git a/src/telnyx/types/calls/action_speak_params.py b/src/telnyx/types/calls/action_speak_params.py index ebef354a1..c67e42e3d 100644 --- a/src/telnyx/types/calls/action_speak_params.py +++ b/src/telnyx/types/calls/action_speak_params.py @@ -51,6 +51,9 @@ class ActionSpeakParams(TypedDict, total=False): [available voices](https://elevenlabs.io/docs/api-reference/get-voices). - **Telnyx:** Use `Telnyx..` (e.g., `Telnyx.KokoroTTS.af`). Use `voice_settings` to configure voice_speed and other synthesis parameters. + `Bayan` provides Arabic (multiple dialects) and English voices (e.g., + `Telnyx.Bayan.Ahmed`, `Telnyx.Bayan.Amanda`). `Sukhan` provides Urdu voices + (e.g., `Telnyx.Sukhan.urdu-professor`); `voice_speed` is not supported. - **Minimax:** Use `Minimax..` (e.g., `Minimax.speech-02-hd.Wise_Woman`). Supported models: `speech-02-turbo`, `speech-02-hd`, `speech-2.6-turbo`, `speech-2.8-turbo`. Use `voice_settings` @@ -65,6 +68,9 @@ class ActionSpeakParams(TypedDict, total=False): `Inworld.Max.Oliver`, `Inworld.TTS2.Loretta`). Supported models: `Mini`, `Max`, `TTS2`. Use `voice_settings` to configure `delivery_mode` (`STABLE`, `BALANCED`, `CREATIVE`), supported by `TTS2` only. + - **Fish Audio:** Use `FishAudio..` (e.g., + `FishAudio.s2.1-pro.`). Supported models: `s2.1-pro`, `s2-pro`, + `s1`. `VoiceId` is a Fish Voice-Library reference ID. - **xAI:** Use `xAI.` (e.g., `xAI.eve`). Available voices: `eve`, `ara`, `rex`, `sal`, `leo`. diff --git a/src/telnyx/types/calls/action_start_ai_assistant_params.py b/src/telnyx/types/calls/action_start_ai_assistant_params.py index 619dc0a31..5d8dd0467 100644 --- a/src/telnyx/types/calls/action_start_ai_assistant_params.py +++ b/src/telnyx/types/calls/action_start_ai_assistant_params.py @@ -106,6 +106,9 @@ class ActionStartAIAssistantParams(TypedDict, total=False): - **Inworld:** Use `Inworld..` (e.g., `Inworld.Mini.Loretta`, `Inworld.Max.Oliver`, `Inworld.TTS2.Loretta`). Supported models: `Mini`, `Max`, `TTS2`. + - **Fish Audio:** Use `FishAudio..` (e.g., + `FishAudio.s2.1-pro.`). Supported models: `s2.1-pro`, `s2-pro`, + `s1`. `VoiceId` is a Fish Voice-Library reference ID. - **xAI:** Use `xAI.` (e.g., `xAI.eve`). Available voices: `eve`, `ara`, `rex`, `sal`, `leo`. """ diff --git a/src/telnyx/types/calls/action_start_conversation_relay_params.py b/src/telnyx/types/calls/action_start_conversation_relay_params.py index 33fde9fee..31c4a4627 100644 --- a/src/telnyx/types/calls/action_start_conversation_relay_params.py +++ b/src/telnyx/types/calls/action_start_conversation_relay_params.py @@ -177,6 +177,9 @@ class ActionStartConversationRelayParams(TypedDict, total=False): - **Inworld:** Use `Inworld..` (e.g., `Inworld.Mini.Loretta`, `Inworld.Max.Oliver`, `Inworld.TTS2.Loretta`). Supported models: `Mini`, `Max`, `TTS2`. + - **Fish Audio:** Use `FishAudio..` (e.g., + `FishAudio.s2.1-pro.`). Supported models: `s2.1-pro`, `s2-pro`, + `s1`. `VoiceId` is a Fish Voice-Library reference ID. - **xAI:** Use `xAI.` (e.g., `xAI.eve`). Available voices: `eve`, `ara`, `rex`, `sal`, `leo`. """ diff --git a/src/telnyx/types/calls/telnyx_voice_settings_param.py b/src/telnyx/types/calls/telnyx_voice_settings_param.py index 31e36e605..1bf31f33e 100644 --- a/src/telnyx/types/calls/telnyx_voice_settings_param.py +++ b/src/telnyx/types/calls/telnyx_voice_settings_param.py @@ -14,5 +14,6 @@ class TelnyxVoiceSettingsParam(TypedDict, total=False): voice_speed: float """The voice speed to be used for the voice. - The voice speed must be between 0.1 and 2.0. Default value is 1.0. + The voice speed must be between 0.1 and 2.0. Default value is 1.0. Not supported + for `Telnyx.Bayan.*` or `Telnyx.Sukhan.*` voices. """ diff --git a/src/telnyx/types/conferences/action_speak_params.py b/src/telnyx/types/conferences/action_speak_params.py index 1fa36b96d..00d7d6ad9 100644 --- a/src/telnyx/types/conferences/action_speak_params.py +++ b/src/telnyx/types/conferences/action_speak_params.py @@ -52,6 +52,9 @@ class ActionSpeakParams(TypedDict, total=False): [available voices](https://elevenlabs.io/docs/api-reference/get-voices). - **Telnyx:** Use `Telnyx..` (e.g., `Telnyx.KokoroTTS.af`). Use `voice_settings` to configure voice_speed and other synthesis parameters. + `Bayan` provides Arabic (multiple dialects) and English voices (e.g., + `Telnyx.Bayan.Ahmed`, `Telnyx.Bayan.Amanda`). `Sukhan` provides Urdu voices + (e.g., `Telnyx.Sukhan.urdu-professor`); `voice_speed` is not supported. - **Minimax:** Use `Minimax..` (e.g., `Minimax.speech-02-hd.Wise_Woman`). Supported models: `speech-02-turbo`, `speech-02-hd`, `speech-2.6-turbo`, `speech-2.8-turbo`. Use `voice_settings` @@ -66,6 +69,9 @@ class ActionSpeakParams(TypedDict, total=False): `Inworld.Max.Oliver`, `Inworld.TTS2.Loretta`). Supported models: `Mini`, `Max`, `TTS2`. Use `voice_settings` to configure `delivery_mode` (`STABLE`, `BALANCED`, `CREATIVE`), supported by `TTS2` only. + - **Fish Audio:** Use `FishAudio..` (e.g., + `FishAudio.s2.1-pro.`). Supported models: `s2.1-pro`, `s2-pro`, + `s1`. `VoiceId` is a Fish Voice-Library reference ID. - **xAI:** Use `xAI.` (e.g., `xAI.eve`). Available voices: `eve`, `ara`, `rex`, `sal`, `leo`. diff --git a/src/telnyx/types/conversation_relay_embedded_config_param.py b/src/telnyx/types/conversation_relay_embedded_config_param.py index 0cdb111ea..e43f25946 100644 --- a/src/telnyx/types/conversation_relay_embedded_config_param.py +++ b/src/telnyx/types/conversation_relay_embedded_config_param.py @@ -143,6 +143,9 @@ class ConversationRelayEmbeddedConfigParam(TypedDict, total=False): - **Inworld:** Use `Inworld..` (e.g., `Inworld.Mini.Loretta`, `Inworld.Max.Oliver`, `Inworld.TTS2.Loretta`). Supported models: `Mini`, `Max`, `TTS2`. + - **Fish Audio:** Use `FishAudio..` (e.g., + `FishAudio.s2.1-pro.`). Supported models: `s2.1-pro`, `s2-pro`, + `s1`. `VoiceId` is a Fish Voice-Library reference ID. - **xAI:** Use `xAI.` (e.g., `xAI.eve`). Available voices: `eve`, `ara`, `rex`, `sal`, `leo`. """ diff --git a/src/telnyx/types/message_send_whatsapp_params.py b/src/telnyx/types/message_send_whatsapp_params.py deleted file mode 100644 index 867bd9bfc..000000000 --- a/src/telnyx/types/message_send_whatsapp_params.py +++ /dev/null @@ -1,29 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing_extensions import Literal, Required, Annotated, TypedDict - -from .._utils import PropertyInfo -from .whatsapp_message_content_param import WhatsappMessageContentParam - -__all__ = ["MessageSendWhatsappParams"] - - -class MessageSendWhatsappParams(TypedDict, total=False): - from_: Required[Annotated[str, PropertyInfo(alias="from")]] - """Phone number in +E.164 format associated with Whatsapp account""" - - to: Required[str] - """Phone number in +E.164 format""" - - whatsapp_message: Required[WhatsappMessageContentParam] - - messaging_profile_id: str - """Messaging profile ID - required if the 'from' number is not SMS-enabled""" - - type: Literal["WHATSAPP"] - """Message type - must be set to "WHATSAPP" """ - - webhook_url: str - """The URL where webhooks related to this message will be sent.""" diff --git a/src/telnyx/types/message_send_whatsapp_response.py b/src/telnyx/types/message_send_whatsapp_response.py deleted file mode 100644 index 8974d8bda..000000000 --- a/src/telnyx/types/message_send_whatsapp_response.py +++ /dev/null @@ -1,67 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing import List, Optional -from datetime import datetime -from typing_extensions import Literal - -from pydantic import Field as FieldInfo - -from .._models import BaseModel -from .rcs_to_item import RcsToItem -from .whatsapp_message_content import WhatsappMessageContent - -__all__ = ["MessageSendWhatsappResponse", "Data", "DataFrom"] - - -class DataFrom(BaseModel): - carrier: Optional[str] = None - """The carrier of the sender.""" - - line_type: Optional[Literal["Wireline", "Wireless", "VoWiFi", "VoIP", "Pre-Paid Wireless", ""]] = None - """The line-type of the sender.""" - - phone_number: Optional[str] = None - """ - Sending address (+E.164 formatted phone number, alphanumeric sender ID, or short - code). - """ - - status: Optional[Literal["received", "delivered"]] = None - - -class Data(BaseModel): - id: Optional[str] = None - """message ID""" - - body: Optional[WhatsappMessageContent] = None - - direction: Optional[str] = None - - encoding: Optional[str] = None - - from_: Optional[DataFrom] = FieldInfo(alias="from", default=None) - - messaging_profile_id: Optional[str] = None - - organization_id: Optional[str] = None - - received_at: Optional[datetime] = None - - record_type: Optional[str] = None - - to: Optional[List[RcsToItem]] = None - - type: Optional[str] = None - - wait_seconds: Optional[float] = None - """ - Seconds the message is queued due to rate limiting before being sent to the - carrier. Represents the maximum wait across all applicable rate limits (account, - carrier, campaign). 0.0 = no queuing delay. - """ - - -class MessageSendWhatsappResponse(BaseModel): - data: Optional[Data] = None diff --git a/src/telnyx/types/phone_number_delete_response.py b/src/telnyx/types/phone_number_delete_response.py index 0749ad238..e2688e90b 100644 --- a/src/telnyx/types/phone_number_delete_response.py +++ b/src/telnyx/types/phone_number_delete_response.py @@ -3,6 +3,7 @@ from __future__ import annotations from typing import List, Optional +from datetime import datetime from typing_extensions import Literal from .._models import BaseModel @@ -14,6 +15,14 @@ class Data(BaseModel): id: Optional[str] = None """Identifies the resource.""" + activated_at: Optional[datetime] = None + """ + ISO 8601 formatted date indicating when the phone number was first activated + (transitioned from purchase-pending or port-pending to active). Will be null for + numbers that have not yet been activated, or for legacy numbers activated before + this field was tracked. + """ + billing_group_id: Optional[str] = None """Identifies the billing group associated with the phone number.""" diff --git a/src/telnyx/types/phone_number_detailed.py b/src/telnyx/types/phone_number_detailed.py index 0c250c7f8..c7766f948 100644 --- a/src/telnyx/types/phone_number_detailed.py +++ b/src/telnyx/types/phone_number_detailed.py @@ -74,6 +74,14 @@ class PhoneNumberDetailed(BaseModel): tags: List[str] """A list of user-assigned tags to help manage the phone number.""" + activated_at: Optional[datetime] = None + """ + ISO 8601 formatted date indicating when the phone number was first activated + (transitioned from purchase-pending or port-pending to active). Will be null for + numbers that have not yet been activated, or for legacy numbers activated before + this field was tracked. + """ + billing_group_id: Optional[str] = None """Identifies the billing group associated with the phone number.""" diff --git a/src/telnyx/types/phone_number_slim_list_response.py b/src/telnyx/types/phone_number_slim_list_response.py index 21610bd83..c1b0f2f3e 100644 --- a/src/telnyx/types/phone_number_slim_list_response.py +++ b/src/telnyx/types/phone_number_slim_list_response.py @@ -3,6 +3,7 @@ from __future__ import annotations from typing import Optional +from datetime import datetime from typing_extensions import Literal from .._models import BaseModel @@ -14,6 +15,14 @@ class PhoneNumberSlimListResponse(BaseModel): id: Optional[str] = None """Identifies the resource.""" + activated_at: Optional[datetime] = None + """ + ISO 8601 formatted date indicating when the phone number was first activated + (transitioned from purchase-pending or port-pending to active). Will be null for + numbers that have not yet been activated, or for legacy numbers activated before + this field was tracked. + """ + billing_group_id: Optional[str] = None """Identifies the billing group associated with the phone number.""" diff --git a/src/telnyx/types/text_to_speech_generate_speech_params.py b/src/telnyx/types/text_to_speech_generate_speech_params.py index 39c3ce2d0..a552ad7b3 100644 --- a/src/telnyx/types/text_to_speech_generate_speech_params.py +++ b/src/telnyx/types/text_to_speech_generate_speech_params.py @@ -59,7 +59,10 @@ class TextToSpeechGenerateSpeechParams(TypedDict, total=False): """Telnyx provider-specific parameters. Use `voice_speed` and `temperature` for `Natural` and `NaturalHD` models. For - the `Ultra` model, use `voice_speed`, `volume`, and `emotion`. + the `Ultra` model, use `voice_speed`, `volume`, and `emotion`. `Bayan` and + `Sukhan` don't use `temperature`, `volume`, or `emotion`, and don't support + `voice_speed`. `Sukhan`'s `response_format` is restricted to `mp3` or `pcm` (no + `wav`). """ text: str @@ -72,10 +75,10 @@ class TextToSpeechGenerateSpeechParams(TypedDict, total=False): """ Voice identifier in the format `provider.model_id.voice_id` or `provider.voice_id`. Examples: `telnyx.NaturalHD.Alloy`, - `Telnyx.Ultra.`, `azure.en-US-AvaMultilingualNeural`, - `aws.Polly.Generative.Lucia`. When provided, `provider`, `model_id`, and - `voice_id` are extracted automatically and take precedence over individual - parameters. + `Telnyx.Ultra.`, `Telnyx.Bayan.Ahmed`, `Telnyx.Sukhan.urdu-professor`, + `azure.en-US-AvaMultilingualNeural`, `aws.Polly.Generative.Lucia`. When + provided, `provider`, `model_id`, and `voice_id` are extracted automatically and + take precedence over individual parameters. """ voice_settings: Dict[str, object] @@ -199,7 +202,7 @@ class Rime(TypedDict, total=False): class Telnyx(TypedDict, total=False): """Telnyx provider-specific parameters. - Use `voice_speed` and `temperature` for `Natural` and `NaturalHD` models. For the `Ultra` model, use `voice_speed`, `volume`, and `emotion`. + Use `voice_speed` and `temperature` for `Natural` and `NaturalHD` models. For the `Ultra` model, use `voice_speed`, `volume`, and `emotion`. `Bayan` and `Sukhan` don't use `temperature`, `volume`, or `emotion`, and don't support `voice_speed`. `Sukhan`'s `response_format` is restricted to `mp3` or `pcm` (no `wav`). """ emotion: Literal["neutral", "happy", "sad", "angry", "fearful", "disgusted", "surprised"] @@ -218,7 +221,11 @@ class Telnyx(TypedDict, total=False): """Sampling temperature. Applies to `Natural` and `NaturalHD` models only.""" voice_speed: float - """Voice speed multiplier. Applies to all models. Range: 0.5 to 2.0.""" + """Voice speed multiplier. + + Applies to all models except `Bayan` and `Sukhan`, which don't support it. + Range: 0.5 to 2.0. + """ volume: float """Volume level for the Ultra model. Range: 0.0 to 2.0.""" diff --git a/src/telnyx/types/text_to_speech_retrieve_speech_params.py b/src/telnyx/types/text_to_speech_retrieve_speech_params.py index ecdc1145d..95931b8cb 100644 --- a/src/telnyx/types/text_to_speech_retrieve_speech_params.py +++ b/src/telnyx/types/text_to_speech_retrieve_speech_params.py @@ -41,10 +41,10 @@ class TextToSpeechRetrieveSpeechParams(TypedDict, total=False): """ Voice identifier in the format `provider.model_id.voice_id` or `provider.voice_id` (e.g. `telnyx.NaturalHD.Telnyx_Alloy`, - `Telnyx.Ultra.`, or `azure.en-US-AvaMultilingualNeural`). When - provided, the `provider`, `model_id`, and `voice_id` are extracted - automatically. Takes precedence over individual `provider`/`model_id`/`voice_id` - parameters. + `Telnyx.Ultra.`, `Telnyx.Bayan.Ahmed`, `Telnyx.Sukhan.urdu-professor`, + or `azure.en-US-AvaMultilingualNeural`). When provided, the `provider`, + `model_id`, and `voice_id` are extracted automatically. Takes precedence over + individual `provider`/`model_id`/`voice_id` parameters. """ voice_id: str diff --git a/src/telnyx/types/whatsapp_contact.py b/src/telnyx/types/whatsapp_contact.py deleted file mode 100644 index 40593fb77..000000000 --- a/src/telnyx/types/whatsapp_contact.py +++ /dev/null @@ -1,69 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing import List, Optional - -from .._models import BaseModel - -__all__ = ["WhatsappContact", "Address", "Email", "Org", "Phone", "URL"] - - -class Address(BaseModel): - city: Optional[str] = None - - country: Optional[str] = None - - country_code: Optional[str] = None - - state: Optional[str] = None - - street: Optional[str] = None - - type: Optional[str] = None - - zip: Optional[str] = None - - -class Email(BaseModel): - email: Optional[str] = None - - type: Optional[str] = None - - -class Org(BaseModel): - company: Optional[str] = None - - department: Optional[str] = None - - title: Optional[str] = None - - -class Phone(BaseModel): - phone: Optional[str] = None - - type: Optional[str] = None - - wa_id: Optional[str] = None - - -class URL(BaseModel): - type: Optional[str] = None - - url: Optional[str] = None - - -class WhatsappContact(BaseModel): - addresses: Optional[List[Address]] = None - - birthday: Optional[str] = None - - emails: Optional[List[Email]] = None - - name: Optional[str] = None - - org: Optional[Org] = None - - phones: Optional[List[Phone]] = None - - urls: Optional[List[URL]] = None diff --git a/src/telnyx/types/whatsapp_contact_param.py b/src/telnyx/types/whatsapp_contact_param.py deleted file mode 100644 index 7d676ac90..000000000 --- a/src/telnyx/types/whatsapp_contact_param.py +++ /dev/null @@ -1,68 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing import Iterable -from typing_extensions import TypedDict - -__all__ = ["WhatsappContactParam", "Address", "Email", "Org", "Phone", "URL"] - - -class Address(TypedDict, total=False): - city: str - - country: str - - country_code: str - - state: str - - street: str - - type: str - - zip: str - - -class Email(TypedDict, total=False): - email: str - - type: str - - -class Org(TypedDict, total=False): - company: str - - department: str - - title: str - - -class Phone(TypedDict, total=False): - phone: str - - type: str - - wa_id: str - - -class URL(TypedDict, total=False): - type: str - - url: str - - -class WhatsappContactParam(TypedDict, total=False): - addresses: Iterable[Address] - - birthday: str - - emails: Iterable[Email] - - name: str - - org: Org - - phones: Iterable[Phone] - - urls: Iterable[URL] diff --git a/src/telnyx/types/whatsapp_interactive.py b/src/telnyx/types/whatsapp_interactive.py deleted file mode 100644 index 3ade2f9f3..000000000 --- a/src/telnyx/types/whatsapp_interactive.py +++ /dev/null @@ -1,162 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing import List, Optional -from typing_extensions import Literal - -from .._models import BaseModel -from .whatsapp_media import WhatsappMedia - -__all__ = [ - "WhatsappInteractive", - "Action", - "ActionButton", - "ActionButtonReply", - "ActionCard", - "ActionCardAction", - "ActionCardBody", - "ActionCardHeader", - "ActionParameters", - "ActionSection", - "ActionSectionProductItem", - "ActionSectionRow", - "Body", - "Footer", - "Header", -] - - -class ActionButtonReply(BaseModel): - id: Optional[str] = None - """unique identifier for each button, 256 character maximum""" - - title: Optional[str] = None - """button label, 20 character maximum""" - - -class ActionButton(BaseModel): - reply: Optional[ActionButtonReply] = None - - type: Optional[Literal["reply"]] = None - - -class ActionCardAction(BaseModel): - catalog_id: Optional[str] = None - """the unique ID of the catalog""" - - product_retailer_id: Optional[str] = None - """the unique retailer ID of the product""" - - -class ActionCardBody(BaseModel): - text: Optional[str] = None - """160 character maximum, up to 2 line breaks""" - - -class ActionCardHeader(BaseModel): - image: Optional[WhatsappMedia] = None - - type: Optional[Literal["image", "video"]] = None - - video: Optional[WhatsappMedia] = None - - -class ActionCard(BaseModel): - action: Optional[ActionCardAction] = None - - body: Optional[ActionCardBody] = None - - card_index: Optional[int] = None - """unique index for each card (0-9)""" - - header: Optional[ActionCardHeader] = None - - type: Optional[Literal["cta_url"]] = None - - -class ActionParameters(BaseModel): - display_text: Optional[str] = None - """button label text, 20 character maximum""" - - url: Optional[str] = None - """button URL to load when tapped by the user""" - - -class ActionSectionProductItem(BaseModel): - product_retailer_id: Optional[str] = None - - -class ActionSectionRow(BaseModel): - id: Optional[str] = None - """arbitrary string identifying the row, 200 character maximum""" - - description: Optional[str] = None - """row description, 72 character maximum""" - - title: Optional[str] = None - """row title, 24 character maximum""" - - -class ActionSection(BaseModel): - product_items: Optional[List[ActionSectionProductItem]] = None - - rows: Optional[List[ActionSectionRow]] = None - - title: Optional[str] = None - """section title, 24 character maximum""" - - -class Action(BaseModel): - button: Optional[str] = None - - buttons: Optional[List[ActionButton]] = None - - cards: Optional[List[ActionCard]] = None - - catalog_id: Optional[str] = None - - mode: Optional[str] = None - - name: Optional[str] = None - - parameters: Optional[ActionParameters] = None - - product_retailer_id: Optional[str] = None - - sections: Optional[List[ActionSection]] = None - - -class Body(BaseModel): - text: Optional[str] = None - """body text, 1024 character maximum""" - - -class Footer(BaseModel): - text: Optional[str] = None - """footer text, 60 character maximum""" - - -class Header(BaseModel): - document: Optional[WhatsappMedia] = None - - image: Optional[WhatsappMedia] = None - - sub_text: Optional[str] = None - - text: Optional[str] = None - """header text, 60 character maximum""" - - video: Optional[WhatsappMedia] = None - - -class WhatsappInteractive(BaseModel): - action: Optional[Action] = None - - body: Optional[Body] = None - - footer: Optional[Footer] = None - - header: Optional[Header] = None - - type: Optional[Literal["cta_url", "list", "carousel", "button", "location_request_message"]] = None diff --git a/src/telnyx/types/whatsapp_interactive_param.py b/src/telnyx/types/whatsapp_interactive_param.py deleted file mode 100644 index e5172a948..000000000 --- a/src/telnyx/types/whatsapp_interactive_param.py +++ /dev/null @@ -1,161 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing import Iterable -from typing_extensions import Literal, TypedDict - -from .whatsapp_media_param import WhatsappMediaParam - -__all__ = [ - "WhatsappInteractiveParam", - "Action", - "ActionButton", - "ActionButtonReply", - "ActionCard", - "ActionCardAction", - "ActionCardBody", - "ActionCardHeader", - "ActionParameters", - "ActionSection", - "ActionSectionProductItem", - "ActionSectionRow", - "Body", - "Footer", - "Header", -] - - -class ActionButtonReply(TypedDict, total=False): - id: str - """unique identifier for each button, 256 character maximum""" - - title: str - """button label, 20 character maximum""" - - -class ActionButton(TypedDict, total=False): - reply: ActionButtonReply - - type: Literal["reply"] - - -class ActionCardAction(TypedDict, total=False): - catalog_id: str - """the unique ID of the catalog""" - - product_retailer_id: str - """the unique retailer ID of the product""" - - -class ActionCardBody(TypedDict, total=False): - text: str - """160 character maximum, up to 2 line breaks""" - - -class ActionCardHeader(TypedDict, total=False): - image: WhatsappMediaParam - - type: Literal["image", "video"] - - video: WhatsappMediaParam - - -class ActionCard(TypedDict, total=False): - action: ActionCardAction - - body: ActionCardBody - - card_index: int - """unique index for each card (0-9)""" - - header: ActionCardHeader - - type: Literal["cta_url"] - - -class ActionParameters(TypedDict, total=False): - display_text: str - """button label text, 20 character maximum""" - - url: str - """button URL to load when tapped by the user""" - - -class ActionSectionProductItem(TypedDict, total=False): - product_retailer_id: str - - -class ActionSectionRow(TypedDict, total=False): - id: str - """arbitrary string identifying the row, 200 character maximum""" - - description: str - """row description, 72 character maximum""" - - title: str - """row title, 24 character maximum""" - - -class ActionSection(TypedDict, total=False): - product_items: Iterable[ActionSectionProductItem] - - rows: Iterable[ActionSectionRow] - - title: str - """section title, 24 character maximum""" - - -class Action(TypedDict, total=False): - button: str - - buttons: Iterable[ActionButton] - - cards: Iterable[ActionCard] - - catalog_id: str - - mode: str - - name: str - - parameters: ActionParameters - - product_retailer_id: str - - sections: Iterable[ActionSection] - - -class Body(TypedDict, total=False): - text: str - """body text, 1024 character maximum""" - - -class Footer(TypedDict, total=False): - text: str - """footer text, 60 character maximum""" - - -class Header(TypedDict, total=False): - document: WhatsappMediaParam - - image: WhatsappMediaParam - - sub_text: str - - text: str - """header text, 60 character maximum""" - - video: WhatsappMediaParam - - -class WhatsappInteractiveParam(TypedDict, total=False): - action: Action - - body: Body - - footer: Footer - - header: Header - - type: Literal["cta_url", "list", "carousel", "button", "location_request_message"] diff --git a/src/telnyx/types/whatsapp_location.py b/src/telnyx/types/whatsapp_location.py deleted file mode 100644 index 819a72f8c..000000000 --- a/src/telnyx/types/whatsapp_location.py +++ /dev/null @@ -1,19 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing import Optional - -from .._models import BaseModel - -__all__ = ["WhatsappLocation"] - - -class WhatsappLocation(BaseModel): - address: Optional[str] = None - - latitude: Optional[str] = None - - longitude: Optional[str] = None - - name: Optional[str] = None diff --git a/src/telnyx/types/whatsapp_location_param.py b/src/telnyx/types/whatsapp_location_param.py deleted file mode 100644 index 29201ccdc..000000000 --- a/src/telnyx/types/whatsapp_location_param.py +++ /dev/null @@ -1,17 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing_extensions import TypedDict - -__all__ = ["WhatsappLocationParam"] - - -class WhatsappLocationParam(TypedDict, total=False): - address: str - - latitude: str - - longitude: str - - name: str diff --git a/src/telnyx/types/whatsapp_media.py b/src/telnyx/types/whatsapp_media.py deleted file mode 100644 index 8a5bad2fb..000000000 --- a/src/telnyx/types/whatsapp_media.py +++ /dev/null @@ -1,23 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing import Optional - -from .._models import BaseModel - -__all__ = ["WhatsappMedia"] - - -class WhatsappMedia(BaseModel): - caption: Optional[str] = None - """media caption""" - - filename: Optional[str] = None - """file name with extension""" - - link: Optional[str] = None - """media URL""" - - voice: Optional[bool] = None - """true if voice message""" diff --git a/src/telnyx/types/whatsapp_media_param.py b/src/telnyx/types/whatsapp_media_param.py deleted file mode 100644 index 6984ec21a..000000000 --- a/src/telnyx/types/whatsapp_media_param.py +++ /dev/null @@ -1,21 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing_extensions import TypedDict - -__all__ = ["WhatsappMediaParam"] - - -class WhatsappMediaParam(TypedDict, total=False): - caption: str - """media caption""" - - filename: str - """file name with extension""" - - link: str - """media URL""" - - voice: bool - """true if voice message""" diff --git a/src/telnyx/types/whatsapp_message_content.py b/src/telnyx/types/whatsapp_message_content.py deleted file mode 100644 index cdc7ad52f..000000000 --- a/src/telnyx/types/whatsapp_message_content.py +++ /dev/null @@ -1,134 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing import List, Optional -from typing_extensions import Literal - -from .._models import BaseModel -from .whatsapp_media import WhatsappMedia -from .whatsapp_contact import WhatsappContact -from .whatsapp_location import WhatsappLocation -from .whatsapp_reaction import WhatsappReaction -from .whatsapp_interactive import WhatsappInteractive - -__all__ = [ - "WhatsappMessageContent", - "Template", - "TemplateComponent", - "TemplateComponentParameter", - "TemplateLanguage", - "Text", -] - - -class TemplateComponentParameter(BaseModel): - text: Optional[str] = None - - type: Optional[Literal["text", "image", "video", "document", "currency", "date_time"]] = None - - -class TemplateComponent(BaseModel): - index: Optional[int] = None - """Button index (required for button components)""" - - parameters: Optional[List[TemplateComponentParameter]] = None - - sub_type: Optional[Literal["quick_reply", "url"]] = None - - type: Optional[Literal["header", "body", "button"]] = None - - -class TemplateLanguage(BaseModel): - """Template language. Required unless template_id is provided.""" - - code: str - """Language code (e.g. en_US)""" - - policy: Optional[str] = None - - -class Template(BaseModel): - """Template message object. - - Provide either template_id or name + language to identify the template. - """ - - components: Optional[List[TemplateComponent]] = None - """Template parameter values for header, body, and button components.""" - - language: Optional[TemplateLanguage] = None - """Template language. Required unless template_id is provided.""" - - name: Optional[str] = None - """Template name as registered with Meta. Required unless template_id is provided.""" - - template_id: Optional[str] = None - """Telnyx template ID (the id field from template list/get responses). - - When provided, name and language are resolved automatically. - """ - - -class Text(BaseModel): - """Text message content. - - Can only be sent within a 24-hour customer service window. - """ - - body: str - """The text message body.""" - - preview_url: Optional[bool] = None - """Whether to show a URL preview in the message.""" - - -class WhatsappMessageContent(BaseModel): - audio: Optional[WhatsappMedia] = None - - biz_opaque_callback_data: Optional[str] = None - """custom data to return with status update""" - - contacts: Optional[List[WhatsappContact]] = None - - document: Optional[WhatsappMedia] = None - - image: Optional[WhatsappMedia] = None - - interactive: Optional[WhatsappInteractive] = None - - location: Optional[WhatsappLocation] = None - - reaction: Optional[WhatsappReaction] = None - - sticker: Optional[WhatsappMedia] = None - - template: Optional[Template] = None - """Template message object. - - Provide either template_id or name + language to identify the template. - """ - - text: Optional[Text] = None - """Text message content. - - Can only be sent within a 24-hour customer service window. - """ - - type: Optional[ - Literal[ - "audio", - "document", - "image", - "sticker", - "video", - "interactive", - "location", - "template", - "reaction", - "contacts", - "text", - ] - ] = None - - video: Optional[WhatsappMedia] = None diff --git a/src/telnyx/types/whatsapp_message_content_param.py b/src/telnyx/types/whatsapp_message_content_param.py deleted file mode 100644 index b5507e9bb..000000000 --- a/src/telnyx/types/whatsapp_message_content_param.py +++ /dev/null @@ -1,131 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing import Iterable -from typing_extensions import Literal, Required, TypedDict - -from .whatsapp_media_param import WhatsappMediaParam -from .whatsapp_contact_param import WhatsappContactParam -from .whatsapp_location_param import WhatsappLocationParam -from .whatsapp_reaction_param import WhatsappReactionParam -from .whatsapp_interactive_param import WhatsappInteractiveParam - -__all__ = [ - "WhatsappMessageContentParam", - "Template", - "TemplateComponent", - "TemplateComponentParameter", - "TemplateLanguage", - "Text", -] - - -class TemplateComponentParameter(TypedDict, total=False): - text: str - - type: Literal["text", "image", "video", "document", "currency", "date_time"] - - -class TemplateComponent(TypedDict, total=False): - index: int - """Button index (required for button components)""" - - parameters: Iterable[TemplateComponentParameter] - - sub_type: Literal["quick_reply", "url"] - - type: Literal["header", "body", "button"] - - -class TemplateLanguage(TypedDict, total=False): - """Template language. Required unless template_id is provided.""" - - code: Required[str] - """Language code (e.g. en_US)""" - - policy: str - - -class Template(TypedDict, total=False): - """Template message object. - - Provide either template_id or name + language to identify the template. - """ - - components: Iterable[TemplateComponent] - """Template parameter values for header, body, and button components.""" - - language: TemplateLanguage - """Template language. Required unless template_id is provided.""" - - name: str - """Template name as registered with Meta. Required unless template_id is provided.""" - - template_id: str - """Telnyx template ID (the id field from template list/get responses). - - When provided, name and language are resolved automatically. - """ - - -class Text(TypedDict, total=False): - """Text message content. - - Can only be sent within a 24-hour customer service window. - """ - - body: Required[str] - """The text message body.""" - - preview_url: bool - """Whether to show a URL preview in the message.""" - - -class WhatsappMessageContentParam(TypedDict, total=False): - audio: WhatsappMediaParam - - biz_opaque_callback_data: str - """custom data to return with status update""" - - contacts: Iterable[WhatsappContactParam] - - document: WhatsappMediaParam - - image: WhatsappMediaParam - - interactive: WhatsappInteractiveParam - - location: WhatsappLocationParam - - reaction: WhatsappReactionParam - - sticker: WhatsappMediaParam - - template: Template - """Template message object. - - Provide either template_id or name + language to identify the template. - """ - - text: Text - """Text message content. - - Can only be sent within a 24-hour customer service window. - """ - - type: Literal[ - "audio", - "document", - "image", - "sticker", - "video", - "interactive", - "location", - "template", - "reaction", - "contacts", - "text", - ] - - video: WhatsappMediaParam diff --git a/src/telnyx/types/whatsapp_reaction.py b/src/telnyx/types/whatsapp_reaction.py deleted file mode 100644 index b17e7e811..000000000 --- a/src/telnyx/types/whatsapp_reaction.py +++ /dev/null @@ -1,15 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing import Optional - -from .._models import BaseModel - -__all__ = ["WhatsappReaction"] - - -class WhatsappReaction(BaseModel): - emoji: Optional[str] = None - - message_id: Optional[str] = None diff --git a/src/telnyx/types/whatsapp_reaction_param.py b/src/telnyx/types/whatsapp_reaction_param.py deleted file mode 100644 index f62f3e0a1..000000000 --- a/src/telnyx/types/whatsapp_reaction_param.py +++ /dev/null @@ -1,13 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing_extensions import TypedDict - -__all__ = ["WhatsappReactionParam"] - - -class WhatsappReactionParam(TypedDict, total=False): - emoji: str - - message_id: str diff --git a/tests/api_resources/ai/test_chat.py b/tests/api_resources/ai/test_chat.py deleted file mode 100644 index f10a9bbfc..000000000 --- a/tests/api_resources/ai/test_chat.py +++ /dev/null @@ -1,262 +0,0 @@ -# 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 telnyx import Telnyx, AsyncTelnyx -from tests.utils import assert_matches_type -from telnyx.types.ai import ChatCreateCompletionResponse - -# pyright: reportDeprecated=false - -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"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_method_create_completion(self, client: Telnyx) -> None: - with pytest.warns(DeprecationWarning): - chat = client.ai.chat.create_completion( - messages=[ - { - "content": "You are a friendly chatbot.", - "role": "system", - }, - { - "content": "Hello, world!", - "role": "user", - }, - ], - ) - - assert_matches_type(ChatCreateCompletionResponse, chat, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_method_create_completion_with_all_params(self, client: Telnyx) -> None: - with pytest.warns(DeprecationWarning): - chat = client.ai.chat.create_completion( - messages=[ - { - "content": "You are a friendly chatbot.", - "role": "system", - }, - { - "content": "Hello, world!", - "role": "user", - }, - ], - api_key_ref="api_key_ref", - best_of=0, - early_stopping=True, - enable_thinking=True, - frequency_penalty=0, - guided_choice=["string"], - guided_json={"foo": "bar"}, - guided_regex="guided_regex", - length_penalty=0, - logprobs=True, - max_tokens=0, - min_p=0, - model="model", - n=0, - presence_penalty=0, - response_format={"type": "text"}, - seed=0, - stop="string", - stream=True, - temperature=0, - tool_choice="none", - tools=[ - { - "function": { - "name": "name", - "description": "description", - "parameters": {"foo": "bar"}, - }, - "type": "function", - } - ], - top_logprobs=0, - top_p=0, - use_beam_search=True, - ) - - assert_matches_type(ChatCreateCompletionResponse, chat, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_raw_response_create_completion(self, client: Telnyx) -> None: - with pytest.warns(DeprecationWarning): - response = client.ai.chat.with_raw_response.create_completion( - messages=[ - { - "content": "You are a friendly chatbot.", - "role": "system", - }, - { - "content": "Hello, world!", - "role": "user", - }, - ], - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - chat = response.parse() - assert_matches_type(ChatCreateCompletionResponse, chat, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_streaming_response_create_completion(self, client: Telnyx) -> None: - with pytest.warns(DeprecationWarning): - with client.ai.chat.with_streaming_response.create_completion( - messages=[ - { - "content": "You are a friendly chatbot.", - "role": "system", - }, - { - "content": "Hello, world!", - "role": "user", - }, - ], - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - chat = response.parse() - assert_matches_type(ChatCreateCompletionResponse, chat, path=["response"]) - - assert cast(Any, response.is_closed) is True - - -class TestAsyncChat: - parametrize = pytest.mark.parametrize( - "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] - ) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_method_create_completion(self, async_client: AsyncTelnyx) -> None: - with pytest.warns(DeprecationWarning): - chat = await async_client.ai.chat.create_completion( - messages=[ - { - "content": "You are a friendly chatbot.", - "role": "system", - }, - { - "content": "Hello, world!", - "role": "user", - }, - ], - ) - - assert_matches_type(ChatCreateCompletionResponse, chat, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_method_create_completion_with_all_params(self, async_client: AsyncTelnyx) -> None: - with pytest.warns(DeprecationWarning): - chat = await async_client.ai.chat.create_completion( - messages=[ - { - "content": "You are a friendly chatbot.", - "role": "system", - }, - { - "content": "Hello, world!", - "role": "user", - }, - ], - api_key_ref="api_key_ref", - best_of=0, - early_stopping=True, - enable_thinking=True, - frequency_penalty=0, - guided_choice=["string"], - guided_json={"foo": "bar"}, - guided_regex="guided_regex", - length_penalty=0, - logprobs=True, - max_tokens=0, - min_p=0, - model="model", - n=0, - presence_penalty=0, - response_format={"type": "text"}, - seed=0, - stop="string", - stream=True, - temperature=0, - tool_choice="none", - tools=[ - { - "function": { - "name": "name", - "description": "description", - "parameters": {"foo": "bar"}, - }, - "type": "function", - } - ], - top_logprobs=0, - top_p=0, - use_beam_search=True, - ) - - assert_matches_type(ChatCreateCompletionResponse, chat, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_raw_response_create_completion(self, async_client: AsyncTelnyx) -> None: - with pytest.warns(DeprecationWarning): - response = await async_client.ai.chat.with_raw_response.create_completion( - messages=[ - { - "content": "You are a friendly chatbot.", - "role": "system", - }, - { - "content": "Hello, world!", - "role": "user", - }, - ], - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - chat = await response.parse() - assert_matches_type(ChatCreateCompletionResponse, chat, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_streaming_response_create_completion(self, async_client: AsyncTelnyx) -> None: - with pytest.warns(DeprecationWarning): - async with async_client.ai.chat.with_streaming_response.create_completion( - messages=[ - { - "content": "You are a friendly chatbot.", - "role": "system", - }, - { - "content": "Hello, world!", - "role": "user", - }, - ], - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - chat = await response.parse() - assert_matches_type(ChatCreateCompletionResponse, chat, path=["response"]) - - assert cast(Any, response.is_closed) is True diff --git a/tests/api_resources/ai/test_tools.py b/tests/api_resources/ai/test_tools.py index 690bb9acb..3883d99fa 100644 --- a/tests/api_resources/ai/test_tools.py +++ b/tests/api_resources/ai/test_tools.py @@ -33,6 +33,7 @@ def test_method_create_with_all_params(self, client: Telnyx) -> None: tool = client.ai.tools.create( display_name="display_name", type="type", + client_side_tool={"foo": "bar"}, function={"foo": "bar"}, handoff={"foo": "bar"}, invite={"foo": "bar"}, @@ -125,6 +126,7 @@ def test_method_update(self, client: Telnyx) -> None: def test_method_update_with_all_params(self, client: Telnyx) -> None: tool = client.ai.tools.update( tool_id="tool_id", + client_side_tool={"foo": "bar"}, display_name="display_name", function={"foo": "bar"}, handoff={"foo": "bar"}, @@ -272,6 +274,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncTelnyx) -> tool = await async_client.ai.tools.create( display_name="display_name", type="type", + client_side_tool={"foo": "bar"}, function={"foo": "bar"}, handoff={"foo": "bar"}, invite={"foo": "bar"}, @@ -364,6 +367,7 @@ async def test_method_update(self, async_client: AsyncTelnyx) -> None: async def test_method_update_with_all_params(self, async_client: AsyncTelnyx) -> None: tool = await async_client.ai.tools.update( tool_id="tool_id", + client_side_tool={"foo": "bar"}, display_name="display_name", function={"foo": "bar"}, handoff={"foo": "bar"}, diff --git a/tests/api_resources/test_ai.py b/tests/api_resources/test_ai.py index bc4486360..e5030de4d 100644 --- a/tests/api_resources/test_ai.py +++ b/tests/api_resources/test_ai.py @@ -10,68 +10,17 @@ from telnyx import Telnyx, AsyncTelnyx from tests.utils import assert_matches_type from telnyx.types import ( - ModelsResponse, AISummarizeResponse, - AICreateResponseDeprecatedResponse, AIRetrieveConversationHistoriesResponse, ) from telnyx._utils import parse_datetime -# pyright: reportDeprecated=false - base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") class TestAI: parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_method_create_response_deprecated(self, client: Telnyx) -> None: - with pytest.warns(DeprecationWarning): - ai = client.ai.create_response_deprecated( - response_request={ - "model": "bar", - "input": "bar", - }, - ) - - assert_matches_type(AICreateResponseDeprecatedResponse, ai, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_raw_response_create_response_deprecated(self, client: Telnyx) -> None: - with pytest.warns(DeprecationWarning): - response = client.ai.with_raw_response.create_response_deprecated( - response_request={ - "model": "bar", - "input": "bar", - }, - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - ai = response.parse() - assert_matches_type(AICreateResponseDeprecatedResponse, ai, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_streaming_response_create_response_deprecated(self, client: Telnyx) -> None: - with pytest.warns(DeprecationWarning): - with client.ai.with_streaming_response.create_response_deprecated( - response_request={ - "model": "bar", - "input": "bar", - }, - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - ai = response.parse() - assert_matches_type(AICreateResponseDeprecatedResponse, ai, path=["response"]) - - assert cast(Any, response.is_closed) is True - @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize def test_method_retrieve_conversation_histories(self, client: Telnyx) -> None: @@ -126,38 +75,6 @@ def test_streaming_response_retrieve_conversation_histories(self, client: Telnyx assert cast(Any, response.is_closed) is True - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_method_retrieve_models(self, client: Telnyx) -> None: - with pytest.warns(DeprecationWarning): - ai = client.ai.retrieve_models() - - assert_matches_type(ModelsResponse, ai, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_raw_response_retrieve_models(self, client: Telnyx) -> None: - with pytest.warns(DeprecationWarning): - response = client.ai.with_raw_response.retrieve_models() - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - ai = response.parse() - assert_matches_type(ModelsResponse, ai, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_streaming_response_retrieve_models(self, client: Telnyx) -> None: - with pytest.warns(DeprecationWarning): - with client.ai.with_streaming_response.retrieve_models() as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - ai = response.parse() - assert_matches_type(ModelsResponse, ai, path=["response"]) - - assert cast(Any, response.is_closed) is True - @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize def test_method_summarize(self, client: Telnyx) -> None: @@ -211,53 +128,6 @@ class TestAsyncAI: "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] ) - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_method_create_response_deprecated(self, async_client: AsyncTelnyx) -> None: - with pytest.warns(DeprecationWarning): - ai = await async_client.ai.create_response_deprecated( - response_request={ - "model": "bar", - "input": "bar", - }, - ) - - assert_matches_type(AICreateResponseDeprecatedResponse, ai, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_raw_response_create_response_deprecated(self, async_client: AsyncTelnyx) -> None: - with pytest.warns(DeprecationWarning): - response = await async_client.ai.with_raw_response.create_response_deprecated( - response_request={ - "model": "bar", - "input": "bar", - }, - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - ai = await response.parse() - assert_matches_type(AICreateResponseDeprecatedResponse, ai, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_streaming_response_create_response_deprecated(self, async_client: AsyncTelnyx) -> None: - with pytest.warns(DeprecationWarning): - async with async_client.ai.with_streaming_response.create_response_deprecated( - response_request={ - "model": "bar", - "input": "bar", - }, - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - ai = await response.parse() - assert_matches_type(AICreateResponseDeprecatedResponse, ai, path=["response"]) - - assert cast(Any, response.is_closed) is True - @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize async def test_method_retrieve_conversation_histories(self, async_client: AsyncTelnyx) -> None: @@ -312,38 +182,6 @@ async def test_streaming_response_retrieve_conversation_histories(self, async_cl assert cast(Any, response.is_closed) is True - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_method_retrieve_models(self, async_client: AsyncTelnyx) -> None: - with pytest.warns(DeprecationWarning): - ai = await async_client.ai.retrieve_models() - - assert_matches_type(ModelsResponse, ai, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_raw_response_retrieve_models(self, async_client: AsyncTelnyx) -> None: - with pytest.warns(DeprecationWarning): - response = await async_client.ai.with_raw_response.retrieve_models() - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - ai = await response.parse() - assert_matches_type(ModelsResponse, ai, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_streaming_response_retrieve_models(self, async_client: AsyncTelnyx) -> None: - with pytest.warns(DeprecationWarning): - async with async_client.ai.with_streaming_response.retrieve_models() as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - ai = await response.parse() - assert_matches_type(ModelsResponse, ai, path=["response"]) - - assert cast(Any, response.is_closed) is True - @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize async def test_method_summarize(self, async_client: AsyncTelnyx) -> None: diff --git a/tests/api_resources/test_messages.py b/tests/api_resources/test_messages.py index 812a37c12..ccb9b6ba4 100644 --- a/tests/api_resources/test_messages.py +++ b/tests/api_resources/test_messages.py @@ -15,7 +15,6 @@ MessageScheduleResponse, MessageSendGroupMmsResponse, MessageSendLongCodeResponse, - MessageSendWhatsappResponse, MessageSendShortCodeResponse, MessageSendNumberPoolResponse, MessageCancelScheduledResponse, @@ -480,254 +479,6 @@ def test_streaming_response_send_short_code(self, client: Telnyx) -> None: assert cast(Any, response.is_closed) is True - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_method_send_whatsapp(self, client: Telnyx) -> None: - message = client.messages.send_whatsapp( - from_="+13125551234", - to="+13125551234", - whatsapp_message={}, - ) - assert_matches_type(MessageSendWhatsappResponse, message, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_method_send_whatsapp_with_all_params(self, client: Telnyx) -> None: - message = client.messages.send_whatsapp( - from_="+13125551234", - to="+13125551234", - whatsapp_message={ - "audio": { - "caption": "caption", - "filename": "filename", - "link": "http://example.com/media.jpg", - "voice": True, - }, - "biz_opaque_callback_data": "biz_opaque_callback_data", - "contacts": [ - { - "addresses": [ - { - "city": "city", - "country": "country", - "country_code": "country_code", - "state": "state", - "street": "street", - "type": "type", - "zip": "zip", - } - ], - "birthday": "birthday", - "emails": [ - { - "email": "email", - "type": "type", - } - ], - "name": "name", - "org": { - "company": "company", - "department": "department", - "title": "title", - }, - "phones": [ - { - "phone": "phone", - "type": "type", - "wa_id": "wa_id", - } - ], - "urls": [ - { - "type": "type", - "url": "url", - } - ], - } - ], - "document": { - "caption": "caption", - "filename": "filename", - "link": "http://example.com/media.jpg", - "voice": True, - }, - "image": { - "caption": "caption", - "filename": "filename", - "link": "http://example.com/media.jpg", - "voice": True, - }, - "interactive": { - "action": { - "button": "button", - "buttons": [ - { - "reply": { - "id": "id", - "title": "title", - }, - "type": "reply", - } - ], - "cards": [ - { - "action": { - "catalog_id": "catalog_id", - "product_retailer_id": "product_retailer_id", - }, - "body": {"text": "text"}, - "card_index": 0, - "header": { - "image": { - "caption": "caption", - "filename": "filename", - "link": "http://example.com/media.jpg", - "voice": True, - }, - "type": "image", - "video": { - "caption": "caption", - "filename": "filename", - "link": "http://example.com/media.jpg", - "voice": True, - }, - }, - "type": "cta_url", - } - ], - "catalog_id": "catalog_id", - "mode": "mode", - "name": "name", - "parameters": { - "display_text": "display_text", - "url": "url", - }, - "product_retailer_id": "product_retailer_id", - "sections": [ - { - "product_items": [{"product_retailer_id": "product_retailer_id"}], - "rows": [ - { - "id": "id", - "description": "description", - "title": "title", - } - ], - "title": "title", - } - ], - }, - "body": {"text": "text"}, - "footer": {"text": "text"}, - "header": { - "document": { - "caption": "caption", - "filename": "filename", - "link": "http://example.com/media.jpg", - "voice": True, - }, - "image": { - "caption": "caption", - "filename": "filename", - "link": "http://example.com/media.jpg", - "voice": True, - }, - "sub_text": "sub_text", - "text": "text", - "video": { - "caption": "caption", - "filename": "filename", - "link": "http://example.com/media.jpg", - "voice": True, - }, - }, - "type": "cta_url", - }, - "location": { - "address": "address", - "latitude": "latitude", - "longitude": "longitude", - "name": "name", - }, - "reaction": { - "emoji": "emoji", - "message_id": "message_id", - }, - "sticker": { - "caption": "caption", - "filename": "filename", - "link": "http://example.com/media.jpg", - "voice": True, - }, - "template": { - "components": [ - { - "index": 0, - "parameters": [ - { - "text": "text", - "type": "text", - } - ], - "sub_type": "quick_reply", - "type": "header", - } - ], - "language": { - "code": "en_US", - "policy": "deterministic", - }, - "name": "order_confirmation", - "template_id": "019cd44b-3a1c-781b-956e-bd33e9fd2ac6", - }, - "text": { - "body": "Hello from Telnyx!", - "preview_url": True, - }, - "type": "audio", - "video": { - "caption": "caption", - "filename": "filename", - "link": "http://example.com/media.jpg", - "voice": True, - }, - }, - messaging_profile_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - type="WHATSAPP", - webhook_url="webhook_url", - ) - assert_matches_type(MessageSendWhatsappResponse, message, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_raw_response_send_whatsapp(self, client: Telnyx) -> None: - response = client.messages.with_raw_response.send_whatsapp( - from_="+13125551234", - to="+13125551234", - whatsapp_message={}, - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - message = response.parse() - assert_matches_type(MessageSendWhatsappResponse, message, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_streaming_response_send_whatsapp(self, client: Telnyx) -> None: - with client.messages.with_streaming_response.send_whatsapp( - from_="+13125551234", - to="+13125551234", - whatsapp_message={}, - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - message = response.parse() - assert_matches_type(MessageSendWhatsappResponse, message, path=["response"]) - - assert cast(Any, response.is_closed) is True - @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize def test_method_send_with_alphanumeric_sender(self, client: Telnyx) -> None: @@ -1241,254 +992,6 @@ async def test_streaming_response_send_short_code(self, async_client: AsyncTelny assert cast(Any, response.is_closed) is True - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_method_send_whatsapp(self, async_client: AsyncTelnyx) -> None: - message = await async_client.messages.send_whatsapp( - from_="+13125551234", - to="+13125551234", - whatsapp_message={}, - ) - assert_matches_type(MessageSendWhatsappResponse, message, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_method_send_whatsapp_with_all_params(self, async_client: AsyncTelnyx) -> None: - message = await async_client.messages.send_whatsapp( - from_="+13125551234", - to="+13125551234", - whatsapp_message={ - "audio": { - "caption": "caption", - "filename": "filename", - "link": "http://example.com/media.jpg", - "voice": True, - }, - "biz_opaque_callback_data": "biz_opaque_callback_data", - "contacts": [ - { - "addresses": [ - { - "city": "city", - "country": "country", - "country_code": "country_code", - "state": "state", - "street": "street", - "type": "type", - "zip": "zip", - } - ], - "birthday": "birthday", - "emails": [ - { - "email": "email", - "type": "type", - } - ], - "name": "name", - "org": { - "company": "company", - "department": "department", - "title": "title", - }, - "phones": [ - { - "phone": "phone", - "type": "type", - "wa_id": "wa_id", - } - ], - "urls": [ - { - "type": "type", - "url": "url", - } - ], - } - ], - "document": { - "caption": "caption", - "filename": "filename", - "link": "http://example.com/media.jpg", - "voice": True, - }, - "image": { - "caption": "caption", - "filename": "filename", - "link": "http://example.com/media.jpg", - "voice": True, - }, - "interactive": { - "action": { - "button": "button", - "buttons": [ - { - "reply": { - "id": "id", - "title": "title", - }, - "type": "reply", - } - ], - "cards": [ - { - "action": { - "catalog_id": "catalog_id", - "product_retailer_id": "product_retailer_id", - }, - "body": {"text": "text"}, - "card_index": 0, - "header": { - "image": { - "caption": "caption", - "filename": "filename", - "link": "http://example.com/media.jpg", - "voice": True, - }, - "type": "image", - "video": { - "caption": "caption", - "filename": "filename", - "link": "http://example.com/media.jpg", - "voice": True, - }, - }, - "type": "cta_url", - } - ], - "catalog_id": "catalog_id", - "mode": "mode", - "name": "name", - "parameters": { - "display_text": "display_text", - "url": "url", - }, - "product_retailer_id": "product_retailer_id", - "sections": [ - { - "product_items": [{"product_retailer_id": "product_retailer_id"}], - "rows": [ - { - "id": "id", - "description": "description", - "title": "title", - } - ], - "title": "title", - } - ], - }, - "body": {"text": "text"}, - "footer": {"text": "text"}, - "header": { - "document": { - "caption": "caption", - "filename": "filename", - "link": "http://example.com/media.jpg", - "voice": True, - }, - "image": { - "caption": "caption", - "filename": "filename", - "link": "http://example.com/media.jpg", - "voice": True, - }, - "sub_text": "sub_text", - "text": "text", - "video": { - "caption": "caption", - "filename": "filename", - "link": "http://example.com/media.jpg", - "voice": True, - }, - }, - "type": "cta_url", - }, - "location": { - "address": "address", - "latitude": "latitude", - "longitude": "longitude", - "name": "name", - }, - "reaction": { - "emoji": "emoji", - "message_id": "message_id", - }, - "sticker": { - "caption": "caption", - "filename": "filename", - "link": "http://example.com/media.jpg", - "voice": True, - }, - "template": { - "components": [ - { - "index": 0, - "parameters": [ - { - "text": "text", - "type": "text", - } - ], - "sub_type": "quick_reply", - "type": "header", - } - ], - "language": { - "code": "en_US", - "policy": "deterministic", - }, - "name": "order_confirmation", - "template_id": "019cd44b-3a1c-781b-956e-bd33e9fd2ac6", - }, - "text": { - "body": "Hello from Telnyx!", - "preview_url": True, - }, - "type": "audio", - "video": { - "caption": "caption", - "filename": "filename", - "link": "http://example.com/media.jpg", - "voice": True, - }, - }, - messaging_profile_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - type="WHATSAPP", - webhook_url="webhook_url", - ) - assert_matches_type(MessageSendWhatsappResponse, message, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_raw_response_send_whatsapp(self, async_client: AsyncTelnyx) -> None: - response = await async_client.messages.with_raw_response.send_whatsapp( - from_="+13125551234", - to="+13125551234", - whatsapp_message={}, - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - message = await response.parse() - assert_matches_type(MessageSendWhatsappResponse, message, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_streaming_response_send_whatsapp(self, async_client: AsyncTelnyx) -> None: - async with async_client.messages.with_streaming_response.send_whatsapp( - from_="+13125551234", - to="+13125551234", - whatsapp_message={}, - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - message = await response.parse() - assert_matches_type(MessageSendWhatsappResponse, message, path=["response"]) - - assert cast(Any, response.is_closed) is True - @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize async def test_method_send_with_alphanumeric_sender(self, async_client: AsyncTelnyx) -> None: