WebSocket 事件
WebSocket 是 Hashee 入站事件的实时传输通道。本页给完整的连接流程、认证、 所有事件帧定义、SDK 自动处理与你需要关心的字段。
连接
Human WebSocket
GET wss://api.hashee.ai/ws/human升级后5 秒内发送 auth 帧:
{ "type": "auth", "token": "<access_token>" }Agent WebSocket
GET wss://api.hashee.ai/ws/agent?agent_id={agent_id}升级后 5 秒内发:
{ "type": "auth", "agent_id": "{agent_id}", "token": "hsk_..."}认证响应
成功:
{ "type": "auth.ok" }失败:
{ "type": "auth.error", "reason": "invalid_token", "message": "Token expired", "i18n_key": "error.auth.expired"}5 秒未发 auth → 服务端关闭连接。
心跳
服务端每 30 秒发 ping;客户端 90 秒内无 pong → 视为断开。
SDK 自动处理 ping/pong + 重连(指数退避 1s → 30s)。
客户端 → 服务端帧
auth.renew
JWT 5 分钟过期前,先 REST /auth/refresh 拿新 access_token,再走:
{ "type": "auth.renew", "access_token": "<new-jwt>" }不需断开重连。
服务端 → 客户端事件
消息事件
message.new
{ "type": "message.new", "conversation_id": "<uuid>", "message_id": "<uuid>", "sender_id": "<uuid>", "sender_type": "human", "content_type": "text", "encrypted_payload": "<base64 wire envelope>", "conversation_seq": 42, "created_at": "2026-05-15T12:34:56.789Z"}SDK 自动解密 + 调 messageHandler 给你 InboundMessage。
message.ack
后端确认你发的消息已落库:
{ "type": "message.ack", "client_message_id": "<your-ulid>", "message_id": "<server-assigned-uuid>", "conversation_seq": 43}message.read
参与者已读到 seq:
{ "type": "message.read", "conversation_id": "<uuid>", "user_id": "<uuid>", "seq": 42}message.recalled
{ "type": "message.recalled", "message_id": "<uuid>", "conversation_id": "<uuid>", "recalled_by": "<uuid>"}message.status_updated
消息投递状态变更(发送中 → 已发送 → 已送达 → 已读)。
message.pinned
群里置顶消息事件。
流事件
stream.start
Agent 开始流式输出:
{ "type": "stream.start", "conversation_id": "<uuid>", "stream_id": "<uuid>", "client_idempotency_key": "<ulid>"}stream.delta
{ "type": "stream.delta", "conversation_id": "<uuid>", "stream_id": "<uuid>", "encrypted_payload": "<base64 加密的 delta>", "seq": 1}每个 delta 独立加密。SDK 自动累加给客户端 renderer。
stream.done
{ "type": "stream.done", "conversation_id": "<uuid>", "stream_id": "<uuid>", "encrypted_payload": "<base64 完整 final payload>", "message_id": "<uuid>"}带完整加密 payload,用于服务端持久化(未来回看历史时不重放 delta)。
stream.abort
Agent 主动中止:
{ "type": "stream.abort", "stream_id": "<uuid>", "reason": "user_cancelled"}stream.error
{ "type": "stream.error", "stream_id": "<uuid>", "reason": "stream_timeout", "message": "..."}reason 枚举:stream_timeout / orphan_detected / client_offline /
peer_revoked / rate_limited。
关系事件
relation.established
新用户加你 Agent:
{ "type": "relation.established", "payload": { "user_id": "<uuid>", "display_name": "Alice", "avatar_url": "https://...", "language": "zh-CN", "referral_source": "invite_link", "public_key": "<base64 X25519>", "signing_public_key": "<base64 Ed25519>" }}SDK 自动缓存对方公钥。
relation.terminated / relation.revoked
{ "type": "relation.terminated", "payload": { "user_id": "<uuid>", "conversation_id": "<uuid>" } }relation.suspended
平台暂停(违规等):
{ "type": "relation.suspended", "payload": { "user_id": "<uuid>", "reason": "..." } }relation.restored
{ "type": "relation.restored", "payload": { "user_id": "<uuid>" } }Artifact 事件
artifact_response
用户回响 artifact:
{ "type": "artifact_response", "payload": { "conversation_id": "<uuid>", "message_id": "<uuid>", "ref_artifact": "<artifact_id>", "action": "submit", "based_on_revision": 1, "payload": { "name": "My Project" }, "sender_id": "<uuid>", "client_timestamp_ms": 1731200000000 }}artifact_update
Agent 更新已发 artifact 后,所有成员客户端收到:
{ "type": "artifact_update", "payload": { "conversation_id": "<uuid>", "ref_artifact": "<artifact_id>", "revision": 2, "encrypted_payload": "<base64>" }}artifact.expired
{ "type": "artifact.expired", "payload": { "conversation_id": "<uuid>", "artifact_id": "<uuid>" }}Agent 治理事件
agent.governance
仅 WS(不通过 webhook):
{ "type": "agent.governance", "payload": { "agent_template_id": "<uuid>", "governance_status": "suspended", "reason": "Policy violation", "since": "2026-05-15T12:00:00Z" }}suspended / banned → SDK 主动断开。
agent.status
Agent 在线状态变更(owner 视角)。
agent.typing
人类用户的 typing 指示。
agent.capability_changed
{ "type": "agent.capability_changed", "payload": { "agent_id": "<uuid>", "from_version": 6, "to_version": 7, "breaking": true, "user_decision": "pending" /* "accepted" | "rejected" | "pending" */ }}Reaction 事件
reaction.update
{ "type": "reaction.update", "payload": { "message_id": "<uuid>", "reactions": [ { "emoji": "thumbsup", "count": 3, "user_ids": ["<u1>", "<u2>", "<u3>"] } ] }}群组事件
group.updated
{ "type": "group.updated", "payload": { "conversation_id": "<uuid>", "changes": { "name": "新群名" } }}group.member_joined
{ "type": "group.member_joined", "payload": { "group_id": "<uuid>", "user_id": "<uuid>", "joined_at": "..." }}group.member_left
{ "type": "group.member_left", "payload": { "group_id": "<uuid>", "user_id": "<uuid>", "reason": "self_leave" }}reason 枚举:self_leave / kicked / deleted_account。
group.dismissed
{ "type": "group.dismissed", "payload": { "group_id": "<uuid>" } }group.invited (Agent only)
{ "type": "group.invited", "payload": { "group_id": "<uuid>", "inviter_user_id": "<uuid>", "join_token": "<base64>" }}Agent 调 agent.acceptGroupInvite(join_token) / declineGroupInvite(...) 决定。
系统事件
system.message_recalled
{ "type": "system.message_recalled", "payload": { "message_id": "<uuid>" } }system.group_key_rotated
{ "type": "system.group_key_rotated", "payload": { "group_id": "<uuid>", "key_version": 2, "wraps": [ /* per-recipient wraps */ ] }}SDK 透明处理;业务无感。
auth.expiring
{ "type": "auth.expiring", "expires_in_seconds": 60 }提示客户端走 /auth/refresh + auth.renew。
session.invalidated
{ "type": "session.invalidated", "payload": { "reason": "device_removed", "message": "...", "i18n_key": "error.session.invalidated" }}reason 枚举:device_removed / password_changed / protection_password_changed / account_deleted / manual_logout.
error
{ "type": "error", "payload": { "code": "RATE_LIMITED", "message": "Too many requests", "i18n_key": "error.rate_limited", "retry_after_ms": 1000 }}事件投递矩阵
| 事件 | WebSocket | Webhook | Polling |
|---|---|---|---|
message.new | ✓ | ✓ | ✓ |
message.ack | ✓ | ✗ | ✗ |
message.read | ✓ | ✗ | ✗ |
relation.established | ✓ | ✓ | ✓ |
relation.terminated | ✓ | ✓ | ✓ |
relation.suspended | ✓ | ✓ | ✓ |
relation.restored | ✓ | ✓ | ✓ |
artifact_response | ✓ | ✓ | ✓ |
artifact_update | ✓ | ✗ | ✗ |
artifact.expired | ✓ | ✗ | ✗ |
agent.governance | ✓ | ✗ | ✗ |
agent.capability_changed | ✓ | ✓ | ✓ |
reaction.update | ✓ | ✗ | ✗ |
group.updated | ✓ | ✗ | ✗ |
group.member_joined | ✓ | ✓ | ✓ |
group.member_left | ✓ | ✓ | ✓ |
group.dismissed | ✓ | ✓ | ✓ |
group.invited | ✓ | ✓ | ✓ |
system.message_recalled | ✓ | ✗ | ✗ |
system.group_key_rotated | ✓ | ✓ | ✓ |
auth.expiring | ✓ | ✗ | ✗ |
session.invalidated | ✓ | ✗ | ✗ |
error | ✓ | ✗ | ✗ |
Webhook 覆盖业务关键事件;运维 / 实时反馈类事件仅 WS。
SDK 自动处理 vs 你的代码
SDK 自动:
- 心跳 / 重连 / 重订阅
- 解密 / 验签 / 解析 wire envelope
- group key wraps 缓存与轮换
- 消息去重(
client_message_id) - typing 自动续签
你代码处理:
messageHandler— 业务逻辑eventHandler— 关系 / artifact_response / capability_changed 等statusHandler— 监控 / 报警decryptFailureHandler— 偶发解密失败上报
下一步
- SDK 接收消息 —
addMessageHandler详解 - SDK 错误处理 — 重连与幂等
- Webhook 协议 — 等价于 WS 的子集