ajuste no contas
This commit is contained in:
@@ -147,10 +147,36 @@ def evaluate(state: dict[str, Any]) -> PolicyDecision | None:
|
||||
method = str(route_decision.get("method") or "")
|
||||
intent = str(state.get("intent") or route_decision.get("intent") or "")
|
||||
|
||||
previous_count = int(state.get("no_match_count") or 0)
|
||||
reset_patch: dict[str, Any] = {"no_match_count": 0} if previous_count else {}
|
||||
|
||||
# Explicit conversational closure is a lifecycle signal, not a new business
|
||||
# intent. It must take precedence over router no-match so deterministic closure
|
||||
# phrases are not turned into generic fallback responses. Never consume it while
|
||||
# a transaction/workflow is still live.
|
||||
if _CLOSE_RE.search(text) and not _has_live_transaction(state):
|
||||
return PolicyDecision(
|
||||
route="end_session", intent="contas_conversation_close",
|
||||
reason="explicit_customer_closure",
|
||||
patch={**reset_patch, "terminal_status": "resolvido",
|
||||
"conversation_terminal_message": "Atendimento encerrado. Obrigado pelo contato."},
|
||||
)
|
||||
|
||||
# The first utterance after a completed operational boundary is a fresh
|
||||
# interaction, never a resume of the workflow that just ended. A short
|
||||
# re-engagement such as "ah espera" may legitimately have no business intent
|
||||
# yet; answer with a neutral invitation instead of treating it as an error.
|
||||
if intent == "contas_no_match" and bool(state.get("operational_context_reset")):
|
||||
return PolicyDecision(
|
||||
route="conversation_policy_response", intent="contas_post_terminal_reentry",
|
||||
answer="Claro. Pode falar. Em que posso ajudar agora?",
|
||||
reason="fresh_interaction_after_operational_boundary",
|
||||
patch={**reset_patch, "no_match_count": 0},
|
||||
)
|
||||
|
||||
# 1) Consecutive incomprehensible utterances. A router fallback is the generic,
|
||||
# architecture-native signal that no intent was understood. Any understood turn
|
||||
# resets the counter. Default requirement is three consecutive failures.
|
||||
previous_count = int(state.get("no_match_count") or 0)
|
||||
if intent == "contas_no_match":
|
||||
count = previous_count + 1
|
||||
limit = max(1, int(os.getenv("CONTAS_NO_MATCH_MAX_CONSECUTIVE", "3")))
|
||||
@@ -167,18 +193,6 @@ def evaluate(state: dict[str, Any]) -> PolicyDecision | None:
|
||||
reason="no_match_retry", patch={"no_match_count": count},
|
||||
)
|
||||
|
||||
reset_patch: dict[str, Any] = {"no_match_count": 0} if previous_count else {}
|
||||
|
||||
# Explicit conversational closure is a lifecycle signal, not a new business
|
||||
# intent. Never consume it while a transaction/workflow is still live.
|
||||
if _CLOSE_RE.search(text) and not _has_live_transaction(state):
|
||||
return PolicyDecision(
|
||||
route="end_session", intent="contas_conversation_close",
|
||||
reason="explicit_customer_closure",
|
||||
patch={**reset_patch, "terminal_status": "resolvido",
|
||||
"conversation_terminal_message": "Atendimento encerrado. Obrigado pelo contato."},
|
||||
)
|
||||
|
||||
# A short plural continuation after an invoice explanation belongs to that
|
||||
# explanation; it must not be mistaken for generic finalization merely because
|
||||
# it contains an affirmative such as "pode seguir". The invoice agent keeps
|
||||
|
||||
Reference in New Issue
Block a user