assistant-runtime-sdk 1.9.0__tar.gz → 1.11.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.
- {assistant_runtime_sdk-1.9.0 → assistant_runtime_sdk-1.11.0}/PKG-INFO +3 -2
- {assistant_runtime_sdk-1.9.0 → assistant_runtime_sdk-1.11.0}/README.md +2 -1
- {assistant_runtime_sdk-1.9.0 → assistant_runtime_sdk-1.11.0}/assistant_runtime_sdk/__init__.py +11 -2
- {assistant_runtime_sdk-1.9.0 → assistant_runtime_sdk-1.11.0}/assistant_runtime_sdk/async_client.py +7 -0
- {assistant_runtime_sdk-1.9.0 → assistant_runtime_sdk-1.11.0}/assistant_runtime_sdk/base.py +15 -0
- {assistant_runtime_sdk-1.9.0 → assistant_runtime_sdk-1.11.0}/assistant_runtime_sdk/client.py +95 -1
- {assistant_runtime_sdk-1.9.0 → assistant_runtime_sdk-1.11.0}/assistant_runtime_sdk/types.py +10 -2
- {assistant_runtime_sdk-1.9.0 → assistant_runtime_sdk-1.11.0}/pyproject.toml +1 -1
- {assistant_runtime_sdk-1.9.0 → assistant_runtime_sdk-1.11.0}/LICENSE +0 -0
- {assistant_runtime_sdk-1.9.0 → assistant_runtime_sdk-1.11.0}/assistant_runtime_sdk/auth.py +0 -0
- {assistant_runtime_sdk-1.9.0 → assistant_runtime_sdk-1.11.0}/assistant_runtime_sdk/exceptions.py +0 -0
- {assistant_runtime_sdk-1.9.0 → assistant_runtime_sdk-1.11.0}/assistant_runtime_sdk/skills.py +0 -0
- {assistant_runtime_sdk-1.9.0 → assistant_runtime_sdk-1.11.0}/assistant_runtime_sdk/streaming.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: assistant_runtime_sdk
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.11.0
|
|
4
4
|
Summary: Python SDK for FAC Cloud - the Assistant Runtime AI assistant backend
|
|
5
5
|
Keywords: frappe,ai,assistant,llm,mcp,anthropic,openai,streaming
|
|
6
6
|
Author: Paul Clinton
|
|
@@ -158,7 +158,8 @@ surface. A representative selection:
|
|
|
158
158
|
|
|
159
159
|
**Billing** — `get_plan_comparison()`, `get_usage_dashboard()`, `get_usage_history()`,
|
|
160
160
|
`get_credit_balance()`, `initiate_checkout()`, `create_hosted_checkout()`,
|
|
161
|
-
`
|
|
161
|
+
`get_checkout_session_status()`, `verify_checkout()`, `upgrade_plan()`,
|
|
162
|
+
`cancel_subscription()`, `get_invoices()`,
|
|
162
163
|
`get_payment_instrument()`, `update_payment_method()`
|
|
163
164
|
|
|
164
165
|
**Users & seats** — `register_user()`, `get_user()`, `list_users()`, `invite_user()`,
|
|
@@ -125,7 +125,8 @@ surface. A representative selection:
|
|
|
125
125
|
|
|
126
126
|
**Billing** — `get_plan_comparison()`, `get_usage_dashboard()`, `get_usage_history()`,
|
|
127
127
|
`get_credit_balance()`, `initiate_checkout()`, `create_hosted_checkout()`,
|
|
128
|
-
`
|
|
128
|
+
`get_checkout_session_status()`, `verify_checkout()`, `upgrade_plan()`,
|
|
129
|
+
`cancel_subscription()`, `get_invoices()`,
|
|
129
130
|
`get_payment_instrument()`, `update_payment_method()`
|
|
130
131
|
|
|
131
132
|
**Users & seats** — `register_user()`, `get_user()`, `list_users()`, `invite_user()`,
|
{assistant_runtime_sdk-1.9.0 → assistant_runtime_sdk-1.11.0}/assistant_runtime_sdk/__init__.py
RENAMED
|
@@ -53,7 +53,7 @@ Standalone Functions:
|
|
|
53
53
|
|
|
54
54
|
"""
|
|
55
55
|
|
|
56
|
-
__version__ = "1.
|
|
56
|
+
__version__ = "1.11.0"
|
|
57
57
|
__author__ = "Paul Clinton"
|
|
58
58
|
__license__ = "AGPL-3.0"
|
|
59
59
|
|
|
@@ -61,7 +61,14 @@ __license__ = "AGPL-3.0"
|
|
|
61
61
|
# Core Client Classes
|
|
62
62
|
# =============================================================================
|
|
63
63
|
|
|
64
|
-
from .client import
|
|
64
|
+
from .client import (
|
|
65
|
+
AssistantRuntimeClient,
|
|
66
|
+
change_pending_owner_email,
|
|
67
|
+
get_registration_state,
|
|
68
|
+
get_terms,
|
|
69
|
+
register_tenant,
|
|
70
|
+
resend_owner_verification,
|
|
71
|
+
)
|
|
65
72
|
|
|
66
73
|
# Async client - import lazily to avoid requiring aiohttp
|
|
67
74
|
# Skill providers - import lazily to avoid requiring strands-agents
|
|
@@ -173,6 +180,8 @@ __all__ = [
|
|
|
173
180
|
"get_terms",
|
|
174
181
|
"register_tenant",
|
|
175
182
|
"get_registration_state",
|
|
183
|
+
"resend_owner_verification",
|
|
184
|
+
"change_pending_owner_email",
|
|
176
185
|
# Exceptions - new names
|
|
177
186
|
"ARError",
|
|
178
187
|
"ARAuthenticationError",
|
{assistant_runtime_sdk-1.9.0 → assistant_runtime_sdk-1.11.0}/assistant_runtime_sdk/async_client.py
RENAMED
|
@@ -384,6 +384,7 @@ class AsyncAssistantRuntimeClient(BaseAssistantRuntimeClient):
|
|
|
384
384
|
*,
|
|
385
385
|
web_search: Optional[bool] = None,
|
|
386
386
|
thinking_enabled: Optional[bool] = None,
|
|
387
|
+
reasoning_effort: Optional[str] = None,
|
|
387
388
|
) -> AsyncGenerator[Dict[str, Any], None]:
|
|
388
389
|
"""Async version of AssistantRuntimeClient.stream_chat.
|
|
389
390
|
|
|
@@ -400,6 +401,7 @@ class AsyncAssistantRuntimeClient(BaseAssistantRuntimeClient):
|
|
|
400
401
|
continue_from_message_id=continue_from_message_id,
|
|
401
402
|
web_search=web_search,
|
|
402
403
|
thinking_enabled=thinking_enabled,
|
|
404
|
+
reasoning_effort=reasoning_effort,
|
|
403
405
|
)
|
|
404
406
|
url = self._build_endpoint_url("streaming.stream_chat")
|
|
405
407
|
payload = self._with_site_url(payload)
|
|
@@ -947,6 +949,11 @@ class AsyncAssistantRuntimeClient(BaseAssistantRuntimeClient):
|
|
|
947
949
|
endpoint, payload = self._prepare_create_hosted_checkout(purpose, params, return_url)
|
|
948
950
|
return await self._request_post_json(endpoint, payload, api_base=self.billing_api_base)
|
|
949
951
|
|
|
952
|
+
async def get_checkout_session_status(self, session: str) -> Optional[Dict[str, Any]]:
|
|
953
|
+
"""Async version of AssistantRuntimeClient.get_checkout_session_status."""
|
|
954
|
+
endpoint, payload = self._prepare_get_checkout_session_status(session)
|
|
955
|
+
return await self._request_post_json(endpoint, payload, api_base=self.billing_api_base)
|
|
956
|
+
|
|
950
957
|
async def verify_checkout(self, session_id: Optional[str] = None) -> Optional[Dict[str, Any]]:
|
|
951
958
|
"""Async version of AssistantRuntimeClient.verify_checkout."""
|
|
952
959
|
endpoint, payload = self._prepare_verify_checkout(session_id)
|
|
@@ -316,6 +316,7 @@ class BaseAssistantRuntimeClient:
|
|
|
316
316
|
continue_from_message_id: Optional[str] = None,
|
|
317
317
|
web_search: Optional[bool] = None,
|
|
318
318
|
thinking_enabled: Optional[bool] = None,
|
|
319
|
+
reasoning_effort: Optional[str] = None,
|
|
319
320
|
) -> Dict[str, Any]:
|
|
320
321
|
"""
|
|
321
322
|
Prepare JSON payload for stream_chat POST request.
|
|
@@ -347,6 +348,8 @@ class BaseAssistantRuntimeClient:
|
|
|
347
348
|
previous truncated response from
|
|
348
349
|
web_search: Optional explicit web-search toggle for this turn
|
|
349
350
|
thinking_enabled: Optional explicit extended-thinking toggle for this turn
|
|
351
|
+
reasoning_effort: Optional thinking level for this turn — "off", "low", "medium",
|
|
352
|
+
"high", "xhigh" or "max"
|
|
350
353
|
|
|
351
354
|
Returns:
|
|
352
355
|
Payload dict ready for JSON body
|
|
@@ -400,6 +403,9 @@ class BaseAssistantRuntimeClient:
|
|
|
400
403
|
if thinking_enabled is not None:
|
|
401
404
|
payload["thinking_enabled"] = bool(thinking_enabled)
|
|
402
405
|
|
|
406
|
+
if reasoning_effort is not None:
|
|
407
|
+
payload["reasoning_effort"] = str(reasoning_effort).strip().lower()
|
|
408
|
+
|
|
403
409
|
return payload
|
|
404
410
|
|
|
405
411
|
def _prepare_resource_params(
|
|
@@ -987,6 +993,15 @@ class BaseAssistantRuntimeClient:
|
|
|
987
993
|
payload["return_url"] = return_url
|
|
988
994
|
return "create_hosted_checkout", payload
|
|
989
995
|
|
|
996
|
+
def _prepare_get_checkout_session_status(self, session: str) -> tuple:
|
|
997
|
+
self._require_billing()
|
|
998
|
+
if not session:
|
|
999
|
+
raise ValueError("session is required")
|
|
1000
|
+
return "get_checkout_session_status", {
|
|
1001
|
+
"tenant_id": self.tenant_id,
|
|
1002
|
+
"session": session,
|
|
1003
|
+
}
|
|
1004
|
+
|
|
990
1005
|
def _prepare_verify_checkout(self, session_id: Optional[str] = None) -> tuple:
|
|
991
1006
|
self._require_billing()
|
|
992
1007
|
payload: Dict[str, Any] = {"tenant_id": self.tenant_id}
|
{assistant_runtime_sdk-1.9.0 → assistant_runtime_sdk-1.11.0}/assistant_runtime_sdk/client.py
RENAMED
|
@@ -329,6 +329,7 @@ class AssistantRuntimeClient(BaseAssistantRuntimeClient):
|
|
|
329
329
|
*,
|
|
330
330
|
web_search: Optional[bool] = None,
|
|
331
331
|
thinking_enabled: Optional[bool] = None,
|
|
332
|
+
reasoning_effort: Optional[str] = None,
|
|
332
333
|
) -> Generator[Dict[str, Any], None, None]:
|
|
333
334
|
"""
|
|
334
335
|
Stream chat response from Assistant Runtime.
|
|
@@ -361,6 +362,9 @@ class AssistantRuntimeClient(BaseAssistantRuntimeClient):
|
|
|
361
362
|
truncated response from
|
|
362
363
|
web_search: Optional explicit web-search toggle for this turn
|
|
363
364
|
thinking_enabled: Optional explicit extended-thinking toggle for this turn
|
|
365
|
+
reasoning_effort: Optional thinking level for this turn — "off", "low", "medium",
|
|
366
|
+
"high", "xhigh" or "max". Servers that predate it ignore it, so callers
|
|
367
|
+
should also send thinking_enabled.
|
|
364
368
|
|
|
365
369
|
Yields:
|
|
366
370
|
Parsed SSE events with structure:
|
|
@@ -390,6 +394,7 @@ class AssistantRuntimeClient(BaseAssistantRuntimeClient):
|
|
|
390
394
|
continue_from_message_id=continue_from_message_id,
|
|
391
395
|
web_search=web_search,
|
|
392
396
|
thinking_enabled=thinking_enabled,
|
|
397
|
+
reasoning_effort=reasoning_effort,
|
|
393
398
|
)
|
|
394
399
|
url = self._build_endpoint_url("streaming.stream_chat")
|
|
395
400
|
payload = self._with_site_url(payload)
|
|
@@ -1394,6 +1399,27 @@ class AssistantRuntimeClient(BaseAssistantRuntimeClient):
|
|
|
1394
1399
|
endpoint, payload = self._prepare_create_hosted_checkout(purpose, params, return_url)
|
|
1395
1400
|
return self._request_post_json(endpoint, payload, api_base=self.billing_api_base)
|
|
1396
1401
|
|
|
1402
|
+
def get_checkout_session_status(self, session: str) -> Optional[Dict[str, Any]]:
|
|
1403
|
+
"""
|
|
1404
|
+
Ask whether the purchase a hosted checkout was opened for has landed.
|
|
1405
|
+
|
|
1406
|
+
The checkout page returns the user with ``fac_checkout=<session>``
|
|
1407
|
+
(and ``result=success|processing|cancelled|failed``) on the query
|
|
1408
|
+
string. Poll this with that session until ``done`` is true. It only
|
|
1409
|
+
reads, so polling it never touches the payment gateway.
|
|
1410
|
+
|
|
1411
|
+
Args:
|
|
1412
|
+
session: The ``fac_checkout`` value from the return URL — the
|
|
1413
|
+
``session`` that :meth:`create_hosted_checkout` returned.
|
|
1414
|
+
|
|
1415
|
+
Returns:
|
|
1416
|
+
Dict with status, purpose, target_plan, plan, pending_plan,
|
|
1417
|
+
payment_status, done (bool) and outcome — one of "applied",
|
|
1418
|
+
"processing", "failed" or "cancelled".
|
|
1419
|
+
"""
|
|
1420
|
+
endpoint, payload = self._prepare_get_checkout_session_status(session)
|
|
1421
|
+
return self._request_post_json(endpoint, payload, api_base=self.billing_api_base)
|
|
1422
|
+
|
|
1397
1423
|
def verify_checkout(self, session_id: Optional[str] = None) -> Optional[Dict[str, Any]]:
|
|
1398
1424
|
"""Verify payment completion after checkout."""
|
|
1399
1425
|
endpoint, payload = self._prepare_verify_checkout(session_id)
|
|
@@ -3308,7 +3334,11 @@ def register_tenant(
|
|
|
3308
3334
|
registration cap exactly once.
|
|
3309
3335
|
|
|
3310
3336
|
Returns:
|
|
3311
|
-
Registration result with tenant_id (secret delivered via email link), or
|
|
3337
|
+
Registration result with tenant_id (secret delivered via email link), or
|
|
3338
|
+
error. A newly created pending tenant also carries ``pending_token``,
|
|
3339
|
+
returned only this once: store it securely, because
|
|
3340
|
+
``resend_owner_verification`` and ``change_pending_owner_email``
|
|
3341
|
+
require it.
|
|
3312
3342
|
"""
|
|
3313
3343
|
url = f"{ar_url.rstrip('/')}/api/method/assistant_runtime.api.register_tenant"
|
|
3314
3344
|
|
|
@@ -3368,6 +3398,70 @@ def get_registration_state(
|
|
|
3368
3398
|
return {"error": str(e)}
|
|
3369
3399
|
|
|
3370
3400
|
|
|
3401
|
+
def _post_guest(ar_url: str, method: str, payload: Dict[str, Any], timeout: int = 30) -> Dict[str, Any]:
|
|
3402
|
+
"""POST to a guest AR method, returning AR's own message when it fails.
|
|
3403
|
+
|
|
3404
|
+
Failures come back as ``{"error", "status_code", "exc_type"}``. ``error`` is
|
|
3405
|
+
the message AR raised when the body carries one, so a caller can show it
|
|
3406
|
+
instead of ``str(HTTPError)``; ``exc_type`` is set only in that case.
|
|
3407
|
+
"""
|
|
3408
|
+
url = f"{ar_url.rstrip('/')}/api/method/assistant_runtime.api.{method}"
|
|
3409
|
+
try:
|
|
3410
|
+
response = requests.post(
|
|
3411
|
+
url, json=payload, headers={"Content-Type": "application/json"}, timeout=timeout,
|
|
3412
|
+
)
|
|
3413
|
+
response.raise_for_status()
|
|
3414
|
+
return response.json().get("message", response.json())
|
|
3415
|
+
except requests.exceptions.HTTPError as e:
|
|
3416
|
+
status_code = e.response.status_code if e.response is not None else None
|
|
3417
|
+
try:
|
|
3418
|
+
data = e.response.json() if e.response is not None else None
|
|
3419
|
+
except ValueError:
|
|
3420
|
+
data = None
|
|
3421
|
+
message = BaseAssistantRuntimeClient._extract_error_from_data(data) if isinstance(data, dict) else None
|
|
3422
|
+
if not message:
|
|
3423
|
+
return {"error": str(e), "status_code": status_code}
|
|
3424
|
+
return {"error": message, "status_code": status_code, "exc_type": data.get("exc_type")}
|
|
3425
|
+
except requests.exceptions.RequestException as e:
|
|
3426
|
+
return {"error": str(e), "status_code": None}
|
|
3427
|
+
|
|
3428
|
+
|
|
3429
|
+
def resend_owner_verification(ar_url: str, site_url: str, pending_token: str) -> Dict[str, Any]:
|
|
3430
|
+
"""Ask AR to re-send the pending verification link. No terms, no secret.
|
|
3431
|
+
|
|
3432
|
+
Args:
|
|
3433
|
+
pending_token: The token ``register_tenant`` returned when this site's
|
|
3434
|
+
tenant was created. AR refuses the call without it.
|
|
3435
|
+
|
|
3436
|
+
Returns:
|
|
3437
|
+
AR's result (``success``, ``retry_after``, ``already_verified``,
|
|
3438
|
+
``owner_email_masked``), or ``{"error", "status_code", "exc_type"}``.
|
|
3439
|
+
"""
|
|
3440
|
+
return _post_guest(
|
|
3441
|
+
ar_url, "resend_owner_verification", {"site_url": site_url, "pending_token": pending_token}
|
|
3442
|
+
)
|
|
3443
|
+
|
|
3444
|
+
|
|
3445
|
+
def change_pending_owner_email(
|
|
3446
|
+
ar_url: str, site_url: str, owner_email: str, pending_token: str
|
|
3447
|
+
) -> Dict[str, Any]:
|
|
3448
|
+
"""Correct the owner address while the tenant is still unverified.
|
|
3449
|
+
|
|
3450
|
+
Args:
|
|
3451
|
+
pending_token: The token ``register_tenant`` returned when this site's
|
|
3452
|
+
tenant was created. AR refuses the call without it.
|
|
3453
|
+
|
|
3454
|
+
Returns:
|
|
3455
|
+
AR's result (``success``, ``retry_after``, ``owner_email_masked``), or
|
|
3456
|
+
``{"error", "status_code", "exc_type"}``.
|
|
3457
|
+
"""
|
|
3458
|
+
return _post_guest(
|
|
3459
|
+
ar_url,
|
|
3460
|
+
"change_pending_owner_email",
|
|
3461
|
+
{"site_url": site_url, "owner_email": owner_email, "pending_token": pending_token},
|
|
3462
|
+
)
|
|
3463
|
+
|
|
3464
|
+
|
|
3371
3465
|
def get_initial_secret(ar_url: str, verification_token: str) -> Dict[str, Any]:
|
|
3372
3466
|
"""One-shot retrieval of the freshly-minted tenant_secret after the
|
|
3373
3467
|
owner has confirmed their email via the verification link.
|
|
@@ -16,7 +16,15 @@ from typing import TypedDict, List, Optional, Any
|
|
|
16
16
|
# =============================================================================
|
|
17
17
|
|
|
18
18
|
|
|
19
|
-
class
|
|
19
|
+
class _ModelInfoOptional(TypedDict, total=False):
|
|
20
|
+
"""Keys newer runtimes add to each model; absent on older ones."""
|
|
21
|
+
|
|
22
|
+
thinking_effective: bool
|
|
23
|
+
reasoning_levels: List[str]
|
|
24
|
+
reasoning_off_floor: bool
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class ModelInfo(_ModelInfoOptional):
|
|
20
28
|
"""Information about an available AI model."""
|
|
21
29
|
|
|
22
30
|
model_id: str
|
|
@@ -104,7 +112,7 @@ class RoutingReceiptData(TypedDict):
|
|
|
104
112
|
shortlist_size: int
|
|
105
113
|
pick_reason: str
|
|
106
114
|
notices: List[str]
|
|
107
|
-
thinking: dict # requested, applied, effort, not_applied_reason
|
|
115
|
+
thinking: dict # requested, applied, effort {requested, applied}, effective_budget, not_applied_reason
|
|
108
116
|
credits: dict # actual
|
|
109
117
|
cycles: int
|
|
110
118
|
also_ran: List[str]
|
|
File without changes
|
|
File without changes
|
{assistant_runtime_sdk-1.9.0 → assistant_runtime_sdk-1.11.0}/assistant_runtime_sdk/exceptions.py
RENAMED
|
File without changes
|
{assistant_runtime_sdk-1.9.0 → assistant_runtime_sdk-1.11.0}/assistant_runtime_sdk/skills.py
RENAMED
|
File without changes
|
{assistant_runtime_sdk-1.9.0 → assistant_runtime_sdk-1.11.0}/assistant_runtime_sdk/streaming.py
RENAMED
|
File without changes
|