fix(ai): add current date/time context and enforce strict suite photo filtering
This commit is contained in:
parent
a97da4eadf
commit
8c456e7e98
@ -111,6 +111,9 @@ class Captain::Assistant < ApplicationRecord
|
|||||||
name: name,
|
name: name,
|
||||||
description: description,
|
description: description,
|
||||||
product_name: config['product_name'] || 'this product',
|
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|
|
scenarios: scenarios.enabled.map do |scenario|
|
||||||
{
|
{
|
||||||
title: scenario.title,
|
title: scenario.title,
|
||||||
|
|||||||
@ -52,6 +52,9 @@ class Captain::Scenario < ApplicationRecord
|
|||||||
instructions: resolved_instructions,
|
instructions: resolved_instructions,
|
||||||
tools: resolved_tools,
|
tools: resolved_tools,
|
||||||
assistant_name: assistant.name.downcase.gsub(/\s+/, '_'),
|
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 || [],
|
response_guidelines: response_guidelines || [],
|
||||||
guardrails: guardrails || []
|
guardrails: guardrails || []
|
||||||
}
|
}
|
||||||
|
|||||||
@ -46,7 +46,11 @@ class Captain::Tools::SendSuiteImagesTool < Captain::Tools::BaseTool
|
|||||||
@conversation ||= resolve_conversation(args, params)
|
@conversation ||= resolve_conversation(args, params)
|
||||||
return error_response('Erro técnico ao enviar fotos. Não consegui identificar a conversa atual.') if @conversation.blank?
|
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)
|
selected_items = find_selected_items(actual_params)
|
||||||
return no_images_response(actual_params) if selected_items.blank?
|
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]))
|
items.limit(normalize_limit(actual_params[:limit]))
|
||||||
end
|
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)
|
def send_images(items)
|
||||||
items.count do |item|
|
items.count do |item|
|
||||||
next false unless item.image.attached?
|
next false unless item.image.attached?
|
||||||
|
|||||||
@ -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.
|
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 -%}
|
{% if conversation || contact -%}
|
||||||
# Current Context
|
# Current Context
|
||||||
|
|
||||||
|
|||||||
@ -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
|
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 %}
|
{% if conversation || contact %}
|
||||||
# Current Context
|
# Current Context
|
||||||
|
|
||||||
|
|||||||
22
progresso/adicionando_data_hora_contexto_ia.md
Normal file
22
progresso/adicionando_data_hora_contexto_ia.md
Normal 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?".
|
||||||
16
progresso/correcao_ferramenta_fotos.md
Normal file
16
progresso/correcao_ferramenta_fotos.md
Normal 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.
|
||||||
Loading…
Reference in New Issue
Block a user