| title | AEP v1 协议参考 |
|---|---|
| weight | 1 |
| description | Agent Event Protocol v1 完整参考:事件类型、Envelope 格式、背压机制与错误码 |
Agent Event Protocol v1 完整参考文档——事件类型、Envelope 格式、背压机制、错误码
AEP v1(Agent Event Protocol)是 HotPlex Gateway 的 WebSocket 通信协议:
- 传输层:WebSocket,NDJSON(Newline-Delimited JSON)编码
- 通信模式:全双工(Full-Duplex),Client 和 Server 可同时发送消息
- 设计理念:Streaming-first、统一 Envelope、结构化用户交互
- 版本标识:
aep/v1
所有消息共用统一的 Envelope 结构:
{
"version": "aep/v1",
"id": "evt_<uuid>",
"seq": 42,
"priority": "data",
"session_id": "sess_<uuid>",
"timestamp": 1710000000123,
"event": {
"type": "message.delta",
"data": {}
}
}| 字段 | 类型 | 必选 | 说明 |
|---|---|---|---|
version |
string | 是 | 固定 aep/v1 |
id |
string | 是 | 事件唯一标识,UUID v4(evt_ 前缀) |
seq |
int64 | 是 | 单调递增序列号,从 1 开始,per-session 独立空间 |
priority |
string | 否 | "control" 或 "data"(默认) |
session_id |
string | 是 | Session 标识(sess_ 前缀) |
timestamp |
int64 | 是 | Unix 毫秒时间戳 |
event.type |
string | 是 | 事件类型 |
event.data |
object | 是 | 事件载荷 |
control:跳过背压队列,优先发送(如control.reconnect、error、done)data:正常排队,受背压控制(如message.delta、tool_call)
- 仅实际发送的事件消耗 seq(被丢弃的 delta 不递增 seq)
ping/pong的 seq 为 0(不参与序号分配)- Client 不应通过 seq gap 检测丢包——gap 不会出现
WebSocket 连接建立后的第一帧必须是 init,30 秒超时。
{
"type": "init",
"data": {
"version": "aep/v1",
"worker_type": "claude_code",
"session_id": "sess_xxx",
"auth": { "token": "<jwt>" },
"config": {
"model": "claude-sonnet-4-6",
"allowed_tools": ["read_file", "write_file"],
"max_turns": 0,
"work_dir": "/app"
},
"client_caps": {
"supports_delta": true,
"supports_tool_call": true,
"supported_kinds": ["message.delta", "tool_call"]
}
}
}session_id 非空时为 Resume 模式,空时创建新 Session。
{
"type": "input",
"data": {
"content": "请帮我重构 login 函数",
"metadata": {}
}
}Session 处于 RUNNING 时发送 input 会被拒绝(SESSION_BUSY)。
{
"type": "permission_response",
"data": {
"id": "perm_123",
"allowed": true,
"reason": "approved by user"
}
}{
"type": "question_response",
"data": {
"id": "q_<uuid>",
"answers": { "问题文本": "选项标签" }
}
}{
"type": "elicitation_response",
"data": {
"id": "el_<uuid>",
"action": "accept",
"content": { "token": "ghp_xxx" }
}
}action 取值:"accept" | "decline" | "cancel"。
通过 Worker stdio 发送的控制命令,用于在 Agent Turn 过程中查询状态或修改运行时行为。
{
"type": "worker_command",
"data": {
"command": "context_usage",
"args": "",
"extra": {}
}
}WorkerStdioCommand 支持以下命令:
| Command | 说明 |
|---|---|
context_usage |
查询当前 context window 使用情况 |
mcp_status |
查询 MCP 服务器连接状态 |
set_model |
切换 LLM 模型 |
set_permission |
修改工具权限策略 |
skills |
列出可用 Skills |
compact |
压缩上下文历史 |
clear |
清空上下文 |
model |
查询当前模型信息 |
effort |
调整推理努力级别 |
rewind |
回退到指定对话快照 |
commit |
触发代码提交 |
{ "type": "ping", "data": {} }{
"type": "init_ack",
"data": {
"session_id": "sess_xxx",
"state": "created",
"server_caps": {
"protocol_version": "aep/v1",
"supports_resume": true,
"supports_delta": true,
"max_frame_size": 32768
}
}
}错误时 state 为 "deleted",附带 error + code 字段。
三段式流式消息生命周期:
message.start → message.delta* → message.end
message.start:消息元数据(ID、role、content_type)message.delta:增量文本(可被背压丢弃,dropped标记)message.end:消息结束标记
非流式场景的完整消息,向后兼容。流式场景推荐使用三段式。
{ "type": "tool_call", "data": { "id": "call_123", "name": "read_file", "input": {"path": "/app/main.py"} } }
{ "type": "tool_result", "data": { "id": "call_123", "output": "file content...", "error": "" } }Autonomous 模式下为通知性质,Worker 内部执行,Client 无需回传结果。
{ "type": "state", "data": { "state": "running", "message": "context_reset" } }状态集合:created | running | idle | terminated
{
"type": "done",
"data": {
"success": true,
"stats": {
"duration_ms": 5200,
"tool_calls": 3,
"input_tokens": 1000,
"output_tokens": 500,
"total_tokens": 1700,
"model": "claude-sonnet-4-6",
"context_used_percent": 45.2
},
"dropped": false
}
}dropped: true 表示本轮有 message.delta 被丢弃,Client 应以最终完整载荷覆盖渲染。
注意:
stats字段类型为map[string]any,无固定 schema。上表列出的是常见字段,实际返回的字段取决于 Worker 类型和执行结果,可能包含cost_usd、cache_read_tokens等额外信息。
Worker 请求人类介入的结构化交互事件。默认 5 分钟超时自动拒绝(auto-deny)。
reasoning:Agent 思维过程(thinking)step:执行阶段标记(plan/execute/verify)raw:Worker 原始事件透传
{
"type": "context_usage",
"data": {
"total_tokens": 62000,
"max_tokens": 200000,
"percentage": 31,
"categories": [{"name": "system_prompt", "tokens": 4500}]
}
}{
"type": "mcp_status",
"data": {
"servers": [{"name": "github-mcp", "status": "connected"}]
}
}{ "type": "pong", "data": { "state": "idle" } }Client → Server:
| Action | 说明 |
|---|---|
terminate |
终止 Worker,Session → TERMINATED |
delete |
删除 Session + 清理 runtime |
reset |
清空上下文,Session 保持 RUNNING |
gc |
归档会话:终止 Worker,保留历史,可 Resume |
cd |
切换工作目录(创建新 Session 继承原 Session 上下文) |
Server → Client(priority: "control"):
| Action | 说明 |
|---|---|
reconnect |
强制重连(服务器维护、版本升级) |
session_invalid |
Session 失效通知 |
throttle |
降级通知(速率限制建议) |
{ "type": "error", "data": { "code": "WORKER_CRASH", "message": "exit code 139" } }error 后必须跟随 done。
| Code | 说明 |
|---|---|
WORKER_START_FAILED |
Worker 启动失败 |
WORKER_CRASH |
进程崩溃(SIGSEGV 等) |
WORKER_TIMEOUT |
执行超时 |
WORKER_OOM |
内存溢出(exit code 137) |
PROCESS_SIGKILL |
被强制终止 |
WORKER_OUTPUT_LIMIT |
单行输出超限(10MB) |
| Code | 说明 |
|---|---|
SESSION_NOT_FOUND |
Session 不存在 |
SESSION_EXPIRED |
Session 已过期 |
SESSION_BUSY |
正在执行,拒绝新 input |
SESSION_TERMINATED |
Session 已终止 |
SESSION_INVALIDATED |
Session 被失效 |
| Code | 说明 |
|---|---|
INVALID_MESSAGE |
消息格式无效 |
PROTOCOL_VIOLATION |
协议违规 |
VERSION_MISMATCH |
版本不兼容 |
CONFIG_INVALID |
配置校验失败 |
| Code | 说明 |
|---|---|
UNAUTHORIZED |
认证失败 |
AUTH_REQUIRED |
认证缺失 |
INTERNAL_ERROR |
内部错误 |
GATEWAY_OVERLOAD |
过载 |
RATE_LIMITED |
速率限制 |
EXECUTION_TIMEOUT |
Worker 僵死超时 |
RECONNECT_REQUIRED |
服务端要求客户端重连 |
RESUME_RETRY |
Session resume 失败,建议重试 |
NOT_SUPPORTED |
操作不支持 |
TURN_TIMEOUT |
Turn 执行超时 |
Worker 产出过快时,Gateway 使用 bounded channel(默认容量 256)缓冲消息:
| 事件类型 | 背压行为 |
|---|---|
message.delta / raw |
可丢弃(非阻塞 select) |
message / done / error / control |
不可丢弃(阻塞发送) |
priority: "control" |
跳过背压队列,直接发送 |
丢弃的 delta 不消耗 seq,通过 done.dropped 标记通知 Client。
Client Server
| |
|--- init(version, caps) ------>|
| |--- 创建/恢复 Session
|<-- init_ack(session_id) ------|
| |
|--- input(content) ----------->|--- state(running)
| |--- message.start
|<-- message.delta * ------------|--- message.delta
|<-- message.end ---------------|
|<-- done(success) -------------|--- state(idle)
| |
Client ←→ Server
Input Flow: input → [state(running)] → [tool_call → tool_result]* → [message.delta*] → done
Control Flow: control(action) → state(new_state) / error
Interactive: permission_request ←→ permission_response
question_request ←→ question_response
elicitation_request ←→ elicitation_response
Heartbeat: ping ←→ pong
必须支持:init、input、control、ping、init_ack、message.delta、state、error、done、pong
可选扩展:message.start/end、message、tool_call/result、reasoning、step、raw、permission_*、question_*、elicitation_*、context_usage、mcp_status、worker_command