diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 141e7cd..ff66120 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.47.0" + ".": "0.48.0" } \ No newline at end of file diff --git a/.stats.yml b/.stats.yml index 9a11071..d4b4e6b 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 138 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/zavu/zavudev-69a49371271acbb8de23d4d5336746b1487a5fb9b30189ec74f6a74a8a487951.yml -openapi_spec_hash: 05122bf62f2a0ba6f1948eb97f1af7fb +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/zavu/zavudev-3a307b6fa4a6fc0199acbf0660fd1e5ca0ac68082b073b74dbd22e70f3a9ea6e.yml +openapi_spec_hash: a9a255215f69ae2c4abbef59b07f08ea config_hash: 70a26cd21f0ca1b34242677b831603db diff --git a/CHANGELOG.md b/CHANGELOG.md index c559515..f02dd90 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,15 @@ # Changelog +## 0.48.0 (2026-08-05) + +Full Changelog: [v0.47.0...v0.48.0](https://github.com/zavudev/sdk-python/compare/v0.47.0...v0.48.0) + +### Features + +* **api:** api update ([f1dc343](https://github.com/zavudev/sdk-python/commit/f1dc3438dcf4bf96037f6d1a01aad8309ba08857)) +* **api:** api update ([0546196](https://github.com/zavudev/sdk-python/commit/054619616c3c3068170d13e0970bcf9afda85782)) +* **api:** api update ([4a47dca](https://github.com/zavudev/sdk-python/commit/4a47dca13b67b2be25881bf728170497be72e4cc)) + ## 0.47.0 (2026-08-02) Full Changelog: [v0.46.0...v0.47.0](https://github.com/zavudev/sdk-python/compare/v0.46.0...v0.47.0) diff --git a/pyproject.toml b/pyproject.toml index 41c18af..2f4c054 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "zavudev" -version = "0.47.0" +version = "0.48.0" description = "The official Python library for the zavudev API" dynamic = ["readme"] license = "Apache-2.0" diff --git a/src/zavudev/_version.py b/src/zavudev/_version.py index bd5f0f6..919a552 100644 --- a/src/zavudev/_version.py +++ b/src/zavudev/_version.py @@ -1,4 +1,4 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. __title__ = "zavudev" -__version__ = "0.47.0" # x-release-please-version +__version__ = "0.48.0" # x-release-please-version diff --git a/src/zavudev/resources/functions/functions.py b/src/zavudev/resources/functions/functions.py index ab96ec4..6bef2dd 100644 --- a/src/zavudev/resources/functions/functions.py +++ b/src/zavudev/resources/functions/functions.py @@ -101,6 +101,11 @@ def create( source_code: TypeScript source code for the function entry point (max ~900KB). + timeout_sec: Per-invocation timeout in seconds. Event and cron invocations are asynchronous, + so a long timeout only bounds cost; a tool called during a live conversation + holds up the reply, and a function exposed over HTTP is additionally bounded by + the platform's HTTP response limit. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -461,6 +466,11 @@ async def create( source_code: TypeScript source code for the function entry point (max ~900KB). + timeout_sec: Per-invocation timeout in seconds. Event and cron invocations are asynchronous, + so a long timeout only bounds cost; a tool called during a live conversation + holds up the reply, and a function exposed over HTTP is additionally bounded by + the platform's HTTP response limit. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request diff --git a/src/zavudev/resources/phone_numbers.py b/src/zavudev/resources/phone_numbers.py index 6aace0e..61b71b1 100644 --- a/src/zavudev/resources/phone_numbers.py +++ b/src/zavudev/resources/phone_numbers.py @@ -201,8 +201,9 @@ def purchase( ) -> PhoneNumberPurchaseResponse: """Purchase an available phone number. - The first US phone number is free for each - team. + Requires a paid plan: the Free plan cannot + purchase phone numbers and receives `402` with code `paid_plan_required`. Paid + plans include the first US number at no charge. Args: phone_number: Phone number in E.164 format. @@ -537,8 +538,9 @@ async def purchase( ) -> PhoneNumberPurchaseResponse: """Purchase an available phone number. - The first US phone number is free for each - team. + Requires a paid plan: the Free plan cannot + purchase phone numbers and receives `402` with code `paid_plan_required`. Paid + plans include the first US number at no charge. Args: phone_number: Phone number in E.164 format. diff --git a/src/zavudev/resources/senders/agent/tools.py b/src/zavudev/resources/senders/agent/tools.py index 032cf2a..bd916f5 100644 --- a/src/zavudev/resources/senders/agent/tools.py +++ b/src/zavudev/resources/senders/agent/tools.py @@ -297,7 +297,16 @@ def test( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> ToolTestResponse: """ - Test a tool by triggering its webhook with test parameters. + Run a tool with the parameters you supply and return what it answered. + + The call is synchronous: the response carries the tool's status, body, and + duration, so a green result is evidence the tool ran rather than evidence it was + accepted. Each run is also recorded and readable afterwards via + `GET /v1/senders/{senderId}/agent/tools/{toolId}/test-runs`. + + A tool that answers with an error is reported as a run with `success: false` — + the endpoint itself still returns 200. This fires the tool's real webhook, so a + test has whatever side effects the tool has. Args: test_params: Parameters to pass to the tool for testing. @@ -587,7 +596,16 @@ async def test( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> ToolTestResponse: """ - Test a tool by triggering its webhook with test parameters. + Run a tool with the parameters you supply and return what it answered. + + The call is synchronous: the response carries the tool's status, body, and + duration, so a green result is evidence the tool ran rather than evidence it was + accepted. Each run is also recorded and readable afterwards via + `GET /v1/senders/{senderId}/agent/tools/{toolId}/test-runs`. + + A tool that answers with an error is reported as a run with `success: false` — + the endpoint itself still returns 200. This fires the tool's real webhook, so a + test has whatever side effects the tool has. Args: test_params: Parameters to pass to the tool for testing. diff --git a/src/zavudev/resources/senders/senders.py b/src/zavudev/resources/senders/senders.py index 738a918..0510e80 100644 --- a/src/zavudev/resources/senders/senders.py +++ b/src/zavudev/resources/senders/senders.py @@ -90,6 +90,7 @@ def create( email_domain_id: str | Omit = omit, email_from_name: str | Omit = omit, email_receiving_enabled: bool | Omit = omit, + enable_sms_oneway: bool | Omit = omit, enable_voice: bool | Omit = omit, phone_number: str | Omit = omit, set_as_default: bool | Omit = omit, @@ -119,6 +120,11 @@ def create( email_receiving_enabled: Enable inbound email receiving on this sender. Requires a verified MX record on the domain; ignored otherwise. + enable_sms_oneway: Enable the one-way SMS channel (`sms_oneway`). Needs nothing else — no phone + number, no credential — so it is the fastest way to get a sender that can send. + Recipients cannot reply. Confirm with `sms_oneway` in the `channels` array on + the response. + enable_voice: Let this sender place and answer phone calls. Requires `phoneNumber`; enabling it without one returns 400. Check the `channels` array on the response to confirm `voice` is on. @@ -150,6 +156,7 @@ def create( "email_domain_id": email_domain_id, "email_from_name": email_from_name, "email_receiving_enabled": email_receiving_enabled, + "enable_sms_oneway": enable_sms_oneway, "enable_voice": enable_voice, "phone_number": phone_number, "set_as_default": set_as_default, @@ -206,6 +213,7 @@ def update( email_domain_id: str | Omit = omit, email_from_name: str | Omit = omit, email_receiving_enabled: bool | Omit = omit, + enable_sms_oneway: bool | Omit = omit, enable_voice: bool | Omit = omit, name: str | Omit = omit, set_as_default: bool | Omit = omit, @@ -237,6 +245,10 @@ def update( email_receiving_enabled: Enable or disable inbound email receiving for this sender. + enable_sms_oneway: Turn the one-way SMS channel on or off. Enabling needs nothing else and takes + effect immediately; disabling removes the channel from the sender. Confirm with + the `channels` array on the response. + enable_voice: Turn the voice channel on or off. The sender must already have a phone number provisioned for calls; enabling it otherwise returns 400 instead of storing a flag that changes nothing. Confirm with the `channels` array on the response. @@ -266,6 +278,7 @@ def update( "email_domain_id": email_domain_id, "email_from_name": email_from_name, "email_receiving_enabled": email_receiving_enabled, + "enable_sms_oneway": enable_sms_oneway, "enable_voice": enable_voice, "name": name, "set_as_default": set_as_default, @@ -577,6 +590,7 @@ async def create( email_domain_id: str | Omit = omit, email_from_name: str | Omit = omit, email_receiving_enabled: bool | Omit = omit, + enable_sms_oneway: bool | Omit = omit, enable_voice: bool | Omit = omit, phone_number: str | Omit = omit, set_as_default: bool | Omit = omit, @@ -606,6 +620,11 @@ async def create( email_receiving_enabled: Enable inbound email receiving on this sender. Requires a verified MX record on the domain; ignored otherwise. + enable_sms_oneway: Enable the one-way SMS channel (`sms_oneway`). Needs nothing else — no phone + number, no credential — so it is the fastest way to get a sender that can send. + Recipients cannot reply. Confirm with `sms_oneway` in the `channels` array on + the response. + enable_voice: Let this sender place and answer phone calls. Requires `phoneNumber`; enabling it without one returns 400. Check the `channels` array on the response to confirm `voice` is on. @@ -637,6 +656,7 @@ async def create( "email_domain_id": email_domain_id, "email_from_name": email_from_name, "email_receiving_enabled": email_receiving_enabled, + "enable_sms_oneway": enable_sms_oneway, "enable_voice": enable_voice, "phone_number": phone_number, "set_as_default": set_as_default, @@ -693,6 +713,7 @@ async def update( email_domain_id: str | Omit = omit, email_from_name: str | Omit = omit, email_receiving_enabled: bool | Omit = omit, + enable_sms_oneway: bool | Omit = omit, enable_voice: bool | Omit = omit, name: str | Omit = omit, set_as_default: bool | Omit = omit, @@ -724,6 +745,10 @@ async def update( email_receiving_enabled: Enable or disable inbound email receiving for this sender. + enable_sms_oneway: Turn the one-way SMS channel on or off. Enabling needs nothing else and takes + effect immediately; disabling removes the channel from the sender. Confirm with + the `channels` array on the response. + enable_voice: Turn the voice channel on or off. The sender must already have a phone number provisioned for calls; enabling it otherwise returns 400 instead of storing a flag that changes nothing. Confirm with the `channels` array on the response. @@ -753,6 +778,7 @@ async def update( "email_domain_id": email_domain_id, "email_from_name": email_from_name, "email_receiving_enabled": email_receiving_enabled, + "enable_sms_oneway": enable_sms_oneway, "enable_voice": enable_voice, "name": name, "set_as_default": set_as_default, diff --git a/src/zavudev/types/function_create_params.py b/src/zavudev/types/function_create_params.py index 40bdc22..336a028 100644 --- a/src/zavudev/types/function_create_params.py +++ b/src/zavudev/types/function_create_params.py @@ -33,3 +33,9 @@ class FunctionCreateParams(TypedDict, total=False): """TypeScript source code for the function entry point (max ~900KB).""" timeout_sec: Annotated[int, PropertyInfo(alias="timeoutSec")] + """Per-invocation timeout in seconds. + + Event and cron invocations are asynchronous, so a long timeout only bounds cost; + a tool called during a live conversation holds up the reply, and a function + exposed over HTTP is additionally bounded by the platform's HTTP response limit. + """ diff --git a/src/zavudev/types/phone_number_pricing.py b/src/zavudev/types/phone_number_pricing.py index 6c0ac3b..661b5ad 100644 --- a/src/zavudev/types/phone_number_pricing.py +++ b/src/zavudev/types/phone_number_pricing.py @@ -11,7 +11,10 @@ class PhoneNumberPricing(BaseModel): is_free_eligible: Optional[bool] = FieldInfo(alias="isFreeEligible", default=None) - """Whether this number qualifies for the free first US number offer.""" + """ + Whether this number qualifies as the plan-included first US number on paid + plans. + """ monthly_price: Optional[float] = FieldInfo(alias="monthlyPrice", default=None) """Monthly price in USD.""" diff --git a/src/zavudev/types/sender_create_params.py b/src/zavudev/types/sender_create_params.py index 2910d8f..b17db04 100644 --- a/src/zavudev/types/sender_create_params.py +++ b/src/zavudev/types/sender_create_params.py @@ -36,6 +36,14 @@ class SenderCreateParams(TypedDict, total=False): Requires a verified MX record on the domain; ignored otherwise. """ + enable_sms_oneway: Annotated[bool, PropertyInfo(alias="enableSmsOneway")] + """Enable the one-way SMS channel (`sms_oneway`). + + Needs nothing else — no phone number, no credential — so it is the fastest way + to get a sender that can send. Recipients cannot reply. Confirm with + `sms_oneway` in the `channels` array on the response. + """ + enable_voice: Annotated[bool, PropertyInfo(alias="enableVoice")] """Let this sender place and answer phone calls. diff --git a/src/zavudev/types/sender_update_params.py b/src/zavudev/types/sender_update_params.py index 3c58022..3b6d96a 100644 --- a/src/zavudev/types/sender_update_params.py +++ b/src/zavudev/types/sender_update_params.py @@ -39,6 +39,13 @@ class SenderUpdateParams(TypedDict, total=False): email_receiving_enabled: Annotated[bool, PropertyInfo(alias="emailReceivingEnabled")] """Enable or disable inbound email receiving for this sender.""" + enable_sms_oneway: Annotated[bool, PropertyInfo(alias="enableSmsOneway")] + """Turn the one-way SMS channel on or off. + + Enabling needs nothing else and takes effect immediately; disabling removes the + channel from the sender. Confirm with the `channels` array on the response. + """ + enable_voice: Annotated[bool, PropertyInfo(alias="enableVoice")] """Turn the voice channel on or off. diff --git a/src/zavudev/types/senders/agent/tool_test_response.py b/src/zavudev/types/senders/agent/tool_test_response.py index cf16168..46deb65 100644 --- a/src/zavudev/types/senders/agent/tool_test_response.py +++ b/src/zavudev/types/senders/agent/tool_test_response.py @@ -1,9 +1,56 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. +from typing import Dict, Optional +from datetime import datetime + +from pydantic import Field as FieldInfo + from ...._models import BaseModel -__all__ = ["ToolTestResponse"] +__all__ = ["ToolTestResponse", "Run"] + + +class Run(BaseModel): + """One run of a tool triggered from the test endpoint. + + Recorded so a test is verifiable after the fact rather than only visible in the response. + """ + + id: str + + created_at: datetime = FieldInfo(alias="createdAt") + + duration_ms: int = FieldInfo(alias="durationMs") + + success: bool + """Whether the tool returned without error. + + A tool that answered with a non-2xx status is a failed run, not an error of this + endpoint. + """ + + tool_id: str = FieldInfo(alias="toolId") + + error: Optional[str] = None + """Why the run failed, when it did.""" + + params: Optional[Dict[str, object]] = None + """The parameters the tool was called with.""" + + response: Optional[str] = None + """The tool's response body, truncated.""" + + status_code: Optional[int] = FieldInfo(alias="statusCode", default=None) + """HTTP status the tool's webhook returned. + + Absent for tools that do not go over HTTP. + """ class ToolTestResponse(BaseModel): - scheduled: bool + run: Run + """One run of a tool triggered from the test endpoint. + + Recorded so a test is verifiable after the fact rather than only visible in the + response. + """ diff --git a/src/zavudev/types/senders/agent_execution.py b/src/zavudev/types/senders/agent_execution.py index 33e6edc..cd40fdd 100644 --- a/src/zavudev/types/senders/agent_execution.py +++ b/src/zavudev/types/senders/agent_execution.py @@ -46,3 +46,12 @@ class AgentExecution(BaseModel): response_message_id: Optional[str] = FieldInfo(alias="responseMessageId", default=None) response_text: Optional[str] = FieldInfo(alias="responseText", default=None) + + tool_calls: Optional[int] = FieldInfo(alias="toolCalls", default=None) + """Tools the agent called while producing this reply. + + Zero on an agent that has tools configured means it answered without calling any + — the case where a reply says it will look something up and nothing ever reaches + your endpoint. Absent on executions recorded before this field existed, which is + not the same as zero. + """ diff --git a/tests/api_resources/test_senders.py b/tests/api_resources/test_senders.py index 426466c..2683d35 100644 --- a/tests/api_resources/test_senders.py +++ b/tests/api_resources/test_senders.py @@ -41,6 +41,7 @@ def test_method_create_with_all_params(self, client: Zavudev) -> None: email_domain_id="emailDomainId", email_from_name="emailFromName", email_receiving_enabled=True, + enable_sms_oneway=True, enable_voice=True, phone_number="phoneNumber", set_as_default=True, @@ -135,6 +136,7 @@ def test_method_update_with_all_params(self, client: Zavudev) -> None: email_domain_id="emailDomainId", email_from_name="emailFromName", email_receiving_enabled=True, + enable_sms_oneway=True, enable_voice=True, name="name", set_as_default=True, @@ -470,6 +472,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncZavudev) - email_domain_id="emailDomainId", email_from_name="emailFromName", email_receiving_enabled=True, + enable_sms_oneway=True, enable_voice=True, phone_number="phoneNumber", set_as_default=True, @@ -564,6 +567,7 @@ async def test_method_update_with_all_params(self, async_client: AsyncZavudev) - email_domain_id="emailDomainId", email_from_name="emailFromName", email_receiving_enabled=True, + enable_sms_oneway=True, enable_voice=True, name="name", set_as_default=True,