diff --git a/enterprise/app/jobs/captain/hermes/outgoing_job.rb b/enterprise/app/jobs/captain/hermes/outgoing_job.rb index aadb97604..1724afe41 100644 --- a/enterprise/app/jobs/captain/hermes/outgoing_job.rb +++ b/enterprise/app/jobs/captain/hermes/outgoing_job.rb @@ -55,17 +55,24 @@ class Captain::Hermes::OutgoingJob < ApplicationJob # Concatena texto de todas as msgs incoming entre a última resposta real # (não-reaction) do agente e a msg âncora. Retorna nil se só tem 1 msg # (pra dispatch usar message.content normal). + # + # Atenção: usa `reorder` em vez de `order` porque o model Message tem + # default_scope `order(created_at: :asc)` — sem reorder, a SQL final fica + # `ORDER BY created_at ASC, created_at DESC` e o ASC ganha. Resultado: + # last_real_outgoing virava a MAIS ANTIGA, agrupando msgs de turns + # passados (caso real: Hermes recebia "wifi+pet" colado mesmo em turns + # separados — visto em conv 6064 em 2026-05-02). def combined_incoming_content(conversation, anchor_message) last_real_outgoing = conversation.messages .where(message_type: :outgoing) .where("(content_attributes ->> 'is_reaction') IS NULL OR (content_attributes ->> 'is_reaction') != 'true'") - .order(created_at: :desc) + .reorder(created_at: :desc) .first scope = conversation.messages.where(message_type: :incoming).where('created_at <= ?', anchor_message.created_at) scope = scope.where('created_at > ?', last_real_outgoing.created_at) if last_real_outgoing - texts = scope.order(:created_at).pluck(:content).map(&:to_s).reject(&:blank?).uniq + texts = scope.reorder(created_at: :asc).pluck(:content).map(&:to_s).reject(&:blank?).uniq return nil if texts.size <= 1 Rails.logger.info("[Captain::Hermes::Debounce] agrupando #{texts.size} msgs do cliente em conv #{conversation.id}")