跳转到主要内容

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.

Qoder Cloud Agents 使用 Server-Sent Events (SSE) 协议将 Agent 的实时执行状态推送到客户端。你无需轮询——建立一次连接即可持续接收所有事件。

连接 URL

GET https://openapi.qoder.sh/api/v1/cloud/sessions/{session_id}/events/stream
请求头:
Authorization: Bearer $QODER_PAT
Accept: text/event-stream

SSE 格式

每个事件由三行组成,以空行分隔:
id: evt_01abc123
event: agent.message
data: {"content":"Hello, I'm ready to help."}

字段说明
id事件唯一标识,用于断线重连
event事件类型,决定 data 的结构
dataJSON 格式的事件负载

完整事件类型

事件类型含义触发时机data 结构
user.message用户发送消息客户端 POST 事件后{"content": "..."}
user.interrupt用户中断当前执行客户端发送中断事件{}
user.define_outcome用户定义预期结果客户端设定目标{"outcome": "..."}
session.status_rescheduledSession 被调度执行收到消息后开始处理{"status": "rescheduled"}
span.model_request_start模型请求开始Agent 发起 LLM 调用{"model": "...", "span_id": "..."}
agent.thinkingAgent 思考中模型推理过程中{"content": "..."}
agent.messageAgent 回复消息模型产出文本{"content": "...", "delta": true}
session.status_idleSession 进入空闲一轮对话完成{"status": "idle"}
span.model_request_end模型请求结束LLM 调用完成{"span_id": "...", "usage": {...}}
session.errorSession 出错运行时异常{"error": "...", "code": "..."}
terminatedSession 终止Session 被关闭或超时{"reason": "..."}

典型事件生命周期

一次完整的对话轮次,事件按以下顺序触发:
user.message                  ← 用户输入
session.status_rescheduled    ← 调度开始
span.model_request_start      ← 模型请求
agent.thinking                ← 推理中(可选)
agent.message                 ← 回复内容(可能多次 delta)
span.model_request_end        ← 模型完成
session.status_idle           ← 空闲,等待下一轮

断线重连与 after_id

SSE 连接建立后,默认从头重放所有历史事件。若只需增量事件,传入 after_id 参数:
GET /sessions/{session_id}/events/stream?after_id=evt_01abc123
浏览器原生 EventSource 会在断线重连时自动携带 Last-Event-ID 请求头,服务端据此返回增量事件。
长时间保持连接时建议客户端记录最后收到的 id,断线后用 after_id 恢复。

delta_flush_interval_ms

通过查询参数控制 agent.message delta 事件的刷新间隔:
GET /sessions/{session_id}/events/stream?delta_flush_interval_ms=100
默认值为 50ms。增大该值可减少事件频率、降低客户端渲染压力。

curl 示例

curl -N \
  -H "Authorization: Bearer $QODER_PAT" \
  -H "Accept: text/event-stream" \
  "https://openapi.qoder.sh/api/v1/cloud/sessions/ses_abc123/events/stream"
after_id 的增量连接:
curl -N \
  -H "Authorization: Bearer $QODER_PAT" \
  -H "Accept: text/event-stream" \
  "https://openapi.qoder.sh/api/v1/cloud/sessions/ses_abc123/events/stream?after_id=evt_01abc123"

JavaScript EventSource 示例

const url = new URL('https://openapi.qoder.sh/api/v1/cloud/sessions/ses_abc123/events/stream');
// 如需增量:url.searchParams.set('after_id', lastEventId);

const es = new EventSource(url, {
  headers: { 'Authorization': `Bearer ${QODER_PAT}` }
});

es.addEventListener('agent.message', (e) => {
  const data = JSON.parse(e.data);
  console.log('Agent:', data.content);
});

es.addEventListener('session.status_idle', () => {
  console.log('轮次完成,等待下一轮输入');
});

es.addEventListener('session.error', (e) => {
  const data = JSON.parse(e.data);
  console.error('错误:', data.error);
  es.close();
});

es.onerror = () => {
  console.warn('连接断开,浏览器将自动重连');
};

客户端实现建议

  1. 记录 last event id —— 每收到事件就更新,用于重连恢复。
  2. 处理 delta 拼接 —— agent.message 可能以流式 delta 到达,客户端需拼接为完整文本。
  3. 监听 terminated —— 收到后主动关闭连接,不再重连。
  4. 超时重试 —— 若 30 秒无事件,主动断开并重连(避免静默断连)。
  5. 过滤事件 —— 仅监听业务关心的事件类型,忽略 span 级别事件可减少处理开销。

常见问题

Q:连接后收到大量历史事件怎么办? A:传入 after_id 参数,指向最后处理过的事件 ID,服务端只返回该 ID 之后的事件。 Q:SSE 连接会自动关闭吗? A:Session 终止时服务端发送 terminated 事件后关闭连接。空闲超时由 Session 配置决定。 Q:能否用 WebSocket 替代? A:当前仅支持 SSE。SSE 对单向推送场景更轻量,且天然支持断线重连。 Q:delta_flush_interval_ms 设太大会丢事件吗? A:不会丢失,只是批量合并后发送。最终内容完整性不受影响。