Forward sandbox into agent builder backend
All checks were successful
build / build (push) Successful in 4s
All checks were successful
build / build (push) Successful in 4s
This commit is contained in:
5
agent.py
5
agent.py
@@ -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,
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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")
|
||||
|
||||
Reference in New Issue
Block a user