Teach builder sandbox rootfs capture
All checks were successful
build / build (push) Successful in 25s
All checks were successful
build / build (push) Successful in 25s
This commit is contained in:
@@ -94,17 +94,18 @@ runtime:
|
||||
```
|
||||
|
||||
For render/media/data agents, commands that create user-visible files MUST run
|
||||
through ``await ctx.workspace_shell(...)`` or ``await ctx.workspace_python(...)``
|
||||
and write under ``/workspace/outputs/...``. Do not use in-process
|
||||
``asyncio.create_subprocess_exec`` for durable outputs; the agent container is
|
||||
not workspace-mounted, so files created in ``/tmp`` or the image filesystem can
|
||||
vanish after the request. Commands must still be bounded with timeouts and broad
|
||||
exception handling, and failures must return structured JSON instead of
|
||||
crashing the worker. Use ``render: bool = False`` by default and expose every
|
||||
public skill argument with concrete type hints so the live ``input_schema``
|
||||
contains the full call surface. If a render command returns nonzero after
|
||||
emitting a usable file, preserve the file under ``/workspace/outputs/...`` and
|
||||
include the command failure as a warning instead of dropping the result.
|
||||
through ``await ctx.workspace_shell(...)`` or ``await ctx.workspace_python(...)``.
|
||||
The platform sandbox persists ``/workspace`` writes directly and captures changed
|
||||
files elsewhere in the guest rootfs under ``outputs/rootfs-captures/...``. Do
|
||||
not use in-process ``asyncio.create_subprocess_exec`` for durable outputs; the
|
||||
agent container is not workspace-mounted or rootfs-captured, so files created in
|
||||
``/tmp`` or the image filesystem can vanish after the request. Commands must
|
||||
still be bounded with timeouts and broad exception handling, and failures must
|
||||
return structured JSON instead of crashing the worker. Use ``render: bool = False``
|
||||
by default and expose every public skill argument with concrete type hints so
|
||||
the live ``input_schema`` contains the full call surface. If a render command
|
||||
returns nonzero after emitting a usable file, preserve the file and include the
|
||||
command failure as a warning instead of dropping the result.
|
||||
|
||||
For Manim presentation agents specifically, generate a stable PDF fallback
|
||||
that does not require Manim rendering. If HTML/video rendering is requested,
|
||||
|
||||
@@ -130,9 +130,10 @@ If a skill calls `ctx.workspace_backend()` or `ctx.workspace`, declare
|
||||
|
||||
If a skill runs code, renderers, converters, or data tools that create
|
||||
downloadable files, run them through `await ctx.workspace_shell(...)` or
|
||||
`await ctx.workspace_python(...)` and make the command write under
|
||||
`/workspace/outputs/...`. In-process subprocesses write inside the agent pod,
|
||||
not the caller's mounted workspace.
|
||||
`await ctx.workspace_python(...)`. The sandbox persists `/workspace` writes
|
||||
directly and mirrors changed files elsewhere in the guest rootfs under
|
||||
`outputs/rootfs-captures/...`. In-process subprocesses write inside the agent
|
||||
pod, not the caller's mounted or rootfs-captured workspace.
|
||||
|
||||
When invoking an inner DeepAgents graph, pass
|
||||
`config={"recursion_limit": 500}` to `graph.ainvoke(...)` or
|
||||
|
||||
@@ -38,8 +38,9 @@ Check these items:
|
||||
- Deterministic tools do exact work; no fake canned-response tools.
|
||||
- File-producing skills call `ctx.write_artifact` and `ctx.emit_artifact`.
|
||||
- Commands that create downloadable outputs run through `ctx.workspace_shell`
|
||||
or `ctx.workspace_python` and write under `/workspace/outputs/...`. Plain
|
||||
subprocesses in the agent container are not durable workspace writes.
|
||||
or `ctx.workspace_python`; `/workspace` writes persist directly and other
|
||||
changed sandbox rootfs files are mirrored under `outputs/rootfs-captures/...`.
|
||||
Plain subprocesses in the agent container are not durable workspace writes.
|
||||
- External calls, secrets, workspace access, pricing, and resources are
|
||||
declared on the class.
|
||||
|
||||
|
||||
@@ -25,7 +25,8 @@ RUNTIME_SKILLS_ROOT = "/outputs/research-agent/.deepagents/skills/"
|
||||
|
||||
SYSTEM_PROMPT = """\
|
||||
You are a careful research agent. Use project skills for workflow rules and
|
||||
write durable files under /workspace/outputs/.
|
||||
use workspace-backed tools for durable files. Prefer /workspace/outputs/ for
|
||||
stable output paths.
|
||||
"""
|
||||
|
||||
|
||||
|
||||
@@ -29,9 +29,9 @@ backend = ctx.workspace_backend()
|
||||
graph = create_deep_agent(model=model, backend=backend, skills=skill_sources or None)
|
||||
```
|
||||
|
||||
Write durable model-created files under `/workspace/outputs/...` in prompts.
|
||||
When writing through `ctx.workspace`, use workspace-relative paths such as
|
||||
`outputs/report.md`.
|
||||
For stable, human-readable paths, ask model-created files to use
|
||||
`/workspace/outputs/...`. When writing through `ctx.workspace`, use
|
||||
workspace-relative paths such as `outputs/report.md`.
|
||||
|
||||
## Artifact Pattern
|
||||
|
||||
@@ -77,10 +77,12 @@ async def run_checked(script: str, timeout_s: int = 120) -> dict[str, str | int]
|
||||
}
|
||||
```
|
||||
|
||||
Commands should write user-visible files under `/workspace/outputs/...`; that
|
||||
path is backed by the caller's workspace bucket. Do not use
|
||||
`asyncio.create_subprocess_exec(...)` for durable outputs. Plain subprocesses
|
||||
run inside the agent container, which is not mounted to the caller workspace.
|
||||
Commands may write to `/workspace/outputs/...` for stable paths, or to normal
|
||||
tool defaults such as `/tmp`, `/root`, or `/app`. The platform sandbox mirrors
|
||||
changed files outside `/workspace` into `outputs/rootfs-captures/...`. Do not
|
||||
use `asyncio.create_subprocess_exec(...)` for durable outputs. Plain subprocesses
|
||||
run inside the agent container, which is not mounted to the caller workspace and
|
||||
is not rootfs-captured.
|
||||
|
||||
If a nonzero command still produced a usable output, preserve the output and
|
||||
include the command failure as a warning instead of discarding the file.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
a2a-pack>=0.1.8
|
||||
a2a-pack>=0.1.9
|
||||
httpx>=0.27
|
||||
boto3>=1.34
|
||||
deepagents>=0.5.0
|
||||
|
||||
@@ -38,8 +38,8 @@ class BuilderPromptTests(unittest.TestCase):
|
||||
def test_prompt_requires_workspace_mounted_execution_for_outputs(self) -> None:
|
||||
self.assertIn("ctx.workspace_shell", SYSTEM_PROMPT)
|
||||
self.assertIn("ctx.workspace_python", SYSTEM_PROMPT)
|
||||
self.assertIn("/workspace/outputs/...", SYSTEM_PROMPT)
|
||||
self.assertIn("not workspace-mounted", SYSTEM_PROMPT)
|
||||
self.assertIn("outputs/rootfs-captures/...", SYSTEM_PROMPT)
|
||||
self.assertIn("not workspace-mounted or rootfs-captured", SYSTEM_PROMPT)
|
||||
|
||||
def test_prompt_and_backend_load_packaged_builder_skills(self) -> None:
|
||||
expected = {
|
||||
@@ -66,7 +66,7 @@ class BuilderPromptTests(unittest.TestCase):
|
||||
self.assertIn('config={"recursion_limit": 500}', files["deepagents-implementation-patterns/SKILL.md"])
|
||||
self.assertIn("ctx.write_artifact", files["workspace-artifact-safety/SKILL.md"])
|
||||
self.assertIn("ctx.workspace_shell", files["workspace-artifact-safety/SKILL.md"])
|
||||
self.assertIn("/workspace/outputs/...", files["workspace-artifact-safety/SKILL.md"])
|
||||
self.assertIn("outputs/rootfs-captures/...", files["workspace-artifact-safety/SKILL.md"])
|
||||
self.assertIn("live_skills[].input_schema", files["agent-quality-review/SKILL.md"])
|
||||
self.assertIn("ctx.workspace_python", files["agent-quality-review/SKILL.md"])
|
||||
|
||||
|
||||
Reference in New Issue
Block a user