ADTP Protocol Specification
The Agent-to-DOM Transfer Protocol (ADTP) is a JSON-based protocol operating over WebSockets. It facilitates real-time bidirectional communication between the client (web application runtime) and the server (orchestration layer & LLM).
Message Envelope Structure
All ADTP messages share a common envelope structure:
{
"type": "MESSAGE_TYPE",
"payload": {
...
},
"meta": {
"id": "msg_f3c8a980-0a56-4b21-827b-fb8ee0b66a9d",
"timestamp": 1706000000000,
"version": "1.0.0"
}
}Sequence Diagrams
1. Connection & Initial Handshake
The client initiates the handshake immediately upon opening the WebSocket connection. The server replies with a session acknowledgment containing a unique session ID.
2. Message Flow & Tool Execution
When the user sends input (either text or voice), the server feeds the input, current context, and active tools into the LLM. If the LLM requests a tool call, the server routes it to the client, awaits the results, and streams back the final response.
Message Types Reference
1. HANDSHAKE_INIT (Client → Server)
Sent by the client to initialize the session parameters.
{
"type": "HANDSHAKE_INIT",
"payload": {
"protocolVersion": "1.0.0",
"capabilities": ["text", "audio", "tools"]
}
}2. HANDSHAKE_ACK (Server → Client)
Sent by the server to confirm connection validation.
{
"type": "HANDSHAKE_ACK",
"payload": {
"sessionId": "ses_9e210bbf",
"protocolVersion": "1.0.0",
"capabilities": ["text", "audio", "tools"]
}
}3. CONTEXT_UPDATE (Client → Server)
Sent dynamically whenever page state, URL, or tools registration changes.
{
"type": "CONTEXT_UPDATE",
"payload": {
"url": "/products/headphones",
"title": "Pro Headphones - Store",
"activeTools": [
{
"name": "add_to_cart",
"description": "Add the currently viewed product to the shopping cart",
"parameters": {
"type": "object",
"properties": {
"quantity": { "type": "number", "minimum": 1 }
},
"required": ["quantity"]
}
}
],
"data": {
"page": "product_detail",
"productId": "pro-headphones",
"price": 149.99
}
}
}4. USER_INPUT (Client → Server)
Carries user messages in either text format or base64 raw PCM audio data.
{
"type": "USER_INPUT",
"payload": {
"modality": "text",
"content": "Add 2 to my cart"
}
}5. TOOL_CALL (Server → Client)
The server requests the client to invoke a local front-end tool.
{
"type": "TOOL_CALL",
"payload": {
"callId": "tc_4892c90",
"name": "add_to_cart",
"args": {
"quantity": 2
}
}
}6. TOOL_RESULT (Client → Server)
The client returns the execution status of a tool.
{
"type": "TOOL_RESULT",
"payload": {
"callId": "tc_4892c90",
"status": "success",
"result": {
"added": true,
"cartTotal": 299.98
}
}
}7. AGENT_RESPONSE (Server → Client)
Streams the text chunk response from the LLM back to the client.
{
"type": "AGENT_RESPONSE",
"payload": {
"chunk": "I have added two Pro Headphones to your cart.",
"done": true
}
}8. SYSTEM_EVENT (Bidirectional)
Reports system alerts, disconnect states, rate limits, or validation errors.
{
"type": "SYSTEM_EVENT",
"payload": {
"kind": "error",
"message": "API key usage limit exceeded."
}
}Connection Troubleshooting: Handshake Timeout
To prevent the client application from stalling in a perpetual connecting state when a WebSocket transport opens but the server fails to respond, DomOSClient implements an automatic Handshake Timeout.
Lifecycle and Mechanics
- Immediately upon opening the network channel (WebSocket or WebRTC DataChannel), the client sends a
HANDSHAKE_INITpacket and starts an internal timer set to5000ms(HANDSHAKE_TIMEOUT_MS). - If a valid
HANDSHAKE_ACKmessage is received from the server, the timer is cleared, and the client transitions to theconnectedstate. - If the timer expires before receiving the
HANDSHAKE_ACKacknowledgment:- The connection state transitions to
error. - A system event error notification is emitted.
- The active WebSocket/DataChannel transport is closed (
close(4000, 'Handshake timeout')) to free up system resources. - The client triggers the configured reconnection delay strategy.
- The connection state transitions to
