builder: require durable workspace execution
Some checks failed
build / build (push) Failing after 2s
Some checks failed
build / build (push) Failing after 2s
This commit is contained in:
@@ -55,33 +55,33 @@ ref = await ctx.write_artifact("frames.zip", zip_bytes, "application/zip")
|
||||
await ctx.emit_artifact(ref)
|
||||
```
|
||||
|
||||
## Bounded Subprocesses
|
||||
## Workspace-Mounted Execution
|
||||
|
||||
Media, rendering, archive, and data conversion agents must not run unbounded
|
||||
commands. Use explicit timeouts and return structured errors:
|
||||
Media, rendering, archive, and data conversion agents must run commands through
|
||||
the workspace-mounted sandbox helpers when those commands create files:
|
||||
|
||||
```python
|
||||
import asyncio
|
||||
|
||||
|
||||
async def run_checked(cmd: list[str], timeout_s: int = 120) -> dict[str, str | int]:
|
||||
try:
|
||||
proc = await asyncio.create_subprocess_exec(
|
||||
*cmd,
|
||||
stdout=asyncio.subprocess.PIPE,
|
||||
stderr=asyncio.subprocess.PIPE,
|
||||
)
|
||||
stdout, stderr = await asyncio.wait_for(proc.communicate(), timeout=timeout_s)
|
||||
except asyncio.TimeoutError:
|
||||
return {"ok": 0, "error": "command timed out", "timeout_s": timeout_s}
|
||||
async def run_checked(script: str, timeout_s: int = 120) -> dict[str, str | int]:
|
||||
result = await ctx.workspace_shell(
|
||||
script,
|
||||
image="python:3.11-slim",
|
||||
timeout_seconds=timeout_s,
|
||||
memory_mib=1024,
|
||||
cpus=1,
|
||||
)
|
||||
return {
|
||||
"ok": 1 if proc.returncode == 0 else 0,
|
||||
"returncode": proc.returncode,
|
||||
"stdout": stdout.decode("utf-8", errors="replace")[-4000:],
|
||||
"stderr": stderr.decode("utf-8", errors="replace")[-4000:],
|
||||
"ok": 1 if result.ok else 0,
|
||||
"returncode": result.exit_code,
|
||||
"stdout": result.stdout[-4000:],
|
||||
"stderr": result.stderr[-4000:],
|
||||
}
|
||||
```
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user