oneshot-python 0.15.0__tar.gz → 0.16.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (20) hide show
  1. {oneshot_python-0.15.0 → oneshot_python-0.16.0}/PKG-INFO +1 -1
  2. {oneshot_python-0.15.0 → oneshot_python-0.16.0}/oneshot/client.py +22 -3
  3. {oneshot_python-0.15.0 → oneshot_python-0.16.0}/pyproject.toml +1 -1
  4. {oneshot_python-0.15.0 → oneshot_python-0.16.0}/tests/test_email_payload.py +12 -0
  5. {oneshot_python-0.15.0 → oneshot_python-0.16.0}/.gitignore +0 -0
  6. {oneshot_python-0.15.0 → oneshot_python-0.16.0}/README.md +0 -0
  7. {oneshot_python-0.15.0 → oneshot_python-0.16.0}/oneshot/__init__.py +0 -0
  8. {oneshot_python-0.15.0 → oneshot_python-0.16.0}/oneshot/_errors.py +0 -0
  9. {oneshot_python-0.15.0 → oneshot_python-0.16.0}/oneshot/_types.py +0 -0
  10. {oneshot_python-0.15.0 → oneshot_python-0.16.0}/oneshot/x402.py +0 -0
  11. {oneshot_python-0.15.0 → oneshot_python-0.16.0}/tests/__init__.py +0 -0
  12. {oneshot_python-0.15.0 → oneshot_python-0.16.0}/tests/test_balance.py +0 -0
  13. {oneshot_python-0.15.0 → oneshot_python-0.16.0}/tests/test_compute.py +0 -0
  14. {oneshot_python-0.15.0 → oneshot_python-0.16.0}/tests/test_emergency_error.py +0 -0
  15. {oneshot_python-0.15.0 → oneshot_python-0.16.0}/tests/test_max_cost_header.py +0 -0
  16. {oneshot_python-0.15.0 → oneshot_python-0.16.0}/tests/test_phones_pending.py +0 -0
  17. {oneshot_python-0.15.0 → oneshot_python-0.16.0}/tests/test_request_id.py +0 -0
  18. {oneshot_python-0.15.0 → oneshot_python-0.16.0}/tests/test_tag_receipt_value.py +0 -0
  19. {oneshot_python-0.15.0 → oneshot_python-0.16.0}/tests/test_x402.py +0 -0
  20. {oneshot_python-0.15.0 → oneshot_python-0.16.0}/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: oneshot-python
3
- Version: 0.15.0
3
+ Version: 0.16.0
4
4
  Summary: Core Python SDK for the OneShot API — HTTP client with x402 payment handling
5
5
  License-Expression: MIT
6
6
  Requires-Python: >=3.10
@@ -38,7 +38,7 @@ try:
38
38
 
39
39
  SDK_VERSION = _pkg_version("oneshot-python")
40
40
  except Exception: # pragma: no cover - editable/source runs without dist metadata
41
- SDK_VERSION = "0.15.0"
41
+ SDK_VERSION = "0.16.0"
42
42
 
43
43
  # ---------------------------------------------------------------------------
44
44
  # Environment configuration
@@ -62,6 +62,7 @@ def _build_email_payload(
62
62
  extra: dict[str, Any],
63
63
  *,
64
64
  reply_to_email_id: Optional[str] = None,
65
+ mailbox_mode: Optional[str] = None,
65
66
  ) -> dict[str, Any]:
66
67
  """Build the /v1/tools/email/send body in the API's field convention.
67
68
 
@@ -93,6 +94,8 @@ def _build_email_payload(
93
94
  payload["reply_to_email_id"] = reply_to_email_id
94
95
  if from_name:
95
96
  payload["from_name"] = from_name
97
+ if mailbox_mode:
98
+ payload["mailbox_mode"] = mailbox_mode
96
99
  return payload
97
100
 
98
101
 
@@ -760,6 +763,7 @@ class OneShotClient:
760
763
  from_mailbox: Optional[str] = None,
761
764
  from_name: Optional[str] = None,
762
765
  reply_to_email_id: Optional[str] = None,
766
+ mailbox_mode: Optional[str] = None,
763
767
  **kwargs: Any,
764
768
  ) -> Any:
765
769
  """Send an email. Blocking.
@@ -767,10 +771,21 @@ class OneShotClient:
767
771
  Set ``reply_to_email_id`` (an inbound email id from ``inbox()``) to
768
772
  reply within a thread — ``to``/``subject`` are then derived from the
769
773
  inbound message unless given.
774
+
775
+ The first send from any ``from_mailbox`` on an owned domain — including
776
+ the default ``agent@`` — provisions a mailbox per address and adds a
777
+ one-time ``mailbox_provisioning_fee`` to the quote; it's free only once
778
+ that address is already provisioned (``active``).
779
+
780
+ ``mailbox_mode`` ('relay' | 'mailbox', default 'relay') selects how a
781
+ domain sends: 'relay' is header-only send (no per-address mailbox, no
782
+ mailbox fee); 'mailbox' provisions a real dedicated mailbox per address
783
+ (better deliverability + per-address warmup). Only applies when a domain
784
+ is first set up — use it on a new ``from_domain``.
770
785
  """
771
786
  return self.call_tool(
772
787
  "/v1/tools/email/send",
773
- _build_email_payload(to, subject, body, from_domain, from_mailbox, from_name, kwargs, reply_to_email_id=reply_to_email_id),
788
+ _build_email_payload(to, subject, body, from_domain, from_mailbox, from_name, kwargs, reply_to_email_id=reply_to_email_id, mailbox_mode=mailbox_mode),
774
789
  )
775
790
 
776
791
  async def aemail(
@@ -783,6 +798,7 @@ class OneShotClient:
783
798
  from_mailbox: Optional[str] = None,
784
799
  from_name: Optional[str] = None,
785
800
  reply_to_email_id: Optional[str] = None,
801
+ mailbox_mode: Optional[str] = None,
786
802
  **kwargs: Any,
787
803
  ) -> Any:
788
804
  """Send an email. Async.
@@ -790,10 +806,13 @@ class OneShotClient:
790
806
  Set ``reply_to_email_id`` (an inbound email id from ``ainbox()``) to
791
807
  reply within a thread — ``to``/``subject`` are then derived from the
792
808
  inbound message unless given.
809
+
810
+ ``mailbox_mode`` ('relay' | 'mailbox', default 'relay') selects how a
811
+ domain sends — see ``email()`` for details.
793
812
  """
794
813
  return await self.acall_tool(
795
814
  "/v1/tools/email/send",
796
- _build_email_payload(to, subject, body, from_domain, from_mailbox, from_name, kwargs, reply_to_email_id=reply_to_email_id),
815
+ _build_email_payload(to, subject, body, from_domain, from_mailbox, from_name, kwargs, reply_to_email_id=reply_to_email_id, mailbox_mode=mailbox_mode),
797
816
  )
798
817
 
799
818
  def voice(self, objective: str, target_number: str, **kwargs: Any) -> Any:
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "oneshot-python"
3
- version = "0.15.0"
3
+ version = "0.16.0"
4
4
  description = "Core Python SDK for the OneShot API — HTTP client with x402 payment handling"
5
5
  readme = {text = "Core Python SDK for the OneShot API", content-type = "text/plain"}
6
6
  license = "MIT"
@@ -46,6 +46,18 @@ def test_payload_passes_extra_kwargs():
46
46
  assert p["wait"] is True
47
47
 
48
48
 
49
+ def test_payload_forwards_mailbox_mode():
50
+ # mailbox_mode is an explicit keyword-only param, forwarded into the send body so
51
+ # the API's per-domain provider override + fee logic sees it.
52
+ p = _build_email_payload("r@x.com", "S", "B", "acme.com", None, None, {}, mailbox_mode="mailbox")
53
+ assert p["mailbox_mode"] == "mailbox"
54
+
55
+
56
+ def test_payload_omits_mailbox_mode_when_absent():
57
+ p = _build_email_payload("r@x.com", "S", "B", "acme.com", None, None, {})
58
+ assert "mailbox_mode" not in p
59
+
60
+
49
61
  # ── reply threading (reply_to_email_id) ───────────────────────────────────
50
62
 
51
63
  def test_reply_payload_omits_to_and_subject_when_derivable():
File without changes