bugfix: oci_openai provider
This commit is contained in:
@@ -448,25 +448,69 @@ class ComplianceRail(Guardrail):
|
|||||||
requer = ctx.get("tipo_fluxo") == "ajuste" or ctx.get("requer_protocolo") is True
|
requer = ctx.get("tipo_fluxo") == "ajuste" or ctx.get("requer_protocolo") is True
|
||||||
if not requer:
|
if not requer:
|
||||||
return RailDecision(code=self.code, allowed=True, sanitized_text=None, reason="Compliance Anatel não aplicável", metadata={"calibrated": True})
|
return RailDecision(code=self.code, allowed=True, sanitized_text=None, reason="Compliance Anatel não aplicável", metadata={"calibrated": True})
|
||||||
expected = list(ctx.get("expected_protocols") or [])
|
|
||||||
if self._PROTOCOL_PATTERN.search(text or ""):
|
original = text or ""
|
||||||
return RailDecision(code=self.code, allowed=True, reason="Resposta contém protocolo obrigatório", metadata={"calibrated": True})
|
expected = [str(value).strip() for value in (ctx.get("expected_protocols") or []) if str(value).strip()]
|
||||||
patched, missing = self._apply_protocol_fallback(text or "", expected)
|
|
||||||
if patched != (text or ""):
|
# Quando o workflow informa os protocolos esperados, esses valores são a
|
||||||
|
# fonte de verdade. Valide-os diretamente no texto (cru ou vocalizado)
|
||||||
|
# antes de recorrer ao regex genérico. Isso evita tanto falso negativo
|
||||||
|
# por distância/Markdown quanto falso positivo por um protocolo diferente.
|
||||||
|
if expected:
|
||||||
|
patched, missing = self._apply_protocol_fallback(original, expected)
|
||||||
|
if not missing:
|
||||||
|
return RailDecision(
|
||||||
|
code=self.code,
|
||||||
|
allowed=True,
|
||||||
|
reason="Resposta contém o(s) protocolo(s) esperado(s)",
|
||||||
|
sanitized_text=None,
|
||||||
|
metadata={
|
||||||
|
"expected_protocols": expected,
|
||||||
|
"protocol_validation": "expected_values",
|
||||||
|
"mechanism": "deterministic",
|
||||||
|
"calibrated": True,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
return RailDecision(
|
return RailDecision(
|
||||||
code=self.code,
|
code=self.code,
|
||||||
allowed=True,
|
allowed=True,
|
||||||
reason="Resposta sem protocolo obrigatório; protocolo anexado deterministicamente",
|
reason="Resposta sem protocolo obrigatório; protocolo anexado deterministicamente",
|
||||||
sanitized_text=patched,
|
sanitized_text=patched,
|
||||||
metadata={"missing_protocols_spoken": missing, "expected_protocols": expected, "mechanism": "deterministic", "calibrated": True},
|
metadata={
|
||||||
|
"missing_protocols_spoken": missing,
|
||||||
|
"expected_protocols": expected,
|
||||||
|
"protocol_validation": "expected_values",
|
||||||
|
"mechanism": "deterministic",
|
||||||
|
"calibrated": True,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Compatibilidade para fluxos legados que exigem protocolo, mas não
|
||||||
|
# fornecem expected_protocols: nesse caso ainda usamos o reconhecimento
|
||||||
|
# genérico por regex.
|
||||||
|
if self._PROTOCOL_PATTERN.search(original):
|
||||||
|
return RailDecision(
|
||||||
|
code=self.code,
|
||||||
|
allowed=True,
|
||||||
|
reason="Resposta contém protocolo obrigatório",
|
||||||
|
metadata={
|
||||||
|
"protocol_validation": "generic_regex",
|
||||||
|
"mechanism": "deterministic",
|
||||||
|
"calibrated": True,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
return RailDecision(
|
return RailDecision(
|
||||||
code=self.code,
|
code=self.code,
|
||||||
allowed=False,
|
allowed=False,
|
||||||
reason="Resposta de ajuste sem número de protocolo",
|
reason="Resposta de ajuste sem número de protocolo",
|
||||||
sanitized_text=text,
|
sanitized_text=text,
|
||||||
metadata={
|
metadata={
|
||||||
"expected_protocols": expected, "mechanism": "deterministic", "calibrated": True,
|
"expected_protocols": expected,
|
||||||
|
"protocol_validation": "generic_regex",
|
||||||
|
"mechanism": "deterministic",
|
||||||
|
"calibrated": True,
|
||||||
"terminal_action": "retry",
|
"terminal_action": "retry",
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -135,6 +135,7 @@ src/agent_framework/llm/__init__.py
|
|||||||
src/agent_framework/llm/base.py
|
src/agent_framework/llm/base.py
|
||||||
src/agent_framework/llm/profile_resolver.py
|
src/agent_framework/llm/profile_resolver.py
|
||||||
src/agent_framework/llm/providers.py
|
src/agent_framework/llm/providers.py
|
||||||
|
src/agent_framework/llm/structured_output.py
|
||||||
src/agent_framework/llm/types.py
|
src/agent_framework/llm/types.py
|
||||||
src/agent_framework/mcp/__init__.py
|
src/agent_framework/mcp/__init__.py
|
||||||
src/agent_framework/mcp/client.py
|
src/agent_framework/mcp/client.py
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,5 +1,7 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from agent_framework.llm.structured_output import parse_json_object
|
||||||
|
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
import re
|
import re
|
||||||
@@ -246,13 +248,4 @@ class GlobalSupervisorRouter:
|
|||||||
return text.strip()
|
return text.strip()
|
||||||
|
|
||||||
def _parse_json(self, raw: Any) -> dict[str, Any]:
|
def _parse_json(self, raw: Any) -> dict[str, Any]:
|
||||||
if isinstance(raw, dict):
|
return parse_json_object(raw)
|
||||||
return raw
|
|
||||||
text = str(raw).strip()
|
|
||||||
if text.startswith("```"):
|
|
||||||
text = re.sub(r"^```(?:json)?", "", text).strip()
|
|
||||||
text = re.sub(r"```$", "", text).strip()
|
|
||||||
match = re.search(r"\{.*\}", text, flags=re.S)
|
|
||||||
if match:
|
|
||||||
text = match.group(0)
|
|
||||||
return json.loads(text)
|
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -42,6 +42,8 @@ Uso via função standalone (compatibilidade):
|
|||||||
"""
|
"""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from agent_framework.llm.structured_output import parse_json_object
|
||||||
|
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
from typing import Any
|
from typing import Any
|
||||||
@@ -239,10 +241,10 @@ def classify_confirmation(
|
|||||||
return False, f"invoke_error — fallback pessimista: {exc}"
|
return False, f"invoke_error — fallback pessimista: {exc}"
|
||||||
|
|
||||||
try:
|
try:
|
||||||
payload: dict[str, Any] = json.loads(raw)
|
payload: dict[str, Any] = parse_json_object(raw)
|
||||||
except (json.JSONDecodeError, TypeError) as exc:
|
except (ValueError, TypeError) as exc:
|
||||||
logger.warning(
|
logger.warning(
|
||||||
"confirmation_rail.json_parse_failed raw=%r error=%r — fallback pessimista",
|
"confirmation_rail.structured_parse_failed raw=%r error=%r — fallback pessimista",
|
||||||
raw[:200],
|
raw[:200],
|
||||||
exc,
|
exc,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -16,6 +16,8 @@ Contexto de migração:
|
|||||||
"""
|
"""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from agent_framework.llm.structured_output import parse_json_object
|
||||||
|
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
@@ -89,7 +91,7 @@ class RagsecRail:
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
raw = self._client.invoke(self.code, input_vars)
|
raw = self._client.invoke(self.code, input_vars)
|
||||||
result: dict = json.loads(raw) if isinstance(raw, str) else raw
|
result: dict = parse_json_object(raw) if isinstance(raw, str) else raw
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
logger.error(
|
logger.error(
|
||||||
"ragsec_rail.invoke_error session=%s exc=%r — assuming allowed",
|
"ragsec_rail.invoke_error session=%s exc=%r — assuming allowed",
|
||||||
|
|||||||
@@ -15,6 +15,8 @@ Contexto de migração:
|
|||||||
"""
|
"""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from agent_framework.llm.structured_output import parse_json_object
|
||||||
|
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
@@ -88,7 +90,7 @@ class RevprecRail:
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
raw = self._client.invoke(self.code, input_vars)
|
raw = self._client.invoke(self.code, input_vars)
|
||||||
result: dict = json.loads(raw) if isinstance(raw, str) else raw
|
result: dict = parse_json_object(raw) if isinstance(raw, str) else raw
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
logger.error(
|
logger.error(
|
||||||
"revprec_rail.invoke_error session=%s exc=%r — assuming allowed",
|
"revprec_rail.invoke_error session=%s exc=%r — assuming allowed",
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ Implementa o Protocol ``Rail`` de contracts.py (AT-06.2).
|
|||||||
"""
|
"""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from agent_framework.llm.structured_output import parse_json_object
|
||||||
|
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
@@ -133,7 +135,7 @@ class CorrespondenciaItemRail:
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
raw = self._client.invoke(self.code, input_vars)
|
raw = self._client.invoke(self.code, input_vars)
|
||||||
result: dict = json.loads(raw) if isinstance(raw, str) else raw
|
result: dict = parse_json_object(raw) if isinstance(raw, str) else raw
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
logger.error(
|
logger.error(
|
||||||
"correspondencia_item_rail.invoke_error session=%s exc=%r — assuming no violation",
|
"correspondencia_item_rail.invoke_error session=%s exc=%r — assuming no violation",
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ Implementa o Protocol ``Rail`` de contracts.py (AT-06.4).
|
|||||||
"""
|
"""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from agent_framework.llm.structured_output import parse_json_object
|
||||||
|
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
@@ -127,7 +129,7 @@ class GroundednessRail:
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
raw = self._client.invoke(self.code, input_vars)
|
raw = self._client.invoke(self.code, input_vars)
|
||||||
result: dict = json.loads(raw) if isinstance(raw, str) else raw
|
result: dict = parse_json_object(raw) if isinstance(raw, str) else raw
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
logger.error(
|
logger.error(
|
||||||
"groundedness_rail.invoke_error session=%s exc=%r — assuming no violation",
|
"groundedness_rail.invoke_error session=%s exc=%r — assuming no violation",
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ Implementa o Protocol ``Rail`` de contracts.py (AT-06.1).
|
|||||||
"""
|
"""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from agent_framework.llm.structured_output import parse_json_object
|
||||||
|
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
@@ -131,7 +133,7 @@ class IntencaoCancelarRail:
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
raw = self._client.invoke(self.code, input_vars)
|
raw = self._client.invoke(self.code, input_vars)
|
||||||
result: dict = json.loads(raw) if isinstance(raw, str) else raw
|
result: dict = parse_json_object(raw) if isinstance(raw, str) else raw
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
logger.error(
|
logger.error(
|
||||||
"intencao_cancelar_rail.invoke_error session=%s exc=%r — assuming no violation",
|
"intencao_cancelar_rail.invoke_error session=%s exc=%r — assuming no violation",
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ Implementa o Protocol ``Rail`` de contracts.py (AT-06.3).
|
|||||||
"""
|
"""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from agent_framework.llm.structured_output import parse_json_object
|
||||||
|
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
@@ -135,7 +137,7 @@ class QuantidadeCoerente:
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
raw = self._client.invoke(self.code, input_vars)
|
raw = self._client.invoke(self.code, input_vars)
|
||||||
result: dict = json.loads(raw) if isinstance(raw, str) else raw
|
result: dict = parse_json_object(raw) if isinstance(raw, str) else raw
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
logger.error(
|
logger.error(
|
||||||
"quantidade_coerente_rail.invoke_error session=%s exc=%r — assuming no violation",
|
"quantidade_coerente_rail.invoke_error session=%s exc=%r — assuming no violation",
|
||||||
|
|||||||
@@ -11,6 +11,8 @@ Implementa o Protocol ``Rail`` de contracts.py (AT-06.6).
|
|||||||
"""
|
"""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from agent_framework.llm.structured_output import parse_json_object
|
||||||
|
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
@@ -131,7 +133,7 @@ class ServicoCorrretoRail:
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
raw = self._client.invoke(self.code, input_vars)
|
raw = self._client.invoke(self.code, input_vars)
|
||||||
result: dict = json.loads(raw) if isinstance(raw, str) else raw
|
result: dict = parse_json_object(raw) if isinstance(raw, str) else raw
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
logger.error(
|
logger.error(
|
||||||
"servico_correto_rail.invoke_error session=%s exc=%r — assuming no violation",
|
"servico_correto_rail.invoke_error session=%s exc=%r — assuming no violation",
|
||||||
|
|||||||
@@ -11,6 +11,8 @@ Implementa o Protocol ``Rail`` de contracts.py (AT-06.5).
|
|||||||
"""
|
"""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from agent_framework.llm.structured_output import parse_json_object
|
||||||
|
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
@@ -128,7 +130,7 @@ class VerbalizacaoPrematura:
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
raw = self._client.invoke(self.code, input_vars)
|
raw = self._client.invoke(self.code, input_vars)
|
||||||
result: dict = json.loads(raw) if isinstance(raw, str) else raw
|
result: dict = parse_json_object(raw) if isinstance(raw, str) else raw
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
logger.error(
|
logger.error(
|
||||||
"verbalizacao_prematura_rail.invoke_error session=%s exc=%r — assuming no violation",
|
"verbalizacao_prematura_rail.invoke_error session=%s exc=%r — assuming no violation",
|
||||||
|
|||||||
@@ -22,6 +22,8 @@ Fallback conservador:
|
|||||||
"""
|
"""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from agent_framework.llm.structured_output import parse_json_object
|
||||||
|
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
@@ -155,7 +157,7 @@ class ToxRail:
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
raw = self._client.invoke(self.code, input_vars)
|
raw = self._client.invoke(self.code, input_vars)
|
||||||
result: dict = json.loads(raw) if isinstance(raw, str) else raw
|
result: dict = parse_json_object(raw) if isinstance(raw, str) else raw
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
logger.error(
|
logger.error(
|
||||||
"tox_rail.invoke_error session=%s exc=%r — assuming allowed",
|
"tox_rail.invoke_error session=%s exc=%r — assuming allowed",
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,5 +1,7 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from agent_framework.llm.structured_output import parse_json_object
|
||||||
|
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
@@ -85,15 +87,9 @@ def _extract_text(raw: Any) -> str:
|
|||||||
|
|
||||||
def _parse_json(text: str) -> dict[str, Any]:
|
def _parse_json(text: str) -> dict[str, Any]:
|
||||||
try:
|
try:
|
||||||
return json.loads(text)
|
return parse_json_object(text)
|
||||||
except Exception:
|
except Exception:
|
||||||
match = re.search(r"\{[\s\S]*\}", text or "")
|
return {"allowed": False, "label": "ERROR", "reason": (text or "")[:500]}
|
||||||
if match:
|
|
||||||
try:
|
|
||||||
return json.loads(match.group(0))
|
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
return {"allowed": False, "label": "ERROR", "reason": (text or "")[:500]}
|
|
||||||
|
|
||||||
|
|
||||||
def _first_substring_match(text: str, triggers: tuple[str, ...]) -> str | None:
|
def _first_substring_match(text: str, triggers: tuple[str, ...]) -> str | None:
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from agent_framework.llm.structured_output import parse_json_object
|
||||||
|
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
from typing import Any
|
from typing import Any
|
||||||
@@ -102,16 +104,4 @@ def _safe_context(context: dict[str, Any]) -> dict[str, Any]:
|
|||||||
|
|
||||||
|
|
||||||
def _parse_json(raw: Any) -> dict[str, Any]:
|
def _parse_json(raw: Any) -> dict[str, Any]:
|
||||||
text = str(raw or "").strip()
|
return parse_json_object(raw)
|
||||||
if text.startswith("```"):
|
|
||||||
text = text.strip("`")
|
|
||||||
if text.lower().startswith("json"):
|
|
||||||
text = text[4:].strip()
|
|
||||||
start = text.find("{")
|
|
||||||
end = text.rfind("}")
|
|
||||||
if start >= 0 and end >= start:
|
|
||||||
text = text[start:end + 1]
|
|
||||||
data = json.loads(text)
|
|
||||||
if not isinstance(data, dict):
|
|
||||||
raise ValueError("LLM guardrail returned non-object JSON")
|
|
||||||
return data
|
|
||||||
|
|||||||
@@ -448,25 +448,69 @@ class ComplianceRail(Guardrail):
|
|||||||
requer = ctx.get("tipo_fluxo") == "ajuste" or ctx.get("requer_protocolo") is True
|
requer = ctx.get("tipo_fluxo") == "ajuste" or ctx.get("requer_protocolo") is True
|
||||||
if not requer:
|
if not requer:
|
||||||
return RailDecision(code=self.code, allowed=True, sanitized_text=None, reason="Compliance Anatel não aplicável", metadata={"calibrated": True})
|
return RailDecision(code=self.code, allowed=True, sanitized_text=None, reason="Compliance Anatel não aplicável", metadata={"calibrated": True})
|
||||||
expected = list(ctx.get("expected_protocols") or [])
|
|
||||||
if self._PROTOCOL_PATTERN.search(text or ""):
|
original = text or ""
|
||||||
return RailDecision(code=self.code, allowed=True, reason="Resposta contém protocolo obrigatório", metadata={"calibrated": True})
|
expected = [str(value).strip() for value in (ctx.get("expected_protocols") or []) if str(value).strip()]
|
||||||
patched, missing = self._apply_protocol_fallback(text or "", expected)
|
|
||||||
if patched != (text or ""):
|
# Quando o workflow informa os protocolos esperados, esses valores são a
|
||||||
|
# fonte de verdade. Valide-os diretamente no texto (cru ou vocalizado)
|
||||||
|
# antes de recorrer ao regex genérico. Isso evita tanto falso negativo
|
||||||
|
# por distância/Markdown quanto falso positivo por um protocolo diferente.
|
||||||
|
if expected:
|
||||||
|
patched, missing = self._apply_protocol_fallback(original, expected)
|
||||||
|
if not missing:
|
||||||
|
return RailDecision(
|
||||||
|
code=self.code,
|
||||||
|
allowed=True,
|
||||||
|
reason="Resposta contém o(s) protocolo(s) esperado(s)",
|
||||||
|
sanitized_text=None,
|
||||||
|
metadata={
|
||||||
|
"expected_protocols": expected,
|
||||||
|
"protocol_validation": "expected_values",
|
||||||
|
"mechanism": "deterministic",
|
||||||
|
"calibrated": True,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
return RailDecision(
|
return RailDecision(
|
||||||
code=self.code,
|
code=self.code,
|
||||||
allowed=True,
|
allowed=True,
|
||||||
reason="Resposta sem protocolo obrigatório; protocolo anexado deterministicamente",
|
reason="Resposta sem protocolo obrigatório; protocolo anexado deterministicamente",
|
||||||
sanitized_text=patched,
|
sanitized_text=patched,
|
||||||
metadata={"missing_protocols_spoken": missing, "expected_protocols": expected, "mechanism": "deterministic", "calibrated": True},
|
metadata={
|
||||||
|
"missing_protocols_spoken": missing,
|
||||||
|
"expected_protocols": expected,
|
||||||
|
"protocol_validation": "expected_values",
|
||||||
|
"mechanism": "deterministic",
|
||||||
|
"calibrated": True,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Compatibilidade para fluxos legados que exigem protocolo, mas não
|
||||||
|
# fornecem expected_protocols: nesse caso ainda usamos o reconhecimento
|
||||||
|
# genérico por regex.
|
||||||
|
if self._PROTOCOL_PATTERN.search(original):
|
||||||
|
return RailDecision(
|
||||||
|
code=self.code,
|
||||||
|
allowed=True,
|
||||||
|
reason="Resposta contém protocolo obrigatório",
|
||||||
|
metadata={
|
||||||
|
"protocol_validation": "generic_regex",
|
||||||
|
"mechanism": "deterministic",
|
||||||
|
"calibrated": True,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
return RailDecision(
|
return RailDecision(
|
||||||
code=self.code,
|
code=self.code,
|
||||||
allowed=False,
|
allowed=False,
|
||||||
reason="Resposta de ajuste sem número de protocolo",
|
reason="Resposta de ajuste sem número de protocolo",
|
||||||
sanitized_text=text,
|
sanitized_text=text,
|
||||||
metadata={
|
metadata={
|
||||||
"expected_protocols": expected, "mechanism": "deterministic", "calibrated": True,
|
"expected_protocols": expected,
|
||||||
|
"protocol_validation": "generic_regex",
|
||||||
|
"mechanism": "deterministic",
|
||||||
|
"calibrated": True,
|
||||||
"terminal_action": "retry",
|
"terminal_action": "retry",
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user