Gravité
Normale — mais très gênante sur les sujets publics actifs : des clics répétés sur « Réessayer » inondent le sujet de doublons de messages du bot, ce qui donne l’impression aux membres que le bot « poste tout seul / est bloqué dans une boucle ».
Plateforme
- Serveur : Discourse core
main(branche 2026.7.x), reproduit sur la dernière version deorigin/main(dbf5eedac40, 14 juillet 2026).discourse-aiintégré au core. - Client : reproduit depuis plusieurs navigateurs/appareils (Chrome desktop, Chrome Android, Safari iOS) — le problème étant côté serveur, le client n’a pas d’importance.
Description
Résultat actuel : Dans un sujet public, cliquer sur Réessayer sur une réponse du bot IA ajoute un tout nouveau message du bot au sujet. La réponse originale reste intacte, chaque clic sur Réessayer ajoute donc un nouveau message. N rétentatives → N messages supplémentaires.
Résultat attendu : Réessayer devrait régénérer la réponse existante du bot sur place (en remplaçant son contenu), comme c’est le cas dans une conversation MP / DM avec le bot IA. Aucun nouveau message ne devrait être créé.
Étapes pour reproduire (sur un Discourse neuf)
- Activer Discourse AI + le bot IA ; créer/activer un agent (persona) IA avec un utilisateur bot, et activer « Autoriser les mentions de sujets » afin qu’il puisse répondre dans les sujets publics (
allow_topic_mentions). Ajouter le groupe de votre utilisateur aux groupes autorisés de l’agent et àai_bot_allowed_groups. - Dans un sujet public,
@mentionnerle bot dans un message pour qu’il réponde. - Sur la réponse du bot, ouvrir le menu admin/clé à molette du message et cliquer sur Réessayer (l’action de régénération →
POST /discourse-ai/ai-bot/post/:post_id/retry). - Observer : une nouvelle réponse du bot est ajoutée au lieu de régénérer l’existant. Répéter Réessayer → un message supplémentaire à chaque fois.
- Pour comparaison, faire la même chose dans un MP avec le bot : Réessayer régénère correctement sur place (pas de doublon). La divergence entre MP et sujet public est l’indice.
Reproduction à 100 % sur les sujets publics.
Cause racine (pointeurs de code, origin/main actuel)
BotController#retry_response(plugins/discourse-ai/app/controllers/discourse_ai/ai_bot/bot_controller.rb) met en file d’attenteJobs::CreateAiReplyavecreply_post_id: post.id— c’est-à-dire « régénérer ce message existant ».Jobs::CreateAiReplyle charge en tant quereply_postet le passe àPlayground#reply_to(..., existing_reply_post: reply_post).- Dans
Playground#reply_to(plugins/discourse-ai/lib/ai_bot/playground.rb) :stream_reply = post.topic.private_message? if stream_reply.nil?→falsepour les sujets publics (~L518).existing_reply_postn’est consommé que dans la brancheif stream_reply(reply_post = existing_reply_post, ~L538).- La branche
elsenon-streaming (~L662) appelle inconditionnellementPostCreator.create!(...), ajoutant un nouveau message sans jamais toucher au message en cours de rétentative.
Ainsi, pour tout sujet non-MP, l’intention « régénérer sur place » de retry_response est silencieusement ignorée et un doublon est créé à la place. (Cette même asymétrie signifie que les réponses du bot dans les sujets publics ne sont pas en streaming, ce qui est le comportement préexistant ; le bug réside spécifiquement dans le fait que existing_reply_post de Réessayer est ignoré sur cette voie.)
Correction suggérée (orientation uniquement)
Respecter existing_reply_post indépendamment du streaming — par exemple, dans la branche non-streaming, si existing_reply_post est présent, le réviser au lieu d’appeler PostCreator.create! ; ou découpler la décision « réutiliser le message existant » de stream_reply.
Mode sans échec
N/A — comportement de plugin côté serveur, indépendant des thèmes/JS du site.