<!-- source-hash: e37a3772ece6c09122bfe5d89ce800e0 -->
Real-time NATS streaming chunk processor hook that converts raw streaming messages into typed message segments, managing stream state, tool execution, and approval workflows.

## Key Components

| Export | Type | Description |
|--------|------|-------------|
| `useRealtimeChunkProcessor` | Hook | Primary hook for processing NATS stream chunks into UI-ready message segments |
| `accumulatorRef` | Internal Ref | Holds a `MessageSegmentAccumulator` instance that tracks and builds segments across chunk events |
| `isInStreamRef` | Internal Ref | Tracks whether a `MESSAGE_START`/`MESSAGE_END` boundary is active |
| `hasEverStreamedRef` | Internal Ref | Distinguishes cold-start vs. resumed-dialog continuation mode |
| `pendingEscalatedRef` | Internal Ref | Tracks escalated (non-display) approval requests awaiting results |

### Handled Chunk Actions

| Action | Behavior |
|--------|----------|
| `message_start` / `message_end` | Opens/closes stream window, resets segment accumulator |
| `text` / `thinking` | Appends to accumulator; uses append mode post-stream |
| `tool_execution` | Routes to accumulator in-stream, or `onToolExecuted` post-stream |
| `approval_request` | Renders inline or escalates based on `displayApprovalTypes` |
| `approval_batch` | Renders batch card or unfolds into legacy cards if `batchApprovalsEnabled = false` |
| `approval_result` | Resolves escalated or inline approvals, updates accumulator status |
| `error` | Parses error detail and emits error segment |

## Usage Example

```typescript
const { processChunk } = useRealtimeChunkProcessor({
  callbacks: {
    onSegmentsUpdate: (segments, opts) => updateMessage(segments, opts),
    onStreamStart: () => setStreaming(true),
    onStreamEnd: () => setStreaming(false),
    onApprove: (requestId) => approveToolCall(requestId),
    onReject: (requestId) => rejectToolCall(requestId),
    onEscalatedApproval: (requestId, data) => notifyTechnician(requestId, data),
    onApprovalResolved: (requestId, status) => syncStatus(requestId, status),
    onError: (error) => console.error(error),
  },
  displayApprovalTypes: ['CLIENT'],
  approvalStatuses: { 'req-123': 'pending' },
  enableThinking: false,
  batchApprovalsEnabled: true,
})

// Feed raw NATS chunks directly
natsSubscription.on('message', (msg) => processChunk(msg.data))
```

> **Note:** `batchApprovalsEnabled` defaults to `true`. Pass `false` to fall back to legacy per-call approval cards. Consumers using `onApprovalResolved` should omit `onSegmentsUpdate` handling for approval results to avoid bubble overwrites during status flips.