> ## Documentation Index
> Fetch the complete documentation index at: https://boxrouter.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Use the OpenAI Agents SDK

> Give an OpenAI Agents SDK agent a BoxRouter sandbox to run shell commands in.

The OpenAI Agents SDK calls a sandbox client whenever an agent needs a shell. `BoxRouterSandboxClient` is that client: each agent run gets its own BoxRouter sandbox, and BoxRouter picks the route. For OpenAI's hosted Agents API, see [Agents API](https://boxrouter.ai/docs/integrations/openai-agents-api.md).

**Before You Begin:** A BoxRouter API key, a connected provider key or Credits, and Python 3.11 or later.

## Install

The package installs the BoxRouter Python SDK as a dependency.

```bash theme={"theme":"css-variables"}
python -m pip install boxrouter-openai-agents
```

## Open a Session

Set your BoxRouter API key as in the [quickstart](https://boxrouter.ai/docs/quickstart.md#set-your-api-key). This script prints a unique run label before creating a sandbox, so you can find it if creation is uncertain. It needs no model key. Save it as `session.py`:

```python theme={"theme":"css-variables"}
import asyncio
import io
from pathlib import Path
from uuid import uuid4

from agents.sandbox.manifest import Manifest
from boxrouter_openai_agents import BoxRouterSandboxClient, BoxRouterSandboxClientOptions


async def main() -> None:
    run_label = f"openai-agents-{uuid4().hex}"
    print(f"Run label: {run_label}", flush=True)
    session = await BoxRouterSandboxClient().create(
        manifest=Manifest(root="/tmp/boxrouter-workspace"),
        options=BoxRouterSandboxClientOptions(lifetime_seconds=300, labels={"run": run_label}),
    )
    async with session:
        await session.write(Path("hello.py"), io.BytesIO(b"print('hello from OpenAI Agents')\n"))
        result = await session.exec("python3 hello.py")
        if result.exit_code != 0:
            raise RuntimeError(result.stderr.decode())
        print(result.stdout.decode(), end="")


asyncio.run(main())
```

```bash theme={"theme":"css-variables"}
python session.py
```

Output

```text theme={"theme":"css-variables"}
Run label: <RUN_LABEL>
hello from OpenAI Agents
```

Leaving the `async with` block requests sandbox destruction. If the script dies first, the sandbox can run past the end of its `lifetime_seconds` lifetime (300 in this example; 900 when unset).

If you don't know whether the sandbox was created, [list sandboxes by the `run` label](https://boxrouter.ai/docs/reference/list-sandboxes) before retrying. The label helps you find and destroy a sandbox that may have started.

`root` is the directory the SDK treats as the workspace. Choose a directory the sandbox user can write to, such as `/tmp/boxrouter-workspace`. Files there last for the sandbox session.

## Run an Agent in It

For a model-driven run, pass the same client and options in `RunConfig`. Set `OPENAI_MODEL` and the model provider's key, such as `OPENAI_API_KEY`. Save this as `agent.py`:

```python theme={"theme":"css-variables"}
import asyncio
import os
from uuid import uuid4

from agents import RunConfig, Runner
from agents.sandbox import SandboxAgent
from agents.sandbox.capabilities import Shell
from agents.sandbox.manifest import Manifest
from boxrouter_openai_agents import BoxRouterSandboxClient, BoxRouterSandboxClientOptions


async def main() -> None:
    run_label = f"openai-agents-{uuid4().hex}"
    print(f"Run label: {run_label}", flush=True)
    agent = SandboxAgent(
        name="worker",
        instructions="Use the sandbox shell for the requested task.",
        model=os.environ["OPENAI_MODEL"],
        capabilities=[Shell()],
        default_manifest=Manifest(root="/tmp/boxrouter-workspace"),
    )
    sandbox = {
        "client": BoxRouterSandboxClient(),
        "options": BoxRouterSandboxClientOptions(lifetime_seconds=300, labels={"run": run_label}),
    }
    result = await Runner.run(
        agent, "Run python3 --version and report it.", run_config=RunConfig(sandbox=sandbox)
    )
    print(result.final_output)


asyncio.run(main())
```

```bash theme={"theme":"css-variables"}
python agent.py
```

The agent prints its report of the sandbox's Python version. When the run ends, the runner closes the session and requests sandbox destruction. If the process dies first, the sandbox can run past the end of its `lifetime_seconds` lifetime (300 in this example). Use the printed run label to [find it](https://boxrouter.ai/docs/reference/list-sandboxes.md), then [destroy it](https://boxrouter.ai/docs/sandboxes.md#destroy-it).

The [Agents SDK sandbox guide](https://openai.github.io/openai-agents-python/sandbox_agents/) covers building the `SandboxAgent`.

## Limits

* Manifest mounts are refused before a sandbox is created, and PTY sessions are not supported.
* If the recorded sandbox is gone when the SDK resumes a session, the client creates a new one. It restores the workspace from the SDK's snapshot; processes and files outside the workspace do not carry over.
* Errors carry the BoxRouter `code`, `request_id` and `outcome`. Only `rate_limited` and `overloaded` with outcome `not_started` are marked retryable; for anything else, check the sandbox before you replay the call.
* If creation fails with `no_eligible_route`, no route met your request; [Sandboxes](https://boxrouter.ai/docs/sandboxes.md#what-you-ask-for-and-what-boxrouter-decides) shows how to read the refusal.

## Next Steps

> [card] [Use the OpenAI Agents API](https://boxrouter.ai/docs/integrations/openai-agents-api.md)
>
> OpenAI's hosted Agents API instead.

> [card] [Create a Sandbox](https://boxrouter.ai/docs/sandboxes.md)
>
> What a sandbox request can ask for.

> [card] [Run Commands](https://boxrouter.ai/docs/commands.md)
>
> Exit codes, timeouts, and output limits.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.