"Nao use markdown. Nao escreva texto fora do JSON. Nao invente dados ausentes.\n\n"
"Formato obrigatorio:\n"
f"{schema_example}\n\n"
"Regras para turn_decision:\n"
"- 'turn_decision' deve seguir o contrato de decisao por turno.\n"
"- 'domain' deve ser review, sales ou general.\n"
"- 'intent' deve refletir a intencao principal do turno completo.\n"
"- 'action' deve ser uma das acoes do contrato.\n"
"- Se faltar dado para continuar um fluxo, use action='ask_missing_fields' e preencha 'missing_fields' e 'response_to_user'.\n"
"- Se nao houver acao operacional, use action='answer_user'.\n"
"- Em pedidos de compra com faixa de preco ou orcamento (ex.: '70 mil', 'ate 50 mil', 'R$ 45000'), preencha entities.generic_memory.orcamento_max.\n"
"- Em pedidos com tipo de carro (ex.: suv, sedan, hatch, pickup), preencha entities.generic_memory.perfil_veiculo.\n"
"- Se o usuario quiser efetivar a compra de um veiculo, use intent='order_create', domain='sales' e prefira tool_name='realizar_pedido'.\n"
"- Se o usuario quiser listar pedidos, use intent='order_list', domain='sales', action='call_tool' e tool_name='listar_pedidos'.\n"
"- Se o usuario quiser listar revisoes, use intent='review_list', domain='review', action='call_tool' e tool_name='listar_agendamentos_revisao'.\n"
"- Se o usuario quiser cancelar revisao, use intent='review_cancel', domain='review' e prefira tool_name='cancelar_agendamento_revisao'.\n"
"- Se o usuario quiser remarcar revisao, use intent='review_reschedule', domain='review' e prefira tool_name='editar_data_revisao'.\n\n"
"Regras para message_plan:\n"
"- 'message_plan.orders' deve listar os pedidos operacionais em ordem de aparicao.\n"
"- Se houver mais de um pedido operacional, separe em itens distintos.\n"
"- Se nao houver pedido operacional, use domain='general' com a mensagem inteira.\n"
"- Cada item deve conter 'domain', 'message' e 'entities'.\n"
"- Mantenha cada 'message' curta e fiel ao texto do usuario.\n"
"- Em pedidos de compra com faixa de preco ou orcamento (ex.: '70 mil', 'ate 50 mil', 'R$ 45000'), preencha entities.generic_memory.orcamento_max.\n"
"- Em pedidos com tipo de carro (ex.: suv, sedan, hatch, pickup), preencha entities.generic_memory.perfil_veiculo.\n\n"
"Regras gerais:\n"
"- turn_decision resume a intencao principal do turno completo.\n"
"- message_plan.orders separa pedidos operacionais em ordem de aparicao; se nao houver pedido operacional, use um unico item general com a mensagem inteira.\n"
"- Cada item de orders deve conter domain, message e entities. Mantenha message curta e fiel ao texto do usuario.\n"
"- domain deve ser review, sales ou general.\n"
"- Em pedidos de compra com faixa de preco ou orcamento (ex.: 70 mil, ate 50 mil, R$ 45000), preencha entities.generic_memory.orcamento_max nas secoes relevantes.\n"
"- Em pedidos com tipo de carro (ex.: suv, sedan, hatch, pickup), preencha entities.generic_memory.perfil_veiculo nas secoes relevantes.\n"
"- Se faltar dado para continuar um fluxo, use action=ask_missing_fields e preencha missing_fields e response_to_user.\n"
"- Se nao houver acao operacional, use action=answer_user.\n"
"- Se o usuario quiser efetivar a compra de um veiculo, use intent=order_create, domain=sales e prefira tool_name=realizar_pedido.\n"
"- Se o usuario quiser listar pedidos, use intent=order_list, domain=sales, action=call_tool e tool_name=listar_pedidos.\n"
"- Se o usuario quiser consultar estoque com filtros de compra, use intent=inventory_search e domain=sales.\n"
"- Se o usuario quiser listar revisoes, use intent=review_list, domain=review, action=call_tool e tool_name=listar_agendamentos_revisao.\n"
"- Se o usuario quiser cancelar revisao, use intent=review_cancel, domain=review e prefira tool_name=cancelar_agendamento_revisao.\n"
"- Se o usuario quiser remarcar revisao, use intent=review_reschedule, domain=review e prefira tool_name=editar_data_revisao.\n"
"- Se o usuario quiser avaliar um veiculo na troca e houver modelo, ano e km, use domain=sales, action=call_tool, tool_name=avaliar_veiculo_troca e informe esses campos em tool_arguments.\n\n"
f"Contexto: {user_context}\n"
f"Mensagem do usuario: {message}"
)
@ -144,6 +159,8 @@ class MessagePlanner:
}
ifhas_turn_decisionandhas_message_plan:
returnbundle
ifhas_turn_decisionorhas_message_plan:
returnbundle
ifattempt==0:
logger.warning(
"Bundle estruturado incompleto; repetindo uma vez. user_id=%s has_turn_decision=%s has_message_plan=%s",