<!-- source-hash: 246e5605bed712d2ecbfd71d23933d41 -->
Provides the React context and typed interface that supply runtime configuration to the Flamingo/OpenFrame chat panel, decoupling API endpoints, navigation behavior, and identity source from the host environment.

## Key Components

### `ChatRuntime` Interface
The central config shape with three top-level concerns:

| Field | Description |
|---|---|
| `endpoints` | All API URLs: streaming chat, agent approval, slash-commands, attachment upload/view, identity, and optional image proxy |
| `navigation` | Mode (`'host'` or `'embed'`), external URL handler, in-app router callback, and new-tab decision logic |
| `source` | Required string used for `localStorage` namespacing (`mingo-chat-<source>-v1`) |

### `ChatRuntimeContext`
Raw React context (`createContext<ChatRuntime | null>(null)`). Mount via `<ChatRuntimeContext.Provider value={...}>` at your tree root.

### `useChatRuntime()`
Nullable consumer hook. Returns `null` when no provider is mounted — signals unconfigured runtime. Use for optional/graceful-degradation consumers.

### `useRequiredChatRuntime()`
Strict consumer hook used inside chat internals. Throws a descriptive error if called outside a provider. Use this inside the chat panel itself.

## Usage Example

```typescript
// Host (hub) — already handled by <HubRuntimeProvider>
// Embedded app — wire your own provider:

const runtime = useMemo<ChatRuntime>(() => ({
  source: 'my-embedded-app',
  endpoints: {
    chatStreamUrl: 'https://hub.openframe.ai/api/docs/chat',
    approvalToolUrl: 'https://hub.openframe.ai/api/chat/agent/confirm-tool',
    commandsUrl: 'https://hub.openframe.ai/api/docs/commands',
    buildListUrl: (type, ids) => null,
    attachmentUploadUrl: 'https://hub.openframe.ai/api/storage/upload',
    attachmentViewUrlPrefix: 'https://hub.openframe.ai/api/storage/view/chat-attachments/',
    identityUrl: 'https://hub.openframe.ai/api/chat/identity',
  },
  navigation: {
    mode: 'embed',
    defaultContentOrigin: 'https://hub.openframe.ai',
  },
}), [])

return (
  <ChatRuntimeContext.Provider value={runtime}>
    <ChatPanel />
  </ChatRuntimeContext.Provider>
)
```

> **Memoization is required.** Passing a new object reference on every render invalidates downstream `useMemo` consumers across the entire chat tree (slash-commands, nav links, stream factory). Always stabilize with `useMemo` and stable deps.