# cloud-sandbox

来源：https://model.dflop.top/en/docs/guides/cloud-sandbox

`xiaozhanAI` can write code and run commands in a cloud Linux sandbox (an OpenAI-hosted container with Python 3, Node.js, LibreOffice, python-docx / python-pptx / openpyxl and CJK fonts) and hand you the resulting Word, PowerPoint, Excel or PDF files. Usage is exactly the same as OpenAI's Responses API:

1. Call `POST /v1/responses` with the `code_interpreter` or `shell` tool;
2. The `container_file_citation` annotation in the answer tells you which container (`container_id`) and which file (`file_id`) holds the result;
3. Download it with `GET /v1/containers/{container_id}/files/{file_id}/content`.

The model decides from your prompt whether to produce a file: ask it to "make a deck" and it will; ask a question and it just answers in text.

> Only `xiaozhanAI` supports the cloud sandbox, and only on `/v1/responses` (`/v1/chat/completions` does not support these two tools — same as OpenAI).

## Quick start

### 1. Ask the model to make a file

```bash
curl https://api.dflop.top/v1/responses \
  -H "Authorization: Bearer $GPUSHARE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "xiaozhanAI",
    "tools": [{ "type": "code_interpreter", "container": { "type": "auto" } }],
    "input": "Use python-pptx to build a 5-slide \"Q3 review\" deck, save it to /mnt/data/q3-review.pptx and give me the file link."
  }'
```

The message in `output` carries the file reference (excerpt):

```json
{
  "type": "output_text",
  "text": "Done: [Download q3-review.pptx](sandbox:/mnt/data/q3-review.pptx)",
  "annotations": [
    {
      "type": "container_file_citation",
      "container_id": "cntr_6acf7f72fff48198b31b607db0a7a003020f215d49c216d5",
      "file_id": "cfile_6acf7f757e848191962c004f076016de",
      "filename": "q3-review.pptx",
      "start_index": 6,
      "end_index": 58
    }
  ]
}
```

The `sandbox:/mnt/data/…` link in the text is a path inside the container and can't be opened directly — download it with the endpoint below.

### 2. Download the file

```bash
curl https://api.dflop.top/v1/containers/$CONTAINER_ID/files/$FILE_ID/content \
  -H "Authorization: Bearer $GPUSHARE_API_KEY" \
  -o q3-review.pptx
```

### Python (OpenAI SDK)

```python
from openai import OpenAI

client = OpenAI(base_url="https://api.dflop.top/v1", api_key="sk-gpushare-...")

resp = client.responses.create(
    model="xiaozhanAI",
    tools=[{"type": "code_interpreter", "container": {"type": "auto"}}],
    input="Use python-docx to write a one-page event plan, save it to /mnt/data/event-plan.docx and give me the file link.",
)

for item in resp.output:
    if item.type != "message":
        continue
    for part in item.content:
        for ann in getattr(part, "annotations", None) or []:
            if ann.type == "container_file_citation":
                data = client.containers.files.content.retrieve(ann.file_id, container_id=ann.container_id)
                data.write_to_file(ann.filename)
                print("saved", ann.filename)
```

Making a file usually takes tens of seconds to a few minutes. Use `stream=True` (`"stream": true`) so data keeps flowing and no client or proxy times out.

## Using the `shell` tool

`code_interpreter` runs Python only; `shell` gives the model a full Linux shell (LibreOffice for PDF conversion, Node.js PptxGenJS for decks, rendering previews, …). Same shape as OpenAI:

```json
{
  "model": "xiaozhanAI",
  "stream": true,
  "tools": [{ "type": "shell", "environment": { "type": "container_auto" } }],
  "input": "Make an 8-slide product-launch deck with a clean palette, save it to /mnt/data/launch.pptx and give me the link."
}
```

File references and downloads work the same way.

## Giving the model your own files

Create a container, upload files into it, then let the model work in that container:

```bash
# ① create a container
curl https://api.dflop.top/v1/containers \
  -H "Authorization: Bearer $GPUSHARE_API_KEY" -H "Content-Type: application/json" \
  -d '{"name": "q3-report"}'
# → {"id": "cntr_…", "object": "container", "status": "running", "memory_limit": "4g", …}

# ② upload (multipart, field name `file`)
curl https://api.dflop.top/v1/containers/$CONTAINER_ID/files \
  -H "Authorization: Bearer $GPUSHARE_API_KEY" \
  -F "file=@sales.xlsx"
# → {"id": "cfile_…", "path": "/mnt/data/…sales.xlsx", "source": "user", …}

# ③ let the model use that container
curl https://api.dflop.top/v1/responses \
  -H "Authorization: Bearer $GPUSHARE_API_KEY" -H "Content-Type: application/json" \
  -d '{
    "model": "xiaozhanAI",
    "tools": [{ "type": "shell", "environment": { "type": "container_reference", "container_id": "'$CONTAINER_ID'" } }],
    "input": "Read sales.xlsx in /mnt/data and write a Word sales report with charts to /mnt/data/sales-report.docx."
  }'
```

With `code_interpreter`, reference an existing container as `"container": "cntr_…"`. The real path of an uploaded file is the `path` returned by the upload (it carries a random prefix); you can tell the model to `ls /mnt/data` first.

In Python: `client.containers.create(name=…)` and `client.containers.files.create(container_id, file=open("sales.xlsx", "rb"))`.

## Endpoints

| Method | Path | Notes |
|---|---|---|
| POST | `/v1/containers` | Create a container (bills one container window right away, see Billing) |
| GET | `/v1/containers` | List your containers (`limit` ≤ 50, `order`, `after`) |
| GET | `/v1/containers/{container_id}` | Container status |
| DELETE | `/v1/containers/{container_id}` | Delete a container |
| GET | `/v1/containers/{container_id}/files` | List files in a container (`limit` / `order` / `after`) |
| POST | `/v1/containers/{container_id}/files` | Upload a file (multipart, field `file`, ≤ 50 MB) |
| GET | `/v1/containers/{container_id}/files/{file_id}` | File metadata |
| GET | `/v1/containers/{container_id}/files/{file_id}/content` | Download a file (always served as an attachment) |
| DELETE | `/v1/containers/{container_id}/files/{file_id}` | Delete a file |

Request and response fields match OpenAI's Containers API. These endpoints keep working for viewing and downloading when your balance runs out (creating a container does not).

## Billing

- **Tokens, web search, image generation**: billed at the normal `xiaozhanAI` prices (see [Models & pricing](../reference/models.md#xiaozhanai-1)).
- **Container fee**: **194.112 points per container per 20 minutes**. The first 20-minute window starts when a container is first used (or created with `POST /v1/containers`); using it again within those 20 minutes costs nothing extra; still using it after 20 minutes starts the next window.
- The container fee is a separate row in your usage log: `unit_type` is `container`, `unit_count` is how many 20-minute windows were billed.

To save on container fees, keep related work in one container (reuse it with `container_reference` / `"container": "cntr_…"`) instead of letting each request create a new one.

## Limits

- Containers always have **4 GB** of memory (any other `memory_limit` is treated as 4 GB).
- Containers have **no internet access**: `network_policy` only accepts `{"type": "disabled"}`.
- OpenAI Files `file_ids` are not supported (not on container creation, auto containers or uploads) — upload your inputs with the upload endpoint.
- `background: true` is not supported; use `stream: true` for long tasks.
- A container is destroyed after **20 minutes** of inactivity, together with its files — download promptly.
- Containers and their files are only accessible with **the API key that created them**; any other key (including other keys of the same account) gets a 404.

## Common errors

| Status | When |
|---|---|
| 404 `Container with id '…' not found.` | The container doesn't exist, was deleted, or wasn't created by this key |
| 400 `Container is expired.` | The container was idle for more than 20 minutes; start a new one (`container_auto` / `type: auto`) |
| 400 `… file_ids is not supported …` / `… network_policy …` | A parameter listed under Limits was used |
| 400 `tool_not_supported` (`shell` on `/v1/chat/completions`) | The cloud sandbox is only on `/v1/responses` |
| 402 | Insufficient balance (creating a container, calling the model) |

More error codes: [Errors](../reference/errors.md).
