Chuyển tới nội dung chính

Message Reference — Tất Cả Message Types

File này là tham chiếu đầy đủ cho mọi message type trong WebSocket protocol. Mỗi type có ví dụ JSON hoàn chỉnh.


Mục Lục


Client → Server


auth

Xác thực sau khi nhận connected. Phải gửi trong vòng 10 giây.

{
"type": "auth",
"token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoiMTIzIn0.signature"
}

chat

Bắt đầu một lượt hội thoại mới. Nếu không có session_id, server sẽ tạo mới.

{
"type": "chat",
"message": "Phân tích cổ phiếu VNM",
"session_id": "abc-123",
"model": "claude-sonnet-4-6",
"agent_id": "financial_agent",
"content_urls": [
"https://example.com/bao-cao.pdf"
],
"agent_config": {
"display_mode": "agent"
}
}

Tối giản (tạo session mới):

{
"type": "chat",
"message": "Phân tích cổ phiếu VNM"
}

subscribe

Đăng ký nhận events của session. Dùng khi reconnect hoặc load lại.

{
"type": "subscribe",
"session_id": "abc-123",
"last_event_id": "01HXYZ100"
}

Không có last_event_id (nhận toàn bộ):

{
"type": "subscribe",
"session_id": "abc-123"
}

stop

Dừng agent đang chạy cho session.

{
"type": "stop",
"session_id": "abc-123"
}

push_message

Xếp hàng message khi agent đang bận. Agent xử lý sau khi lượt hiện tại xong.

{
"type": "push_message",
"session_id": "abc-123",
"message": "Cũng phân tích thêm HPG nhé"
}

approval — Phê Duyệt Tool

Phê duyệt hoặc từ chối tool calls trong approval_request. Dùng field decisions.

Approve:

{
"type": "approval",
"session_id": "abc-123",
"approval_key": "abc-123_1",
"decisions": [
{
"type": "approve"
}
]
}

Reject:

{
"type": "approval",
"session_id": "abc-123",
"approval_key": "abc-123_1",
"decisions": [
{
"type": "reject"
}
]
}

Edit (sửa arguments):

{
"type": "approval",
"session_id": "abc-123",
"approval_key": "abc-123_1",
"decisions": [
{
"type": "edit",
"edited_action": {
"name": "execute_trade",
"args": {
"symbol": "VNM",
"quantity": 50,
"side": "buy"
}
}
}
]
}

Nhiều actions:

{
"type": "approval",
"session_id": "abc-123",
"approval_key": "abc-123_1",
"decisions": [
{
"type": "approve"
},
{
"type": "reject"
}
],
"user_edit_content": "Chỉ approve cái đầu tiên thôi nhé"
}

approval — Trả Lời Câu Hỏi

Dành riêng cho ask_user_question. Dùng field answers, không dùng decisions.

{
"type": "approval",
"session_id": "abc-123",
"approval_key": "abc-123_1",
"answers": [
{
"id": "q1",
"answer": "Tăng trưởng"
},
{
"id": "q2",
"answer": "500"
}
]
}

ping (Client)

Client có thể chủ động gửi ping để kiểm tra kết nối.

{
"type": "ping"
}

pong (Client)

Phản hồi khi nhận ping từ server. Bắt buộc — không gửi pong sẽ bị ngắt kết nối sau 2 lần miss.

{
"type": "pong"
}

Server → Client (Control)


connected

Gửi ngay khi kết nối WebSocket thành công. Client phải gửi auth ngay sau đây.

{
"type": "connected",
"sid": "550e8400-e29b-41d4-a716-446655440000",
"ping_interval": 25000,
"ping_timeout": 20000,
"max_payload": 2097152
}
FieldMô tả
sidConnection ID (dùng để debug)
ping_intervalServer gửi ping mỗi 25000ms
ping_timeoutClient phải pong trong 20000ms
max_payloadKích thước message tối đa (2MB)

auth_ok

Xác thực thành công. Sau đây có thể gửi chat, subscribe, ...

{
"type": "auth_ok"
}

subscribed (running)

Task đã bắt đầu hoặc đang chạy. Server sẽ stream events ngay sau đây.

{
"type": "subscribed",
"session_id": "abc-123",
"status": "running"
}

subscribed (completed)

Session đã hoàn thành. Server sẽ replay events còn thiếu rồi dừng.

{
"type": "subscribed",
"session_id": "abc-123",
"status": "completed"
}

message_queued

Message đã được xếp hàng chờ xử lý (agent đang bận).

{
"type": "message_queued",
"session_id": "abc-123"
}

session_renamed

Server tự động đặt tên session bằng LLM (Gemini 2.5 Flash Lite) dựa trên tin nhắn đầu tiên của người dùng. Gửi sau khi LLM generate xong (~1-2 giây sau tin nhắn đầu tiên).

{
"type": "session_renamed",
"session_id": "abc-123",
"session_name": "Phân tích cổ phiếu VNM",
"auto": true
}
FieldMô tả
session_idID của session được đổi tên
session_nameTên mới do LLM tạo (tối đa 100 ký tự, viết hoa chữ cái đầu, cùng ngôn ngữ với tin nhắn user)
autoLuôn true — đây là auto-rename, không phải user đổi tên thủ công
thông tin
  • Chỉ trigger một lần duy nhất cho mỗi session (dedup bằng Redis lock)
  • Nếu user đã đổi tên thủ công trước khi LLM xong → auto-rename bị hủy
  • Client nên cập nhật session_name trong danh sách sessions khi nhận event này

error

Lỗi protocol hoặc nghiệp vụ. Không phải lỗi từ agent (lỗi agent dùng terminal_error block).

{
"type": "error",
"code": "SESSION_NOT_FOUND",
"message": "Session not found or no active stream"
}

Tất cả error codes:

codeKhi nào
INVALID_JSONMessage không phải JSON hợp lệ
UNKNOWN_TYPEtype không xác định
EMPTY_MESSAGEchat không có message
MISSING_SESSION_IDsubscribe không có session_id
SESSION_NOT_FOUNDSession không tồn tại hoặc hết TTL
SESSION_NOT_RUNNINGstop/push_message khi không có task
TASK_START_FAILEDLỗi nội bộ khi start task

ping (Server)

Server gửi mỗi 25 giây. Client phải trả pong trong 20 giây.

{
"type": "ping"
}

pong (Server)

Phản hồi khi client gửi ping.

{
"type": "pong"
}

Server → Client (Agent Output)

Các events này được stream trong phạm vi một lượt agent trả lời.


message_start

Event đầu tiên của mỗi lượt. Bắt đầu nhận các content blocks.

{
"type": "message_start",
"session_id": "abc-123",
"timestamp": 1710000000.123,
"display_mode": "agent",
"is_new_session_from_share": false,
"message_id": "msg-uuid-001"
}

message_delta

Báo lý do kết thúc lượt, gửi trước message_stop.

{
"type": "message_delta",
"delta": {
"stop_reason": "end_turn"
}
}

message_stop

Event cuối cùng của lượt. Lượt đã hoàn toàn kết thúc.

{
"type": "message_stop",
"duration_ms": 3420,
"message_id": "msg-uuid-001"
}

content_block_startthinking

Bắt đầu block suy luận của AI. Chỉ có khi display_mode: "agent".

{
"type": "content_block_start",
"index": 0,
"content_block": {
"type": "thinking",
"thinking": "",
"subagent": null,
"parent_tool_use_id": null
},
"message_id": "msg-uuid-001"
}

content_block_starttext

Bắt đầu block văn bản trả lời.

{
"type": "content_block_start",
"index": 3,
"content_block": {
"type": "text",
"text": "",
"subagent": null,
"parent_tool_use_id": null,
"is_part": false
},
"message_id": "msg-uuid-001"
}

content_block_starttool_use

Agent gọi một công cụ. Input đã có sẵn trong content_block.input. Không có delta.

{
"type": "content_block_start",
"index": 1,
"content_block": {
"type": "tool_use",
"id": "toolu_01XyzAbc",
"name": "search_stock",
"tool_use_id": "toolu_01XyzAbc",
"tool_content_message": "Tìm kiếm cổ phiếu",
"input": {
"symbol": "VNM"
},
"subagent": null,
"parent_tool_use_id": null
},
"message_id": "msg-uuid-001"
}

content_block_starttool_result

Kết quả sau khi tool thực thi xong. Nội dung đã có sẵn trong content_block.content. Không có delta.

{
"type": "content_block_start",
"index": 2,
"content_block": {
"type": "tool_result",
"tool_use_id": "toolu_01XyzAbc",
"name": "search_stock",
"status": "success",
"content": "VNM - Vinamilk\nGiá: 82,000 VND\nThay đổi: -1.2%\nKhối lượng: 1.2M",
"artifact": null,
"subagent": null,
"parent_tool_use_id": null
},
"message_id": "msg-uuid-001"
}

Tool thất bại:

{
"type": "content_block_start",
"index": 2,
"content_block": {
"type": "tool_result",
"tool_use_id": "toolu_01XyzAbc",
"name": "search_stock",
"status": "error",
"content": "Không tìm thấy mã cổ phiếu: XYZ",
"artifact": null
}
}

content_block_startfile_processing

Bắt đầu xử lý file đính kèm. Luôn là block đầu tiên (index 0).

{
"type": "content_block_start",
"index": 0,
"content_block": {
"type": "file_processing",
"status": "processing",
"files": [
{
"url": "https://example.com/bao-cao-tai-chinh.pdf"
}
]
},
"message_id": "msg-uuid-001"
}

content_block_startapproval_request

Agent cần người dùng phê duyệt trước khi thực thi tool. Dữ liệu chi tiết đến qua content_block_delta.

{
"type": "content_block_start",
"index": 4,
"content_block": {
"type": "approval_request",
"approval_key": "abc-123_1"
},
"message_id": "msg-uuid-001"
}

content_block_startapproval_result

Kết quả sau khi người dùng đã quyết định. Quyết định đến qua content_block_delta.

{
"type": "content_block_start",
"index": 5,
"content_block": {
"type": "approval_result",
"approval_key": "abc-123_1"
},
"message_id": "msg-uuid-001"
}

content_block_startapproval_timeout

Người dùng không phản hồi trong thời gian quy định. Agent tự reject.

{
"type": "content_block_start",
"index": 5,
"content_block": {
"type": "approval_timeout",
"approval_key": "abc-123_1"
},
"message_id": "msg-uuid-001"
}

content_block_deltathinking_delta

Nội dung suy luận dần dần. Nối tất cả delta.thinking để có nội dung đầy đủ.

{
"type": "content_block_delta",
"index": 0,
"delta": {
"type": "thinking_delta",
"thinking": "Tôi cần tra giá cổ phiếu VNM trước khi phân tích..."
},
"message_id": "msg-uuid-001"
}

content_block_deltatext_delta

Nội dung văn bản dần dần. Nối tất cả delta.text để có nội dung đầy đủ.

{
"type": "content_block_delta",
"index": 3,
"delta": {
"type": "text_delta",
"text": "Cổ phiếu **VNM** đang giao dịch ở mức "
},
"message_id": "msg-uuid-001"
}

content_block_deltatext_delta (terminal_user_stopped)

Block text bình thường nhưng có extras.block_subtype = "user_stopped". Client phải đổi block.type thành "terminal_user_stopped".

{
"type": "content_block_delta",
"index": 4,
"delta": {
"type": "text_delta",
"text": "Người dùng đã dừng cuộc trò chuyện. Gửi tin nhắn mới để tiếp tục",
"extras": {
"block_subtype": "user_stopped"
}
},
"message_id": "msg-uuid-001"
}

content_block_deltatext_delta (terminal_error)

Block text bình thường nhưng có extras.block_subtype = "error". Client phải đổi block.type thành "terminal_error".

{
"type": "content_block_delta",
"index": 4,
"delta": {
"type": "text_delta",
"text": "Đã xảy ra lỗi. Vui lòng thử lại.",
"extras": {
"block_subtype": "error",
"code": "LLM_ERROR",
"can_retry": true,
"error_type": "terminal",
"details": {
"error": "Rate limit exceeded"
}
}
},
"message_id": "msg-uuid-001"
}

Các giá trị code:

codeNguyên nhân
LLM_ERRORLỗi gọi LLM (rate limit, timeout, ...)
AGENT_ERRORLỗi logic agent
APPROVAL_TIMEOUTHết thời gian chờ phê duyệt

content_block_delta — file_processing status

Cập nhật trạng thái xử lý file.

{
"type": "content_block_delta",
"index": 0,
"delta": {
"status": "completed",
"message": "Processed 1 file"
},
"message_id": "msg-uuid-001"
}

Các giá trị status: "processing""completed" hoặc "error".


content_block_delta — approval_request data

Dữ liệu chi tiết của approval_request. Chứa danh sách actions cần phê duyệt.

Tool call thông thường:

{
"type": "content_block_delta",
"index": 4,
"delta": {
"action_requests": [
{
"name": "execute_trade",
"args": {
"symbol": "VNM",
"quantity": 100,
"side": "buy",
"price": 82000
},
"tool_use_id": "toolu_01XyzAbc"
}
],
"review_configs": [
{
"require_approval": true
}
],
"timeout_seconds": 300
},
"message_id": "msg-uuid-001"
}

ask_user_question:

{
"type": "content_block_delta",
"index": 4,
"delta": {
"action_requests": [
{
"name": "ask_user_question",
"args": {
"questions": [
{
"id": "q1",
"question": "Chiến lược đầu tư?",
"type": "select",
"options": [
"Tăng trưởng",
"Phòng thủ"
]
},
{
"id": "q2",
"question": "Số tiền (triệu VND)?",
"type": "text"
}
]
}
}
],
"review_configs": [
{
"require_approval": true
}
],
"timeout_seconds": 600
},
"message_id": "msg-uuid-001"
}

content_block_delta — approval_result decisions

Kết quả quyết định của người dùng.

{
"type": "content_block_delta",
"index": 5,
"delta": {
"decisions": [
{
"type": "approve"
}
]
},
"message_id": "msg-uuid-001"
}

content_block_stop

Kết thúc một block. Không có thêm delta cho block này.

{
"type": "content_block_stop",
"index": 0,
"message_id": "msg-uuid-001"
}

Block text cuối cùng của lượt (câu trả lời):

{
"type": "content_block_stop",
"index": 3,
"is_final": true,
"message_id": "msg-uuid-001"
}

is_final: true chỉ xuất hiện trên block text cuối cùng — xác nhận đây là câu trả lời hoàn chỉnh.


Ví Dụ Luồng Hoàn Chỉnh

Luồng Bình Thường (Có Tool Call)

{ "type": "message_start", "session_id": "abc-123", "timestamp": 1710000000.0, "display_mode": "agent", "message_id": "msg-001" }
{ "type": "content_block_start", "index": 0, "content_block": { "type": "thinking", "thinking": "" }, "message_id": "msg-001" }
{ "type": "content_block_delta", "index": 0, "delta": { "type": "thinking_delta", "thinking": "Cần tra giá VNM." }, "message_id": "msg-001" }
{ "type": "content_block_stop", "index": 0, "message_id": "msg-001" }
{ "type": "content_block_start", "index": 1, "content_block": { "type": "tool_use", "id": "toolu_01", "name": "search_stock", "tool_use_id": "toolu_01", "tool_content_message": "Tìm kiếm", "input": { "symbol": "VNM" } }, "message_id": "msg-001" }
{ "type": "content_block_stop", "index": 1, "message_id": "msg-001" }
{ "type": "content_block_start", "index": 2, "content_block": { "type": "tool_result", "tool_use_id": "toolu_01", "name": "search_stock", "status": "success", "content": "VNM: 82,000 VND (-1.2%)" }, "message_id": "msg-001" }
{ "type": "content_block_stop", "index": 2, "message_id": "msg-001" }
{ "type": "content_block_start", "index": 3, "content_block": { "type": "text", "text": "" }, "message_id": "msg-001" }
{ "type": "content_block_delta", "index": 3, "delta": { "type": "text_delta", "text": "Cổ phiếu VNM đang ở 82,000 VND, giảm 1.2%." }, "message_id": "msg-001" }
{ "type": "content_block_stop", "index": 3, "is_final": true, "message_id": "msg-001" }
{ "type": "message_delta", "delta": { "stop_reason": "end_turn" } }
{ "type": "message_stop", "duration_ms": 2840, "message_id": "msg-001" }

Luồng User Dừng

{ "type": "message_start", "session_id": "abc-123", "timestamp": 1710000000.0, "display_mode": "agent", "message_id": "msg-002" }
{ "type": "content_block_start", "index": 0, "content_block": { "type": "tool_use", "id": "toolu_02", "name": "get_financials", "tool_use_id": "toolu_02", "input": { "symbol": "VNM" } }, "message_id": "msg-002" }
{ "type": "content_block_stop", "index": 0, "message_id": "msg-002" }

... (user gửi lệnh stop) ...

{ "type": "content_block_start", "index": 1, "content_block": { "type": "text", "text": "" }, "message_id": "msg-002" }
{ "type": "content_block_delta", "index": 1, "delta": { "type": "text_delta", "text": "Người dùng đã dừng cuộc trò chuyện. Gửi tin nhắn mới để tiếp tục", "extras": { "block_subtype": "user_stopped" } }, "message_id": "msg-002" }
{ "type": "content_block_stop", "index": 1, "message_id": "msg-002" }
{ "type": "message_delta", "delta": { "stop_reason": "end_turn" } }
{ "type": "message_stop", "duration_ms": 1200, "message_id": "msg-002" }

Luồng Phê Duyệt Tool

{ "type": "message_start", "session_id": "abc-123", "timestamp": 1710000000.0, "display_mode": "agent", "message_id": "msg-003" }
{ "type": "content_block_start", "index": 0, "content_block": { "type": "tool_use", "id": "toolu_03", "name": "execute_trade", "tool_use_id": "toolu_03", "input": { "symbol": "VNM", "quantity": 100, "side": "buy" } }, "message_id": "msg-003" }
{ "type": "content_block_stop", "index": 0, "message_id": "msg-003" }
{ "type": "content_block_start", "index": 1, "content_block": { "type": "approval_request", "approval_key": "abc-123_1" }, "message_id": "msg-003" }
{ "type": "content_block_delta", "index": 1, "delta": { "action_requests": [{ "name": "execute_trade", "args": { "symbol": "VNM", "quantity": 100 }, "tool_use_id": "toolu_03" }], "review_configs": [{ "require_approval": true }], "timeout_seconds": 300 }, "message_id": "msg-003" }
{ "type": "content_block_stop", "index": 1, "message_id": "msg-003" }

... (client gửi approval với decisions: approve) ...

{ "type": "content_block_start", "index": 2, "content_block": { "type": "approval_result", "approval_key": "abc-123_1" }, "message_id": "msg-003" }
{ "type": "content_block_delta", "index": 2, "delta": { "decisions": [{ "type": "approve" }] }, "message_id": "msg-003" }
{ "type": "content_block_stop", "index": 2, "message_id": "msg-003" }
{ "type": "content_block_start", "index": 3, "content_block": { "type": "tool_result", "tool_use_id": "toolu_03", "name": "execute_trade", "status": "success", "content": "Lệnh mua 100 cổ VNM tại 82,000 VND đã được thực hiện" }, "message_id": "msg-003" }
{ "type": "content_block_stop", "index": 3, "message_id": "msg-003" }
{ "type": "content_block_start", "index": 4, "content_block": { "type": "text", "text": "" }, "message_id": "msg-003" }
{ "type": "content_block_delta", "index": 4, "delta": { "type": "text_delta", "text": "Đã thực hiện lệnh mua thành công." }, "message_id": "msg-003" }
{ "type": "content_block_stop", "index": 4, "is_final": true, "message_id": "msg-003" }
{ "type": "message_delta", "delta": { "stop_reason": "end_turn" } }
{ "type": "message_stop", "duration_ms": 5200, "message_id": "msg-003" }