Files
agent_contas/tests/migration/original_test_out_of_scope.py

45 lines
1.5 KiB
Python

"""Testes do contrato de saída do rail OOS.
O `label` ("IN_SCOPE"/"OUT_OF_SCOPE") saiu do prompt em 2026-08-05: nenhum
consumidor de produção o lia (a decisão usa `allowed` + `code`, fixado no
pipeline) e ele era gerado a cada turno. O `reason` passou a vir VAZIO quando
`allowed=true`, como no FRASEOLOGIA — descrever por que algo está DENTRO do
escopo não é lido por ninguém.
"""
from __future__ import annotations
import os
import pytest
os.environ.setdefault("USE_MOCK_LLM", "true")
from agent_framework.guardrails.calibrated.llm_rails import out_of_scope
from agent_framework.guardrails.calibrated.prompts.out_of_scope import build_oos_prompt
@pytest.fixture(autouse=True)
def _force_mock(monkeypatch):
monkeypatch.setenv("USE_MOCK_LLM", "true")
def test_prompt_oos_nao_pede_mais_label():
prompt = build_oos_prompt("Posso ajudar com sua fatura?")
assert '"label"' not in prompt
assert "IN_SCOPE" not in prompt.split("Responda APENAS JSON valido:")[-1]
def test_prompt_oos_exige_reason_vazio_quando_allowed():
prompt = build_oos_prompt("Posso ajudar com sua fatura?")
contrato = prompt.split("Responda APENAS JSON valido:")[-1]
assert "se allowed=true: string vazia" in contrato
# e os exemplos de IN_SCOPE seguem a mesma regra
assert '{"allowed": true, "reason": ""}' in prompt
def test_oos_rail_devolve_shape_esperado():
r = out_of_scope("Posso te ajudar com mais alguma dúvida sobre a fatura?")
assert r.code == "OOS"
assert r.mechanism == "llm_supervisor"
assert isinstance(r.allowed, bool)