mirror of
https://github.com/hoshikawa2/agent_platform_oci.git
synced 2026-09-07 10:13:46 +00:00
bugfixes: transaction parameter collector, generic formatting messages, guardrails, prompts. Testing contas
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
pyproject.toml
|
||||
src/agent_framework/__init__.py
|
||||
src/agent_framework/gateway_policy_context.py
|
||||
src/agent_framework/idempotency.py
|
||||
src/agent_framework/observer.py
|
||||
src/agent_framework/runtime_mcp_gateway_adapter.py
|
||||
src/agent_framework.egg-info/PKG-INFO
|
||||
@@ -28,6 +29,8 @@ src/agent_framework/channels/__init__.py
|
||||
src/agent_framework/channels/adapters.py
|
||||
src/agent_framework/channels/base.py
|
||||
src/agent_framework/channels/gateway.py
|
||||
src/agent_framework/channels/interruption.py
|
||||
src/agent_framework/channels/transcription.py
|
||||
src/agent_framework/checkpoints/__init__.py
|
||||
src/agent_framework/checkpoints/checkpoint_repository.py
|
||||
src/agent_framework/checkpoints/langgraph_saver.py
|
||||
@@ -73,9 +76,11 @@ src/agent_framework/guardrails/calibrated/pipeline.py
|
||||
src/agent_framework/guardrails/calibrated/prompts/__init__.py
|
||||
src/agent_framework/guardrails/calibrated/prompts/_context.py
|
||||
src/agent_framework/guardrails/calibrated/prompts/ausencia_oferta_proativa.py
|
||||
src/agent_framework/guardrails/calibrated/prompts/coerencia.py
|
||||
src/agent_framework/guardrails/calibrated/prompts/dlex_in.py
|
||||
src/agent_framework/guardrails/calibrated/prompts/dlex_out.py
|
||||
src/agent_framework/guardrails/calibrated/prompts/fallback.py
|
||||
src/agent_framework/guardrails/calibrated/prompts/fraseologia.py
|
||||
src/agent_framework/guardrails/calibrated/prompts/out_of_scope.py
|
||||
src/agent_framework/guardrails/calibrated/prompts/pinj.py
|
||||
src/agent_framework/guardrails/calibrated/prompts/ragsec.py
|
||||
@@ -174,6 +179,8 @@ src/agent_framework/persistence/__init__.py
|
||||
src/agent_framework/persistence/mongodb_store.py
|
||||
src/agent_framework/persistence/oracle_store.py
|
||||
src/agent_framework/persistence/sqlite_store.py
|
||||
src/agent_framework/presentation/__init__.py
|
||||
src/agent_framework/presentation/renderers.py
|
||||
src/agent_framework/rag/__init__.py
|
||||
src/agent_framework/rag/embedding_provider.py
|
||||
src/agent_framework/rag/graph_store.py
|
||||
@@ -200,6 +207,7 @@ src/agent_framework/supervisor/__init__.py
|
||||
src/agent_framework/supervisor/router_supervisor.py
|
||||
src/agent_framework/supervisor/supervisor.py
|
||||
src/agent_framework/workflows/__init__.py
|
||||
src/agent_framework/workflows/graph.py
|
||||
src/agent_framework/workflows/models.py
|
||||
src/agent_framework/workflows/registry.py
|
||||
src/agent_framework/workflows/repository.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.
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.
@@ -129,6 +129,8 @@ def _is_vas_section_name(section_name: str) -> bool:
|
||||
or "servicos de valor adicionado" in normalized
|
||||
or "servicos valor adicionado" in normalized
|
||||
or "sva detalhe total" in normalized
|
||||
or "servicos contratados de parceiros" in normalized
|
||||
or "servico contratado de parceiro" in normalized
|
||||
)
|
||||
|
||||
|
||||
@@ -185,13 +187,23 @@ def _extract_contestation_invoice_items(
|
||||
"validatedAmount",
|
||||
)
|
||||
if candidate_name and candidate_amount is not None and candidate_amount > 0:
|
||||
payload_type = str(payload.get("type") or payload.get("tipo") or "").strip()
|
||||
payload_desc = str(payload.get("desc") or "").strip()
|
||||
classe = str(payload.get("classe", "")).strip().lower()
|
||||
is_vas = (
|
||||
_is_vas_section_name(section_name)
|
||||
or _is_vas_section_name(payload_type)
|
||||
or classe in {"avulso", "estrategico"}
|
||||
)
|
||||
found.append(
|
||||
{
|
||||
"name": candidate_name,
|
||||
"amount": _money(candidate_amount),
|
||||
"is_vas": _is_vas_section_name(section_name),
|
||||
"is_vas": is_vas,
|
||||
"section": section_name,
|
||||
"classe": str(payload.get("classe", "")).strip().lower(),
|
||||
"source_type": payload_type,
|
||||
"source_desc": payload_desc,
|
||||
"classe": classe,
|
||||
"estrategico": bool(payload.get("estrategico")),
|
||||
"verb": str(payload.get("verb", "")).strip().lower(),
|
||||
}
|
||||
@@ -397,14 +409,25 @@ def validate_contestation_items(
|
||||
"vas_estrategico": False,
|
||||
"status": "em_validacao",
|
||||
}
|
||||
matched_candidate = next(
|
||||
(
|
||||
candidate
|
||||
for candidate in candidates
|
||||
if _is_same_plan_name(candidate.get("name", ""), item_name)
|
||||
),
|
||||
None,
|
||||
matching_candidates = [
|
||||
candidate
|
||||
for candidate in candidates
|
||||
if _is_same_plan_name(candidate.get("name", ""), item_name)
|
||||
]
|
||||
# A mesma cobrança pode aparecer em múltiplas visões da fatura.
|
||||
# Prefira a evidência que traz classificação explícita de VAS em vez
|
||||
# de aceitar a primeira ocorrência genérica e concluir incorretamente
|
||||
# que o item está fora da seção VAS.
|
||||
matching_candidates.sort(
|
||||
key=lambda candidate: (
|
||||
0 if (
|
||||
str(candidate.get("classe", "")).strip().lower() in {"avulso", "estrategico"}
|
||||
or bool(candidate.get("is_vas"))
|
||||
) else 1,
|
||||
0 if _normalize_match_text(candidate.get("name", "")) == _normalize_match_text(item_name) else 1,
|
||||
)
|
||||
)
|
||||
matched_candidate = matching_candidates[0] if matching_candidates else None
|
||||
if matched_candidate is None:
|
||||
_record_failure(
|
||||
item_log,
|
||||
@@ -414,6 +437,9 @@ def validate_contestation_items(
|
||||
continue
|
||||
item_log["item_na_fatura"] = True
|
||||
item_log["item_confirmado"] = True
|
||||
item_log["item_fatura_resolvido"] = str(matched_candidate.get("name", "") or "")
|
||||
item_log["secao_fatura"] = str(matched_candidate.get("section", "") or "")
|
||||
item_log["tipo_fatura"] = str(matched_candidate.get("source_type", "") or "")
|
||||
|
||||
classe = str(matched_candidate.get("classe", "")).strip().lower()
|
||||
is_strategic = (
|
||||
|
||||
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.
@@ -328,47 +328,6 @@ class ProactiveOfferRail(Guardrail):
|
||||
)
|
||||
|
||||
|
||||
def _sanitize_low_risk_phraseology(text: str, reason: str) -> str | None:
|
||||
"""Remove apenas fechamentos/redirecionamentos de baixo risco.
|
||||
|
||||
FRASEOLOGIA continua fail-closed para conteúdo material. Para B4 e ofertas
|
||||
genéricas de continuação, porém, bloquear toda uma resposta grounded piora a
|
||||
UX; nesses casos removemos somente a sentença ofensora.
|
||||
"""
|
||||
normalized_reason = (reason or "").casefold()
|
||||
low_risk = any(token in normalized_reason for token in (
|
||||
"viola b4", "outro canal", "atendimento especializado",
|
||||
"realizar alguma ação", "oferta de ação", "orienta o cliente",
|
||||
))
|
||||
if not low_risk:
|
||||
return None
|
||||
|
||||
forbidden = (
|
||||
"entre em contato", "fale com um atendente", "procure uma loja",
|
||||
"acesse o app", "acesse o site", "atendimento especializado",
|
||||
"área de planos", "area de planos", "é só me avisar",
|
||||
"e so me avisar", "realizar alguma ação", "realizar alguma acao",
|
||||
"gerenciar esses serviços", "gerenciar esses servicos",
|
||||
)
|
||||
sentences = re.split(r"(?<=[.!?])\s+", (text or "").strip())
|
||||
kept: list[str] = []
|
||||
removed = False
|
||||
for sentence in sentences:
|
||||
normalized = sentence.casefold()
|
||||
proactive = (
|
||||
("se quiser" in normalized or "caso queira" in normalized or "se desejar" in normalized)
|
||||
and any(token in normalized for token in ("realizar", "gerenciar", "cancelar", "contratar", "alterar", "ação", "acao"))
|
||||
)
|
||||
if proactive or any(token in normalized for token in forbidden):
|
||||
removed = True
|
||||
continue
|
||||
kept.append(sentence.strip())
|
||||
sanitized = " ".join(x for x in kept if x).strip()
|
||||
if removed and sanitized:
|
||||
return sanitized
|
||||
return None
|
||||
|
||||
|
||||
class PhraseologyRail(Guardrail):
|
||||
"""FRASEOLOGIA calibrado: bloqueia fraseados proibidos do agente."""
|
||||
code = "FRASEOLOGIA"
|
||||
@@ -380,26 +339,9 @@ class PhraseologyRail(Guardrail):
|
||||
_llm(ctx), "FRASEOLOGIA", {"text": text or "", "context": ctx},
|
||||
profile_name="grl", component_name="guardrail.fraseologia", generation_name="guardrail.fraseologia",
|
||||
)
|
||||
allowed = bool(out.get("allowed", True))
|
||||
reason = str(out.get("reason") or out.get("label") or "FRASEOLOGIA avaliado")
|
||||
if not allowed:
|
||||
sanitized = _sanitize_low_risk_phraseology(text or "", reason)
|
||||
if sanitized:
|
||||
return RailDecision(
|
||||
code=self.code,
|
||||
allowed=True,
|
||||
reason=f"FRASEOLOGIA sanitizada: {reason}",
|
||||
sanitized_text=sanitized,
|
||||
metadata={
|
||||
"mechanism": "llm_rail+deterministic_sanitize",
|
||||
"data": out,
|
||||
"calibrated": True,
|
||||
"original_allowed": False,
|
||||
},
|
||||
)
|
||||
return RailDecision(
|
||||
code=self.code, allowed=allowed,
|
||||
reason=reason,
|
||||
code=self.code, allowed=bool(out.get("allowed", True)),
|
||||
reason=str(out.get("reason") or out.get("label") or "FRASEOLOGIA avaliado"),
|
||||
sanitized_text=text, metadata={"mechanism": "llm_rail", "data": out, "calibrated": True},
|
||||
)
|
||||
|
||||
|
||||
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.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user