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

# 参考

> CLI 命令、fleet API 端点，以及工作器 spawn 约定

Outposts 的完整参考文档：工作器 CLI、fleet API、`devin-remote` 二进制程序分发，以及适用于自定义编排器的 spawn 约定。

<div id="authentication">
  ## 身份验证
</div>

工作器和编排器通过属于某个服务用户的 [v3 API 令牌](/zh/api-reference/v3/overview) 进行身份验证。分配给该服务用户的角色决定了该令牌拥有的 Outposts 作用域：

| 角色权限                                           | 令牌作用域                           | 授予                               |
| ---------------------------------------------- | ------------------------------- | -------------------------------- |
| **使用 outpost 机器** (`UseOutpostsMachine`)       | `account.outposts.machine`      | 读取队列以及认领/释放会话                    |
| **管理 Outposts** (`ManageOutpostsOrchestrator`) | `account.outposts.orchestrator` | 创建和删除 outpost (隐含包含 machine 作用域) |

Outposts 以你的**账户**为作用域，并在该账户下的所有组织之间共享。

<div id="cli">
  ## CLI
</div>

<div id="devin-worker-start">
  ### `devin worker start`
</div>

轮询 outpost 的队列，认领会话，下载正确的 `devin-remote` 二进制程序，并处理这些会话。请在包含该会话已检出代码仓库的目录中运行此命令。

```bash theme={null}
devin worker start --outpost=<outpost_id>
```

| 标志                                 | 环境变量                           | 描述                                                                |
| ---------------------------------- | ------------------------------ | ----------------------------------------------------------------- |
| `--outpost`                        | —                              | 仅认领来自此 outpost 的会话。如果在交互式终端中省略，工作器会提示你从你账户的 outpost 中选择。          |
| `--session` (alias `--session-id`) | —                              | 认领并处理一个特定会话，然后退出。                                                 |
| `--acceptor-id`                    | `DEVIN_WORKER_ACCEPTOR_ID`     | 用于认领、续期和重启恢复的稳定工作器身份。默认值为生成的 ID，并持久保存在工作器数据目录下。切勿在多台机器之间共享同一个 ID。 |
| `--token`                          | `DEVIN_OUTPOSTS_TOKEN`         | 工作器的身份验证令牌。如果两者都未设置，该命令会报错。                                       |
| `--once`                           | —                              | 处理完一个会话后退出，而不是返回队列。                                               |
| `--api-url`                        | `DEVIN_API_URL`                | Devin API 基础 URL。默认为 `https://api.devin.ai`。                      |
| `--cache-dir`                      | `DEVIN_WORKER_CACHE_DIR`       | 用于缓存已下载 `devin-remote` 二进制程序的目录。默认为 `~/.devin/worker/cache`。      |
| `--static-base-url`                | `DEVIN_WORKER_STATIC_BASE_URL` | 发布 `devin-remote` 二进制程序的基础 URL。                                   |
| `--gateway-url`                    | `DEVIN_OUTPOST_GATEWAY_URL`    | 当认领响应中未提供 outpost 网关 URL 时使用的回退值。                                 |
| `--remote-binary-sha`              | `DEVIN_WORKER_REMOTE_SHA`      | 当会话未固定 `devin-remote` 的 git SHA 时使用的回退值。如果两者都未设置，则使用最新发布的 SHA。    |
| `--pty-bridge-port`                | `DEVIN_PTY_BRIDGE_PORT`        | 固定的 PTY bridge 端口。默认情况下，每个会话都会分配一个空闲端口。                           |
| `--poll-interval-secs`             | —                              | 队列轮询和会话状态检查的间隔秒数。默认为 `5`。                                         |

工作器环境还可以包含 `DEVIN_CHROME_PATH`，用于为会话指定 Chrome/Chromium 二进制程序，以启用浏览器功能。

<div id="devin-worker-outpost-create">
  ### `devin worker outpost create`
</div>

创建一个 outpost——即由你的基础架构提供支持的命名会话队列。需要 `orchestrator` 作用域。

```bash theme={null}
devin worker outpost create <name> --platform <platform> --description "..."
```

| 参数 / 开关         | 描述                                           |
| --------------- | -------------------------------------------- |
| `<name>`        | 唯一的 (每个账户内) outpost 名称，例如 `rhel`、`gpu-h200`。 |
| `--platform`    | 主机平台：`linux`、`macos` 或 `windows`。            |
| `--description` | 显示在 Web 应用中的易读描述。                            |

输出新 outpost 的 ID (`outpost_env-...`)。你也可以在 Web 应用的 **设置 → 环境 → Outposts** 中创建 outpost。

<div id="devin-worker-outpost-delete">
  ### `devin worker outpost delete`
</div>

删除一个 outpost。需要 orchestrator 作用域。

```bash theme={null}
devin worker outpost delete <outpost_id>
```

<div id="fleet-api">
  ## Fleet API
</div>

所有端点都位于 `https://api.devin.ai/opbeta/outposts/` 下，并使用 Bearer 令牌进行认证：

```bash theme={null}
curl -H "Authorization: Bearer $DEVIN_API_TOKEN" ...
```

资源采用 Kubernetes 风格的 `metadata` / `spec` / `status` 结构，队列则遵循 Kubernetes 的“先列出再监听”语义，并保证至少一次投递。

<div id="objects">
  ### 对象
</div>

<div id="queue-entry-devins">
  #### 队列条目 (`devins`)
</div>

每个排队中的会话都对应一个队列条目：

| 字段                       | 说明                                                            |
| ------------------------ | ------------------------------------------------------------- |
| `metadata.session_id`    | 会话 (devin) 的 ID。                                              |
| `metadata.outpost_id`    | 会话排队所在的 outpost。                                              |
| `metadata.created_at`    | 会话进入队列的时间 (Unix 时间戳) 。                                        |
| `metadata.updated_at`    | 此对象上次变更的时间 (Unix 时间戳) 。                                       |
| `spec.kind`              | `new` 或 `resume`。                                             |
| `spec.platform`          | 机器平台，例如 `linux`。                                              |
| `spec.remote_binary_sha` | 工作器应运行的 `devin-remote` 二进制程序的短 commit SHA；`null` 表示使用工作器的默认值。 |
| `spec.network_policy`    | 会话生效的网络策略 (见下文) 。                                             |
| `status.phase`           | 队列阶段：`pending` 或 `claimed`。                                   |
| `status.acceptor_id`     | 当前持有认领的工作器 (如果已认领) 。                                          |
| `status.claim_deadline`  | 当前认领到期、会话返回队列的时间。                                             |
| `status.session_status`  | 底层会话的粗略状态：`pending`、`running`、`suspended` 或 `terminated`。     |
| `status.connect_token`   | 网关连接令牌；仅在认领成功后返回。                                             |
| `status.gateway_url`     | outpost 网关的公共 websocket URL；仅在认领成功后返回。                        |

`spec.network_policy` 会说明会话的网络访问是否受限 (`enabled`) ，以及允许访问的目标 (`allow`) ：主机名 glob 模式 (`{"hostname": ...}`) 、IPv4 地址/CIDR (`{"ipv4": ...}`) 或 IPv6 地址/CIDR (`{"ipv6": ...}`) 。

<div id="outpost">
  #### Outpost
</div>

| 字段                     | 描述                               |
| ---------------------- | -------------------------------- |
| `metadata.outpost_id`  | Outpost ID (`outpost_env-...`) 。 |
| `metadata.account_id`  | 拥有该 Outpost 的账户。                 |
| `metadata.created_at`  | Outpost 的创建时间 (Unix 时间戳) 。       |
| `spec.name`            | Outpost 名称 (在每个账户内唯一) 。          |
| `spec.platform`        | 机器平台；`null` 表示默认平台。              |
| `spec.description`     | 便于人类阅读的描述。                       |
| `status.queue_depth`   | 队列中待处理 (未被认领) 的 session 数量。      |
| `status.active_claims` | 工作器持有的未过期认领数。                    |

<div id="list-queued-sessions">
  ### 列出排队会话
</div>

```
GET /opbeta/outposts/devins
```

| 查询参数          | 描述                                                                         |
| ------------- | -------------------------------------------------------------------------- |
| `outpost`     | 按 outpost ID 过滤。适用于列出和监听。                                                  |
| `phase`       | 按队列阶段过滤 (`pending` 或 `claimed`) 。监听时会忽略。                                   |
| `acceptor_id` | 按认领会话的工作器过滤。监听时会忽略。                                                        |
| `first`       | 每页最多返回的行数，范围为 1–200。默认为 100。                                               |
| `cursor`      | 来自先前列出响应或监听事件的不透明游标 (两者可互换) 。对于列出，会返回该位置及之后的行；对于监听，会先重放此游标之后的变更，再流式传输实时变更。 |
| `watch`       | 以 SSE 流式传输变更，而不是列出结果。                                                      |

示例响应：

```json theme={null}
{
  "items": [
    {
      "metadata": {
        "session_id": "devin-...",
        "outpost_id": "outpost_env-...",
        "created_at": 1781050000,
        "updated_at": 1781050000
      },
      "spec": {
        "kind": "new",
        "platform": "linux",
        "remote_binary_sha": null
      },
      "status": {
        "phase": "pending",
        "acceptor_id": null,
        "claim_deadline": null,
        "session_status": "pending"
      }
    }
  ],
  "cursor": "djE6MTc4MTA1MDAwMC4w",
  "has_next_page": false,
  "total": 1
}
```

分页和投递语义：

* 当 `has_next_page` 为 `true` 时，将每个响应中的 `cursor` 传入下一次请求。
* 投递采用至少一次语义：处于页面边界的会话可能会同时出现在前后两个页面中，因此应按 `metadata.session_id` 对条目执行 upsert，而不要将每一项都视为新项 (`claim CAS` 会让重复项不会造成影响) 。
* 当 `has_next_page` 变为 `false` 时，将返回的游标保存为监听的起始位置。

<div id="watch-for-changes">
  ### 监听变更
</div>

```
GET /opbeta/outposts/devins?watch=true&cursor=<cursor>
```

以流方式传输 Server-Sent Events。会话的队列条目发生变化时会触发 `MODIFIED` 事件 (新排队的会话也会以 `MODIFIED` 事件形式到达) ；当该条目被移除时会触发 `DELETED` 事件。每个 SSE 的 `data` 字段都包含：

```json theme={null}
{
  "type": "MODIFIED",
  "object": {
    "metadata": {
      "session_id": "devin-...",
      "outpost_id": "outpost_env-...",
      "created_at": 1781050000,
      "updated_at": 1781050100
    },
    "spec": {
      "kind": "new",
      "platform": "linux",
      "remote_binary_sha": null
    },
    "status": {
      "phase": "pending",
      "acceptor_id": null,
      "claim_deadline": null,
      "session_status": "pending"
    }
  },
  "cursor": "djE6MTc4MTA1MDEwMC4w"
}
```

监听语义：

* 处理完每个事件后，保存其顶层 `cursor`；重新连接时使用上次保存的游标，以回放断开期间发生的变更。
* 事件交付至少一次——因此需要容忍重复事件。
* 流最多持续五分钟；应采用可重连的监听循环。
* 当 `watch=true` 时，`phase` 和 `acceptor_id` 过滤器会被忽略；请根据每个事件 `object` 中的字段过滤收到的事件。
* 省略游标会从头开始，因此常规对账应采用“先列出再监听”的方式。

<div id="get-a-queue-entry">
  ### 获取队列条目
</div>

```
GET /opbeta/outposts/devins/{session_id}
```

返回某个会话对应的队列条目。

<div id="claim-a-session">
  ### 认领会话
</div>

```
POST /opbeta/outposts/devins/{session_id}/claim
```

```json theme={null}
{ "acceptor_id": "worker-1" }
```

以原子方式为给定的工作器身份认领该会话。如果它已被另一个工作器抢先认领，该请求会返回 `409`。认领成功后的响应会包含 `status.connect_token` 和 `status.gateway_url` —— 也就是 `devin-remote` 建立连接所需的凭据 (请参阅 [spawn 约定](#spawn-contract)) 。

认领表示工作器承诺会在服务器分配的认领截止时间 (`status.claim_deadline`) 内就绪；过期的认领会自动返回队列。

<div id="release-a-claim">
  ### 解除认领
</div>

```
POST /opbeta/outposts/devins/{session_id}/release
```

```json theme={null}
{ "acceptor_id": "worker-1" }
```

释放工作器的认领，使会话立即返回队列 (例如，在预配失败时) 。

<div id="outposts">
  ### Outposts
</div>

```
GET    /opbeta/outposts/outposts                 # 列出 outpost
POST   /opbeta/outposts/outposts                 # 创建 outpost
GET    /opbeta/outposts/outposts/{outpost_id}    # 获取 outpost
DELETE /opbeta/outposts/outposts/{outpost_id}    # 删除 outpost
```

创建请求体：

```json theme={null}
{
  "name": "my-outpost",
  "platform": "linux",
  "description": "Dev boxes in our VPC"
}
```

创建、GET 和删除需要 orchestrator 作用域；每个 outpost 响应都会返回实时的 `status.queue_depth` 和 `status.active_claims`。

<div id="remote-binary-distribution">
  ## 远程二进制程序分发
</div>

`devin worker start` 命令会自动下载正确的 `devin-remote` 二进制程序。不使用 Devin CLI 的自定义编排器可直接从以下地址下载：

```
https://static.devin.ai/devin-rs/remote/
```

**确认最新版本：**

```bash theme={null}
# 返回适用于你当前平台的最新已发布二进制程序的 git SHA
curl -fsSL "https://static.devin.ai/devin-rs/remote/latest_linux_x64"
```

**下载并验证：**

```bash theme={null}
SHA=$(curl -fsSL "https://static.devin.ai/devin-rs/remote/latest_linux_x64")

# 下载二进制程序
curl -fL "https://static.devin.ai/devin-rs/remote/devin-remote_${SHA}_linux_x64" \
  -o devin-remote

# 下载并验证校验和
curl -fsSL "https://static.devin.ai/devin-rs/remote/devin-remote_${SHA}_linux_x64.sha256" \
  -o devin-remote.sha256
echo "$(cat devin-remote.sha256)  devin-remote" | sha256sum -c

chmod +x devin-remote
```

**可用平台：**

| 后缀                | 操作系统 / 架构           |
| ----------------- | ------------------- |
| `linux_x64`       | Linux x86\_64       |
| `macos_arm64`     | macOS Apple Silicon |
| `windows_x64.exe` | Windows x86\_64     |

如果该 session 的队列条目包含 `spec.remote_binary_sha`，请使用该 SHA，而不要使用 `latest`——这会将该 session 固定到经过测试的特定版本。

<div id="spawn-contract">
  ## Spawn 约定
</div>

如果你的编排器不是使用 `devin worker start`，而是自行启动 `devin-remote`，请按如下方式启动它：

```bash theme={null}
devin-remote serve
```

使用以下环境变量：

| Variable                      | Required | Description                                                                                                                                                                                                                                                                |
| ----------------------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `DEVIN_OUTPOST_GATEWAY_URL`   | 是        | Outpost 网关的基础 URL，例如 `wss://outpost-gateway.devin.ai`。                                                                                                                                                                                                                     |
| `DEVIN_OUTPOST_CONNECT_TOKEN` | 是        | 网关使用的 Bearer 连接令牌，来自认领响应。                                                                                                                                                                                                                                                  |
| `DEVIN_OUTPOST_SESSION_ID`    | 是        | 正在提供服务的会话 ID。以上三个 `DEVIN_OUTPOST_*` 变量必须一并设置。                                                                                                                                                                                                                              |
| `DEVIN_REMOTE_STATE_DIR`      | 强烈建议     | 每个会话的状态目录，远程端会在其中存储凭据、令牌和 shell 集成文件。每个会话请使用唯一目录 (例如 `~/.devin/worker/sessions/<session_id>`，这也是 `devin worker` 使用的路径) 。如果未设置，远程端会回退到共享的系统级默认目录 (Linux 上为 `/opt/.devin`，macOS 上为 `~/.devin`，Windows 上为 `C:\ProgramData\devin`) ；此时该目录必须存在且可写，并且会导致并发会话之间泄露各自的会话状态。请始终设置此项。 |
| `DEVIN_CHROME_PATH`           | 可选       | 机器上供浏览器工具使用的 Chrome/Chromium 二进制程序路径 (Outposts 上没有由 Devin 管理的 Chrome) 。                                                                                                                                                                                                    |
| `DEVIN_OUTPOST_DESKTOP`       | 可选       | 设为 `true` 以启用桌面 (VNC) 流。它在远程端按需启用——在有查看器连接之前不会捕获任何内容——因此始终启用也是安全的。                                                                                                                                                                                                         |

为远程端提供一个干净的环境，其中只包含上述变量以及基础系统变量 (`PATH`、`HOME`、`USER`、`LOGNAME`、`TMPDIR`、`LANG`、`TZ`，以及——用于 Linux/X11 上桌面流的屏幕捕获——`DISPLAY`、`WAYLAND_DISPLAY`、`XAUTHORITY`) 。不要将任何 Agent 不应看到的信息泄露到远程端：这些信息会被 Agent 的 shell 继承。

额外的生命周期要求：

* **工作目录**：从包含该会话代码仓库的目录启动远程端 (与 `devin worker start` 的规则相同) 。
* **会话结束**：当会话结束 (进入休眠或终止) 时，Devin 会通知远程端，远程端随后会自行以退出状态码 0 退出。将正常退出来视为会话结束：确认队列条目的 `status.session_status` 为 `suspended` 或 `terminated` (状态更新可能会比退出晚几秒，因此请重读几次) ，然后释放认领。作为回退方案，也要在远程端运行期间轮询 `status.session_status`，并在其变为 `terminated` 时自行终止进程 (或者当队列条目消失时终止) 。
