Forward sandbox into agent builder backend
All checks were successful
build / build (push) Successful in 4s

This commit is contained in:
robert
2026-06-03 21:51:30 -03:00
parent 74c99643b4
commit bc8de5a7ae
3 changed files with 60 additions and 4 deletions

View File

@@ -129,11 +129,16 @@ class AgentBuilder(A2AAgent[BuilderConfig, NoAuth]):
await ctx.emit_progress(
f"llm: {creds.model} via {creds.source} ({creds.base_url})"
)
try:
sandbox = ctx.sandbox
except Exception: # noqa: BLE001 - sandbox is optional in local/MCP runs.
sandbox = None
graph = build_agent_builder(BuilderContext(
bucket=bucket, cp_jwt=cp_jwt,
project_prefix=f"agents/{name}",
workspace=workspace,
sandbox=sandbox,
grant_token=getattr(workspace, "_grant_token", None),
llm_base_url=creds.base_url,
llm_api_key=creds.api_key,

View File

@@ -27,6 +27,7 @@ class BuilderContext:
settings: Settings | None = None
project_prefix: str | None = None
workspace: Any | None = None
sandbox: Any | None = None
grant_token: str | None = None
# LLM creds forwarded by the orchestrator according to this agent's Card.
# The builder accepts caller-selected creds and falls back to platform
@@ -368,7 +369,12 @@ def _build_project_backend(ctx: BuilderContext, *, settings: Settings) -> Any |
except Exception: # noqa: BLE001
return _with_builder_skills(StateBackend())
return _with_builder_skills(
_workspace_backend_with_grep_compat(WorkspaceBackend, ctx.workspace),
_workspace_backend_with_grep_compat(
WorkspaceBackend,
ctx.workspace,
sandbox=ctx.sandbox,
default_image=settings.image,
),
artifacts_root=f"/{prefix}/{_BUILDER_ARTIFACT_DIR}",
)
try:
@@ -404,12 +410,21 @@ def _build_project_backend(ctx: BuilderContext, *, settings: Settings) -> Any |
)
)
return _with_builder_skills(
_workspace_backend_with_grep_compat(WorkspaceBackend, workspace),
_workspace_backend_with_grep_compat(
WorkspaceBackend,
workspace,
sandbox=ctx.sandbox,
default_image=settings.image,
),
artifacts_root=f"/{prefix}/{_BUILDER_ARTIFACT_DIR}",
)
def _workspace_backend_with_grep_compat(workspace_backend_cls: Any, workspace: Any) -> Any:
def _workspace_backend_with_grep_compat(
workspace_backend_cls: Any,
workspace: Any,
**backend_kwargs: Any,
) -> Any:
"""Patch older a2a-pack WorkspaceBackend grep glob behavior.
Older ``WorkspaceBackend.grep`` only matched ``glob`` against the full
@@ -436,7 +451,7 @@ def _workspace_backend_with_grep_compat(workspace_backend_cls: Any, workspace: A
return result
return super().grep(pattern, path=path, glob=scoped_glob)
return BuilderWorkspaceBackend(workspace)
return BuilderWorkspaceBackend(workspace, **backend_kwargs)
def _with_builder_skills(default_backend: Any, *, artifacts_root: str = "/") -> Any:

View File

@@ -27,6 +27,8 @@ class BuilderPromptTests(unittest.TestCase):
"config={\"recursion_limit\": DEEPAGENTS_RECURSION_LIMIT}",
agent_source,
)
self.assertIn("sandbox = ctx.sandbox", agent_source)
self.assertIn("sandbox=sandbox", agent_source)
self.assertIn("stream=True", agent_source)
self.assertIn('grant_write_prefixes=("agents/{name}/",)', agent_source)
@@ -256,3 +258,37 @@ inline = Pricing(price_per_call_usd=0.01, compute={"runtime_seconds": 600}, tota
result.matches,
[{"path": "/agents/github-repo-inspector/agent.py"}],
)
def test_project_backend_grep_compat_preserves_sandbox_kwargs(self) -> None:
class _Backend:
def __init__(
self,
workspace: object,
*,
sandbox: object | None = None,
default_image: str = "python:3.11-slim",
) -> None:
self.workspace = workspace
self.sandbox = sandbox
self.default_image = default_image
def grep(
self,
pattern: str,
path: str | None = None,
glob: str | None = None,
):
return type("GrepResult", (), {"error": None, "matches": []})()
workspace = object()
sandbox = object()
backend = _workspace_backend_with_grep_compat(
_Backend,
workspace,
sandbox=sandbox,
default_image="python:3.12-slim",
)
self.assertIs(backend.workspace, workspace)
self.assertIs(backend.sandbox, sandbox)
self.assertEqual(backend.default_image, "python:3.12-slim")