Manages the client-side chat state for an AI assistant conversation, handling message streaming, tool approval workflows, and adaptive thinking display via SSE. ## Key Components ### `UseChatOptions` Configuration interface for the hook: - `useMock` / `debugMode` — toggle mock/debug SSE modes - `assistantName` / `assistantAvatar` — customize assistant identity - `streamFn` — override default SSE transport with a custom function - `initialMessages` — seed conversation state (e.g., from `localStorage`) - `onMessagesChange` — persistence callback triggered on every message update ### `useChat(options)` Primary hook returning: | Return Value | Type | Description | |---|---|---| | `messages` | `Message[]` | Full conversation history | | `isTyping` | `boolean` | True until first text chunk arrives | | `isStreaming` | `boolean` | True while SSE stream is active | | `sseError` | `Error \| null` | Stream-level error state | | `sendMessage` | `fn` | Send a user turn, optionally hidden | | `abort` | `fn` | Cancel the active stream | | `reset` | `fn` | Reset SSE state | ### `sendMessage(text, extra?, options?)` Appends a user message, creates an optimistic assistant placeholder, then iterates the SSE stream, handling three segment types: - **`text`** — accumulates into the last assistant message - **`thinking`** — prepended as a thinking card (always before answer text) - **`approval_request`** — renders a tool-approval card with `onApprove`/`onReject` callbacks - **`decision_resolved`** — flips approval card status and appends a receipt to the current turn ## Usage Example ```typescript import { useChat } from './use-chat' function ChatWidget() { const { messages, isTyping, sendMessage, abort } = useChat({ assistantName: 'Mingo', initialMessages: JSON.parse(localStorage.getItem('chat') ?? '[]'), onMessagesChange: (msgs) => localStorage.setItem('chat', JSON.stringify(msgs)), streamFn: myCustomStreamFn, // optional: bypass default SSE }) return (
{messages.map((m) => )} {isTyping && }
) } ``` > **Hidden turns**: Pass `{ hidden: true }` to `sendMessage` for post-approval auto-continuation — the user message is added to LLM context but not rendered in the UI, keeping the visible thread clean.