<!-- source-hash: 38493d239449552957a80bb746221c21 -->
Defines core constants, enums, types, and utility functions for the Flamingo chat system, covering chat participants, message roles, connection states, and SSE wire shapes.

## Key Components

| Export | Kind | Description |
|--------|------|-------------|
| `CHAT_TYPE` / `ChatType` | Const + Type | Distinguishes `CLIENT_CHAT` from `ADMIN_AI_CHAT` contexts |
| `OWNER_TYPE` / `OwnerType` | Const + Type | Message ownership: `CLIENT`, `ADMIN`, or `ASSISTANT` |
| `MESSAGE_ROLE` / `MessageRole` | Const + Type | Conversation roles: `user`, `assistant`, `error`, `system` |
| `ASSISTANT_TYPE` / `AssistantType` | Const + Type | AI assistants: `fae` (client-facing) and `mingo` (technician-facing) |
| `AUTHOR_TYPE` / `AuthorType` | Const + Type | Full author roster including `user`, `admin`, `fae`, `mingo`, `system` |
| `APPROVAL_STATUS` / `ChatApprovalStatus` | Const + Type | Approval workflow states: `pending`, `approved`, `rejected` |
| `CONNECTION_STATUS` / `ConnectionStatus` | Const + Type | WebSocket/SSE lifecycle states |
| `MessageOwner` | Interface | Identifies who owns a message, with optional user profile fields |
| `buildChatRefKey` | Function | Builds canonical `docType:externalId` keys for `chatRefs` map lookups |
| `isStructuredContent` | Function | Type guard — checks if `MessageContent` is a `MessageSegment[]` |
| `normalizeContent` | Function | Coerces string or segment array to a uniform `MessageSegment[]` |
| `TextEventData` / `ToolExecutionEventData` / `SSEEventData` | Interfaces + Union | Wire shapes for SSE streaming events |
| `QuickAction` | Interface | Shape for quick-reply chip components (`id` + `text`) |

## Usage Example

```typescript
import {
  CHAT_TYPE,
  MESSAGE_ROLE,
  ASSISTANT_TYPE,
  APPROVAL_STATUS,
  CONNECTION_STATUS,
  buildChatRefKey,
  isStructuredContent,
  normalizeContent,
} from './chat.types'

// Route to the correct AI assistant based on chat context
const assistant =
  chatType === CHAT_TYPE.CLIENT ? ASSISTANT_TYPE.FAE : ASSISTANT_TYPE.MINGO

// Build a chatRefs lookup key matching inline [card://ticket:42] markers
const refKey = buildChatRefKey('ticket', '42') // → "ticket:42"

// Normalize incoming content before rendering
const segments = normalizeContent(message.content)
// → always MessageSegment[], safe to iterate

// Check approval before displaying an action
if (approval === APPROVAL_STATUS.PENDING) {
  showApprovalBanner()
}

// Handle SSE connection lifecycle
if (status === CONNECTION_STATUS.RECONNECTING) {
  showReconnectingSpinner()
}
```