Appearance
在沙箱中运行程序
本文档介绍如何通过平台 API 在 Mythra Agent Studio 的沙箱中执行文件或命令,并获取其输出与退出状态。
概述
在 Mythra Agent Studio 中,你可以通过 API 在指定沙箱的隔离容器内运行一个可执行文件或命令,例如:
- 执行脚本文件:
python3 /data/main.py、node /data/index.js、/data/run.sh - 执行命令:
ls、echo hello、pytest - 运行构建、测试等工具链
平台提供了两个能力互补的端点:
/execute:一次性执行,等待命令结束后一次性返回完整输出。/execute/sse:通过 Server-Sent Events(SSE)逐行流式返回标准输出与标准错误,适合运行时间较长或需要实时查看输出的场景。
先决条件
在调用 API 之前,你需要准备好以下信息:
ProjectID:项目 IDSandboxID:沙箱 IDWDS_API_KEY:有效的 WDS API Key,用于身份验证
身份认证
两个端点都要求进行 WDS Token 认证,以下两种方式任选其一:
- 通过请求头:
Authorization: Bearer <WDS_API_KEY> - 通过 Cookie:
wds_api_key=<WDS_API_KEY>
如果认证失败,平台会返回 401 Unauthorized。
端点概览
| 方法 | 端点 | 说明 |
|---|---|---|
POST | /WebIDE/api/v1/projects/{ProjectID}/sandboxes/{SandboxID}/execute | 一次性执行,返回完整结果 |
POST | /WebIDE/api/v1/projects/{ProjectID}/sandboxes/{SandboxID}/execute/sse | 流式执行,逐行返回输出 |
两个端点的请求体格式完全相同。
请求体
请求体为 JSON 对象:
json
{
"executable": "node",
"args": ["/data/hello.js", "--name", "Mythra"],
"workDir": "/data",
"env": {
"NODE_ENV": "production"
},
"stdin": "",
"timeout": 30
}字段说明
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
executable | string | 是 | 要运行的可执行文件或命令,例如 node、python3、bash、./main |
args | string[] | 否 | 传给可执行文件的参数列表 |
workDir | string | 否 | 容器内的工作目录,默认为 /data |
env | object | 否 | 以 key-value 形式注入到进程的环境变量 |
stdin | string | 否 | 写入进程标准输入的文本 |
timeout | int | 否 | 超时时间(秒),默认值与最大值均为 60 |
执行环境
- 沙箱目录会被挂载到容器的
/data,默认工作目录也是/data。 - 因此,沙箱根目录下的文件在容器内对应
/data/文件名,也可以直接用相对路径引用(例如python3 main.py)。 - 平台实际执行的是
[executable, ...args]组合而成的容器启动命令。 - 每次执行都会创建一个临时容器(名称形如
mythra-exec-{userId}-{projectId}-{sandboxId}-{nonce})。 - 如果超过
timeout指定的时间,平台会停止容器并返回timedOut: true。
一次性执行:/execute
使用 curl
bash
#!/bin/bash
WDS_BASE_URL="https://agent.wiseverds.com"
WDS_API_KEY="WDS_**************"
ProjectID=2231
SandboxID=j4urFhRG
curl -i \
-X POST \
-H "Authorization: Bearer $WDS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"executable": "node",
"args": ["-e", "console.log(\"hello from sandbox\")"],
"workDir": "/data",
"timeout": 30
}' \
"$WDS_BASE_URL/WebIDE/api/v1/projects/$ProjectID/sandboxes/$SandboxID/execute"响应示例
json
{
"result": {
"exitCode": 0,
"stdout": "hello from sandbox\n",
"stderr": "",
"timedOut": false,
"container": "mythra-exec-12345678-projabcd-sandbox1-XyZ12345"
}
}响应字段说明
| 字段 | 类型 | 说明 |
|---|---|---|
exitCode | int | 进程退出码,0 通常表示成功 |
stdout | string | 标准输出(超过 1MB 会被截断并追加 [Output truncated]) |
stderr | string | 标准错误(超过 1MB 会被截断并追加 [Output truncated]) |
timedOut | bool | 是否超时 |
container | string | 执行本次命令的容器名称 |
流式执行:/execute/sse
当需要实时查看输出、或命令运行时间较长时,推荐使用 /execute/sse。响应以 text/event-stream 流式返回。
使用 curl
bash
#!/bin/bash
WDS_BASE_URL="https://agent.wiseverds.com"
WDS_API_KEY="WDS_**************"
ProjectID=2231
SandboxID=j4urFhRG
curl -N -i \
-X POST \
-H "Authorization: Bearer $WDS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"executable": "python3",
"args": ["/data/main.py"],
"workDir": "/data",
"timeout": 60
}' \
"$WDS_BASE_URL/WebIDE/api/v1/projects/$ProjectID/sandboxes/$SandboxID/execute/sse"SSE 输出格式
每个事件都使用 message 作为事件名,data 为 JSON 对象:
json
{ "event": "<事件类型>", "data": "<数据>" }一条常见的流示例如下:
event: message
data: {"event":"stdout","data":"Hello from Python!"}
event: message
data: {"event":"stderr","data":""}
event: message
data: {"event":"exit","data":"{\"exitCode\":0,\"timedOut\":false,\"container\":\"mythra-exec-...\"}"}事件类型
| 事件类型 | 说明 |
|---|---|
stdout | 一条标准输出,data 为文本行 |
stderr | 一条标准错误,data 为文本行 |
ping | 心跳保活,data 为时间戳 |
exit | 进程结束,data 为 JSON 字符串,包含 exitCode、timedOut、container |
error | 执行失败,data 为错误信息 |
使用 JavaScript (fetch) 读取 SSE
javascript
const baseUrl = 'https://agent.wiseverds.com';
const apiKey = 'WDS_**************';
const projectId = 2231;
const sandboxId = 'j4urFhRG';
const url = `${baseUrl}/WebIDE/api/v1/projects/${projectId}/sandboxes/${sandboxId}/execute/sse`;
const response = await fetch(url, {
method: 'POST',
headers: {
'Authorization': `Bearer ${apiKey}`,
'Content-Type': 'application/json',
'Accept': 'text/event-stream',
},
body: JSON.stringify({
executable: 'python3',
args: ['/data/main.py'],
workDir: '/data',
timeout: 60,
}),
});
const reader = response.body.getReader();
const decoder = new TextDecoder();
while (true) {
const { value, done } = await reader.read();
if (done) break;
process.stdout.write(decoder.decode(value, { stream: true }));
}完整示例
假设你的沙箱根目录下有一个 main.py 文件:
python
import sys
print("hello from sandbox")
print("args:", sys.argv[1:], file=sys.stderr)你可以通过以下请求执行它:
bash
curl -i \
-X POST \
-H "Authorization: Bearer $WDS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"executable": "python3",
"args": ["main.py", "--foo", "bar"],
"workDir": "/data"
}' \
"$WDS_BASE_URL/WebIDE/api/v1/projects/$ProjectID/sandboxes/$SandboxID/execute"如果文件位于沙箱子目录中,使用对应的相对路径即可,例如 "args": ["scripts/run.py"](相对于 /data),或使用绝对路径 "/data/scripts/run.py"。
执行 Shell 命令
平台是直接以 [executable, ...args] 的形式启动容器进程的,不会经过 Shell 解析。因此 不能 把 executable 直接写成 Shell 内置命令或复合命令,例如:
text
{ "executable": "cd" } ❌
{ "executable": "ls -la | grep foo > out.txt" } ❌如果需要执行 Shell 命令,请显式调用 Shell,并把完整命令放到 -c 后面的参数中:
json
{
"executable": "/bin/sh",
"args": ["-c", "ls -la | grep foo > out.txt"]
}也可以使用 /bin/bash,用于需要 Bash 特有特性的场景(例如 [[ ]]、数组、$RANDOM 等):
json
{
"executable": "/bin/bash",
"args": ["-c", "for f in *.txt; do echo \"$f\"; done"]
}Shell命令是否需要转义
分两层来看:
- JSON 层:整个请求体必须是合法 JSON,命令字符串里出现的双引号、反斜杠、换行等需要按 JSON 规则转义(例如
\"、\\、\n)。这是唯一一层“额外”转义。 - Shell 层:命令字符串本身交给
/bin/sh -c解释,其中$、|、>、<、&&、引号等符号会按照 Shell 的正常语义生效。也就是说,命令字符串本身就是“最终要交给 Shell 的脚本内容”,不需要再做第二层转义。
例如,以下两种写法是等价的:
写法一(JSON 中把命令里的双引号写成 \"):
json
{ "executable": "/bin/sh", "args": ["-c", "echo \"hello\""] }写法二(命令里改用单引号,避免转义双引号):
json
{ "executable": "/bin/sh", "args": ["-c", "echo 'hello'"] }两者最终交给 Shell 的都是 echo "hello"(写法二等价为 echo 'hello'),都能输出 hello。
注意事项
- 优先使用
/bin/sh:/bin/sh(POSIX)在绝大多数镜像中都可用;只有确实用到 Bash 独有语法时才使用/bin/bash,因为部分精简镜像可能没有安装 Bash。 - 不要省略
-c:Shell 的-c选项表示“把下一个参数当作命令字符串执行”。如果写成"args": ["ls -la"],Shell 会把它当作脚本文件名去执行,而不是命令。 - 多条命令请使用
;、&&或||:例如"cd /data && ls -la && python3 main.py",控制执行顺序和错误处理。 - 建议在脚本开头使用
set -e:如果希望任意一条命令失败即停止并返回非零退出码,可以写成"set -e; command1; command2"。默认情况下/bin/sh -c会继续执行后续命令并返回最后一条命令的退出码。 - 环境变量可通过
env字段传入:也可以直接在 Shell 命令中使用VAR=value command的临时赋值写法。 - 重定向与管道是允许的,但写入位置要确认:容器工作目录默认为
/data,重定向生成的out.txt会自动落在/data下,即对应你的沙箱根目录,之后可在沙箱中查看或同步。 - 通配符由 Shell 展开:
*.txt、$HOME、$(...)等只有在走/bin/sh -c时才会被展开;直接传executable+args不会展开。 - 非交互式 Shell 不会加载启动文件:
/bin/sh -c通常不会读取~/.bashrc、~/.profile等启动文件,若有依赖,请在命令中显式设置。
常见问题
返回 401 Unauthorized
请检查 Authorization 头中的 API Key 是否有效,或 Cookie 中是否正确携带了 wds_api_key。
返回 400 Bad Request
请检查请求体是否为合法 JSON,以及 executable 字段是否已填写。executable 是必填字段。
返回 404 Not Found
指定的沙箱不存在。请确认 ProjectID 和 SandboxID 是否正确。
返回 500 Internal Server Error
可能原因包括:Docker 配置加载失败、命令执行失败等。响应中的 error 字段会包含更多信息。
输出被截断
/execute 端点对 stdout 和 stderr 分别设置了 1MB 的返回上限,超过部分会被截断并追加 [Output truncated]。如果需要完整输出,建议改用 /execute/sse 流式读取。
命令运行时间超过 600 秒
两个API端点的超时时间最大为 600 秒。超时后平台会停止容器并返回 timedOut: true。
相关文档
- 沙箱 - 了解沙箱的基本概念与工作流程
- 通过 TCP 端口访问容器内服务 - 在容器内运行 HTTP 服务并通过 TCP 访问
- 通过 UNIX Domain Socket 在沙箱中运行 HTTP 服务 - 通过 Unix Socket 运行服务