源码位置:
pkgs/bay/app/api/v1/
- 概览
- 认证
- 通用约定
- 1. Sandboxes API
- 2. Capabilities API(执行能力)
- 3. Cargos API(持久化存储)
- 4. History API(执行历史)
- 5. Skills API(技能生命周期)
- 6. Profiles API(配置档案)
- 7. Admin API(管理接口)
- 错误码参考(→ 独立文档)
Bay API v1 是 Shipyard Neo 的控制面 REST API,基于 FastAPI 构建。它提供沙箱(Sandbox)的完整生命周期管理,包括创建、执行代码、文件操作、浏览器自动化以及技能(Skill)的演进管理。
所有 v1 端点挂载在 /v1 路径下,子模块的路由注册如下(见 __init__.py):
| 前缀 | 模块 | Tag | 说明 |
|---|---|---|---|
/v1/sandboxes |
sandboxes |
sandboxes | 沙箱 CRUD 和生命周期 |
/v1/sandboxes |
capabilities |
capabilities | 代码执行、文件操作、浏览器 |
/v1/sandboxes |
history |
history | 执行历史查询与标注 |
/v1/cargos |
cargos |
cargos | 持久化存储卷管理 |
/v1/skills |
skills |
skills | 技能候选、评估、发布 |
/v1/profiles |
profiles |
profiles | Profile 配置查询 |
/v1/admin |
admin |
admin | GC 管理等运维接口 |
认证逻辑定义在 dependencies.authenticate()。
请求进入
├─ 携带 Authorization: Bearer <token>
│ ├─ DB 中有 key hash → hash 匹配 ? 通过(返回 owner) : 401
│ └─ DB 中无 key hash + allow_anonymous → 通过
│
└─ 未携带 token
├─ allow_anonymous = true → 通过(可选 X-Owner header)
└─ allow_anonymous = false → 401
- API Key 来源(当前优先级):
BAY_API_KEY环境变量(最高优先级)- 配置文件
security.api_key - 若以上都未配置:
- DB 中已有活跃 key hash → 使用 DB 现有 key
- DB 为空(首次启动)→ 自动生成
sk-bay-...,hash 存入 DB,明文写入credentials.json
- 开发模式:
allow_anonymous: true时,支持通过X-Ownerheader 指定 owner(用于测试)
部分写操作(创建沙箱、创建 Cargo、延长 TTL)支持 Idempotency-Key header:
POST /v1/sandboxes
Idempotency-Key: my-unique-key-123相同 key + 相同请求体 → 返回缓存响应,不重复执行。
列表接口使用游标分页(cursor-based pagination):
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
limit |
int | 50 | 每页条数,1-200 |
cursor |
string | null | null | 分页游标 |
响应中包含 next_cursor,为 null 时表示无更多数据。
所有接受文件路径的参数均会进行安全校验(见 validators/path.py):
- 不允许绝对路径(以
/开头) - 不允许路径穿越(
../逃逸工作区) - 不允许 null 字节
{
"error": {
"code": "not_found",
"message": "Resource not found",
"request_id": "...",
"details": {}
}
}源码:
sandboxes.py前缀:/v1/sandboxes
沙箱是 Bay 的核心资源——一个隔离的计算环境,包含容器会话(Session)和工作区存储(Cargo)。
POST /v1/sandboxes
创建一个新的沙箱实例。当前实现是“预热优先,未命中回退普通创建”:
- 若携带
Idempotency-Key,先检查幂等缓存;命中则直接返回缓存响应(不触发 claim/warmup 副作用)。 - 若未指定
cargo_id,优先尝试从 warm pool claim 可用实例。 - claim 成功:立即返回该 sandbox(API 响应模型不暴露 warm pool 内部字段)。
- claim 失败:走普通创建。
- 普通创建后仅投递 warmup 队列(队列不可用时回退 background task)。
说明:API 响应语义保持稳定,
SandboxResponse不包含 warm pool 内部状态字段。
请求体 (CreateSandboxRequest):
| 字段 | 类型 | 默认值 | 说明 |
|---|---|---|---|
profile |
string | "python-default" |
Profile ID,决定运行时能力和资源 |
cargo_id |
string | null | null | 关联已有 Cargo;null 则自动创建(且仅此场景尝试 warm claim) |
ttl |
int | null | null | 生存时间(秒),null/0 表示永不过期 |
请求头:
| Header | 说明 |
|---|---|
Idempotency-Key |
可选,幂等键用于安全重试 |
响应 201 (SandboxResponse):
{
"id": "sbx_abc123",
"status": "idle",
"profile": "python-default",
"cargo_id": "crg_xyz789",
"capabilities": ["python", "shell", "filesystem"],
"created_at": "2025-01-01T00:00:00Z",
"expires_at": "2025-01-01T01:00:00Z",
"idle_expires_at": null
}状态说明:
| 状态 | 含义 |
|---|---|
idle |
无运行会话 |
starting |
会话正在启动 |
ready |
会话已运行并就绪 |
failed |
上一次会话启动失败 |
expired |
TTL 已到期 |
- warm pool 内部实例仅用于被 claim,不会作为独立资源暴露给用户 API。
GET /v1/sandboxes默认只返回is_warm_pool=false的用户沙箱。- 普通创建后的 warmup 采用共享队列削峰(固定 worker + 有界队列 + 去重 + 满队列丢弃策略)。
- 队列在进程
lifespan启动/停止时统一管理;若队列不可用,会回退到 background task 执行 warmup。
GET /v1/sandboxes
列出当前用户的所有沙箱。
查询参数:
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
limit |
int | 50 | 1-200 |
cursor |
string | null | null | 分页游标 |
status |
string | null | null | 按状态过滤: idle, starting, ready, failed, expired |
响应 200 (SandboxListResponse):
{
"items": [{ "...SandboxResponse" }],
"next_cursor": "cursor_token_or_null"
}GET /v1/sandboxes/{sandbox_id}
响应 200: SandboxResponse
当沙箱有活跃会话(status=ready)时,响应中会包含 containers 字段,列出各容器的运行时版本和健康状态:
{
"id": "sbx_abc123",
"status": "ready",
"profile": "browser-enabled",
"cargo_id": "crg_xyz789",
"capabilities": ["browser", "filesystem", "python", "shell"],
"created_at": "2025-01-01T00:00:00Z",
"expires_at": "2025-01-01T01:00:00Z",
"idle_expires_at": "2025-01-01T00:10:00Z",
"containers": [
{
"name": "ship",
"runtime_type": "ship",
"status": "running",
"version": "0.1.2",
"capabilities": ["filesystem", "python", "shell"],
"healthy": true
},
{
"name": "browser",
"runtime_type": "gull",
"status": "running",
"version": "0.1.2",
"capabilities": ["browser"],
"healthy": true
}
]
}containers 字段说明:
| 字段 | 类型 | 说明 |
|---|---|---|
containers |
list | null | 容器运行时状态列表。仅在有活跃会话时返回,idle 状态时为 null |
ContainerRuntimeResponse 结构:
| 字段 | 类型 | 说明 |
|---|---|---|
name |
string | 容器名称,如 "ship", "browser" |
runtime_type |
string | 运行时类型: ship | gull |
status |
string | 容器状态: running | stopped | failed |
version |
string | null | 运行时版本号,如 "0.1.2"。查询失败时为 null |
capabilities |
list[string] | 该容器提供的能力列表 |
healthy |
bool | null | 健康状态。true=健康, false=不健康, null=未检查/查询失败 |
注意: 列表接口
GET /v1/sandboxes不返回containers字段,避免 N+1 查询性能问题。
POST /v1/sandboxes/{sandbox_id}/extend_ttl
延长沙箱的过期时间(expires_at)。
请求体 (ExtendTTLRequest):
| 字段 | 类型 | 说明 |
|---|---|---|
extend_by |
int | 延长秒数 |
约束:
- 不能复活已过期的沙箱 →
409 sandbox_expired - 不能延长无限 TTL 的沙箱 →
409 sandbox_ttl_infinite - 支持
Idempotency-Key
响应 200: SandboxResponse(更新后的 expires_at)
POST /v1/sandboxes/{sandbox_id}/keepalive
重置空闲超时计时器(idle_expires_at),不 延长 TTL。不会隐式启动计算(如果没有活跃会话)。
响应 200:
{ "status": "ok" }POST /v1/sandboxes/{sandbox_id}/stop
停止沙箱——回收计算资源(销毁容器),但保留工作区存储(Cargo)。幂等操作,重复调用不会报错。
响应 200:
{ "status": "stopped" }DELETE /v1/sandboxes/{sandbox_id}
永久删除沙箱。
行为:
- 销毁所有运行中的会话
- 级联删除托管 Cargo(
managed=true) - 不 级联删除外部 Cargo(
managed=false)
响应 204: 无响应体
源码:
capabilities.py前缀:/v1/sandboxes/{sandbox_id}/...
Capabilities API 将执行请求路由到沙箱内的运行时适配器(Ship/Gull)。每个端点都带有能力级别校验——在路由到运行时之前先检查 Profile 是否支持该能力。
能力校验通过 FastAPI 依赖注入实现(见 require_capability()):
- Level 1(Profile): API 层检查 →
400 capability_not_supported - Level 2(Runtime): 运行时容器内检查
POST /v1/sandboxes/{sandbox_id}/python/exec
在沙箱中执行 Python 代码。首次调用会自动启动容器会话。代码通过 IPython kernel 执行,支持富文本输出(图片等)。
需要能力: python
请求体 (PythonExecRequest):
| 字段 | 类型 | 默认值 | 说明 |
|---|---|---|---|
code |
string | 必填 | Python 代码 |
timeout |
int | 30 | 超时秒数,1-300 |
include_code |
bool | false | 响应中是否回显代码 |
description |
string | null | null | 执行描述(记录到历史) |
tags |
string | null | null | 标签(记录到历史) |
响应 200 (PythonExecResponse):
{
"success": true,
"output": "Hello World\n",
"error": null,
"data": {
"execution_count": 1,
"output": {
"text": "Hello World\n",
"images": [{"image/png": "base64..."}]
}
},
"execution_id": "exe_abc123",
"execution_time_ms": 142,
"code": null
}| 字段 | 说明 |
|---|---|
data |
IPython 内核富输出,包含 execution_count、文本和图片 |
execution_id |
执行历史记录 ID,可用于后续查询/标注 |
code |
仅当 include_code=true 时返回 |
POST /v1/sandboxes/{sandbox_id}/shell/exec
在沙箱中执行 Shell 命令。
需要能力: shell
请求体 (ShellExecRequest):
| 字段 | 类型 | 默认值 | 说明 |
|---|---|---|---|
command |
string | 必填 | Shell 命令 |
timeout |
int | 30 | 超时秒数,1-300 |
cwd |
string | null | null | 工作目录(相对 /workspace,经过路径校验) |
include_code |
bool | false | 响应中是否回显命令 |
description |
string | null | null | 执行描述 |
tags |
string | null | null | 标签 |
响应 200 (ShellExecResponse):
{
"success": true,
"output": "total 4\ndrwxr-xr-x 2 user user 4096 ...\n",
"error": null,
"exit_code": 0,
"execution_id": "exe_def456",
"execution_time_ms": 85,
"command": null
}POST /v1/sandboxes/{sandbox_id}/browser/exec
在沙箱中执行浏览器自动化命令,路由到 Gull 运行时。
需要能力: browser
请求体 (BrowserExecRequest):
| 字段 | 类型 | 默认值 | 说明 |
|---|---|---|---|
cmd |
string | 必填 | 浏览器自动化命令 |
timeout |
int | 30 | 超时秒数,1-300 |
响应 200 (BrowserExecResponse):
{
"success": true,
"output": "...",
"error": null,
"exit_code": 0
}POST /v1/sandboxes/{sandbox_id}/browser/exec_batch
批量执行多条浏览器自动化命令。整批作为单条执行历史记录。
需要能力: browser
请求体 (BrowserBatchExecRequest):
| 字段 | 类型 | 默认值 | 说明 |
|---|---|---|---|
commands |
list[string] | 必填 | 命令列表(至少 1 条) |
timeout |
int | 60 | 整批超时秒数,1-600 |
stop_on_error |
bool | true | 遇错是否停止 |
响应 200 (BrowserBatchExecResponse):
{
"results": [
{
"cmd": "navigate https://example.com",
"stdout": "...",
"stderr": "",
"exit_code": 0,
"step_index": 0,
"duration_ms": 1200
}
],
"total_steps": 3,
"completed_steps": 3,
"success": true,
"duration_ms": 3500
}GET /v1/sandboxes/{sandbox_id}/filesystem/files?path=src/main.py
需要能力: filesystem
查询参数:
| 参数 | 类型 | 说明 |
|---|---|---|
path |
string | 文件路径(相对 /workspace,必填) |
响应 200 (FileReadResponse):
{ "content": "print('hello')\n" }PUT /v1/sandboxes/{sandbox_id}/filesystem/files
需要能力: filesystem
请求体 (FileWriteRequest):
| 字段 | 类型 | 说明 |
|---|---|---|
path |
string | 文件路径(相对 /workspace,经过校验) |
content |
string | 文件内容 |
响应 200:
{ "status": "ok" }GET /v1/sandboxes/{sandbox_id}/filesystem/directories?path=.
需要能力: filesystem
查询参数:
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
path |
string | "." |
目录路径(相对 /workspace) |
响应 200 (FileListResponse):
{
"entries": [
{ "name": "main.py", "type": "file", "size": 1024 },
{ "name": "src", "type": "directory" }
]
}DELETE /v1/sandboxes/{sandbox_id}/filesystem/files?path=temp.txt
需要能力: filesystem
查询参数:
| 参数 | 类型 | 说明 |
|---|---|---|
path |
string | 要删除的路径(必填) |
响应 200:
{ "status": "ok" }POST /v1/sandboxes/{sandbox_id}/filesystem/upload
Content-Type: multipart/form-data
上传二进制文件到沙箱工作区。
需要能力: filesystem
Form 参数:
| 参数 | 类型 | 说明 |
|---|---|---|
file |
file | 要上传的文件 |
path |
string | 目标路径(相对 /workspace) |
响应 200 (FileUploadResponse):
{
"status": "ok",
"path": "data/input.csv",
"size": 4096
}GET /v1/sandboxes/{sandbox_id}/filesystem/download?path=output.csv
以二进制流下载沙箱中的文件。
需要能力: filesystem
查询参数:
| 参数 | 类型 | 说明 |
|---|---|---|
path |
string | 文件路径(必填) |
响应 200: 二进制文件流
Content-Type: application/octet-streamContent-Disposition: attachment; filename="output.csv"
源码:
cargos.py前缀:/v1/cargos
Cargo 是沙箱的持久化工作区存储卷。分为两种类型:
| 类型 | managed |
生命周期 | 说明 |
|---|---|---|---|
| 托管 Cargo | true |
随沙箱创建/删除 | 沙箱自动创建,删除沙箱时级联删除 |
| 外部 Cargo | false |
用户手动管理 | 通过 API 创建,可跨多个沙箱共享 |
POST /v1/cargos
创建一个新的外部 Cargo(managed=false)。外部 Cargo 需要用户手动删除,可在多个沙箱间共享。
请求体 (CreateCargoRequest):
| 字段 | 类型 | 默认值 | 说明 |
|---|---|---|---|
size_limit_mb |
int | null | null | 大小限制(MB),1-65536,null 使用默认值 |
请求头:
| Header | 说明 |
|---|---|
Idempotency-Key |
可选,幂等键 |
响应 201 (CargoResponse):
{
"id": "crg_abc123",
"managed": false,
"managed_by_sandbox_id": null,
"backend": "docker-volume",
"size_limit_mb": 512,
"created_at": "2025-01-01T00:00:00Z",
"last_accessed_at": "2025-01-01T00:00:00Z"
}GET /v1/cargos
列出当前用户的 Cargo。
查询参数:
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
limit |
int | 50 | 1-200 |
cursor |
string | null | null | 分页游标 |
managed |
bool | null | null | 过滤托管状态。默认(null/省略)仅返回外部 Cargo;true 仅返回托管 Cargo |
响应 200 (CargoListResponse):
{
"items": [{ "...CargoResponse" }],
"next_cursor": null
}GET /v1/cargos/{cargo_id}
响应 200: CargoResponse
DELETE /v1/cargos/{cargo_id}
删除约束:
| 场景 | 行为 |
|---|---|
| 外部 Cargo 仍被活跃沙箱引用 | 409 conflict,响应含 active_sandbox_ids |
| 托管 Cargo 的管理沙箱仍活跃 | 409 conflict |
| 托管 Cargo 的管理沙箱已软删除 | 允许删除 |
响应 204: 无响应体
源码:
history.py前缀:/v1/sandboxes/{sandbox_id}/history
执行历史在 Bay 控制面存储,按沙箱归属关系进行隔离。每次 Python/Shell/Browser 执行都会自动记录。
GET /v1/sandboxes/{sandbox_id}/history
查询参数:
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
exec_type |
string | null | null | 按类型过滤: python, shell |
success_only |
bool | false | 仅返回成功的执行 |
limit |
int | 100 | 1-500 |
offset |
int | 0 | 偏移量 |
tags |
string | null | null | 按标签过滤 |
has_notes |
bool | false | 仅返回有备注的记录 |
has_description |
bool | false | 仅返回有描述的记录 |
响应 200 (ExecutionHistoryResponse):
{
"entries": [
{
"id": "exe_abc123",
"session_id": "ses_xyz",
"exec_type": "python",
"code": "print('hello')",
"success": true,
"execution_time_ms": 142,
"output": "hello\n",
"error": null,
"description": "测试代码",
"tags": "test",
"notes": null,
"created_at": "2025-01-01T00:00:00Z"
}
],
"total": 42
}GET /v1/sandboxes/{sandbox_id}/history/last
查询参数:
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
exec_type |
string | null | null | 按类型过滤: python, shell |
响应 200: ExecutionHistoryEntryResponse
GET /v1/sandboxes/{sandbox_id}/history/{execution_id}
响应 200: ExecutionHistoryEntryResponse
PATCH /v1/sandboxes/{sandbox_id}/history/{execution_id}
为执行记录添加描述、标签或备注。
请求体 (AnnotateExecutionRequest):
| 字段 | 类型 | 说明 |
|---|---|---|
description |
string | null | 执行描述 |
tags |
string | null | 标签 |
notes |
string | null | 备注 |
所有字段均为可选,仅更新提供的字段。
响应 200: ExecutionHistoryEntryResponse(更新后的记录)
源码:
skills.py前缀:/v1/skills
Skills API 管理技能的完整生命周期:候选创建 → 评估 → 晋升发布 → 回滚。技能(Skill)是由执行历史提炼而成的可复用代码片段。
执行历史(Executions)
↓ create_candidate(选取有价值的执行)
Candidate(候选)
↓ evaluate(评估打分)
Candidate(已评估,passed=true)
↓ promote(晋升到 canary/stable)
Release(发布版本)
↓ rollback(如有问题)
Release(回滚版本)
Skills 域提供通用 payload 读写能力,推荐用于 candidate payload 与其他可复用工件内容存储。
写入后返回 blob: 引用(payload_ref),后续通过该引用读取。
POST /v1/skills/payloads
请求体:
| 字段 | 类型 | 默认值 | 说明 |
|---|---|---|---|
payload |
object | array | 必填 | JSON 负载内容(仅支持 object/array) |
kind |
string | "generic" |
负载类型标记 |
响应 201:
{
"payload_ref": "blob:blob_abc123",
"kind": "candidate_payload"
}GET /v1/skills/payloads/{payload_ref}
响应 200:
{
"payload_ref": "blob:blob_abc123",
"kind": "candidate_payload",
"payload": {
"commands": ["open about:blank"]
}
}错误语义:
| 场景 | 状态码 | 说明 |
|---|---|---|
payload_ref 非 blob: 格式 |
400 validation_error |
不支持的引用类型 |
blob: 引用不存在或不可见 |
404 not_found |
资源未找到 |
兼容说明:
GET /v1/sandboxes/{sandbox_id}/browser/traces/{trace_ref}仍保留,响应结构保持不变;其内部读取逻辑与通用 payload 存储一致。
POST /v1/skills/candidates
请求体 (SkillCandidateCreateRequest):
| 字段 | 类型 | 默认值 | 说明 |
|---|---|---|---|
skill_key |
string | 必填 | 技能标识键 |
source_execution_ids |
list[string] | 必填 | 来源执行记录 ID 列表 |
scenario_key |
string | null | null | 场景标识 |
payload_ref |
string | null | null | 负载引用 |
响应 201 (SkillCandidateResponse):
{
"id": "cand_abc123",
"skill_key": "data-cleaning-v1",
"scenario_key": null,
"payload_ref": null,
"source_execution_ids": ["exe_001", "exe_002"],
"status": "draft",
"latest_score": null,
"latest_pass": null,
"last_evaluated_at": null,
"promotion_release_id": null,
"created_by": "default",
"created_at": "2025-01-01T00:00:00Z",
"updated_at": "2025-01-01T00:00:00Z"
}候选状态:
| 状态 | 说明 |
|---|---|
draft |
草稿,待评估 |
evaluating |
评估中 |
promoted |
已晋升为发布版本 |
rejected |
已拒绝 |
rolled_back |
已回滚 |
GET /v1/skills/candidates
查询参数:
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
status |
string | null | null | 按状态过滤 |
skill_key |
string | null | null | 按技能键过滤 |
limit |
int | 100 | 1-500 |
offset |
int | 0 | 偏移量 |
响应 200 (SkillCandidateListResponse):
{
"items": [{ "...SkillCandidateResponse" }],
"total": 10
}GET /v1/skills/candidates/{candidate_id}
响应 200: SkillCandidateResponse
POST /v1/skills/candidates/{candidate_id}/evaluate
请求体 (SkillEvaluationRequest):
| 字段 | 类型 | 默认值 | 说明 |
|---|---|---|---|
passed |
bool | 必填 | 是否通过 |
score |
float | null | null | 评分 |
benchmark_id |
string | null | null | 基准测试 ID |
report |
string | null | null | 评估报告 |
响应 200 (SkillEvaluationResponse):
{
"id": "eval_xyz",
"candidate_id": "cand_abc123",
"benchmark_id": null,
"score": 0.95,
"passed": true,
"report": "All tests passed",
"evaluated_by": "default",
"created_at": "2025-01-01T00:05:00Z"
}POST /v1/skills/candidates/{candidate_id}/promote
将已通过评估的候选晋升为发布版本。
请求体 (SkillPromotionRequest):
| 字段 | 类型 | 默认值 | 说明 |
|---|---|---|---|
stage |
string | "canary" |
发布阶段: canary, stable |
响应 200 (SkillReleaseResponse):
{
"id": "rel_001",
"skill_key": "data-cleaning-v1",
"candidate_id": "cand_abc123",
"version": 1,
"stage": "canary",
"is_active": true,
"promoted_by": "default",
"promoted_at": "2025-01-01T00:10:00Z",
"rollback_of": null
}GET /v1/skills/releases
查询参数:
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
skill_key |
string | null | null | 按技能键过滤 |
active_only |
bool | false | 仅返回活跃版本 |
stage |
string | null | null | 按阶段过滤: canary, stable |
limit |
int | 100 | 1-500 |
offset |
int | 0 | 偏移量 |
响应 200 (SkillReleaseListResponse):
{
"items": [{ "...SkillReleaseResponse" }],
"total": 5
}POST /v1/skills/releases/{release_id}/rollback
回滚指定的发布版本。
响应 200: SkillReleaseResponse(新创建的回滚版本,rollback_of 指向被回滚的版本 ID)
源码:
profiles.py前缀:/v1/profiles
Profile 定义了沙箱的运行时配置模板,包括镜像、资源限制、能力集合和空闲超时。Profile 在服务端配置文件中定义,API 仅提供只读查询。
GET /v1/profiles
查询参数:
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
detail |
bool | false | 是否包含容器拓扑和描述信息 |
响应 200 (ProfileListResponse):
{
"items": [
{
"id": "python-default",
"image": "shipyard/ship:latest",
"resources": { "cpus": 1.0, "memory": "1g" },
"capabilities": ["python", "shell", "filesystem"],
"idle_timeout": 600,
"description": null,
"containers": null
}
]
}detail=true 时额外返回:
| 字段 | 说明 |
|---|---|
description |
Profile 描述文本 |
containers |
容器拓扑列表(多容器 Profile 支持) |
{
"containers": [
{
"name": "ship",
"runtime_type": "ship",
"capabilities": ["filesystem", "python", "shell"],
"resources": { "cpus": 1.0, "memory": "1g" }
},
{
"name": "gull",
"runtime_type": "gull",
"capabilities": ["browser"],
"resources": { "cpus": 0.5, "memory": "512m" }
}
]
}源码:
admin.py前缀:/v1/admin
运维管理接口,目前提供 GC(垃圾回收)的手动触发和状态查询。
POST /v1/admin/gc/run
同步执行一次 GC 周期,等待完成后返回详细结果。即使 gc.enabled: false(后台 GC 关闭)时仍可使用。
请求体(可选)(GCRunRequest):
| 字段 | 类型 | 默认值 | 说明 |
|---|---|---|---|
tasks |
list[string] | null | null | 指定运行的任务列表,null 表示全部 |
可用任务名:
| 任务名 | 说明 |
|---|---|
idle_session |
回收空闲超时的会话 |
expired_sandbox |
清理 TTL 过期的沙箱 |
orphan_cargo |
清理孤儿 Cargo |
orphan_container |
清理孤儿容器 |
响应 200 (GCRunResponse):
{
"results": [
{
"task_name": "idle_session",
"cleaned_count": 3,
"skipped_count": 0,
"errors": []
},
{
"task_name": "expired_sandbox",
"cleaned_count": 1,
"skipped_count": 0,
"errors": []
}
],
"total_cleaned": 4,
"total_errors": 0,
"duration_ms": 523
}错误状态码:
| 状态码 | 说明 |
|---|---|
200 |
GC 执行完成(即使部分任务有错误) |
423 |
GC 已在运行中(另一个周期进行中) |
503 |
GC 调度器不可用(内部异常) |
GET /v1/admin/gc/status
获取 GC 调度器当前的配置和运行状态。
响应 200 (GCStatusResponse):
{
"enabled": true,
"is_running": false,
"instance_id": "bay-gc-01",
"interval_seconds": 60,
"tasks": {
"idle_session": { "enabled": true },
"expired_sandbox": { "enabled": true },
"orphan_cargo": { "enabled": true },
"orphan_container": { "enabled": true }
}
}→ 详见独立文档: Bay 错误码参考