> ## Documentation Index
> Fetch the complete documentation index at: https://docs.agentfront.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Streaming Protocol

> NDJSON streaming protocol for real-time code execution

The EnclaveJS streaming protocol enables real-time communication between clients and the execution runtime. It uses NDJSON (Newline Delimited JSON) for efficient streaming with optional end-to-end encryption.

## Protocol Overview

```mermaid theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
%%{init: {'theme': 'base', 'themeVariables': { 'primaryColor': '#e8a045', 'primaryTextColor': '#fff', 'primaryBorderColor': '#c78935', 'lineColor': '#c78935', 'secondaryColor': '#f0b865', 'tertiaryColor': '#fff5e6'}}}%%
sequenceDiagram
    participant C as Client
    participant B as Broker
    participant R as Runtime

    C->>B: HTTP POST (execute code)
    B->>R: WebSocket (start session)
    R-->>B: Events
    B-->>C: NDJSON Stream (events)
    Note over C,R: On tool_call
    C->>B: Tool Result
    B->>R: Tool Result
    R-->>B: Continue
    B-->>C: More Events
    R-->>B: Complete
    B-->>C: Final Event
```

## Event Types

### session\_init

Sent when a session starts:

```json theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
{
  "type": "session_init",
  "sessionId": "sess_abc123",
  "timestamp": 1704067200000,
  "payload": {
    "limits": {
      "maxDurationMs": 30000,
      "maxToolCalls": 100
    }
  }
}
```

### stdout

Captured console output:

```json theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
{
  "type": "stdout",
  "sessionId": "sess_abc123",
  "timestamp": 1704067200100,
  "payload": {
    "data": "Processing user: Alice\n"
  }
}
```

### log

Structured log messages:

```json theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
{
  "type": "log",
  "sessionId": "sess_abc123",
  "timestamp": 1704067200150,
  "payload": {
    "level": "info",
    "message": "Tool call completed",
    "data": { "tool": "users:list", "duration": 42 }
  }
}
```

### tool\_call

Request for tool execution:

```json theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
{
  "type": "tool_call",
  "sessionId": "sess_abc123",
  "timestamp": 1704067200200,
  "payload": {
    "callId": "call_xyz789",
    "tool": "users:list",
    "args": { "limit": 10 }
  }
}
```

### tool\_result\_applied

Confirmation that tool result was applied:

```json theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
{
  "type": "tool_result_applied",
  "sessionId": "sess_abc123",
  "timestamp": 1704067200300,
  "payload": {
    "callId": "call_xyz789"
  }
}
```

### heartbeat

Keep-alive message:

```json theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
{
  "type": "heartbeat",
  "sessionId": "sess_abc123",
  "timestamp": 1704067205000,
  "payload": {}
}
```

### final

Session completed:

```json theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
{
  "type": "final",
  "sessionId": "sess_abc123",
  "timestamp": 1704067210000,
  "payload": {
    "result": { "count": 5, "items": [...] },
    "stats": {
      "duration": 10000,
      "toolCallCount": 3,
      "iterationCount": 15
    }
  }
}
```

### error

Execution error:

```json theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
{
  "type": "error",
  "sessionId": "sess_abc123",
  "timestamp": 1704067210000,
  "payload": {
    "code": "TIMEOUT",
    "message": "Execution exceeded 30s timeout"
  }
}
```

## NDJSON Format

Events are sent as newline-delimited JSON:

```
{"type":"session_init","sessionId":"sess_abc123",...}\n
{"type":"stdout","sessionId":"sess_abc123",...}\n
{"type":"tool_call","sessionId":"sess_abc123",...}\n
{"type":"final","sessionId":"sess_abc123",...}\n
```

Benefits:

* **Streaming-friendly** - Parse events as they arrive
* **Memory efficient** - No buffering entire response
* **Simple parsing** - Split by newline, parse each line

## Tool Call Flow

When the runtime needs to call a tool:

```mermaid theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
%%{init: {'theme': 'base', 'themeVariables': { 'primaryColor': '#e8a045', 'primaryTextColor': '#fff', 'primaryBorderColor': '#c78935', 'lineColor': '#c78935', 'secondaryColor': '#f0b865', 'tertiaryColor': '#fff5e6'}}}%%
flowchart TD
    TC1["1. Runtime emits tool_call event"] --> TC2["2. Client/Broker receives and executes tool"]
    TC2 --> TC3["3. Client/Broker sends tool result"]
    TC3 --> TC4["4. Runtime applies result, emits tool_result_applied"]
    TC4 --> TC5["5. Execution continues"]
    style TC1 fill:#e8a045,stroke:#c78935,color:#fff
    style TC2 fill:#f0b865,stroke:#c78935,color:#333
    style TC3 fill:#f0b865,stroke:#c78935,color:#333
    style TC4 fill:#e8a045,stroke:#c78935,color:#fff
    style TC5 fill:#e8a045,stroke:#c78935,color:#fff
```

### Submitting Tool Results

```ts theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
// Via HTTP (when using broker)
POST /sessions/:sessionId/tool-result
{
  "callId": "call_xyz789",
  "result": { "users": [...] }
}

// Via WebSocket (direct to runtime)
{
  "type": "tool_result",
  "callId": "call_xyz789",
  "result": { "users": [...] }
}
```

## End-to-End Encryption

Optional encryption using ECDH key exchange + AES-256-GCM:

### Key Exchange

```
1. Client generates ECDH key pair (P-256)
2. Client sends ClientHello with public key
3. Server generates ECDH key pair
4. Server sends ServerHello with public key
5. Both derive shared secret
6. Session keys derived via HKDF
```

### Encrypted Events

```json theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
{
  "encrypted": true,
  "iv": "base64-nonce",
  "ciphertext": "base64-encrypted-event",
  "tag": "base64-auth-tag"
}
```

### Configuration

```ts theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
const client = new EnclaveClient({
  serverUrl: 'https://broker.example.com',
  encryption: {
    enabled: true,
    curve: 'P-256',
  },
});
```

## Reconnection

The protocol supports reconnection with event replay:

```ts theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
const client = new EnclaveClient({
  reconnection: {
    enabled: true,
    maxAttempts: 5,
    initialDelayMs: 1000,
    maxDelayMs: 30000,
    backoffMultiplier: 2,
  },
});
```

### Sequence Tracking

Events include sequence numbers for ordering:

```json theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
{
  "type": "stdout",
  "seq": 42,
  ...
}
```

On reconnection, the client sends the last received sequence number to resume from that point.

## Event Filtering

Filter events to reduce bandwidth:

```ts theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
// Only receive specific event types
const stream = broker.execute(code, {
  filter: {
    types: ['stdout', 'final', 'error'],
  },
});

// Block noisy events
const stream = broker.execute(code, {
  filter: {
    blockedTypes: ['heartbeat', 'log'],
  },
});
```

## Protocol Constants

| Constant             | Value   | Description             |
| -------------------- | ------- | ----------------------- |
| `PROTOCOL_VERSION`   | `"1.0"` | Protocol version        |
| `HEARTBEAT_INTERVAL` | 5000ms  | Time between heartbeats |
| `DEFAULT_TIMEOUT`    | 30000ms | Default session timeout |

## Related

* [EnclaveJS Overview](/enclave/enclavejs/overview) - Streaming runtime architecture
* [@enclave-vm/types](/enclave/enclavejs/types) - Type definitions
* [@enclave-vm/stream](/enclave/enclavejs/stream) - Stream utilities
