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

# 启动 Session

> 创建、运行、查看和归档 Cloud Agent Sessions。

Session 是 Agent 的运行工作区。它把 Agent 快照、Environment、可选资源和可选 Vault 凭证绑定在一起。新 Session 初始为 `idle`，发送事件后开始执行。

## Session 状态生命周期

Session 是一个状态机。Session 资源上的 `status` 字段取以下值之一：

| 状态             | 说明                                      | 可流转到                                  |
| -------------- | --------------------------------------- | ------------------------------------- |
| `idle`         | Session 空闲，可以发送消息                       | `running`、`rescheduling`、`terminated` |
| `running`      | Agent 正在处理 turn                         | `idle`、`rescheduling`、`terminated`    |
| `rescheduling` | 底层运行时正在重新调度，期间 Session 不可用，恢复后回到 `idle` | `idle`、`terminated`                   |
| `terminated`   | Session 已终止（终态）                         | —                                     |

另外两个生命周期标记不出现在 `status` 字段中：

* **已归档（archived）**：通过非空 `archived_at` 时间戳标识。`status` 字段本身**不会**变成 `archived`——Session 仍可被读取，但拒绝新事件。
* **cancel 响应**：`POST /api/v1/cloud/sessions/{id}/cancel` 接口的响应体始终是固定字面量 `"status": "canceling"`。这只是响应结构，不是 Session 持久化的 status；turn 中止后 Session 的 `status` 仍回到 `idle`。

<Steps>
  <Step title="创建 → idle">
    新 Session 进入 `idle`，等待输入。
  </Step>

  <Step title="idle → running">
    发送 `user.message` 事件后，状态切换到 `running`。
  </Step>

  <Step title="running → idle">
    本轮完成后回到 `idle`，可继续下一轮。
  </Step>

  <Step title="running → idle（cancel 后）">
    取消正在执行的 Session 会中断当前 turn，Session 回到 `idle`。cancel 接口响应体使用固定 `"status": "canceling"` 字面量，与持久化的状态无关。Session 仍可继续使用。
  </Step>

  <Step title="rescheduling">
    运行时可能临时进入 `rescheduling`，重新调度完成后会回到 `idle`。
  </Step>

  <Step title="archived / terminated（终态）">
    归档（通过 `archived_at`）或终止后 Session 永久结束，无法恢复。
  </Step>
</Steps>

## Cancel 语义

* **对 `idle` Session 调用 cancel**：空操作（no-op），返回 HTTP `200`，状态保持 `idle`。
* **对 `running` Session 调用 cancel**：中断 Agent，返回 HTTP `202`。状态先变为 `canceling`，中断完成后回到 `idle`。
* **cancel 后**：Session 仍可复用——直接发送下一条 `user.message` 即可开始新 turn。

```bash theme={null}
# 取消当前 turn
curl -s -X POST "https://api.qoder.com/api/v1/cloud/sessions/$SESSION_ID/cancel" \
  -H "Authorization: Bearer $QODER_PAT"
```

<Note>
  只有 `archived` 和 `terminated` 是终态。取消后的 Session 总会回到 `idle`，可以继续接受消息。
</Note>

## 向 running Session 发消息（409 错误）

如果向正在 `running` 的 Session 发送 `user.message`，API 返回 **HTTP 409**：

```json theme={null}
{
  "type": "error",
  "request_id": "cb80235f-76a2-4ff3-9e28-5aa2da12dc14",
  "error": {
    "type": "invalid_request_error",
    "message": "Session is currently processing a turn. Cancel the current turn or wait for completion."
  }
}
```

这是新用户最常踩的坑。请始终等待 `session.status_idle` 事件后再发送下一条消息，或者先 cancel 当前 turn。

## 创建 Session

使用已有 `agent` 和 `environment_id` 创建 Session：

```bash theme={null}
curl -s -X POST "https://api.qoder.com/api/v1/cloud/sessions" \
  -H "Authorization: Bearer $QODER_PAT" \
  -H "Content-Type: application/json" \
  -d '{
    "agent": {"id": "agent_019e390add9f7bac9b6cc806db46fcbd", "type": "agent", "version": 2},
    "environment_id": "env_019e2590d33f711fabf42f2857cecd8a",
    "title": "Code review session",
    "metadata": {"purpose": "review"}
  }'
```

创建响应是 [Session 对象](/zh/cloud-agents/api/sessions/schemas#session-对象)，包含 `agent`、`environment_id`、`status`、`resources`、`vault_ids`、`deployment_id`、`outcome_evaluations`、`stats`、`environment_variables`、`archived_at`、`created_at` 和 `updated_at`。

旧请求字段 `environment`、`delta_flush_interval_ms`、`memory_store_ids` 和 `vaults` 不支持。`environment_variables` 已重新启用 — 请求采用 JSON 字符串格式（详见 [创建 Session](/zh/cloud-agents/api/sessions/create) 的字段说明与校验规则）。

## 创建时挂载资源

通过 `resources` 数组挂载文件、仓库和 Memory Store：

```json theme={null}
{
  "resources": [
    {
      "type": "file",
      "file_id": "file_019e5ce0bf307a1a8f952eb814aea3d5",
      "mount_path": "/data/input/spec.md"
    },
    {
      "type": "github_repository",
      "url": "https://github.com/your-org/your-repo",
      "mount_path": "/data/workspace/your-repo",
      "authorization_token": "ghp_xxxxxxxxxxxxxxxxxxxxxxxxxxxx"
    },
    {
      "type": "memory_store",
      "memory_store_id": "memstore_019eed05b61e78cea61bfd366e072878",
      "access": "read_write",
      "instructions": "Use this memory for long-lived project context."
    }
  ]
}
```

创建后追加文件请使用 [`POST /api/v1/cloud/sessions/{session_id}/resources`](/zh/cloud-agents/api/sessions/add-resource)。当前 CAS 创建后追加仅支持 file resource。resource list/get/update/delete 接口可用于查看、轮转 GitHub token 或移除资源。

## 发送消息

通过 Events API 发送 `user.message`。`content` 必须是非空 content block 数组：

```bash theme={null}
curl -s -X POST "https://api.qoder.com/api/v1/cloud/sessions/$SESSION_ID/events" \
  -H "Authorization: Bearer $QODER_PAT" \
  -H "Content-Type: application/json" \
  -d '{
    "events": [
      {
        "type": "user.message",
        "content": [
          {"type": "text", "text": "Review this repository and summarize the risks."}
        ]
      }
    ]
  }'
```

send-events 接口返回 **HTTP 200** 和 `{"data":[...]}`。可发送事件类型包括：`user.message`、`user.interrupt`、`user.tool_confirmation`、`user.tool_result`、`user.custom_tool_result`、`user.define_outcome` 和 `system.message`。

## 读取事件

使用事件流实时读取：

```bash theme={null}
curl -s -N "https://api.qoder.com/api/v1/cloud/sessions/$SESSION_ID/events/stream" \
  -H "Authorization: Bearer $QODER_PAT" \
  -H "Accept: text/event-stream"
```

事件流以 Server-Sent Events 输出 `id`、`event` 和 `data`。Stream endpoint 支持 `Last-Event-ID` header 进行断线重连；事件类型 query filter 当前不支持。

如果需要接收增量流式事件，请在创建 Session 时设置 `incremental_streaming_enabled: true`。开启后，stream 可能在最终完整 `agent.message` 前输出 `agent.message_start`、`agent.content_block_delta` 等增量事件。快速验证流程见 [增量流式](/zh/cloud-agents/incremental-streaming)。

使用 list endpoint 读取历史和分页：

```bash theme={null}
curl -s "https://api.qoder.com/api/v1/cloud/sessions/$SESSION_ID/events?limit=20&order=desc" \
  -H "Authorization: Bearer $QODER_PAT"
```

列表响应使用 `data` 和 `next_page`。

## 读取和更新 Sessions

```bash theme={null}
# 获取一个 Session
curl -s "https://api.qoder.com/api/v1/cloud/sessions/$SESSION_ID" \
  -H "Authorization: Bearer $QODER_PAT"

# 列出 Sessions
curl -s "https://api.qoder.com/api/v1/cloud/sessions?limit=20" \
  -H "Authorization: Bearer $QODER_PAT"

# 更新 title、metadata 或 Agent 配置（tools、MCP servers）
curl -s -X POST "https://api.qoder.com/api/v1/cloud/sessions/$SESSION_ID" \
  -H "Authorization: Bearer $QODER_PAT" \
  -H "Content-Type: application/json" \
  -d '{"title":"Updated title","metadata":{"priority":"high"}}'
```

Session list 使用 `page` / `next_page` 分页，并支持 `agent_id`、`agent_version`、`deployment_id`、`memory_store_id`、`statuses` 和 `created_at[...]` 等过滤。

## Threads

Managed-agent Session 可以包含协调器主线程和子线程。Thread endpoint 使用公开 `session_thread` 结构，不再包含 `role`、`name`、`agent_id`、`agent_version` 或 `stop_reason` 等旧字段。

```bash theme={null}
curl -s "https://api.qoder.com/api/v1/cloud/sessions/$SESSION_ID/threads" \
  -H "Authorization: Bearer $QODER_PAT"
```

子线程可以通过 `POST /api/v1/cloud/sessions/{session_id}/threads/{thread_id}/archive` 归档。当前 CAS 对协调器主线程归档返回 `409`。

## 生命周期

归档 Session：

```bash theme={null}
curl -s -X POST "https://api.qoder.com/api/v1/cloud/sessions/$SESSION_ID/archive" \
  -H "Authorization: Bearer $QODER_PAT"
```

删除 Session：

```bash theme={null}
curl -s -X DELETE "https://api.qoder.com/api/v1/cloud/sessions/$SESSION_ID" \
  -H "Authorization: Bearer $QODER_PAT"
```

删除返回：

```json theme={null}
{
  "id": "sess_019e3bb1e8c171fd9abbb1477ffb84cc",
  "type": "session_deleted"
}
```

cancel 接口返回 `{"id":"...","type":"session","status":"canceling"}`。当存在活跃 turn 需要取消时返回 **202 Accepted**；当 Session 已处于 `idle` 时为幂等 no-op，返回 **200 OK**。

## 多轮对话工作流

Session 支持多轮对话。推荐流程如下：

1. 发送 `user.message` 事件。
2. 监听 SSE 事件流。
3. 等待 `session.status_idle` 事件。
4. 发送下一条 `user.message`。

```bash theme={null}
#!/bin/bash
# 多轮对话示例
BASE_URL="https://api.qoder.com/api/v1/cloud"
SESSION_ID="sess_019e5ce0bf9074b69c3481e93771a522"
HEADERS=(
  -H "Authorization: Bearer $QODER_PAT"
)

# 第一轮：提出需求
curl -s -X POST "$BASE_URL/sessions/$SESSION_ID/events" \
  "${HEADERS[@]}" \
  -H "Content-Type: application/json" \
  -d '{"events": [{"type": "user.message", "content": [{"type": "text", "text": "创建一个 Python Flask 项目脚手架。"}]}]}'

# 等待处理完成...（轮询或监听 SSE）
sleep 30

# 第二轮：追加要求
curl -s -X POST "$BASE_URL/sessions/$SESSION_ID/events" \
  "${HEADERS[@]}" \
  -H "Content-Type: application/json" \
  -d '{"events": [{"type": "user.message", "content": [{"type": "text", "text": "给项目添加单元测试和 CI 配置。"}]}]}'
```

<Note>
  请始终等待 `session.status_idle` 后再发送下一条消息。在 Session 仍处于 `running` 时发消息会返回 HTTP 409。
</Note>

## 最佳实践

1. **版本锁定** — 生产环境始终使用 `{"id": ..., "type": "agent", "version": ...}` 形式创建 Session，避免因 Agent 更新导致行为变化。
2. **元数据标记** — 用 `metadata` 记录业务上下文（任务 ID、触发来源等），便于追溯和调试。
3. **及时取消** — 不再需要的 Session 及时 cancel，释放计算资源。

## 常见问题

**Q: 向 running 状态的 Session 发消息会怎样？**

A: 会返回 **HTTP 409**，`type: "invalid_request_error"`，错误信息为 *"Session is currently processing a turn. Cancel the current turn or wait for completion."*。需要先取消当前轮（cancel）或等待 Session 回到 `idle`，再发送新消息。

**Q: 取消后的 Session 还能继续用吗？**

A: 可以。cancel 后状态从 `canceling` 自动回到 `idle`，Session 保持可用——直接发送下一条 `user.message` 即可继续对话。仅 `archived` 和 `terminated` 是终态。

**Q: 如何获取 Session 的完整对话历史？**

A: 通过 `GET /api/v1/cloud/sessions/{id}/events` 获取该 Session 的所有事件，包括用户消息和 Agent 响应。

**Q: SSE 断线怎么重连？**

A: 重连时在请求头中传入 `Last-Event-ID`，服务端会从该 ID 之后重放事件。

**Q: `GET /api/v1/cloud/environments` 返回空数组？**

A: 请检查你的 Personal Access Token (PAT) 是否具有目标工作区的权限。Environment 的访问范围取决于认证用户的权限。

## API Reference

* [创建 Session](/zh/cloud-agents/api/sessions/create)
* [发送事件](/zh/cloud-agents/api/sessions/send-event)
* [列出事件](/zh/cloud-agents/api/sessions/list-events)
* [事件流](/zh/cloud-agents/api/sessions/stream-events)
* [列出 Session resources](/zh/cloud-agents/api/sessions/list-resources)
* [列出 Session threads](/zh/cloud-agents/api/sessions/list-threads)
* [Session 数据结构](/zh/cloud-agents/api/sessions/schemas)
