Ajustes conforme relatorio de testes 2026-08-27
This commit is contained in:
80
tests/migration/test_revprec_epistemic_uncertainty.py
Normal file
80
tests/migration/test_revprec_epistemic_uncertainty.py
Normal file
@@ -0,0 +1,80 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import pytest
|
||||
|
||||
from app.extensions.tim_guardrails import TimPrematureActionRail
|
||||
|
||||
|
||||
class FakeLLM:
|
||||
def __init__(self, content: str):
|
||||
self.content = content
|
||||
|
||||
async def ainvoke(self, messages, **kwargs):
|
||||
return self.content
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_revprec_allows_structured_insufficient_evidence_without_calling_llm():
|
||||
text = "Identifiquei dados de desconto, mas os dados disponíveis não informam o motivo da retirada ou do término do desconto."
|
||||
|
||||
class MustNotRunLLM:
|
||||
async def ainvoke(self, *args, **kwargs):
|
||||
raise AssertionError("LLM não deveria ser chamada no bypass estrutural")
|
||||
|
||||
ctx = {
|
||||
"guardrail_llm": MustNotRunLLM(),
|
||||
"mcp_results": [
|
||||
{
|
||||
"tool_name": "termino_desconto",
|
||||
"ok": True,
|
||||
"result": {
|
||||
"output": {
|
||||
"formatar": {
|
||||
"mensagem": text,
|
||||
"epistemic_status": "insufficient_evidence",
|
||||
"discount_reason_grounded": False,
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
],
|
||||
}
|
||||
out = await TimPrematureActionRail().evaluate(text, ctx)
|
||||
assert out.allowed is True
|
||||
assert out.reason == "insufficient_evidence_non_assertive"
|
||||
assert out.metadata["mechanism"] == "deterministic_epistemic_bypass"
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_revprec_does_not_bypass_if_message_does_not_match_structured_result():
|
||||
structured = "Os dados disponíveis não informam o motivo."
|
||||
text = "Cancelei o serviço com sucesso."
|
||||
ctx = {
|
||||
"guardrail_llm": FakeLLM("1"),
|
||||
"mcp_results": [{"result": {"output": {"mensagem": structured, "epistemic_status": "insufficient_evidence"}}}],
|
||||
}
|
||||
out = await TimPrematureActionRail().evaluate(text, ctx)
|
||||
assert out.allowed is False
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_revprec_still_blocks_real_premature_action_without_structured_marker():
|
||||
out = await TimPrematureActionRail().evaluate(
|
||||
"Cancelei o serviço com sucesso.",
|
||||
{"guardrail_llm": FakeLLM("1"), "mcp_results": []},
|
||||
)
|
||||
assert out.allowed is False
|
||||
|
||||
|
||||
def test_termino_desconto_declares_epistemic_status():
|
||||
from app.domain.contas.service import ContasDomainService
|
||||
from app.domain.contas.workflow_actions import build_contas_workflow_actions
|
||||
|
||||
action = build_contas_workflow_actions(ContasDomainService()).get("formatar_capability_resposta")
|
||||
no_reason = action({"tipo": "termino_desconto"}, {"input": {}})
|
||||
with_reason = action(
|
||||
{"tipo": "termino_desconto", "discount_evidence": {"discount_reason": "fim da campanha"}},
|
||||
{"input": {}},
|
||||
)
|
||||
assert no_reason["epistemic_status"] == "insufficient_evidence"
|
||||
assert with_reason["epistemic_status"] == "grounded_fact"
|
||||
Reference in New Issue
Block a user