236 lines
8.2 KiB
YAML
236 lines
8.2 KiB
YAML
name: invoice_explanation
|
|
version: 2
|
|
start: preparar
|
|
|
|
nodes:
|
|
- id: preparar
|
|
action: preparar_invoice_explanation
|
|
input:
|
|
msisdn: $.input.msisdn
|
|
customer_id: $.input.customer_id
|
|
current_invoice_number: $.input.current_invoice_number
|
|
past_invoice_number: $.input.past_invoice_number
|
|
current_invoice_due_date: $.input.current_invoice_due_date
|
|
past_invoice_due_date: $.input.past_invoice_due_date
|
|
channel: $.input.channel
|
|
tentativa_anterior: $.vars.preparar.tentativa
|
|
invoice_explanation_base: $.input.invoice_explanation_base
|
|
|
|
- id: formatar
|
|
action: formatar_invoice_explanation
|
|
input:
|
|
explicacao_base: $.vars.preparar.explicacao_base
|
|
invoice_detail: $.input.invoice_detail
|
|
# A pausa faz parte do contrato do workflow, não da action de formatação.
|
|
# Depois de apresentar a explicação, sempre aguardamos SIM/NAO antes de
|
|
# entrar em `decisao`. A action `formatar_invoice_explanation` permanece
|
|
# responsável apenas por montar a mensagem.
|
|
pause:
|
|
enabled: true
|
|
return_from: $.output.mensagem
|
|
expected_input:
|
|
key: resposta_usuario
|
|
allowed_values: ["SIM", "NAO", "CONTINUAR"]
|
|
normalize: upper_strip
|
|
reprompt: "Não entendi. Essa explicação resolveu sua dúvida? Responda sim ou não."
|
|
semantic_classifier:
|
|
enabled: true
|
|
include_relevant_context: true
|
|
# Saída sentinela fora de allowed_values. Quando usada, o framework
|
|
# não retoma o workflow e devolve o reprompt declarado acima.
|
|
unmatched_value: OUTRO
|
|
option_actions:
|
|
CONTINUAR:
|
|
action: contextual_reentry
|
|
prompt: |
|
|
Classifique a fala do cliente em uma das opções de {{ allowed_values }}.
|
|
Se a fala não tiver significado suficiente no contexto para escolher com segurança
|
|
SIM, NAO ou CONTINUAR, retorne OUTRO.
|
|
|
|
A pergunta pendente é:
|
|
{{ pending_prompt }}
|
|
|
|
Contexto conversacional relevante imediatamente anterior a esta decisão:
|
|
{{ relevant_conversation_context }}
|
|
|
|
A fala atual do cliente é:
|
|
{{ user_input }}
|
|
|
|
Para este workflow:
|
|
- SIM: use somente quando o cliente indicar entendimento, aceitação ou encerramento da dúvida,
|
|
sem introduzir nova pergunta, hipótese, valor, referência ou fato a validar.
|
|
- NAO: use quando o cliente responder negativamente à pergunta pendente ou disser de forma
|
|
explícita que a explicação não resolveu sua dúvida. Exemplos: "não", "de jeito nenhum",
|
|
"não resolveu", "ainda não entendi".
|
|
- CONTINUAR: use quando a fala for compreensível, mas não responder diretamente SIM ou NAO e,
|
|
considerando o contexto imediatamente anterior, complementar, especificar ou continuar a
|
|
solicitação que originou a pergunta pendente. Inclua novas perguntas, hipóteses, valores,
|
|
referências e fatos propostos pelo cliente que ainda precisem ser validados.
|
|
- OUTRO: use somente quando a fala for incompreensível, desconexa, fragmentária ou não tiver
|
|
significado suficiente para responder à pergunta pendente nem continuar a solicitação.
|
|
|
|
Exemplos:
|
|
- "sim", "legal", "ok", "beleza", "entendi", "obrigado" => SIM
|
|
- "não", "de jeito nenhum", "não resolveu", "ainda não entendi" => NAO
|
|
- contexto: "tem uma cobrança aqui que eu não reconheço"; fala: "é a de quatorze e noventa e nove" => CONTINUAR
|
|
- "então minha fatura ficaria R$ 275,00, certo?" => CONTINUAR
|
|
- "quer dizer que no próximo mês vou pagar menos?" => CONTINUAR
|
|
- palavra isolada ou fragmento sem relação semântica suficiente com a pergunta => OUTRO
|
|
|
|
Regras de segurança:
|
|
- Nunca trate pergunta, hipótese, valor, referência ou fato proposto pelo cliente como concordância.
|
|
- CONTINUAR não confirma nem ratifica nenhum dado dito pelo cliente; apenas solicita reentrada
|
|
contextual para nova validação pelas fontes de negócio.
|
|
- Para fala compreensível, retorne somente uma das opções oferecidas em {{ allowed_values }}.
|
|
- Para fala incompreensível ou sem significado contextual suficiente, retorne somente OUTRO.
|
|
resume_from: decisao
|
|
|
|
- id: checar_tentativa
|
|
action: checar_tentativa_cvn
|
|
input:
|
|
tentativa: $.vars.preparar.tentativa
|
|
|
|
- id: texto_intencao_invalida
|
|
action: montar_resposta_texto
|
|
input:
|
|
dados:
|
|
texto_usuario: "Não consegui validar sua solicitação. Pode informar novamente sobre a sua fatura?"
|
|
|
|
- id: fim_intencao_invalida
|
|
action: montar_resposta_texto
|
|
input:
|
|
dados:
|
|
texto_usuario: "Não foi possível validar sua solicitação neste momento."
|
|
|
|
- id: resposta_falha_servico
|
|
action: montar_resposta_texto
|
|
input:
|
|
dados:
|
|
texto_usuario: "Para continuar com a sua solicitação, aguarde um instante."
|
|
|
|
- id: decisao
|
|
action: no_op
|
|
input: {}
|
|
|
|
- id: registrar_sim
|
|
action: registrar_atendimento_invoice_explanation
|
|
input:
|
|
resposta_usuario: SIM
|
|
|
|
- id: registrar_protocolo_aceite
|
|
action: registrar_protocolo_inicio
|
|
input:
|
|
msisdn: $.input.msisdn
|
|
scenario: invoice_explanation_aceite_fechado
|
|
request_status: Fechado
|
|
status: CLOSED
|
|
workflow_response_final: true
|
|
mensagem_final: "Seu número de protocolo é {protocol}."
|
|
|
|
- id: registrar_nao
|
|
action: registrar_atendimento_invoice_explanation
|
|
input:
|
|
resposta_usuario: NAO
|
|
|
|
# Política de jornada do agente Contas: uma negativa à pergunta de confirmação da
|
|
# explicação transfere o atendimento para continuidade humana. A primitive de
|
|
# HUMAN_HANDOFF é do framework; a decisão e a fraseologia ficam declaradas aqui.
|
|
- id: handoff_pos_explicacao_nao
|
|
action: preparar_handoff_invoice_explanation
|
|
input:
|
|
mensagem: "Para continuar com a sua solicitação, aguarde um instante."
|
|
reason: invoice_explanation_not_resolved
|
|
|
|
# A variação foi causada por VAS avulso ou estratégico? Sem VAS variado não há nada que
|
|
# o bot resolva, e insistir com o orquestrador só gasta turno (SPEC §9 "Explicação da variação recusada").
|
|
- id: checar_vas_variacao
|
|
action: checar_vas_variado
|
|
input:
|
|
invoice_variation: $.input.invoice_variation
|
|
invoice_detail: $.input.invoice_detail
|
|
|
|
# Nó só para nomear o last_node: o backend o mapeia para nao_resolvido em
|
|
# auto_finalize_status_map, e a fala vem do NAO_RESOLVIDO_CLOSING.
|
|
- id: finalizar_nao_resolvido
|
|
action: no_op
|
|
input: {}
|
|
|
|
edges:
|
|
- from: preparar
|
|
to: formatar
|
|
priority: 10
|
|
when:
|
|
eq: [$.vars.preparar.success, true]
|
|
|
|
- from: preparar
|
|
to: resposta_falha_servico
|
|
priority: 20
|
|
when:
|
|
eq: [$.vars.preparar.service_failed, true]
|
|
|
|
- from: preparar
|
|
to: checar_tentativa
|
|
priority: 30
|
|
when:
|
|
eq: [$.vars.preparar.success, false]
|
|
|
|
- from: checar_tentativa
|
|
to: fim_intencao_invalida
|
|
priority: 10
|
|
when:
|
|
eq: [$.vars.checar_tentativa.limite_excedido, true]
|
|
|
|
- from: checar_tentativa
|
|
to: texto_intencao_invalida
|
|
priority: 20
|
|
|
|
- from: formatar
|
|
to: decisao
|
|
|
|
- from: decisao
|
|
to: registrar_sim
|
|
priority: 10
|
|
when:
|
|
eq: [$.input.resposta_usuario, SIM]
|
|
|
|
- from: decisao
|
|
to: registrar_nao
|
|
priority: 20
|
|
when:
|
|
eq: [$.input.resposta_usuario, NAO]
|
|
|
|
- from: registrar_sim
|
|
to: registrar_protocolo_aceite
|
|
|
|
- from: registrar_protocolo_aceite
|
|
to: END
|
|
|
|
- from: registrar_nao
|
|
to: handoff_pos_explicacao_nao
|
|
|
|
- from: handoff_pos_explicacao_nao
|
|
to: END
|
|
|
|
- from: checar_vas_variacao
|
|
to: finalizar_nao_resolvido
|
|
priority: 10
|
|
when:
|
|
eq: [$.vars.checar_vas_variacao.tem_vas_variado, false]
|
|
|
|
# Tem VAS variado (ou não deu para saber): devolve ao orquestrador, como sempre.
|
|
- from: checar_vas_variacao
|
|
to: END
|
|
priority: 20
|
|
|
|
- from: finalizar_nao_resolvido
|
|
to: END
|
|
|
|
- from: texto_intencao_invalida
|
|
to: END
|
|
|
|
- from: fim_intencao_invalida
|
|
to: END
|
|
|
|
- from: resposta_falha_servico
|
|
to: END
|