nova funcionalidade: reconciliacao temporal

This commit is contained in:
2026-09-02 13:07:21 -03:00
parent e6c254ff83
commit 76c8cdc738
190 changed files with 747 additions and 82 deletions

View File

@@ -0,0 +1,24 @@
from __future__ import annotations
import pytest
from app.agents.suporte_contas_agent import SuporteContasAgent
class MustNotRunLLM:
async def ainvoke(self, *args, **kwargs):
raise AssertionError("no_match_retry já é decisão de controle e não deve ser reinterpretado")
@pytest.mark.asyncio
async def test_no_match_retry_returns_safe_clarification_without_generative_reinterpretation():
agent = SuporteContasAgent(MustNotRunLLM(), tool_router=None)
state = {
"intent": "contas_no_match_retry",
"user_text": "bota dois planos um em cima do outro pra cá",
"sanitized_input": "bota dois planos um em cima do outro pra cá",
"mcp_tools": [],
"context": {},
}
result = await agent.run(state)
assert result["answer"] == "Desculpe, não entendi. Poderia repetir de outra forma?"

View File

@@ -177,3 +177,61 @@ async def test_revprec_does_not_use_state_or_history_as_authoritative_exact_mess
}
out = await TimPrematureActionRail().evaluate(text, ctx)
assert out.allowed is False
@pytest.mark.asyncio
async def test_revprec_allows_plain_invoice_explanation_without_llm():
text = "[FaturasAgent] Analisando a sua fatura atual, a variação foi de R$ 46,99 com Tamboro Mensal de R$ 14,99."
class MustNotRunLLM:
async def ainvoke(self, *args, **kwargs):
raise AssertionError("explicação informacional não deve ser julgada como execução prematura")
out = await TimPrematureActionRail().evaluate(
text,
{"guardrail_llm": MustNotRunLLM(), "mcp_results": []},
)
assert out.allowed is True
assert out.reason == "no_operational_completion_claim"
assert out.metadata["mechanism"] == "deterministic_claim_scope"
@pytest.mark.asyncio
async def test_revprec_allows_composed_contestation_when_current_execution_structurally_proves_claims():
text = (
"Sua contestação do valor R$ 14,99 referente ao Tamboro Mensal foi registrada com sucesso. "
"O protocolo aberto é 1234567890. Um novo boleto será emitido e você recebeu um SMS."
)
class MustNotRunLLM:
async def ainvoke(self, *args, **kwargs):
raise AssertionError("evidência estrutural suficiente não deve ser re-julgada probabilisticamente")
ctx = {
"guardrail_llm": MustNotRunLLM(),
"mcp_results": [
{
"tool_name": "qualquer_tool_transacional",
"ok": True,
"result": {
"status": "COMPLETED",
"output": {
"registrar": {
"success": True,
"contestation_registered": True,
"contested_invoice_amount": "14.99",
"sr": "1234567890",
"sms_sent": True,
"barcode": "34191.79001 01043.510047",
"items": [
{"itemName": "Tamboro Mensal", "message": "Contestação criada com sucesso"}
],
}
},
},
}
],
}
out = await TimPrematureActionRail().evaluate(text, ctx)
assert out.allowed is True
assert out.reason == "current_execution_structurally_grounded"
assert out.metadata["mechanism"] == "deterministic_structured_execution_evidence"