fix(ai): add current date/time context and enforce strict suite photo filtering

This commit is contained in:
Rodrigo Borba 2026-02-26 19:12:25 -03:00
parent a97da4eadf
commit 8c456e7e98
7 changed files with 59 additions and 29 deletions

View File

@ -111,6 +111,9 @@ class Captain::Assistant < ApplicationRecord
name: name,
description: description,
product_name: config['product_name'] || 'this product',
current_date: Time.current.in_time_zone('Brasilia').strftime('%d/%m/%Y'),
current_time: Time.current.in_time_zone('Brasilia').strftime('%H:%M'),
current_timezone: 'Horário de Brasília (BRT/BRST)',
scenarios: scenarios.enabled.map do |scenario|
{
title: scenario.title,

View File

@ -52,6 +52,9 @@ class Captain::Scenario < ApplicationRecord
instructions: resolved_instructions,
tools: resolved_tools,
assistant_name: assistant.name.downcase.gsub(/\s+/, '_'),
current_date: Time.current.in_time_zone('Brasilia').strftime('%d/%m/%Y'),
current_time: Time.current.in_time_zone('Brasilia').strftime('%H:%M'),
current_timezone: 'Horário de Brasília (BRT/BRST)',
response_guidelines: response_guidelines || [],
guardrails: guardrails || []
}

View File

@ -46,7 +46,11 @@ class Captain::Tools::SendSuiteImagesTool < Captain::Tools::BaseTool
@conversation ||= resolve_conversation(args, params)
return error_response('Erro técnico ao enviar fotos. Não consegui identificar a conversa atual.') if @conversation.blank?
enrich_suite_filters_from_conversation!(actual_params)
if actual_params[:suite_category].blank? && actual_params[:suite_number].blank?
return error_response(
'Erro: Para buscar fotos, é obrigatório informar o parâmetro suite_category ou suite_number correspondente ao pedido do cliente.'
)
end
selected_items = find_selected_items(actual_params)
return no_images_response(actual_params) if selected_items.blank?
@ -173,34 +177,6 @@ class Captain::Tools::SendSuiteImagesTool < Captain::Tools::BaseTool
items.limit(normalize_limit(actual_params[:limit]))
end
def enrich_suite_filters_from_conversation!(actual_params)
return if normalize_filter(actual_params[:suite_number]).present?
inferred_suite = infer_suite_number_from_last_incoming_message
return if inferred_suite.blank?
actual_params[:suite_number] = inferred_suite
end
def infer_suite_number_from_last_incoming_message
text = last_incoming_text
return nil if text.blank?
# Captura "suite 110", "suíte 110", "suite n 110", "suite nº 110".
match = text.match(/\bsu[ií]te\s*(?:n(?:u|ú)?m(?:ero)?\.?\s*)?(?:n[ºo]\s*)?([a-z0-9_-]{1,20})\b/i)
return nil if match.blank?
normalize_filter(match[1])
end
def last_incoming_text
@conversation.messages
.where(message_type: :incoming)
.order(created_at: :desc)
.limit(1)
.pick(:content)
end
def send_images(items)
items.count do |item|
next false unless item.image.attached?

View File

@ -8,6 +8,11 @@ You are {{name}}, a helpful and knowledgeable assistant. Your role is to primari
Don't digress away from your instructions, and use all the available tools at your disposal for solving customer issues. If you are to state something factual about {{product_name}} ensure you source that information from the FAQs only. Use the `captain--tools--faq_lookup` tool for this.
# Data e Hora Atual
- Data: {{ current_date }}
- Hora: {{ current_time }}
- Fuso Horário: {{ current_timezone }}
{% if conversation || contact -%}
# Current Context

View File

@ -8,6 +8,11 @@ You are a specialized agent called "{{ title }}", your task is to handle the fol
If you believe the user's request is not within the scope of your role, you can assign this conversation back to the orchestrator agent using the `handoff_to_{{ assistant_name }}` tool
# Data e Hora Atual
- Data: {{ current_date }}
- Hora: {{ current_time }}
- Fuso Horário: {{ current_timezone }}
{% if conversation || contact %}
# Current Context

View File

@ -0,0 +1,22 @@
# Adicionando Data e Hora Atual no Contexto da IA
**Objetivo:** Permitir que tanto o Assistente Principal quanto os Cenários da IA tenham ciência da data, hora e fuso horário atuais (Brasília) para melhor precisão em tarefas e respostas rotineiras (ex: "Que dia é hoje?", agendamentos, etc).
**Arquivos Alterados:**
- `enterprise/app/models/captain/assistant.rb` (Método `prompt_context`)
- `enterprise/app/models/captain/scenario.rb` (Método `prompt_context`)
- `enterprise/lib/captain/prompts/assistant.liquid` (Template principal da IA)
- `enterprise/lib/captain/prompts/scenario.liquid` (Template dos cenários da IA)
**Implementação:**
1. Injetadas no backend as variáveis:
- `current_date: Time.current.in_time_zone('Brasilia').strftime('%d/%m/%Y')`
- `current_time: Time.current.in_time_zone('Brasilia').strftime('%H:%M')`
- `current_timezone: 'Horário de Brasília (BRT/BRST)'`
2. Modificados os arquivos de template Liquid para exibir este contexto logo acima de `# Current Context`.
**Risco/Trade-offs Controlados:**
Ocupa cerca de ~15 tokens fixos no system prompt com os dados temporais. É um custo mínimo garantindo excelente retorno para a percepção humana da inteligência e capacidade situacional da IA.
**Como Validar:**
Basta conversar com a IA e questionar "Que horas são agora?" ou "Qual a data de hoje?".

View File

@ -0,0 +1,16 @@
# Correção do Envio de Fotos (send_suite_images_tool)
**Objetivo:** Garantir que a IA envie fotos condizentes com o pedido do cliente (por Categoria ou Número da Suíte), resolvendo o bug onde a IA enviava fotos de categorias erradas e misturadas por causa de inferência baseada em regex.
**Arquivos Alterados:**
- `enterprise/app/services/captain/tools/send_suite_images_tool.rb`
**Implementação:**
1. Foi removido o bloco que tentava inferir (`infer_suite_number_from_last_incoming_message`) o parâmetro `suite_number` a partir da última mensagem usando um Regex falho (que confundia nomes de categorias, ex: "alexa", julgando-as como `suite_number`).
2. Adicionada validação estrita no início do método `execute`:
- A ferramenta foi forçada a exigir ou `suite_category` ou `suite_number`.
- Se os dois estiverem em branco, agora retorna `error_response` guiando a IA: *"Erro: Para buscar fotos, é obrigatório informar o parâmetro suite_category ou suite_number correspondente ao pedido do cliente."*
3. Com o erro explícito devolvido à LLM e sem a inferência mágica de background, o agente será forçado a preencher os parâmetros corretos para que a query do ActiveRecord filtre perfeitamente a categoria.
**Como Validar:**
Basta pedir: "Me manda foto da suíte alexa". A IA vai chamar a ferramenta passando `suite_category: "alexa"` e receberá apenas as fotos da categoria Alexa.