Серьезность
Обычная — но вызывает высокий уровень раздражения в загруженных публичных темах: многократные нажатия кнопки «Повторить» засыпают тему дубликатами сообщений бота, из-за чего пользователям кажется, что бот «отправляет сообщения сам по себе / застрял в цикле».
Платформа
- Сервер: Discourse core
main(ветка 2026.7.x), воспроизведено на последней версииorigin/main(dbf5eedac40, 14.07.2026).discourse-aiвключен в ядро. - Клиент: воспроизведено в различных браузерах/на устройствах (Chrome на десктопе, Chrome на Android, Safari на iOS) — проблема находится на стороне сервера, поэтому клиент не имеет значения.
Описание
Фактический результат: В публичной теме нажатие кнопки Повторить на ответе AI-бота добавляет совершенно новое сообщение бота в тему. Исходный ответ остается нетронутым, поэтому каждое нажатие «Повторить» добавляет еще одно сообщение. N повторений → N дополнительных сообщений.
Ожидаемый результат: Кнопка «Повторить» должна пересоздавать существующий ответ бота на месте (заменять его содержимое), так же, как это происходит в личных сообщениях (PM/DM) с AI-ботом. Новое сообщение создаваться не должно.
Шаги для воспроизведения (на чистой установке Discourse)
- Включите Discourse AI + AI-бота; создайте/включите AI агента (персона) с пользователем-ботом и включите опцию «Разрешить упоминания в темах», чтобы он мог отвечать в публичных темах (
allow_topic_mentions). Добавьте группу вашего пользователя в список разрешенных групп агента и вai_bot_allowed_groups. - В публичной теме сделайте
@упоминаниебота в сообщении, чтобы он ответил. - В ответе бота откройте меню администратора/настроек сообщения (значок гаечного ключа) и нажмите Повторить (действие регенерации →
POST /discourse-ai/ai-bot/post/:post_id/retry). - Наблюдение: вместо регенерации существующего ответа добавляется новый ответ бота. Повторите нажатие «Повторить» → каждый раз добавляется одно лишнее сообщение.
- Для сравнения выполните то же самое в личном сообщении с ботом: «Повторить» корректно регенерирует ответ на месте (без дубликатов). Разница между поведением в личных сообщениях и публичных темах является ключевым признаком проблемы.
Проблема воспроизводится в 100% случаев в публичных темах.
Причина (указатели на код, текущий origin/main)
BotController#retry_response(plugins/discourse-ai/app/controllers/discourse_ai/ai_bot/bot_controller.rb) ставит в очередьJobs::CreateAiReplyс параметромreply_post_id: post.id— т.е. «пересоздать это существующее сообщение».Jobs::CreateAiReplyзагружает его какreply_postи передает вPlayground#reply_to(..., existing_reply_post: reply_post).- В
Playground#reply_to(plugins/discourse-ai/lib/ai_bot/playground.rb):stream_reply = post.topic.private_message? if stream_reply.nil?→falseдля публичных тем (~L518).existing_reply_postиспользуется только внутри ветвиif stream_reply(reply_post = existing_reply_post, ~L538).- Нестриминговая ветвь
else(~L662) безоговорочно вызываетPostCreator.create!(...), добавляя новое сообщение и никогда не затрагивая сообщение, которое должно быть пересоздано.
Таким образом, для любой непубличной темы намерение «пересоздать на месте» из retry_response тихо игнорируется, и вместо этого создается дубликат. (Та же асимметрия означает, что ответы бота в публичных темах не используют стриминг, что является существующим поведением; ошибка заключается именно в том, что existing_reply_post игнорируется на этом пути.)
Предлагаемое исправление (общее направление)
Учитывать existing_reply_post независимо от использования стриминга — например, в нестриминговой ветви, если existing_reply_post присутствует, использовать метод revise вместо вызова PostCreator.create!; или разделить решение об «использовании существующего сообщения» от флага stream_reply.
Безопасный режим
Не применимо — поведение серверной части плагина, не зависит от тем/JS сайта.