Files
agent_contas/docs/FIX_CONTAS_RESIDUAL_CONVERSATION_PARITY_20260831.md

3.8 KiB

Correção de paridade conversacional residual do Contas — 2026-08-31

Escopo

Correções pontuais extraídas do comportamento útil do Contas anterior sem restaurar o runtime legado:

  • retenção antes de handoff humano;
  • jurídico/Anatel/Procon com dependência de entidade previamente em foco;
  • três falas consecutivas realmente incompreensíveis;
  • preservação do pós-finalização no framework, com status terminal de erro respeitado;
  • cancelamento múltiplo por entidades nomeadas/contextuais e por "todos os VAS avulsos".

Arquitetura

Foi adicionada app/domain/contas/conversation_policy.py, executada depois do EnterpriseRouter e antes do agente de domínio. A policy não executa side effects: apenas reprompta, enriquece contexto ou altera o roteamento. Toda operação transacional continua passando pelo AgentRuntimeMixin, pré-validação MCP, confirmação explícita e workflow do Contas.

Retenção

Quando o router solicita handoff humano, a policy procura evidência autoritativa de VAS avulso que participou da variação da conta usando varied_avulso_items. Sem evidência, o handoff segue normalmente. Com evidência, a policy oferece dois degraus: explicação da variação e, em seguida, tratamento dos VAS identificados. Recusa do segundo degrau leva ao handoff humano normal.

O aceite do tratamento cria reentrada contextual com os nomes já comprovados; o cliente não precisa repeti-los e a transação continua sujeita à pré-validação e confirmação.

Jurídico / Anatel / Procon

A mera ameaça regulatória não cria uma transação. Sem entidade concreta em foco, a fala é encaminhada como reclamação ampla ao suporte, sem MCP transacional. Quando já existe subject/items em estado transacional, o foco é preservado e a fala pode continuar no fluxo correspondente. A fatura inteira nunca é usada para inventar o alvo.

Três falas incompreensíveis

Foi criada a intent semântica contas_no_match, exclusiva para fala sem conteúdo recuperável. fallback genérico não conta como incompreensão. O contador é consecutivo e reinicia em qualquer turno compreendido.

  • 1ª: pede reformulação;
  • 2ª: pede reformulação;
  • 3ª: encerra pelo nó global end_session, chamando finalizar_atendimento com status=erro_no_match.

O limite pode ser configurado por CONTAS_NO_MATCH_MAX_CONSECUTIVE, default 3.

Cancelamento múltiplo

validar_vas_subject agora resolve múltiplas entidades exclusivamente contra catálogo autorizado VAS/fatura. Exemplos suportados após extração semântica contextual:

  • cancela Netflix e HBO;
  • os dois / ambos, quando o extrator LLM consegue resolver os nomes pelo contexto imediato;
  • todos os VAS avulsos.

todos genérico não expande em massa. Para "todos os VAS avulsos", itens estratégicos/bundle são filtrados pela política de domínio. Os itens resolvidos são enviados como items[] para o workflow batch existente, com uma única confirmação explícita antes da execução.

Pós-finalização

Não foi criado runtime duplicado. O lifecycle continua no framework. O nó end_session passou apenas a respeitar um terminal_status já definido pela policy (por exemplo erro_no_match) e uma mensagem terminal específica, mantendo o mecanismo atual de replay/soft reset.

Testes

Novos testes:

  • tests/migration/test_contas_conversation_policy_residuals.py;
  • tests/migration/test_multiple_vas_subject_resolution.py.

Regressão direcionada: 61 PASS.

Regressão completa tests/migration: 810 PASS / 2 FAIL. Os mesmos dois FAIL foram reproduzidos no ZIP original sem estas alterações, portanto são falhas preexistentes e fora do escopo desta correção:

  1. test_validar_contestacao_aprova_quando_item_e_valor_sao_comprovados;
  2. test_termino_desconto_e_valor_divergente_preservam_semantica_do_original.