getstack 0.9.0__tar.gz → 0.10.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.
- {getstack-0.9.0 → getstack-0.10.0}/PKG-INFO +1 -1
- {getstack-0.9.0 → getstack-0.10.0}/pyproject.toml +1 -1
- {getstack-0.9.0 → getstack-0.10.0}/src/getstack/__init__.py +3 -0
- getstack-0.10.0/src/getstack/_async/partner_tenants.py +78 -0
- getstack-0.10.0/src/getstack/partner_tenants.py +83 -0
- {getstack-0.9.0 → getstack-0.10.0}/.gitignore +0 -0
- {getstack-0.9.0 → getstack-0.10.0}/CLAUDE.md +0 -0
- {getstack-0.9.0 → getstack-0.10.0}/LICENSE +0 -0
- {getstack-0.9.0 → getstack-0.10.0}/README.md +0 -0
- {getstack-0.9.0 → getstack-0.10.0}/src/getstack/_async/__init__.py +0 -0
- {getstack-0.9.0 → getstack-0.10.0}/src/getstack/_async/agents.py +0 -0
- {getstack-0.9.0 → getstack-0.10.0}/src/getstack/_async/audit.py +0 -0
- {getstack-0.9.0 → getstack-0.10.0}/src/getstack/_async/credentials.py +0 -0
- {getstack-0.9.0 → getstack-0.10.0}/src/getstack/_async/dropoffs.py +0 -0
- {getstack-0.9.0 → getstack-0.10.0}/src/getstack/_async/identity.py +0 -0
- {getstack-0.9.0 → getstack-0.10.0}/src/getstack/_async/inbound_webhooks.py +0 -0
- {getstack-0.9.0 → getstack-0.10.0}/src/getstack/_async/intents.py +0 -0
- {getstack-0.9.0 → getstack-0.10.0}/src/getstack/_async/llm.py +0 -0
- {getstack-0.9.0 → getstack-0.10.0}/src/getstack/_async/missions.py +0 -0
- {getstack-0.9.0 → getstack-0.10.0}/src/getstack/_async/notifications.py +0 -0
- {getstack-0.9.0 → getstack-0.10.0}/src/getstack/_async/passport_session.py +0 -0
- {getstack-0.9.0 → getstack-0.10.0}/src/getstack/_async/passports.py +0 -0
- {getstack-0.9.0 → getstack-0.10.0}/src/getstack/_async/proxy.py +0 -0
- {getstack-0.9.0 → getstack-0.10.0}/src/getstack/_async/reviews.py +0 -0
- {getstack-0.9.0 → getstack-0.10.0}/src/getstack/_async/scan.py +0 -0
- {getstack-0.9.0 → getstack-0.10.0}/src/getstack/_async/security_events.py +0 -0
- {getstack-0.9.0 → getstack-0.10.0}/src/getstack/_async/services.py +0 -0
- {getstack-0.9.0 → getstack-0.10.0}/src/getstack/_async/skills.py +0 -0
- {getstack-0.9.0 → getstack-0.10.0}/src/getstack/agent_auth.py +0 -0
- {getstack-0.9.0 → getstack-0.10.0}/src/getstack/agents.py +0 -0
- {getstack-0.9.0 → getstack-0.10.0}/src/getstack/audit.py +0 -0
- {getstack-0.9.0 → getstack-0.10.0}/src/getstack/auth.py +0 -0
- {getstack-0.9.0 → getstack-0.10.0}/src/getstack/browser_bootstrap.py +0 -0
- {getstack-0.9.0 → getstack-0.10.0}/src/getstack/client.py +0 -0
- {getstack-0.9.0 → getstack-0.10.0}/src/getstack/credentials.py +0 -0
- {getstack-0.9.0 → getstack-0.10.0}/src/getstack/dropoffs.py +0 -0
- {getstack-0.9.0 → getstack-0.10.0}/src/getstack/errors.py +0 -0
- {getstack-0.9.0 → getstack-0.10.0}/src/getstack/evidence_packs.py +0 -0
- {getstack-0.9.0 → getstack-0.10.0}/src/getstack/identity.py +0 -0
- {getstack-0.9.0 → getstack-0.10.0}/src/getstack/inbound_webhooks.py +0 -0
- {getstack-0.9.0 → getstack-0.10.0}/src/getstack/intents.py +0 -0
- {getstack-0.9.0 → getstack-0.10.0}/src/getstack/llm.py +0 -0
- {getstack-0.9.0 → getstack-0.10.0}/src/getstack/missions.py +0 -0
- {getstack-0.9.0 → getstack-0.10.0}/src/getstack/notifications.py +0 -0
- {getstack-0.9.0 → getstack-0.10.0}/src/getstack/passport_session.py +0 -0
- {getstack-0.9.0 → getstack-0.10.0}/src/getstack/passports.py +0 -0
- {getstack-0.9.0 → getstack-0.10.0}/src/getstack/proxy.py +0 -0
- {getstack-0.9.0 → getstack-0.10.0}/src/getstack/py.typed +0 -0
- {getstack-0.9.0 → getstack-0.10.0}/src/getstack/reviews.py +0 -0
- {getstack-0.9.0 → getstack-0.10.0}/src/getstack/scan.py +0 -0
- {getstack-0.9.0 → getstack-0.10.0}/src/getstack/security_events.py +0 -0
- {getstack-0.9.0 → getstack-0.10.0}/src/getstack/services.py +0 -0
- {getstack-0.9.0 → getstack-0.10.0}/src/getstack/skills.py +0 -0
- {getstack-0.9.0 → getstack-0.10.0}/src/getstack/types.py +0 -0
|
@@ -226,6 +226,7 @@ class Stack:
|
|
|
226
226
|
self.evidence_packs = EvidencePacksService(self._client)
|
|
227
227
|
self.llm = LlmService(self._client)
|
|
228
228
|
self.inbound_webhooks = InboundWebhookService(self._client)
|
|
229
|
+
self.partner_tenants = PartnerTenantsService(self._client)
|
|
229
230
|
|
|
230
231
|
def issue_passport(
|
|
231
232
|
self,
|
|
@@ -366,6 +367,7 @@ class AsyncStack:
|
|
|
366
367
|
from ._async.missions import AsyncMissionsService
|
|
367
368
|
from ._async.llm import AsyncLlmService
|
|
368
369
|
from ._async.inbound_webhooks import AsyncInboundWebhookService
|
|
370
|
+
from ._async.partner_tenants import AsyncPartnerTenantsService
|
|
369
371
|
from ._async.passport_session import AsyncPassportSession
|
|
370
372
|
|
|
371
373
|
self.agents = AsyncAgentService(self._client)
|
|
@@ -385,6 +387,7 @@ class AsyncStack:
|
|
|
385
387
|
self.missions = AsyncMissionsService(self._client)
|
|
386
388
|
self.llm = AsyncLlmService(self._client)
|
|
387
389
|
self.inbound_webhooks = AsyncInboundWebhookService(self._client)
|
|
390
|
+
self.partner_tenants = AsyncPartnerTenantsService(self._client)
|
|
388
391
|
# Stash for issue_passport() — Python doesn't easily expose the
|
|
389
392
|
# class binding without re-importing inside the method body.
|
|
390
393
|
self._AsyncPassportSession = AsyncPassportSession
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
"""Async mirror of PartnerTenantsService (Phase 5.6)."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import Any, Literal, Optional
|
|
6
|
+
|
|
7
|
+
from ..client import AsyncHttpClient
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
Tier = Literal["free", "developer", "studio", "enterprise"]
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class AsyncPartnerTenantsService:
|
|
14
|
+
def __init__(self, client: AsyncHttpClient):
|
|
15
|
+
self._client = client
|
|
16
|
+
|
|
17
|
+
async def create(
|
|
18
|
+
self,
|
|
19
|
+
external_customer_id: Optional[str] = None,
|
|
20
|
+
tier: Optional[Tier] = None,
|
|
21
|
+
) -> dict[str, Any]:
|
|
22
|
+
body: dict[str, Any] = {}
|
|
23
|
+
if external_customer_id is not None:
|
|
24
|
+
body["external_customer_id"] = external_customer_id
|
|
25
|
+
if tier is not None:
|
|
26
|
+
body["tier"] = tier
|
|
27
|
+
return await self._client.post("/v1/partner/tenants", json=body)
|
|
28
|
+
|
|
29
|
+
async def list(self) -> list[dict[str, Any]]:
|
|
30
|
+
res = await self._client.get("/v1/partner/tenants")
|
|
31
|
+
return list(res.get("tenants", []))
|
|
32
|
+
|
|
33
|
+
async def get(self, tenant_id: str) -> dict[str, Any]:
|
|
34
|
+
return await self._client.get(f"/v1/partner/tenants/{tenant_id}")
|
|
35
|
+
|
|
36
|
+
async def revoke(self, tenant_id: str) -> dict[str, Any]:
|
|
37
|
+
return await self._client.delete(f"/v1/partner/tenants/{tenant_id}")
|
|
38
|
+
|
|
39
|
+
async def create_inbound_webhook(
|
|
40
|
+
self,
|
|
41
|
+
tenant_id: str,
|
|
42
|
+
provider: Literal["agentmail", "generic"],
|
|
43
|
+
agent_id: str,
|
|
44
|
+
forward_url: Optional[str] = None,
|
|
45
|
+
generic_config: Optional[dict[str, Any]] = None,
|
|
46
|
+
) -> dict[str, Any]:
|
|
47
|
+
body: dict[str, Any] = {"provider": provider, "agent_id": agent_id}
|
|
48
|
+
if forward_url is not None:
|
|
49
|
+
body["forward_url"] = forward_url
|
|
50
|
+
if generic_config is not None:
|
|
51
|
+
body["generic_config"] = generic_config
|
|
52
|
+
return await self._client.post(
|
|
53
|
+
f"/v1/partner/tenants/{tenant_id}/inbound-webhooks",
|
|
54
|
+
json=body,
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
async def issue_passport(
|
|
58
|
+
self,
|
|
59
|
+
tenant_id: str,
|
|
60
|
+
agent_id: str,
|
|
61
|
+
ttl_seconds: Optional[int] = None,
|
|
62
|
+
services: Optional[list[dict[str, Any]]] = None,
|
|
63
|
+
named_intents: Optional[list[str]] = None,
|
|
64
|
+
accountability_mode: Optional[Literal["enforced", "logged", "standard"]] = None,
|
|
65
|
+
) -> dict[str, Any]:
|
|
66
|
+
body: dict[str, Any] = {"agent_id": agent_id}
|
|
67
|
+
if ttl_seconds is not None:
|
|
68
|
+
body["ttl_seconds"] = ttl_seconds
|
|
69
|
+
if services is not None:
|
|
70
|
+
body["services"] = services
|
|
71
|
+
if named_intents is not None:
|
|
72
|
+
body["named_intents"] = named_intents
|
|
73
|
+
if accountability_mode is not None:
|
|
74
|
+
body["accountability_mode"] = accountability_mode
|
|
75
|
+
return await self._client.post(
|
|
76
|
+
f"/v1/partner/tenants/{tenant_id}/passports/issue",
|
|
77
|
+
json=body,
|
|
78
|
+
)
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
"""Partner-tenancy surface (Phase 5.6).
|
|
2
|
+
|
|
3
|
+
Platform partners (AgentMail, Cofounder, etc.) with is_partner=True on
|
|
4
|
+
their operator row provision isolated child operators on behalf of
|
|
5
|
+
their customers via this service.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
from typing import Any, Literal, Optional
|
|
11
|
+
|
|
12
|
+
from .client import HttpClient
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
Tier = Literal["free", "developer", "studio", "enterprise"]
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class PartnerTenantsService:
|
|
19
|
+
def __init__(self, client: HttpClient):
|
|
20
|
+
self._client = client
|
|
21
|
+
|
|
22
|
+
def create(
|
|
23
|
+
self,
|
|
24
|
+
external_customer_id: Optional[str] = None,
|
|
25
|
+
tier: Optional[Tier] = None,
|
|
26
|
+
) -> dict[str, Any]:
|
|
27
|
+
body: dict[str, Any] = {}
|
|
28
|
+
if external_customer_id is not None:
|
|
29
|
+
body["external_customer_id"] = external_customer_id
|
|
30
|
+
if tier is not None:
|
|
31
|
+
body["tier"] = tier
|
|
32
|
+
return self._client.post("/v1/partner/tenants", json=body)
|
|
33
|
+
|
|
34
|
+
def list(self) -> list[dict[str, Any]]:
|
|
35
|
+
res = self._client.get("/v1/partner/tenants")
|
|
36
|
+
return list(res.get("tenants", []))
|
|
37
|
+
|
|
38
|
+
def get(self, tenant_id: str) -> dict[str, Any]:
|
|
39
|
+
return self._client.get(f"/v1/partner/tenants/{tenant_id}")
|
|
40
|
+
|
|
41
|
+
def revoke(self, tenant_id: str) -> dict[str, Any]:
|
|
42
|
+
return self._client.delete(f"/v1/partner/tenants/{tenant_id}")
|
|
43
|
+
|
|
44
|
+
def create_inbound_webhook(
|
|
45
|
+
self,
|
|
46
|
+
tenant_id: str,
|
|
47
|
+
provider: Literal["agentmail", "generic"],
|
|
48
|
+
agent_id: str,
|
|
49
|
+
forward_url: Optional[str] = None,
|
|
50
|
+
generic_config: Optional[dict[str, Any]] = None,
|
|
51
|
+
) -> dict[str, Any]:
|
|
52
|
+
body: dict[str, Any] = {"provider": provider, "agent_id": agent_id}
|
|
53
|
+
if forward_url is not None:
|
|
54
|
+
body["forward_url"] = forward_url
|
|
55
|
+
if generic_config is not None:
|
|
56
|
+
body["generic_config"] = generic_config
|
|
57
|
+
return self._client.post(
|
|
58
|
+
f"/v1/partner/tenants/{tenant_id}/inbound-webhooks",
|
|
59
|
+
json=body,
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
def issue_passport(
|
|
63
|
+
self,
|
|
64
|
+
tenant_id: str,
|
|
65
|
+
agent_id: str,
|
|
66
|
+
ttl_seconds: Optional[int] = None,
|
|
67
|
+
services: Optional[list[dict[str, Any]]] = None,
|
|
68
|
+
named_intents: Optional[list[str]] = None,
|
|
69
|
+
accountability_mode: Optional[Literal["enforced", "logged", "standard"]] = None,
|
|
70
|
+
) -> dict[str, Any]:
|
|
71
|
+
body: dict[str, Any] = {"agent_id": agent_id}
|
|
72
|
+
if ttl_seconds is not None:
|
|
73
|
+
body["ttl_seconds"] = ttl_seconds
|
|
74
|
+
if services is not None:
|
|
75
|
+
body["services"] = services
|
|
76
|
+
if named_intents is not None:
|
|
77
|
+
body["named_intents"] = named_intents
|
|
78
|
+
if accountability_mode is not None:
|
|
79
|
+
body["accountability_mode"] = accountability_mode
|
|
80
|
+
return self._client.post(
|
|
81
|
+
f"/v1/partner/tenants/{tenant_id}/passports/issue",
|
|
82
|
+
json=body,
|
|
83
|
+
)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|