ship grants, a2a_client, discovery, sandbox SDK + tests

This commit is contained in:
robert
2026-05-09 12:43:07 -03:00
parent b6f6cd1643
commit 2dcb8a09cd
15 changed files with 1853 additions and 75 deletions

View File

@@ -199,6 +199,42 @@ class WorkspaceClient(ABC):
@abstractmethod
async def list_grants(self) -> list[WorkspaceGrant]: ...
async def delegate(
self,
*,
audience: str,
allow_patterns: Sequence[str] = ("**",),
deny_patterns: Sequence[str] = (),
mode: WorkspaceMode = WorkspaceMode.READ_ONLY,
outputs_prefix: str | None = None,
ttl_seconds: int = 300,
) -> str:
"""Mint a signed grant token the caller can hand to ``ctx.call``.
The default implementation requires the workspace to expose
``self.bucket`` and ``self.issuer`` — override in concrete clients
that don't fit that shape.
"""
from .grants import mint_grant
bucket = getattr(self, "bucket", None) or getattr(self, "_bucket", None)
if bucket is None:
raise NotImplementedError(
"this WorkspaceClient does not expose a bucket; override delegate()"
)
issuer = getattr(self, "issuer", "self")
_, token = mint_grant(
issuer=issuer,
audience=audience,
bucket=bucket,
mode=mode,
allow_patterns=tuple(allow_patterns),
deny_patterns=tuple(deny_patterns),
outputs_prefix=outputs_prefix,
ttl_seconds=ttl_seconds,
)
return token
# ---------------------------------------------------------------------------
# Local in-memory implementation, for dev/tests.
@@ -288,11 +324,16 @@ class LocalWorkspaceClient(WorkspaceClient):
files: dict[str, bytes],
*,
access: WorkspaceAccess,
bucket: str = "local",
issuer: str = "local",
) -> None:
self._files: dict[str, bytes] = dict(files)
self._access = access
self._grants: dict[str, WorkspaceGrant] = {}
self._counter = 0
# Expose bucket+issuer so the default WorkspaceClient.delegate() works.
self.bucket = bucket
self.issuer = issuer
def _detect(self, path: str) -> FileType:
for ext, ft in self._EXT_TO_TYPE.items():