diff --git a/agent.py b/agent.py index 7e9da97..2e3aa2e 100644 --- a/agent.py +++ b/agent.py @@ -278,4 +278,4 @@ def _find_url(value: Any) -> str | None: m = _URL_RE.search(value) return m.group(0) if m else None return None -# rebuild against a2a-pack 0.1.32 for Knative agent manifests +# rebuild against a2a-pack 0.1.33 for workspace-backed DeepAgents artifacts diff --git a/agent_builder/builder.py b/agent_builder/builder.py index 271f391..96a0e33 100644 --- a/agent_builder/builder.py +++ b/agent_builder/builder.py @@ -17,6 +17,7 @@ from .tools import ToolContext, build_tools BUILDER_SKILL_SOURCE = "/.agent-builder/skills/" _BUILDER_SKILL_NAMESPACE = ("agent-builder", "skills") +_BUILDER_ARTIFACT_DIR = ".agent-builder" @dataclass(frozen=True) @@ -324,7 +325,10 @@ def _build_project_backend(ctx: BuilderContext, *, settings: Settings) -> Any | from a2a_pack.deepagents import WorkspaceBackend except Exception: # noqa: BLE001 return _with_builder_skills(StateBackend()) - return _with_builder_skills(WorkspaceBackend(ctx.workspace)) + return _with_builder_skills( + WorkspaceBackend(ctx.workspace), + artifacts_root=f"/{prefix}/{_BUILDER_ARTIFACT_DIR}", + ) try: from a2a_pack import Grant, WorkspaceAccess, WorkspaceMode from a2a_pack.deepagents import WorkspaceBackend @@ -357,10 +361,13 @@ def _build_project_backend(ctx: BuilderContext, *, settings: Settings) -> Any | write_prefixes=(f"{prefix}/", "outputs/"), ) ) - return _with_builder_skills(WorkspaceBackend(workspace)) + return _with_builder_skills( + WorkspaceBackend(workspace), + artifacts_root=f"/{prefix}/{_BUILDER_ARTIFACT_DIR}", + ) -def _with_builder_skills(default_backend: Any) -> Any: +def _with_builder_skills(default_backend: Any, *, artifacts_root: str = "/") -> Any: skill_store = InMemoryStore() for path, content in _builder_skill_files().items(): skill_store.put( @@ -375,6 +382,7 @@ def _with_builder_skills(default_backend: Any) -> Any: return CompositeBackend( default=default_backend, routes={BUILDER_SKILL_SOURCE: skill_backend}, + artifacts_root=artifacts_root, ) diff --git a/agent_builder/tools.py b/agent_builder/tools.py index 85f80a2..856cbf4 100644 --- a/agent_builder/tools.py +++ b/agent_builder/tools.py @@ -28,7 +28,7 @@ if TYPE_CHECKING: from .config import Settings -A2A_PACK_MIN_VERSION = "0.1.32" +A2A_PACK_MIN_VERSION = "0.1.33" @dataclass(frozen=True) diff --git a/requirements.txt b/requirements.txt index 6906161..6ed8a02 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ -a2a-pack>=0.1.32 +a2a-pack>=0.1.33 httpx>=0.27 boto3>=1.34 deepagents>=0.5.0 diff --git a/tests/test_builder_prompt.py b/tests/test_builder_prompt.py index cc7872f..c1cf226 100644 --- a/tests/test_builder_prompt.py +++ b/tests/test_builder_prompt.py @@ -5,10 +5,13 @@ import unittest from agent_builder.builder import ( BUILDER_SKILL_SOURCE, + BuilderContext, SYSTEM_PROMPT, + _build_project_backend, _builder_skill_files, _with_builder_skills, ) +from agent_builder.config import Settings from agent_builder.tools import A2A_PACK_MIN_VERSION from deepagents.backends import StateBackend @@ -128,3 +131,31 @@ class BuilderPromptTests(unittest.TestCase): paths = [entry["path"] for entry in (listing.entries or [])] for skill_name in expected: self.assertIn(f"{BUILDER_SKILL_SOURCE}{skill_name}/", paths) + + def test_project_backend_keeps_deepagents_artifacts_inside_project_grant(self) -> None: + backend = _build_project_backend( + BuilderContext( + bucket="user-1-files", + project_prefix="agents/svgwrite-agent", + workspace=object(), + ), + settings=Settings( + sandbox_url="http://sandbox", + sandbox_timeout_s=1200, + sandbox_token=None, + deploy_wait_timeout_s=900, + litellm_url="http://litellm", + litellm_key="", + litellm_model="gpt-5.5", + cp_url="http://control-plane", + minio_endpoint="http://minio", + minio_access_key="", + minio_secret_key="", + image="python:3.11-slim", + ), + ) + + self.assertEqual( + backend.artifacts_root, + "/agents/svgwrite-agent/.agent-builder", + )