# @hiyve/react-intelligence

AI intelligence, meeting summaries, alerts, scheduling, and sentiment analysis components for Hiyve.

## Installation

```bash
npx @hiyve/cli login
npm install @hiyve/react-intelligence
```

## Quick Start

`CloudProvider` connects your app to the Hiyve Cloud AI service. Provide a `generateCloudToken` callback that fetches a cloud token from your backend, and the SDK handles authentication and automatic token refresh:

```tsx
import { CloudProvider, AIAssistant } from '@hiyve/react-intelligence';
import { HiyveProvider } from '@hiyve/react';

async function generateCloudToken({ userId }: { userId: string }) {
  const res = await fetch('/api/generate-cloud-token', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ userId }),
  });
  const { cloudToken, environment } = await res.json();
  return { cloudToken, environment };
}

function App() {
  return (
    <HiyveProvider generateRoomToken={generateRoomToken}>
      <CloudProvider generateCloudToken={generateCloudToken}>
        <MeetingRoom />
      </CloudProvider>
    </HiyveProvider>
  );
}

function MeetingRoom() {
  return <AIAssistant roomName="my-room" />;
}
```

When `IdentityProvider` wraps your app, `CloudProvider` automatically resolves the user's email for token generation -- no `userId` prop needed:

```tsx
<IdentityProvider>
  <CloudProvider generateCloudToken={generateCloudToken}>
    <App />
  </CloudProvider>
</IdentityProvider>
```

You can also pass `userId` directly if you are not using `IdentityProvider`:

```tsx
<CloudProvider userId="user@example.com" generateCloudToken={generateCloudToken}>
  <App />
</CloudProvider>
```

## Components

### Cloud Provider

| Component | Description |
|-----------|-------------|
| `CloudProvider` | React provider that connects to the Hiyve Cloud AI service |

### AI Assistant

| Component | Description |
|-----------|-------------|
| `AIAssistant` | Full-featured conversational AI assistant panel |
| `ConversationView` | Displays conversation messages with markdown rendering |
| `AssistantInput` | Text input with send button for the assistant |
| `MessageBubble` | Individual message display (user or assistant) |
| `QuickActions` | Predefined action buttons for common queries |
| `IntelligenceReadinessStatus` | Shows whether AI services are ready |

### Intelligence

| Component | Description |
|-----------|-------------|
| `IntelligencePanel` | Combined panel with query input, summary, and action items |
| `QueryInput` | Text input for asking AI questions about the meeting |
| `SummaryPanel` | Displays AI-generated meeting summary |
| `ActionItemsPanel` | Lists extracted action items with priorities |

### Meeting Summary

| Component | Description |
|-----------|-------------|
| `MeetingSummary` | Rich meeting summary with all sections |
| `SummaryExportButton` | Export meeting summary to markdown |
| `KeyPointsSection` | Key discussion points |
| `DecisionsSection` | Decisions made during the meeting |
| `ActionItemsSection` | Action items with assignees and due dates |
| `ParticipantSection` | Participant details with speaking metrics |

### Alerts

| Component | Description |
|-----------|-------------|
| `AlertsPanel` | Full alert management panel with filtering |
| `AlertList` | Scrollable list of alerts |
| `AlertCard` | Individual alert display with priority and type |
| `AlertToast` | Toast notification for new alerts |
| `AlertStack` | Stacked toast notifications |
| `AlertSettingsPanel` | Configure alert sensitivity and categories |
| `AlertDetailDialog` | Full detail view for a single alert |

### Scheduling

| Component | Description |
|-----------|-------------|
| `ScheduleForm` | Meeting scheduling form with recurrence and invites |
| `MeetingList` | List of scheduled meetings |
| `MeetingCard` | Individual meeting card with status and actions |
| `RecurrenceSelector` | Recurrence pattern selector (daily, weekly, monthly) |

### Mood Analysis

| Component | Description |
|-----------|-------------|
| `MoodAnalysisProvider` | Provider that enables real-time facial emotion and engagement detection on participant video streams. Wrap your video components with this provider and use `useMoodAnalysis()` to access per-participant mood states. Configurable via `analyzerType`, `detectionInterval`, and `smoothing` props. |

### Sentiment Dashboard

| Component | Description |
|-----------|-------------|
| `SentimentDashboard` | Real-time and historical sentiment overview |
| `ParticipantMoodCard` | Individual participant mood display |
| `RoomMetricsOverview` | Aggregated room engagement metrics |
| `EmotionHeatmap` | Emotion distribution heatmap over time |
| `EngagementHeatmap` | Engagement level heatmap over time |
| `MoodSessionViewer` | View saved mood session data |

### Intelligence Settings

| Component | Description |
|-----------|-------------|
| `IntelligenceSettings` | Configuration panel for AI intelligence features |

### Intelligence Hub

| Component | Description |
|-----------|-------------|
| `IntelligenceHub` | Tabbed container combining AI assistant, search, scorecard, and other intelligence panels |

### Search

| Component | Description |
|-----------|-------------|
| `SearchPanel` | Semantic search across meeting transcriptions and documents |

### Scorecard

| Component | Description |
|-----------|-------------|
| `ScorecardPanel` | Displays analysis scorecards (sales, interview, consultation, coaching, or custom) |

### Coaching

| Component | Description |
|-----------|-------------|
| `CoachingOverlay` | Real-time coaching hints overlay during meetings |
| `TalkRatioBar` | Visual bar showing talk/listen ratio |
| `TopicTracker` | Displays current topic and topic shift history |

### Conversation Manager

| Component | Description |
|-----------|-------------|
| `ConversationList` | Displays and manages saved AI conversation sessions |

### Agent Assistant

Components for building agent-style AI assistants with structured results, inline action forms, reasoning visualization, and network graph rendering.

| Component | Description |
|-----------|-------------|
| `AgentInput` | Text input with send button for agent queries |
| `AgentSidebar` | Conversation history sidebar with create, rename, and delete |
| `AgentConversationView` | Scrollable message list with auto-scroll and structured results |
| `AgentMessage` | Single message display (user query or structured assistant result) |
| `AgentResults` | Renders structured assistant results including text, tables, lists, action buttons, forms, reasoning steps, and network graphs |
| `ActionForm` | Inline form for collecting missing parameters before executing an action |
| `ReasoningSteps` | Collapsible timeline showing the agent's reasoning process (tool calls, thinking steps, errors) |
| `NetworkGraph` | Force-directed graph visualization for relationship data |

#### AgentInput Props

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `onSubmit` | `(query: string) => void` | **required** | Callback when a query is submitted |
| `loading` | `boolean` | `false` | Disables input and shows loading state |
| `disabled` | `boolean` | `false` | Disables the input |
| `labels` | `Partial<AgentAssistantLabels>` | - | Custom labels |
| `colors` | `Partial<AgentAssistantColors>` | - | Custom colors |
| `styles` | `Partial<AgentAssistantStyles>` | - | Custom styles |
| `sx` | `SxProps<Theme>` | - | MUI sx prop |

`AgentInput` exposes an imperative handle via `ref` with `setValue(text)` and `focus()` methods.

#### AgentSidebar Props

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `open` | `boolean` | **required** | Whether the sidebar is visible |
| `onClose` | `() => void` | **required** | Callback to close the sidebar |
| `conversations` | `AgentConversation[]` | `[]` | List of conversations to display |
| `activeConversationId` | `string \| null` | - | Currently selected conversation |
| `onSelectConversation` | `(id: string) => void` | **required** | Callback when a conversation is selected |
| `onNewConversation` | `() => void` | **required** | Callback to create a new conversation |
| `onDeleteConversation` | `(id: string) => void` | **required** | Callback to delete a conversation |
| `onRenameConversation` | `(id: string, title: string) => void` | **required** | Callback to rename a conversation |
| `labels` | `Partial<AgentAssistantLabels>` | - | Custom labels |
| `colors` | `Partial<AgentAssistantColors>` | - | Custom colors |
| `styles` | `Partial<AgentAssistantStyles>` | - | Custom styles |
| `icons` | `Partial<AgentAssistantIcons>` | - | Custom icons |
| `sx` | `SxProps<Theme>` | - | MUI sx prop |

#### AgentConversationView Props

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `messages` | `AgentAssistantMessage[]` | `[]` | Messages to display |
| `loading` | `boolean` | `false` | Shows a loading indicator |
| `onAction` | `(messageId: string, action: Record<string, unknown>, data: Record<string, unknown>) => void` | - | Callback for action button clicks in results |
| `storedRooms` | `StoredRoom[]` | - | Room list for autocomplete in action forms |
| `onFormSubmit` | `(messageId: string, action: Record<string, unknown>, formData: Record<string, unknown>) => void` | - | Callback for inline form submission |
| `onFormCancel` | `(messageId: string) => void` | - | Callback for inline form cancellation |
| `isNavigating` | `boolean` | `false` | Disables action buttons during navigation |
| `onCopyToInput` | `(text: string) => void` | - | Callback to copy text back to the input |
| `onDeleteMessage` | `(messageId: string) => void` | - | Callback to delete a message |
| `resultRenderer` | `(result: Record<string, unknown>, props: AgentResultsProps) => ReactNode` | - | Custom renderer for assistant results |
| `labels` | `Partial<AgentAssistantLabels>` | - | Custom labels |
| `colors` | `Partial<AgentAssistantColors>` | - | Custom colors |
| `styles` | `Partial<AgentAssistantStyles>` | - | Custom styles |
| `icons` | `Partial<AgentAssistantIcons>` | - | Custom icons |
| `sx` | `SxProps<Theme>` | - | MUI sx prop |

#### AgentMessage Props

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `message` | `AgentAssistantMessage` | **required** | The message to render |
| `onAction` | `(messageId: string, action: Record<string, unknown>, data: Record<string, unknown>) => void` | - | Callback for action button clicks |
| `storedRooms` | `StoredRoom[]` | - | Room list for form autocomplete |
| `onFormSubmit` | `(messageId: string, action: Record<string, unknown>, formData: Record<string, unknown>) => void` | - | Callback for inline form submission |
| `onFormCancel` | `(messageId: string) => void` | - | Callback for inline form cancellation |
| `isNavigating` | `boolean` | `false` | Disables action buttons during navigation |
| `onCopyToInput` | `(text: string) => void` | - | Callback to copy text back to the input |
| `onDelete` | `(messageId: string) => void` | - | Callback to delete the message |
| `resultRenderer` | `(result: Record<string, unknown>, props: AgentResultsProps) => ReactNode` | - | Custom renderer for assistant results |
| `onError` | `(error: Error) => void` | - | Callback fired on errors (e.g., clipboard failures) |
| `labels` | `Partial<AgentAssistantLabels>` | - | Custom labels |
| `colors` | `Partial<AgentAssistantColors>` | - | Custom colors |
| `styles` | `Partial<AgentAssistantStyles>` | - | Custom styles |
| `icons` | `Partial<AgentAssistantIcons>` | - | Custom icons |
| `sx` | `SxProps<Theme>` | - | MUI sx prop |

#### ActionForm Props

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `tool` | `string` | **required** | Tool name the form collects parameters for |
| `partialParams` | `Record<string, unknown>` | - | Pre-filled parameter values |
| `missingParams` | `string[]` | - | Parameter names the form should collect |
| `formFields` | `ActionFormField[]` | - | Field definitions (type, label, placeholder, required, options) |
| `storedRooms` | `StoredRoom[]` | - | Room list for autocomplete on room fields |
| `status` | `'pending' \| 'submitting' \| 'submitted' \| 'cancelled'` | `'pending'` | Current form status |
| `onSubmit` | `(params: Record<string, unknown>) => void` | **required** | Callback when the form is submitted |
| `onCancel` | `() => void` | **required** | Callback when the form is cancelled |
| `getTitleForTool` | `(tool: string) => string` | - | Custom title based on tool name |
| `getSubmitTextForTool` | `(tool: string, status: string) => string` | - | Custom submit button text |
| `labels` | `Partial<AgentAssistantLabels>` | - | Custom labels |
| `colors` | `Partial<AgentAssistantColors>` | - | Custom colors |
| `sx` | `SxProps<Theme>` | - | MUI sx prop |

#### ReasoningSteps Props

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `steps` | `AgentReasoningStep[]` | `[]` | Reasoning steps to display |
| `stats` | `AgentReasoningStats` | - | Summary statistics (iterations, tool calls, duration) |
| `defaultExpanded` | `boolean` | `false` | Whether the timeline starts expanded |
| `loading` | `boolean` | `false` | Whether reasoning is still in progress |
| `labels` | `Partial<AgentAssistantLabels>` | - | Custom labels |
| `colors` | `Partial<AgentAssistantColors>` | - | Custom colors |
| `sx` | `SxProps<Theme>` | - | MUI sx prop |

#### NetworkGraph Props

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `data` | `GraphData` | **required** | Graph nodes and edges |
| `onNodeClick` | `(node: GraphNode) => void` | - | Callback when a node is clicked |
| `height` | `number` | - | Graph height in pixels |
| `showLegend` | `boolean` | - | Whether to show the node type legend |
| `showControls` | `boolean` | - | Whether to show zoom controls |
| `nodeColors` | `Record<string, string>` | `defaultGraphNodeColors` | Custom colors by node type |
| `labels` | `Partial<AgentAssistantLabels>` | - | Custom labels |
| `colors` | `Partial<AgentAssistantColors>` | - | Custom colors |
| `sx` | `SxProps<Theme>` | - | MUI sx prop |

#### Agent Assistant Usage

```tsx
import {
  AgentInput,
  AgentConversationView,
  AgentSidebar,
  useAgentConversations,
} from '@hiyve/react-intelligence';

function AgentPanel({ userId }: { userId: string }) {
  const {
    conversations,
    activeConversationId,
    activeConversation,
    createConversation,
    deleteConversation,
    switchConversation,
    renameConversation,
    addMessage,
    deleteMessage,
  } = useAgentConversations(userId);

  const [sidebarOpen, setSidebarOpen] = useState(false);
  const [loading, setLoading] = useState(false);

  async function handleSubmit(query: string) {
    addMessage({ type: 'user', query });
    setLoading(true);
    const result = await fetchAgentResponse(query);
    addMessage({ type: 'assistant', result });
    setLoading(false);
  }

  return (
    <div style={{ display: 'flex', height: '100%' }}>
      <AgentSidebar
        open={sidebarOpen}
        onClose={() => setSidebarOpen(false)}
        conversations={conversations}
        activeConversationId={activeConversationId}
        onSelectConversation={switchConversation}
        onNewConversation={createConversation}
        onDeleteConversation={deleteConversation}
        onRenameConversation={renameConversation}
      />
      <div style={{ flex: 1, display: 'flex', flexDirection: 'column' }}>
        <AgentConversationView
          messages={activeConversation?.messages}
          loading={loading}
          onDeleteMessage={deleteMessage}
        />
        <AgentInput onSubmit={handleSubmit} loading={loading} />
      </div>
    </div>
  );
}
```

### Room Dashboard

A configurable card-grid dashboard designed for rooms without active video. The dashboard provides AI assistant, semantic search, alerts, room statistics, and settings cards in a responsive grid layout. Cards can be shown, hidden, reordered, or replaced with custom cards.

| Component | Description |
|-----------|-------------|
| `RoomDashboard` | Orchestrator that arranges cards in a responsive grid |
| `RoomStatsDashboard` | Standalone full-page stats view with stat cards, chart slot, and recent files |
| `DashboardCard` | Reusable card wrapper with header, icon, badge, and expand/collapse support |
| `AIAssistantCard` | AI assistant card operating in stateless mode (no live meeting context) |
| `SearchCard` | Semantic search card for querying historical transcriptions and documents |
| `AlertsCard` | Historical alerts card with auto-refresh |
| `RoomStatsCard` | Presentational card displaying consumer-provided room statistics |
| `SettingsCard` | Intelligence configuration card (visible to room owners) |

#### RoomDashboard Props

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `roomId` | `string` | **required** | Room identifier for scoping search and alerts |
| `userId` | `string` | **required** | Current user identifier |
| `isOwner` | `boolean` | `false` | Whether the current user is the room owner |
| `cloud` | `CloudClient` | - | CloudClient instance for search and AI queries |
| `showAssistant` | `boolean` | `true` | Show the AI Assistant card |
| `showSearch` | `boolean` | `true` | Show the Search card |
| `showAlerts` | `boolean` | `true` | Show the Alerts card |
| `showRoomStats` | `boolean` | `true` | Show the Room Stats card |
| `showSettings` | `boolean` | `isOwner` | Show the Settings card |
| `cardOrder` | `string[]` | `['assistant', 'search', 'roomStats', 'alerts', 'settings']` | Card display order (built-in and custom card IDs) |
| `customCards` | `RoomDashboardCardConfig[]` | - | Custom cards to inject into the dashboard |
| `renderCard` | `(cardId: string, defaultRender: () => ReactNode) => ReactNode \| null` | - | Intercept any card's rendering; return `null` to hide |
| `onSend` | `(message: string) => Promise<string>` | - | Custom AI query handler for the assistant card |
| `systemPrompt` | `string` | - | System prompt for the AI assistant |
| `quickActions` | `QuickAction[]` | - | Quick action buttons for the AI assistant |
| `showConversationManager` | `boolean` | `false` | Enable multi-conversation management in the assistant |
| `conversationManagerOptions` | `ConversationManagerOptions` | - | Options for the conversation manager |
| `alertsAutoRefresh` | `boolean` | `true` | Auto-refresh historical alerts |
| `alertsAutoRefreshInterval` | `number` | `30` | Auto-refresh interval in seconds |
| `intelligenceConfig` | `IntelligenceConfig` | - | Current intelligence configuration (for settings card) |
| `onIntelligenceConfigChange` | `(config: IntelligenceConfig) => void` | - | Callback when intelligence configuration changes |
| `roomStats` | `RoomStatsData` | - | Room statistics data |
| `labels` | `Partial<RoomDashboardLabels>` | - | Custom labels |
| `colors` | `Partial<RoomDashboardColors>` | - | Custom colors |
| `styles` | `Partial<RoomDashboardStyles>` | - | Custom styles |
| `sx` | `SxProps<Theme>` | - | MUI sx prop |

#### DashboardCard Props

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `id` | `string` | **required** | Unique card identifier |
| `title` | `string` | **required** | Card title displayed in the header |
| `icon` | `ReactNode` | - | Icon in the header |
| `badge` | `number` | - | Badge count displayed next to the title |
| `expandable` | `boolean` | `false` | Whether the card can be expanded/collapsed |
| `defaultExpanded` | `boolean` | `true` | Initial expanded state |
| `actions` | `ReactNode` | - | Header action buttons slot |
| `gridSize` | `{ xs?, sm?, md?, lg? }` | - | Responsive grid sizing |
| `minHeight` | `number \| string` | - | Minimum card height |
| `maxHeight` | `number \| string` | - | Maximum card height |
| `children` | `ReactNode` | **required** | Card content |
| `colors` | `Partial<RoomDashboardColors>` | - | Color overrides |
| `sx` | `SxProps<Theme>` | - | MUI sx prop |

#### RoomStatsDashboard Props

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `stats` | `RoomStatsData` | **required** | Room statistics data (loading state, activity flag, recent files) |
| `statCards` | `Array<{ icon: ReactNode; label: string; value: string \| number }>` | **required** | Primary stat cards displayed in the top row |
| `secondaryStatCards` | `Array<{ icon: ReactNode; label: string; value: string \| number }>` | - | Secondary stat cards displayed below the chart |
| `renderChart` | `() => ReactNode` | - | Render function for an activity chart (keeps the SDK free of charting library deps) |
| `emptyTitle` | `string` | `'No activity yet'` | Title shown when there is no activity |
| `emptyDescription` | `string` | `'Start a session to see usage statistics.'` | Description shown when there is no activity |
| `recentFilesTitle` | `string` | `'Recent Files'` | Title for the recent files section |
| `sx` | `SxProps<Theme>` | - | MUI sx prop |

#### RoomStatsDashboard Usage

```tsx
import { RoomStatsDashboard } from '@hiyve/react-intelligence';
import GroupIcon from '@mui/icons-material/Group';
import FolderIcon from '@mui/icons-material/Folder';
import VideocamIcon from '@mui/icons-material/Videocam';
import TimerIcon from '@mui/icons-material/Timer';

function StatsPage({ stats }: { stats: RoomStatsData }) {
  return (
    <RoomStatsDashboard
      stats={stats}
      statCards={[
        { icon: <GroupIcon />, label: 'Participants', value: stats.participantCount ?? 0 },
        { icon: <FolderIcon />, label: 'Files', value: stats.fileCount ?? 0 },
        { icon: <VideocamIcon />, label: 'Recordings', value: stats.recordingCount ?? 0 },
        { icon: <TimerIcon />, label: 'Sessions', value: stats.sessionCount ?? 0 },
      ]}
      renderChart={() => <MyChart data={chartData} />}
    />
  );
}
```

#### Room Dashboard Usage

```tsx
import {
  RoomDashboard,
  DashboardCard,
} from '@hiyve/react-intelligence';
import type { RoomDashboardCardConfig } from '@hiyve/react-intelligence';

// Basic usage
function RoomView({ roomId, userId }: { roomId: string; userId: string }) {
  return (
    <RoomDashboard
      roomId={roomId}
      userId={userId}
      isOwner={true}
      roomStats={{
        roomCount: 12,
        fileCount: 45,
        sessionCount: 8,
        participantCount: 24,
      }}
    />
  );
}

// With custom cards
const customCards: RoomDashboardCardConfig[] = [
  {
    id: 'announcements',
    title: 'Announcements',
    gridSize: { xs: 12, md: 6 },
    render: (context) => <AnnouncementsFeed roomId={context.roomId} />,
  },
];

function CustomDashboard({ roomId, userId }: { roomId: string; userId: string }) {
  return (
    <RoomDashboard
      roomId={roomId}
      userId={userId}
      customCards={customCards}
      cardOrder={['assistant', 'announcements', 'search', 'roomStats']}
      showAlerts={false}
    />
  );
}
```

## Hooks

### Cloud & AI

| Hook | Description |
|------|-------------|
| `useCloud()` | Access the full cloud context (requires `CloudProvider`) |
| `useIntelligence(userId)` | AI query, summary, and action items |
| `useLiveContext(roomName, userId)` | Manage live meeting context for AI |
| `useConversation(options)` | Manage AI conversation state and history |
| `useIntelligenceReadiness(options)` | Check if AI services are available |

### Alerts & Scheduling

| Hook | Description |
|------|-------------|
| `useAlerts(roomId)` | Alert history, settings, and acknowledgment |
| `useAlertToasts(options)` | Manage toast notifications for alerts |
| `useScheduling()` | Create, update, cancel, and list meetings |

### Search & Analysis

| Hook | Description |
|------|-------------|
| `useSearch(options)` | Semantic search across transcriptions and documents |
| `useAnalysis(options)` | Run scorecard analysis on meeting transcripts |

### Note Generation

| Hook | Description |
|------|-------------|
| `useNoteGeneration(options)` | Generate AI-powered meeting notes from transcripts |

### Conversation Manager

| Hook | Description |
|------|-------------|
| `useConversationManager(options)` | Manage multiple AI conversation sessions with persistence |

### Mood & Sentiment

| Hook | Description |
|------|-------------|
| `useMoodAnalysis()` | Access mood analysis state and controls (requires `MoodAnalysisProvider`) |
| `useMoodAnalysisSafe()` | Safe version of `useMoodAnalysis` that returns `null` when no provider is present |
| `useMoodState(userId)` | Get the mood state for a specific user (convenience wrapper) |
| `useMoodAnalysisStatus()` | Get loading, ready, and error status for mood analysis |
| `useMoodCloudSync(options)` | Sync local mood data with Hiyve Cloud |

### Chat Notes

| Hook | Description |
|------|-------------|
| `useChatNoteSave(options)` | Auto-save AI chat conversations as note files to storage |

### Alert Toasts

| Hook | Description |
|------|-------------|
| `useAlertToastsWithProvider(alerts, options)` | Manage alert toast notifications from an externally provided alerts array |

### Agent Conversations

| Hook | Description |
|------|-------------|
| `useAgentConversations(userId, storagePrefix?)` | Manage agent conversation sessions with per-user persistence |

#### useAgentConversations

Manages multiple agent conversations with automatic persistence scoped to each user. Conversations are preserved across page reloads.

**Parameters:**

| Param | Type | Description |
|-------|------|-------------|
| `userId` | `string \| null` | User identifier for scoping conversations. Pass `null` to reset. |
| `storagePrefix` | `string` | Optional prefix for isolating conversation storage between different agent instances |

**Returns** `UseAgentConversationsReturn`:

| Property | Type | Description |
|----------|------|-------------|
| `conversations` | `AgentConversation[]` | All conversations for the current user |
| `activeConversationId` | `string \| null` | Currently active conversation ID |
| `activeConversation` | `AgentConversation \| null` | Currently active conversation object |
| `createConversation` | `() => string` | Create a new conversation and return its ID |
| `deleteConversation` | `(id: string) => void` | Delete a conversation |
| `switchConversation` | `(id: string) => void` | Switch to a different conversation |
| `addMessage` | `(message) => string` | Add a message to the active conversation and return its ID |
| `deleteMessage` | `(messageId: string) => void` | Delete a message (and its paired question/answer) |
| `renameConversation` | `(id: string, title: string) => void` | Rename a conversation |
| `clearActiveConversation` | `() => void` | Clear all messages in the active conversation |
| `clearAllConversations` | `() => void` | Delete all conversations |
| `ensureActiveConversation` | `() => string` | Return the active conversation ID, creating one if needed |
| `updatePendingAction` | `(action: Record<string, unknown> \| null) => void` | Set a pending action on the active conversation |
| `clearPendingAction` | `() => void` | Clear the pending action |
| `updateMessageFormState` | `(messageId: string, formState) => void` | Update a message's inline form state |
| `updateMessageResult` | `(messageId: string, result: Record<string, unknown>) => void` | Update a message's structured result |

## Customization

Every component domain supports custom labels, colors, styles, and icons via merge functions.

### AI Assistant

```tsx
import {
  AIAssistant,
  defaultAIAssistantLabels,
  mergeAIAssistantColors,
} from '@hiyve/react-intelligence';

<AIAssistant
  userId="user-123"
  roomName="my-room"
  labels={{ ...defaultAIAssistantLabels, title: 'Meeting AI' }}
  colors={mergeAIAssistantColors({ userBubble: '#e3f2fd' })}
/>
```

### Intelligence Panel

```tsx
import {
  IntelligencePanel,
  DEFAULT_INTELLIGENCE_LABELS,
  DEFAULT_INTELLIGENCE_COLORS,
} from '@hiyve/react-intelligence';

<IntelligencePanel
  labels={{ ...DEFAULT_INTELLIGENCE_LABELS, title: 'AI Insights' }}
  colors={{ ...DEFAULT_INTELLIGENCE_COLORS, primary: '#1976d2' }}
/>
```

### Meeting Summary

```tsx
import {
  MeetingSummary,
  mergeMeetingSummaryLabels,
  mergeMeetingSummaryColors,
} from '@hiyve/react-intelligence';

<MeetingSummary
  data={summaryData}
  labels={mergeMeetingSummaryLabels({ title: 'Session Recap' })}
  colors={mergeMeetingSummaryColors({ primary: '#2e7d32' })}
/>
```

### Alerts

```tsx
import {
  AlertsPanel,
  mergeAlertsPanelLabels,
  mergeAlertsColors,
} from '@hiyve/react-intelligence';

<AlertsPanel
  roomId="room-123"
  labels={mergeAlertsPanelLabels({ title: 'Meeting Alerts' })}
  colors={mergeAlertsColors({ high: '#d32f2f' })}
/>
```

### Scheduling

```tsx
import {
  ScheduleForm,
  mergeScheduleFormLabels,
  mergeSchedulingColors,
} from '@hiyve/react-intelligence';

<ScheduleForm
  onSubmit={handleSubmit}
  labels={mergeScheduleFormLabels({ submitButton: 'Create Meeting' })}
  colors={mergeSchedulingColors({ primary: '#1565c0' })}
/>
```

### Sentiment Dashboard

```tsx
import {
  SentimentDashboard,
  mergeSentimentDashboardLabels,
  mergeSentimentDashboardColors,
} from '@hiyve/react-intelligence';

<SentimentDashboard
  roomName="my-room"
  labels={mergeSentimentDashboardLabels({ title: 'Mood Overview' })}
  colors={mergeSentimentDashboardColors({ positive: '#4caf50' })}
/>
```

### Intelligence Settings

```tsx
import {
  IntelligenceSettings,
  defaultIntelligenceSettingsLabels,
  mergeIntelligenceSettingsLabels,
} from '@hiyve/react-intelligence';

<IntelligenceSettings
  labels={mergeIntelligenceSettingsLabels({ title: 'AI Configuration' })}
/>
```

### Intelligence Hub

```tsx
import {
  IntelligenceHub,
  mergeIntelligenceHubLabels,
  mergeIntelligenceHubColors,
} from '@hiyve/react-intelligence';

<IntelligenceHub
  userId="user-123"
  roomName="my-room"
  labels={mergeIntelligenceHubLabels({ title: 'AI Hub' })}
  colors={mergeIntelligenceHubColors({ primary: '#1976d2' })}
/>
```

### Search Panel

```tsx
import {
  SearchPanel,
  mergeSearchPanelLabels,
  mergeSearchPanelColors,
} from '@hiyve/react-intelligence';

<SearchPanel
  userId="user-123"
  labels={mergeSearchPanelLabels({ placeholder: 'Search meetings...' })}
  colors={mergeSearchPanelColors({ primary: '#1976d2' })}
/>
```

### Scorecard Panel

```tsx
import {
  ScorecardPanel,
  mergeScorecardPanelLabels,
  mergeScorecardPanelColors,
} from '@hiyve/react-intelligence';

<ScorecardPanel
  variant="sales"
  transcript={transcript}
  userId="user-123"
  labels={mergeScorecardPanelLabels({ title: 'Call Score' })}
  colors={mergeScorecardPanelColors({ high: '#4caf50' })}
/>
```

### Coaching Overlay

```tsx
import {
  CoachingOverlay,
  TalkRatioBar,
  TopicTracker,
  mergeCoachingOverlayLabels,
  mergeCoachingOverlayColors,
} from '@hiyve/react-intelligence';

<CoachingOverlay
  hints={hints}
  labels={mergeCoachingOverlayLabels({ dismiss: 'Got it' })}
  colors={mergeCoachingOverlayColors({ hint: '#fff3e0' })}
/>
<TalkRatioBar talkRatio={0.65} />
<TopicTracker currentTopic="Budget" topicShifts={shifts} />
```

### Conversation List

```tsx
import {
  ConversationList,
  mergeConversationListLabels,
  mergeConversationListColors,
} from '@hiyve/react-intelligence';

<ConversationList
  labels={mergeConversationListLabels({ title: 'Past Conversations' })}
  colors={mergeConversationListColors({ selected: '#e3f2fd' })}
/>
```

### Agent Assistant

```tsx
import {
  AgentConversationView,
  mergeAgentAssistantLabels,
  mergeAgentAssistantColors,
  mergeAgentAssistantStyles,
} from '@hiyve/react-intelligence';

<AgentConversationView
  messages={messages}
  labels={mergeAgentAssistantLabels({ thinking: 'Processing...' })}
  colors={mergeAgentAssistantColors({ accent: '#7c3aed' })}
  styles={mergeAgentAssistantStyles({ borderRadius: 8 })}
/>
```

### Room Dashboard

```tsx
import {
  RoomDashboard,
  mergeRoomDashboardLabels,
  mergeRoomDashboardColors,
  mergeRoomDashboardStyles,
} from '@hiyve/react-intelligence';

<RoomDashboard
  roomId="room-123"
  userId="user-123"
  labels={mergeRoomDashboardLabels({ assistantCard: 'AI Helper' })}
  colors={mergeRoomDashboardColors({ cardBackground: '#1a1a2e' })}
  styles={mergeRoomDashboardStyles({ borderRadius: 16, gridSpacing: 3 })}
/>
```

## CloudProvider Props

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `generateCloudToken` | `(params: { userId: string }) => Promise<string \| { cloudToken: string; environment?: string }>` | - | Callback that fetches a cloud token from your backend. Called lazily on the first AI request and again automatically when the token expires. The SDK passes `{ userId }` so your callback can forward it to your server. Can return a plain token string or an object with `cloudToken` and optional `environment` for automatic environment detection. **Recommended approach.** |
| `cloudToken` | `string` | - | A pre-fetched cloud token (skips `generateCloudToken` entirely). Useful when you manage token lifecycle externally. |
| `userId` | `string` | auto-resolved | User identifier (typically email) passed to `generateCloudToken`. Automatically resolved from `IdentityProvider` or `HiyveProvider` when available. Pass explicitly if you need cloud tokens before joining a room. |
| `environment` | `'production' \| 'development'` | `'production'` | Target environment. When omitted and `generateCloudToken` returns `{ environment }`, the environment is auto-detected from the token response. |
| `baseUrl` | `string` | - | Custom API base URL. Overrides `environment` if provided. |
| `timeout` | `number` | `30000` | Request timeout in milliseconds. |

## Key Types

### Agent Assistant Types

| Type | Description |
|------|-------------|
| `AgentAssistantMessage` | A message in an agent conversation (user query or structured assistant result) |
| `AgentConversation` | A conversation session containing messages and metadata |
| `AgentReasoningStep` | A step in the agent's reasoning process (thinking, tool call, tool result, error) |
| `AgentReasoningStats` | Statistics about the reasoning process (iterations, tool calls, duration) |
| `GraphNode` | A node in the network graph (id, label, type, color, properties) |
| `GraphEdge` | An edge in the network graph (source, target, type, weight) |
| `GraphData` | Graph data containing nodes and edges |
| `ActionFormField` | Field definition for an action form (name, type, label, required, options) |
| `StoredRoom` | A room entry for autocomplete in action forms |
| `AgentAssistantLabels` | Labels configuration for agent assistant components |
| `AgentAssistantIcons` | Icons configuration for agent assistant components |
| `AgentAssistantColors` | Color configuration for agent assistant components |
| `AgentAssistantStyles` | Style configuration for agent assistant components |
| `AgentInputProps` | Props for `AgentInput` |
| `AgentInputRef` | Imperative handle for `AgentInput` (`setValue`, `focus`) |
| `AgentSidebarProps` | Props for `AgentSidebar` |
| `AgentConversationViewProps` | Props for `AgentConversationView` |
| `AgentMessageProps` | Props for `AgentMessage` |
| `AgentResultsProps` | Props for `AgentResults` |
| `ActionFormProps` | Props for `ActionForm` |
| `AgentReasoningStepsProps` | Props for `ReasoningSteps` |
| `NetworkGraphProps` | Props for `NetworkGraph` |
| `UseAgentConversationsReturn` | Return type for `useAgentConversations` |

### Room Dashboard Types

| Type | Description |
|------|-------------|
| `RoomDashboardProps` | Props for `RoomDashboard` |
| `DashboardCardProps` | Props for `DashboardCard` |
| `RoomStatsData` | Consumer-provided room statistics (room count, file count, sessions, participants, last active, recordings, custom stats) |
| `RoomDashboardCardConfig` | Configuration for injecting custom cards (id, title, icon, badge, gridSize, render function) |
| `RoomDashboardContext` | Context passed to custom card render functions (roomId, userId, isOwner, colors, styles) |
| `RoomDashboardLabels` | Labels configuration for the dashboard |
| `RoomDashboardColors` | Color configuration for the dashboard |
| `RoomDashboardStyles` | Style configuration for the dashboard |

## Type Aliases

Several common type names (e.g. `ActionItem`, `MeetingAlert`, `Meeting`, `EmotionType`) appear in multiple feature areas. To avoid collisions, import them using the prefixed aliases below:

| Import Name | Description |
|-------------|-------------|
| `CloudActionItem` | Action items returned by cloud AI queries |
| `IntelligenceActionItem` | Action items displayed in the intelligence panel |
| `SummaryActionItem` | Action items displayed in meeting summaries |
| `CloudMeetingAlert` | Alert objects from cloud API responses |
| `AlertsMeetingAlert` | Alert objects used by alerts UI components |
| `CloudMeeting` | Meeting objects from cloud API responses |
| `SchedulingMeeting` | Meeting objects used by scheduling UI components |
| `MoodEmotionType` | Emotion values used by `MoodAnalysisProvider` |
| `SentimentEmotionType` | Emotion values used by `SentimentDashboard` |

## Utilities

Re-exported from `@hiyve/cloud` for convenience. These are available without importing `@hiyve/cloud` directly.

### Cloud Client

| Export | Description |
|--------|-------------|
| `CloudClient` | Framework-agnostic client class for the Hiyve Cloud AI service |

### Validation

| Export | Description |
|--------|-------------|
| `validateLength(text, max)` | Validate that a string does not exceed a maximum length |
| `validateRoomName(name)` | Validate a room name format and length |
| `validateTranscriptBatch(segments)` | Validate a batch of transcript segments |
| `MAX_QUERY_LENGTH` | Maximum allowed query length |
| `MAX_TRANSCRIPT_LENGTH` | Maximum allowed transcript length |
| `MAX_ROOM_NAME_LENGTH` | Maximum allowed room name length |
| `MAX_TRANSCRIPT_BATCH_SIZE` | Maximum number of transcript segments per batch |

### Mood Bridge

| Export | Description |
|--------|-------------|
| `emotionToSentiment(emotion)` | Convert a mood emotion value to a sentiment entry |
| `moodStateToSentimentEntry(moodState)` | Convert a full mood state object to a sentiment entry |

### Cloud Defaults

| Export | Description |
|--------|-------------|
| `DEFAULT_BASE_URL` | Default API base URL |
| `DEFAULT_TIMEOUT` | Default request timeout in milliseconds |
| `DEFAULT_MODEL` | Default AI model identifier |
| `DEFAULT_SUMMARY_MAX_LENGTH` | Default maximum summary length |
| `DEFAULT_ENHANCE_STYLE` | Default text enhancement style |
| `DEFAULT_ALERT_SETTINGS` | Default alert configuration |
| `DEFAULT_ENVIRONMENT` | Default cloud environment |
| `ENVIRONMENT_URLS` | Map of environment names to API URLs |

### Formatting Utilities

Utilities exported from individual component modules:

| Export | Description |
|--------|-------------|
| `formatAgentTimestamp(date)` | Format a timestamp for display in agent messages |
| `formatConversationDate(date)` | Format a date for the conversation sidebar (today, yesterday, or date) |
| `agentNormalizeRoomName(name)` | Normalize a room name for display (removes random suffixes) |
| `formatToolName(name)` | Format a tool name for display (e.g., `create_schedule` to `Create Schedule`) |
| `generateMessageId()` | Generate a unique message identifier |
| `formatMessageTime(date)` | Format a message timestamp |
| `groupMessagesByDate(messages)` | Group messages by date for sectioned display |
| `parseMarkdown(text)` | Parse markdown text for rendering |
| `summaryToMarkdown(data)` | Convert meeting summary data to a markdown string |
| `parseSummaryText(text)` | Parse raw summary text into structured data |

### Heatmap Utilities

Functions for processing mood data into heatmap visualizations.

| Export | Description |
|--------|-------------|
| `bucketDataByTime(data, interval, startTime, endTime)` | Group mood data points into time buckets for heatmap rendering |
| `aggregateEngagement(points)` | Calculate average engagement from a set of mood data points |
| `aggregateEmotion(points)` | Find the dominant emotion from a set of mood data points |
| `emotionToNumericValue(emotion)` | Convert an emotion type to a numeric value (0-100) |
| `processDataForHeatmap(data, interval, startTime, endTime)` | Process per-participant mood data into a grid of heatmap cells |
| `formatTimeLabel(timestamp)` | Format a timestamp for heatmap axis labels |
| `getEngagementHeatmapColor(value)` | Get a color string for an engagement value (null-safe) |
| `getEmotionHeatmapColor(value)` | Get a color string for an emotion numeric value (null-safe) |

### Scheduling Utilities

| Export | Description |
|--------|-------------|
| `formatMeetingDate(date)` | Format a date for meeting display (e.g., "Mon, Jan 15, 2024") |
| `formatMeetingTime(date)` | Format a time for meeting display (e.g., "2:30 PM") |
| `formatMeetingDateTime(date)` | Format date and time together (e.g., "Mon, Jan 15, 2024 at 2:30 PM") |
| `schedulingFormatDuration(start, end)` | Format the duration between two dates (e.g., "1h 30m") |
| `getTimezoneDisplayName(timezone)` | Get a display-friendly name for an IANA timezone |
| `isValidEmail(email)` | Validate an email address format |
| `parseEmails(input)` | Parse a comma/semicolon-separated string into valid email addresses |
| `getRecurrenceDescription(recurrence)` | Get a human-readable description of a recurrence pattern |
| `isMeetingStartingSoon(meeting, thresholdMinutes?)` | Check if a meeting starts within the given threshold |
| `isMeetingInProgress(meeting)` | Check if a meeting is currently in progress |
| `sortMeetingsByTime(meetings, direction?)` | Sort meetings by start time (ascending or descending) |
| `groupMeetingsByDate(meetings)` | Group meetings by date for sectioned display |
| `getDefaultFormValues()` | Get default values for the meeting scheduling form |

### Summary Utilities

| Export | Description |
|--------|-------------|
| `getSentimentColor(sentiment, colors?)` | Get a color for a sentiment value (positive, negative, neutral, mixed) |
| `getStatusColor(status, colors?)` | Get a color for an action item status (pending, in-progress, completed) |
| `summaryGetPriorityColor(priority, colors?)` | Get a color for a priority level (high, medium, low) |
| `summaryFormatDuration(seconds)` | Format seconds into a human-readable duration |
| `formatSpeakingPercentage(percentage)` | Format a speaking percentage (e.g., `0.65` to `"65%"`) |
| `formatDate(date)` | Format a date for summary display |
| `formatTime(date)` | Format a time for summary display |
| `generateId()` | Generate a unique identifier string |
| `summaryToMarkdown(data)` | Convert meeting summary data to a markdown string |
| `parseSummaryText(text)` | Parse raw AI summary text into structured summary data |

### Alert Utilities

| Export | Description |
|--------|-------------|
| `getAlertTypeConfig(type, config?)` | Get the configuration (label, icon, color) for an alert type |
| `getAlertTypeColor(type)` | Get the color for an alert type |
| `alertsGetPriorityColor(priority)` | Get the color for an alert priority level |
| `formatAlertTimestamp(timestamp)` | Format an alert timestamp for display |
| `getScoreColor(score, colors)` | Get a color for a scorecard score (high, medium, low thresholds) |

### Mood Utilities

| Export | Description |
|--------|-------------|
| `getEmotionLabel(emotion)` | Get a human-readable label for an emotion type |
| `createDefaultMoodState(enabled?)` | Create a default mood state object |
| `formatConfidence(confidence)` | Format a confidence value as a percentage string |
| `moodGetEmotionColor(emotion, colors?)` | Get a color for an emotion type |
| `moodGetEngagementColor(engagement, colors?)` | Get a color for an engagement level |
| `moodFormatEngagement(engagement)` | Format an engagement value for display |
| `mergeAnalyzerOptions(options?)` | Merge partial analyzer options with defaults |

### Sentiment Utilities

| Export | Description |
|--------|-------------|
| `sentimentGetEmotionColor(emotion, colors?)` | Get a color for an emotion type (sentiment dashboard variant) |
| `sentimentGetEngagementColor(engagement, colors?)` | Get a color for an engagement level (sentiment dashboard variant) |
| `sentimentFormatEngagement(engagement)` | Format an engagement value for display |
| `getEngagementLevel(engagement)` | Classify an engagement value as high, medium, or low |
| `calculateAverageEngagement(moodStates)` | Calculate the average engagement across participants |
| `findDominantEmotion(moodStates)` | Find the most common emotion across participants |
| `formatHeatmapTime(timestamp)` | Format a timestamp for heatmap display |
| `getEmotionEmoji(emotion)` | Get an emoji for an emotion type |
| `emotionToValue` | Map of emotion types to numeric values |

## Requirements

- React 18+
- `@hiyve/react` with `HiyveProvider` (for room-connected features)
- `@hiyve/cloud` (CloudClient, installed automatically as peer dependency)
- `@mui/material` v5 or v6
- `@mui/icons-material` v5 or v6
- `@emotion/react` and `@emotion/styled`

## License

Proprietary - Hiyve SDK
