|
| 1 | +# Tutorial 050: Sync OpenAI Agents SDK with a Local Sandbox |
| 2 | + |
| 3 | +This tutorial demonstrates how to build a **synchronous** agent on AgentEx using the |
| 4 | +[OpenAI Agents SDK](https://developers.openai.com/api/docs/guides/agents) and its |
| 5 | +**sandbox** runtime, running with the **local** (`unix_local`) backend. |
| 6 | + |
| 7 | +The agent is a "local sandbox assistant": it answers questions by actually running |
| 8 | +real shell commands (e.g. `python3 --version`, `ls /tmp`, `python3 -c "..."`) |
| 9 | +instead of guessing. |
| 10 | + |
| 11 | +## Key Concepts |
| 12 | + |
| 13 | +### Sync ACP |
| 14 | +The sync ACP model uses HTTP request/response for communication. The |
| 15 | +`@acp.on_message_send` handler receives a message, runs the agent, and returns the |
| 16 | +agent's final answer as a `TextContent`. |
| 17 | + |
| 18 | +### OpenAI Agents SDK Sandbox |
| 19 | +The OpenAI Agents SDK ships `agents.sandbox`, which lets you give an agent |
| 20 | +**capabilities** (instead of hand-written tools) that the runtime turns into real |
| 21 | +tools backed by a sandbox: |
| 22 | + |
| 23 | +- **`SandboxAgent`**: an `Agent` that is granted sandbox capabilities. |
| 24 | +- **Capabilities** (`from agents.sandbox.capabilities import Shell, Filesystem, Memory`): |
| 25 | + each capability expands into a set of real tools. This tutorial uses `Shell`, which |
| 26 | + lets the model run real shell commands. |
| 27 | +- **`SandboxRunConfig`** + a sandbox **client**: tells the runtime *where* the tools |
| 28 | + actually execute. |
| 29 | + |
| 30 | +### The LOCAL sandbox (`UnixLocalSandboxClient`) |
| 31 | +This tutorial uses the local backend |
| 32 | +(`from agents.sandbox.sandboxes.unix_local import UnixLocalSandboxClient, UnixLocalSandboxClientOptions`), |
| 33 | +`backend_id="unix_local"`. The local sandbox runs shell commands **ON THE HOST** — |
| 34 | +the agent's own container/process. There is **no Docker, no Temporal, and no remote |
| 35 | +sandbox infrastructure** involved. This makes it the simplest way to give an agent a |
| 36 | +real shell. |
| 37 | + |
| 38 | +The sandbox is wired up through the SDK's `RunConfig`: |
| 39 | + |
| 40 | +```python |
| 41 | +from agents import Runner, set_tracing_disabled |
| 42 | +from agents.run_config import RunConfig |
| 43 | +from agents.sandbox import SandboxAgent, SandboxRunConfig |
| 44 | +from agents.sandbox.capabilities import Shell |
| 45 | +from agents.sandbox.sandboxes.unix_local import ( |
| 46 | + UnixLocalSandboxClient, |
| 47 | + UnixLocalSandboxClientOptions, |
| 48 | +) |
| 49 | + |
| 50 | +set_tracing_disabled(True) # avoid api.openai.com tracing 401 behind a gateway |
| 51 | + |
| 52 | +agent = SandboxAgent( |
| 53 | + name="Local Sandbox Assistant", |
| 54 | + instructions="...use the shell tools to actually run commands...", |
| 55 | + capabilities=[Shell()], |
| 56 | +) |
| 57 | +run_config = RunConfig( |
| 58 | + sandbox=SandboxRunConfig( |
| 59 | + client=UnixLocalSandboxClient(), |
| 60 | + options=UnixLocalSandboxClientOptions(), |
| 61 | + ) |
| 62 | +) |
| 63 | +result = await Runner.run(agent, input="what's the python version?", run_config=run_config) |
| 64 | +print(result.final_output) |
| 65 | +``` |
| 66 | + |
| 67 | +`Runner.run` drives the full tool-call loop internally: the model issues shell |
| 68 | +commands, the local sandbox runs them on the host, the output is fed back, and the |
| 69 | +loop continues until the model produces a final answer. |
| 70 | + |
| 71 | +## Files |
| 72 | + |
| 73 | +| File | Description | |
| 74 | +|------|-------------| |
| 75 | +| `project/acp.py` | ACP server and message handler (runs the sandbox agent) | |
| 76 | +| `project/agent.py` | `SandboxAgent` + `RunConfig(sandbox=...)` wiring + `run_agent` | |
| 77 | +| `project/tools.py` | Sandbox capability factory (`Shell`) | |
| 78 | +| `tests/test_agent.py` | Integration tests | |
| 79 | +| `manifest.yaml` | Agent configuration | |
| 80 | + |
| 81 | +## Running Locally |
| 82 | + |
| 83 | +```bash |
| 84 | +# From this directory |
| 85 | +agentex agents run |
| 86 | +``` |
| 87 | + |
| 88 | +Set `OPENAI_API_KEY` (or `LITELLM_API_KEY` if you're behind the Scale LiteLLM |
| 89 | +gateway) in your environment or in a `.env` file in `project/` so the agent can call |
| 90 | +the model. |
| 91 | + |
| 92 | +## Running Tests |
| 93 | + |
| 94 | +```bash |
| 95 | +pytest tests/test_agent.py -v |
| 96 | +``` |
| 97 | + |
| 98 | +## Notes |
| 99 | + |
| 100 | +- **No infra required.** Because this uses the `unix_local` backend, the shell tools |
| 101 | + run directly in the agent's process — no Docker daemon, no Temporal, no remote |
| 102 | + sandbox. Swap the client for a remote/containerized backend to isolate execution. |
| 103 | +- **Tracing.** `set_tracing_disabled(True)` turns off the OpenAI Agents SDK's native |
| 104 | + tracer (which would otherwise try to ship traces to `api.openai.com`). The manifest |
| 105 | + also sets `OPENAI_AGENTS_DISABLE_TRACING=1`. AgentEx/SGP tracing still runs via the |
| 106 | + tracing manager configured in `acp.py` when SGP credentials are present. |
| 107 | +- **Capabilities are the tools.** To let the agent do more, add capabilities in |
| 108 | + `project/tools.py` (e.g. `Filesystem()`, `Memory()`). |
| 109 | + |
| 110 | +## Further Reading |
| 111 | + |
| 112 | +- OpenAI Agents SDK guide: https://developers.openai.com/api/docs/guides/agents |
| 113 | +- The next evolution of the Agents SDK: https://openai.com/index/the-next-evolution-of-the-agents-sdk/ |
0 commit comments