oneshot-python 0.24.0__tar.gz → 0.26.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 (32) hide show
  1. {oneshot_python-0.24.0 → oneshot_python-0.26.0}/PKG-INFO +2 -2
  2. {oneshot_python-0.24.0 → oneshot_python-0.26.0}/README.md +26 -1
  3. {oneshot_python-0.24.0 → oneshot_python-0.26.0}/oneshot/__init__.py +6 -0
  4. {oneshot_python-0.24.0 → oneshot_python-0.26.0}/oneshot/_errors.py +22 -0
  5. {oneshot_python-0.24.0 → oneshot_python-0.26.0}/oneshot/_types.py +24 -0
  6. {oneshot_python-0.24.0 → oneshot_python-0.26.0}/oneshot/client.py +400 -18
  7. {oneshot_python-0.24.0 → oneshot_python-0.26.0}/oneshot/physical_mail.py +15 -2
  8. {oneshot_python-0.24.0 → oneshot_python-0.26.0}/pyproject.toml +2 -2
  9. oneshot_python-0.26.0/tests/test_access_token.py +298 -0
  10. oneshot_python-0.26.0/tests/test_linkedin.py +72 -0
  11. oneshot_python-0.26.0/tests/test_top_up_credits.py +87 -0
  12. {oneshot_python-0.24.0 → oneshot_python-0.26.0}/.gitignore +0 -0
  13. {oneshot_python-0.24.0 → oneshot_python-0.26.0}/oneshot/x402.py +0 -0
  14. {oneshot_python-0.24.0 → oneshot_python-0.26.0}/tests/__init__.py +0 -0
  15. {oneshot_python-0.24.0 → oneshot_python-0.26.0}/tests/test_balance.py +0 -0
  16. {oneshot_python-0.24.0 → oneshot_python-0.26.0}/tests/test_browser.py +0 -0
  17. {oneshot_python-0.24.0 → oneshot_python-0.26.0}/tests/test_budgets.py +0 -0
  18. {oneshot_python-0.24.0 → oneshot_python-0.26.0}/tests/test_charge_amount.py +0 -0
  19. {oneshot_python-0.24.0 → oneshot_python-0.26.0}/tests/test_compute.py +0 -0
  20. {oneshot_python-0.24.0 → oneshot_python-0.26.0}/tests/test_domains.py +0 -0
  21. {oneshot_python-0.24.0 → oneshot_python-0.26.0}/tests/test_email_payload.py +0 -0
  22. {oneshot_python-0.24.0 → oneshot_python-0.26.0}/tests/test_emergency_error.py +0 -0
  23. {oneshot_python-0.24.0 → oneshot_python-0.26.0}/tests/test_max_cost_header.py +0 -0
  24. {oneshot_python-0.24.0 → oneshot_python-0.26.0}/tests/test_payment_rejection.py +0 -0
  25. {oneshot_python-0.24.0 → oneshot_python-0.26.0}/tests/test_phones_pending.py +0 -0
  26. {oneshot_python-0.24.0 → oneshot_python-0.26.0}/tests/test_physical_mail.py +0 -0
  27. {oneshot_python-0.24.0 → oneshot_python-0.26.0}/tests/test_poll_backoff.py +0 -0
  28. {oneshot_python-0.24.0 → oneshot_python-0.26.0}/tests/test_request_id.py +0 -0
  29. {oneshot_python-0.24.0 → oneshot_python-0.26.0}/tests/test_tag_receipt_value.py +0 -0
  30. {oneshot_python-0.24.0 → oneshot_python-0.26.0}/tests/test_wait_false.py +0 -0
  31. {oneshot_python-0.24.0 → oneshot_python-0.26.0}/tests/test_x402.py +0 -0
  32. {oneshot_python-0.24.0 → oneshot_python-0.26.0}/uv.lock +0 -0
@@ -1,7 +1,7 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: oneshot-python
3
- Version: 0.24.0
4
- Summary: Core Python SDK for the OneShot API — HTTP client with x402 payment handling — 35 tools
3
+ Version: 0.26.0
4
+ Summary: Core Python SDK for the OneShot API — HTTP client with x402 payment handling — 43 tools
5
5
  License-Expression: MIT
6
6
  Requires-Python: >=3.10
7
7
  Requires-Dist: eth-account>=0.13.0
@@ -66,6 +66,31 @@ Read endpoints (inbox, SMS inbox, notifications, balance, browser profiles) retu
66
66
 
67
67
  This is automatic — no extra code beyond `private_key`. **Requires `oneshot-python >= 0.17.0`.** Older versions keep working until the API enables enforcement, after which they must send a valid `x-agent-proof`.
68
68
 
69
+ ## Access tokens (credits-only sessions)
70
+
71
+ Some code can't hold your wallet key — a hosted MCP client such as Grok Bot, a cloud
72
+ runner, a third-party agent platform. Mint an **access token** from a wallet session and
73
+ hand that over instead:
74
+
75
+ ```python
76
+ # From a wallet session (once):
77
+ created = client.create_access_token(name="grok-bot") # created["token"] is shown once
78
+
79
+ # In the hosted environment:
80
+ hosted = OneShotClient.create(access_token=created["token"]) # resolves the wallet address
81
+ hosted.call_tool("/v1/tools/search", {"query": "…"}) # billed to the agent's credits
82
+ ```
83
+
84
+ An access-token session identifies the agent with the token (no `x-agent-proof`), **pays
85
+ every call from the agent's prepaid credit balance**, and never signs x402. When credits
86
+ can't cover a call it raises `InsufficientCreditsError` (`required`, `balance`,
87
+ `shortfall`) — top up and retry. Budgets set on the agent still apply, with credit-funded
88
+ spend counted; they are **read-only** from a token session (`get_budgets()` works, passing
89
+ `budgets`/`alert_email` raises). A token cannot mint, list, or revoke tokens; do that from
90
+ the wallet session (`list_access_tokens()`, `revoke_access_token(id)`). `access_token` is
91
+ exclusive with `private_key`. Pass `address=` to skip the lookup, and use `acreate` /
92
+ `acreate_access_token` inside `asyncio` programs. **Requires `oneshot-python >= 0.26.0`.**
93
+
69
94
  ## Spend Budgets
70
95
 
71
96
  Cap what the agent can spend so a runaway loop can't drain the wallet overnight:
@@ -192,7 +217,7 @@ Every method has an `a*` async mirror (`acompute`, `aget_compute_goal`, …).
192
217
  ## Links
193
218
 
194
219
  - [Documentation](https://docs.oneshotagent.com/sdk/installation#install-via-pip-python)
195
- - [LangChain integration](https://pypi.org/project/langchain-oneshot/) — 35 tools as LangChain BaseTool
220
+ - [LangChain integration](https://pypi.org/project/langchain-oneshot/) — 43 tools as LangChain BaseTool
196
221
  - [GAME plugin](https://pypi.org/project/game-plugin-oneshot/) — Virtuals Protocol integration
197
222
  - [TypeScript SDK](https://www.npmjs.com/package/@oneshot-agent/sdk)
198
223
  - [MCP Server](https://www.npmjs.com/package/@oneshot-agent/mcp-server)
@@ -7,6 +7,7 @@ from oneshot._errors import (
7
7
  BudgetSyncError,
8
8
  ContentBlockedError,
9
9
  EmergencyNumberError,
10
+ InsufficientCreditsError,
10
11
  JobError,
11
12
  JobTimeoutError,
12
13
  OneShotError,
@@ -15,6 +16,8 @@ from oneshot._errors import (
15
16
  ValidationError,
16
17
  )
17
18
  from oneshot._types import (
19
+ AccessTokenCreated,
20
+ AccessTokenInfo,
18
21
  AgentBudgetConfig,
19
22
  AgentBudgetStatus,
20
23
  ComputeBudgetStatus,
@@ -48,7 +51,10 @@ __all__ = [
48
51
  "ValidationError",
49
52
  "ContentBlockedError",
50
53
  "EmergencyNumberError",
54
+ "InsufficientCreditsError",
51
55
  "sign_payment_authorization",
56
+ "AccessTokenCreated",
57
+ "AccessTokenInfo",
52
58
  "AgentBudgetConfig",
53
59
  "AgentBudgetStatus",
54
60
  "ComputeSchedule",
@@ -115,6 +115,28 @@ class BudgetExceededError(OneShotError):
115
115
  self.resets_at = resets_at
116
116
 
117
117
 
118
+ class InsufficientCreditsError(OneShotError):
119
+ """An access-token (credits-only) session asked for a paid call the agent's
120
+ prepaid credit balance cannot cover. Nothing was charged; top up credits
121
+ and retry, or use a wallet session. ``required``, ``balance`` and
122
+ ``shortfall`` are USDC amounts when the API reported them.
123
+
124
+ Mirrors ``InsufficientCreditsError`` in ``libs/agent-sdk/src/errors.ts``.
125
+ """
126
+
127
+ def __init__(
128
+ self,
129
+ message: str,
130
+ required: float | None = None,
131
+ balance: float | None = None,
132
+ shortfall: float | None = None,
133
+ ) -> None:
134
+ super().__init__(message)
135
+ self.required = required
136
+ self.balance = balance
137
+ self.shortfall = shortfall
138
+
139
+
118
140
  class BudgetSyncError(OneShotError):
119
141
  """The configured spend budget could not be confirmed with the server, so
120
142
  the paid call was NOT made.
@@ -267,3 +267,27 @@ class AgentBudgetStatus(TypedDict):
267
267
  remaining_usdc: Optional[str]
268
268
  pct_used: Optional[float]
269
269
  resets_at: str
270
+
271
+
272
+ class AccessTokenCreated(TypedDict):
273
+ """Response of ``POST /v1/agents/me/access-tokens``. Mirrors ``AccessTokenCreated`` in TS.
274
+ ``token`` is shown exactly once and never stored server-side."""
275
+
276
+ id: str
277
+ token: str
278
+ token_prefix: str
279
+ name: Optional[str]
280
+ created_at: str
281
+
282
+
283
+ class AccessTokenInfo(TypedDict):
284
+ """One row of ``GET /v1/agents/me/access-tokens``. Mirrors ``AccessTokenInfo`` in TS."""
285
+
286
+ id: str
287
+ token_prefix: str
288
+ name: Optional[str]
289
+ source: str
290
+ last_used_at: Optional[str]
291
+ created_at: str
292
+ revoked_at: Optional[str]
293
+ spent_today_usdc: str