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