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

Session 状态生命周期

Session 是一个状态机。Session 资源上的 status 字段取以下值之一:
状态说明可流转到
idleSession 空闲,可以发送消息runningreschedulingterminated
runningAgent 正在处理 turnidlereschedulingterminated
rescheduling底层运行时正在重新调度,期间 Session 不可用,恢复后回到 idleidleterminated
terminatedSession 已终止(终态)
另外两个生命周期标记不出现在 status 字段中:
  • 已归档(archived):通过非空 archived_at 时间戳标识。status 字段本身不会变成 archived——Session 仍可被读取,但拒绝新事件。
  • cancel 响应POST /api/v1/cloud/sessions/{id}/cancel 接口的响应体始终是固定字面量 "status": "canceling"。这只是响应结构,不是 Session 持久化的 status;turn 中止后 Session 的 status 仍回到 idle
1

创建 → idle

新 Session 进入 idle,等待输入。
2

idle → running

发送 user.message 事件后,状态切换到 running
3

running → idle

本轮完成后回到 idle,可继续下一轮。
4

running → idle(cancel 后)

取消正在执行的 Session 会中断当前 turn,Session 回到 idle。cancel 接口响应体使用固定 "status": "canceling" 字面量,与持久化的状态无关。Session 仍可继续使用。
5

rescheduling

运行时可能临时进入 rescheduling,重新调度完成后会回到 idle
6

archived / terminated(终态)

归档(通过 archived_at)或终止后 Session 永久结束,无法恢复。

Cancel 语义

  • idle Session 调用 cancel:空操作(no-op),返回 HTTP 200,状态保持 idle
  • running Session 调用 cancel:中断 Agent,返回 HTTP 202。状态先变为 canceling,中断完成后回到 idle
  • cancel 后:Session 仍可复用——直接发送下一条 user.message 即可开始新 turn。
# 取消当前 turn
curl -s -X POST "https://api.qoder.com/api/v1/cloud/sessions/$SESSION_ID/cancel" \
  -H "Authorization: Bearer $QODER_PAT"
只有 archivedterminated 是终态。取消后的 Session 总会回到 idle,可以继续接受消息。

向 running Session 发消息(409 错误)

如果向正在 running 的 Session 发送 user.message,API 返回 HTTP 409
{
  "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

使用已有 agentenvironment_id 创建 Session:
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 对象,包含 agentenvironment_idstatusresourcesvault_idsdeployment_idoutcome_evaluationsstatsenvironment_variablesarchived_atcreated_atupdated_at 旧请求字段 environmentdelta_flush_interval_msmemory_store_idsvaults 不支持。environment_variables 已重新启用 — 请求采用 JSON 字符串格式(详见 创建 Session 的字段说明与校验规则)。

创建时挂载资源

通过 resources 数组挂载文件、仓库和 Memory Store:
{
  "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。当前 CAS 创建后追加仅支持 file resource。resource list/get/update/delete 接口可用于查看、轮转 GitHub token 或移除资源。

发送消息

通过 Events API 发送 user.messagecontent 必须是非空 content block 数组:
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.messageuser.interruptuser.tool_confirmationuser.tool_resultuser.custom_tool_resultuser.define_outcomesystem.message

读取事件

使用事件流实时读取:
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 输出 ideventdata。Stream endpoint 支持 Last-Event-ID header 进行断线重连;事件类型 query filter 当前不支持。 如果需要接收增量流式事件,请在创建 Session 时设置 incremental_streaming_enabled: true。开启后,stream 可能在最终完整 agent.message 前输出 agent.message_startagent.content_block_delta 等增量事件。快速验证流程见 增量流式 使用 list endpoint 读取历史和分页:
curl -s "https://api.qoder.com/api/v1/cloud/sessions/$SESSION_ID/events?limit=20&order=desc" \
  -H "Authorization: Bearer $QODER_PAT"
列表响应使用 datanext_page

读取和更新 Sessions

# 获取一个 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_idagent_versiondeployment_idmemory_store_idstatusescreated_at[...] 等过滤。

Threads

Managed-agent Session 可以包含协调器主线程和子线程。Thread endpoint 使用公开 session_thread 结构,不再包含 rolenameagent_idagent_versionstop_reason 等旧字段。
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:
curl -s -X POST "https://api.qoder.com/api/v1/cloud/sessions/$SESSION_ID/archive" \
  -H "Authorization: Bearer $QODER_PAT"
删除 Session:
curl -s -X DELETE "https://api.qoder.com/api/v1/cloud/sessions/$SESSION_ID" \
  -H "Authorization: Bearer $QODER_PAT"
删除返回:
{
  "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
#!/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 配置。"}]}]}'
请始终等待 session.status_idle 后再发送下一条消息。在 Session 仍处于 running 时发消息会返回 HTTP 409。

最佳实践

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

常见问题

Q: 向 running 状态的 Session 发消息会怎样? A: 会返回 HTTP 409type: "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 即可继续对话。仅 archivedterminated 是终态。 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