109 lines
3.5 KiB
Python
109 lines
3.5 KiB
Python
from __future__ import annotations
|
|
|
|
from typing import Any
|
|
|
|
from agent_framework.presentation import register_tool_response_renderer
|
|
|
|
|
|
def _money_brl(value: Any) -> str:
|
|
try:
|
|
return f"{float(value):.2f}".replace(".", ",")
|
|
except (TypeError, ValueError):
|
|
return str(value)
|
|
|
|
|
|
def render_contas_plan(
|
|
*, tool_name: str, result: dict[str, Any], state: dict[str, Any], agent_label: str
|
|
) -> str | None:
|
|
plans = result.get("plans")
|
|
if not isinstance(plans, list) or not plans:
|
|
return None
|
|
|
|
lines: list[str] = []
|
|
for plan in plans:
|
|
if not isinstance(plan, dict):
|
|
continue
|
|
name = plan.get("name")
|
|
if not name:
|
|
continue
|
|
value = plan.get("value")
|
|
line = f"- {name}"
|
|
if value is not None:
|
|
line += f": R$ {_money_brl(value)}"
|
|
lines.append(line)
|
|
|
|
if not lines:
|
|
return None
|
|
if len(lines) == 1:
|
|
return f"[{agent_label}] Seu plano é:\n{lines[0]}"
|
|
return f"[{agent_label}] Existem {len(lines)} planos associados à sua conta:\n" + "\n".join(lines)
|
|
|
|
|
|
|
|
def _service_value(service: dict[str, Any]) -> Any:
|
|
details = service.get("details") if isinstance(service.get("details"), dict) else {}
|
|
for candidate in (
|
|
details.get("valor"),
|
|
details.get("value"),
|
|
service.get("valor"),
|
|
service.get("value"),
|
|
service.get("price"),
|
|
):
|
|
if candidate not in (None, ""):
|
|
return candidate
|
|
return None
|
|
|
|
|
|
def _money_brl_preserve(value: Any) -> str:
|
|
if value is None:
|
|
return ""
|
|
text = str(value).strip()
|
|
if not text:
|
|
return ""
|
|
# TIM APIs may already return BRL decimal strings such as "10,00".
|
|
# Normalize only when needed and never invent a value.
|
|
if "," in text and "." not in text:
|
|
try:
|
|
return f"{float(text.replace(',', '.')):.2f}".replace(".", ",")
|
|
except ValueError:
|
|
return text
|
|
return _money_brl(value)
|
|
|
|
|
|
def render_contas_vas(
|
|
*, tool_name: str, result: dict[str, Any], state: dict[str, Any], agent_label: str
|
|
) -> str | None:
|
|
services = result.get("products") or result.get("services")
|
|
if not isinstance(services, list) or not services:
|
|
return None
|
|
|
|
lines: list[str] = []
|
|
for service in services:
|
|
if not isinstance(service, dict):
|
|
continue
|
|
name = service.get("name") or service.get("description") or service.get("billDescription")
|
|
if not name:
|
|
continue
|
|
|
|
details = service.get("details") if isinstance(service.get("details"), dict) else {}
|
|
can = service.get("can") if isinstance(service.get("can"), dict) else {}
|
|
details_can = details.get("can") if isinstance(details.get("can"), dict) else {}
|
|
cancelable = bool(can.get("cancel", details_can.get("cancel", False)))
|
|
category = service.get("classe") or details.get("classe") or ("avulso" if cancelable else None)
|
|
value = _service_value(service)
|
|
|
|
line = f"- {name}"
|
|
if category:
|
|
line += f" ({category})"
|
|
if value not in (None, ""):
|
|
line += f": R$ {_money_brl_preserve(value)}"
|
|
lines.append(line)
|
|
|
|
if not lines:
|
|
return None
|
|
return f"[{agent_label}] Você possui os seguintes serviços ativos:\n" + "\n".join(lines)
|
|
|
|
def register_tool_renderers() -> None:
|
|
register_tool_response_renderer("contas.plan", render_contas_plan)
|
|
register_tool_response_renderer("contas.vas", render_contas_vas)
|