From cd519a73c401a4b0bca524051b1f2bf572fde082 Mon Sep 17 00:00:00 2001 From: Rodribm10 Date: Fri, 1 May 2026 15:24:57 -0300 Subject: [PATCH] fix(captain): converte markdown bold pra formato WhatsApp no callback Hermes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Hermes (e LLMs default em geral) emitem **negrito** no formato markdown padrão. WhatsApp usa formato próprio: *negrito* (single asterisk). Sem conversão, o cliente vê asteriscos literais no WhatsApp, parecendo bug. Defesa em camadas: 1. SOUL.md da Valentina foi atualizado com regra explícita de formato WhatsApp (single asterisk pra bold, underscore pra itálico, etc). 2. Este controller faz normalização defensiva no callback recebido do Hermes: regex `**texto**` -> `*texto*` antes de criar a mensagem outgoing. Não afeta o resto do conteúdo. normalize_for_whatsapp() é trivialmente reversível e idempotente (executar 2x é igual a 1x). Co-Authored-By: Claude Opus 4.7 (1M context) --- .../captain/hermes_callback_controller.rb | 27 +++++++++++++++---- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/app/controllers/webhooks/captain/hermes_callback_controller.rb b/app/controllers/webhooks/captain/hermes_callback_controller.rb index 563dff60c..cad7174c5 100644 --- a/app/controllers/webhooks/captain/hermes_callback_controller.rb +++ b/app/controllers/webhooks/captain/hermes_callback_controller.rb @@ -21,16 +21,13 @@ class Webhooks::Captain::HermesCallbackController < ApplicationController before_action :fetch_inbox def process_payload - content = params[:content].to_s.strip + content = extract_content return head :bad_request if content.blank? conversation = recent_conversation_for(@inbox) return log_no_conversation_and_ack if conversation.blank? - Rails.logger.info( - "[Hermes::Callback] reply received for conv #{conversation.display_id} (#{content.length} chars)" - ) - + log_reply(conversation, content) create_outgoing_message(conversation, content) head :ok rescue StandardError => e @@ -73,6 +70,26 @@ class Webhooks::Captain::HermesCallbackController < ApplicationController head :ok end + def extract_content + normalize_for_whatsapp(params[:content].to_s.strip) + end + + # Converte markdown padrão (que LLMs default usam) pra formato WhatsApp: + # **negrito** -> *negrito* + # WhatsApp usa single asterisk pra bold; double asterisk aparece literal + # pro cliente, parecendo bug. Defesa caso o SOUL.md não convença o LLM. + def normalize_for_whatsapp(content) + return content if content.blank? + + content.gsub(/\*\*([^*\n]+?)\*\*/, '*\1*') + end + + def log_reply(conversation, content) + Rails.logger.info( + "[Hermes::Callback] reply received for conv #{conversation.display_id} (#{content.length} chars)" + ) + end + def create_outgoing_message(conversation, content) assistant = conversation.inbox.captain_assistant sender = assistant.presence || User.find_by(id: conversation.assignee_id)