# Выбор agent role карточками в пустом окне чата (вместо выпадающего списка) Контекст: при создании нового чата identity (agent role) выбирается из выпадающего списка Mantine ``: `apps/client/src/features/ai-chat/components/ai-chat-window.tsx:543-561`. Значение `""` → «Universal assistant» (роль `null`); остальные опции — `enabledRoles` (эмодзи + имя). 2. Список включённых ролей фильтруется клиентом из всех живых ролей: `ai-chat-window.tsx:144-147` (`enabledRoles = roles.filter(r => r.enabled)`). Источник — `useAiRolesQuery(windowOpen)` (`apps/client/src/features/ai-chat/queries/ai-chat-query.ts:131-137`). 3. Выбранный id хранится в jotai-атоме: `apps/client/src/features/ai-chat/atoms/ai-chat-atom.ts:23` (`selectedAiRoleIdAtom`, `null` = Universal assistant). Сбрасывается в `null` при «New chat»: `ai-chat-window.tsx:168-174` (`startNewChat`). 4. Выбранный id прокидывается в тред и уходит в теле первого запроса: `ai-chat-window.tsx:570-578` (`roleId={activeChatId === null ? selectedRoleId : null}`) → `apps/client/src/features/ai-chat/components/chat-thread.tsx:95-96, 128-138` (`roleIdRef` → `prepareSendMessagesRequest` кладёт `roleId` в body). Сервер учитывает `roleId` ТОЛЬКО при создании чата и фиксирует роль навсегда; для существующего чата роль читается из строки чата (бейдж в шапке окна: `ai-chat-window.tsx:433-440`). 5. Пустая область чата сейчас — бледный текст по центру: `apps/client/src/features/ai-chat/components/message-list.tsx:130-140` (`
` + `emptyState ?? t("Ask the AI agent anything...")`). Важно: `MessageList` УЖЕ принимает произвольный `emptyState: ReactNode` (`message-list.tsx:10-33, 64-70`) — этим пользуется публичный шэр. Данные роли в picker-представлении (доступны не-админам): `id, name, emoji, description, enabled` — `apps/server/src/core/ai-chat/roles/ai-agent-roles.service.ts:35-41, 164-173`. То есть для карточек есть эмодзи и название (описание опционально). ## Желаемое поведение - Вместо `` (`:543-561`) и импорт `Select` (`:9`, используется только там — проверить, что `Group/Loader/Tooltip` остаются нужны). - Собрать узел карточек только когда `activeChatId === null && enabledRoles.length > 0`, иначе `undefined`. - Передать его в `` (`:570-578`). Существующее `roleId={...}` без изменений. 3. **`chat-thread.tsx`**: - Добавить необязательный проп `emptyState?: ReactNode` (импорт `ReactNode`) и форварднуть в `` (`:164`). 4. **`message-list.tsx`** — без изменений (проп `emptyState` уже поддержан). Иллюстративный набросок (НЕ финальный код), `AiChatWindow`: ```tsx // Role cards become the empty-state ONLY for a brand-new chat that has roles. const roleCardsNode = activeChatId === null && enabledRoles.length > 0 ? ( ) : undefined; // ... ``` ## Краевые случаи - **Нет включённых ролей** → карточки не показываем (`emptyState = undefined`), остаётся обычный дефолтный текст empty-state. - **Существующий чат** (`activeChatId !== null`) → карточек нет; роль уже зафиксирована и показана бейджем в шапке (`ai-chat-window.tsx:433-440`). - **Сброс выбора** при «New chat» уже делается (`setSelectedRoleId(null)`, `startNewChat`) — поведение сохраняется. - **Много ролей** → контейнер с переносом и прокруткой, чтобы не ломать пустую область чата. - **Тёмная тема** → за счёт `-light`/`-filled` переменных Mantine цвета корректны в обеих темах. - **Эмодзи нет** → карточка показывает только имя (как сейчас в ``). Если решим добавить подпись-подсказку (например «или просто начните печатать») — это один новый ключ в `en-US/translation.json`; по умолчанию в объём не закладываю. ## Режим работы при реализации Изменение нетривиальное (новый компонент + логика выбора/цветов + интеграция с empty-state), поэтому — делегирование кодеру с обязательным последующим ревью (`review` subagent), затем верификация перечитыванием файлов. ## Открытые вопросы (решить перед/во время реализации) - [ ] Нужна ли карточка Universal assistant отдельной плиткой, или достаточно «ничего не выбрано = дефолт»? Предлагается отдельная карточка (явный возврат к дефолту после клика по роли) — подтвердить. - [ ] Показывать ли `description` роли на карточке (есть в picker-view) или только эмодзи + имя? По умолчанию — только эмодзи + имя, описание в `title`. - [ ] Нужна ли подпись-подсказка над карточками (тогда +1 ключ локали).