chore: import upstream snapshot with attribution

This commit is contained in:
wehub-resource-sync
2026-07-13 12:39:17 +08:00
commit 4ed4e9ff99
1368 changed files with 334957 additions and 0 deletions
@@ -0,0 +1,32 @@
# Sandbox resume
This example shows a small sandbox resume flow with `AGENTS.md` mounted in the sandbox and loaded into the agent instructions. It runs in two
steps: first it builds the app and smoke tests it, then it serializes the
sandbox session state, resumes the sandbox, and adds pytest coverage.
By default the agent builds a tiny warehouse-robot status API, smoke-tests it, then resumes the same sandbox to add tests. The sandbox workspace starts with
one instruction file:
- `AGENTS.md` with instructions to build FastAPI apps, use type hints and Pydantic, install dependencies with `uv`, run Python commands through `uv run python`, and test locally before finishing.
Run the example from the repository root:
```bash
uv run python examples/sandbox/tutorials/sandbox_resume/main.py
```
This demo exits after the scripted resume flow so the serialized session state and resume step stay easy to follow.
You can override the model or prompt:
```bash
uv run python examples/sandbox/tutorials/sandbox_resume/main.py --model gpt-5.6-sol --question "Build a FastAPI service that exposes a warehouse robot's maintenance status."
```
To run the same flow in Docker, build the shared tutorial image once and pass
`--docker`:
```bash
docker build --tag sandbox-tutorials:latest examples/sandbox/tutorials
uv run python examples/sandbox/tutorials/sandbox_resume/main.py --docker
```
@@ -0,0 +1 @@
@@ -0,0 +1,145 @@
"""
Show the smallest Unix-local sandbox flow with workspace instructions.
The manifest includes an AGENTS.md file that tells the agent how to build the
app, and the prompt asks for a tiny FastAPI operations status API with a health
check.
"""
import argparse
import asyncio
import sys
from pathlib import Path
from textwrap import dedent
from agents import Runner, RunResultStreaming, TResponseInputItem
from agents.run import RunConfig
from agents.sandbox import Manifest, SandboxAgent, SandboxRunConfig
from agents.sandbox.capabilities import Filesystem, Shell
from agents.sandbox.entries import File
if __package__ is None or __package__ == "":
sys.path.insert(0, str(Path(__file__).resolve().parents[4]))
from examples.sandbox.tutorials.misc import (
DEFAULT_SANDBOX_IMAGE,
create_sandbox_client_and_session,
load_env_defaults,
print_event,
)
DEFAULT_QUESTION = (
"Build a small warehouse-robot operations status API with FastAPI. Include a health "
"check, a typed `/robots/{robot_id}/status` endpoint backed by a tiny in-memory "
"fixture, and clear 404 behavior. Install dependencies with uv, smoke test it locally "
"with `uv run python` and `urllib.request`, and summarize what you built."
)
DEMO_DIR = Path(__file__).resolve().parent
RESUME_QUESTION = (
"Now add pytest coverage for the health check, robot status success case, and unknown "
"robot 404 case. Install any missing dependencies with uv, run the tests locally, and "
"summarize the files you changed."
)
AGENTS_MD = dedent(
"""\
# AGENTS.md
- When asked to build an app, make it a FastAPI app.
- Use type hints and Pydantic models.
- Use `uv` when installing dependencies.
- Run Python commands as `uv run python ...`, not bare `python`.
- Smoke test local HTTP endpoints with `uv run python` and `urllib.request`, not `curl`.
- Test the app locally before finishing.
"""
)
async def run_step(result: RunResultStreaming) -> list[TResponseInputItem]:
async for event in result.stream_events():
print_event(event)
print_event(str(result.final_output).strip())
return result.to_input_list()
async def main(model: str, question: str, use_docker: bool, image: str) -> None:
manifest = Manifest(entries={"AGENTS.md": File(content=AGENTS_MD.encode("utf-8"))})
agent = SandboxAgent(
name="Vibe Coder",
model=model,
instructions=AGENTS_MD,
capabilities=[Shell(), Filesystem()],
)
client, sandbox = await create_sandbox_client_and_session(
manifest=manifest,
use_docker=use_docker,
image=image,
)
conversation: list[TResponseInputItem] = [{"role": "user", "content": question}]
try:
async with sandbox:
result = Runner.run_streamed(
agent,
conversation,
max_turns=20,
run_config=RunConfig(
sandbox=SandboxRunConfig(session=sandbox),
tracing_disabled=True,
workflow_name="Sandbox resume example",
),
)
conversation = await run_step(result)
frozen_session_state = client.deserialize_session_state(
client.serialize_session_state(sandbox.state)
)
conversation.append({"role": "user", "content": RESUME_QUESTION})
resumed_sandbox = await client.resume(frozen_session_state)
try:
async with resumed_sandbox:
resumed_result = Runner.run_streamed(
agent,
conversation,
max_turns=20,
run_config=RunConfig(
sandbox=SandboxRunConfig(session=resumed_sandbox),
tracing_disabled=True,
workflow_name="Sandbox resume example",
),
)
conversation = await run_step(resumed_result)
finally:
await client.delete(resumed_sandbox)
finally:
await client.delete(sandbox)
if __name__ == "__main__":
load_env_defaults(DEMO_DIR / ".env")
parser = argparse.ArgumentParser()
parser.add_argument(
"--model",
default="gpt-5.4-mini",
help="Model name to use.",
)
parser.add_argument(
"--question",
default=DEFAULT_QUESTION,
help="Prompt to send to the agent.",
)
parser.add_argument(
"--docker",
action="store_true",
help="Run this example in Docker instead of Unix-local.",
)
parser.add_argument(
"--image",
default=DEFAULT_SANDBOX_IMAGE,
help="Docker image to use when --docker is set.",
)
args = parser.parse_args()
asyncio.run(main(args.model, args.question, args.docker, args.image))