Что хотим
В мобильном приложении в меню списка ассистентов (раскрывающийся switcher над чатом) напротив каждого ассистента добавить 4 кнопки:
- Telegram — клик открывает поле ввода bot token. После сохранения ассистент становится TG-ботом: в личке отвечает на все сообщения, в группах — когда упомянули (@mention / reply), по аналогии с TG-ботом DigiTax.
- WhatsApp — то же, но для WA Cloud API. Поле для access token + phone_number_id.
- Виджет — выбор цвета кнопки (primary_color) + сгенерированный embed-снippet для вставки на сайт.
- Поделиться — поиск пользователей секретаря, multi-select. Выбранные юзеры видят этот чат у себя в мобильном приложении и в админке (web).
«Ассистент» в мобилке = ChatSession (см. mobile/src/views/ChatView.vue:179 loadAvailableAssistants).
Что уже есть в бэкенде
BotInstance (modules/channels/telegram/models.py) — конфиг бота: token, system_prompt, RAG, LLM, persona, TTS, allowed_users, payments, sales_funnel
WhatsAppInstance (modules/channels/whatsapp/models.py) — phone_number_id, access_token, system_prompt, RAG, LLM
WidgetInstance (modules/channels/widget/models.py) — title, greeting, primary_color, position, system_prompt, RAG, LLM
ChatSessionShare (modules/chat/models.py:274) — шаринг чат-сессий
GET /admin/chat/shareable-users — поиск пользователей для шаринга
- TG/WA боты создают per-user
ChatSession через LLMRouter (telegram_bot/services/llm_router.py:73)
- CRUD + start/stop для всех инстансов есть
- Public widget:
GET /widget.js?instance={id} (modules/channels/widget/router_public.py:40)
Главный архитектурный вопрос
Как связать ассистента (сессию) с инстансом TG/WA/виджета?
Вариант A — клонировать конфиг сессии в новый инстанс
При создании TG-бота из ассистента: создаём BotInstance с system_prompt/RAG/LLM скопированными из ChatSession.
- ➕ без миграций схемы
- ➖ при правке system_prompt у ассистента — не подхватится ботом, нужна кнопка «sync»
- Привязка идентифицируется по
name/тегу (например assistant-{session_id})
Вариант B — добавить FK chat_session_id в инстансы (рекомендуется)
В BotInstance/WhatsAppInstance/WidgetInstance — nullable FK на chat_sessions.id. Раннеры читают system_prompt/RAG/LLM live из сессии.
- ➕ единый источник правды, изменения подхватываются автоматически
- ➕ чистый список привязок в мобилке (фильтр по FK)
- ➖ миграция в 3 таблицах + правки в
telegram_bot//whatsapp_bot//widget runner для чтения конфига из linked-сессии
|
A (clone) |
B (FK) |
| Миграций |
0 |
1 (3 таблицы) |
| Изменения в ботах |
нет |
читать конфиг из сессии |
| Sync system_prompt |
вручную |
автоматом |
Скорее всего идём по B.
Открытые вопросы по скоупу
- 1:1 или 1:N? — один ассистент = один TG-бот / одна WA-инстанция / один виджет, или несколько?
- Виджет: какие поля настраиваются в мобилке? Только
primary_color, или сразу title/greeting/position/button_size?
- TG бот в группах — поведение «отвечать только на @mention / reply» уже реализовано в
telegram_bot/? Если нет — это часть скоупа.
- WA в группах — Cloud API не поддерживает группы (только 1:1). Только личка?
- Шаринг чата с другим юзером — копия или live? Если live: оба видят одну историю (как Google Docs); если копия: каждый получает свою. Текущий
ChatSessionShare, судя по всему, делает live-доступ.
- Перевод TG-бота в режим «привязан к ассистенту» не должен сломать существующие 1+ боты в проде (DigiTax, новостной). Миграция должна выставить
chat_session_id=NULL для них и оставить как есть.
Предлагаемое разбиение на PR-ы
Делать одной волной слишком крупно. Разбиваю по возрастанию сложности:
UI-эскиз (мобилка)
В mobile/src/views/ChatView.vue panel showAssistantSwitcher — рендерим строки ассистентов. Под каждым именем — ряд из 4 иконок (TG / WA / виджет / share). Клик открывает bottom-sheet с формой.
Иконки: lucide-vue-next — Send (TG), MessageCircle (WA), Code2 (виджет), Share2 (share). Активное состояние (привязка существует) — амбер; неактивное — стоун-400.
Связанные файлы
mobile/src/views/ChatView.vue — switcher (~line 1100, 1580)
mobile/src/api/chat.ts, admin.ts — добавить новые методы
modules/channels/telegram/router.py, models.py
modules/channels/whatsapp/router.py, models.py
modules/channels/widget/router.py, router_public.py, models.py
modules/chat/router.py — share endpoints
alembic/versions/ — новая миграция (если B)
Что хотим
В мобильном приложении в меню списка ассистентов (раскрывающийся switcher над чатом) напротив каждого ассистента добавить 4 кнопки:
«Ассистент» в мобилке =
ChatSession(см.mobile/src/views/ChatView.vue:179loadAvailableAssistants).Что уже есть в бэкенде
BotInstance(modules/channels/telegram/models.py) — конфиг бота: token, system_prompt, RAG, LLM, persona, TTS, allowed_users, payments, sales_funnelWhatsAppInstance(modules/channels/whatsapp/models.py) — phone_number_id, access_token, system_prompt, RAG, LLMWidgetInstance(modules/channels/widget/models.py) — title, greeting, primary_color, position, system_prompt, RAG, LLMChatSessionShare(modules/chat/models.py:274) — шаринг чат-сессийGET /admin/chat/shareable-users— поиск пользователей для шарингаChatSessionчерезLLMRouter(telegram_bot/services/llm_router.py:73)GET /widget.js?instance={id}(modules/channels/widget/router_public.py:40)Главный архитектурный вопрос
Как связать ассистента (сессию) с инстансом TG/WA/виджета?
Вариант A — клонировать конфиг сессии в новый инстанс
При создании TG-бота из ассистента: создаём
BotInstanceсsystem_prompt/RAG/LLMскопированными изChatSession.name/тегу (напримерassistant-{session_id})Вариант B — добавить FK
chat_session_idв инстансы (рекомендуется)В
BotInstance/WhatsAppInstance/WidgetInstance— nullable FK наchat_sessions.id. Раннеры читаютsystem_prompt/RAG/LLMlive из сессии.telegram_bot//whatsapp_bot//widget runner для чтения конфига из linked-сессииСкорее всего идём по B.
Открытые вопросы по скоупу
primary_color, или сразуtitle/greeting/position/button_size?telegram_bot/? Если нет — это часть скоупа.ChatSessionShare, судя по всему, делает live-доступ.chat_session_id=NULLдля них и оставить как есть.Предлагаемое разбиение на PR-ы
Делать одной волной слишком крупно. Разбиваю по возрастанию сложности:
ChatSessionShare. Минимум бэкенда, в основном UI.WidgetInstance(вариант A) или линкуется (вариант B). Здесь же — миграция для FK, если идём по B.getMe, созданиеBotInstanceс auto_start, проверка group-mention поведения.WhatsAppInstance.UI-эскиз (мобилка)
В
mobile/src/views/ChatView.vuepanelshowAssistantSwitcher— рендерим строки ассистентов. Под каждым именем — ряд из 4 иконок (TG / WA / виджет / share). Клик открывает bottom-sheet с формой.Иконки:
lucide-vue-next—Send(TG),MessageCircle(WA),Code2(виджет),Share2(share). Активное состояние (привязка существует) — амбер; неактивное — стоун-400.Связанные файлы
mobile/src/views/ChatView.vue— switcher (~line 1100, 1580)mobile/src/api/chat.ts,admin.ts— добавить новые методыmodules/channels/telegram/router.py,models.pymodules/channels/whatsapp/router.py,models.pymodules/channels/widget/router.py,router_public.py,models.pymodules/chat/router.py— share endpointsalembic/versions/— новая миграция (если B)