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(
|
await ctx.emit_progress(
|
||||||
f"llm: {creds.model} via {creds.source} ({creds.base_url})"
|
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(
|
graph = build_agent_builder(BuilderContext(
|
||||||
bucket=bucket, cp_jwt=cp_jwt,
|
bucket=bucket, cp_jwt=cp_jwt,
|
||||||
project_prefix=f"agents/{name}",
|
project_prefix=f"agents/{name}",
|
||||||
workspace=workspace,
|
workspace=workspace,
|
||||||
|
sandbox=sandbox,
|
||||||
grant_token=getattr(workspace, "_grant_token", None),
|
grant_token=getattr(workspace, "_grant_token", None),
|
||||||
llm_base_url=creds.base_url,
|
llm_base_url=creds.base_url,
|
||||||
llm_api_key=creds.api_key,
|
llm_api_key=creds.api_key,
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ class BuilderContext:
|
|||||||
settings: Settings | None = None
|
settings: Settings | None = None
|
||||||
project_prefix: str | None = None
|
project_prefix: str | None = None
|
||||||
workspace: Any | None = None
|
workspace: Any | None = None
|
||||||
|
sandbox: Any | None = None
|
||||||
grant_token: str | None = None
|
grant_token: str | None = None
|
||||||
# LLM creds forwarded by the orchestrator according to this agent's Card.
|
# LLM creds forwarded by the orchestrator according to this agent's Card.
|
||||||
# The builder accepts caller-selected creds and falls back to platform
|
# 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
|
except Exception: # noqa: BLE001
|
||||||
return _with_builder_skills(StateBackend())
|
return _with_builder_skills(StateBackend())
|
||||||
return _with_builder_skills(
|
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}",
|
artifacts_root=f"/{prefix}/{_BUILDER_ARTIFACT_DIR}",
|
||||||
)
|
)
|
||||||
try:
|
try:
|
||||||
@@ -404,12 +410,21 @@ def _build_project_backend(ctx: BuilderContext, *, settings: Settings) -> Any |
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
return _with_builder_skills(
|
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}",
|
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.
|
"""Patch older a2a-pack WorkspaceBackend grep glob behavior.
|
||||||
|
|
||||||
Older ``WorkspaceBackend.grep`` only matched ``glob`` against the full
|
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 result
|
||||||
return super().grep(pattern, path=path, glob=scoped_glob)
|
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:
|
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}",
|
"config={\"recursion_limit\": DEEPAGENTS_RECURSION_LIMIT}",
|
||||||
agent_source,
|
agent_source,
|
||||||
)
|
)
|
||||||
|
self.assertIn("sandbox = ctx.sandbox", agent_source)
|
||||||
|
self.assertIn("sandbox=sandbox", agent_source)
|
||||||
self.assertIn("stream=True", agent_source)
|
self.assertIn("stream=True", agent_source)
|
||||||
self.assertIn('grant_write_prefixes=("agents/{name}/",)', 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,
|
result.matches,
|
||||||
[{"path": "/agents/github-repo-inspector/agent.py"}],
|
[{"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