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

# Streaming Transport Policy Configuration in Chappie

> Choose between WebSocket with automatic HTTP/SSE fallback or HTTP/SSE-only transport, and understand replay divergence protection for streaming responses.

Chappie streams responses from the ChatGPT/Codex backend using one of two transports: a WebSocket connection to the Codex WebSocket endpoint, or HTTP Server-Sent Events (SSE). By default Chappie prefers WebSocket for lower first-token latency and switches to HTTP/SSE automatically if WebSocket cannot recover. You can override this behaviour through `ChappieStreamingTransportPolicy`.

## How the default transport works

With the default policy, Chappie opens a WebSocket connection for each streaming request. If the connection drops mid-stream, Chappie attempts to reconnect up to **5 times**. If all reconnection attempts fail, Chappie falls back to HTTP/SSE for the remainder of that session.

When a reconnect succeeds and the server replays previously delivered text, Chappie suppresses the replayed prefix so your UI does not receive duplicate tokens. If the replayed content **diverges** from what was already delivered — meaning the server sends different text for an already-emitted prefix — Chappie stops the stream and throws `ChappieClientError.streamingTransportReplayDiverged` rather than corrupting your conversation output.

## Available transport policies

`ChappieStreamingTransportPolicy` exposes two ready-made static values:

| Policy         | `prefersWebSocket` | `maxWebSocketReconnectionAttempts` | `fallsBackToHTTPSSE` |
| -------------- | ------------------ | ---------------------------------- | -------------------- |
| `.default`     | `true`             | `5`                                | `true`               |
| `.httpSSEOnly` | `false`            | `0`                                | `true`               |

You can also construct a custom policy using the memberwise initialiser:

```swift theme={null}
public init(
    prefersWebSocket: Bool = true,
    maxWebSocketReconnectionAttempts: Int = 5,
    fallsBackToHTTPSSE: Bool = true
)
```

## Forcing HTTP/SSE-only transport

Pass `.httpSSEOnly` when you need deterministic, WebSocket-free transport:

```swift theme={null}
let client = Chappie.client(
    streamingTransportPolicy: .httpSSEOnly
)
```

Via a shared `ChappieConfiguration`:

```swift theme={null}
let config = ChappieConfiguration(
    streamingTransportPolicy: .httpSSEOnly
)

let authSession = Chappie.authSession(configuration: config)
let client = Chappie.client(configuration: config)
```

<Note>
  The default WebSocket transport typically delivers the first streaming token with lower latency than HTTP/SSE. Switch to `.httpSSEOnly` only when WebSocket is unavailable or you need simpler transport semantics for testing.
</Note>

## When to use `.httpSSEOnly`

Use HTTP/SSE-only transport in these situations:

* **Environments with WebSocket restrictions** — corporate networks, certain VPN configurations, or enterprise MDM policies that block WebSocket upgrades.
* **Automated testing** — HTTP/SSE removes WebSocket reconnection state from the equation, making test behaviour more predictable.
* **Debugging transport issues** — isolating whether a problem is WebSocket-specific by confirming the same request works over SSE.

## Handling `streamingTransportReplayDiverged`

`ChappieClientError.streamingTransportReplayDiverged` means a WebSocket reconnect returned text that contradicts what your UI already displayed. The associated string value contains the partial text that was emitted before the divergence was detected.

When you catch this error, re-render the conversation from scratch or show the user an error prompt asking them to retry:

```swift theme={null}
do {
    for try await event in client.stream("Draft a reply.") {
        switch event {
        case .textDelta(let delta):
            appendText(delta)
        case .completed:
            break
        default:
            break
        }
    }
} catch ChappieClientError.streamingTransportReplayDiverged(let partialText) {
    // The partial text shown so far may be inconsistent.
    // Clear the in-progress message and prompt the user to retry.
    clearInProgressMessage()
    showRetryPrompt()
    print("Diverged after: \(partialText)")
}
```

<Tip>
  If you see `streamingTransportReplayDiverged` frequently in production, switch to `.httpSSEOnly` as a mitigation while you investigate whether a proxy or network policy is corrupting WebSocket reconnection payloads.
</Tip>
