-
Notifications
You must be signed in to change notification settings - Fork 5
Chat
Полнофункциональный чат с ИИ-ассистентом: стриминг, голосовой ввод/вывод, ветвление диалогов (branching), markdown-рендеринг, управление сессиями, контекстные файлы, выбор LLM и RAG-коллекций.
-
Стриминг — ответы появляются посимвольно через SSE (
POST /admin/chat/sessions/{id}/stream) -
Markdown-рендеринг — полная поддержка разметки через
marked+DOMPurify: заголовки, код с подсветкой, таблицы, списки, цитаты, ссылки. Стили в.chat-markdown(main.css) используют HSL-переменные темы, включая отдельные стили для user-сообщений (.bg-primary .chat-markdown) - Контекст — вся активная история сессии передаётся LLM
- Автоматический заголовок — первое сообщение становится названием сессии
| Функция | Описание | Активация |
|---|---|---|
| Voice Mode | Автоматическое озвучивание каждого ответа ИИ | Кнопка 🔊 в заголовке |
| TTS | Ручное озвучивание конкретного ответа | Кнопка 🔊 на сообщении ассистента |
| STT | Голосовой ввод через микрофон (Vosk/Whisper) | Кнопка 🎙 рядом с полем ввода |
Заголовок содержит название сессии (редактируется кликом) и ряд кнопок управления. Слева направо:
- Отображается текущее название чата
- Клик — переход в режим редактирования (inline-input)
- При наведении появляется иконка карандаша
- Enter — сохранить, Esc — отменить
Под названием — строка с метриками:
- Количество сообщений
- Метка
(custom prompt)если задан кастомный промпт -
Шкала токенов — прогресс-бар использования контекстного окна:
- Зелёный — < 70%
- Жёлтый — 70–90%
- Красный — > 90% (с предупреждением «Контекст почти заполнен»)
| Кнопка | Иконка | Описание |
|---|---|---|
| Выбор LLM | Brain + выпадающий список | Переключение LLM-провайдера для текущей сессии |
| RAG-коллекции | BookOpen + чекбоксы | Выбор коллекций базы знаний (если есть) |
| Экспорт | Download | Выпадающее меню экспорта чата |
| Позиция ввода | ArrowDownToLine / ArrowUpToLine | Переключение поля ввода между верхом и низом |
| Voice Mode | Volume2 / VolumeX | Включение/выключение автоозвучивания ответов |
| Дерево веток | GitBranch | Показать/скрыть панель BranchTree |
| Настройки | Settings2 | Показать/скрыть панель настроек |
| Новая ветка | Plus | Начать новую ветку с чистого листа |
| Удалить чат | Trash2 (красная) | Удалить текущую сессию (с подтверждением) |
Выпадающий список в заголовке чата позволяет переключать LLM на лету:
- Системный — использует глобальную настройку из раздела LLM
- vLLM (Local) — локальная модель (Qwen/Llama/DeepSeek)
- Cloud providers — любой настроенный облачный провайдер (Gemini, Claude, OpenAI и др.)
Сохраняется в localStorage — применяется к текущему браузеру, не к сессии. Не влияет на глобальные настройки.
Если в системе есть коллекции базы знаний (Wiki RAG), рядом с LLM-селектором появляются чекбоксы:
- Каждая коллекция — отдельный чекбокс
- Можно выбрать несколько коллекций одновременно
- Настройка привязана к сессии — сохраняется на сервере через
rag_modeиknowledge_collection_ids - При переключении между чатами — восстанавливается из данных сессии
Выпадающее меню с тремя вариантами:
| Действие | Описание |
|---|---|
| Копировать чат | Копирует весь диалог в буфер обмена в формате Markdown |
| Экспорт .md | Скачивает файл название_чата.md
|
| Экспорт .json | Скачивает файл название_чата.json (role, content, timestamp) |
Поле ввода может располагаться вверху (по умолчанию) или внизу — переключается кнопкой в заголовке. Позиция сохраняется в localStorage.
| Элемент | Описание |
|---|---|
| Текстовое поле | Автоматически отключается при стриминге или записи голоса |
| Микрофон | Начать/остановить запись голоса (STT). Пульсирует красным при записи |
| Отправить | Отправить сообщение. Показывает спиннер при стриминге |
- Enter — отправить сообщение
- Ctrl+Enter — также отправить
- При записи голоса отображается индикатор «Запись...» с пульсирующей точкой
При наведении на сообщение появляется панель действий. Набор кнопок зависит от роли (user/assistant).
| Кнопка | Иконка | Описание |
|---|---|---|
| Озвучить | Volume2 / Square | Озвучить через TTS. При повторном нажатии — остановить |
| Регенерация | RefreshCw | Создать новую версию ответа (сохраняет старую как sibling) |
| Копировать | Copy | Скопировать текст сообщения в буфер обмена |
| Итоги ветки | ListChecks | Суммаризация диалога до этого сообщения → сохраняется как контекстный файл |
| В контекст | FileOutput | Сохранить текст ответа как контекстный файл (response_YYYY-MM-DD_HH:MM.md) |
| Редактировать | Edit3 | Редактирование текста ответа (без регенерации) |
| Новая ветка | Plus | Начать новую ветку с чистого листа |
| Удалить | Trash2 (красная) | Удалить это сообщение и все последующие |
| Кнопка | Иконка | Описание |
|---|---|---|
| Копировать | Copy | Скопировать текст в буфер обмена |
| Итоги ветки | ListChecks | Суммаризация диалога до этого сообщения |
| Редактировать | Edit3 | Редактировать текст → ИИ сгенерирует новый ответ (создаёт sibling) |
| Регенерация | RefreshCw | Повторно отправить это сообщение для нового ответа |
| Новая ветка | Plus | Начать новую ветку с чистого листа |
| Удалить | Trash2 (красная) | Удалить это сообщение и все последующие |
Кнопка «В контекст» (FileOutput) на сообщениях ассистента:
- Создаёт контекстный файл с именем
response_YYYY-MM-DD_HH:MM.md - Содержимое — полный текст ответа
- Файл сразу сохраняется на сервере и появляется в настройках → «Файлы контекста»
- При следующем запросе текст файла будет подставлен в системный промпт
- Показывает тост «Сохранено в контекст»
Удобно для закрепления важных инструкций, выводов и результатов анализа прямо из чата.
Кнопка ListChecks отправляет POST /admin/chat/sessions/{id}/messages/{msg_id}/summarize:
- Сервер анализирует весь диалог до указанного сообщения
- Генерирует краткое резюме через LLM
- Результат автоматически сохраняется как контекстный файл
summary_YYYY-MM-DD_HH:MM.md - Во время генерации на кнопке вращается спиннер
Выдвижная панель справа (не модальное окно), переключается кнопкой Settings2 в заголовке чата. Ширина изменяется перетаскиванием разделителя (300–800px, сохраняется в localStorage). Содержит две вкладки.
Кастомный system prompt для текущей сессии:
-
Текстовое поле — многострочное, занимает максимум доступного пространства (
flex-1), моноширинный шрифт - Подсказка — описание назначения промпта
-
Кнопки — «Отмена» (закрывает панель) и «Сохранить» (отправляет
PUT /admin/chat/sessions/{id}сsystem_prompt) - Промпт применяется при следующем запросе, существующие ответы не пересчитываются
Файлы, содержимое которых подставляется в системный промпт при каждом запросе:
- Список файлов — название, превью содержимого (до 200 символов)
- Редактирование — кнопка Edit3 открывает inline-редактор с полем имени и содержимого
- Удаление — кнопка X удаляет файл из списка
Действия:
| Кнопка | Описание |
|---|---|
| Загрузить файл | Открывает диалог выбора файлов (.txt, .md, .json, .csv, .xml, .yaml, .yml, .log, .py, .js, .ts) |
| Пустой файл | Создаёт новый файл и сразу открывает редактор |
| Сохранить | Сохраняет все файлы на сервер (PUT /admin/chat/sessions/{id} с context_files) |
Источники контекстных файлов:
- Загрузка с диска (кнопка «Загрузить файл»)
- Ручное создание (кнопка «Пустой файл»)
- Суммаризация ветки (кнопка ListChecks на сообщении →
summary_*.md) - Сохранение ответа (кнопка FileOutput на сообщении ассистента →
response_*.md)
Система ветвления в стиле OpenWebUI — не-деструктивное редактирование и регенерация ответов.
Каждое сообщение (ChatMessage) имеет:
-
parent_id— ссылка на родительское сообщение -
is_active— активна ли эта версия
- Нажмите иконку редактирования на сообщении
- Измените текст → Отправить
- Старая версия деактивируется (
is_active=False), создаётся новый sibling - Для user-сообщений: ИИ генерирует новый ответ на отредактированное сообщение
- Для assistant-сообщений: текст сохраняется без регенерации
- Нажмите иконку регенерации на ответе ИИ
- Старый ответ деактивируется, генерируется новый
- Все предыдущие версии сохраняются
Кнопка «Новая ветка» (Plus) создаёт свежую ветку диалога в рамках той же сессии — сохраняет system_prompt + файлы контекста, но начинает с пустой историей (0 токенов из старых веток).
Кнопка доступна в трёх местах:
- Заголовок чата — рядом с кнопкой дерева веток
- Панель Branch Tree — в заголовке панели
- Каждое сообщение — в панели действий (рядом с «удалить»)
Механика: POST /admin/chat/sessions/{id}/branches/new деактивирует все is_active сообщения → следующее отправленное сообщение автоматически становится новым корнем.
- Сообщения с альтернативами показывают переключатель
< 1/3 > -
BranchTree — выдвижная панель справа в стиле файлового проводника:
- Иконки ролей: 👤 User (синий), 🤖 Bot (зелёный), ⚙️ System (жёлтый)
- Сворачивание/разворачивание — клик по шевронам (▶/▼) на узлах с потомками
- Ответы ассистента — уменьшенный шрифт (11px), дополнительный отступ слева
- Бейджи веток — счётчик альтернатив у узлов с несколькими потомками
- Вертикальные линии-индикаторы на точках ветвления
- Клик по активной ветке → прокрутка чата к этому сообщению с подсвечиванием (ring-primary, 1.5 сек)
- Клик по неактивной ветке → переключение на неё + прокрутка к переключённому сообщению
- Переключение ветки активирует выбранную версию и всех её потомков
- Редактирование — при нажатии «Save» отредактированный текст сразу виден в чате (optimistic update через vue-query cache), форма закрывается мгновенно, показывается спиннер загрузки ответа
- Регенерация — аналогично: спиннер загрузки появляется сразу при нажатии
| Endpoint | Описание |
|---|---|
PUT /admin/chat/sessions/{id}/messages/{msg_id} |
Не-деструктивное редактирование (создаёт sibling) |
POST /admin/chat/sessions/{id}/messages/{msg_id}/regenerate |
Регенерация ответа |
GET /admin/chat/sessions/{id}/branches |
Дерево веток |
POST /admin/chat/sessions/{id}/branches/switch |
Переключить активную ветку |
POST /admin/chat/sessions/{id}/branches/new |
Начать новую ветку с чистого листа |
-
Список чатов — только чаты из админ-панели (
source=admin), с превью последнего сообщения. API фильтрация:GET /admin/chat/sessions?source=admin&exclude_source=.... Значениеtelegramв API прозрачно маппится наtelegram_botв БД - Создание — кнопка "+" создаёт новую сессию
-
Закрепление — Pin/Unpin через кнопку при наведении, закреплённые показываются с иконкой Pin и сортируются в начало списка. Поле
pinned(boolean) в моделиChatSession. Миграция:alembic/versions/20260216_0001_add_chat_pinned.py - Сворачивание — кнопка PanelLeftClose скрывает боковую панель до иконок (только десктоп)
- Ресайз — ширина панели изменяется перетаскиванием разделителя (200–480px, сохраняется в localStorage)
- Мобильная версия — панель открывается поверх контента с затемнением фона
Примечание: чаты из Telegram, WhatsApp и Widget-ботов вынесены в CRM → Inbox для unified inbox.
| Действие | Как |
|---|---|
| Переименование | Двойной клик по названию → редактирование → Enter. Или кнопка Edit3 при наведении |
| Закрепление | Кнопка Pin при наведении на чат. Закреплённые чаты отмечены иконкой |
| Удаление | Иконка корзины при наведении (с диалогом подтверждения) |
| Групповое удаление | Кнопка ListChecks → режим выбора → отметить чекбоксами → «Удалить выбранные» |
Активируется кнопкой ListChecks в заголовке боковой панели:
- У каждого чата появляется чекбокс
- Тулбар показывает количество выбранных
- Выбрать все — отметить все чаты
- Снять выделение — убрать все отметки
-
Удалить выбранные — массовое удаление с подтверждением (
POST /admin/chat/sessions/bulk-delete)
Промпт сессии определяется по приоритету:
- Кастомный промпт сессии (если задан через панель настроек)
- Промпт персоны (Anna/Marina)
- Код-fallback по умолчанию (
_DEFAULT_RAG_PROMPT)
Плюс Wiki RAG контекст добавляется автоматически (если Wiki RAG инициализирован).
Функция _finalize_prompt() в app/routers/chat.py автоматически добавляет _NO_TOOLS_SUFFIX к каждому системному промпту перед отправкой в LLM. Это запрещает Claude генерировать фейковые tool calls (filesystem read_file, function_calls, code execution) как текст — частая причина зависания ответов при использовании Claude bridge. Применяется ко всем 4 эндпоинтам чата (send, stream, edit, regenerate).
Все эндпоинты чата защищены через require_permission("chat", level). Уровни: view (просмотр), edit (создание/изменение), manage (полное управление включая чужие ресурсы).
Все запросы фильтруются по workspace_id из JWT (workspace_context(user, "chat")) — сессии изолированы между workspace'ами. Менеджеры (manage-уровень) видят все ресурсы workspace; остальные — только свои + расшаренные.
| Endpoint | Уровень | Описание |
|---|---|---|
GET /admin/chat/sessions |
view |
Список сессий. manage видит все, остальные — только свои + расшаренные |
POST /admin/chat/sessions |
edit |
Создать сессию (с source tracking) |
GET /admin/chat/sessions/{id} |
view |
Получить сессию с сообщениями и sibling_info |
PUT /admin/chat/sessions/{id} |
edit |
Обновить (переименовать, сменить промпт, pinned, context_files, rag_mode) |
DELETE /admin/chat/sessions/{id} |
edit |
Удалить сессию (owner или manage) |
POST /admin/chat/sessions/bulk-delete |
manage |
Массовое удаление |
POST /admin/chat/sessions/{id}/messages |
edit |
Отправить сообщение (без стриминга) |
POST /admin/chat/sessions/{id}/stream |
edit |
SSE стриминг ответа |
PUT /admin/chat/sessions/{id}/messages/{msg_id} |
edit |
Редактирование сообщения (создаёт sibling) |
DELETE /admin/chat/sessions/{id}/messages/{msg_id} |
edit |
Удалить сообщение |
POST /admin/chat/sessions/{id}/messages/{msg_id}/regenerate |
edit |
Регенерация ответа |
POST /admin/chat/sessions/{id}/messages/{msg_id}/summarize |
edit |
Суммаризация ветки до сообщения |
GET /admin/chat/sessions/{id}/branches |
view |
Дерево веток |
POST /admin/chat/sessions/{id}/branches/switch |
view |
Переключить активную ветку |
POST /admin/chat/sessions/{id}/branches/new |
edit |
Начать новую ветку |
GET /admin/chat/sessions/{id}/shares |
edit |
Список шар сессии |
POST /admin/chat/sessions/{id}/shares |
edit |
Расшарить сессию |
PUT /admin/chat/sessions/{id}/shares/{user_id} |
edit |
Изменить permission шара |
DELETE /admin/chat/sessions/{id}/shares/{user_id} |
edit |
Удалить шар |
POST /admin/chat/sessions/{id}/fork |
edit |
Форк сессии (глубокое копирование) |
GET /admin/chat/shareable-users |
view |
Список пользователей для шаринга |
Подробнее о системе прав: RBAC
Полноэкранный режим для сосредоточенной работы с чатом. Активируется кнопкой Maximize2 в заголовке чата или в сайдбаре (свёрнутый режим). Выход — Esc или кнопка Minimize2.
Вместо обычного заголовка в zen-режиме слева отображается узкая вертикальная панель (48px) в стиле VS Code Activity Bar. Состоит из иконок-кнопок, разделённых тонкими линиями:
| Позиция | Иконка | Описание |
|---|---|---|
| Верх | Аватар (буква) | Первая буква названия сессии. Клик — переименовать |
| Minimize2 | Выйти из zen-режима | |
| Основные | Terminal | Включить/выключить Claude Code (для admin) |
| Brain | Выбор LLM-провайдера (dropdown вправо) | |
| BookOpen | RAG-коллекции (dropdown вправо) | |
| Share2 | Поделиться чатом | |
| GitFork | Форкнуть (для read-only сессий) | |
| Download | Экспорт (copy / md / json) | |
| Режимы | ArrowDown/Up | Переместить поле ввода вверх/вниз |
| Volume2 | Voice mode вкл/выкл | |
| GitBranch | Панель дерева веток | |
| FolderOpen | Рабочая директория CC | |
| Paperclip | Контекстные файлы CC | |
| Настройки | Settings2 | Открыть полную панель настроек |
| Низ | Plus | Новая ветка / новая CC-сессия |
| Trash2 | Удалить чат / выключить CC |
В верхней части области сообщений отображается компактное название сессии. Клик — редактирование inline (Enter — сохранить, Esc — отменить).
Все dropdown-меню в activity bar открываются вправо от иконки. Используют стилизацию zen-glass (полупрозрачный фон с blur). Закрываются по клику вне меню.
Панели настроек и дерева веток в zen-режиме полностью функциональны — открываются справа с возможностью drag-resize. Resize-хэндлы поддерживают как мышь, так и touch-события (для сенсорных экранов).
| Клавиша | Действие |
|---|---|
Enter |
Отправить сообщение |
Ctrl+Enter |
Отправить сообщение (альтернатива) |
Shift+Enter |
Новая строка |
Esc |
Отмена редактирования / выход из zen-режима |
Ctrl+K / ⌘K
|
Command Palette |