Projeto do Agent Contas ORACLE
This commit is contained in:
472
docs/MANUAL_AGENT_CONTAS_MIGRADO.md
Normal file
472
docs/MANUAL_AGENT_CONTAS_MIGRADO.md
Normal file
@@ -0,0 +1,472 @@
|
||||
# Manual do Agent Contas Migrado para agent_framework_oci
|
||||
|
||||
## 1. Objetivo
|
||||
|
||||
Esta versão reconstrói o Agent Contas sobre o `agent_framework_oci` com uma regra arquitetural simples: **o código executável novo não depende do pacote anterior do Contas**. O projeto anterior é apenas referência funcional para preservar regras, contratos de API, fixtures e comportamentos de negócio durante a migração.
|
||||
|
||||
O agente novo reutiliza do framework tudo que é infraestrutura genérica: LangGraph, router, stickiness, supervisor, confirmação transacional, clarificação, memória, summary memory, long-term memory, checkpoints, persistence, RAG, embeddings, MCP Tool Router, guardrails, output supervisor, judges, identity, channels, SSE, usage accounting e telemetria.
|
||||
|
||||
O novo domínio Contas mantém somente o que é realmente específico da TIM: chamadas de faturas, VAS, contestação, protocolos, tracking, SMS, Secure PDF e regras que relacionam essas operações.
|
||||
|
||||
## 2. Regra de independência
|
||||
|
||||
A Definition of Done da migração é:
|
||||
|
||||
```bash
|
||||
grep -R "agente_contas_tim" app mcp config
|
||||
```
|
||||
|
||||
Resultado esperado: nenhuma ocorrência/import do pacote anterior.
|
||||
|
||||
O pacote entregue já inclui `tests/migration/test_no_legacy_dependency.py` para impedir regressão dessa regra.
|
||||
|
||||
## 3. Arquitetura
|
||||
|
||||
```text
|
||||
Canal / Frontend
|
||||
|
|
||||
v
|
||||
app/main.py
|
||||
|
|
||||
v
|
||||
agent_framework_oci
|
||||
|-- ChannelGateway / IdentityResolver
|
||||
|-- LangGraph / AgentWorkflow
|
||||
|-- EnterpriseRouter / Route Stickiness / Supervisor
|
||||
|-- Guardrails / Output Supervisor / Judges
|
||||
|-- Memory / Summary Memory / LTM / Checkpoints
|
||||
|-- RAG / Embeddings / Cache
|
||||
|-- MCPToolRouter
|
||||
|-- Langfuse / Analytics / OTEL / OCI Streaming
|
||||
|
|
||||
v
|
||||
MCP Contas :8400
|
||||
|
|
||||
v
|
||||
app/domain/contas
|
||||
|-- TimApiClient
|
||||
|-- ContasDomainService
|
||||
`-- fixtures de desenvolvimento
|
||||
|
|
||||
v
|
||||
APIs TIM
|
||||
```
|
||||
|
||||
Não existe um segundo LangGraph, LLM gateway, confirmation manager, workflow engine ou memory store dentro do MCP.
|
||||
|
||||
## 4. Agentes de domínio
|
||||
|
||||
A versão migrada possui quatro agentes reais do domínio Contas:
|
||||
|
||||
| Agente | Responsabilidade |
|
||||
|---|---|
|
||||
| `faturas_agent` | Consulta de faturas, composição, variação e explicação de cobrança |
|
||||
| `vas_agent` | Consulta de VAS, histórico, serviços estratégicos/bundles e informação de serviços |
|
||||
| `contestacao_agent` | Cancelamento transacional de VAS e contestação de cobrança |
|
||||
| `suporte_contas_agent` | Protocolos, acompanhamento, suporte e encerramento |
|
||||
|
||||
Todos herdam `AgentRuntimeMixin` do framework. Eles não implementam máquina de confirmação/clarificação própria.
|
||||
|
||||
## 5. LangGraph do framework
|
||||
|
||||
O fluxo principal é o `StateGraph` do `agent_framework_oci` usado em `app/workflows/agent_graph.py`:
|
||||
|
||||
```text
|
||||
START
|
||||
-> input_guardrails
|
||||
-> load_long_term_memory
|
||||
-> routing_decision
|
||||
-> agente de domínio
|
||||
-> output_supervisor
|
||||
-> output_guardrails
|
||||
-> judge
|
||||
-> supervisor_review
|
||||
-> persist_long_term_memory
|
||||
-> persist
|
||||
-> END
|
||||
```
|
||||
|
||||
O `EnterpriseRouter` decide a intent, agente e tools. O route stickiness decide continuidade da conversa. O runtime do framework controla coleta de parâmetros e confirmação de tools transacionais.
|
||||
|
||||
## 6. Transações
|
||||
|
||||
As tools abaixo são transacionais em `config/tool_policies.yaml`:
|
||||
|
||||
- `cancelar_vas_avulso`
|
||||
- `tratar_vas_estrategico`
|
||||
- `contestar_cobranca`
|
||||
|
||||
A confirmação ocorre **antes** da chamada MCP e é responsabilidade do `AgentRuntimeMixin`. O domínio recebe a chamada somente depois de a política do framework permitir execução.
|
||||
|
||||
Isso evita o problema clássico de um "sim" responder à pergunta errada: a confirmação está vinculada ao estado transacional/tool pendente do framework, não a heurísticas no prompt.
|
||||
|
||||
## 7. RAG
|
||||
|
||||
Conhecimento conceitual não é uma API TIM e por isso não é implementado como "workflow de busca" dentro do MCP.
|
||||
|
||||
O projeto usa diretamente:
|
||||
|
||||
- `RagService`
|
||||
- `create_embedding_provider()`
|
||||
- `VECTOR_STORE_PROVIDER`
|
||||
- `GRAPH_STORE_PROVIDER`
|
||||
- `EMBEDDING_PROVIDER`
|
||||
|
||||
`buscar_informacao` permanece desabilitada no catálogo MCP; perguntas de conhecimento passam pelo RAG nativo do framework.
|
||||
|
||||
## 8. Funcionalidades migradas
|
||||
|
||||
| Funcionalidade do Contas | Nova implementação | Responsabilidade do framework |
|
||||
|---|---|---|
|
||||
| Consulta de faturas | `ContasDomainService.consultar_faturas` | seleção da tool, identity, cache, resposta |
|
||||
| Explicação de fatura | API de fatura + billing analysis como evidência | LLM produz explicação grounded |
|
||||
| Consulta VAS | `consultar_vas` | routing/tool selection |
|
||||
| Histórico VAS | `consultar_historico_vas` | routing/tool selection |
|
||||
| Cancelamento VAS avulso | consulta -> match -> bloqueio -> cancelamento | parâmetros + confirmação + estado |
|
||||
| VAS estratégico/bundle | domínio retorna serviço e orientação | conversa/continuidade no LangGraph |
|
||||
| Contestação | faturas/contrato/profile -> protocolo -> contestação -> tracking | parâmetros + confirmação + estado |
|
||||
| Status de solicitação | `consultar_status_solicitacao` | roteamento e contexto |
|
||||
| SMS | `enviar_sms` | tool policy/contexto |
|
||||
| Secure PDF | `recuperar_fatura_pdf` | roteamento/identity |
|
||||
| Encerramento | efeitos de domínio opcionais | `end_session`, memória e telemetria |
|
||||
| Guardrails | nenhum código local duplicado | framework |
|
||||
| Judges | nenhum código local duplicado | framework |
|
||||
| Memória | nenhum store local de conversa | framework |
|
||||
| LTM | nenhum mecanismo local | framework |
|
||||
| Checkpoint | nenhum `MemorySaver` dentro do MCP | framework |
|
||||
| Telemetria | eventos do runtime/framework | framework |
|
||||
|
||||
## 9. Estrutura do projeto
|
||||
|
||||
```text
|
||||
app/
|
||||
main.py
|
||||
state.py
|
||||
agents/
|
||||
faturas_agent.py
|
||||
vas_agent.py
|
||||
contestacao_agent.py
|
||||
suporte_contas_agent.py
|
||||
domain/contas/
|
||||
client.py
|
||||
service.py
|
||||
fixtures/
|
||||
workflows/
|
||||
agent_graph.py
|
||||
observability/
|
||||
|
||||
config/
|
||||
routing.yaml
|
||||
tools.yaml
|
||||
tool_policies.yaml
|
||||
mcp_servers.yaml
|
||||
mcp_parameter_mapping.yaml
|
||||
identity.yaml
|
||||
prompts/
|
||||
|
||||
contas_mcp/servers/contas_mcp_server/
|
||||
main.py
|
||||
|
||||
agent_framework_oci/
|
||||
... framework reutilizado ...
|
||||
```
|
||||
|
||||
## 10. Arquivo `.env`
|
||||
|
||||
O `.env` fornecido para esta reconstrução foi preservado byte a byte no pacote. Não foi recomposto nem reduzido.
|
||||
|
||||
O arquivo contém dois grupos:
|
||||
|
||||
1. configurações do `agent_framework_oci`;
|
||||
2. variáveis TIM de domínio/compatibilidade já compiladas para os ambientes.
|
||||
|
||||
Embora algumas variáveis antigas possam deixar de ser usadas depois da migração, elas foram mantidas para não perder o trabalho de consolidação. A remoção deve ocorrer apenas após testes de DEV/FQA/PRD.
|
||||
|
||||
### Variáveis principais do framework
|
||||
|
||||
- `LLM_PROVIDER`
|
||||
- `OCI_AUTH_MODE`, `OCI_CONFIG_FILE`, `OCI_PROFILE`, `OCI_COMPARTMENT_ID`, `OCI_REGION`
|
||||
- `SESSION_REPOSITORY_PROVIDER`
|
||||
- `MEMORY_REPOSITORY_PROVIDER`
|
||||
- `CHECKPOINT_REPOSITORY_PROVIDER`
|
||||
- `VECTOR_STORE_PROVIDER`
|
||||
- `GRAPH_STORE_PROVIDER`
|
||||
- `EMBEDDING_PROVIDER`
|
||||
- `ENABLE_LANGFUSE`
|
||||
- `ENABLE_INPUT_GUARDRAILS`
|
||||
- `ENABLE_OUTPUT_GUARDRAILS`
|
||||
- `ENABLE_JUDGES`
|
||||
- `ENABLE_SUPERVISOR`
|
||||
- `ENABLE_ROUTE_STICKINESS`
|
||||
- `ENABLE_MCP_TOOLS`
|
||||
- `ENABLE_CONVERSATION_SUMMARY_MEMORY`
|
||||
- `ENABLE_LONG_TERM_MEMORY`
|
||||
|
||||
### Modo mock x APIs TIM reais
|
||||
|
||||
Mock atual:
|
||||
|
||||
```env
|
||||
TIM_GATEWAY_MODE=mock
|
||||
TIM_USE_MOCK_GATEWAY=true
|
||||
```
|
||||
|
||||
Integrações reais:
|
||||
|
||||
```env
|
||||
TIM_GATEWAY_MODE=real
|
||||
TIM_USE_MOCK_GATEWAY=false
|
||||
```
|
||||
|
||||
Os dois valores devem estar coerentes.
|
||||
|
||||
## 11. Integrações TIM
|
||||
|
||||
| Integração | Variável | Método | VPN TIM provável |
|
||||
|---|---|---|---|
|
||||
| Complete Invoices | `TIM_COMPLETE_INVOICES_URL` | POST | Sim em FQA interno |
|
||||
| Billing Analysis | `TIM_DIVERGENCIA_URL` | POST | Sim |
|
||||
| Consulta VAS | `TIM_URL_CONSULTA_VAS` | GET | Sim |
|
||||
| Histórico VAS | `TIM_VAS_HISTORY_URL` | GET | Sim |
|
||||
| Bloqueio VAS | `TIM_URL_BLOQUEIO_VAS` | POST | Sim |
|
||||
| Cancelamento VAS | `TIM_CANCELAMENTO_URL` | DELETE | Sim |
|
||||
| Contrato | `TIM_CONTRATO_URL` | GET | Sim |
|
||||
| Full Profile | `TIM_PROFILE_FULL_URL` | GET | Sim |
|
||||
| Contestação | `TIM_CUSTOMER_CONTESTATION_URL` | POST | Sim |
|
||||
| Protocolo | `TIM_PROTOCOL_URL` | POST | Sim |
|
||||
| Service Request Status | `TIM_SERVICE_REQUEST_STATUS_URL` | POST | Sim |
|
||||
| Tracking Activities | `TIM_TRACKING_ACTIVITIES_URL` | POST | Sim |
|
||||
| SMS | `TIM_SMS_URL` | POST | Sim |
|
||||
| Secure PDF | `TIM_URL_INVOICE_RECOVER` | POST | Sim |
|
||||
|
||||
Os endpoints FQA do `.env` usam `pmidfqa.internal.timbrasil.com.br`; portanto DNS/rota corporativa precisa estar disponível para teste real.
|
||||
|
||||
## 12. Outras integrações
|
||||
|
||||
| Integração | Uso | Ativação |
|
||||
|---|---|---|
|
||||
| OCI GenAI | LLM | `LLM_PROVIDER=oci_sdk` + `OCI_AUTH_MODE` |
|
||||
| Autonomous DB | session/memory/checkpoint/vector/usage | providers `autonomous` + `ADB_*` |
|
||||
| OCI Embeddings | RAG | `EMBEDDING_PROVIDER=oci` |
|
||||
| Langfuse | tracing | `ENABLE_LANGFUSE=true` |
|
||||
| GCP Pub/Sub | analytics corporativo | `ENABLE_ANALYTICS=true`, provider Pub/Sub e credencial GCP |
|
||||
| MongoDB | sequence Pub/Sub | `PUBSUB_SEQUENCE_PROVIDER=mongodb` |
|
||||
| Redis | cache/sequence opcional | `ENABLE_REDIS_CACHE=true` ou provider sequence redis |
|
||||
| OTEL | logs/traces | `ENABLE_OTEL=true` + endpoint |
|
||||
| OCI Streaming | eventos alternativos | `ENABLE_OCI_STREAMING=true` |
|
||||
|
||||
## 13. Instalação local
|
||||
|
||||
Recomendado: Linux/WSL com Python 3.13.
|
||||
|
||||
```bash
|
||||
cd contas_migrado_framework_native
|
||||
uv sync
|
||||
```
|
||||
|
||||
Se o `uv` ainda não estiver disponível, instale-o conforme o padrão do seu ambiente e depois execute `uv sync`.
|
||||
|
||||
## 14. Subir o MCP Contas
|
||||
|
||||
Terminal 1:
|
||||
|
||||
```bash
|
||||
uv run uvicorn contas_mcp.servers.contas_mcp_server.main:app \
|
||||
--host 0.0.0.0 --port 8400
|
||||
```
|
||||
|
||||
Validar:
|
||||
|
||||
```bash
|
||||
curl http://localhost:8400/health
|
||||
curl http://localhost:8400/mcp/tools/list
|
||||
```
|
||||
|
||||
`/health` deve reportar:
|
||||
|
||||
```json
|
||||
{
|
||||
"status": "ok",
|
||||
"architecture": "framework-native",
|
||||
"legacy_dependency": false
|
||||
}
|
||||
```
|
||||
|
||||
## 15. Subir o Agent Contas
|
||||
|
||||
Terminal 2:
|
||||
|
||||
```bash
|
||||
uv run uvicorn app.main:app --host 0.0.0.0 --port 8000
|
||||
```
|
||||
|
||||
Validar:
|
||||
|
||||
```bash
|
||||
curl http://localhost:8000/health
|
||||
```
|
||||
|
||||
## 16. Smoke test do MCP em mock
|
||||
|
||||
```bash
|
||||
PYTHONPATH=".:agent_framework_oci/libs/agent_framework/src" \
|
||||
python scripts/smoke_mcp.py
|
||||
```
|
||||
|
||||
Esse teste cobre faturas, invoice explanation, VAS, histórico, cancelamento e contestação usando fixtures migradas para o novo domínio.
|
||||
|
||||
## 17. Testar o agente pelo Gateway
|
||||
|
||||
Exemplo de consulta:
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:8000/gateway/message \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{
|
||||
"channel":"web",
|
||||
"agent_id":"telecom_contas",
|
||||
"tenant_id":"default",
|
||||
"payload":{
|
||||
"text":"Quero consultar minha fatura",
|
||||
"session_id":"contas-test-001",
|
||||
"user_id":"user-001",
|
||||
"msisdn":"11999999999",
|
||||
"message_id":"msg-001"
|
||||
}
|
||||
}'
|
||||
```
|
||||
|
||||
Depois teste continuidade na mesma `session_id`.
|
||||
|
||||
## 18. Teste transacional de VAS
|
||||
|
||||
1. Envie: `Quero cancelar TIM Fashion Mensal`.
|
||||
2. O framework deve identificar tool transacional e pedir confirmação.
|
||||
3. Responda `sim` na mesma sessão.
|
||||
4. Somente então `cancelar_vas_avulso` deve ser chamada.
|
||||
5. Em modo mock, o resultado deve conter `block.status=200` e `cancellation.status=200`.
|
||||
|
||||
Teste negativo importante:
|
||||
|
||||
1. Entre em estado aguardando confirmação de cancelamento.
|
||||
2. Envie `você ainda está por aí?`.
|
||||
3. A frase não pode confirmar a transação.
|
||||
|
||||
## 19. Teste de contestação
|
||||
|
||||
Em mock:
|
||||
|
||||
```text
|
||||
Quero contestar Tamboro Mensal no valor de 14,99, não reconheço essa cobrança.
|
||||
```
|
||||
|
||||
Esperado:
|
||||
|
||||
- route `contestacao_agent`;
|
||||
- parâmetros `subject` e `valor` coletados;
|
||||
- confirmação antes da mutação;
|
||||
- abertura de protocolo;
|
||||
- contestação;
|
||||
- tracking;
|
||||
- resposta final grounded nos retornos da tool.
|
||||
|
||||
## 20. Testes de memória
|
||||
|
||||
### Short-term / summary
|
||||
|
||||
Na mesma sessão:
|
||||
|
||||
```text
|
||||
Meu serviço é TIM Fashion Mensal.
|
||||
...
|
||||
Qual serviço eu mencionei antes?
|
||||
```
|
||||
|
||||
### Long-term memory
|
||||
|
||||
Com `ENABLE_LONG_TERM_MEMORY=true`, grave uma informação elegível, encerre a sessão e abra outra sessão com a mesma identidade de negócio. Verifique se o contexto é recuperado conforme as regras de LTM do framework.
|
||||
|
||||
## 21. Testes de RAG
|
||||
|
||||
Valide que a intent de conhecimento não dispara MCP desnecessariamente. Exemplos:
|
||||
|
||||
```text
|
||||
O que significa cobrança proporcional?
|
||||
Como funciona o vencimento da fatura?
|
||||
```
|
||||
|
||||
O trace deve mostrar `RagService`; a tool `buscar_informacao` não precisa ser executada.
|
||||
|
||||
## 22. Testes de guardrails e judges
|
||||
|
||||
Com as flags habilitadas no `.env`:
|
||||
|
||||
- prompt injection deve passar pelos input guardrails;
|
||||
- resposta candidata passa pelo Output Supervisor/output guardrails;
|
||||
- groundedness deve considerar `mcp_results` quando a resposta usa dados TIM;
|
||||
- judges rodam após a geração e antes da persistência final.
|
||||
|
||||
Use o Langfuse para observar a sequência de nodes do LangGraph.
|
||||
|
||||
## 23. Teste de conectividade/VPN
|
||||
|
||||
O pacote contém:
|
||||
|
||||
```bash
|
||||
python scripts/check_integrations.py
|
||||
```
|
||||
|
||||
O script resolve DNS e testa TCP dos endpoints configurados. Execute antes e depois de conectar a VPN.
|
||||
|
||||
Para APIs FQA, um resultado `DNS_FAIL`, `TCP_FAIL` ou timeout indica que a rede ainda não está pronta. Um `TCP_OK` prova conectividade de rede, mas não autenticação/contrato HTTP.
|
||||
|
||||
## 24. Ativar APIs reais gradualmente
|
||||
|
||||
Não habilite todas as mutações de uma vez. Ordem recomendada:
|
||||
|
||||
1. VPN/DNS;
|
||||
2. `consultar_faturas`;
|
||||
3. `consultar_vas`;
|
||||
4. `consultar_historico_vas`;
|
||||
5. contrato/profile;
|
||||
6. billing analysis;
|
||||
7. Secure PDF;
|
||||
8. protocol/status/tracking;
|
||||
9. SMS;
|
||||
10. cancelamento VAS;
|
||||
11. contestação.
|
||||
|
||||
Depois faça teste end-to-end completo.
|
||||
|
||||
## 25. Kubernetes
|
||||
|
||||
Use o mesmo `.env` como fonte para construir ConfigMap/Secret, separando segredos no mecanismo corporativo apropriado. O backend necessita alcançar:
|
||||
|
||||
- MCP Contas;
|
||||
- OCI GenAI;
|
||||
- Autonomous DB;
|
||||
- Langfuse, se habilitado;
|
||||
- endpoints TIM internos em modo real;
|
||||
- providers de analytics habilitados.
|
||||
|
||||
O MCP pode rodar no mesmo pod como sidecar ou, preferencialmente, como deployment/service separado. Configure `config/mcp_servers.yaml` para o DNS do Service Kubernetes.
|
||||
|
||||
## 26. Critérios de aceite da migração
|
||||
|
||||
A migração é considerada concluída quando:
|
||||
|
||||
- [ ] zero imports/referências executáveis ao pacote anterior;
|
||||
- [ ] backend e MCP sobem após o diretório anterior ser removido;
|
||||
- [ ] read-only APIs funcionam em FQA;
|
||||
- [ ] cancelamento exige confirmação do framework e funciona em FQA;
|
||||
- [ ] contestação exige confirmação e reproduz efeitos esperados;
|
||||
- [ ] RAG usa `RagService` do framework;
|
||||
- [ ] memory/summary/LTM/checkpoint usam providers do framework;
|
||||
- [ ] guardrails e judges aparecem nos traces;
|
||||
- [ ] LangGraph é a única máquina de estados conversacional;
|
||||
- [ ] Pub/Sub/sequence/OTEL/Langfuse são validados conforme ambiente;
|
||||
- [ ] testes de carga são executados antes de produção.
|
||||
|
||||
## 27. Segurança do `.env`
|
||||
|
||||
O arquivo preservado contém material sensível. Ele foi mantido porque isso foi um requisito explícito da reconstrução. Para distribuição fora do ambiente controlado, rotacione credenciais expostas e substitua valores por Secrets/Vault/Key Vault/Kubernetes Secret conforme política corporativa.
|
||||
223
docs/MATRIZ_MIGRACAO.md
Normal file
223
docs/MATRIZ_MIGRACAO.md
Normal file
@@ -0,0 +1,223 @@
|
||||
# Matriz de Migração — Contas -> agent_framework_oci
|
||||
|
||||
| Capacidade | Destino novo | Reuso framework | Código de domínio novo | Dependência anterior |
|
||||
|---|---|---:|---:|---:|
|
||||
| LangGraph | `app/workflows/agent_graph.py` | Sim | composição mínima | Não |
|
||||
| Router | EnterpriseRouter | Sim | routing.yaml | Não |
|
||||
| Stickiness | framework | Sim | configuração | Não |
|
||||
| Supervisor | framework | Sim | configuração | Não |
|
||||
| Confirmação | AgentRuntimeMixin | Sim | tool policy | Não |
|
||||
| Clarificação | AgentRuntimeMixin/MCP mapping | Sim | schemas/mapping | Não |
|
||||
| Sessions | framework repository | Sim | Não | Não |
|
||||
| Message memory | framework | Sim | Não | Não |
|
||||
| Summary memory | framework | Sim | Não | Não |
|
||||
| LTM | framework | Sim | Não | Não |
|
||||
| Checkpoint | framework | Sim | Não | Não |
|
||||
| RAG | RagService | Sim | conteúdo/config | Não |
|
||||
| Guardrails | GuardrailPipeline | Sim | config | Não |
|
||||
| Output Supervisor | framework | Sim | Não | Não |
|
||||
| Judges | JudgePipeline | Sim | config | Não |
|
||||
| MCP router | framework | Sim | tool catalog | Não |
|
||||
| Faturas | MCP/domain | Não aplicável | Sim | Não |
|
||||
| Billing Analysis | MCP/domain | Não aplicável | Sim | Não |
|
||||
| Consulta/Histórico VAS | MCP/domain | Não aplicável | Sim | Não |
|
||||
| Bloqueio/Cancelamento VAS | MCP/domain | confirmação no framework | Sim | Não |
|
||||
| Contestação | MCP/domain | confirmação/estado no framework | Sim | Não |
|
||||
| Protocol/Status/Tracking | MCP/domain | contexto no framework | Sim | Não |
|
||||
| SMS | MCP/domain | contexto no framework | Sim | Não |
|
||||
| Secure PDF | MCP/domain | contexto no framework | Sim | Não |
|
||||
| Langfuse | framework | Sim | Não | Não |
|
||||
| Pub/Sub/sequence | framework | Sim | configuração | Não |
|
||||
| OCI Streaming | framework | Sim | configuração | Não |
|
||||
| OTEL | framework | Sim | configuração | Não |
|
||||
|
||||
## Regra
|
||||
|
||||
O pacote anterior não é uma biblioteca do novo projeto. Se uma regra específica for necessária, ela deve ser portada e testada dentro de `app/domain/contas`; infraestrutura genérica deve ser eliminada em favor do framework.
|
||||
|
||||
|
||||
## Contratos TIM validados por regressão
|
||||
|
||||
| Integração | Paridade coberta | Estado |
|
||||
|---|---|---|
|
||||
| CompleteInvoices | método/payload/header `ClientID` | ✅ |
|
||||
| Query VAS | URL por MSISDN, `clientId=AIAAGENTCR`, auth | ✅ |
|
||||
| VAS History | query `msisdn`, `clientId`, `messageId`, auth | ✅ |
|
||||
| Block VAS | payload PMid + fallbacks e headers | ✅ |
|
||||
| Cancel VAS | DELETE, channel, protocol, headers, messageId | ✅ |
|
||||
| Contract Information | GET por MSISDN, `clientId`, auth | ✅ |
|
||||
| Profile/Line Info | GET e header `ClientID` | ✅ |
|
||||
| Billing Analysis | GET por MSISDN + channel | ✅ |
|
||||
| Bill PDF | POST detalhado + criptografia | ✅ |
|
||||
| Secure PDF | GET com parâmetros criptografados | ✅ |
|
||||
| Customer Contestation | payload/headers principais | ✅ |
|
||||
| Service Request Status | envelope `serviceRequest` | ✅ |
|
||||
| Tracking Activities | customer/invoice/activity/user | ✅ |
|
||||
| Protocol V2 | envelope Siebel + headers corporativos | ✅ |
|
||||
| SMS Barcode | payload completo + retry/RCT | ✅ |
|
||||
|
||||
## Jornadas compostas e comportamento conversacional
|
||||
|
||||
| Capacidade original | Implementação migrada | Reuso do framework | Regressão |
|
||||
|---|---|---:|---:|
|
||||
| Cancelamento VAS -> contestação | dois workflows encadeados no MCP | `WorkflowRuntime` | ✅ |
|
||||
| Composição final cancelamento | `app/domain/contas/vas_cancellation_message.py` | domínio determinístico | ✅ 19 casos originais |
|
||||
| Fallback VAS History | `ContasDomainService.cancelar_vas_avulso` | transporte via adapter | ✅ |
|
||||
| Cancelamento parcial em lote | action expõe cancelados/falhas/candidatos | WorkflowRuntime + IdempotencyStore | ✅ |
|
||||
| Idempotência transacional | `create_idempotency_store()` | framework | ✅ |
|
||||
| Replay pós-finalização | Channel short-circuit | framework | ✅ |
|
||||
| Idle nudge replay | Channel short-circuit | framework | ✅ |
|
||||
| Processing interruption | replay + classificador LLM fail-safe | `LLMProvider` framework | ✅ |
|
||||
| Correção Fim/Mim -> Sim | channel transcription | framework | ✅ |
|
||||
| Finalização status/summary | regra pura de domínio | workflow framework | ✅ |
|
||||
| Protocolo informacional final | action + ProtocolV2 | WorkflowRuntime | ✅ |
|
||||
|
||||
### Bootstrap MCP
|
||||
|
||||
`WorkflowRuntime`, checkpointer e `IdempotencyStore` são inicializados de forma lazy. Isto evita dependência de Oracle/Redis para endpoints de diagnóstico e garante que o backend durável só seja aberto quando um workflow realmente precisar ser executado.
|
||||
|
||||
## Incrementos de paridade - baseline 420
|
||||
|
||||
| Capacidade original | Implementação migrada | Responsabilidade | Estado |
|
||||
|---|---|---|---:|
|
||||
| InvoiceContextProvider / prefetch | `InvoiceContextService` + `agent_framework.cache.Cache` | domínio escolhe evidências; framework fornece cache | ✅ |
|
||||
| Isolamento de invoice context por sessão | chave `session_id:msisdn:invoice_id` | framework cache | ✅ |
|
||||
| Plano família titular/dependente | normalização antes do workflow + contestação única no titular | domínio + WorkflowRuntime | ✅ |
|
||||
| Correção de linha por invoice detail | normalização determinística | domínio | ✅ |
|
||||
| CVAL fail-stop | edge `success=false -> END` | WorkflowRuntime | ✅ |
|
||||
| Snapshot parcial em falha | `WorkflowRuntime` recupera último state do LangGraph | framework | ✅ |
|
||||
| Retry Billing Analysis / RCT 079-084 | metadata `_transport` + `RCTPolicy` | domínio define códigos; observer publica | ✅ |
|
||||
| Finalização invoice explanation | protocolo informacional somente após workflow executado | domínio + WorkflowRuntime | ✅ |
|
||||
| VEB fechado / force RT15 | reuso ou novo protocolo conforme flags | domínio | ✅ |
|
||||
| Inicialização AgentWorkflow | router/agentes/grafo dentro de `__init__` | aplicação/framework | ✅ |
|
||||
|
||||
### Incrementos de paridade — baseline 435
|
||||
|
||||
| Capacidade original | Implementação migrada | Responsabilidade | Status |
|
||||
|---|---|---|---|
|
||||
| Invoice prefetch single-flight | `InvoiceContextService` + `agent_framework.cache.Cache` | domínio escolhe evidências; framework fornece cache | ✅ |
|
||||
| CVN de prefetch sem duplicação | `business_events` + cache markers | domínio define código; observer framework publica | ✅ |
|
||||
| Latch invoice/workflow já executado | `AgentRuntimeMixin.business_workflows_executed` | framework | ✅ |
|
||||
| Batch cancellation max 5 | action async + semaphore | domínio action sobre WorkflowRuntime | ✅ |
|
||||
| Protocolo por linha antes de cancelar | action `cancelamento_vas_avulso_batch` | domínio + adapter TIM | ✅ |
|
||||
| Erro estruturado de workflow | `WorkflowRunResult.error_details` | framework | ✅ |
|
||||
| Provider error de contestação | MCP mapping sobre `error_details` | domínio/MCP fino | ✅ |
|
||||
|
||||
|
||||
## Baseline 440 testes - continuação
|
||||
|
||||
- 440 testes de migração passando; 2 skipped por dependências indisponíveis neste runtime (`langgraph`/`jellyfish`).
|
||||
- Cancelamento VAS: falha de bloqueio/cancelamento pode permanecer candidata à contestação sem mascarar sucesso.
|
||||
- Resposta composta preserva protocolos de cancelamento por linha + protocolo de contestação e sinaliza finalização sugerida.
|
||||
- Plano família: protocolo de cancelamento em dependente resolve `socialSecNo` via LineInfo da própria linha.
|
||||
- Registro de protocolo aceita aliases de resposta `interactionProtocol`, `protocolNumber`, `protocol` e `protocolo`.
|
||||
- Finalização informacional recalcula Bundle/Estratégico/Avulso pela evidência de `invoice_detail`/Billing Analysis quando disponível.
|
||||
|
||||
## Finalização - paridade adicional (baseline 533)
|
||||
|
||||
| Capability original | Implementação migrada | Framework reutilizado | Evidência |
|
||||
|---|---|---|---|
|
||||
| CVN aceite/recusa no encerramento | `finalizar_atendimento_action` | `business_events` + `AgentObserver` | testes de finalização estendida |
|
||||
| Protocolo RT-15 informacional | action de domínio + TIM client | WorkflowRuntime/observer/idempotência | RCT.085/086 + CVN.010/011 |
|
||||
| Nota de invoice explanation | valor canônico `Explicação dos valores da fatura` | workflow latch do framework | regressão |
|
||||
| Handoff/retention suppression | flags no state/domain action | estado persistido do framework | regressão |
|
||||
| SAD decision tree | `SAD.001/002/003/004/005/006/007` como business events | AgentObserver | regressão |
|
||||
| Classificação VAS sem invoice detail | aliases determinísticos de domínio | nenhuma engine paralela | regressão |
|
||||
| Regressão offline de workflow | `WorkflowRuntime(... allow_deterministic_fallback=True)` somente em teste | DSL/actions do framework | 18 casos históricos executados |
|
||||
|
||||
## Atualização de paridade - baseline 550
|
||||
|
||||
| Capability | Original | Migrado | Evidência |
|
||||
|---|---|---|---|
|
||||
| Finalização com prefetch de fatura | CVN lookup + RT-15 quando aplicável | Implementado | regressão de finalização |
|
||||
| Supressão após transição para negócio | não reemite CVN/MPI | Implementado | regressão dedicada |
|
||||
| VEB terminal | não duplica RT-15/CVN | Implementado | regressão dedicada |
|
||||
| Precedência de tipo pela fatura | total/parcial/sem match | Implementado | regressão dedicada |
|
||||
| Protocolo já existente | não duplica RT-15 | Implementado | regressão dedicada |
|
||||
| Matcher fonético/transcrição | catálogo real | Implementado sem xfails | suíte de transcrição |
|
||||
|
||||
## VAA — rastreabilidade de cancelamento/contestação
|
||||
|
||||
| Capability histórica | Implementação migrada | Framework reutilizado | Estado |
|
||||
|---|---|---|---|
|
||||
| VAA.001–004 cancelamento | `cancelamento_vas_avulso_batch` retorna `business_events` | AgentObserver / analytics | OK |
|
||||
| VAA.005–009 contestação/boleto | `abrir_contestacao_cliente` retorna `business_events` | AgentObserver / analytics | OK |
|
||||
| VAA.012–015 SMS | `enviar_sms` retorna `business_events` e mantém fluxo em erro | AgentObserver / analytics | OK |
|
||||
| VAA.016–017 status SR | `atualizar_status_sr` retorna `business_events` | AgentObserver / analytics | OK |
|
||||
|
||||
|
||||
## Baseline 560 testes - metadata corporativa TIM
|
||||
|
||||
- 560 testes de migração passando, sem skips/xfails.
|
||||
- Business events preservam contexto corporativo: `agentProtocolId`, `adjustedProtocol`, `billingId`, `uraCallId`, `channelId`, `sessionId`, `messageId` e `agentSpecificData`.
|
||||
- Contestação VAA.005-009 preserva itens/valores ajustados e protocolo.
|
||||
- Finalização CVN.010/011 preserva protocolo TIM/URA e billing context.
|
||||
- RCTs derivados de retry HTTP carregam `apiUrl`, `apiStatusCode`, `apiResponsePayload` e `latencyMs`.
|
||||
- SMS e Service Request Status carregam metadata de transporte e contexto de protocolo.
|
||||
- `tim_payload_mapper` aceita o formato histórico `agentSpecificData` JSON-string e o converte para o objeto canônico TIM no payload final.
|
||||
|
||||
### Paridade de eventos conversacionais — baseline 565
|
||||
|
||||
| Família | Paridade adicionada |
|
||||
|---|---|
|
||||
| VEB | ordem dos branches de VAS estratégico e metadata do turno/URA |
|
||||
| MPI | contexto de invoice explanation, pró-rata e cancelamento |
|
||||
| CVN | contexto conversacional/protocolo no encerramento |
|
||||
| SAD | `llmResponse`, `messageId`, sessão/canal e `sessionEndAt` normalizado |
|
||||
|
||||
## Incremento de paridade — baseline 570
|
||||
|
||||
| Funcionalidade original | Implementação migrada | Responsabilidade |
|
||||
|---|---|---|
|
||||
| Cancelamento solicitado para item estratégico/bundle | `InvoiceResolver` redireciona para workflow `vas_estrategico` | Domínio + WorkflowRuntime |
|
||||
| Invoice explanation SIM | recomenda `resolvido` pelo último node do workflow | MCP adapter fino sobre WorkflowRuntime |
|
||||
| Invoice explanation NÃO sem VAS variado | recomenda `nao_resolvido` | MCP adapter fino sobre WorkflowRuntime |
|
||||
| Pró-rata aceito / sem Plano Controle | recomenda `resolvido` | MCP adapter fino sobre WorkflowRuntime |
|
||||
| Orientação de cancelamento de VAS estratégico por parceiro | action declara `requires_rag/rag_queries`; `AgentRuntimeMixin` chama `RagService` | Framework |
|
||||
| Gate padrão de regressão | `pytest -q` -> `tests/` | Projeto migrado |
|
||||
|
||||
## Baseline 578 - wrapper cancelamento + LLM composition
|
||||
|
||||
- 593 testes passando; zero skipped/xfail.
|
||||
- Cancelamento preserva `auto_finalize_on_failure` em falha técnica de contestação.
|
||||
- Item já contestado não mascara cancelamento concluído como falha sistêmica.
|
||||
- `cancelamento_vas_protocol` e todos os protocolos de resposta são preservados.
|
||||
- Plano família contesta titular + dependentes em uma única `contestacao_tool`.
|
||||
- Lote com muitos no-match continua contestando exatamente os candidatos elegíveis.
|
||||
- Pró-rata usa `requires_llm_composition` do framework em vez de gateway LLM de domínio.
|
||||
|
||||
|
||||
### Paridade de wrappers históricos — baseline 593
|
||||
|
||||
| Comportamento original | Implementação migrada | Estado |
|
||||
|---|---|---|
|
||||
| `tipo_atendimento=contestacao` | `_workflow_payload(contestacao_tool)` | ✅ |
|
||||
| Contexto do turno no workflow | payload MCP preserva IDs/canal/mensagem | ✅ |
|
||||
| CPF como alias de socialSecNo | normalização no wrapper composto | ✅ |
|
||||
| `cancelados` sem `results.success` | fallback agregado do wrapper | ✅ |
|
||||
| `itens_para_contestacao` | alias de `contestation_candidates` | ✅ |
|
||||
| falha block/cancel ainda elegível a RT-02 | composição de dois WorkflowRuntime | ✅ |
|
||||
| SMS falha sem derrubar jornada | `sms_not_send_error` | ✅ |
|
||||
| Bundle + Estratégico + NÃO | protocolo deferido + RAG obrigatório | ✅ |
|
||||
|
||||
## Complemento de paridade — baseline 599
|
||||
|
||||
| Comportamento histórico | Implementação migrada | Prova |
|
||||
|---|---|---|
|
||||
| Itens já contestados | normalização em `abrir_contestacao_cliente` + compositor determinístico | teste de wrapper 1:1 |
|
||||
| Itens contestados/não contestados | classificação na action de domínio | regressão de contestação |
|
||||
| Total contestado somente dos itens aceitos | cálculo determinístico no domínio | regressão de contestação |
|
||||
| Contestação retorna valor zero | fallback para total efetivamente cancelado | teste de wrapper 1:1 |
|
||||
| Valor na fala em pt-BR | normalização na borda MCP | teste `R$ 14,99` |
|
||||
| `next_subject` | ignorado pelo compositor determinístico | teste de wrapper 1:1 |
|
||||
| Billing Analysis indisponível | fraseologia canônica e `auto_finalize_on_failure=false` | regressão invoice explanation |
|
||||
|
||||
### Cobertura 1:1 de wrappers — baseline 615
|
||||
|
||||
Além dos testes de domínio/actions/workflows, a suíte passa a reproduzir diretamente
|
||||
outcomes históricos dos wrappers `cancelar_vas_single` e `finalize_support`, cobrindo
|
||||
no-match, candidatos explícitos, falhas parciais RT-01→RT-02, SMS, protocolos,
|
||||
`protocol_closed`, plano família/titular-dependente e protocolo informacional deferido.
|
||||
|
||||
Esses testes são classificados como **paridade explícita de contrato externo**, e não
|
||||
apenas cobertura indireta por actions internas.
|
||||
295
docs/VALIDACAO_MIGRACAO.md
Normal file
295
docs/VALIDACAO_MIGRACAO.md
Normal file
@@ -0,0 +1,295 @@
|
||||
# Validação da reconstrução
|
||||
|
||||
## Resultado
|
||||
|
||||
- Sintaxe Python (`compileall`): **PASS**
|
||||
- YAML de `config/`: **PASS**
|
||||
- Testes de domínio mock: **4 PASS**
|
||||
- Smoke MCP: **PASS** para faturas, invoice explanation, VAS, histórico, cancelamento e contestação
|
||||
- Diretório do pacote anterior presente: **NÃO**
|
||||
- Imports do namespace anterior em `app/`, `mcp/`, `config/`: **0**
|
||||
- `.env`: **preservado byte a byte**
|
||||
|
||||
## Limitação do ambiente de construção
|
||||
|
||||
O runtime usado para montar o pacote não possui `langgraph` instalado globalmente. Por isso o teste de import/execução do `StateGraph` completo não foi executado aqui. O projeto declara `langgraph` em `pyproject.toml`; rode `uv sync` antes de subir o backend.
|
||||
|
||||
## Aceite recomendado em ambiente do projeto
|
||||
|
||||
```bash
|
||||
uv sync
|
||||
pytest -q tests/migration
|
||||
uv run uvicorn contas_mcp.servers.contas_mcp_server.main:app --port 8400
|
||||
uv run uvicorn app.main:app --port 8000
|
||||
```
|
||||
|
||||
Depois execute os cenários descritos em `MANUAL_AGENT_CONTAS_MIGRADO.md`.
|
||||
|
||||
|
||||
## Atualização de paridade - 2026-08-18
|
||||
|
||||
Gate local atual: **338 passed / 3 skipped** em `tests/migration`.
|
||||
|
||||
Os skips dependem de bibliotecas não instaladas no runtime de construção (principalmente LangGraph/jellyfish) e permanecem habilitados para execução após `uv sync`.
|
||||
|
||||
Contratos adicionais corrigidos nesta rodada:
|
||||
|
||||
- VAS History: `GET ?msisdn=...`, `clientId`, `messageId` e `Authorization`.
|
||||
- Contract Information: `clientId` (não `client_id`) e Basic Auth.
|
||||
- Profile/Line Info: header `ClientID` conforme contrato original.
|
||||
- Cancelamento VAS: `messageId` sempre não vazio, além de `channel=AIAGENTCR` e `interactionProtocol`.
|
||||
|
||||
Gates estruturais mantidos:
|
||||
|
||||
- zero imports de `agente_contas_tim` em `app/`, `mcp/` e no código-fonte do framework;
|
||||
- zero imports diretos de `langgraph.graph` no domínio Contas;
|
||||
- workflows do domínio executados por `agent_framework.workflows.WorkflowRuntime`;
|
||||
- `FrameworkStateGraph` usado para composição do grafo principal;
|
||||
- `.env` preservado como arquivo principal de configuração.
|
||||
|
||||
## Atualização de paridade - continuação 2026-08-18
|
||||
|
||||
Gate local atual: **400 passed / 2 skipped** em `tests/migration`.
|
||||
|
||||
Skips restantes:
|
||||
|
||||
- `test_original_item_matcher_transcription.py`: requer `jellyfish`, dependência declarada no projeto e instalada por `uv sync`.
|
||||
- `test_original_workflow_cases.py`: requer `langgraph`, dependência declarada no projeto e instalada por `uv sync`.
|
||||
|
||||
Novas coberturas e correções comprovadas nesta rodada:
|
||||
|
||||
- cenário real `cy0001` voltou a integrar a regressão de `vas_variation`; o skip causado por caminho incorreto do harness foi removido;
|
||||
- replay pós-finalização preserva `terminal_status` e possui fallback seguro quando a sessão é restaurada sem a última fala;
|
||||
- transformação de transcrição `Fim/Mim -> Sim` foi validada contra a matriz original de fronteira de fala inteira;
|
||||
- `processing_interruption` interrompível voltou a usar classificador LLM leve do **framework**; sem classificador/erro/resultado negativo o comportamento é replay fail-safe;
|
||||
- os dois templates oficiais do framework receberam o mesmo fluxo de classificação de interrupção;
|
||||
- SMS recuperou o default canônico `senderName=TIM Brasil`;
|
||||
- Service Request Status prioriza `messageId`/`ura_call_id` antes de `session_id`;
|
||||
- o compositor determinístico de mensagem de cancelamento VAS foi portado e os 19 testes originais passam;
|
||||
- `cancelar_vas_avulso` encadeia `cancelamento_vas_avulso -> contestacao_tool` usando **dois WorkflowRuntime do framework**;
|
||||
- o MCP inicializa WorkflowRuntime/checkpointer/idempotência de forma lazy, evitando abrir Oracle durante import/health/tools-list;
|
||||
- o `IdempotencyStore` selecionado pelo framework é agora realmente injetado nos actions do Contas, eliminando o fallback local involuntário para memória;
|
||||
- cancelamento usa VAS History como fallback e bloqueia recancelamento quando `canCancel=false`;
|
||||
- resultado em lote expõe `cancelados`, `nao_encontrados`, `nao_cancelados` e `itens_para_contestacao`, preservando sucesso parcial;
|
||||
- finalização normaliza status/aliases e summary conforme o original;
|
||||
- finalização informacional cria protocolo fechado somente quando necessário e evita duplicidade quando já existe protocolo;
|
||||
- combinações canônicas de notas `VAS Bundle`, `VAS Estratégico` e `VAS Avulso` foram portadas e testadas.
|
||||
|
||||
### Gates estruturais desta versão
|
||||
|
||||
```text
|
||||
agente_contas_tim em app/ 0
|
||||
agente_contas_tim em mcp/ 0
|
||||
agente_contas_tim em agent_framework/src 0
|
||||
langgraph.graph em app/ 0
|
||||
langgraph.graph em mcp/ 0
|
||||
```
|
||||
|
||||
O LangGraph continua interno ao `agent_framework_oci` por `FrameworkStateGraph` e `WorkflowRuntime`.
|
||||
|
||||
## Atualização de paridade - continuação 2026-08-18 (baseline 420)
|
||||
|
||||
Gate local atual: **420 passed / 2 skipped** em `tests/migration`.
|
||||
|
||||
Novas correções comprovadas desde a baseline 400:
|
||||
|
||||
- plano família mantém o MSISDN do titular na contestação e o MSISDN real do dependente no cancelamento;
|
||||
- `invoice_detail` corrige deterministicamente a linha do item antes do side effect;
|
||||
- `CVAL` encerra `contestacao_tool` imediatamente quando bloqueia a operação, sem seguir para SMS/contrato/SR;
|
||||
- o MCP propaga `success=false`, mensagem e estado sistêmico quando a contestação é bloqueada;
|
||||
- finalização de `invoice_explanation` cria protocolo informacional apenas quando o workflow realmente executou, não por mero prefetch;
|
||||
- protocolo VEB já fechado é reutilizado sem nova abertura/fechamento; `force_rt15_finalization_protocol` força um RT-15 novo quando solicitado;
|
||||
- `suppress_cvn_protocol_ic` preserva a semântica de VAS estratégico deferido;
|
||||
- `WorkflowRuntime` preserva snapshot parcial, nodes e trace quando uma action posterior falha;
|
||||
- Billing Analysis agora carrega metadata de tentativas e gera RCT.079-084 por tentativa;
|
||||
- corrigido bug de `msisdn` duplicado em `preparar_invoice_explanation`;
|
||||
- corrigido bug de inicialização de `AgentWorkflow`: router/agentes/grafo estavam em código inalcançável após `return`;
|
||||
- `InvoiceContextService` foi reconstruído sobre `agent_framework.cache.Cache`, com isolamento por sessão, TTL, prefetch e reaproveitamento de CompleteInvoices/Billing Analysis/detalhe.
|
||||
|
||||
Os dois skips continuam sendo exclusivamente dependências deste runtime de construção:
|
||||
|
||||
- `jellyfish` para regressão fonética completa;
|
||||
- `langgraph` para os 18 casos reais de WorkflowRuntime.
|
||||
|
||||
## Baseline 435 testes — continuação de paridade
|
||||
|
||||
Nesta baseline foram adicionadas as seguintes garantias:
|
||||
|
||||
- `InvoiceContextService` com single-flight por sessão/fatura, cache incompleto sensível a `include_detail`, CVN.002/CVN.006/CVN.007 como `business_events` deduplicados por sessão e sem republicação em cache hit.
|
||||
- Metadados de prefetch: `fetch_elapsed_ms`, `task_timings`, `cache_age_ms` e erros por subconsulta.
|
||||
- Latch genérico `business_workflows_executed` no `AgentRuntimeMixin`; workflows em `PAUSED` já contam como executados e o latch é persistido no patch transacional.
|
||||
- Cancelamento em lote com concorrência máxima 5 (configurável por `TIM_CANCELAMENTO_BATCH_CONCURRENCY`) e protocolo por linha antes do side effect; falha de protocolo bloqueia o cancelamento daquela linha.
|
||||
- `WorkflowRunResult.error_details` preserva fatos estruturados de exceções externas sem acoplamento do framework a TIM.
|
||||
- Contestação FAILED mapeia mensagem do provider/protocolo parcial quando disponíveis e diferencia erro de negócio de falha sistêmica.
|
||||
|
||||
Resultado local: **435 passed / 2 skipped** em `tests/migration`.
|
||||
Os dois skips continuam dependentes de `langgraph`/`jellyfish` indisponíveis neste runtime de construção.
|
||||
|
||||
|
||||
## Baseline 440 testes - continuação
|
||||
|
||||
- 440 testes de migração passando; 2 skipped por dependências indisponíveis neste runtime (`langgraph`/`jellyfish`).
|
||||
- Cancelamento VAS: falha de bloqueio/cancelamento pode permanecer candidata à contestação sem mascarar sucesso.
|
||||
- Resposta composta preserva protocolos de cancelamento por linha + protocolo de contestação e sinaliza finalização sugerida.
|
||||
- Plano família: protocolo de cancelamento em dependente resolve `socialSecNo` via LineInfo da própria linha.
|
||||
- Registro de protocolo aceita aliases de resposta `interactionProtocol`, `protocolNumber`, `protocol` e `protocolo`.
|
||||
- Finalização informacional recalcula Bundle/Estratégico/Avulso pela evidência de `invoice_detail`/Billing Analysis quando disponível.
|
||||
|
||||
## Baseline 533 - dependências de regressão e finalização
|
||||
|
||||
- `tests/migration`: **533 passed / 4 xfailed / 0 skipped**.
|
||||
- Os quatro `xfail` são limitações históricas documentadas do ranking fonético (`gueimiloft`, `tim miusic`, `apou`, `agebeo max`), não testes ignorados por dependência.
|
||||
- `jellyfish` deixou de ser requisito obrigatório: o domínio possui fallback puro-Python para Jaro-Winkler, Levenshtein e chave fonética. A biblioteca externa pode ser usada como aceleração, mas o projeto e a regressão não dependem dela.
|
||||
- Os 18 casos históricos de workflow não usam mais `importorskip(langgraph)`. Em builders offline executam pelo backend determinístico **explicitamente opt-in** do `WorkflowRuntime`; em produção o backend padrão continua sendo LangGraph e a ausência de `langgraph` continua sendo erro de configuração.
|
||||
- Finalização validada adicionalmente para: CVN.008/CVN.009, MPI.006/MPI.005, RCT.085/RCT.086, CVN.010/CVN.011, SAD.001 e árvore SAD opcional; protocolo informacional canônico de invoice explanation; supressão em handoff; ausência de aceite informacional após workflows transacionais; classificação de VAS estratégico/avulso sem invoice detail.
|
||||
|
||||
### Lockfile
|
||||
O `uv.lock` herdado de snapshots anteriores foi removido porque ainda descrevia o pacote legado (`agente-contas-tim`) e dependências que já não pertencem ao projeto (`jellyfish` obrigatório, NeMoGuardrails/LangChain extras, entre outras). O primeiro `uv sync` deve regenerar o lock a partir do `pyproject.toml` atual.
|
||||
|
||||
## Baseline 550 - finalização e matcher sem skips/xfails
|
||||
|
||||
Validação consolidada desta etapa:
|
||||
|
||||
```text
|
||||
550 passed
|
||||
0 skipped
|
||||
0 xfailed
|
||||
```
|
||||
|
||||
Coberturas adicionadas nesta etapa:
|
||||
|
||||
- finalização conversacional diferencia encerramento genérico de contexto real de fatura;
|
||||
- prefetch/invoice context pode garantir CVN.002/CVN.006 e RT-15 conforme semântica histórica;
|
||||
- `conversation_unresolved_transition_emitted` impede reemissão indevida de CVN/MPI positivos;
|
||||
- VEB terminal com protocolo fechado não cria RT-15 duplicado nem reemite CVN/MPI;
|
||||
- evidência da fatura prevalece sobre tipo informacional salvo em match total;
|
||||
- match parcial mescla inferência da fatura com tipo salvo ainda não representado;
|
||||
- sem match na fatura, tipos salvos conflitantes são descartados;
|
||||
- protocolo já existente impede RT-15 duplicado;
|
||||
- alias `cpf` é propagado como `socialSecNo` no protocolo informacional;
|
||||
- matcher de transcrição resolveu os quatro casos históricos antes marcados como xfail.
|
||||
|
||||
### Matcher sem dívida conhecida no catálogo de regressão
|
||||
|
||||
O `SimilarityItemMatcher` passou a combinar:
|
||||
|
||||
- similaridade de frase;
|
||||
- similaridade fonética;
|
||||
- alinhamento token-a-token;
|
||||
- dupla evidência grafia + fonética por token.
|
||||
|
||||
Isso corrigiu explicitamente:
|
||||
|
||||
- `gueimiloft` -> `Gameloft`;
|
||||
- `tim miusic` -> `TIM Music`;
|
||||
- `apou` -> `Apple Music`;
|
||||
- `agebeo max` -> `HBO Max`.
|
||||
|
||||
## Baseline 556 — paridade VAA (2026-08-18)
|
||||
|
||||
A regressão de migração passou a executar 556 testes sem skip/xfail.
|
||||
|
||||
Nesta etapa os testes históricos do projeto original foram usados diretamente como catálogo para restaurar a família VAA sem trazer o publisher legado:
|
||||
|
||||
- cancelamento VAS: VAA.001/VAA.002/VAA.003 no caminho feliz e VAA.004 em falha operacional;
|
||||
- contestação: VAA.005 + VAA.006/VAA.007 e VAA.008/VAA.009 conforme sucesso e elegibilidade do código de barras;
|
||||
- SMS: VAA.012/VAA.014 em sucesso e VAA.013/VAA.015 em falha, mantendo o workflow ativo;
|
||||
- atualização/fechamento de SR: VAA.016/VAA.017.
|
||||
|
||||
Os events são retornados como `business_events`; transporte, sequence e fan-out permanecem responsabilidade exclusiva do `AgentObserver`/analytics do agent_framework_oci.
|
||||
|
||||
|
||||
## Baseline 560 testes - metadata corporativa TIM
|
||||
|
||||
- 560 testes de migração passando, sem skips/xfails.
|
||||
- Business events preservam contexto corporativo: `agentProtocolId`, `adjustedProtocol`, `billingId`, `uraCallId`, `channelId`, `sessionId`, `messageId` e `agentSpecificData`.
|
||||
- Contestação VAA.005-009 preserva itens/valores ajustados e protocolo.
|
||||
- Finalização CVN.010/011 preserva protocolo TIM/URA e billing context.
|
||||
- RCTs derivados de retry HTTP carregam `apiUrl`, `apiStatusCode`, `apiResponsePayload` e `latencyMs`.
|
||||
- SMS e Service Request Status carregam metadata de transporte e contexto de protocolo.
|
||||
- `tim_payload_mapper` aceita o formato histórico `agentSpecificData` JSON-string e o converte para o objeto canônico TIM no payload final.
|
||||
|
||||
## Baseline 565 — metadata MPI/VEB/SAD e VAS estratégico
|
||||
|
||||
- Regressão: **565 passed / 0 skipped / 0 xfailed**.
|
||||
- `VEB.*`, `MPI.*`, `CVN.*` e `SAD.*` passam a carregar metadata conversacional TIM via `_event_context`: `customerMessage`, `llmResponse`, `messageId`, `sessionId`, `channelId`, `uraCallId`, `billingId` e `sessionEndAt` quando aplicável.
|
||||
- `SAD.001` normaliza `session_end_at` ISO-8601 para epoch milliseconds.
|
||||
- VAS Estratégico recuperou a semântica histórica: `NAO` estratégico -> `VEB.004 -> VEB.006 -> VEB.007`; Bundle + `NAO` -> `VEB.004 -> VEB.005 -> VEB.007` e protocolo deferido para finalização; `SIM` -> `VEB.003` e registro de atendimento.
|
||||
- Invoice Explanation (`MPI.005/006`), Pró-Rata (`MPI.010`) e cancelamento (`MPI.011`) usam o mesmo enriquecimento de contexto.
|
||||
|
||||
## Baseline 570 testes
|
||||
|
||||
- `pytest -q`: **570 passed**, 0 skipped, 0 xfailed.
|
||||
- `pyproject.toml` limita o gate padrão a `tests/`, evitando coleta acidental dos scripts de teste duplicados existentes dentro dos templates do framework.
|
||||
- `cancelar_vas_avulso` redireciona automaticamente para `vas_estrategico` quando o `InvoiceResolver` classifica a cobrança como estratégico/bundle.
|
||||
- `invoice_explanation` recuperou `recomenda_finalizacao/status_finalizacao_sugerido` por branch do `WorkflowRuntime`.
|
||||
- `pro_rata` recuperou recomendação de finalização nos branches `registrar_aceitou` e `registrar_nao_controle`.
|
||||
- VAS Estratégico recuperou a busca de orientação do parceiro sem RAG próprio: a action declara `requires_rag/rag_queries`, e o `AgentRuntimeMixin` executa `RagService` do framework.
|
||||
|
||||
## Baseline 578 - wrapper cancelamento + LLM composition
|
||||
|
||||
- 593 testes passando; zero skipped/xfail.
|
||||
- Cancelamento preserva `auto_finalize_on_failure` em falha técnica de contestação.
|
||||
- Item já contestado não mascara cancelamento concluído como falha sistêmica.
|
||||
- `cancelamento_vas_protocol` e todos os protocolos de resposta são preservados.
|
||||
- Plano família contesta titular + dependentes em uma única `contestacao_tool`.
|
||||
- Lote com muitos no-match continua contestando exatamente os candidatos elegíveis.
|
||||
- Pró-rata usa `requires_llm_composition` do framework em vez de gateway LLM de domínio.
|
||||
|
||||
|
||||
## Continuação — paridade explícita dos wrappers (baseline 593)
|
||||
|
||||
- `contestacao_tool` volta a garantir `tipo_atendimento=contestacao` e preserva o contexto do turno (`message_id`, `customer_message`, `ura_call_id`, `channel_id`, `ani`, `invoice_id`).
|
||||
- Falhas de contestação são diferenciadas entre erro técnico (`erro_falha_sistema`) e conflito/item já contestado com mensagem/protocolo do provider.
|
||||
- Cancelamento composto aceita tanto `contestation_candidates` quanto o alias histórico `itens_para_contestacao`.
|
||||
- Resultado agregado em `cancelados/nao_cancelados` é aceito mesmo quando `results[]` não repete a flag `success`.
|
||||
- `cpf` volta a ser alias de `social_sec_no` e é normalizado para dígitos antes de protocolo/contestação.
|
||||
- Em fluxo misto Bundle + Estratégico no branch NÃO, o protocolo segue deferido para finalização, porém as `rag_queries` dos serviços estratégicos são preservadas.
|
||||
- Falha parcial com candidato continua encadeando `cancelamento_vas_avulso -> contestacao_tool`; falha de SMS não transforma o cancelamento em falha.
|
||||
- `pytest -q`: **593 passed, 0 skipped, 0 xfailed**.
|
||||
|
||||
## Baseline 599 testes — paridade explícita de wrappers
|
||||
|
||||
Validação consolidada: `599 passed`, `0 skipped`, `0 xfailed`.
|
||||
|
||||
A rodada adicionou regressões 1:1 baseadas nos wrappers históricos para:
|
||||
|
||||
- `itens_ja_contestados` preservados desde a action de contestação até o compositor de resposta;
|
||||
- classificação de `contested_items`, `not_contested_items` e itens já contestados feita no domínio, não reconstruída no MCP;
|
||||
- totais de contestação calculados somente sobre itens efetivamente aceitos;
|
||||
- valor `0`/`0,00` retornado pela contestação tratado como ausência de valor útil para composição, usando o total cancelado;
|
||||
- valores monetários normalizados em pt-BR na borda do MCP (`14,99`);
|
||||
- `next_subject` não interfere na composição determinística de cancelamento;
|
||||
- falha de serviço em `invoice_explanation` preserva a fraseologia canônica e não ativa auto-finalização.
|
||||
|
||||
Gates: `compileall` PASS, zero imports do namespace legado e zero imports diretos de LangGraph em `app/`/`mcp/`.
|
||||
|
||||
## Baseline 615 — contratos 1:1 dos wrappers históricos
|
||||
|
||||
A regressão foi ampliada para 615 testes executados, sem skips e sem xfails.
|
||||
Nesta etapa foram portados como contratos explícitos do MCP novo os seguintes
|
||||
outcomes do `backend_cancelar_vas_single` e `finalize_support` históricos:
|
||||
|
||||
- sucesso implícito quando o workflow reporta `cancelados[]` sem `success=true`;
|
||||
- lista explícita vazia de candidatos não cria fallback indevido para contestação;
|
||||
- no-match não chama contestação nem vocaliza valor como se houvesse ajuste;
|
||||
- `protocol_closed` da contestação é preservado;
|
||||
- flags internas `sms_sent` não vazam no contrato externo e falha de SMS é propagada por `sms_not_send_error`;
|
||||
- cancelamento com protocolo e sem item efetivamente contestado continua resolvido;
|
||||
- candidato explícito pode seguir para RT-02 mesmo após falha/no-match em RT-01;
|
||||
- falha parcial de bloqueio/cancelamento continua elegível à contestação quando marcada pelo domínio;
|
||||
- `holder_msisdn` não pode ser sobrescrito por linha dependente;
|
||||
- item do titular não é marcado como dependente;
|
||||
- titular + múltiplos dependentes são agregados em uma única contestação do titular;
|
||||
- VAS estratégico após invoice explanation prioriza nota estratégica na finalização;
|
||||
- Bundle + Estratégico deferidos geram RT-15 combinado na finalização;
|
||||
- invoice explanation não abre protocolo informacional antes da finalização.
|
||||
|
||||
Gate executado:
|
||||
|
||||
```text
|
||||
pytest -q: 615 passed
|
||||
compileall app/mcp/framework: PASS
|
||||
agente_contas_tim em app/mcp/framework runtime: 0
|
||||
import direto langgraph.graph em app/mcp: 0
|
||||
```
|
||||
Reference in New Issue
Block a user