> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/Arvo-AI/aurora/llms.txt
> Use this file to discover all available pages before exploring further.

# WebSocket Protocol

> Real-time communication with Aurora's AI agent

# WebSocket Protocol

Aurora uses WebSocket connections for real-time, bidirectional communication with the AI agent. This enables streaming responses, live tool execution updates, and interactive confirmations.

## Connection

### Endpoint

```
ws://localhost:5006
```

(Use `wss://` for production with TLS)

### Authentication

Authentication is handled via the initialization message after connecting.

**Connection Example:**

```javascript theme={null}
const ws = new WebSocket('ws://localhost:5006');

ws.onopen = () => {
  // Send initialization message
  ws.send(JSON.stringify({
    type: 'init',
    user_id: 'user_123'
  }));
};
```

## Message Protocol

All messages follow a consistent JSON structure:

```json theme={null}
{
  "type": "message_type",
  "data": { /* type-specific payload */ },
  "session_id": "optional-session-id"
}
```

## Client → Server Messages

### Initialization

Sent immediately after connection to authenticate the user.

<ParamField path="type" type="string" default="init">
  Message type identifier
</ParamField>

<ParamField path="user_id" type="string" required>
  Authenticated user identifier
</ParamField>

**Example:**

```json theme={null}
{
  "type": "init",
  "user_id": "user_123"
}
```

***

### Chat Query

Send a message to the AI agent.

<ParamField path="query" type="string" required>
  User's message text
</ParamField>

<ParamField path="user_id" type="string" required>
  User identifier
</ParamField>

<ParamField path="session_id" type="string" required>
  Chat session UUID (for context continuity)
</ParamField>

<ParamField path="model" type="string" optional>
  LLM model to use (e.g., "gpt-4", "claude-3-opus")
</ParamField>

<ParamField path="mode" type="string" default="agent">
  Chat mode: `agent` (read-write) or `ask` (read-only)
</ParamField>

<ParamField path="selected_project_id" type="string" optional>
  Active cloud project ID
</ParamField>

<ParamField path="attachments" type="array" default="[]">
  File attachments (images, PDFs, etc.)
</ParamField>

<ParamField path="ui_state" type="object" optional>
  UI preferences to save with session
</ParamField>

<ParamField path="direct_tool_call" type="object" optional>
  Direct tool invocation (bypasses AI decision-making)
</ParamField>

**Example:**

```json theme={null}
{
  "query": "Create a GKE cluster in us-central1",
  "user_id": "user_123",
  "session_id": "550e8400-e29b-41d4-a716-446655440000",
  "model": "gpt-4",
  "mode": "agent",
  "selected_project_id": "my-gcp-project",
  "ui_state": {
    "selectedModel": "gpt-4",
    "selectedMode": "agent",
    "selectedProviders": ["gcp"]
  }
}
```

***

### Control Messages

Control ongoing operations.

<ParamField path="type" type="string" default="control">
  Message type identifier
</ParamField>

<ParamField path="action" type="string" required>
  Control action: `cancel`
</ParamField>

<ParamField path="session_id" type="string" required>
  Session to control
</ParamField>

<ParamField path="user_id" type="string" required>
  User identifier
</ParamField>

**Example (Cancel):**

```json theme={null}
{
  "type": "control",
  "action": "cancel",
  "session_id": "550e8400-e29b-41d4-a716-446655440000",
  "user_id": "user_123"
}
```

**Cancellation Behavior:**

* Stops ongoing AI workflow
* Cancels pending infrastructure confirmations
* Consolidates partial messages
* Saves context for session resumption
* Sends END status to client

***

### Confirmation Response

Respond to infrastructure confirmation requests.

<ParamField path="type" type="string" default="confirmation_response">
  Message type identifier
</ParamField>

<ParamField path="confirmation_id" type="string" required>
  ID of the confirmation request
</ParamField>

<ParamField path="approved" type="boolean" required>
  Whether the action is approved
</ParamField>

<ParamField path="user_id" type="string" required>
  User identifier
</ParamField>

<ParamField path="session_id" type="string" required>
  Session identifier
</ParamField>

**Example:**

```json theme={null}
{
  "type": "confirmation_response",
  "confirmation_id": "conf_abc123",
  "approved": true,
  "user_id": "user_123",
  "session_id": "550e8400-e29b-41d4-a716-446655440000"
}
```

## Server → Client Messages

### Status Messages

Indicate connection and workflow status.

<ResponseField name="type" type="string" default="status">
  Message type
</ResponseField>

<ResponseField name="data" type="object">
  <ResponseField name="status" type="string">
    Status value: `START` or `END`
  </ResponseField>
</ResponseField>

<ResponseField name="isComplete" type="boolean" optional>
  Whether workflow is complete (only for END)
</ResponseField>

**Example (Start):**

```json theme={null}
{
  "type": "status",
  "data": {
    "status": "START"
  }
}
```

**Example (End):**

```json theme={null}
{
  "type": "status",
  "data": {
    "status": "END"
  },
  "isComplete": true,
  "session_id": "550e8400-e29b-41d4-a716-446655440000"
}
```

***

### Message Chunks

Streamed response text from the AI agent.

<ResponseField name="type" type="string" default="message">
  Message type
</ResponseField>

<ResponseField name="data" type="object">
  <ResponseField name="text" type="string">
    Text content (single token or sentence)
  </ResponseField>

  <ResponseField name="is_chunk" type="boolean" default={true}>
    Whether this is a streaming chunk
  </ResponseField>

  <ResponseField name="is_complete" type="boolean" default={false}>
    Whether the message is complete
  </ResponseField>

  <ResponseField name="streaming" type="boolean" default={true}>
    Whether streaming is active
  </ResponseField>
</ResponseField>

<ResponseField name="session_id" type="string">
  Associated session ID
</ResponseField>

**Example:**

```json theme={null}
{
  "type": "message",
  "data": {
    "text": "I'll create a GKE cluster ",
    "is_chunk": true,
    "is_complete": false,
    "streaming": true
  },
  "session_id": "550e8400-e29b-41d4-a716-446655440000"
}
```

**Streaming Behavior:**

* Text is sent incrementally as LLM generates it
* Chunks are split at sentence boundaries for smooth display
* Multiple chunks combine to form complete messages
* Large chunks (>100 chars) are automatically split

***

### Tool Call Events

Notify client of tool invocations.

<ResponseField name="type" type="string" default="tool_call">
  Message type
</ResponseField>

<ResponseField name="data" type="object">
  <ResponseField name="tool_name" type="string">
    Name of the tool being called
  </ResponseField>

  <ResponseField name="input" type="object">
    Tool parameters
  </ResponseField>

  <ResponseField name="status" type="string">
    Tool execution status: `running`, `success`, `error`
  </ResponseField>

  <ResponseField name="timestamp" type="string">
    ISO 8601 timestamp
  </ResponseField>

  <ResponseField name="tool_call_id" type="string">
    Unique identifier for this tool call
  </ResponseField>

  <ResponseField name="output" type="string" optional>
    Tool execution result (when complete)
  </ResponseField>
</ResponseField>

**Example:**

```json theme={null}
{
  "type": "tool_call",
  "data": {
    "tool_name": "gcp_compute",
    "input": {
      "action": "create_gke_cluster",
      "cluster_name": "prod-cluster",
      "region": "us-central1"
    },
    "status": "running",
    "timestamp": "2024-03-15T10:30:00Z",
    "tool_call_id": "call_abc123"
  },
  "session_id": "550e8400-e29b-41d4-a716-446655440000"
}
```

***

### Tool Result Events

Report tool execution results.

<ResponseField name="type" type="string" default="tool_result">
  Message type
</ResponseField>

<ResponseField name="data" type="object">
  <ResponseField name="tool_name" type="string">
    Tool that was executed
  </ResponseField>

  <ResponseField name="result" type="any">
    Tool execution result (structure varies by tool)
  </ResponseField>

  <ResponseField name="session_id" type="string">
    Associated session
  </ResponseField>
</ResponseField>

***

### Confirmation Requests

Request user approval for infrastructure changes.

<ResponseField name="type" type="string" default="confirmation_request">
  Message type
</ResponseField>

<ResponseField name="data" type="object">
  <ResponseField name="confirmation_id" type="string">
    Unique confirmation identifier
  </ResponseField>

  <ResponseField name="action" type="string">
    Action requiring approval
  </ResponseField>

  <ResponseField name="details" type="object">
    Details about the proposed change
  </ResponseField>

  <ResponseField name="resources" type="array">
    Resources that will be created/modified
  </ResponseField>
</ResponseField>

***

### Usage Info

API cost tracking information.

<ResponseField name="type" type="string" default="usage_info">
  Message type
</ResponseField>

<ResponseField name="data" type="object">
  <ResponseField name="total_cost" type="number">
    Total API cost in USD (rounded to 2 decimals)
  </ResponseField>
</ResponseField>

**Example:**

```json theme={null}
{
  "type": "usage_info",
  "data": {
    "total_cost": 0.15
  }
}
```

***

### Error Messages

<ResponseField name="type" type="string" default="error">
  Message type
</ResponseField>

<ResponseField name="data" type="object">
  <ResponseField name="text" type="string">
    Error message
  </ResponseField>

  <ResponseField name="severity" type="string" optional>
    Error severity: `error`, `warning`
  </ResponseField>

  <ResponseField name="code" type="string" optional>
    Error code (e.g., "READ\_ONLY\_MODE")
  </ResponseField>

  <ResponseField name="session_id" type="string" optional>
    Associated session
  </ResponseField>
</ResponseField>

**Example:**

```json theme={null}
{
  "type": "error",
  "data": {
    "text": "Failed to create cluster: insufficient permissions",
    "severity": "error",
    "session_id": "550e8400-e29b-41d4-a716-446655440000"
  }
}
```

## Rate Limiting

WebSocket connections are rate-limited:

* **Rate:** 5 messages per 60 seconds per client
* **Enforcement:** Token bucket algorithm
* **Response:** Error message when limit exceeded

```json theme={null}
{
  "type": "error",
  "data": {
    "text": "Rate limit exceeded. Please wait and try again."
  }
}
```

## Connection Lifecycle

1. **Connect** - Establish WebSocket connection
2. **Initialize** - Send init message with user\_id
3. **Ready** - Receive START status
4. **Chat** - Exchange messages and receive responses
5. **Tools** - Receive tool call events during execution
6. **Complete** - Receive END status when done
7. **Disconnect** - Close connection gracefully

## Best Practices

### Connection Management

* Implement automatic reconnection with exponential backoff
* Handle connection drops gracefully
* Send init message immediately after connecting
* Monitor connection state and show status to user

### Message Handling

* Buffer message chunks for display
* Update UI progressively as chunks arrive
* Show tool execution status in real-time
* Handle out-of-order messages by session\_id

### Error Recovery

* Retry failed messages with exponential backoff
* Show connection errors to user
* Allow manual retry of failed operations
* Preserve unsent messages across reconnections

### Performance

* Keep WebSocket connection alive between messages
* Reuse connections for multiple sessions
* Close connections after extended inactivity
* Monitor memory usage from buffered chunks

## Example Client

```javascript theme={null}
class AuroraWebSocket {
  constructor(url, userId) {
    this.url = url;
    this.userId = userId;
    this.ws = null;
    this.messageHandlers = {};
  }

  connect() {
    this.ws = new WebSocket(this.url);
    
    this.ws.onopen = () => {
      console.log('Connected to Aurora');
      this.send({ type: 'init', user_id: this.userId });
    };
    
    this.ws.onmessage = (event) => {
      const message = JSON.parse(event.data);
      const handler = this.messageHandlers[message.type];
      if (handler) handler(message);
    };
    
    this.ws.onerror = (error) => {
      console.error('WebSocket error:', error);
    };
    
    this.ws.onclose = () => {
      console.log('Disconnected from Aurora');
      // Implement reconnection logic here
    };
  }

  send(message) {
    if (this.ws && this.ws.readyState === WebSocket.OPEN) {
      this.ws.send(JSON.stringify(message));
    }
  }

  on(type, handler) {
    this.messageHandlers[type] = handler;
  }

  sendChat(query, sessionId, options = {}) {
    this.send({
      query,
      user_id: this.userId,
      session_id: sessionId,
      model: options.model || 'gpt-4',
      mode: options.mode || 'agent',
      ...options
    });
  }

  cancel(sessionId) {
    this.send({
      type: 'control',
      action: 'cancel',
      session_id: sessionId,
      user_id: this.userId
    });
  }
}

// Usage
const aurora = new AuroraWebSocket('ws://localhost:5006', 'user_123');

aurora.on('message', (msg) => {
  console.log('Received:', msg.data.text);
});

aurora.on('tool_call', (msg) => {
  console.log('Tool call:', msg.data.tool_name);
});

aurora.on('status', (msg) => {
  if (msg.data.status === 'END') {
    console.log('Workflow complete');
  }
});

aurora.connect();

// Send a message
aurora.sendChat('Create a GKE cluster', 'session-123');
```
