From 81f24d7357627840e95827b53ae115a42305bccd Mon Sep 17 00:00:00 2001 From: "cristiano.hoshikawa" Date: Sat, 29 Aug 2026 10:03:42 -0300 Subject: [PATCH] Ajustes conforme relatorio de testes 2026-08-27 --- README.md | 11 +- README_en.md | 10 +- .../__pycache__/agent_graph.cpython-313.pyc | Bin 54261 -> 56262 bytes .../app/workflows/agent_graph.py | 52 +- .../config/routing.yaml | 29 + .../docs/TRANSACTION_SEMANTIC_CONFIRMATION.md | 11 + .../app/agents/billing_agent.py | 2 +- .../app/agents/orders_agent.py | 2 +- .../app/agents/product_agent.py | 2 +- .../app/agents/support_agent.py | 2 +- .../tool_renderers.cpython-313.pyc | Bin 6035 -> 4412 bytes .../app/presentation/tool_renderers.py | 37 +- .../__pycache__/agent_graph.cpython-313.pyc | Bin 60618 -> 56269 bytes .../app/workflows/agent_graph.py | 173 ++-- .../config/routing.yaml | 29 + .../docs/TRANSACTION_SEMANTIC_CONFIRMATION.md | 11 + .../app/agents/billing_agent.py | 2 +- .../app/agents/orders_agent.py | 2 +- .../app/agents/product_agent.py | 2 +- .../app/agents/support_agent.py | 2 +- .../app/presentation/tool_renderers.py | 37 +- .../__pycache__/agent_graph.cpython-313.pyc | Bin 56846 -> 52494 bytes .../app/workflows/agent_graph.py | 173 ++-- .../config/routing.yaml | 29 + .../docs/TRANSACTION_SEMANTIC_CONFIRMATION.md | 11 + .../app/__pycache__/__init__.cpython-313.pyc | Bin 220 -> 185 bytes .../app/__pycache__/main.cpython-313.pyc | Bin 32372 -> 32264 bytes ...mcp_gateway_client_factory.cpython-313.pyc | Bin 1068 -> 993 bytes .../app/__pycache__/state.cpython-313.pyc | Bin 2707 -> 2493 bytes .../__pycache__/billing_agent.cpython-313.pyc | Bin 6312 -> 5256 bytes .../__pycache__/orders_agent.cpython-313.pyc | Bin 5965 -> 5164 bytes .../__pycache__/product_agent.cpython-313.pyc | Bin 6309 -> 5280 bytes .../__pycache__/prompting.cpython-313.pyc | Bin 1217 -> 1182 bytes .../__pycache__/runtime.cpython-313.pyc | Bin 504 -> 384 bytes .../__pycache__/support_agent.cpython-313.pyc | Bin 6020 -> 5176 bytes .../app/agents/billing_agent.py | 2 +- .../app/agents/orders_agent.py | 2 +- .../app/agents/product_agent.py | 2 +- .../app/agents/support_agent.py | 2 +- .../__pycache__/__init__.cpython-313.pyc | Bin 291 -> 216 bytes .../__pycache__/grl_examples.cpython-313.pyc | Bin 1873 -> 1798 bytes .../__pycache__/ic_examples.cpython-313.pyc | Bin 1829 -> 1754 bytes .../__pycache__/mcp_examples.cpython-313.pyc | Bin 1971 -> 1896 bytes .../__pycache__/noc_examples.cpython-313.pyc | Bin 1918 -> 1843 bytes .../observer_examples.cpython-313.pyc | Bin 1427 -> 1352 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 234 -> 199 bytes .../telemetry_observer.cpython-313.pyc | Bin 4845 -> 4810 bytes .../tool_renderers.cpython-313.pyc | Bin 6025 -> 4402 bytes .../app/presentation/tool_renderers.py | 37 +- .../__pycache__/agent_graph.cpython-313.pyc | Bin 60608 -> 56259 bytes .../app/workflows/agent_graph.py | 173 ++-- .../config/routing.yaml | 29 + .../docs/TRANSACTION_SEMANTIC_CONFIRMATION.md | 11 + .../app/agents/billing_agent.py | 2 +- .../app/agents/orders_agent.py | 2 +- .../app/agents/product_agent.py | 2 +- .../app/agents/support_agent.py | 2 +- .../tool_renderers.cpython-313.pyc | Bin 6015 -> 4392 bytes .../app/presentation/tool_renderers.py | 37 +- .../__pycache__/agent_graph.cpython-313.pyc | Bin 56836 -> 52484 bytes .../app/workflows/agent_graph.py | 173 ++-- .../config/routing.yaml | 29 + .../docs/TRANSACTION_SEMANTIC_CONFIRMATION.md | 11 + .../app/agents/billing_agent.py | 2 +- .../app/agents/orders_agent.py | 2 +- .../app/agents/product_agent.py | 2 +- .../app/agents/support_agent.py | 2 +- .../__pycache__/agent_graph.cpython-313.pyc | Bin 56845 -> 52493 bytes .../app/workflows/agent_graph.py | 173 ++-- .../config/routing.yaml | 29 + .../docs/TRANSACTION_SEMANTIC_CONFIRMATION.md | 11 + .../IMPLEMENTACAO_PAUSE_RESUME_LANGGRAPH.md | 43 + .../Pause_Resume_Workflow/README.md | 46 + .../agent_template_backend/README.md | 26 + .../agent_template_backend/app/__init__.py | 0 .../app/__pycache__/__init__.cpython-313.pyc | Bin 0 -> 219 bytes .../app/__pycache__/demo.cpython-313.pyc | Bin 0 -> 3090 bytes .../agent_template_backend/app/demo.py | 56 ++ .../docs/TRANSACTION_SEMANTIC_CONFIRMATION.md | 11 + ..._pause_resume.cpython-313-pytest-9.0.2.pyc | Bin 0 -> 7783 bytes .../tests/test_pause_resume.py | 35 + .../workflows/confirmacao.active.yaml | 1 + .../workflows/confirmacao.v1.yaml | 45 + .../app/__pycache__/__init__.cpython-313.pyc | Bin 0 -> 232 bytes .../app/__pycache__/demo.cpython-313.pyc | Bin 0 -> 3103 bytes .../docs/TRANSACTION_SEMANTIC_CONFIRMATION.md | 11 + ..._pause_resume.cpython-313-pytest-9.0.2.pyc | Bin 0 -> 7796 bytes .../tests/test_pause_resume.py | 13 + .../workflows/confirmacao.v1.yaml | 13 + .../app/agents/billing_agent.py | 2 +- .../app/agents/orders_agent.py | 2 +- .../app/agents/product_agent.py | 2 +- .../app/agents/support_agent.py | 2 +- .../tool_renderers.cpython-313.pyc | Bin 6024 -> 4401 bytes .../app/presentation/tool_renderers.py | 37 +- .../__pycache__/agent_graph.cpython-313.pyc | Bin 56845 -> 52493 bytes .../app/workflows/agent_graph.py | 173 ++-- .../config/routing.yaml | 29 + .../docs/TRANSACTION_SEMANTIC_CONFIRMATION.md | 11 + .../app/agents/billing_agent.py | 2 +- .../app/agents/orders_agent.py | 2 +- .../app/agents/product_agent.py | 2 +- .../app/agents/support_agent.py | 2 +- .../__pycache__/agent_graph.cpython-313.pyc | Bin 56854 -> 52502 bytes .../app/workflows/agent_graph.py | 173 ++-- .../config/routing.yaml | 29 + .../docs/TRANSACTION_SEMANTIC_CONFIRMATION.md | 11 + .../app/agents/billing_agent.py | 2 +- .../app/agents/orders_agent.py | 2 +- .../app/agents/product_agent.py | 2 +- .../app/agents/support_agent.py | 2 +- .../app/presentation/tool_renderers.py | 37 +- .../__pycache__/agent_graph.cpython-313.pyc | Bin 60987 -> 56639 bytes .../app/workflows/agent_graph.py | 173 ++-- .../config/routing.yaml | 29 + .../docs/TRANSACTION_SEMANTIC_CONFIRMATION.md | 11 + .../app/agents/billing_agent.py | 2 +- .../app/agents/orders_agent.py | 2 +- .../app/agents/product_agent.py | 2 +- .../app/agents/support_agent.py | 2 +- .../app/presentation/tool_renderers.py | 37 +- .../__pycache__/agent_graph.cpython-313.pyc | Bin 60993 -> 56645 bytes .../app/workflows/agent_graph.py | 173 ++-- .../config/routing.yaml | 29 + .../docs/TRANSACTION_SEMANTIC_CONFIRMATION.md | 11 + ...KFLOW_HUMAN_HANDOFF_PRECEDENCE_20260829.md | 49 ++ ...X_POST_FINALIZATION_SOFT_RESET_20260829.md | 15 + ...LOW_FINAL_STATUS_NORMALIZATION_20260829.md | 7 + ...ERMINAL_LIFECYCLE_SAME_SESSION_20260829.md | 25 + ...OW_TERMINAL_SNAPSHOT_SEMANTICS_20260829.md | 31 + .../en/03_transaction_workflows_and_state.md | 79 ++ ...rails_judges_and_transaction_evaluation.md | 63 ++ ...ut_guardrail_feedback_and_blocked_turns.md | 157 ++++ docs/developer/en/INDEX_DEVELOPER_GUIDE.md | 12 +- .../pt/03_transaction_workflows_and_state.md | 133 +++ ...rails_judges_and_transaction_evaluation.md | 63 ++ ...ut_guardrail_feedback_and_blocked_turns.md | 157 ++++ docs/developer/pt/INDEX_DEVELOPER_GUIDE.md | 11 +- .../__pycache__/__init__.cpython-313.pyc | Bin 0 -> 379 bytes .../__pycache__/extensions.cpython-313.pyc | Bin 0 -> 2107 bytes .../gateway_policy_context.cpython-313.pyc | Bin 0 -> 1459 bytes .../__pycache__/idempotency.cpython-313.pyc | Bin 0 -> 5663 bytes .../__pycache__/observer.cpython-313.pyc | Bin 0 -> 17523 bytes ...untime_mcp_gateway_adapter.cpython-313.pyc | Bin 0 -> 2156 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 0 -> 515 bytes .../composite_publisher.cpython-313.pyc | Bin 0 -> 2470 bytes .../__pycache__/event_builder.cpython-313.pyc | Bin 0 -> 1228 bytes .../__pycache__/factory.cpython-313.pyc | Bin 0 -> 3964 bytes .../__pycache__/publisher.cpython-313.pyc | Bin 0 -> 1840 bytes .../tim_payload_mapper.cpython-313.pyc | Bin 0 -> 9254 bytes .../__pycache__/tim_sequence.cpython-313.pyc | Bin 0 -> 17529 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 0 -> 482 bytes .../__pycache__/kafka.cpython-313.pyc | Bin 0 -> 1780 bytes .../__pycache__/langfuse.cpython-313.pyc | Bin 0 -> 23140 bytes .../__pycache__/oci_streaming.cpython-313.pyc | Bin 0 -> 1789 bytes .../__pycache__/pubsub.cpython-313.pyc | Bin 0 -> 7408 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 0 -> 371 bytes .../usage_repository.cpython-313.pyc | Bin 0 -> 15654 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 0 -> 181 bytes .../cache/__pycache__/cache.cpython-313.pyc | Bin 0 -> 16491 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 0 -> 184 bytes .../__pycache__/adapters.cpython-313.pyc | Bin 0 -> 4140 bytes .../channels/__pycache__/base.cpython-313.pyc | Bin 0 -> 1764 bytes .../__pycache__/gateway.cpython-313.pyc | Bin 0 -> 5739 bytes .../__pycache__/interruption.cpython-313.pyc | Bin 0 -> 6424 bytes .../__pycache__/transcription.cpython-313.pyc | Bin 0 -> 1397 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 0 -> 891 bytes .../checkpoint_repository.cpython-313.pyc | Bin 0 -> 27131 bytes .../langgraph_saver.cpython-313.pyc | Bin 0 -> 23513 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 0 -> 182 bytes .../agent_registry.cpython-313.pyc | Bin 0 -> 6915 bytes .../__pycache__/settings.cpython-313.pyc | Bin 0 -> 12743 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 0 -> 182 bytes .../__pycache__/oci_streaming.cpython-313.pyc | Bin 0 -> 3286 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 0 -> 274 bytes .../mcp_gateway_client.cpython-313.pyc | Bin 0 -> 3300 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 0 -> 688 bytes .../__pycache__/client.cpython-313.pyc | Bin 0 -> 4578 bytes .../__pycache__/config.cpython-313.pyc | Bin 0 -> 5013 bytes .../__pycache__/models.cpython-313.pyc | Bin 0 -> 4506 bytes .../__pycache__/router.cpython-313.pyc | Bin 0 -> 14787 bytes .../__pycache__/session_store.cpython-313.pyc | Bin 0 -> 3497 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 0 -> 1469 bytes .../__pycache__/base.cpython-313.pyc | Bin 0 -> 1343 bytes .../__pycache__/config_loader.cpython-313.pyc | Bin 0 -> 9128 bytes .../__pycache__/custom_rails.cpython-313.pyc | Bin 0 -> 4372 bytes .../__pycache__/executor.cpython-313.pyc | Bin 0 -> 321 bytes .../framework_llm_client.cpython-313.pyc | Bin 0 -> 18051 bytes .../langgraph_adapters.cpython-313.pyc | Bin 0 -> 3789 bytes .../__pycache__/llm_rails.cpython-313.pyc | Bin 0 -> 6610 bytes .../output_supervisor.cpython-313.pyc | Bin 0 -> 24274 bytes .../parallel_executor.cpython-313.pyc | Bin 0 -> 21830 bytes .../__pycache__/pipeline.cpython-313.pyc | Bin 0 -> 10857 bytes .../__pycache__/rail_action.cpython-313.pyc | Bin 0 -> 622 bytes .../__pycache__/rail_decision.cpython-313.pyc | Bin 0 -> 1573 bytes .../__pycache__/rail_result.cpython-313.pyc | Bin 0 -> 972 bytes .../__pycache__/rails.cpython-313.pyc | Bin 0 -> 35846 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 0 -> 2962 bytes .../__pycache__/_compat.cpython-313.pyc | Bin 0 -> 2413 bytes .../__pycache__/config.cpython-313.pyc | Bin 0 -> 7635 bytes .../contestation_validation.cpython-313.pyc | Bin 0 -> 1016 bytes .../__pycache__/contracts.cpython-313.pyc | Bin 0 -> 6869 bytes .../__pycache__/input_size.cpython-313.pyc | Bin 0 -> 3617 bytes .../__pycache__/llm_adapter.cpython-313.pyc | Bin 0 -> 3767 bytes .../__pycache__/llm_client.cpython-313.pyc | Bin 0 -> 7306 bytes .../__pycache__/llm_rails.cpython-313.pyc | Bin 0 -> 8862 bytes .../output_sanitization.cpython-313.pyc | Bin 0 -> 13878 bytes .../__pycache__/pipeline.cpython-313.pyc | Bin 0 -> 12629 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 0 -> 441 bytes .../__pycache__/_context.cpython-313.pyc | Bin 0 -> 5839 bytes .../ausencia_oferta_proativa.cpython-313.pyc | Bin 0 -> 9847 bytes .../__pycache__/coerencia.cpython-313.pyc | Bin 0 -> 9453 bytes .../__pycache__/dlex_in.cpython-313.pyc | Bin 0 -> 1272 bytes .../__pycache__/dlex_out.cpython-313.pyc | Bin 0 -> 1559 bytes .../__pycache__/fallback.cpython-313.pyc | Bin 0 -> 17620 bytes .../__pycache__/fraseologia.cpython-313.pyc | Bin 0 -> 7601 bytes .../__pycache__/out_of_scope.cpython-313.pyc | Bin 0 -> 17461 bytes .../prompts/__pycache__/pinj.cpython-313.pyc | Bin 0 -> 8392 bytes .../__pycache__/ragsec.cpython-313.pyc | Bin 0 -> 1088 bytes .../__pycache__/revprec.cpython-313.pyc | Bin 0 -> 5379 bytes .../__pycache__/safe_out.cpython-313.pyc | Bin 0 -> 1010 bytes .../prompts/__pycache__/tox.cpython-313.pyc | Bin 0 -> 612 bytes .../toxicidade_output.cpython-313.pyc | Bin 0 -> 896 bytes .../guardrails/calibrated/prompts/dlex_out.py | 1 + .../__pycache__/__init__.cpython-313.pyc | Bin 0 -> 612 bytes .../supervision_template.cpython-313.pyc | Bin 0 -> 2196 bytes .../__pycache__/tts_rules.cpython-313.pyc | Bin 0 -> 1146 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 0 -> 1631 bytes .../rails/__pycache__/alcada.cpython-313.pyc | Bin 0 -> 4967 bytes .../rails/__pycache__/anatel.cpython-313.pyc | Bin 0 -> 9116 bytes .../__pycache__/confirmation.cpython-313.pyc | Bin 0 -> 10987 bytes .../rails/__pycache__/dlex_in.cpython-313.pyc | Bin 0 -> 3247 bytes .../__pycache__/dlex_out.cpython-313.pyc | Bin 0 -> 3299 bytes .../rails/__pycache__/ragsec.cpython-313.pyc | Bin 0 -> 5381 bytes .../rails/__pycache__/revprec.cpython-313.pyc | Bin 0 -> 5389 bytes .../rails/__pycache__/tox.cpython-313.pyc | Bin 0 -> 8212 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 0 -> 5731 bytes .../correspondencia_item.cpython-313.pyc | Bin 0 -> 9178 bytes .../__pycache__/groundedness.cpython-313.pyc | Bin 0 -> 8611 bytes .../intencao_cancelar.cpython-313.pyc | Bin 0 -> 9328 bytes .../quantidade_coerente.cpython-313.pyc | Bin 0 -> 9198 bytes .../servico_correto.cpython-313.pyc | Bin 0 -> 8999 bytes .../verbalizacao_prematura.cpython-313.pyc | Bin 0 -> 8547 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 0 -> 501 bytes .../rules/__pycache__/alcada.cpython-313.pyc | Bin 0 -> 1849 bytes .../__pycache__/oos_blocklist.cpython-313.pyc | Bin 0 -> 3028 bytes .../__pycache__/pinj_patterns.cpython-313.pyc | Bin 0 -> 3698 bytes .../__pycache__/tox_blocklist.cpython-313.pyc | Bin 0 -> 1474 bytes .../lib/agent_framework/guardrails/rails.py | 225 ++++- .../__pycache__/__init__.cpython-313.pyc | Bin 0 -> 376 bytes .../__pycache__/mcp_mapper.cpython-313.pyc | Bin 0 -> 4660 bytes .../__pycache__/models.cpython-313.pyc | Bin 0 -> 3112 bytes .../__pycache__/resolver.cpython-313.pyc | Bin 0 -> 4681 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 0 -> 586 bytes .../judges/__pycache__/judge.cpython-313.pyc | Bin 0 -> 38252 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 0 -> 193 bytes .../__pycache__/_compat.cpython-313.pyc | Bin 0 -> 2233 bytes .../__pycache__/llm_client.cpython-313.pyc | Bin 0 -> 6070 bytes .../__pycache__/models.cpython-313.pyc | Bin 0 -> 906 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 0 -> 201 bytes .../prompts/__pycache__/aluc.cpython-313.pyc | Bin 0 -> 6497 bytes .../prompts/__pycache__/csi.cpython-313.pyc | Bin 0 -> 1300 bytes .../__pycache__/fallback.cpython-313.pyc | Bin 0 -> 8003 bytes .../prompts/__pycache__/rqlt.cpython-313.pyc | Bin 0 -> 1133 bytes .../prompts/__pycache__/vctn.cpython-313.pyc | Bin 0 -> 594 bytes .../llm/__pycache__/__init__.cpython-313.pyc | Bin 0 -> 301 bytes .../llm/__pycache__/base.cpython-313.pyc | Bin 0 -> 1591 bytes .../profile_resolver.cpython-313.pyc | Bin 0 -> 9247 bytes .../llm/__pycache__/providers.cpython-313.pyc | Bin 0 -> 41678 bytes .../llm/__pycache__/types.cpython-313.pyc | Bin 0 -> 1242 bytes .../mcp/__pycache__/__init__.cpython-313.pyc | Bin 0 -> 441 bytes .../mcp/__pycache__/client.cpython-313.pyc | Bin 0 -> 18394 bytes .../mcp/__pycache__/models.cpython-313.pyc | Bin 0 -> 2104 bytes .../mcp/__pycache__/registry.cpython-313.pyc | Bin 0 -> 4708 bytes .../__pycache__/tool_policy.cpython-313.pyc | Bin 0 -> 5653 bytes .../__pycache__/tool_router.cpython-313.pyc | Bin 0 -> 14157 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 0 -> 1103 bytes .../long_term_extractor.cpython-313.pyc | Bin 0 -> 2481 bytes .../long_term_memory.cpython-313.pyc | Bin 0 -> 6807 bytes .../long_term_models.cpython-313.pyc | Bin 0 -> 1716 bytes .../long_term_store.cpython-313.pyc | Bin 0 -> 29154 bytes .../message_history.cpython-313.pyc | Bin 0 -> 8327 bytes .../summary_memory.cpython-313.pyc | Bin 0 -> 12478 bytes .../__pycache__/summary_store.cpython-313.pyc | Bin 0 -> 9488 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 0 -> 182 bytes .../__pycache__/identity.cpython-313.pyc | Bin 0 -> 3433 bytes .../__pycache__/session.cpython-313.pyc | Bin 0 -> 2676 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 0 -> 1362 bytes .../__pycache__/code_mapper.cpython-313.pyc | Bin 0 -> 18540 bytes .../__pycache__/context.cpython-313.pyc | Bin 0 -> 7354 bytes .../control_events.cpython-313.pyc | Bin 0 -> 2042 bytes .../__pycache__/decorators.cpython-313.pyc | Bin 0 -> 1753 bytes .../__pycache__/event_bus.cpython-313.pyc | Bin 0 -> 3600 bytes .../__pycache__/grl_events.cpython-313.pyc | Bin 0 -> 914 bytes .../guardrail_events.cpython-313.pyc | Bin 0 -> 2018 bytes .../__pycache__/ic_events.cpython-313.pyc | Bin 0 -> 593 bytes .../informational_events.cpython-313.pyc | Bin 0 -> 433 bytes .../__pycache__/judge_events.cpython-313.pyc | Bin 0 -> 1378 bytes .../langfuse_enterprise.cpython-313.pyc | Bin 0 -> 3742 bytes .../langgraph_telemetry.cpython-313.pyc | Bin 0 -> 4931 bytes .../__pycache__/llm_advisors.cpython-313.pyc | Bin 0 -> 2905 bytes .../__pycache__/noc_contract.cpython-313.pyc | Bin 0 -> 5042 bytes .../__pycache__/noc_events.cpython-313.pyc | Bin 0 -> 574 bytes .../__pycache__/noc_otel.cpython-313.pyc | Bin 0 -> 6289 bytes .../__pycache__/observer.cpython-313.pyc | Bin 0 -> 5072 bytes .../__pycache__/otel.cpython-313.pyc | Bin 0 -> 3379 bytes .../streaming_events.cpython-313.pyc | Bin 0 -> 1802 bytes .../streaming_exporter.cpython-313.pyc | Bin 0 -> 1321 bytes .../__pycache__/telemetry.cpython-313.pyc | Bin 0 -> 52395 bytes .../tim_backoffice_contract.cpython-313.pyc | Bin 0 -> 1762 bytes .../__pycache__/token_cost.cpython-313.pyc | Bin 0 -> 8658 bytes .../workflow_events.cpython-313.pyc | Bin 0 -> 3297 bytes .../oci/__pycache__/__init__.cpython-313.pyc | Bin 0 -> 179 bytes .../oci/__pycache__/auth.cpython-313.pyc | Bin 0 -> 3211 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 0 -> 187 bytes .../__pycache__/mongodb_store.cpython-313.pyc | Bin 0 -> 7647 bytes .../__pycache__/oracle_store.cpython-313.pyc | Bin 0 -> 44923 bytes .../__pycache__/sqlite_store.cpython-313.pyc | Bin 0 -> 14986 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 0 -> 422 bytes .../__pycache__/renderers.cpython-313.pyc | Bin 0 -> 4285 bytes .../rag/__pycache__/__init__.cpython-313.pyc | Bin 0 -> 677 bytes .../embedding_provider.cpython-313.pyc | Bin 0 -> 6484 bytes .../__pycache__/graph_store.cpython-313.pyc | Bin 0 -> 5495 bytes .../rag/__pycache__/ingest.cpython-313.pyc | Bin 0 -> 12548 bytes .../__pycache__/rag_service.cpython-313.pyc | Bin 0 -> 10017 bytes .../__pycache__/vector_store.cpython-313.pyc | Bin 0 -> 18623 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 0 -> 188 bytes .../session_repository.cpython-313.pyc | Bin 0 -> 8557 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 0 -> 393 bytes .../__pycache__/config_loader.cpython-313.pyc | Bin 0 -> 2264 bytes .../__pycache__/continuity.cpython-313.pyc | Bin 0 -> 13206 bytes .../enterprise_router.cpython-313.pyc | Bin 0 -> 42902 bytes .../__pycache__/models.cpython-313.pyc | Bin 0 -> 2414 bytes .../routing/enterprise_router.py | 678 ++++++++++++-- .../__pycache__/__init__.cpython-313.pyc | Bin 0 -> 316 bytes .../__pycache__/agent_runtime.cpython-313.pyc | Bin 0 -> 163433 bytes .../transaction_input.cpython-313.pyc | Bin 0 -> 2897 bytes .../transaction_parameters.cpython-313.pyc | Bin 0 -> 10039 bytes .../agent_framework/runtime/agent_runtime.py | 832 ++++++++++++++++-- .../runtime/transaction_parameters.py | 24 +- .../__pycache__/__init__.cpython-313.pyc | Bin 0 -> 1174 bytes .../authentication.cpython-313.pyc | Bin 0 -> 15394 bytes .../__pycache__/factory.cpython-313.pyc | Bin 0 -> 7963 bytes .../__pycache__/installer.cpython-313.pyc | Bin 0 -> 5581 bytes .../__pycache__/middleware.cpython-313.pyc | Bin 0 -> 8865 bytes .../sse/__pycache__/__init__.cpython-313.pyc | Bin 0 -> 179 bytes .../sse/__pycache__/events.cpython-313.pyc | Bin 0 -> 9555 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 0 -> 186 bytes .../router_supervisor.cpython-313.pyc | Bin 0 -> 379 bytes .../__pycache__/supervisor.cpython-313.pyc | Bin 0 -> 4911 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 0 -> 846 bytes .../__pycache__/graph.cpython-313.pyc | Bin 0 -> 1383 bytes .../input_contract.cpython-313.pyc | Bin 0 -> 8758 bytes .../__pycache__/models.cpython-313.pyc | Bin 0 -> 6738 bytes .../__pycache__/registry.cpython-313.pyc | Bin 0 -> 2329 bytes .../__pycache__/repository.cpython-313.pyc | Bin 0 -> 2682 bytes .../__pycache__/runtime.cpython-313.pyc | Bin 0 -> 32948 bytes .../__pycache__/tool_executor.cpython-313.pyc | Bin 0 -> 1934 bytes .../workflows/input_contract.py | 151 ++++ .../lib/agent_framework/workflows/models.py | 43 + .../lib/agent_framework/workflows/runtime.py | 96 +- .../__pycache__/__init__.cpython-313.pyc | Bin 411 -> 411 bytes .../__pycache__/extensions.cpython-313.pyc | Bin 2139 -> 2139 bytes .../gateway_policy_context.cpython-313.pyc | Bin 1433 -> 1453 bytes .../__pycache__/idempotency.cpython-313.pyc | Bin 5695 -> 5695 bytes .../__pycache__/observer.cpython-313.pyc | Bin 17555 -> 17555 bytes ...untime_mcp_gateway_adapter.cpython-313.pyc | Bin 2130 -> 2150 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 547 -> 547 bytes .../composite_publisher.cpython-313.pyc | Bin 2502 -> 2502 bytes .../__pycache__/event_builder.cpython-313.pyc | Bin 1260 -> 1260 bytes .../__pycache__/factory.cpython-313.pyc | Bin 3996 -> 3996 bytes .../__pycache__/publisher.cpython-313.pyc | Bin 1872 -> 1872 bytes .../tim_payload_mapper.cpython-313.pyc | Bin 9286 -> 9286 bytes .../__pycache__/tim_sequence.cpython-313.pyc | Bin 17561 -> 17561 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 514 -> 514 bytes .../__pycache__/kafka.cpython-313.pyc | Bin 1812 -> 1812 bytes .../__pycache__/langfuse.cpython-313.pyc | Bin 23172 -> 23172 bytes .../__pycache__/oci_streaming.cpython-313.pyc | Bin 1821 -> 1821 bytes .../__pycache__/pubsub.cpython-313.pyc | Bin 7440 -> 7440 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 403 -> 403 bytes .../usage_repository.cpython-313.pyc | Bin 15686 -> 15686 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 213 -> 213 bytes .../cache/__pycache__/cache.cpython-313.pyc | Bin 16523 -> 16523 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 216 -> 216 bytes .../__pycache__/adapters.cpython-313.pyc | Bin 4172 -> 4172 bytes .../channels/__pycache__/base.cpython-313.pyc | Bin 1796 -> 1796 bytes .../__pycache__/gateway.cpython-313.pyc | Bin 5771 -> 5771 bytes .../__pycache__/interruption.cpython-313.pyc | Bin 6456 -> 6456 bytes .../__pycache__/transcription.cpython-313.pyc | Bin 1429 -> 1429 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 923 -> 923 bytes .../checkpoint_repository.cpython-313.pyc | Bin 27163 -> 27163 bytes .../langgraph_saver.cpython-313.pyc | Bin 32222 -> 32222 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 214 -> 214 bytes .../agent_registry.cpython-313.pyc | Bin 6947 -> 6947 bytes .../__pycache__/settings.cpython-313.pyc | Bin 13789 -> 13789 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 156 -> 176 bytes .../__pycache__/oci_streaming.cpython-313.pyc | Bin 3260 -> 3280 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 306 -> 306 bytes .../mcp_gateway_client.cpython-313.pyc | Bin 3332 -> 3332 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 662 -> 682 bytes .../__pycache__/client.cpython-313.pyc | Bin 4552 -> 4572 bytes .../__pycache__/config.cpython-313.pyc | Bin 4987 -> 5007 bytes .../__pycache__/models.cpython-313.pyc | Bin 4480 -> 4500 bytes .../__pycache__/router.cpython-313.pyc | Bin 14761 -> 14147 bytes .../__pycache__/session_store.cpython-313.pyc | Bin 3471 -> 3491 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 1501 -> 1501 bytes .../__pycache__/base.cpython-313.pyc | Bin 1375 -> 1375 bytes .../__pycache__/config_loader.cpython-313.pyc | Bin 9160 -> 9160 bytes .../__pycache__/custom_rails.cpython-313.pyc | Bin 4404 -> 4404 bytes .../__pycache__/executor.cpython-313.pyc | Bin 295 -> 315 bytes .../framework_llm_client.cpython-313.pyc | Bin 17783 -> 17783 bytes .../langgraph_adapters.cpython-313.pyc | Bin 3763 -> 3783 bytes .../__pycache__/llm_rails.cpython-313.pyc | Bin 5923 -> 5923 bytes .../output_supervisor.cpython-313.pyc | Bin 24306 -> 24306 bytes .../parallel_executor.cpython-313.pyc | Bin 21862 -> 21862 bytes .../__pycache__/pipeline.cpython-313.pyc | Bin 10889 -> 10889 bytes .../__pycache__/rail_action.cpython-313.pyc | Bin 654 -> 654 bytes .../__pycache__/rail_decision.cpython-313.pyc | Bin 1605 -> 1605 bytes .../__pycache__/rail_result.cpython-313.pyc | Bin 1004 -> 1004 bytes .../__pycache__/rails.cpython-313.pyc | Bin 34444 -> 41639 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 2994 -> 2994 bytes .../__pycache__/_compat.cpython-313.pyc | Bin 2445 -> 2445 bytes .../__pycache__/config.cpython-313.pyc | Bin 7579 -> 7629 bytes .../contestation_validation.cpython-313.pyc | Bin 2177 -> 2177 bytes .../__pycache__/contracts.cpython-313.pyc | Bin 6901 -> 6901 bytes .../__pycache__/input_size.cpython-313.pyc | Bin 3649 -> 3649 bytes .../__pycache__/llm_adapter.cpython-313.pyc | Bin 3799 -> 3799 bytes .../__pycache__/llm_client.cpython-313.pyc | Bin 7338 -> 7338 bytes .../__pycache__/llm_rails.cpython-313.pyc | Bin 8894 -> 8894 bytes .../output_sanitization.cpython-313.pyc | Bin 13910 -> 13910 bytes .../__pycache__/pipeline.cpython-313.pyc | Bin 12661 -> 12661 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 473 -> 473 bytes .../__pycache__/_context.cpython-313.pyc | Bin 5871 -> 5871 bytes .../ausencia_oferta_proativa.cpython-313.pyc | Bin 11265 -> 11265 bytes .../__pycache__/coerencia.cpython-313.pyc | Bin 9485 -> 9485 bytes .../__pycache__/dlex_in.cpython-313.pyc | Bin 1304 -> 1304 bytes .../__pycache__/dlex_out.cpython-313.pyc | Bin 1591 -> 1815 bytes .../__pycache__/fallback.cpython-313.pyc | Bin 17652 -> 17652 bytes .../__pycache__/fraseologia.cpython-313.pyc | Bin 7633 -> 7633 bytes .../__pycache__/out_of_scope.cpython-313.pyc | Bin 17493 -> 17493 bytes .../prompts/__pycache__/pinj.cpython-313.pyc | Bin 8424 -> 8424 bytes .../__pycache__/ragsec.cpython-313.pyc | Bin 1120 -> 1120 bytes .../__pycache__/revprec.cpython-313.pyc | Bin 5411 -> 5411 bytes .../__pycache__/safe_out.cpython-313.pyc | Bin 984 -> 1004 bytes .../prompts/__pycache__/tox.cpython-313.pyc | Bin 644 -> 644 bytes .../toxicidade_output.cpython-313.pyc | Bin 928 -> 928 bytes .../guardrails/calibrated/prompts/dlex_out.py | 1 + .../__pycache__/__init__.cpython-313.pyc | Bin 581 -> 606 bytes .../supervision_template.cpython-313.pyc | Bin 2160 -> 2190 bytes .../__pycache__/tts_rules.cpython-313.pyc | Bin 1115 -> 1140 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 1663 -> 1663 bytes .../rails/__pycache__/alcada.cpython-313.pyc | Bin 4999 -> 4999 bytes .../rails/__pycache__/anatel.cpython-313.pyc | Bin 9148 -> 9148 bytes .../__pycache__/confirmation.cpython-313.pyc | Bin 11042 -> 11042 bytes .../rails/__pycache__/dlex_in.cpython-313.pyc | Bin 3279 -> 3279 bytes .../__pycache__/dlex_out.cpython-313.pyc | Bin 3331 -> 3331 bytes .../rails/__pycache__/ragsec.cpython-313.pyc | Bin 5462 -> 5462 bytes .../rails/__pycache__/revprec.cpython-313.pyc | Bin 5470 -> 5470 bytes .../rails/__pycache__/tox.cpython-313.pyc | Bin 8293 -> 8293 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 5685 -> 5725 bytes .../correspondencia_item.cpython-313.pyc | Bin 9012 -> 9226 bytes .../__pycache__/groundedness.cpython-313.pyc | Bin 8512 -> 8659 bytes .../intencao_cancelar.cpython-313.pyc | Bin 9170 -> 9376 bytes .../quantidade_coerente.cpython-313.pyc | Bin 8954 -> 9246 bytes .../servico_correto.cpython-313.pyc | Bin 8662 -> 9047 bytes .../verbalizacao_prematura.cpython-313.pyc | Bin 8497 -> 8595 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 533 -> 533 bytes .../rules/__pycache__/alcada.cpython-313.pyc | Bin 1881 -> 1881 bytes .../__pycache__/oos_blocklist.cpython-313.pyc | Bin 3002 -> 3022 bytes .../__pycache__/pinj_patterns.cpython-313.pyc | Bin 3730 -> 3730 bytes .../__pycache__/tox_blocklist.cpython-313.pyc | Bin 1506 -> 1506 bytes .../src/agent_framework/guardrails/rails.py | 225 ++++- .../__pycache__/__init__.cpython-313.pyc | Bin 408 -> 408 bytes .../__pycache__/mcp_mapper.cpython-313.pyc | Bin 4692 -> 4692 bytes .../__pycache__/models.cpython-313.pyc | Bin 3144 -> 3144 bytes .../__pycache__/resolver.cpython-313.pyc | Bin 4713 -> 4713 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 618 -> 618 bytes .../judges/__pycache__/judge.cpython-313.pyc | Bin 37576 -> 37576 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 225 -> 225 bytes .../__pycache__/_compat.cpython-313.pyc | Bin 2207 -> 2227 bytes .../__pycache__/llm_client.cpython-313.pyc | Bin 5404 -> 5404 bytes .../__pycache__/models.cpython-313.pyc | Bin 880 -> 900 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 233 -> 233 bytes .../prompts/__pycache__/aluc.cpython-313.pyc | Bin 6529 -> 6529 bytes .../prompts/__pycache__/csi.cpython-313.pyc | Bin 1332 -> 1332 bytes .../__pycache__/fallback.cpython-313.pyc | Bin 8035 -> 8035 bytes .../prompts/__pycache__/rqlt.cpython-313.pyc | Bin 1165 -> 1165 bytes .../prompts/__pycache__/vctn.cpython-313.pyc | Bin 626 -> 626 bytes .../llm/__pycache__/__init__.cpython-313.pyc | Bin 476 -> 476 bytes .../llm/__pycache__/base.cpython-313.pyc | Bin 1623 -> 1623 bytes .../profile_resolver.cpython-313.pyc | Bin 9322 -> 9322 bytes .../llm/__pycache__/providers.cpython-313.pyc | Bin 45052 -> 45052 bytes .../structured_output.cpython-313.pyc | Bin 7459 -> 7459 bytes .../llm/__pycache__/types.cpython-313.pyc | Bin 1274 -> 1274 bytes .../mcp/__pycache__/__init__.cpython-313.pyc | Bin 473 -> 473 bytes .../mcp/__pycache__/client.cpython-313.pyc | Bin 18426 -> 18426 bytes .../mcp/__pycache__/models.cpython-313.pyc | Bin 2136 -> 2136 bytes .../mcp/__pycache__/registry.cpython-313.pyc | Bin 4740 -> 4740 bytes .../__pycache__/tool_policy.cpython-313.pyc | Bin 5685 -> 5685 bytes .../__pycache__/tool_router.cpython-313.pyc | Bin 14189 -> 14189 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 1135 -> 1135 bytes .../long_term_extractor.cpython-313.pyc | Bin 2513 -> 2513 bytes .../long_term_memory.cpython-313.pyc | Bin 6839 -> 6839 bytes .../long_term_models.cpython-313.pyc | Bin 1748 -> 1748 bytes .../long_term_store.cpython-313.pyc | Bin 29186 -> 29186 bytes .../message_history.cpython-313.pyc | Bin 8359 -> 8359 bytes .../summary_memory.cpython-313.pyc | Bin 12510 -> 12510 bytes .../__pycache__/summary_store.cpython-313.pyc | Bin 9520 -> 9520 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 214 -> 214 bytes .../__pycache__/identity.cpython-313.pyc | Bin 3465 -> 3465 bytes .../__pycache__/session.cpython-313.pyc | Bin 2708 -> 2708 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 1394 -> 1394 bytes .../__pycache__/code_mapper.cpython-313.pyc | Bin 21447 -> 21447 bytes .../__pycache__/context.cpython-313.pyc | Bin 7386 -> 7386 bytes .../control_events.cpython-313.pyc | Bin 2016 -> 2036 bytes .../__pycache__/decorators.cpython-313.pyc | Bin 1727 -> 1747 bytes .../__pycache__/event_bus.cpython-313.pyc | Bin 3632 -> 3632 bytes .../__pycache__/grl_events.cpython-313.pyc | Bin 437 -> 908 bytes .../guardrail_events.cpython-313.pyc | Bin 2050 -> 2050 bytes .../__pycache__/ic_events.cpython-313.pyc | Bin 625 -> 625 bytes .../informational_events.cpython-313.pyc | Bin 407 -> 427 bytes .../__pycache__/judge_events.cpython-313.pyc | Bin 1410 -> 1410 bytes .../langfuse_enterprise.cpython-313.pyc | Bin 3716 -> 3736 bytes .../langgraph_telemetry.cpython-313.pyc | Bin 4963 -> 4963 bytes .../__pycache__/llm_advisors.cpython-313.pyc | Bin 2937 -> 2937 bytes .../__pycache__/noc_contract.cpython-313.pyc | Bin 5074 -> 5074 bytes .../__pycache__/noc_events.cpython-313.pyc | Bin 548 -> 568 bytes .../__pycache__/noc_otel.cpython-313.pyc | Bin 6321 -> 6321 bytes .../__pycache__/observer.cpython-313.pyc | Bin 5104 -> 5104 bytes .../__pycache__/otel.cpython-313.pyc | Bin 3411 -> 3411 bytes .../streaming_events.cpython-313.pyc | Bin 1834 -> 1834 bytes .../streaming_exporter.cpython-313.pyc | Bin 1295 -> 1315 bytes .../__pycache__/telemetry.cpython-313.pyc | Bin 52427 -> 52427 bytes .../tim_backoffice_contract.cpython-313.pyc | Bin 1736 -> 1756 bytes .../__pycache__/token_cost.cpython-313.pyc | Bin 8690 -> 8690 bytes .../workflow_events.cpython-313.pyc | Bin 3329 -> 3329 bytes .../oci/__pycache__/__init__.cpython-313.pyc | Bin 211 -> 211 bytes .../oci/__pycache__/auth.cpython-313.pyc | Bin 3243 -> 3243 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 219 -> 219 bytes .../__pycache__/mongodb_store.cpython-313.pyc | Bin 7621 -> 7641 bytes .../__pycache__/oracle_store.cpython-313.pyc | Bin 44955 -> 44955 bytes .../__pycache__/sqlite_store.cpython-313.pyc | Bin 15018 -> 15018 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 454 -> 454 bytes .../__pycache__/renderers.cpython-313.pyc | Bin 4317 -> 4317 bytes .../rag/__pycache__/__init__.cpython-313.pyc | Bin 709 -> 709 bytes .../embedding_provider.cpython-313.pyc | Bin 6516 -> 6516 bytes .../__pycache__/graph_store.cpython-313.pyc | Bin 5527 -> 5527 bytes .../rag/__pycache__/ingest.cpython-313.pyc | Bin 12580 -> 12580 bytes .../__pycache__/kbdb_service.cpython-313.pyc | Bin 10011 -> 10011 bytes .../__pycache__/rag_service.cpython-313.pyc | Bin 10897 -> 10897 bytes .../__pycache__/vector_store.cpython-313.pyc | Bin 18655 -> 18655 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 220 -> 220 bytes .../session_repository.cpython-313.pyc | Bin 8589 -> 8589 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 425 -> 425 bytes .../__pycache__/config_loader.cpython-313.pyc | Bin 2296 -> 2296 bytes .../__pycache__/continuity.cpython-313.pyc | Bin 12315 -> 15933 bytes .../enterprise_router.cpython-313.pyc | Bin 36172 -> 61687 bytes .../__pycache__/models.cpython-313.pyc | Bin 2446 -> 2446 bytes .../src/agent_framework/routing/continuity.py | 97 ++ .../routing/enterprise_router.py | 585 +++++++++++- .../__pycache__/__init__.cpython-313.pyc | Bin 348 -> 348 bytes .../__pycache__/agent_runtime.cpython-313.pyc | Bin 151759 -> 177586 bytes .../transaction_input.cpython-313.pyc | Bin 2871 -> 2891 bytes .../transaction_parameters.cpython-313.pyc | Bin 10308 -> 11117 bytes .../agent_framework/runtime/agent_runtime.py | 645 ++++++++++++-- .../runtime/transaction_parameters.py | 9 +- .../__pycache__/__init__.cpython-313.pyc | Bin 1176 -> 1168 bytes .../authentication.cpython-313.pyc | Bin 15396 -> 15388 bytes .../__pycache__/factory.cpython-313.pyc | Bin 7965 -> 7957 bytes .../__pycache__/installer.cpython-313.pyc | Bin 5583 -> 5575 bytes .../__pycache__/middleware.cpython-313.pyc | Bin 8867 -> 8859 bytes .../sse/__pycache__/__init__.cpython-313.pyc | Bin 211 -> 211 bytes .../sse/__pycache__/events.cpython-313.pyc | Bin 9587 -> 9587 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 218 -> 218 bytes .../router_supervisor.cpython-313.pyc | Bin 353 -> 373 bytes .../__pycache__/supervisor.cpython-313.pyc | Bin 4943 -> 4943 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 878 -> 878 bytes .../__pycache__/graph.cpython-313.pyc | Bin 1415 -> 1415 bytes .../input_contract.cpython-313.pyc | Bin 2253 -> 8790 bytes .../__pycache__/models.cpython-313.pyc | Bin 5232 -> 7669 bytes .../__pycache__/registry.cpython-313.pyc | Bin 2361 -> 2361 bytes .../__pycache__/repository.cpython-313.pyc | Bin 2714 -> 2714 bytes .../__pycache__/runtime.cpython-313.pyc | Bin 32980 -> 36150 bytes .../__pycache__/tool_executor.cpython-313.pyc | Bin 1966 -> 1966 bytes .../workflows/input_contract.py | 110 +++ .../src/agent_framework/workflows/models.py | 43 + .../src/agent_framework/workflows/runtime.py | 96 +- .../__pycache__/main.cpython-313.pyc | Bin 0 -> 4785 bytes templates/agent_template_backend/.env | 207 ----- .../app/__pycache__/__init__.cpython-313.pyc | Bin 184 -> 145 bytes .../app/__pycache__/main.cpython-313.pyc | Bin 36696 -> 36677 bytes ...mcp_gateway_client_factory.cpython-313.pyc | Bin 1032 -> 993 bytes .../app/__pycache__/state.cpython-313.pyc | Bin 2937 -> 2973 bytes .../__pycache__/billing_agent.cpython-313.pyc | Bin 6276 -> 5216 bytes .../__pycache__/orders_agent.cpython-313.pyc | Bin 5929 -> 5124 bytes .../__pycache__/product_agent.cpython-313.pyc | Bin 6999 -> 5240 bytes .../__pycache__/prompting.cpython-313.pyc | Bin 1181 -> 1142 bytes .../__pycache__/runtime.cpython-313.pyc | Bin 468 -> 344 bytes .../__pycache__/support_agent.cpython-313.pyc | Bin 5984 -> 5136 bytes .../app/agents/billing_agent.py | 2 +- .../app/agents/orders_agent.py | 2 +- .../app/agents/product_agent.py | 2 +- .../app/agents/support_agent.py | 2 +- .../__pycache__/__init__.cpython-313.pyc | Bin 255 -> 216 bytes .../__pycache__/grl_examples.cpython-313.pyc | Bin 1837 -> 1798 bytes .../__pycache__/ic_examples.cpython-313.pyc | Bin 1793 -> 1754 bytes .../__pycache__/mcp_examples.cpython-313.pyc | Bin 1935 -> 1896 bytes .../__pycache__/noc_examples.cpython-313.pyc | Bin 1882 -> 1843 bytes .../observer_examples.cpython-313.pyc | Bin 1391 -> 1352 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 198 -> 159 bytes .../telemetry_observer.cpython-313.pyc | Bin 4809 -> 4770 bytes .../tool_renderers.cpython-313.pyc | Bin 5989 -> 4366 bytes .../app/presentation/tool_renderers.py | 37 +- .../__pycache__/__init__.cpython-313.pyc | Bin 238 -> 199 bytes .../__pycache__/devolucao.cpython-313.pyc | Bin 1016 -> 977 bytes .../__pycache__/agent_graph.cpython-313.pyc | Bin 60957 -> 56786 bytes .../app/workflows/agent_graph.py | 175 ++-- .../config/routing.yaml | 29 + .../docs/TRANSACTION_SEMANTIC_CONFIRMATION.md | 11 + .../agent_template_backend_day_zero/.env | 207 ----- .../app/__pycache__/__init__.cpython-313.pyc | Bin 193 -> 186 bytes .../app/__pycache__/main.cpython-313.pyc | Bin 35274 -> 31083 bytes ...mcp_gateway_client_factory.cpython-313.pyc | Bin 1041 -> 1034 bytes .../app/__pycache__/state.cpython-313.pyc | Bin 2651 -> 1918 bytes .../__pycache__/billing_agent.cpython-313.pyc | Bin 6285 -> 2541 bytes .../__pycache__/orders_agent.cpython-313.pyc | Bin 5938 -> 2459 bytes .../__pycache__/product_agent.cpython-313.pyc | Bin 6282 -> 2564 bytes .../__pycache__/prompting.cpython-313.pyc | Bin 1190 -> 1183 bytes .../__pycache__/runtime.cpython-313.pyc | Bin 392 -> 385 bytes .../__pycache__/support_agent.cpython-313.pyc | Bin 5993 -> 2461 bytes .../app/agents/billing_agent.py | 2 +- .../app/agents/orders_agent.py | 2 +- .../app/agents/product_agent.py | 2 +- .../app/agents/support_agent.py | 2 +- .../__pycache__/__init__.cpython-313.pyc | Bin 207 -> 200 bytes .../telemetry_observer.cpython-313.pyc | Bin 4818 -> 4811 bytes .../__pycache__/agent_graph.cpython-313.pyc | Bin 56838 -> 52663 bytes .../app/workflows/agent_graph.py | 173 ++-- .../config/routing.yaml | 29 + .../docs/TRANSACTION_SEMANTIC_CONFIRMATION.md | 11 + .../conftest.cpython-313-pytest-9.0.2.pyc | Bin 788 -> 788 bytes ..._continuation.cpython-313-pytest-9.0.2.pyc | Bin 8801 -> 8816 bytes ...pected_values.cpython-313-pytest-9.0.2.pyc | Bin 0 -> 8240 bytes ...on_parameters.cpython-313-pytest-9.0.2.pyc | Bin 0 -> 5439 bytes ...authorization.cpython-313-pytest-9.0.2.pyc | Bin 0 -> 22452 bytes ...ce_delegation.cpython-313-pytest-9.0.2.pyc | Bin 0 -> 12229 bytes ...ic_classifier.cpython-313-pytest-9.0.2.pyc | Bin 0 -> 35493 bytes ...ameter_prompt.cpython-313-pytest-9.0.2.pyc | Bin 6151 -> 6195 bytes ..._presentation.cpython-313-pytest-9.0.2.pyc | Bin 10418 -> 10454 bytes ...tion_sampling.cpython-313-pytest-9.0.2.pyc | Bin 6299 -> 6354 bytes ...ction_runtime.cpython-313-pytest-9.0.2.pyc | Bin 8776 -> 8831 bytes ..._deadlock_fix.cpython-313-pytest-9.0.2.pyc | Bin 11432 -> 11476 bytes ...me_precedence.cpython-313-pytest-9.0.2.pyc | Bin 28469 -> 67358 bytes ...optimizations.cpython-313-pytest-9.0.2.pyc | Bin 7922 -> 7960 bytes ..._revalidation.cpython-313-pytest-9.0.2.pyc | Bin 13672 -> 13716 bytes ...saction_shift.cpython-313-pytest-9.0.2.pyc | Bin 25794 -> 25794 bytes ...output_parser.cpython-313-pytest-9.0.2.pyc | Bin 8361 -> 8416 bytes ...stomer_facing.cpython-313-pytest-9.0.2.pyc | Bin 4791 -> 4802 bytes ..._descriptions.cpython-313-pytest-9.0.2.pyc | Bin 10415 -> 10459 bytes ...lm_precedence.cpython-313-pytest-9.0.2.pyc | Bin 32364 -> 47178 bytes ...ession_matrix.cpython-313-pytest-9.0.2.pyc | Bin 52038 -> 52046 bytes ..._interruption.cpython-313-pytest-9.0.2.pyc | Bin 28271 -> 28271 bytes ...nal_tool_flow.cpython-313-pytest-9.0.2.pyc | Bin 70421 -> 121202 bytes ...ntextual_reentry_transaction_parameters.py | 44 + ...lex_out_expected_protocol_authorization.py | 153 ++++ ...est_expected_input_coherence_delegation.py | 133 +++ ...test_expected_input_semantic_classifier.py | 284 ++++++ .../test_paused_workflow_resume_precedence.py | 546 +++++++++++- ...st_transaction_parameter_llm_precedence.py | 222 ++++- tests/test_transactional_tool_flow.py | 562 ++++++++++++ ...agent_runtime.cpython-313-pytest-9.0.2.pyc | Bin 3349 -> 3396 bytes ...uthentication.cpython-313-pytest-9.0.2.pyc | Bin 8543 -> 8590 bytes ...tion_policies.cpython-313-pytest-9.0.2.pyc | Bin 9446 -> 9493 bytes .../test_cache.cpython-313-pytest-9.0.2.pyc | Bin 3342 -> 3389 bytes ...e_distributed.cpython-313-pytest-9.0.2.pyc | Bin 2015 -> 2062 bytes ...ports_compile.cpython-313-pytest-9.0.2.pyc | Bin 593 -> 640 bytes ...pt_controlled.cpython-313-pytest-9.0.2.pyc | Bin 16529 -> 16576 bytes ...untime_config.cpython-313-pytest-9.0.2.pyc | Bin 30659 -> 30706 bytes ...ckpoint_saver.cpython-313-pytest-9.0.2.pyc | Bin 2327 -> 2374 bytes ...aph_telemetry.cpython-313-pytest-9.0.2.pyc | Bin 4715 -> 4762 bytes ...rich_response.cpython-313-pytest-9.0.2.pyc | Bin 22888 -> 22932 bytes ...ry_autonomous.cpython-313-pytest-9.0.2.pyc | Bin 7793 -> 7840 bytes ...ics_publisher.cpython-313-pytest-9.0.2.pyc | Bin 7084 -> 7131 bytes .../test_rag.cpython-313-pytest-9.0.2.pyc | Bin 2886 -> 2933 bytes ...kbdb_provider.cpython-313-pytest-9.0.2.pyc | Bin 11547 -> 11594 bytes ...ql_generation.cpython-313-pytest-9.0.2.pyc | Bin 1425 -> 1472 bytes ...ime_grounding.cpython-313-pytest-9.0.2.pyc | Bin 9650 -> 9697 bytes ..._checkpointer.cpython-313-pytest-9.0.2.pyc | Bin 5271 -> 5318 bytes ...te_stickiness.cpython-313-pytest-9.0.2.pyc | Bin 27026 -> 27073 bytes .../test_sse.cpython-313-pytest-9.0.2.pyc | Bin 4485 -> 4532 bytes ..._replay_dedup.cpython-313-pytest-9.0.2.pyc | Bin 4414 -> 4461 bytes ...gfuse_compact.cpython-313-pytest-9.0.2.pyc | Bin 42279 -> 42326 bytes ...st_enterprise.cpython-313-pytest-9.0.2.pyc | Bin 5673 -> 5720 bytes ...tool_policies.cpython-313-pytest-9.0.2.pyc | Bin 13723 -> 13770 bytes ...nal_workflows.cpython-313-pytest-9.0.2.pyc | Bin 12089 -> 12129 bytes ...e_diagnostics.cpython-313-pytest-9.0.2.pyc | Bin 5401 -> 5448 bytes ...rkflow_static.cpython-313-pytest-9.0.2.pyc | Bin 3273 -> 3320 bytes ...hot_semantics.cpython-313-pytest-9.0.2.pyc | Bin 0 -> 19458 bytes ...st_workflow_terminal_snapshot_semantics.py | 190 ++++ 699 files changed, 7989 insertions(+), 2364 deletions(-) create mode 100644 Tuning-Performance/Authentication/agent_template_backend_authentication/docs/TRANSACTION_SEMANTIC_CONFIRMATION.md create mode 100644 Tuning-Performance/Deterministic_Transactional_Workflow/agent_template_backend/docs/TRANSACTION_SEMANTIC_CONFIRMATION.md create mode 100644 Tuning-Performance/External_Guardrails_Judges/agent_template_backend/docs/TRANSACTION_SEMANTIC_CONFIRMATION.md create mode 100644 Tuning-Performance/Long_Term_Memory/templates/agent_template_backend/docs/TRANSACTION_SEMANTIC_CONFIRMATION.md create mode 100644 Tuning-Performance/Normal/templates/agent_template_backend/docs/TRANSACTION_SEMANTIC_CONFIRMATION.md create mode 100644 Tuning-Performance/Normal/templates/agent_template_backend_day_zero/docs/TRANSACTION_SEMANTIC_CONFIRMATION.md create mode 100644 Tuning-Performance/Pause_Resume_Workflow/agent_template_backend/README.md create mode 100644 Tuning-Performance/Pause_Resume_Workflow/agent_template_backend/app/__init__.py create mode 100644 Tuning-Performance/Pause_Resume_Workflow/agent_template_backend/app/__pycache__/__init__.cpython-313.pyc create mode 100644 Tuning-Performance/Pause_Resume_Workflow/agent_template_backend/app/__pycache__/demo.cpython-313.pyc create mode 100644 Tuning-Performance/Pause_Resume_Workflow/agent_template_backend/app/demo.py create mode 100644 Tuning-Performance/Pause_Resume_Workflow/agent_template_backend/docs/TRANSACTION_SEMANTIC_CONFIRMATION.md create mode 100644 Tuning-Performance/Pause_Resume_Workflow/agent_template_backend/tests/__pycache__/test_pause_resume.cpython-313-pytest-9.0.2.pyc create mode 100644 Tuning-Performance/Pause_Resume_Workflow/agent_template_backend/tests/test_pause_resume.py create mode 100644 Tuning-Performance/Pause_Resume_Workflow/agent_template_backend/workflows/confirmacao.active.yaml create mode 100644 Tuning-Performance/Pause_Resume_Workflow/agent_template_backend/workflows/confirmacao.v1.yaml create mode 100644 Tuning-Performance/Pause_Resume_Workflow/agent_template_backend_pause_resume/app/__pycache__/__init__.cpython-313.pyc create mode 100644 Tuning-Performance/Pause_Resume_Workflow/agent_template_backend_pause_resume/app/__pycache__/demo.cpython-313.pyc create mode 100644 Tuning-Performance/Pause_Resume_Workflow/agent_template_backend_pause_resume/docs/TRANSACTION_SEMANTIC_CONFIRMATION.md create mode 100644 Tuning-Performance/Pause_Resume_Workflow/agent_template_backend_pause_resume/tests/__pycache__/test_pause_resume.cpython-313-pytest-9.0.2.pyc create mode 100644 Tuning-Performance/Route_Stickness/templates/agent_template_backend/docs/TRANSACTION_SEMANTIC_CONFIRMATION.md create mode 100644 Tuning-Performance/Route_Stickness/templates/agent_template_backend_day_zero/docs/TRANSACTION_SEMANTIC_CONFIRMATION.md create mode 100644 Tuning-Performance/Transaction_Evidence/agent_template_backend/docs/TRANSACTION_SEMANTIC_CONFIRMATION.md create mode 100644 Tuning-Performance/Transaction_Pre_Validation/agent_template_backend/docs/TRANSACTION_SEMANTIC_CONFIRMATION.md create mode 100644 docs/FIX_PAUSED_WORKFLOW_HUMAN_HANDOFF_PRECEDENCE_20260829.md create mode 100644 docs/FIX_POST_FINALIZATION_SOFT_RESET_20260829.md create mode 100644 docs/FIX_WORKFLOW_FINAL_STATUS_NORMALIZATION_20260829.md create mode 100644 docs/FIX_WORKFLOW_TERMINAL_LIFECYCLE_SAME_SESSION_20260829.md create mode 100644 docs/FIX_WORKFLOW_TERMINAL_SNAPSHOT_SEMANTICS_20260829.md create mode 100644 docs/developer/en/12_input_guardrail_feedback_and_blocked_turns.md create mode 100644 docs/developer/pt/12_input_guardrail_feedback_and_blocked_turns.md create mode 100644 libs/agent_framework/build/lib/agent_framework/__pycache__/__init__.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/__pycache__/extensions.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/__pycache__/gateway_policy_context.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/__pycache__/idempotency.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/__pycache__/observer.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/__pycache__/runtime_mcp_gateway_adapter.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/analytics/__pycache__/__init__.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/analytics/__pycache__/composite_publisher.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/analytics/__pycache__/event_builder.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/analytics/__pycache__/factory.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/analytics/__pycache__/publisher.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/analytics/__pycache__/tim_payload_mapper.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/analytics/__pycache__/tim_sequence.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/analytics/providers/__pycache__/__init__.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/analytics/providers/__pycache__/kafka.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/analytics/providers/__pycache__/langfuse.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/analytics/providers/__pycache__/oci_streaming.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/analytics/providers/__pycache__/pubsub.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/billing/__pycache__/__init__.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/billing/__pycache__/usage_repository.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/cache/__pycache__/__init__.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/cache/__pycache__/cache.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/channels/__pycache__/__init__.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/channels/__pycache__/adapters.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/channels/__pycache__/base.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/channels/__pycache__/gateway.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/channels/__pycache__/interruption.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/channels/__pycache__/transcription.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/checkpoints/__pycache__/__init__.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/checkpoints/__pycache__/checkpoint_repository.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/checkpoints/__pycache__/langgraph_saver.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/config/__pycache__/__init__.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/config/__pycache__/agent_registry.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/config/__pycache__/settings.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/events/__pycache__/__init__.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/events/__pycache__/oci_streaming.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/gateways/__pycache__/__init__.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/gateways/__pycache__/mcp_gateway_client.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/global_supervisor/__pycache__/__init__.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/global_supervisor/__pycache__/client.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/global_supervisor/__pycache__/config.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/global_supervisor/__pycache__/models.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/global_supervisor/__pycache__/router.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/global_supervisor/__pycache__/session_store.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/guardrails/__pycache__/__init__.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/guardrails/__pycache__/base.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/guardrails/__pycache__/config_loader.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/guardrails/__pycache__/custom_rails.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/guardrails/__pycache__/executor.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/guardrails/__pycache__/framework_llm_client.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/guardrails/__pycache__/langgraph_adapters.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/guardrails/__pycache__/llm_rails.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/guardrails/__pycache__/output_supervisor.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/guardrails/__pycache__/parallel_executor.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/guardrails/__pycache__/pipeline.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/guardrails/__pycache__/rail_action.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/guardrails/__pycache__/rail_decision.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/guardrails/__pycache__/rail_result.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/guardrails/__pycache__/rails.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/__pycache__/__init__.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/__pycache__/_compat.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/__pycache__/config.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/__pycache__/contestation_validation.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/__pycache__/contracts.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/__pycache__/input_size.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/__pycache__/llm_adapter.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/__pycache__/llm_client.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/__pycache__/llm_rails.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/__pycache__/output_sanitization.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/__pycache__/pipeline.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/prompts/__pycache__/__init__.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/prompts/__pycache__/_context.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/prompts/__pycache__/ausencia_oferta_proativa.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/prompts/__pycache__/coerencia.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/prompts/__pycache__/dlex_in.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/prompts/__pycache__/dlex_out.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/prompts/__pycache__/fallback.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/prompts/__pycache__/fraseologia.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/prompts/__pycache__/out_of_scope.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/prompts/__pycache__/pinj.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/prompts/__pycache__/ragsec.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/prompts/__pycache__/revprec.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/prompts/__pycache__/safe_out.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/prompts/__pycache__/tox.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/prompts/__pycache__/toxicidade_output.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/prompts/shared/__pycache__/__init__.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/prompts/shared/__pycache__/supervision_template.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/prompts/shared/__pycache__/tts_rules.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/rails/__pycache__/__init__.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/rails/__pycache__/alcada.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/rails/__pycache__/anatel.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/rails/__pycache__/confirmation.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/rails/__pycache__/dlex_in.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/rails/__pycache__/dlex_out.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/rails/__pycache__/ragsec.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/rails/__pycache__/revprec.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/rails/__pycache__/tox.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/rails/supervision/__pycache__/__init__.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/rails/supervision/__pycache__/correspondencia_item.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/rails/supervision/__pycache__/groundedness.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/rails/supervision/__pycache__/intencao_cancelar.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/rails/supervision/__pycache__/quantidade_coerente.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/rails/supervision/__pycache__/servico_correto.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/rails/supervision/__pycache__/verbalizacao_prematura.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/rules/__pycache__/__init__.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/rules/__pycache__/alcada.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/rules/__pycache__/oos_blocklist.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/rules/__pycache__/pinj_patterns.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/rules/__pycache__/tox_blocklist.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/identity/__pycache__/__init__.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/identity/__pycache__/mcp_mapper.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/identity/__pycache__/models.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/identity/__pycache__/resolver.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/judges/__pycache__/__init__.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/judges/__pycache__/judge.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/judges/calibrated/__pycache__/__init__.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/judges/calibrated/__pycache__/_compat.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/judges/calibrated/__pycache__/llm_client.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/judges/calibrated/__pycache__/models.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/judges/calibrated/prompts/__pycache__/__init__.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/judges/calibrated/prompts/__pycache__/aluc.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/judges/calibrated/prompts/__pycache__/csi.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/judges/calibrated/prompts/__pycache__/fallback.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/judges/calibrated/prompts/__pycache__/rqlt.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/judges/calibrated/prompts/__pycache__/vctn.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/llm/__pycache__/__init__.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/llm/__pycache__/base.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/llm/__pycache__/profile_resolver.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/llm/__pycache__/providers.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/llm/__pycache__/types.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/mcp/__pycache__/__init__.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/mcp/__pycache__/client.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/mcp/__pycache__/models.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/mcp/__pycache__/registry.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/mcp/__pycache__/tool_policy.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/mcp/__pycache__/tool_router.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/memory/__pycache__/__init__.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/memory/__pycache__/long_term_extractor.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/memory/__pycache__/long_term_memory.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/memory/__pycache__/long_term_models.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/memory/__pycache__/long_term_store.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/memory/__pycache__/message_history.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/memory/__pycache__/summary_memory.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/memory/__pycache__/summary_store.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/models/__pycache__/__init__.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/models/__pycache__/identity.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/models/__pycache__/session.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/observability/__pycache__/__init__.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/observability/__pycache__/code_mapper.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/observability/__pycache__/context.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/observability/__pycache__/control_events.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/observability/__pycache__/decorators.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/observability/__pycache__/event_bus.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/observability/__pycache__/grl_events.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/observability/__pycache__/guardrail_events.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/observability/__pycache__/ic_events.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/observability/__pycache__/informational_events.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/observability/__pycache__/judge_events.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/observability/__pycache__/langfuse_enterprise.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/observability/__pycache__/langgraph_telemetry.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/observability/__pycache__/llm_advisors.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/observability/__pycache__/noc_contract.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/observability/__pycache__/noc_events.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/observability/__pycache__/noc_otel.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/observability/__pycache__/observer.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/observability/__pycache__/otel.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/observability/__pycache__/streaming_events.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/observability/__pycache__/streaming_exporter.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/observability/__pycache__/telemetry.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/observability/__pycache__/tim_backoffice_contract.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/observability/__pycache__/token_cost.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/observability/__pycache__/workflow_events.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/oci/__pycache__/__init__.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/oci/__pycache__/auth.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/persistence/__pycache__/__init__.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/persistence/__pycache__/mongodb_store.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/persistence/__pycache__/oracle_store.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/persistence/__pycache__/sqlite_store.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/presentation/__pycache__/__init__.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/presentation/__pycache__/renderers.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/rag/__pycache__/__init__.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/rag/__pycache__/embedding_provider.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/rag/__pycache__/graph_store.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/rag/__pycache__/ingest.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/rag/__pycache__/rag_service.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/rag/__pycache__/vector_store.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/repositories/__pycache__/__init__.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/repositories/__pycache__/session_repository.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/routing/__pycache__/__init__.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/routing/__pycache__/config_loader.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/routing/__pycache__/continuity.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/routing/__pycache__/enterprise_router.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/routing/__pycache__/models.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/runtime/__pycache__/__init__.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/runtime/__pycache__/agent_runtime.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/runtime/__pycache__/transaction_input.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/runtime/__pycache__/transaction_parameters.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/security/__pycache__/__init__.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/security/__pycache__/authentication.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/security/__pycache__/factory.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/security/__pycache__/installer.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/security/__pycache__/middleware.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/sse/__pycache__/__init__.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/sse/__pycache__/events.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/supervisor/__pycache__/__init__.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/supervisor/__pycache__/router_supervisor.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/supervisor/__pycache__/supervisor.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/workflows/__pycache__/__init__.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/workflows/__pycache__/graph.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/workflows/__pycache__/input_contract.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/workflows/__pycache__/models.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/workflows/__pycache__/registry.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/workflows/__pycache__/repository.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/workflows/__pycache__/runtime.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/workflows/__pycache__/tool_executor.cpython-313.pyc create mode 100644 libs/agent_framework/build/lib/agent_framework/workflows/input_contract.py create mode 100644 mcp/servers/telecom_mcp_server/__pycache__/main.cpython-313.pyc delete mode 100644 templates/agent_template_backend/.env create mode 100644 templates/agent_template_backend/docs/TRANSACTION_SEMANTIC_CONFIRMATION.md delete mode 100644 templates/agent_template_backend_day_zero/.env create mode 100644 templates/agent_template_backend_day_zero/docs/TRANSACTION_SEMANTIC_CONFIRMATION.md create mode 100644 tests/__pycache__/test_compliance_protocol_expected_values.cpython-313-pytest-9.0.2.pyc create mode 100644 tests/__pycache__/test_contextual_reentry_transaction_parameters.cpython-313-pytest-9.0.2.pyc create mode 100644 tests/__pycache__/test_dlex_out_expected_protocol_authorization.cpython-313-pytest-9.0.2.pyc create mode 100644 tests/__pycache__/test_expected_input_coherence_delegation.cpython-313-pytest-9.0.2.pyc create mode 100644 tests/__pycache__/test_expected_input_semantic_classifier.cpython-313-pytest-9.0.2.pyc create mode 100644 tests/test_contextual_reentry_transaction_parameters.py create mode 100644 tests/test_dlex_out_expected_protocol_authorization.py create mode 100644 tests/test_expected_input_coherence_delegation.py create mode 100644 tests/test_expected_input_semantic_classifier.py create mode 100644 tests/unit/__pycache__/test_workflow_terminal_snapshot_semantics.cpython-313-pytest-9.0.2.pyc create mode 100644 tests/unit/test_workflow_terminal_snapshot_semantics.py diff --git a/README.md b/README.md index b91aab5..1b43152 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ A documentação possui três níveis: 1. **Tutorial principal:** este [`README.md`](README.md) — criação, configuração, execução e teste de um agente do início ao fim. 2. **Arquitetura:** [01 — Arquitetura e Conceitos](docs/developer/pt/01_architecture_and_concepts.md) — componentes, responsabilidades e onde implementar cada coisa. -3. **Referências especializadas:** manuais `02` a `11` — implementação profunda e troubleshooting por capacidade. +3. **Referências especializadas:** manuais `02` a `12` — implementação profunda e troubleshooting por capacidade. Se você está começando um novo agente, siga este `README.md` desde o início. Para aprofundamento ou troubleshooting, use os links abaixo. @@ -11217,6 +11217,9 @@ O conteúdo desta pasta deve ser tratado como uma extensão adicional do framewo | Recebo 401 entre gateway/backend/MCP | Basic Auth, credenciais por hop | [Gateways e Auth](docs/developer/pt/05_agent_gateway_mcp_gateway_and_auth.md) | | Preciso decidir se algo pertence ao framework ou ao agente | boundary core/agente | [Arquitetura e Conceitos](docs/developer/pt/01_architecture_and_concepts.md) | | Guardrail específico de um agente está quebrando outro | extensibilidade, imports de domínio no core | [Guardrails e Judges](docs/developer/pt/06_guardrails_judges_and_transaction_evaluation.md) | +| Uma frase incompleta recebe mensagem genérica de “regra de segurança” | feedback de input guardrail, `COER`, blocked-turn state | [Feedback de Guardrails de Entrada](docs/developer/pt/12_input_guardrail_feedback_and_blocked_turns.md) | +| `route=blocked` aparece junto com tools/resultados de outro turno | limpeza de estado do turno bloqueado | [Feedback de Guardrails de Entrada](docs/developer/pt/12_input_guardrail_feedback_and_blocked_turns.md) | +| Workflow conclui e gera protocolo, mas a resposta final vira mensagem de segurança | `expected_protocols`, `CMP`, `DLEX_OUT`, ordem de `output_guardrails` | [Guardrails e Judges](docs/developer/pt/06_guardrails_judges_and_transaction_evaluation.md) | | Judge não roda em uma transação | sampling, `always_run_for_transactional`, sinais transacionais | [Guardrails e Judges](docs/developer/pt/06_guardrails_judges_and_transaction_evaluation.md) | | Groundedness está avaliando sem contexto correto | RAG context, MCP evidence, judge inputs | [RAG/Grounding](docs/developer/pt/07_rag_business_context_and_grounding.md) | | RAG não encontra conteúdo | provider, ingestão, embeddings, configuração | [RAG/Grounding](docs/developer/pt/07_rag_business_context_and_grounding.md) | @@ -11301,6 +11304,12 @@ O conteúdo desta pasta deve ser tratado como uma extensão adicional do framewo **Use quando:** for necessário provar o caminho executado ou diagnosticar produção. +### [12 — Feedback de Guardrails de Entrada e Turnos Bloqueados](docs/developer/pt/12_input_guardrail_feedback_and_blocked_turns.md) + +**O que é:** semântica de mensagens públicas para bloqueios de input, limpeza do estado do turno e passagem da resposta pelos guardrails de saída. + +**Use quando:** um `COER`/guardrail de entrada gera mensagem genérica, `route=blocked` carrega resultados antigos ou há dúvida sobre a precedência entre input guardrails, routing e tools. + ### Tutorial principal [`README.md`](README.md) continua sendo a referência para o passo a passo completo: diff --git a/README_en.md b/README_en.md index 834af65..46603af 100644 --- a/README_en.md +++ b/README_en.md @@ -32,7 +32,7 @@ The documentation has three clear levels: 1. **Main tutorial:** this [`README_en.md`](README_en.md) — build, configure, run and test an agent end to end. 2. **Architecture:** [01 — Architecture and Concepts](docs/developer/en/01_architecture_and_concepts.md) — components, boundaries and implementation placement. -3. **Specialized references:** manuals `02` through `11` — deep implementation and troubleshooting by capability. +3. **Specialized references:** manuals `02` through `12` — deep implementation and troubleshooting by capability. If you are creating a new agent, follow this `README_en.md` from the beginning. For deeper implementation details or troubleshooting, use the links below. @@ -11205,6 +11205,14 @@ The content of this folder should be treated as an additional framework extensio **Use it when:** proving execution paths or diagnosing production behavior. +### [12 — Input Guardrail Feedback and Blocked-Turn Semantics](docs/developer/en/12_input_guardrail_feedback_and_blocked_turns.md) + +**What it is:** user-facing semantics for input blocks, blocked-turn state cleanup, and output-guardrail validation of the generated feedback. + +**Use it when:** `COER`/input guardrails generate generic messages, `route=blocked` carries stale results, or you need to reason about precedence between input guardrails, routing, and tools. + ### Main tutorial [`README_en.md`](README_en.md) remains the complete step-by-step guide. + +| Workflow completes and generates a protocol, but the final response becomes a safety message | `expected_protocols`, `CMP`, `DLEX_OUT`, `output_guardrails` ordering | [Guardrails and Judges](docs/developer/en/06_guardrails_judges_and_transaction_evaluation.md) | diff --git a/Tuning-Performance/Authentication/agent_template_backend_authentication/app/workflows/__pycache__/agent_graph.cpython-313.pyc b/Tuning-Performance/Authentication/agent_template_backend_authentication/app/workflows/__pycache__/agent_graph.cpython-313.pyc index dbe6f0989dac2c2c33f4715a3e6c08170cf7aaba..70ba3b260dc934933fd7b2953c2f95d2ff98463a 100644 GIT binary patch delta 6145 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 Z@`cs}@+#Z(L2ufCnPgwpA<|ON_+JHY(ait= diff --git a/Tuning-Performance/Authentication/agent_template_backend_authentication/app/workflows/agent_graph.py b/Tuning-Performance/Authentication/agent_template_backend_authentication/app/workflows/agent_graph.py index b8ed7bc..ed17e04 100644 --- a/Tuning-Performance/Authentication/agent_template_backend_authentication/app/workflows/agent_graph.py +++ b/Tuning-Performance/Authentication/agent_template_backend_authentication/app/workflows/agent_graph.py @@ -160,7 +160,7 @@ class AgentWorkflow: builder.add_conditional_edges( "input_guardrails", self._after_input_guardrails, - {"blocked": "persist", "continue": "load_long_term_memory"}, + {"blocked": "output_guardrails", "continue": "load_long_term_memory"}, ) builder.add_edge("load_long_term_memory", "routing_decision") builder.add_conditional_edges( @@ -197,6 +197,31 @@ class AgentWorkflow: def _after_input_guardrails(self, state): return "blocked" if state.get("blocked") else "continue" + @staticmethod + def _input_guardrail_user_message(decisions, state, sanitized_text): + # Keep the technical guardrail reason in telemetry, but expose only a + # safe, actionable message to the end user. The message is intentionally + # routed through output_guardrails before persistence/delivery. + blocked = [d for d in decisions if not getattr(d, "allowed", True)] + first = blocked[0] if blocked else None + code = str(getattr(first, "code", "") or "").upper() + if code == "COER": + return ( + "Não consegui entender sua última mensagem porque ela parece " + "incompleta ou ambígua. Pode reformular ou completar o que você quis dizer?" + ) + if code == "INPUT_SIZE": + return "Sua mensagem ficou muito longa para eu processar de uma vez. Pode resumir ou dividir em partes?" + if code == "DLEX_IN": + return "Não posso usar essa informação da forma solicitada. Reformule o pedido sem incluir dados ou conteúdo restrito." + if code == "PINJ": + return "Não posso seguir instruções que tentem alterar as regras do atendimento. Posso continuar ajudando com a sua solicitação." + if code == "TOX": + return "Não consegui prosseguir com essa mensagem. Pode reformular o pedido para continuarmos o atendimento?" + if code == "CMP": + return "Não posso prosseguir com essa solicitação dessa forma. Posso ajudar com uma alternativa permitida." + return "Não consegui processar essa mensagem. Pode reformular para eu continuar o atendimento?" + async def input_guardrails(self, state): if state.get("session_ended") is True: answer = str(getattr( @@ -281,12 +306,33 @@ class AgentWorkflow: component="workflow.input_guardrails.final", ) if any(not d.allowed for d in decisions): + # A blocking input guardrail stops the turn before routing/tools. + # Clear turn-local routing/tool state so stale data from a prior + # turn cannot appear as if it was executed after the block. + user_message = self._input_guardrail_user_message(decisions, state, sanitized) return { "sanitized_input": sanitized, - "answer": "Não consegui seguir com essa mensagem por regra de segurança.", - "final_answer": "Não consegui seguir com essa mensagem por regra de segurança.", + "answer": user_message, + "final_answer": None, "guardrail_decisions": [d.model_dump() for d in decisions], "route": "blocked", + "intent": "input_guardrail_blocked", + "route_decision": { + "route": "blocked", + "agent": None, + "intent": "input_guardrail_blocked", + "confidence": 1.0, + "reason": "Entrada interrompida por guardrail antes do roteamento.", + "method": "guardrail", + "next_state": state.get("next_state"), + "handoff": False, + "metadata": {}, + "domain": state.get("domain"), + "mcp_tools": [], + }, + "mcp_tools": [], + "mcp_results": [], + "judge_results": [], "blocked": True, } return { diff --git a/Tuning-Performance/Authentication/agent_template_backend_authentication/config/routing.yaml b/Tuning-Performance/Authentication/agent_template_backend_authentication/config/routing.yaml index 03aeaa9..bb4ef6f 100644 --- a/Tuning-Performance/Authentication/agent_template_backend_authentication/config/routing.yaml +++ b/Tuning-Performance/Authentication/agent_template_backend_authentication/config/routing.yaml @@ -7,6 +7,35 @@ router: confidence_threshold: 0.65 allow_handoff: true + transaction_confirmation: + # Explicit yes/no stays deterministic. Only inconclusive replies use this LLM fallback. + semantic_fallback: + enabled: true + allowed_values: [SIM, NAO, CONTINUAR] + confirm_values: [SIM] + reject_values: [NAO] + continue_values: [CONTINUAR] + include_relevant_context: true + profile_name: router + prompt: | + Você classifica a resposta do cliente a uma confirmação transacional pendente. + Considere a pergunta pendente, somente o histórico recente relacionado ao mesmo tema e a fala atual. + Não execute a ação e não invente fatos. + + Classes permitidas: {{ allowed_values }} + - SIM: confirmação/aceite inequívoco, inclusive equivalentes como "isso mesmo", "pode confirmar", "é isso" quando o contexto tornar o aceite claro. + - NAO: recusa/cancelamento inequívoco da ação pendente. + - CONTINUAR: qualquer resposta que não confirme nem rejeite inequivocamente, incluindo pergunta adicional, correção, novo dado, ambiguidade ou possível mudança de assunto. + + Pergunta pendente: + {{ pending_prompt }} + + Histórico relevante: + {{ relevant_conversation_context }} + + Resposta atual do cliente: + {{ user_input }} + state_policies: - state: WAITING_BILLING_CONFIRMATION agent: billing_agent diff --git a/Tuning-Performance/Authentication/agent_template_backend_authentication/docs/TRANSACTION_SEMANTIC_CONFIRMATION.md b/Tuning-Performance/Authentication/agent_template_backend_authentication/docs/TRANSACTION_SEMANTIC_CONFIRMATION.md new file mode 100644 index 0000000..a550871 --- /dev/null +++ b/Tuning-Performance/Authentication/agent_template_backend_authentication/docs/TRANSACTION_SEMANTIC_CONFIRMATION.md @@ -0,0 +1,11 @@ +# Confirmação Transacional Semântica + +Este template suporta confirmação transacional em duas camadas: primeiro um parser determinístico para `sim`/`não` e equivalentes explícitos; somente quando ele não consegue decidir, o framework usa um classificador semântico configurado em `config/routing.yaml`. + +A configuração `router.transaction_confirmation.semantic_fallback` usa três classes: `SIM`, `NAO` e `CONTINUAR`. O prompt pode usar `{{ pending_prompt }}`, `{{ relevant_conversation_context }}`, `{{ user_input }}` e `{{ allowed_values }}`. O histórico injetado é apenas contexto de interpretação; não substitui validação de negócio ou evidência MCP. + +Exemplo: após `Você confirma o cancelamento do serviço Tamboro Mensal?`, a frase `isso mesmo, pode confirmar` pode ser classificada como `SIM`. Já `mas qual é o valor?` deve ser `CONTINUAR`, portanto não executa a ação por confirmação. + +Entradas explícitas já suportadas continuam no caminho determinístico e não geram custo adicional de LLM. Em observabilidade, o fallback usa `transaction.confirmation.semantic_classifier` e o `route_decision.metadata` informa `transaction_confirmation_source: semantic`. + +Consulte `docs/developer/pt/03_transaction_workflows_and_state.md` do framework para o contrato completo e exemplos. diff --git a/Tuning-Performance/Deterministic_Transactional_Workflow/agent_template_backend/app/agents/billing_agent.py b/Tuning-Performance/Deterministic_Transactional_Workflow/agent_template_backend/app/agents/billing_agent.py index 05254d1..aa60099 100644 --- a/Tuning-Performance/Deterministic_Transactional_Workflow/agent_template_backend/app/agents/billing_agent.py +++ b/Tuning-Performance/Deterministic_Transactional_Workflow/agent_template_backend/app/agents/billing_agent.py @@ -95,7 +95,7 @@ class BillingAgent(AgentRuntimeMixin): state, system_prompt=apply_agent_profile_prompt( state, - "Você é um agente especialista em faturas.\n\nUse dados de tools/MCP e RAG autorizados como fonte de verdade para responder somente à solicitação atual.\nNunca exponha identificadores técnicos ou de identidade presentes no estado, contexto ou MCP, incluindo customer_key, contract_key, account_key, resource_key, session_key, customer_id, document, message_id, ura_call_id ou MSISDN/telefone completo.\nNão transforme nomes internos de campos em rótulos para o cliente, como “contract_key”, “customer_key” ou “MSISDN”.\nPara consultas informativas de fatura, apresente somente dados de negócio necessários, como valor, vencimento, situação e itens cobrados.\nNão acrescente canais, telefones, códigos USSD, URLs, aplicativos, lojas, relatórios adicionais, procedimentos alternativos ou próximos passos que não tenham sido explicitamente retornados pela tool/RAG e solicitados pelo usuário.\nNão ofereça espontaneamente outras ações ou detalhamentos.\nSe uma tool retornar BLOCKED, OUT_OF_SCOPE, NOT_ALLOWED, FAILED ou outro resultado terminal, explique somente o motivo retornado, não declare sucesso, não invente alternativa e encerre a resposta.", + "Você é um agente especialista em faturas. Responda com clareza, objetividade e sem sugerir ações não solicitadas. Use dados MCP quando disponíveis.", ), mcp_results=tool_context, rag_context=rag_context, diff --git a/Tuning-Performance/Deterministic_Transactional_Workflow/agent_template_backend/app/agents/orders_agent.py b/Tuning-Performance/Deterministic_Transactional_Workflow/agent_template_backend/app/agents/orders_agent.py index b793c26..f557bed 100644 --- a/Tuning-Performance/Deterministic_Transactional_Workflow/agent_template_backend/app/agents/orders_agent.py +++ b/Tuning-Performance/Deterministic_Transactional_Workflow/agent_template_backend/app/agents/orders_agent.py @@ -95,7 +95,7 @@ class OrdersAgent(AgentRuntimeMixin): state, system_prompt=apply_agent_profile_prompt( state, - "Você é um agente de pedidos de varejo.\n\nUse dados de tools/MCP e RAG autorizados como fonte de verdade e responda somente à solicitação atual.\nNunca exponha identificadores técnicos ou de identidade presentes no estado, contexto ou MCP, incluindo customer_key, contract_key, account_key, resource_key, session_key, customer_id, document, message_id, ura_call_id ou telefone completo.\nNão transforme nomes internos de campos em rótulos para o cliente.\nNão declare sucesso, alteração, troca, cancelamento ou qualquer mutação se a tool não tiver confirmado a execução.\nNão acrescente canais, procedimentos, ofertas ou próximos passos não solicitados.\nSe uma tool retornar BLOCKED, OUT_OF_SCOPE, NOT_ALLOWED, FAILED ou outro resultado terminal, explique somente o motivo retornado, não invente alternativa e encerre a resposta.", + "Você é um agente de pedidos de varejo. Use dados de tools quando disponíveis.", ), mcp_results=tool_context, rag_context=rag_context, diff --git a/Tuning-Performance/Deterministic_Transactional_Workflow/agent_template_backend/app/agents/product_agent.py b/Tuning-Performance/Deterministic_Transactional_Workflow/agent_template_backend/app/agents/product_agent.py index 998dad6..34433f5 100644 --- a/Tuning-Performance/Deterministic_Transactional_Workflow/agent_template_backend/app/agents/product_agent.py +++ b/Tuning-Performance/Deterministic_Transactional_Workflow/agent_template_backend/app/agents/product_agent.py @@ -95,7 +95,7 @@ class ProductAgent(AgentRuntimeMixin): state, system_prompt=apply_agent_profile_prompt( state, - "Você é um agente especialista em produtos, planos e serviços.\n\nUse dados de tools/MCP e RAG autorizados como fonte de verdade e responda somente à solicitação atual.\nNunca exponha identificadores técnicos ou de identidade presentes no estado, contexto ou MCP, incluindo customer_key, contract_key, account_key, resource_key, session_key, customer_id, document, message_id, ura_call_id ou MSISDN/telefone completo.\nNão transforme nomes internos de campos em rótulos para o cliente.\nEm consultas meramente informativas, não exponha flags ou capacidades transacionais internas como can.cancel e não informe espontaneamente que algo pode ser cancelado, alterado, contratado, removido ou trocado. Só mencione capacidade transacional quando o usuário tiver solicitado essa ação.\nNão faça oferta proativa e não execute nem simule mutações sem a confirmação exigida pelo framework.\nNão acrescente canais, procedimentos ou próximos passos não solicitados.\nSe uma tool retornar BLOCKED, OUT_OF_SCOPE, NOT_ALLOWED, FAILED ou outro resultado terminal, explique somente o motivo retornado, não declare sucesso, não invente alternativa e encerre a resposta.", + "Você é um agente especialista em produtos, planos e serviços. Explique sem fazer oferta proativa e sem executar ações sem confirmação. Use dados MCP quando disponíveis.", ), mcp_results=tool_context, rag_context=rag_context, diff --git a/Tuning-Performance/Deterministic_Transactional_Workflow/agent_template_backend/app/agents/support_agent.py b/Tuning-Performance/Deterministic_Transactional_Workflow/agent_template_backend/app/agents/support_agent.py index b15a0e4..b4f0244 100644 --- a/Tuning-Performance/Deterministic_Transactional_Workflow/agent_template_backend/app/agents/support_agent.py +++ b/Tuning-Performance/Deterministic_Transactional_Workflow/agent_template_backend/app/agents/support_agent.py @@ -95,7 +95,7 @@ class SupportAgent(AgentRuntimeMixin): state, system_prompt=apply_agent_profile_prompt( state, - "Você é um agente de suporte de varejo para troca, devolução e garantia.\n\nUse dados de tools/MCP e RAG autorizados como fonte de verdade e responda somente à solicitação atual.\nNunca exponha identificadores técnicos ou de identidade presentes no estado, contexto ou MCP, incluindo customer_key, contract_key, account_key, resource_key, session_key, customer_id, document, message_id, ura_call_id ou telefone completo.\nNão transforme nomes internos de campos em rótulos para o cliente.\nNão declare sucesso nem simule troca, devolução, garantia ou outra mutação se a tool não tiver confirmado a execução.\nNão acrescente canais, procedimentos, ofertas ou próximos passos não solicitados.\nSe uma tool retornar BLOCKED, OUT_OF_SCOPE, NOT_ALLOWED, FAILED ou outro resultado terminal, explique somente o motivo retornado, não invente alternativa e encerre a resposta.", + "Você é um agente de suporte de varejo para troca, devolução e garantia.", ), mcp_results=tool_context, rag_context=rag_context, diff --git a/Tuning-Performance/Deterministic_Transactional_Workflow/agent_template_backend/app/presentation/__pycache__/tool_renderers.cpython-313.pyc b/Tuning-Performance/Deterministic_Transactional_Workflow/agent_template_backend/app/presentation/__pycache__/tool_renderers.cpython-313.pyc index 79a8274a69f01c26de313e79379329b613dc9359..009b7c12fbc13a60978eabb33f4e2eeba0d9df9c 100644 GIT binary patch delta 810 zcmZ`%&rcIU6yE9XwrfiZ+8w3_RWaGr)=yX8Vzgk z&6l5Tj7L7i-l37bLfz$s3gM(c)*Y9ZZO`R|m4Q37YL}_Q8lKCX^5&J+7i6GC6VB_J zh7J-yUTZ68RgY;afmH;kkDECyZ!Af)<|j*df$%0J7%H-6jgtx~Vj6-|??EF1)_Ic| z5Q!&N_Ur(VURX?#r`nHbY-f9?-X0p;P3>AAQ9Dv>8^zW{_yMwIkZ~x?e8cwY*w^vm z4L{V~!hT@1YmwKbzV2`tB#nmSR;01vRo%QrRns)7Af=#R!4QBn8-#L3ht)<#{ECd2 zS)g$-*z*>pTYEh}11KZj^qwin$R??Iw9GwDYJT5+72r-##LGD>%_?_XCXZDdX2Sr9 zCk@xDJ5pzln)$$z)cnvbr6@wPQ&=JlU7b{}rvSwFP z3NLmBA60oZ{Xelv)#huA(@{L@Zk4*XF|X2{E9nU5AoRna!H@Bh=Q{ZSofG@1<>{lW zmES*q#nfAp)^y#gG;7Wby$vCP#V&|a|3C(zsY5G*vWLS-G;}x?M#0~M2D*!=`o+J2 CJHv$l delta 1950 zcmZ`(T}%{L6u!g$&+aUX%OWlU*X5@yA}cNeF4mv=6QF>`&1xbVGVTs^5N5V_W=%m2 zyj9vJti5fd+NLy`79W~wcxWGdFyW;SeOR+rx6?E=X>4L&w2?Lq=|j)mb)~U(9=^Hv zobTN8opXO~1!&0qR1kOspYdIK>{riC_vf5@J~W}|p@gW5A#r5K($AcktFi;dgb?>M z0r(+`axs$|MN7h_5JyGp2KvCs({G)Xw9MRUvz)3yC}yU6?d9!J+mMAV&%T&tJ69M% zs6A{d&M=BuqmFLyiN0cBAj-$A|DoAlqbXoO zZOwe51fc;xn0R{IV6QEGZgIt&kP<|TEb;_Iy5bw@tM*RrEMVoH zm=ltF{#Bx@80tp?6Wff0r(rAh>qliaDJw?P;p6^WnT^^C+VnQX7hV|v^aYc@+TIg_ZFHVAqEvI2c z#Yu5;Ton^|VBcZflvD|p-jXJg<0_ueWG$hz@bQ$ULwYhSCt7eqji;CtEa6irO;#jr zTEnNMNiB$#<*O_|3KV8o@>!=W`Sn(9y^IyXt0mp|5j*(? zhl38oG%D$aRZJ#fPl$(^c^T^0bV?mQ!7z`hvSOIVB_$}(X45N`hGm>}$FSt3l5&V3 za8D5Z(NVq8a27Nqby-!28_b#jfZ0bM3l;PYlV@NXSlC(7-T@Ue=!pw?%FEvt_}VzMSBlJ3f1S-kudU%^alf@pTbf z*}Ok%tIOGiIoGT!eQu#|VdvtT8DHC7`?j1-NFUGIYS)|x7rGYPGQKT$?X3^!SA6rd zw|YKtZU235@Qye5gQqg*ulcm;qo#%KtUq+$zwbu-*IhTezB!l;@4N7NuDtS6&&8hk zW7+bC3kPzg{`s+NX%h=7EuTG~^VHn;G~DqtT#GMm&Ng=3^K?Eanii`Tg&VP3k=s(X zyFU{d$TSY#^Bnr!hkPdgpB1#-8K_;cquRhi!x4)ZfML>3r^tFXt!4mkDk2yF(yr-X=ZDlW zsAtf?fE|E>K-WtJMwp+SAku;$F=4L`X=M;%uoZy*nwMjK63SQBJB_+8<`TrBr22t(~NwsUG#flkEIW&C#c{3J{P86x_|StQ%P7?2unnm zo4m##OmCJ3Ed4N)X|8m~bQng1L393e6EjQ str: def render_telecom_invoice(*, tool_name: str, result: dict[str, Any], state: dict[str, Any], agent_label: str) -> str | None: - """Renderiza somente campos de negócio seguros da fatura. - - Identificadores técnicos/PII presentes no payload MCP (por exemplo msisdn, - customer_id, document e business keys) não devem ser propagados ao usuário. - """ - lines = [f"[{agent_label}] Dados da sua fatura:"] - total = result.get("valor_total") - vencimento = result.get("vencimento") - status = result.get("status") - if total is not None: - lines.append(f"Valor total: R$ {_money_brl(total)}.") - if vencimento not in (None, ""): - lines.append(f"Vencimento: {vencimento}.") - if status not in (None, ""): - lines.append(f"Situação: {status}.") - - items = result.get("itens") or [] - rendered_items: list[str] = [] - if isinstance(items, list): - for item in items: - if not isinstance(item, dict): - continue - description = item.get("descricao") or item.get("nome") - value = item.get("valor") - if description in (None, ""): - continue - if value is None: - rendered_items.append(str(description)) - else: - rendered_items.append(f"{description}: R$ {_money_brl(value)}") - if rendered_items: - lines.append("Itens: " + "; ".join(rendered_items) + ".") - - # Se não houver nenhum campo de negócio seguro além do cabeçalho, deixe a - # composição pela LLM/guardrails em vez de despejar o payload bruto. - return " ".join(lines) if len(lines) > 1 else None + return f"[{agent_label}] Fatura consultada: {result}." def render_telecom_plan(*, tool_name: str, result: dict[str, Any], state: dict[str, Any], agent_label: str) -> str | None: diff --git a/Tuning-Performance/Deterministic_Transactional_Workflow/agent_template_backend/app/workflows/__pycache__/agent_graph.cpython-313.pyc b/Tuning-Performance/Deterministic_Transactional_Workflow/agent_template_backend/app/workflows/__pycache__/agent_graph.cpython-313.pyc index 192132da76d083548dc4bd252d3c7d07840e493f..49ad6af0646e5fddea4a1552840095a8f46cfdcf 100644 GIT binary patch delta 7884 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 delta 11176 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 diff --git a/Tuning-Performance/Deterministic_Transactional_Workflow/agent_template_backend/app/workflows/agent_graph.py b/Tuning-Performance/Deterministic_Transactional_Workflow/agent_template_backend/app/workflows/agent_graph.py index 303bf51..ed17e04 100644 --- a/Tuning-Performance/Deterministic_Transactional_Workflow/agent_template_backend/app/workflows/agent_graph.py +++ b/Tuning-Performance/Deterministic_Transactional_Workflow/agent_template_backend/app/workflows/agent_graph.py @@ -160,7 +160,7 @@ class AgentWorkflow: builder.add_conditional_edges( "input_guardrails", self._after_input_guardrails, - {"blocked": "persist", "continue": "load_long_term_memory"}, + {"blocked": "output_guardrails", "continue": "load_long_term_memory"}, ) builder.add_edge("load_long_term_memory", "routing_decision") builder.add_conditional_edges( @@ -197,6 +197,31 @@ class AgentWorkflow: def _after_input_guardrails(self, state): return "blocked" if state.get("blocked") else "continue" + @staticmethod + def _input_guardrail_user_message(decisions, state, sanitized_text): + # Keep the technical guardrail reason in telemetry, but expose only a + # safe, actionable message to the end user. The message is intentionally + # routed through output_guardrails before persistence/delivery. + blocked = [d for d in decisions if not getattr(d, "allowed", True)] + first = blocked[0] if blocked else None + code = str(getattr(first, "code", "") or "").upper() + if code == "COER": + return ( + "Não consegui entender sua última mensagem porque ela parece " + "incompleta ou ambígua. Pode reformular ou completar o que você quis dizer?" + ) + if code == "INPUT_SIZE": + return "Sua mensagem ficou muito longa para eu processar de uma vez. Pode resumir ou dividir em partes?" + if code == "DLEX_IN": + return "Não posso usar essa informação da forma solicitada. Reformule o pedido sem incluir dados ou conteúdo restrito." + if code == "PINJ": + return "Não posso seguir instruções que tentem alterar as regras do atendimento. Posso continuar ajudando com a sua solicitação." + if code == "TOX": + return "Não consegui prosseguir com essa mensagem. Pode reformular o pedido para continuarmos o atendimento?" + if code == "CMP": + return "Não posso prosseguir com essa solicitação dessa forma. Posso ajudar com uma alternativa permitida." + return "Não consegui processar essa mensagem. Pode reformular para eu continuar o atendimento?" + async def input_guardrails(self, state): if state.get("session_ended") is True: answer = str(getattr( @@ -281,12 +306,33 @@ class AgentWorkflow: component="workflow.input_guardrails.final", ) if any(not d.allowed for d in decisions): + # A blocking input guardrail stops the turn before routing/tools. + # Clear turn-local routing/tool state so stale data from a prior + # turn cannot appear as if it was executed after the block. + user_message = self._input_guardrail_user_message(decisions, state, sanitized) return { "sanitized_input": sanitized, - "answer": "Não consegui seguir com essa mensagem por regra de segurança.", - "final_answer": "Não consegui seguir com essa mensagem por regra de segurança.", + "answer": user_message, + "final_answer": None, "guardrail_decisions": [d.model_dump() for d in decisions], "route": "blocked", + "intent": "input_guardrail_blocked", + "route_decision": { + "route": "blocked", + "agent": None, + "intent": "input_guardrail_blocked", + "confidence": 1.0, + "reason": "Entrada interrompida por guardrail antes do roteamento.", + "method": "guardrail", + "next_state": state.get("next_state"), + "handoff": False, + "metadata": {}, + "domain": state.get("domain"), + "mcp_tools": [], + }, + "mcp_tools": [], + "mcp_results": [], + "judge_results": [], "blocked": True, } return { @@ -494,119 +540,6 @@ class AgentWorkflow: "next_state": "SESSION_ENDED", } - @staticmethod - def _output_guardrail_context(state: dict) -> dict: - """Monta o contexto operacional do turno para os guardrails de saída. - - Mantém evidências/protocolos necessários aos rails, mas impede que uma - transação encerrada ou semanticamente interrompida governe o novo turno. - O histórico completo permanece no state/checkpoint para auditoria. - """ - ctx = dict(state.get("context", {}) or {}) - mcp_results = state.get("mcp_results") or [] - ctx["evidence"] = mcp_results or ctx.get("evidence") - ctx["tool_result"] = mcp_results or ctx.get("tool_result") - ctx["tool_executed"] = any(isinstance(r, dict) and r.get("ok") for r in mcp_results) - - history = list(state.get("history") or []) - current_user_text = str(state.get("user_text") or "").strip() - if current_user_text: - if ( - not history - or not isinstance(history[-1], dict) - or str(history[-1].get("content") or "") != current_user_text - or str(history[-1].get("role") or "") != "user" - ): - history.append({"role": "user", "content": current_user_text}) - - route_decision = state.get("route_decision") or {} - route_metadata = route_decision.get("metadata") if isinstance(route_decision, dict) else {} - route_metadata = route_metadata if isinstance(route_metadata, dict) else {} - pre_validation = state.get("transaction_pre_validation") or {} - pre_validation = pre_validation if isinstance(pre_validation, dict) else {} - tx_status = str( - state.get("transaction_status") or pre_validation.get("status") or "" - ).strip().upper() - terminal_tx = bool(pre_validation.get("terminal")) or tx_status in { - "COMPLETED", "FAILED", "CANCELLED", "BLOCKED", "OUT_OF_SCOPE" - } - semantic_intent_shift = ( - str(route_metadata.get("transaction_interruption") or "").strip().lower() - == "intent_shift" - ) - stickiness_intent_shift = bool(route_metadata.get("route_stickiness_preempted")) - should_isolate_history = semantic_intent_shift or (terminal_tx and stickiness_intent_shift) - - current_route = str( - state.get("route") - or (route_decision.get("route") if isinstance(route_decision, dict) else "") - or "" - ).strip() - current_intent = str( - state.get("intent") - or (route_decision.get("intent") if isinstance(route_decision, dict) else "") - or "" - ).strip() - ctx["current_user_message"] = current_user_text - ctx["current_route"] = current_route - ctx["current_intent"] = current_intent - - if should_isolate_history: - operational_history = ( - [{"role": "user", "content": current_user_text}] - if current_user_text else [] - ) - ctx["historical_transaction_ignored"] = True - ctx["historical_transaction_status"] = tx_status or ( - "INTERRUPTED" if semantic_intent_shift else "TERMINAL" - ) - if semantic_intent_shift: - ctx["historical_transaction_interruption"] = "intent_shift" - for stale_key in ( - "transaction_pre_validation", - "transaction_status", - "active_transaction", - "transaction", - ): - ctx.pop(stale_key, None) - else: - operational_history = history - - ctx["conversation_history"] = operational_history - ctx["history_texts"] = [ - str(item.get("content") or "") - for item in operational_history - if isinstance(item, dict) and item.get("content") not in (None, "") - ] - - protocols: list[str] = [] - seen: set[str] = set() - protocol_keys = { - "protocol_number", "protocolo_id", "interactionProtocol", - "protocolNumber", "finalizacao_protocol", - } - - def walk(value): - if isinstance(value, dict): - for key, item in value.items(): - if key in protocol_keys and item not in (None, ""): - text = str(item).strip() - if text and text not in seen: - seen.add(text) - protocols.append(text) - elif isinstance(item, (dict, list, tuple)): - walk(item) - elif isinstance(value, (list, tuple)): - for item in value: - walk(item) - - walk(mcp_results) - if protocols: - ctx["expected_protocols"] = protocols - ctx["requer_protocolo"] = True - ctx.setdefault("tipo_fluxo", "ajuste") - return ctx - async def output_supervisor(self, state): """Valida a resposta candidata com o OutputSupervisor corporativo. @@ -622,15 +555,15 @@ class AgentWorkflow: } candidate = state.get("answer") or "" - context = self._output_guardrail_context(state) - context.update({ + context = { + **(state.get("context") or {}), "tenant_id": state.get("tenant_id"), "agent_id": state.get("agent_id"), "session_id": state.get("conversation_key") or state.get("session_id"), "route": state.get("route"), "intent": state.get("intent"), "supervisor_attempt": int(state.get("supervisor_attempt", 0)), - }) + } async with self.telemetry.span( "workflow.output_supervisor", session_id=state.get("conversation_key") or state.get("session_id"), @@ -716,7 +649,7 @@ class AgentWorkflow: component="workflow.output_guardrails.start", ) final, decisions = await self.guardrails.run_output( - state["answer"], self._output_guardrail_context(state) + state["answer"], state.get("context", {}) ) for _decision in decisions: await self.guardrail_telemetry.evaluated("output", _decision) diff --git a/Tuning-Performance/Deterministic_Transactional_Workflow/agent_template_backend/config/routing.yaml b/Tuning-Performance/Deterministic_Transactional_Workflow/agent_template_backend/config/routing.yaml index 03aeaa9..bb4ef6f 100644 --- a/Tuning-Performance/Deterministic_Transactional_Workflow/agent_template_backend/config/routing.yaml +++ b/Tuning-Performance/Deterministic_Transactional_Workflow/agent_template_backend/config/routing.yaml @@ -7,6 +7,35 @@ router: confidence_threshold: 0.65 allow_handoff: true + transaction_confirmation: + # Explicit yes/no stays deterministic. Only inconclusive replies use this LLM fallback. + semantic_fallback: + enabled: true + allowed_values: [SIM, NAO, CONTINUAR] + confirm_values: [SIM] + reject_values: [NAO] + continue_values: [CONTINUAR] + include_relevant_context: true + profile_name: router + prompt: | + Você classifica a resposta do cliente a uma confirmação transacional pendente. + Considere a pergunta pendente, somente o histórico recente relacionado ao mesmo tema e a fala atual. + Não execute a ação e não invente fatos. + + Classes permitidas: {{ allowed_values }} + - SIM: confirmação/aceite inequívoco, inclusive equivalentes como "isso mesmo", "pode confirmar", "é isso" quando o contexto tornar o aceite claro. + - NAO: recusa/cancelamento inequívoco da ação pendente. + - CONTINUAR: qualquer resposta que não confirme nem rejeite inequivocamente, incluindo pergunta adicional, correção, novo dado, ambiguidade ou possível mudança de assunto. + + Pergunta pendente: + {{ pending_prompt }} + + Histórico relevante: + {{ relevant_conversation_context }} + + Resposta atual do cliente: + {{ user_input }} + state_policies: - state: WAITING_BILLING_CONFIRMATION agent: billing_agent diff --git a/Tuning-Performance/Deterministic_Transactional_Workflow/agent_template_backend/docs/TRANSACTION_SEMANTIC_CONFIRMATION.md b/Tuning-Performance/Deterministic_Transactional_Workflow/agent_template_backend/docs/TRANSACTION_SEMANTIC_CONFIRMATION.md new file mode 100644 index 0000000..a550871 --- /dev/null +++ b/Tuning-Performance/Deterministic_Transactional_Workflow/agent_template_backend/docs/TRANSACTION_SEMANTIC_CONFIRMATION.md @@ -0,0 +1,11 @@ +# Confirmação Transacional Semântica + +Este template suporta confirmação transacional em duas camadas: primeiro um parser determinístico para `sim`/`não` e equivalentes explícitos; somente quando ele não consegue decidir, o framework usa um classificador semântico configurado em `config/routing.yaml`. + +A configuração `router.transaction_confirmation.semantic_fallback` usa três classes: `SIM`, `NAO` e `CONTINUAR`. O prompt pode usar `{{ pending_prompt }}`, `{{ relevant_conversation_context }}`, `{{ user_input }}` e `{{ allowed_values }}`. O histórico injetado é apenas contexto de interpretação; não substitui validação de negócio ou evidência MCP. + +Exemplo: após `Você confirma o cancelamento do serviço Tamboro Mensal?`, a frase `isso mesmo, pode confirmar` pode ser classificada como `SIM`. Já `mas qual é o valor?` deve ser `CONTINUAR`, portanto não executa a ação por confirmação. + +Entradas explícitas já suportadas continuam no caminho determinístico e não geram custo adicional de LLM. Em observabilidade, o fallback usa `transaction.confirmation.semantic_classifier` e o `route_decision.metadata` informa `transaction_confirmation_source: semantic`. + +Consulte `docs/developer/pt/03_transaction_workflows_and_state.md` do framework para o contrato completo e exemplos. diff --git a/Tuning-Performance/External_Guardrails_Judges/agent_template_backend/app/agents/billing_agent.py b/Tuning-Performance/External_Guardrails_Judges/agent_template_backend/app/agents/billing_agent.py index 05254d1..aa60099 100644 --- a/Tuning-Performance/External_Guardrails_Judges/agent_template_backend/app/agents/billing_agent.py +++ b/Tuning-Performance/External_Guardrails_Judges/agent_template_backend/app/agents/billing_agent.py @@ -95,7 +95,7 @@ class BillingAgent(AgentRuntimeMixin): state, system_prompt=apply_agent_profile_prompt( state, - "Você é um agente especialista em faturas.\n\nUse dados de tools/MCP e RAG autorizados como fonte de verdade para responder somente à solicitação atual.\nNunca exponha identificadores técnicos ou de identidade presentes no estado, contexto ou MCP, incluindo customer_key, contract_key, account_key, resource_key, session_key, customer_id, document, message_id, ura_call_id ou MSISDN/telefone completo.\nNão transforme nomes internos de campos em rótulos para o cliente, como “contract_key”, “customer_key” ou “MSISDN”.\nPara consultas informativas de fatura, apresente somente dados de negócio necessários, como valor, vencimento, situação e itens cobrados.\nNão acrescente canais, telefones, códigos USSD, URLs, aplicativos, lojas, relatórios adicionais, procedimentos alternativos ou próximos passos que não tenham sido explicitamente retornados pela tool/RAG e solicitados pelo usuário.\nNão ofereça espontaneamente outras ações ou detalhamentos.\nSe uma tool retornar BLOCKED, OUT_OF_SCOPE, NOT_ALLOWED, FAILED ou outro resultado terminal, explique somente o motivo retornado, não declare sucesso, não invente alternativa e encerre a resposta.", + "Você é um agente especialista em faturas. Responda com clareza, objetividade e sem sugerir ações não solicitadas. Use dados MCP quando disponíveis.", ), mcp_results=tool_context, rag_context=rag_context, diff --git a/Tuning-Performance/External_Guardrails_Judges/agent_template_backend/app/agents/orders_agent.py b/Tuning-Performance/External_Guardrails_Judges/agent_template_backend/app/agents/orders_agent.py index b793c26..f557bed 100644 --- a/Tuning-Performance/External_Guardrails_Judges/agent_template_backend/app/agents/orders_agent.py +++ b/Tuning-Performance/External_Guardrails_Judges/agent_template_backend/app/agents/orders_agent.py @@ -95,7 +95,7 @@ class OrdersAgent(AgentRuntimeMixin): state, system_prompt=apply_agent_profile_prompt( state, - "Você é um agente de pedidos de varejo.\n\nUse dados de tools/MCP e RAG autorizados como fonte de verdade e responda somente à solicitação atual.\nNunca exponha identificadores técnicos ou de identidade presentes no estado, contexto ou MCP, incluindo customer_key, contract_key, account_key, resource_key, session_key, customer_id, document, message_id, ura_call_id ou telefone completo.\nNão transforme nomes internos de campos em rótulos para o cliente.\nNão declare sucesso, alteração, troca, cancelamento ou qualquer mutação se a tool não tiver confirmado a execução.\nNão acrescente canais, procedimentos, ofertas ou próximos passos não solicitados.\nSe uma tool retornar BLOCKED, OUT_OF_SCOPE, NOT_ALLOWED, FAILED ou outro resultado terminal, explique somente o motivo retornado, não invente alternativa e encerre a resposta.", + "Você é um agente de pedidos de varejo. Use dados de tools quando disponíveis.", ), mcp_results=tool_context, rag_context=rag_context, diff --git a/Tuning-Performance/External_Guardrails_Judges/agent_template_backend/app/agents/product_agent.py b/Tuning-Performance/External_Guardrails_Judges/agent_template_backend/app/agents/product_agent.py index 998dad6..34433f5 100644 --- a/Tuning-Performance/External_Guardrails_Judges/agent_template_backend/app/agents/product_agent.py +++ b/Tuning-Performance/External_Guardrails_Judges/agent_template_backend/app/agents/product_agent.py @@ -95,7 +95,7 @@ class ProductAgent(AgentRuntimeMixin): state, system_prompt=apply_agent_profile_prompt( state, - "Você é um agente especialista em produtos, planos e serviços.\n\nUse dados de tools/MCP e RAG autorizados como fonte de verdade e responda somente à solicitação atual.\nNunca exponha identificadores técnicos ou de identidade presentes no estado, contexto ou MCP, incluindo customer_key, contract_key, account_key, resource_key, session_key, customer_id, document, message_id, ura_call_id ou MSISDN/telefone completo.\nNão transforme nomes internos de campos em rótulos para o cliente.\nEm consultas meramente informativas, não exponha flags ou capacidades transacionais internas como can.cancel e não informe espontaneamente que algo pode ser cancelado, alterado, contratado, removido ou trocado. Só mencione capacidade transacional quando o usuário tiver solicitado essa ação.\nNão faça oferta proativa e não execute nem simule mutações sem a confirmação exigida pelo framework.\nNão acrescente canais, procedimentos ou próximos passos não solicitados.\nSe uma tool retornar BLOCKED, OUT_OF_SCOPE, NOT_ALLOWED, FAILED ou outro resultado terminal, explique somente o motivo retornado, não declare sucesso, não invente alternativa e encerre a resposta.", + "Você é um agente especialista em produtos, planos e serviços. Explique sem fazer oferta proativa e sem executar ações sem confirmação. Use dados MCP quando disponíveis.", ), mcp_results=tool_context, rag_context=rag_context, diff --git a/Tuning-Performance/External_Guardrails_Judges/agent_template_backend/app/agents/support_agent.py b/Tuning-Performance/External_Guardrails_Judges/agent_template_backend/app/agents/support_agent.py index b15a0e4..b4f0244 100644 --- a/Tuning-Performance/External_Guardrails_Judges/agent_template_backend/app/agents/support_agent.py +++ b/Tuning-Performance/External_Guardrails_Judges/agent_template_backend/app/agents/support_agent.py @@ -95,7 +95,7 @@ class SupportAgent(AgentRuntimeMixin): state, system_prompt=apply_agent_profile_prompt( state, - "Você é um agente de suporte de varejo para troca, devolução e garantia.\n\nUse dados de tools/MCP e RAG autorizados como fonte de verdade e responda somente à solicitação atual.\nNunca exponha identificadores técnicos ou de identidade presentes no estado, contexto ou MCP, incluindo customer_key, contract_key, account_key, resource_key, session_key, customer_id, document, message_id, ura_call_id ou telefone completo.\nNão transforme nomes internos de campos em rótulos para o cliente.\nNão declare sucesso nem simule troca, devolução, garantia ou outra mutação se a tool não tiver confirmado a execução.\nNão acrescente canais, procedimentos, ofertas ou próximos passos não solicitados.\nSe uma tool retornar BLOCKED, OUT_OF_SCOPE, NOT_ALLOWED, FAILED ou outro resultado terminal, explique somente o motivo retornado, não invente alternativa e encerre a resposta.", + "Você é um agente de suporte de varejo para troca, devolução e garantia.", ), mcp_results=tool_context, rag_context=rag_context, diff --git a/Tuning-Performance/External_Guardrails_Judges/agent_template_backend/app/presentation/tool_renderers.py b/Tuning-Performance/External_Guardrails_Judges/agent_template_backend/app/presentation/tool_renderers.py index cb44202..f77c47a 100644 --- a/Tuning-Performance/External_Guardrails_Judges/agent_template_backend/app/presentation/tool_renderers.py +++ b/Tuning-Performance/External_Guardrails_Judges/agent_template_backend/app/presentation/tool_renderers.py @@ -13,42 +13,7 @@ def _money_brl(value: Any) -> str: def render_telecom_invoice(*, tool_name: str, result: dict[str, Any], state: dict[str, Any], agent_label: str) -> str | None: - """Renderiza somente campos de negócio seguros da fatura. - - Identificadores técnicos/PII presentes no payload MCP (por exemplo msisdn, - customer_id, document e business keys) não devem ser propagados ao usuário. - """ - lines = [f"[{agent_label}] Dados da sua fatura:"] - total = result.get("valor_total") - vencimento = result.get("vencimento") - status = result.get("status") - if total is not None: - lines.append(f"Valor total: R$ {_money_brl(total)}.") - if vencimento not in (None, ""): - lines.append(f"Vencimento: {vencimento}.") - if status not in (None, ""): - lines.append(f"Situação: {status}.") - - items = result.get("itens") or [] - rendered_items: list[str] = [] - if isinstance(items, list): - for item in items: - if not isinstance(item, dict): - continue - description = item.get("descricao") or item.get("nome") - value = item.get("valor") - if description in (None, ""): - continue - if value is None: - rendered_items.append(str(description)) - else: - rendered_items.append(f"{description}: R$ {_money_brl(value)}") - if rendered_items: - lines.append("Itens: " + "; ".join(rendered_items) + ".") - - # Se não houver nenhum campo de negócio seguro além do cabeçalho, deixe a - # composição pela LLM/guardrails em vez de despejar o payload bruto. - return " ".join(lines) if len(lines) > 1 else None + return f"[{agent_label}] Fatura consultada: {result}." def render_telecom_plan(*, tool_name: str, result: dict[str, Any], state: dict[str, Any], agent_label: str) -> str | None: diff --git a/Tuning-Performance/External_Guardrails_Judges/agent_template_backend/app/workflows/__pycache__/agent_graph.cpython-313.pyc b/Tuning-Performance/External_Guardrails_Judges/agent_template_backend/app/workflows/__pycache__/agent_graph.cpython-313.pyc index 7e370465aefd0ee85dd21f4b866a0082c54b18fd..d345c8b99ebaa89d672fabcfb7a50b936582abb3 100644 GIT binary patch delta 7377 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 UkVnq%$cL|mimy@#h4j+@0;G0*U;qFB diff --git a/Tuning-Performance/External_Guardrails_Judges/agent_template_backend/app/workflows/agent_graph.py b/Tuning-Performance/External_Guardrails_Judges/agent_template_backend/app/workflows/agent_graph.py index 2cb86e1..fc29245 100644 --- a/Tuning-Performance/External_Guardrails_Judges/agent_template_backend/app/workflows/agent_graph.py +++ b/Tuning-Performance/External_Guardrails_Judges/agent_template_backend/app/workflows/agent_graph.py @@ -159,7 +159,7 @@ class AgentWorkflow: builder.add_conditional_edges( "input_guardrails", self._after_input_guardrails, - {"blocked": "persist", "continue": "routing_decision"}, + {"blocked": "output_guardrails", "continue": "routing_decision"}, ) builder.add_conditional_edges( "routing_decision", @@ -195,6 +195,31 @@ class AgentWorkflow: def _after_input_guardrails(self, state): return "blocked" if state.get("blocked") else "continue" + @staticmethod + def _input_guardrail_user_message(decisions, state, sanitized_text): + # Keep the technical guardrail reason in telemetry, but expose only a + # safe, actionable message to the end user. The message is intentionally + # routed through output_guardrails before persistence/delivery. + blocked = [d for d in decisions if not getattr(d, "allowed", True)] + first = blocked[0] if blocked else None + code = str(getattr(first, "code", "") or "").upper() + if code == "COER": + return ( + "Não consegui entender sua última mensagem porque ela parece " + "incompleta ou ambígua. Pode reformular ou completar o que você quis dizer?" + ) + if code == "INPUT_SIZE": + return "Sua mensagem ficou muito longa para eu processar de uma vez. Pode resumir ou dividir em partes?" + if code == "DLEX_IN": + return "Não posso usar essa informação da forma solicitada. Reformule o pedido sem incluir dados ou conteúdo restrito." + if code == "PINJ": + return "Não posso seguir instruções que tentem alterar as regras do atendimento. Posso continuar ajudando com a sua solicitação." + if code == "TOX": + return "Não consegui prosseguir com essa mensagem. Pode reformular o pedido para continuarmos o atendimento?" + if code == "CMP": + return "Não posso prosseguir com essa solicitação dessa forma. Posso ajudar com uma alternativa permitida." + return "Não consegui processar essa mensagem. Pode reformular para eu continuar o atendimento?" + async def input_guardrails(self, state): if state.get("session_ended") is True: answer = str(getattr( @@ -279,12 +304,33 @@ class AgentWorkflow: component="workflow.input_guardrails.final", ) if any(not d.allowed for d in decisions): + # A blocking input guardrail stops the turn before routing/tools. + # Clear turn-local routing/tool state so stale data from a prior + # turn cannot appear as if it was executed after the block. + user_message = self._input_guardrail_user_message(decisions, state, sanitized) return { "sanitized_input": sanitized, - "answer": "Não consegui seguir com essa mensagem por regra de segurança.", - "final_answer": "Não consegui seguir com essa mensagem por regra de segurança.", + "answer": user_message, + "final_answer": None, "guardrail_decisions": [d.model_dump() for d in decisions], "route": "blocked", + "intent": "input_guardrail_blocked", + "route_decision": { + "route": "blocked", + "agent": None, + "intent": "input_guardrail_blocked", + "confidence": 1.0, + "reason": "Entrada interrompida por guardrail antes do roteamento.", + "method": "guardrail", + "next_state": state.get("next_state"), + "handoff": False, + "metadata": {}, + "domain": state.get("domain"), + "mcp_tools": [], + }, + "mcp_tools": [], + "mcp_results": [], + "judge_results": [], "blocked": True, } return { @@ -492,119 +538,6 @@ class AgentWorkflow: "next_state": "SESSION_ENDED", } - @staticmethod - def _output_guardrail_context(state: dict) -> dict: - """Monta o contexto operacional do turno para os guardrails de saída. - - Mantém evidências/protocolos necessários aos rails, mas impede que uma - transação encerrada ou semanticamente interrompida governe o novo turno. - O histórico completo permanece no state/checkpoint para auditoria. - """ - ctx = dict(state.get("context", {}) or {}) - mcp_results = state.get("mcp_results") or [] - ctx["evidence"] = mcp_results or ctx.get("evidence") - ctx["tool_result"] = mcp_results or ctx.get("tool_result") - ctx["tool_executed"] = any(isinstance(r, dict) and r.get("ok") for r in mcp_results) - - history = list(state.get("history") or []) - current_user_text = str(state.get("user_text") or "").strip() - if current_user_text: - if ( - not history - or not isinstance(history[-1], dict) - or str(history[-1].get("content") or "") != current_user_text - or str(history[-1].get("role") or "") != "user" - ): - history.append({"role": "user", "content": current_user_text}) - - route_decision = state.get("route_decision") or {} - route_metadata = route_decision.get("metadata") if isinstance(route_decision, dict) else {} - route_metadata = route_metadata if isinstance(route_metadata, dict) else {} - pre_validation = state.get("transaction_pre_validation") or {} - pre_validation = pre_validation if isinstance(pre_validation, dict) else {} - tx_status = str( - state.get("transaction_status") or pre_validation.get("status") or "" - ).strip().upper() - terminal_tx = bool(pre_validation.get("terminal")) or tx_status in { - "COMPLETED", "FAILED", "CANCELLED", "BLOCKED", "OUT_OF_SCOPE" - } - semantic_intent_shift = ( - str(route_metadata.get("transaction_interruption") or "").strip().lower() - == "intent_shift" - ) - stickiness_intent_shift = bool(route_metadata.get("route_stickiness_preempted")) - should_isolate_history = semantic_intent_shift or (terminal_tx and stickiness_intent_shift) - - current_route = str( - state.get("route") - or (route_decision.get("route") if isinstance(route_decision, dict) else "") - or "" - ).strip() - current_intent = str( - state.get("intent") - or (route_decision.get("intent") if isinstance(route_decision, dict) else "") - or "" - ).strip() - ctx["current_user_message"] = current_user_text - ctx["current_route"] = current_route - ctx["current_intent"] = current_intent - - if should_isolate_history: - operational_history = ( - [{"role": "user", "content": current_user_text}] - if current_user_text else [] - ) - ctx["historical_transaction_ignored"] = True - ctx["historical_transaction_status"] = tx_status or ( - "INTERRUPTED" if semantic_intent_shift else "TERMINAL" - ) - if semantic_intent_shift: - ctx["historical_transaction_interruption"] = "intent_shift" - for stale_key in ( - "transaction_pre_validation", - "transaction_status", - "active_transaction", - "transaction", - ): - ctx.pop(stale_key, None) - else: - operational_history = history - - ctx["conversation_history"] = operational_history - ctx["history_texts"] = [ - str(item.get("content") or "") - for item in operational_history - if isinstance(item, dict) and item.get("content") not in (None, "") - ] - - protocols: list[str] = [] - seen: set[str] = set() - protocol_keys = { - "protocol_number", "protocolo_id", "interactionProtocol", - "protocolNumber", "finalizacao_protocol", - } - - def walk(value): - if isinstance(value, dict): - for key, item in value.items(): - if key in protocol_keys and item not in (None, ""): - text = str(item).strip() - if text and text not in seen: - seen.add(text) - protocols.append(text) - elif isinstance(item, (dict, list, tuple)): - walk(item) - elif isinstance(value, (list, tuple)): - for item in value: - walk(item) - - walk(mcp_results) - if protocols: - ctx["expected_protocols"] = protocols - ctx["requer_protocolo"] = True - ctx.setdefault("tipo_fluxo", "ajuste") - return ctx - async def output_supervisor(self, state): """Valida a resposta candidata com o OutputSupervisor corporativo. @@ -620,15 +553,15 @@ class AgentWorkflow: } candidate = state.get("answer") or "" - context = self._output_guardrail_context(state) - context.update({ + context = { + **(state.get("context") or {}), "tenant_id": state.get("tenant_id"), "agent_id": state.get("agent_id"), "session_id": state.get("conversation_key") or state.get("session_id"), "route": state.get("route"), "intent": state.get("intent"), "supervisor_attempt": int(state.get("supervisor_attempt", 0)), - }) + } async with self.telemetry.span( "workflow.output_supervisor", session_id=state.get("conversation_key") or state.get("session_id"), @@ -714,7 +647,7 @@ class AgentWorkflow: component="workflow.output_guardrails.start", ) final, decisions = await self.guardrails.run_output( - state["answer"], self._output_guardrail_context(state) + state["answer"], state.get("context", {}) ) for _decision in decisions: await self.guardrail_telemetry.evaluated("output", _decision) diff --git a/Tuning-Performance/External_Guardrails_Judges/agent_template_backend/config/routing.yaml b/Tuning-Performance/External_Guardrails_Judges/agent_template_backend/config/routing.yaml index 03aeaa9..bb4ef6f 100644 --- a/Tuning-Performance/External_Guardrails_Judges/agent_template_backend/config/routing.yaml +++ b/Tuning-Performance/External_Guardrails_Judges/agent_template_backend/config/routing.yaml @@ -7,6 +7,35 @@ router: confidence_threshold: 0.65 allow_handoff: true + transaction_confirmation: + # Explicit yes/no stays deterministic. Only inconclusive replies use this LLM fallback. + semantic_fallback: + enabled: true + allowed_values: [SIM, NAO, CONTINUAR] + confirm_values: [SIM] + reject_values: [NAO] + continue_values: [CONTINUAR] + include_relevant_context: true + profile_name: router + prompt: | + Você classifica a resposta do cliente a uma confirmação transacional pendente. + Considere a pergunta pendente, somente o histórico recente relacionado ao mesmo tema e a fala atual. + Não execute a ação e não invente fatos. + + Classes permitidas: {{ allowed_values }} + - SIM: confirmação/aceite inequívoco, inclusive equivalentes como "isso mesmo", "pode confirmar", "é isso" quando o contexto tornar o aceite claro. + - NAO: recusa/cancelamento inequívoco da ação pendente. + - CONTINUAR: qualquer resposta que não confirme nem rejeite inequivocamente, incluindo pergunta adicional, correção, novo dado, ambiguidade ou possível mudança de assunto. + + Pergunta pendente: + {{ pending_prompt }} + + Histórico relevante: + {{ relevant_conversation_context }} + + Resposta atual do cliente: + {{ user_input }} + state_policies: - state: WAITING_BILLING_CONFIRMATION agent: billing_agent diff --git a/Tuning-Performance/External_Guardrails_Judges/agent_template_backend/docs/TRANSACTION_SEMANTIC_CONFIRMATION.md b/Tuning-Performance/External_Guardrails_Judges/agent_template_backend/docs/TRANSACTION_SEMANTIC_CONFIRMATION.md new file mode 100644 index 0000000..a550871 --- /dev/null +++ b/Tuning-Performance/External_Guardrails_Judges/agent_template_backend/docs/TRANSACTION_SEMANTIC_CONFIRMATION.md @@ -0,0 +1,11 @@ +# Confirmação Transacional Semântica + +Este template suporta confirmação transacional em duas camadas: primeiro um parser determinístico para `sim`/`não` e equivalentes explícitos; somente quando ele não consegue decidir, o framework usa um classificador semântico configurado em `config/routing.yaml`. + +A configuração `router.transaction_confirmation.semantic_fallback` usa três classes: `SIM`, `NAO` e `CONTINUAR`. O prompt pode usar `{{ pending_prompt }}`, `{{ relevant_conversation_context }}`, `{{ user_input }}` e `{{ allowed_values }}`. O histórico injetado é apenas contexto de interpretação; não substitui validação de negócio ou evidência MCP. + +Exemplo: após `Você confirma o cancelamento do serviço Tamboro Mensal?`, a frase `isso mesmo, pode confirmar` pode ser classificada como `SIM`. Já `mas qual é o valor?` deve ser `CONTINUAR`, portanto não executa a ação por confirmação. + +Entradas explícitas já suportadas continuam no caminho determinístico e não geram custo adicional de LLM. Em observabilidade, o fallback usa `transaction.confirmation.semantic_classifier` e o `route_decision.metadata` informa `transaction_confirmation_source: semantic`. + +Consulte `docs/developer/pt/03_transaction_workflows_and_state.md` do framework para o contrato completo e exemplos. diff --git a/Tuning-Performance/Long_Term_Memory/templates/agent_template_backend/app/__pycache__/__init__.cpython-313.pyc b/Tuning-Performance/Long_Term_Memory/templates/agent_template_backend/app/__pycache__/__init__.cpython-313.pyc index 823d284146ce2f1f0d4687f6682c0ce3984f82bf..884409ed746324caa06d75871c191596fb69d6ae 100644 GIT binary patch delta 46 zcmcb^xRa6lGcPX}0}#y7&!5O`EE1ugn^&TrqVF5*86QxTpOu0O7k-F(sct;i_-Foauf5CQ}uoF^U~u(Qj2oqeN%Juiz+9k1p@#|$RiN| diff --git a/Tuning-Performance/Long_Term_Memory/templates/agent_template_backend/app/__pycache__/main.cpython-313.pyc b/Tuning-Performance/Long_Term_Memory/templates/agent_template_backend/app/__pycache__/main.cpython-313.pyc index baf5776751f8743d88b21ddc8377ab8fc6784898..7f097b787e7a971338ef60224ef4de3fe6916148 100644 GIT binary patch delta 29 jcmezJhq2=iBll-sUM>b8c#v7Jky~1rk$dxG;fGlOpM(kQ delta 120 zcmeD9!}#S7Bll-sUM>b8$Pwt<$So}#R<56$SE8SiSdyrpm}VJYo?n!$pO~JSR}!CA zl$e_e;>YJFXX=NP=4Ixk>jtD2rR5jpCgvrl>igv9rN@V)7UjnKrsn1sRqB_d<`(26 UmZTQzPrk=3#;CtpUHD-Z02oax?*IS* diff --git a/Tuning-Performance/Long_Term_Memory/templates/agent_template_backend/app/__pycache__/mcp_gateway_client_factory.cpython-313.pyc b/Tuning-Performance/Long_Term_Memory/templates/agent_template_backend/app/__pycache__/mcp_gateway_client_factory.cpython-313.pyc index 71b133957919c7e3d3b8c5003d9076f46e46e55d..d6621835a07807c6a6b4ba4914d4e5640f3f740f 100644 GIT binary patch delta 27 hcmZ3(@sOSSGcPX}0}urN%iYMG%*5!lc^6X=BLHn@2g3jW delta 102 zcmaFJzJ`PQGcPX}0}$j0^lju$X7cIP&&?~*Pf09E)K5&aj4#hG%GOUzPt7ZdPb*5y zO$G7e^OH06LrU{9^U`$#Qj5~^i*gh5l2i44^7GQ;LsE-!<9$uO@GcPX}0}wpOEXY!y$Xmj6hiPMTBcmis3~R8II#42p6UdT=vt%YaG79s` zg83XVEUZ8klO37lCzmk_i7J3aK{^%T>Xkt11C`-2DsUN9I7^fjR=VWeXWmb@_`XIX$4dAK_;VdH%E7-V*JKaRnbaOXzAme5x)%Vbe*iqrRxZiFLDJDZXiV*Ho5sJr8%i~MV>$| iBM=vh0f`UHjEs!;85F;;88WI)kX)epnE}WE>jMDFSVE`( delta 542 zcmYk0O)o=16oxzPt+u2hY1%|fC@qQ_)MtDoHb@YpU05`^8Mo7>^v-SOj<1D?*bA9W z?Yi&>u=Xo##6~RbMEw9W7Za1r$@8A~yl3Vy#KXZxFxc!8r_y%0XI}@ITl3sqoCCfL zT0xXAflw^gFYLUQ_hvgB3JB`_A->@53TR&Gd$Zkg8pOE;+QU66)2lKG>HCsD4!?7U zrsbvq<)>6;P|=V>&0=m?_0sZ%mJvtG4bah}${&;O#K)D+D4LLzounw-6ADDhpDM=VAG-}kYTf0K@8i!8~(Jui;R6t3J_JR z&}NA7vM&VQ`Kj+S+EL5aduuy4txsCtb0k{J)IGJCYx1NexaofbD||DMUXtIXE3&N0 oKl|rRt8h@ki*!v$Ag&z|<--F2cy-0Unld1H)m~3FTmqcjH{m#p6951J diff --git a/Tuning-Performance/Long_Term_Memory/templates/agent_template_backend/app/agents/__pycache__/billing_agent.cpython-313.pyc b/Tuning-Performance/Long_Term_Memory/templates/agent_template_backend/app/agents/__pycache__/billing_agent.cpython-313.pyc index abd23f2bbe20e039078cc384c293b16a029789b2..0e9f1e1ccd115e065d40dcf3f436c542eb47c4e6 100644 GIT binary patch delta 217 zcmWm6F-ikL6oBC{Bt!xmA$WjSCZHKCJb_h;K!{i`&zWbKb!Xl>ZxYcat(A?HL8}y| zv5>_R>@B>7cmdum>zKJ)gnt5`$&1?*HF>tjNiD)c(%oUK07ditMXYZw|X1 LRjPV>)M@_#iw#bG delta 1276 zcmYLJO>Z1U5Ji?Fp(TzG2hM$sH1Uc92ad*eP?WXT%G%;MDtc;{j{9TMAI9b~k#b0m zNJu#aiH}3zh*tc9xgvf*j`<7x0bb4Q8eew0tGepFSFil){_mgN`*&||@&W$d{r$t! zUqAix-sd}yUrwFR(}prlY57I{U5J-cTCvadGLmCC*Fl@__s4%G54y?ZBC%?y2}w1qatJm}PY%x%t0xCvDJnTc^ZgLk z!3DJpJ|myi6-T^c)lwuCIkmwz990Sqpjh=kRv|=E1t>qj*U1Z3Se3H>HXgKZ?5ND2llwXr;@x@NXew~ZO_n zSR>?x2&VA<`5R%rCG`IJPt|a@MGMNf6FA5`84%&TKRJ_O;bkf|leF#zmt=E=6XafE zN|7o>?MCd|dEPq2^QvEK6O?BS75ZPI326iCifo7#tl_m0p)jCiF!#{`m}X|5(Epn# zh7v_OafU`SE$oygPX^Vt>Pg{#-Ix`GxL7QXDs}N>hD&N;Edp$5ZNpQ-Ph?BEUke;X z4V)LoT5SxPn-LEpR@5G!LZ42xQ2N@qLFtt6^Q>Sr!>AY*bzlH9!LXy5M|VdI6jfwt zTC^S3W-9x_x31sBf-0#DB5e#1mK?c%iye@a=`wl7{tEd}Fi;?bT7SXi!vbWoz#vjW zt_7>&#%5qUAc*SA+5GVFF_f8KoY(V*_2O`Tc3i2``FVXXo6WzL(8GgAv*RPFC_RE0 zUJL+U9n^5fldVRILVml#LAf9jZ+pqU4Z<|6Ekz_2alrQ0c+4F%{#O_r6|BG!xtsqH fSlj*kyYKeWP0H-*c3nQYduQj_C+im<-`V{SGu`BS diff --git a/Tuning-Performance/Long_Term_Memory/templates/agent_template_backend/app/agents/__pycache__/orders_agent.cpython-313.pyc b/Tuning-Performance/Long_Term_Memory/templates/agent_template_backend/app/agents/__pycache__/orders_agent.cpython-313.pyc index 3a5ff2f4601e9ddc83c1bbc4bf5cd232a0625baa..f05ef2c6479b9fb2140f2b7910601bb299e3ab20 100644 GIT binary patch delta 137 zcmX@Bw?>2SGcPX}0}#y7&(Crb+Q?_Zq>-$jn^&TrqVF5*86QxTpOuaoz#2-MS zKu9#mEuBRN6&=3Zv^4<{ubiHp@Fu$5d_Ug>h2oOVYK_asbwu@P~i1p!OcHDb; ztG9jQ{rCQZX}^Ei3e{ZumTIBsy=lvx^*s{WUwcZNq7V8_cdfkjH1RH?U+7E%UJ3ew zw2gN)Q|m1N3C%y?XtdIi=bz>uJ#kEIR{OijDJD5b_bVn{qj{<)T46e7P@I2OPAdTM zDR1Z+bho6zeIDJC^CWG=i-J^!avptd2jYUXQzmIwds3;5028VcxmYv?R&i0WQa(Yq z?rMs`J_RLg-d#Ss8lvlhYOhjeSCB;yl&|vN6u44s42p~*iV+ATfMy#b(Svj5 z9|OBK`ys%O_dpsYI53@pr()aSD3-!}7L&ob;lKnMMrYQSQ)*F$gHW3kAV2^%n6i+# zzz(k%T(ji{iEs;HPNDp1l0Y_HxdFeqGn(9dn$c-^nbn+VBnIkbk3^-;yUX3IAe72r z@&?vzK@Ap4t-DPq{X|0K&btOY&b94$04Pk$B3wlRNn7n72qg;?Q{)W+LdYBkdNLfX zZ*OiCG&&qtqpj*-eYCe((C%nltqq5x7x`*y?fGzXBdhHbIOp^wlLG4fcCC|Mafi LmBDP~&eGC9YcXIQ diff --git a/Tuning-Performance/Long_Term_Memory/templates/agent_template_backend/app/agents/__pycache__/product_agent.cpython-313.pyc b/Tuning-Performance/Long_Term_Memory/templates/agent_template_backend/app/agents/__pycache__/product_agent.cpython-313.pyc index cfd8819c5d64be7542b27d649592df2822308a77..2b363379dec9a409185770edb90caa27cea5e5f1 100644 GIT binary patch delta 217 zcmZ2#xImNdGcPX}0}#y7&(GQ_w2{x0Nh3u+H?KrLMc+5rGd`dwKPxr4q*y;OJvFZ+ zKCLJ*H?=&!C_6qsIdgL#QxXT$28PL>xSZ-0Tq_E4G7C#n6^c`H719!`Qi~Mw(^88{ z5)}%H@)Juk%MukJa;X)m$)zQUMGA?Bmml7mS`5~ZoS&DLS(FPBTAZ(^5L%q7kdl~^ zU##Hk9H3BGnwXc8uaJ^iT#%o4cx_o~X0e_o%PrpG%HopL+<2h*xtpi*bFwlyGjCoX H!pZ^w1G`UU delta 1238 zcmYk5O^Z}l5Qf8`5IQK5MZjHcg|?e4Tx2=Uj3TzvgFPayE|qiZc8+sCuIFQHv+3;I ziY{HKNC+-N<1grKAp87{{DHjZ-02|=4fotrx9Y9ut@?QD_aCqSd+plj8~pzH>&^2I zKm2+9&fdeS<-}9&erjI&a5m+oxYTrkt(0@)m7bnvr`_`QiG|6M4^^jAE^~e-kUgmbZ|mKkN58r=j4O_wO%W4 zJ$2qC#0#BEz*mB}AhGwZWs2THkkIxc9*tHy@%E4HXHT3mo5|=nJH;d`ME}C1TLiCl zrxmgz2c_*7<+OqjpG$=rplgvH_a${C=SgD17h_UI$}0I14#i{APMNG->q+I9ASN_t z@@fbStkQ5|rF;grdbLJkpM#R&7$rvS-Nk3SB)T0_>s2n@jmaVg36} zlhKhaO~-5!N9ZWV7v9=cuaiFKI3`z0?I3rCmzAgDo>hej&_xGM-tk%&6-5LxR)ZD0 z3I0k9tgX3*^l-Y^oY=`l*%w)e&C*lv;Z~GD!*|sjHb{DDQ^4F7%K`@QT*Dw(mV#Hj zZvBK7+YP#LMG%->3jM!MLoYHHXFcVZx1WLrPK_D7oHX1OV`vz;3*sG4AlOMrOnvZN z814F!m8f+FKL_Sf+iZkvt~2`;=0v>Z!n@O0q+yU{rI&z6y%?;*Zt*UPvBEH^>Iguv zh8HNQq}9cyVXS+2yVACL8>5fw0r75Ku!WP+LMU6Vs|aA&KgWUY&gKUXj}FH)e{$N) z?=_2q`N`3kj_0S%{%kgXTCVQxKbRdI7PdZvZduGSDj)+dtafb1WiX5`&JD}@OhD9n zU@76XR`IF&-ik6D5SbOo?%ry5UR$gNyB$!tCjqfsieiitZ+`pk=G8s>{pS6Rt5^O5 D^PAH9 diff --git a/Tuning-Performance/Long_Term_Memory/templates/agent_template_backend/app/agents/__pycache__/prompting.cpython-313.pyc b/Tuning-Performance/Long_Term_Memory/templates/agent_template_backend/app/agents/__pycache__/prompting.cpython-313.pyc index 0ab1a52bff309be8b133a8388def5ab4a4d3f478..27c5dd67ede2919acdfd9154c883b727601ef3d0 100644 GIT binary patch delta 66 zcmX@eIggY3GcPX}0}#y7&)>)`z^sv=pPN^rpQ7&@>=_?Wl%JKFTvDu`n4X$f5}#I- Un44OjUz8o6pPacljX9bT0F7`JbN~PV delta 85 zcmbQod61L)GcPX}0}$j0^lju8U>0uH&&?~*Pf09E)K5&aj4#hG%ATyxEUFw*nwOcE nt{aeAl$KwVo0ylJs_&DZmmVLIT9g~_o0^+nRJqxiIhqjwM=BeS diff --git a/Tuning-Performance/Long_Term_Memory/templates/agent_template_backend/app/agents/__pycache__/runtime.cpython-313.pyc b/Tuning-Performance/Long_Term_Memory/templates/agent_template_backend/app/agents/__pycache__/runtime.cpython-313.pyc index 108929121ccab9207f5ef8b18ad6511f68d49c19..321fc08938aeca5f7295d480b1be6e2d3b8e0ef1 100644 GIT binary patch delta 136 zcmeyt+`!EHnU|M~0SM;k=Vy6LonGO@^$*-w*w;!P_H z_W1b3oSgXhl?Wpv`=1?pe~;$pGM7a2vk9&tH0vKMg!1pp8SCIkQg delta 284 zcmWlS%}T>S6ou~?HMJ1zu5_cNqLPIUf?eoV5d1|+6&J!Vv^OD|nF%)|;!67hLU7{) zxbblWSAj0{34|_m>EytEp+z1iqmkReA|6&$vof82@BL# z+SF+B9jWq#kXa_gJ4|bGHReiNK9W{)8SjXDL$_QeZX;rn3hOM)Fy(_go$6%c3@J9G zq#hzaHaZalBqdHz8G7IrRh~(Ug(JMIu>RJf`@o!wWp{o&#@GaUzYSoQ>;o<)u>A$? OPw0F%_r^X2uJaEy?NmGf diff --git a/Tuning-Performance/Long_Term_Memory/templates/agent_template_backend/app/agents/__pycache__/support_agent.cpython-313.pyc b/Tuning-Performance/Long_Term_Memory/templates/agent_template_backend/app/agents/__pycache__/support_agent.cpython-313.pyc index 66abc5411b3ffcf32ebe4e9ac64aea3389900cef..bcd05596d98c5ecf8965eaf9ad03596c391eb6ae 100644 GIT binary patch delta 97 zcmZqC-=V?xnU|M~0SM;k=Vt{7ZR9g!(n!(I%`4GQ(f1AZj1MTv&q_@$Db`O+Pt7Zd zPb*5yO)bwa%8t)Z&fMJ3l*qy4%`o{Bm+$6OzJpARNt@LLgP53a2*hr#7iMJv0MX7L A5C8xG delta 946 zcmXw2J8u&~5Dw-cWRwUB8mcJ~I&uXP5@pCsC{7$Djwnx~y*aaFcjvMXlOQ2CNVG`& z0VE1UiQLe;MWUzRHz4r`m_6H;iyiOm%=hw-hwsacf9vc0HTnGh`SJC;``c2W8XCgkN6NuQ_C zva1mSTLDBc|13wNm5w<7I{(6eF`?P)A0?*{=u*00A?R9~r@GNfrppY7^KZ&&B|tdk z4PAromb7x8M+a~W6r#K+KxHVGk#oBsE;Q6rc>dm(6(|U3w}O}$;i1yk03OR&a9VHYElM0K}bpbnAJ;~kOs+=GnFWi Qe|u~94mM^_?%urdA1(7?F#rGn diff --git a/Tuning-Performance/Long_Term_Memory/templates/agent_template_backend/app/agents/billing_agent.py b/Tuning-Performance/Long_Term_Memory/templates/agent_template_backend/app/agents/billing_agent.py index 05254d1..aa60099 100644 --- a/Tuning-Performance/Long_Term_Memory/templates/agent_template_backend/app/agents/billing_agent.py +++ b/Tuning-Performance/Long_Term_Memory/templates/agent_template_backend/app/agents/billing_agent.py @@ -95,7 +95,7 @@ class BillingAgent(AgentRuntimeMixin): state, system_prompt=apply_agent_profile_prompt( state, - "Você é um agente especialista em faturas.\n\nUse dados de tools/MCP e RAG autorizados como fonte de verdade para responder somente à solicitação atual.\nNunca exponha identificadores técnicos ou de identidade presentes no estado, contexto ou MCP, incluindo customer_key, contract_key, account_key, resource_key, session_key, customer_id, document, message_id, ura_call_id ou MSISDN/telefone completo.\nNão transforme nomes internos de campos em rótulos para o cliente, como “contract_key”, “customer_key” ou “MSISDN”.\nPara consultas informativas de fatura, apresente somente dados de negócio necessários, como valor, vencimento, situação e itens cobrados.\nNão acrescente canais, telefones, códigos USSD, URLs, aplicativos, lojas, relatórios adicionais, procedimentos alternativos ou próximos passos que não tenham sido explicitamente retornados pela tool/RAG e solicitados pelo usuário.\nNão ofereça espontaneamente outras ações ou detalhamentos.\nSe uma tool retornar BLOCKED, OUT_OF_SCOPE, NOT_ALLOWED, FAILED ou outro resultado terminal, explique somente o motivo retornado, não declare sucesso, não invente alternativa e encerre a resposta.", + "Você é um agente especialista em faturas. Responda com clareza, objetividade e sem sugerir ações não solicitadas. Use dados MCP quando disponíveis.", ), mcp_results=tool_context, rag_context=rag_context, diff --git a/Tuning-Performance/Long_Term_Memory/templates/agent_template_backend/app/agents/orders_agent.py b/Tuning-Performance/Long_Term_Memory/templates/agent_template_backend/app/agents/orders_agent.py index b793c26..f557bed 100644 --- a/Tuning-Performance/Long_Term_Memory/templates/agent_template_backend/app/agents/orders_agent.py +++ b/Tuning-Performance/Long_Term_Memory/templates/agent_template_backend/app/agents/orders_agent.py @@ -95,7 +95,7 @@ class OrdersAgent(AgentRuntimeMixin): state, system_prompt=apply_agent_profile_prompt( state, - "Você é um agente de pedidos de varejo.\n\nUse dados de tools/MCP e RAG autorizados como fonte de verdade e responda somente à solicitação atual.\nNunca exponha identificadores técnicos ou de identidade presentes no estado, contexto ou MCP, incluindo customer_key, contract_key, account_key, resource_key, session_key, customer_id, document, message_id, ura_call_id ou telefone completo.\nNão transforme nomes internos de campos em rótulos para o cliente.\nNão declare sucesso, alteração, troca, cancelamento ou qualquer mutação se a tool não tiver confirmado a execução.\nNão acrescente canais, procedimentos, ofertas ou próximos passos não solicitados.\nSe uma tool retornar BLOCKED, OUT_OF_SCOPE, NOT_ALLOWED, FAILED ou outro resultado terminal, explique somente o motivo retornado, não invente alternativa e encerre a resposta.", + "Você é um agente de pedidos de varejo. Use dados de tools quando disponíveis.", ), mcp_results=tool_context, rag_context=rag_context, diff --git a/Tuning-Performance/Long_Term_Memory/templates/agent_template_backend/app/agents/product_agent.py b/Tuning-Performance/Long_Term_Memory/templates/agent_template_backend/app/agents/product_agent.py index 998dad6..34433f5 100644 --- a/Tuning-Performance/Long_Term_Memory/templates/agent_template_backend/app/agents/product_agent.py +++ b/Tuning-Performance/Long_Term_Memory/templates/agent_template_backend/app/agents/product_agent.py @@ -95,7 +95,7 @@ class ProductAgent(AgentRuntimeMixin): state, system_prompt=apply_agent_profile_prompt( state, - "Você é um agente especialista em produtos, planos e serviços.\n\nUse dados de tools/MCP e RAG autorizados como fonte de verdade e responda somente à solicitação atual.\nNunca exponha identificadores técnicos ou de identidade presentes no estado, contexto ou MCP, incluindo customer_key, contract_key, account_key, resource_key, session_key, customer_id, document, message_id, ura_call_id ou MSISDN/telefone completo.\nNão transforme nomes internos de campos em rótulos para o cliente.\nEm consultas meramente informativas, não exponha flags ou capacidades transacionais internas como can.cancel e não informe espontaneamente que algo pode ser cancelado, alterado, contratado, removido ou trocado. Só mencione capacidade transacional quando o usuário tiver solicitado essa ação.\nNão faça oferta proativa e não execute nem simule mutações sem a confirmação exigida pelo framework.\nNão acrescente canais, procedimentos ou próximos passos não solicitados.\nSe uma tool retornar BLOCKED, OUT_OF_SCOPE, NOT_ALLOWED, FAILED ou outro resultado terminal, explique somente o motivo retornado, não declare sucesso, não invente alternativa e encerre a resposta.", + "Você é um agente especialista em produtos, planos e serviços. Explique sem fazer oferta proativa e sem executar ações sem confirmação. Use dados MCP quando disponíveis.", ), mcp_results=tool_context, rag_context=rag_context, diff --git a/Tuning-Performance/Long_Term_Memory/templates/agent_template_backend/app/agents/support_agent.py b/Tuning-Performance/Long_Term_Memory/templates/agent_template_backend/app/agents/support_agent.py index b15a0e4..b4f0244 100644 --- a/Tuning-Performance/Long_Term_Memory/templates/agent_template_backend/app/agents/support_agent.py +++ b/Tuning-Performance/Long_Term_Memory/templates/agent_template_backend/app/agents/support_agent.py @@ -95,7 +95,7 @@ class SupportAgent(AgentRuntimeMixin): state, system_prompt=apply_agent_profile_prompt( state, - "Você é um agente de suporte de varejo para troca, devolução e garantia.\n\nUse dados de tools/MCP e RAG autorizados como fonte de verdade e responda somente à solicitação atual.\nNunca exponha identificadores técnicos ou de identidade presentes no estado, contexto ou MCP, incluindo customer_key, contract_key, account_key, resource_key, session_key, customer_id, document, message_id, ura_call_id ou telefone completo.\nNão transforme nomes internos de campos em rótulos para o cliente.\nNão declare sucesso nem simule troca, devolução, garantia ou outra mutação se a tool não tiver confirmado a execução.\nNão acrescente canais, procedimentos, ofertas ou próximos passos não solicitados.\nSe uma tool retornar BLOCKED, OUT_OF_SCOPE, NOT_ALLOWED, FAILED ou outro resultado terminal, explique somente o motivo retornado, não invente alternativa e encerre a resposta.", + "Você é um agente de suporte de varejo para troca, devolução e garantia.", ), mcp_results=tool_context, rag_context=rag_context, diff --git a/Tuning-Performance/Long_Term_Memory/templates/agent_template_backend/app/examples/__pycache__/__init__.cpython-313.pyc b/Tuning-Performance/Long_Term_Memory/templates/agent_template_backend/app/examples/__pycache__/__init__.cpython-313.pyc index 82f6849ced0bfe64d8e426f05d50be9740ff75dc..e011e2c1613531059c3e340e048f089dc4c4b424 100644 GIT binary patch delta 24 ecmZ3?bc2!mGcPX}0}urN%bm!b$7nh6XdD1kz6VzT delta 99 zcmcb?xR{CiGcPX}0}$j0^iAZ>^J&q~%`4GQNi0d!PfW9nFV8Q^)=x}N%`1sdD@x2w z1@YtalQZ>0O7k-F(sct;i_-Foauf5CQ}uoF^U~u(Qj2oqeN%Juiz@XeR>c7TdITej diff --git a/Tuning-Performance/Long_Term_Memory/templates/agent_template_backend/app/examples/__pycache__/grl_examples.cpython-313.pyc b/Tuning-Performance/Long_Term_Memory/templates/agent_template_backend/app/examples/__pycache__/grl_examples.cpython-313.pyc index 5ce2480386fc425c237b69444af71cc785146b9f..417fdeaf32888e0d6d9e8772ec338891007c6a65 100644 GIT binary patch delta 27 hcmcb}*T%>FnU|M~0SJQsL;dI#+T<8W$P!Vr{-Z CFC&cr diff --git a/Tuning-Performance/Long_Term_Memory/templates/agent_template_backend/app/examples/__pycache__/mcp_examples.cpython-313.pyc b/Tuning-Performance/Long_Term_Memory/templates/agent_template_backend/app/examples/__pycache__/mcp_examples.cpython-313.pyc index 0f860a4a4aea9993049fa0b2bb0d13a9d62c2430..8684f23bc51276468a617f04c595b2327971cf01 100644 GIT binary patch delta 27 hcmdnY|ALSEGcPX}0}urN%iYNRoQ2VLvmI+G6997O2kQU; delta 102 zcmaFCx0#>&GcPX}0}$j0^ljvR&f?RdpPN^rpORRTsGpc-8DE}Xl&znbo|;z@pH`HZ zn+oE`=O<_Chm_`J=B4Wfq!y*+7v(1AC8z59(ihMgVA}2j&0( delta 102 zcmX@XHJO|HGcPX}0}$j0^ljw!WcKOR&&?~*Pf09E)K5&aj4#hG%GOUzPt7ZdPb*5y zO$G7e^OH06LrU{9^U`$#Qj5~^i*gh5l2i44^7GQ;LsE-!<9$0O7k-F(sct;i_-Foauf5CQ}uoF^U~u(Qj2oqeN%Juiz+9kB?16hwj)UZ diff --git a/Tuning-Performance/Long_Term_Memory/templates/agent_template_backend/app/observability/__pycache__/telemetry_observer.cpython-313.pyc b/Tuning-Performance/Long_Term_Memory/templates/agent_template_backend/app/observability/__pycache__/telemetry_observer.cpython-313.pyc index 70a39579f9332a7105b2ded40ca13058c34ea66d..a01c7f1edebe2bb12924ef4912b0d2702dae7027 100644 GIT binary patch delta 66 zcmaE>dP+sl2M~TKR2&LKSkd+*fTz$C_gJTxujS>F+DY}BtESu UF*mh5zbHFCKRI*rf5vwL0MvaK=>&C|f@&ri%`d9le24L!008>Q BC2jx! diff --git a/Tuning-Performance/Long_Term_Memory/templates/agent_template_backend/app/presentation/__pycache__/tool_renderers.cpython-313.pyc b/Tuning-Performance/Long_Term_Memory/templates/agent_template_backend/app/presentation/__pycache__/tool_renderers.cpython-313.pyc index 2c6e20ef9c7e6ef0613d7d8297a2ffe4eb6a3784..32cbdf804cb8637d1026aa386d7d188a32214831 100644 GIT binary patch delta 766 zcmZ`%&ubGw7@f)PCQH+#vH4NcnsypfCDan7*3z^Ti~XfY4=q)s)G#D#Nlka-%%sp% zMLbA*5*@tw2ME$jwFr6@Ja~&Y84v{NU1$$d5d0>3tPAsa-^`ouee>Au+}m{cAQWmr z@J$t-tPTd>gkRzQo!pu$awRHgj;=VaC=@+cP+kD;uyV1$9A5QY?iALC4dYtAXWRF5x{X)0=r5@^V46+ufhPgnqMy#|f^6*y~g z6Dld}bl*uJZLqi|kI>gpcx!WOtHT3C>RGjgYBR6zGnnj+>XXL{`XP?3E*0R1ih3bK;!f|-wja{}TKsqAt#Gd<;z>4TuBPQG9UpjU2 zOvk~rC(|-*f>=`ij;F0FK&NFUF@lrwc7n__GY;u<9rRJSR4$4oF4#FT;chJd4Sq@= zH`8wlC!wsjfQH;BbDryDeQZ*GO3dFn&RYBZ^VdxO9LgSB^GdafGtRC-iDB^pfS-^G d{)W=~D6x-b5B(2TdO}W}79j&I=f$i7!S&^`UCwxm%VJ#d-MV-gCcm zzH`ppGoSeBmzrq0v zU*tm^d+4b*MloyD(FL(2Z_%&L8MFR}W&1bF=8D-Ei~eb?=LA}7JLs5&2=)qe=o-~* zEzU#zTuP=i9VcY0 z%EJruaYe)9x;&gF%qZbAl947-o735o0J?HUiAxEM$T~I_ZpBq4uIa&}Jv}%DCKgV| zs)ke2*r+BYaAfaM+?>(~mS2;TsZk9lbwy98t`wAzJvz{*I z9X4I(q*0BWGBiUPHJ#^VHLfr*&9v$Ul&1GDdyX*%E-=D)paGMOHt5u?l716qgkw)V z!ZQeAj212mu)?UtmezIN&fX!?IyorBn*q zPcJz9qFFkkDXM81mDPYqv1MbG$&a$yO}>x_sRUmF6M*QVqXwI&spGz9$D^WYu6jk>9+?Yw`WDmbSS3 zwM%wX>z{4BJ~G#SUA+{V>YVJH-v8E1+0u^N4FL1ha-16~G&@ro*OEA6!3XzbY%3Q8 zXG&TzVK*XRA$9N~eg-hKC}1aSh)IA!3xiDzwgZ@aN+O0%I+(#rBm5@56P6wHB7cnw z%~x4}DB-;HFPL>w!6<7Pyubi{P>56mm=^tPnyh2n8V2wiMFazY>}nn!X02z?z@U)< zyBaGA3eQb2%+A@}BCQC73H#fSHU>ckTL9=Uj&{Bq7W?KKoI5y3dB|nqxG;T1IM3ap z4~0HXqOIas6U)T3Nb1=CG^3!ki+(Nc=6iuUL_O|ztRYy%(dBFe$JZ@6gZO3m>CE zjKDVI1P;D{`!!V#l#mG3JOka&lV*BP^x29{lxgoyYKioyyo*F(3*&|KHu|@xYC{9J cW2v8WasH+CUaop+i<7hd?knYvaD>(P57NieN&o-= diff --git a/Tuning-Performance/Long_Term_Memory/templates/agent_template_backend/app/presentation/tool_renderers.py b/Tuning-Performance/Long_Term_Memory/templates/agent_template_backend/app/presentation/tool_renderers.py index cb44202..f77c47a 100644 --- a/Tuning-Performance/Long_Term_Memory/templates/agent_template_backend/app/presentation/tool_renderers.py +++ b/Tuning-Performance/Long_Term_Memory/templates/agent_template_backend/app/presentation/tool_renderers.py @@ -13,42 +13,7 @@ def _money_brl(value: Any) -> str: def render_telecom_invoice(*, tool_name: str, result: dict[str, Any], state: dict[str, Any], agent_label: str) -> str | None: - """Renderiza somente campos de negócio seguros da fatura. - - Identificadores técnicos/PII presentes no payload MCP (por exemplo msisdn, - customer_id, document e business keys) não devem ser propagados ao usuário. - """ - lines = [f"[{agent_label}] Dados da sua fatura:"] - total = result.get("valor_total") - vencimento = result.get("vencimento") - status = result.get("status") - if total is not None: - lines.append(f"Valor total: R$ {_money_brl(total)}.") - if vencimento not in (None, ""): - lines.append(f"Vencimento: {vencimento}.") - if status not in (None, ""): - lines.append(f"Situação: {status}.") - - items = result.get("itens") or [] - rendered_items: list[str] = [] - if isinstance(items, list): - for item in items: - if not isinstance(item, dict): - continue - description = item.get("descricao") or item.get("nome") - value = item.get("valor") - if description in (None, ""): - continue - if value is None: - rendered_items.append(str(description)) - else: - rendered_items.append(f"{description}: R$ {_money_brl(value)}") - if rendered_items: - lines.append("Itens: " + "; ".join(rendered_items) + ".") - - # Se não houver nenhum campo de negócio seguro além do cabeçalho, deixe a - # composição pela LLM/guardrails em vez de despejar o payload bruto. - return " ".join(lines) if len(lines) > 1 else None + return f"[{agent_label}] Fatura consultada: {result}." def render_telecom_plan(*, tool_name: str, result: dict[str, Any], state: dict[str, Any], agent_label: str) -> str | None: diff --git a/Tuning-Performance/Long_Term_Memory/templates/agent_template_backend/app/workflows/__pycache__/agent_graph.cpython-313.pyc b/Tuning-Performance/Long_Term_Memory/templates/agent_template_backend/app/workflows/__pycache__/agent_graph.cpython-313.pyc index 8adf49f375f6a548c633aee93dee68ec47c2cfc1..0807ab7ce0cb9b8c00c2b3401cf6f3eb948bbebe 100644 GIT binary patch delta 7678 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 Tlg>{DbGB+}%N+`#kQ4kLFQD=7 diff --git a/Tuning-Performance/Long_Term_Memory/templates/agent_template_backend/app/workflows/agent_graph.py b/Tuning-Performance/Long_Term_Memory/templates/agent_template_backend/app/workflows/agent_graph.py index 303bf51..ed17e04 100644 --- a/Tuning-Performance/Long_Term_Memory/templates/agent_template_backend/app/workflows/agent_graph.py +++ b/Tuning-Performance/Long_Term_Memory/templates/agent_template_backend/app/workflows/agent_graph.py @@ -160,7 +160,7 @@ class AgentWorkflow: builder.add_conditional_edges( "input_guardrails", self._after_input_guardrails, - {"blocked": "persist", "continue": "load_long_term_memory"}, + {"blocked": "output_guardrails", "continue": "load_long_term_memory"}, ) builder.add_edge("load_long_term_memory", "routing_decision") builder.add_conditional_edges( @@ -197,6 +197,31 @@ class AgentWorkflow: def _after_input_guardrails(self, state): return "blocked" if state.get("blocked") else "continue" + @staticmethod + def _input_guardrail_user_message(decisions, state, sanitized_text): + # Keep the technical guardrail reason in telemetry, but expose only a + # safe, actionable message to the end user. The message is intentionally + # routed through output_guardrails before persistence/delivery. + blocked = [d for d in decisions if not getattr(d, "allowed", True)] + first = blocked[0] if blocked else None + code = str(getattr(first, "code", "") or "").upper() + if code == "COER": + return ( + "Não consegui entender sua última mensagem porque ela parece " + "incompleta ou ambígua. Pode reformular ou completar o que você quis dizer?" + ) + if code == "INPUT_SIZE": + return "Sua mensagem ficou muito longa para eu processar de uma vez. Pode resumir ou dividir em partes?" + if code == "DLEX_IN": + return "Não posso usar essa informação da forma solicitada. Reformule o pedido sem incluir dados ou conteúdo restrito." + if code == "PINJ": + return "Não posso seguir instruções que tentem alterar as regras do atendimento. Posso continuar ajudando com a sua solicitação." + if code == "TOX": + return "Não consegui prosseguir com essa mensagem. Pode reformular o pedido para continuarmos o atendimento?" + if code == "CMP": + return "Não posso prosseguir com essa solicitação dessa forma. Posso ajudar com uma alternativa permitida." + return "Não consegui processar essa mensagem. Pode reformular para eu continuar o atendimento?" + async def input_guardrails(self, state): if state.get("session_ended") is True: answer = str(getattr( @@ -281,12 +306,33 @@ class AgentWorkflow: component="workflow.input_guardrails.final", ) if any(not d.allowed for d in decisions): + # A blocking input guardrail stops the turn before routing/tools. + # Clear turn-local routing/tool state so stale data from a prior + # turn cannot appear as if it was executed after the block. + user_message = self._input_guardrail_user_message(decisions, state, sanitized) return { "sanitized_input": sanitized, - "answer": "Não consegui seguir com essa mensagem por regra de segurança.", - "final_answer": "Não consegui seguir com essa mensagem por regra de segurança.", + "answer": user_message, + "final_answer": None, "guardrail_decisions": [d.model_dump() for d in decisions], "route": "blocked", + "intent": "input_guardrail_blocked", + "route_decision": { + "route": "blocked", + "agent": None, + "intent": "input_guardrail_blocked", + "confidence": 1.0, + "reason": "Entrada interrompida por guardrail antes do roteamento.", + "method": "guardrail", + "next_state": state.get("next_state"), + "handoff": False, + "metadata": {}, + "domain": state.get("domain"), + "mcp_tools": [], + }, + "mcp_tools": [], + "mcp_results": [], + "judge_results": [], "blocked": True, } return { @@ -494,119 +540,6 @@ class AgentWorkflow: "next_state": "SESSION_ENDED", } - @staticmethod - def _output_guardrail_context(state: dict) -> dict: - """Monta o contexto operacional do turno para os guardrails de saída. - - Mantém evidências/protocolos necessários aos rails, mas impede que uma - transação encerrada ou semanticamente interrompida governe o novo turno. - O histórico completo permanece no state/checkpoint para auditoria. - """ - ctx = dict(state.get("context", {}) or {}) - mcp_results = state.get("mcp_results") or [] - ctx["evidence"] = mcp_results or ctx.get("evidence") - ctx["tool_result"] = mcp_results or ctx.get("tool_result") - ctx["tool_executed"] = any(isinstance(r, dict) and r.get("ok") for r in mcp_results) - - history = list(state.get("history") or []) - current_user_text = str(state.get("user_text") or "").strip() - if current_user_text: - if ( - not history - or not isinstance(history[-1], dict) - or str(history[-1].get("content") or "") != current_user_text - or str(history[-1].get("role") or "") != "user" - ): - history.append({"role": "user", "content": current_user_text}) - - route_decision = state.get("route_decision") or {} - route_metadata = route_decision.get("metadata") if isinstance(route_decision, dict) else {} - route_metadata = route_metadata if isinstance(route_metadata, dict) else {} - pre_validation = state.get("transaction_pre_validation") or {} - pre_validation = pre_validation if isinstance(pre_validation, dict) else {} - tx_status = str( - state.get("transaction_status") or pre_validation.get("status") or "" - ).strip().upper() - terminal_tx = bool(pre_validation.get("terminal")) or tx_status in { - "COMPLETED", "FAILED", "CANCELLED", "BLOCKED", "OUT_OF_SCOPE" - } - semantic_intent_shift = ( - str(route_metadata.get("transaction_interruption") or "").strip().lower() - == "intent_shift" - ) - stickiness_intent_shift = bool(route_metadata.get("route_stickiness_preempted")) - should_isolate_history = semantic_intent_shift or (terminal_tx and stickiness_intent_shift) - - current_route = str( - state.get("route") - or (route_decision.get("route") if isinstance(route_decision, dict) else "") - or "" - ).strip() - current_intent = str( - state.get("intent") - or (route_decision.get("intent") if isinstance(route_decision, dict) else "") - or "" - ).strip() - ctx["current_user_message"] = current_user_text - ctx["current_route"] = current_route - ctx["current_intent"] = current_intent - - if should_isolate_history: - operational_history = ( - [{"role": "user", "content": current_user_text}] - if current_user_text else [] - ) - ctx["historical_transaction_ignored"] = True - ctx["historical_transaction_status"] = tx_status or ( - "INTERRUPTED" if semantic_intent_shift else "TERMINAL" - ) - if semantic_intent_shift: - ctx["historical_transaction_interruption"] = "intent_shift" - for stale_key in ( - "transaction_pre_validation", - "transaction_status", - "active_transaction", - "transaction", - ): - ctx.pop(stale_key, None) - else: - operational_history = history - - ctx["conversation_history"] = operational_history - ctx["history_texts"] = [ - str(item.get("content") or "") - for item in operational_history - if isinstance(item, dict) and item.get("content") not in (None, "") - ] - - protocols: list[str] = [] - seen: set[str] = set() - protocol_keys = { - "protocol_number", "protocolo_id", "interactionProtocol", - "protocolNumber", "finalizacao_protocol", - } - - def walk(value): - if isinstance(value, dict): - for key, item in value.items(): - if key in protocol_keys and item not in (None, ""): - text = str(item).strip() - if text and text not in seen: - seen.add(text) - protocols.append(text) - elif isinstance(item, (dict, list, tuple)): - walk(item) - elif isinstance(value, (list, tuple)): - for item in value: - walk(item) - - walk(mcp_results) - if protocols: - ctx["expected_protocols"] = protocols - ctx["requer_protocolo"] = True - ctx.setdefault("tipo_fluxo", "ajuste") - return ctx - async def output_supervisor(self, state): """Valida a resposta candidata com o OutputSupervisor corporativo. @@ -622,15 +555,15 @@ class AgentWorkflow: } candidate = state.get("answer") or "" - context = self._output_guardrail_context(state) - context.update({ + context = { + **(state.get("context") or {}), "tenant_id": state.get("tenant_id"), "agent_id": state.get("agent_id"), "session_id": state.get("conversation_key") or state.get("session_id"), "route": state.get("route"), "intent": state.get("intent"), "supervisor_attempt": int(state.get("supervisor_attempt", 0)), - }) + } async with self.telemetry.span( "workflow.output_supervisor", session_id=state.get("conversation_key") or state.get("session_id"), @@ -716,7 +649,7 @@ class AgentWorkflow: component="workflow.output_guardrails.start", ) final, decisions = await self.guardrails.run_output( - state["answer"], self._output_guardrail_context(state) + state["answer"], state.get("context", {}) ) for _decision in decisions: await self.guardrail_telemetry.evaluated("output", _decision) diff --git a/Tuning-Performance/Long_Term_Memory/templates/agent_template_backend/config/routing.yaml b/Tuning-Performance/Long_Term_Memory/templates/agent_template_backend/config/routing.yaml index 03aeaa9..bb4ef6f 100644 --- a/Tuning-Performance/Long_Term_Memory/templates/agent_template_backend/config/routing.yaml +++ b/Tuning-Performance/Long_Term_Memory/templates/agent_template_backend/config/routing.yaml @@ -7,6 +7,35 @@ router: confidence_threshold: 0.65 allow_handoff: true + transaction_confirmation: + # Explicit yes/no stays deterministic. Only inconclusive replies use this LLM fallback. + semantic_fallback: + enabled: true + allowed_values: [SIM, NAO, CONTINUAR] + confirm_values: [SIM] + reject_values: [NAO] + continue_values: [CONTINUAR] + include_relevant_context: true + profile_name: router + prompt: | + Você classifica a resposta do cliente a uma confirmação transacional pendente. + Considere a pergunta pendente, somente o histórico recente relacionado ao mesmo tema e a fala atual. + Não execute a ação e não invente fatos. + + Classes permitidas: {{ allowed_values }} + - SIM: confirmação/aceite inequívoco, inclusive equivalentes como "isso mesmo", "pode confirmar", "é isso" quando o contexto tornar o aceite claro. + - NAO: recusa/cancelamento inequívoco da ação pendente. + - CONTINUAR: qualquer resposta que não confirme nem rejeite inequivocamente, incluindo pergunta adicional, correção, novo dado, ambiguidade ou possível mudança de assunto. + + Pergunta pendente: + {{ pending_prompt }} + + Histórico relevante: + {{ relevant_conversation_context }} + + Resposta atual do cliente: + {{ user_input }} + state_policies: - state: WAITING_BILLING_CONFIRMATION agent: billing_agent diff --git a/Tuning-Performance/Long_Term_Memory/templates/agent_template_backend/docs/TRANSACTION_SEMANTIC_CONFIRMATION.md b/Tuning-Performance/Long_Term_Memory/templates/agent_template_backend/docs/TRANSACTION_SEMANTIC_CONFIRMATION.md new file mode 100644 index 0000000..a550871 --- /dev/null +++ b/Tuning-Performance/Long_Term_Memory/templates/agent_template_backend/docs/TRANSACTION_SEMANTIC_CONFIRMATION.md @@ -0,0 +1,11 @@ +# Confirmação Transacional Semântica + +Este template suporta confirmação transacional em duas camadas: primeiro um parser determinístico para `sim`/`não` e equivalentes explícitos; somente quando ele não consegue decidir, o framework usa um classificador semântico configurado em `config/routing.yaml`. + +A configuração `router.transaction_confirmation.semantic_fallback` usa três classes: `SIM`, `NAO` e `CONTINUAR`. O prompt pode usar `{{ pending_prompt }}`, `{{ relevant_conversation_context }}`, `{{ user_input }}` e `{{ allowed_values }}`. O histórico injetado é apenas contexto de interpretação; não substitui validação de negócio ou evidência MCP. + +Exemplo: após `Você confirma o cancelamento do serviço Tamboro Mensal?`, a frase `isso mesmo, pode confirmar` pode ser classificada como `SIM`. Já `mas qual é o valor?` deve ser `CONTINUAR`, portanto não executa a ação por confirmação. + +Entradas explícitas já suportadas continuam no caminho determinístico e não geram custo adicional de LLM. Em observabilidade, o fallback usa `transaction.confirmation.semantic_classifier` e o `route_decision.metadata` informa `transaction_confirmation_source: semantic`. + +Consulte `docs/developer/pt/03_transaction_workflows_and_state.md` do framework para o contrato completo e exemplos. diff --git a/Tuning-Performance/Normal/templates/agent_template_backend/app/agents/billing_agent.py b/Tuning-Performance/Normal/templates/agent_template_backend/app/agents/billing_agent.py index 05254d1..aa60099 100644 --- a/Tuning-Performance/Normal/templates/agent_template_backend/app/agents/billing_agent.py +++ b/Tuning-Performance/Normal/templates/agent_template_backend/app/agents/billing_agent.py @@ -95,7 +95,7 @@ class BillingAgent(AgentRuntimeMixin): state, system_prompt=apply_agent_profile_prompt( state, - "Você é um agente especialista em faturas.\n\nUse dados de tools/MCP e RAG autorizados como fonte de verdade para responder somente à solicitação atual.\nNunca exponha identificadores técnicos ou de identidade presentes no estado, contexto ou MCP, incluindo customer_key, contract_key, account_key, resource_key, session_key, customer_id, document, message_id, ura_call_id ou MSISDN/telefone completo.\nNão transforme nomes internos de campos em rótulos para o cliente, como “contract_key”, “customer_key” ou “MSISDN”.\nPara consultas informativas de fatura, apresente somente dados de negócio necessários, como valor, vencimento, situação e itens cobrados.\nNão acrescente canais, telefones, códigos USSD, URLs, aplicativos, lojas, relatórios adicionais, procedimentos alternativos ou próximos passos que não tenham sido explicitamente retornados pela tool/RAG e solicitados pelo usuário.\nNão ofereça espontaneamente outras ações ou detalhamentos.\nSe uma tool retornar BLOCKED, OUT_OF_SCOPE, NOT_ALLOWED, FAILED ou outro resultado terminal, explique somente o motivo retornado, não declare sucesso, não invente alternativa e encerre a resposta.", + "Você é um agente especialista em faturas. Responda com clareza, objetividade e sem sugerir ações não solicitadas. Use dados MCP quando disponíveis.", ), mcp_results=tool_context, rag_context=rag_context, diff --git a/Tuning-Performance/Normal/templates/agent_template_backend/app/agents/orders_agent.py b/Tuning-Performance/Normal/templates/agent_template_backend/app/agents/orders_agent.py index b793c26..f557bed 100644 --- a/Tuning-Performance/Normal/templates/agent_template_backend/app/agents/orders_agent.py +++ b/Tuning-Performance/Normal/templates/agent_template_backend/app/agents/orders_agent.py @@ -95,7 +95,7 @@ class OrdersAgent(AgentRuntimeMixin): state, system_prompt=apply_agent_profile_prompt( state, - "Você é um agente de pedidos de varejo.\n\nUse dados de tools/MCP e RAG autorizados como fonte de verdade e responda somente à solicitação atual.\nNunca exponha identificadores técnicos ou de identidade presentes no estado, contexto ou MCP, incluindo customer_key, contract_key, account_key, resource_key, session_key, customer_id, document, message_id, ura_call_id ou telefone completo.\nNão transforme nomes internos de campos em rótulos para o cliente.\nNão declare sucesso, alteração, troca, cancelamento ou qualquer mutação se a tool não tiver confirmado a execução.\nNão acrescente canais, procedimentos, ofertas ou próximos passos não solicitados.\nSe uma tool retornar BLOCKED, OUT_OF_SCOPE, NOT_ALLOWED, FAILED ou outro resultado terminal, explique somente o motivo retornado, não invente alternativa e encerre a resposta.", + "Você é um agente de pedidos de varejo. Use dados de tools quando disponíveis.", ), mcp_results=tool_context, rag_context=rag_context, diff --git a/Tuning-Performance/Normal/templates/agent_template_backend/app/agents/product_agent.py b/Tuning-Performance/Normal/templates/agent_template_backend/app/agents/product_agent.py index 998dad6..34433f5 100644 --- a/Tuning-Performance/Normal/templates/agent_template_backend/app/agents/product_agent.py +++ b/Tuning-Performance/Normal/templates/agent_template_backend/app/agents/product_agent.py @@ -95,7 +95,7 @@ class ProductAgent(AgentRuntimeMixin): state, system_prompt=apply_agent_profile_prompt( state, - "Você é um agente especialista em produtos, planos e serviços.\n\nUse dados de tools/MCP e RAG autorizados como fonte de verdade e responda somente à solicitação atual.\nNunca exponha identificadores técnicos ou de identidade presentes no estado, contexto ou MCP, incluindo customer_key, contract_key, account_key, resource_key, session_key, customer_id, document, message_id, ura_call_id ou MSISDN/telefone completo.\nNão transforme nomes internos de campos em rótulos para o cliente.\nEm consultas meramente informativas, não exponha flags ou capacidades transacionais internas como can.cancel e não informe espontaneamente que algo pode ser cancelado, alterado, contratado, removido ou trocado. Só mencione capacidade transacional quando o usuário tiver solicitado essa ação.\nNão faça oferta proativa e não execute nem simule mutações sem a confirmação exigida pelo framework.\nNão acrescente canais, procedimentos ou próximos passos não solicitados.\nSe uma tool retornar BLOCKED, OUT_OF_SCOPE, NOT_ALLOWED, FAILED ou outro resultado terminal, explique somente o motivo retornado, não declare sucesso, não invente alternativa e encerre a resposta.", + "Você é um agente especialista em produtos, planos e serviços. Explique sem fazer oferta proativa e sem executar ações sem confirmação. Use dados MCP quando disponíveis.", ), mcp_results=tool_context, rag_context=rag_context, diff --git a/Tuning-Performance/Normal/templates/agent_template_backend/app/agents/support_agent.py b/Tuning-Performance/Normal/templates/agent_template_backend/app/agents/support_agent.py index b15a0e4..b4f0244 100644 --- a/Tuning-Performance/Normal/templates/agent_template_backend/app/agents/support_agent.py +++ b/Tuning-Performance/Normal/templates/agent_template_backend/app/agents/support_agent.py @@ -95,7 +95,7 @@ class SupportAgent(AgentRuntimeMixin): state, system_prompt=apply_agent_profile_prompt( state, - "Você é um agente de suporte de varejo para troca, devolução e garantia.\n\nUse dados de tools/MCP e RAG autorizados como fonte de verdade e responda somente à solicitação atual.\nNunca exponha identificadores técnicos ou de identidade presentes no estado, contexto ou MCP, incluindo customer_key, contract_key, account_key, resource_key, session_key, customer_id, document, message_id, ura_call_id ou telefone completo.\nNão transforme nomes internos de campos em rótulos para o cliente.\nNão declare sucesso nem simule troca, devolução, garantia ou outra mutação se a tool não tiver confirmado a execução.\nNão acrescente canais, procedimentos, ofertas ou próximos passos não solicitados.\nSe uma tool retornar BLOCKED, OUT_OF_SCOPE, NOT_ALLOWED, FAILED ou outro resultado terminal, explique somente o motivo retornado, não invente alternativa e encerre a resposta.", + "Você é um agente de suporte de varejo para troca, devolução e garantia.", ), mcp_results=tool_context, rag_context=rag_context, diff --git a/Tuning-Performance/Normal/templates/agent_template_backend/app/presentation/__pycache__/tool_renderers.cpython-313.pyc b/Tuning-Performance/Normal/templates/agent_template_backend/app/presentation/__pycache__/tool_renderers.cpython-313.pyc index 970b809f47ad8563dde405293a4ecf1333a80c4b..23b52e138221f8fc623622c7fe8fe767b8579417 100644 GIT binary patch delta 794 zcmZ`%&rcIU6yE9XwrfiZ+8@}K%D7ZbgIEmy2nC5meyA~+fan29Gif)Z*zVSuDUo8L z7Y%18Uc7NJ8V_Q)n0PSZFW_X%B%TZx4@yG4c+of2BW^NZzBliC?|XT(zt6m~Bm3cS zP=jx>_;h(F^e*xe^>5^BF3*<df;50M>x6Pfd(=fndcf3H!t&NVa zK9mtpI{Ox7XoXZgTI3!l)n?ai72tMIz_VE_%?fv1CJ&VzR)Q@NPa3XQbEMAhHFCZg zsWk)Fl%jx}z7Z@DhN+Gz*IoeeF<=i-3@q1i;H+7t%m7HUT5%mF&9=1|urlIO*IDx% zq>gW~u8Rn!esfqyC@bC`SuN}af?|5-`f=7Q*sT{g!-IxOzS zo}r}p5&M=>&p_2~sPdvJt(t2zDfZ*Gc?IZ{NF|0rek*~e+Y1k?yxRJ&NV!tt3yjm# zc-&oG{QC-%D&2mHwr~Q%W)L*^A)fJEC+DLR;zMHg{z2Bt@1MV7>Q9l@Xw54(s?Hd_ z4k3cW1_1V88|aH>?`nx%?P|+!pj0b@&`8S)A-mNRN9opJ5cz+m40IFGBvkwXUQNQ3 delta 1843 zcmZ`(U2GIp6rSnq?9Bem?w0MAvbFTG{jm$BYgzikmY`C8+S*p^W+7=IWY`^=DecU9 zXSSgQ(mwb=^`Wg-Lj{dB5?$WFn&^WMnwt2+!;(c<#~4Wzqb~-e@u3guxmyY(;5>YL z?z!K&-*?X3*=*?FCeH&&ax(B(*XKrl^Ih|N!g}6_jA>>hC7W_YKDmqh%-*XMfx$5h z`yd7QE)!=HoQH{*M7an{=3Se}b(fQT?y4Yv!mnVfb?_%PGfcuZz>#LVzeO10sRVrz zd<(l4LA@B|)>nv0*yD~4*pmZ~D{Gty`%^sOX`bLp2$Vt*e2#?0HsK7! z4rpp#^oLy_=zF3u_jItXLBfx5N4C6^I!sT^kB*eLWlZ z$KC-CuoEwXn!wbfomwVtuVuo4OdhHR6fLD-by7x#KBj1LyLq4vW z8F~3ra27)rubPTxSdNrpBr%Lew`>~pW%1*36P!887tdQ2x+yJ&R!ch2AM`?7EDAd; zZdfrbyPQtLJ0aK+k}TVZu4)!Hs%T+}lylElSo|m*h{YG(;WDVjaN`;Boudj_t~K4X zsp=Z`K-!Q1(E3C6a-qH*knz&3H$ixsx#wnlrE`^YQm!hRlXm9ZEz|o8?hUg&Gd*+X z^6olVm2SKcoDVMa=1arVJq5`>J2*4AAm*hl(+9|DXH85fT?podnt~|Jx@X*TXBT@G zcV}PE1)6V)I|_m{H<%ZyA8#I5Y|l350^4tjO?Sv8=hi8I)k5m>zT5ur4S)CtUqvCf z`NM|y8Wub9!N~1k=hdBGv|nrg@<2Y?dH$6`S;d8}`L2Z{`Leq6`wQOS!bslRK#RO( zGv^Av&9{AZH+*%Mli6+g`qo>%wma*oY-Luun)oXAwUY1X&Bgk1_5HVeuig(Z0WSD= zIYF*a^@_+;hZgHDjbxiIY3HM}?KACj``>yoXKTG$3$Qf99bx&kVgGKcZpT|-h&V){ z9w02@1{#McY^AV`LJNS!r)6v!xRoXXq?6yqw?o)U4E`b;UGms}DPaTTFR^9{`zfWI z!X^qq3Y7pBXPnC5jdWQ>0sbBti~vCPu@4{3)=;RWP)C7YfHi~eXBv#reR_j%BLl*i z{;}XD3K0q~0FYlD&HQc%_ALdSZ7f(GaB(afBZu8**em3FcP}fGkTg+GomiZ#P5jR= ziduWfH_}Ud4^WR1yXS3t6rvSmN$6J(U?%_TV@y;Ui)UI$680x1beAc=%XF>SZESGGQ_Hrk N^s~fQT4tkt{s-rv)u{jg diff --git a/Tuning-Performance/Normal/templates/agent_template_backend/app/presentation/tool_renderers.py b/Tuning-Performance/Normal/templates/agent_template_backend/app/presentation/tool_renderers.py index cb44202..f77c47a 100644 --- a/Tuning-Performance/Normal/templates/agent_template_backend/app/presentation/tool_renderers.py +++ b/Tuning-Performance/Normal/templates/agent_template_backend/app/presentation/tool_renderers.py @@ -13,42 +13,7 @@ def _money_brl(value: Any) -> str: def render_telecom_invoice(*, tool_name: str, result: dict[str, Any], state: dict[str, Any], agent_label: str) -> str | None: - """Renderiza somente campos de negócio seguros da fatura. - - Identificadores técnicos/PII presentes no payload MCP (por exemplo msisdn, - customer_id, document e business keys) não devem ser propagados ao usuário. - """ - lines = [f"[{agent_label}] Dados da sua fatura:"] - total = result.get("valor_total") - vencimento = result.get("vencimento") - status = result.get("status") - if total is not None: - lines.append(f"Valor total: R$ {_money_brl(total)}.") - if vencimento not in (None, ""): - lines.append(f"Vencimento: {vencimento}.") - if status not in (None, ""): - lines.append(f"Situação: {status}.") - - items = result.get("itens") or [] - rendered_items: list[str] = [] - if isinstance(items, list): - for item in items: - if not isinstance(item, dict): - continue - description = item.get("descricao") or item.get("nome") - value = item.get("valor") - if description in (None, ""): - continue - if value is None: - rendered_items.append(str(description)) - else: - rendered_items.append(f"{description}: R$ {_money_brl(value)}") - if rendered_items: - lines.append("Itens: " + "; ".join(rendered_items) + ".") - - # Se não houver nenhum campo de negócio seguro além do cabeçalho, deixe a - # composição pela LLM/guardrails em vez de despejar o payload bruto. - return " ".join(lines) if len(lines) > 1 else None + return f"[{agent_label}] Fatura consultada: {result}." def render_telecom_plan(*, tool_name: str, result: dict[str, Any], state: dict[str, Any], agent_label: str) -> str | None: diff --git a/Tuning-Performance/Normal/templates/agent_template_backend/app/workflows/__pycache__/agent_graph.cpython-313.pyc b/Tuning-Performance/Normal/templates/agent_template_backend/app/workflows/__pycache__/agent_graph.cpython-313.pyc index 114625a75f1eb41ac56ec89a9e485938646aa83e..7293dd3a2ae752b087f93066c4c4d05cfde32779 100644 GIT binary patch delta 7409 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 delta 11090 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 gak}f)4srP4WsQXX1$pf1aJExT8*fnvg dict: - """Monta o contexto operacional do turno para os guardrails de saída. - - Mantém evidências/protocolos necessários aos rails, mas impede que uma - transação encerrada ou semanticamente interrompida governe o novo turno. - O histórico completo permanece no state/checkpoint para auditoria. - """ - ctx = dict(state.get("context", {}) or {}) - mcp_results = state.get("mcp_results") or [] - ctx["evidence"] = mcp_results or ctx.get("evidence") - ctx["tool_result"] = mcp_results or ctx.get("tool_result") - ctx["tool_executed"] = any(isinstance(r, dict) and r.get("ok") for r in mcp_results) - - history = list(state.get("history") or []) - current_user_text = str(state.get("user_text") or "").strip() - if current_user_text: - if ( - not history - or not isinstance(history[-1], dict) - or str(history[-1].get("content") or "") != current_user_text - or str(history[-1].get("role") or "") != "user" - ): - history.append({"role": "user", "content": current_user_text}) - - route_decision = state.get("route_decision") or {} - route_metadata = route_decision.get("metadata") if isinstance(route_decision, dict) else {} - route_metadata = route_metadata if isinstance(route_metadata, dict) else {} - pre_validation = state.get("transaction_pre_validation") or {} - pre_validation = pre_validation if isinstance(pre_validation, dict) else {} - tx_status = str( - state.get("transaction_status") or pre_validation.get("status") or "" - ).strip().upper() - terminal_tx = bool(pre_validation.get("terminal")) or tx_status in { - "COMPLETED", "FAILED", "CANCELLED", "BLOCKED", "OUT_OF_SCOPE" - } - semantic_intent_shift = ( - str(route_metadata.get("transaction_interruption") or "").strip().lower() - == "intent_shift" - ) - stickiness_intent_shift = bool(route_metadata.get("route_stickiness_preempted")) - should_isolate_history = semantic_intent_shift or (terminal_tx and stickiness_intent_shift) - - current_route = str( - state.get("route") - or (route_decision.get("route") if isinstance(route_decision, dict) else "") - or "" - ).strip() - current_intent = str( - state.get("intent") - or (route_decision.get("intent") if isinstance(route_decision, dict) else "") - or "" - ).strip() - ctx["current_user_message"] = current_user_text - ctx["current_route"] = current_route - ctx["current_intent"] = current_intent - - if should_isolate_history: - operational_history = ( - [{"role": "user", "content": current_user_text}] - if current_user_text else [] - ) - ctx["historical_transaction_ignored"] = True - ctx["historical_transaction_status"] = tx_status or ( - "INTERRUPTED" if semantic_intent_shift else "TERMINAL" - ) - if semantic_intent_shift: - ctx["historical_transaction_interruption"] = "intent_shift" - for stale_key in ( - "transaction_pre_validation", - "transaction_status", - "active_transaction", - "transaction", - ): - ctx.pop(stale_key, None) - else: - operational_history = history - - ctx["conversation_history"] = operational_history - ctx["history_texts"] = [ - str(item.get("content") or "") - for item in operational_history - if isinstance(item, dict) and item.get("content") not in (None, "") - ] - - protocols: list[str] = [] - seen: set[str] = set() - protocol_keys = { - "protocol_number", "protocolo_id", "interactionProtocol", - "protocolNumber", "finalizacao_protocol", - } - - def walk(value): - if isinstance(value, dict): - for key, item in value.items(): - if key in protocol_keys and item not in (None, ""): - text = str(item).strip() - if text and text not in seen: - seen.add(text) - protocols.append(text) - elif isinstance(item, (dict, list, tuple)): - walk(item) - elif isinstance(value, (list, tuple)): - for item in value: - walk(item) - - walk(mcp_results) - if protocols: - ctx["expected_protocols"] = protocols - ctx["requer_protocolo"] = True - ctx.setdefault("tipo_fluxo", "ajuste") - return ctx - async def output_supervisor(self, state): """Valida a resposta candidata com o OutputSupervisor corporativo. @@ -620,15 +553,15 @@ class AgentWorkflow: } candidate = state.get("answer") or "" - context = self._output_guardrail_context(state) - context.update({ + context = { + **(state.get("context") or {}), "tenant_id": state.get("tenant_id"), "agent_id": state.get("agent_id"), "session_id": state.get("conversation_key") or state.get("session_id"), "route": state.get("route"), "intent": state.get("intent"), "supervisor_attempt": int(state.get("supervisor_attempt", 0)), - }) + } async with self.telemetry.span( "workflow.output_supervisor", session_id=state.get("conversation_key") or state.get("session_id"), @@ -714,7 +647,7 @@ class AgentWorkflow: component="workflow.output_guardrails.start", ) final, decisions = await self.guardrails.run_output( - state["answer"], self._output_guardrail_context(state) + state["answer"], state.get("context", {}) ) for _decision in decisions: await self.guardrail_telemetry.evaluated("output", _decision) diff --git a/Tuning-Performance/Normal/templates/agent_template_backend/config/routing.yaml b/Tuning-Performance/Normal/templates/agent_template_backend/config/routing.yaml index 03aeaa9..bb4ef6f 100644 --- a/Tuning-Performance/Normal/templates/agent_template_backend/config/routing.yaml +++ b/Tuning-Performance/Normal/templates/agent_template_backend/config/routing.yaml @@ -7,6 +7,35 @@ router: confidence_threshold: 0.65 allow_handoff: true + transaction_confirmation: + # Explicit yes/no stays deterministic. Only inconclusive replies use this LLM fallback. + semantic_fallback: + enabled: true + allowed_values: [SIM, NAO, CONTINUAR] + confirm_values: [SIM] + reject_values: [NAO] + continue_values: [CONTINUAR] + include_relevant_context: true + profile_name: router + prompt: | + Você classifica a resposta do cliente a uma confirmação transacional pendente. + Considere a pergunta pendente, somente o histórico recente relacionado ao mesmo tema e a fala atual. + Não execute a ação e não invente fatos. + + Classes permitidas: {{ allowed_values }} + - SIM: confirmação/aceite inequívoco, inclusive equivalentes como "isso mesmo", "pode confirmar", "é isso" quando o contexto tornar o aceite claro. + - NAO: recusa/cancelamento inequívoco da ação pendente. + - CONTINUAR: qualquer resposta que não confirme nem rejeite inequivocamente, incluindo pergunta adicional, correção, novo dado, ambiguidade ou possível mudança de assunto. + + Pergunta pendente: + {{ pending_prompt }} + + Histórico relevante: + {{ relevant_conversation_context }} + + Resposta atual do cliente: + {{ user_input }} + state_policies: - state: WAITING_BILLING_CONFIRMATION agent: billing_agent diff --git a/Tuning-Performance/Normal/templates/agent_template_backend/docs/TRANSACTION_SEMANTIC_CONFIRMATION.md b/Tuning-Performance/Normal/templates/agent_template_backend/docs/TRANSACTION_SEMANTIC_CONFIRMATION.md new file mode 100644 index 0000000..a550871 --- /dev/null +++ b/Tuning-Performance/Normal/templates/agent_template_backend/docs/TRANSACTION_SEMANTIC_CONFIRMATION.md @@ -0,0 +1,11 @@ +# Confirmação Transacional Semântica + +Este template suporta confirmação transacional em duas camadas: primeiro um parser determinístico para `sim`/`não` e equivalentes explícitos; somente quando ele não consegue decidir, o framework usa um classificador semântico configurado em `config/routing.yaml`. + +A configuração `router.transaction_confirmation.semantic_fallback` usa três classes: `SIM`, `NAO` e `CONTINUAR`. O prompt pode usar `{{ pending_prompt }}`, `{{ relevant_conversation_context }}`, `{{ user_input }}` e `{{ allowed_values }}`. O histórico injetado é apenas contexto de interpretação; não substitui validação de negócio ou evidência MCP. + +Exemplo: após `Você confirma o cancelamento do serviço Tamboro Mensal?`, a frase `isso mesmo, pode confirmar` pode ser classificada como `SIM`. Já `mas qual é o valor?` deve ser `CONTINUAR`, portanto não executa a ação por confirmação. + +Entradas explícitas já suportadas continuam no caminho determinístico e não geram custo adicional de LLM. Em observabilidade, o fallback usa `transaction.confirmation.semantic_classifier` e o `route_decision.metadata` informa `transaction_confirmation_source: semantic`. + +Consulte `docs/developer/pt/03_transaction_workflows_and_state.md` do framework para o contrato completo e exemplos. diff --git a/Tuning-Performance/Normal/templates/agent_template_backend_day_zero/app/agents/billing_agent.py b/Tuning-Performance/Normal/templates/agent_template_backend_day_zero/app/agents/billing_agent.py index 05254d1..aa60099 100644 --- a/Tuning-Performance/Normal/templates/agent_template_backend_day_zero/app/agents/billing_agent.py +++ b/Tuning-Performance/Normal/templates/agent_template_backend_day_zero/app/agents/billing_agent.py @@ -95,7 +95,7 @@ class BillingAgent(AgentRuntimeMixin): state, system_prompt=apply_agent_profile_prompt( state, - "Você é um agente especialista em faturas.\n\nUse dados de tools/MCP e RAG autorizados como fonte de verdade para responder somente à solicitação atual.\nNunca exponha identificadores técnicos ou de identidade presentes no estado, contexto ou MCP, incluindo customer_key, contract_key, account_key, resource_key, session_key, customer_id, document, message_id, ura_call_id ou MSISDN/telefone completo.\nNão transforme nomes internos de campos em rótulos para o cliente, como “contract_key”, “customer_key” ou “MSISDN”.\nPara consultas informativas de fatura, apresente somente dados de negócio necessários, como valor, vencimento, situação e itens cobrados.\nNão acrescente canais, telefones, códigos USSD, URLs, aplicativos, lojas, relatórios adicionais, procedimentos alternativos ou próximos passos que não tenham sido explicitamente retornados pela tool/RAG e solicitados pelo usuário.\nNão ofereça espontaneamente outras ações ou detalhamentos.\nSe uma tool retornar BLOCKED, OUT_OF_SCOPE, NOT_ALLOWED, FAILED ou outro resultado terminal, explique somente o motivo retornado, não declare sucesso, não invente alternativa e encerre a resposta.", + "Você é um agente especialista em faturas. Responda com clareza, objetividade e sem sugerir ações não solicitadas. Use dados MCP quando disponíveis.", ), mcp_results=tool_context, rag_context=rag_context, diff --git a/Tuning-Performance/Normal/templates/agent_template_backend_day_zero/app/agents/orders_agent.py b/Tuning-Performance/Normal/templates/agent_template_backend_day_zero/app/agents/orders_agent.py index b793c26..f557bed 100644 --- a/Tuning-Performance/Normal/templates/agent_template_backend_day_zero/app/agents/orders_agent.py +++ b/Tuning-Performance/Normal/templates/agent_template_backend_day_zero/app/agents/orders_agent.py @@ -95,7 +95,7 @@ class OrdersAgent(AgentRuntimeMixin): state, system_prompt=apply_agent_profile_prompt( state, - "Você é um agente de pedidos de varejo.\n\nUse dados de tools/MCP e RAG autorizados como fonte de verdade e responda somente à solicitação atual.\nNunca exponha identificadores técnicos ou de identidade presentes no estado, contexto ou MCP, incluindo customer_key, contract_key, account_key, resource_key, session_key, customer_id, document, message_id, ura_call_id ou telefone completo.\nNão transforme nomes internos de campos em rótulos para o cliente.\nNão declare sucesso, alteração, troca, cancelamento ou qualquer mutação se a tool não tiver confirmado a execução.\nNão acrescente canais, procedimentos, ofertas ou próximos passos não solicitados.\nSe uma tool retornar BLOCKED, OUT_OF_SCOPE, NOT_ALLOWED, FAILED ou outro resultado terminal, explique somente o motivo retornado, não invente alternativa e encerre a resposta.", + "Você é um agente de pedidos de varejo. Use dados de tools quando disponíveis.", ), mcp_results=tool_context, rag_context=rag_context, diff --git a/Tuning-Performance/Normal/templates/agent_template_backend_day_zero/app/agents/product_agent.py b/Tuning-Performance/Normal/templates/agent_template_backend_day_zero/app/agents/product_agent.py index 998dad6..34433f5 100644 --- a/Tuning-Performance/Normal/templates/agent_template_backend_day_zero/app/agents/product_agent.py +++ b/Tuning-Performance/Normal/templates/agent_template_backend_day_zero/app/agents/product_agent.py @@ -95,7 +95,7 @@ class ProductAgent(AgentRuntimeMixin): state, system_prompt=apply_agent_profile_prompt( state, - "Você é um agente especialista em produtos, planos e serviços.\n\nUse dados de tools/MCP e RAG autorizados como fonte de verdade e responda somente à solicitação atual.\nNunca exponha identificadores técnicos ou de identidade presentes no estado, contexto ou MCP, incluindo customer_key, contract_key, account_key, resource_key, session_key, customer_id, document, message_id, ura_call_id ou MSISDN/telefone completo.\nNão transforme nomes internos de campos em rótulos para o cliente.\nEm consultas meramente informativas, não exponha flags ou capacidades transacionais internas como can.cancel e não informe espontaneamente que algo pode ser cancelado, alterado, contratado, removido ou trocado. Só mencione capacidade transacional quando o usuário tiver solicitado essa ação.\nNão faça oferta proativa e não execute nem simule mutações sem a confirmação exigida pelo framework.\nNão acrescente canais, procedimentos ou próximos passos não solicitados.\nSe uma tool retornar BLOCKED, OUT_OF_SCOPE, NOT_ALLOWED, FAILED ou outro resultado terminal, explique somente o motivo retornado, não declare sucesso, não invente alternativa e encerre a resposta.", + "Você é um agente especialista em produtos, planos e serviços. Explique sem fazer oferta proativa e sem executar ações sem confirmação. Use dados MCP quando disponíveis.", ), mcp_results=tool_context, rag_context=rag_context, diff --git a/Tuning-Performance/Normal/templates/agent_template_backend_day_zero/app/agents/support_agent.py b/Tuning-Performance/Normal/templates/agent_template_backend_day_zero/app/agents/support_agent.py index b15a0e4..b4f0244 100644 --- a/Tuning-Performance/Normal/templates/agent_template_backend_day_zero/app/agents/support_agent.py +++ b/Tuning-Performance/Normal/templates/agent_template_backend_day_zero/app/agents/support_agent.py @@ -95,7 +95,7 @@ class SupportAgent(AgentRuntimeMixin): state, system_prompt=apply_agent_profile_prompt( state, - "Você é um agente de suporte de varejo para troca, devolução e garantia.\n\nUse dados de tools/MCP e RAG autorizados como fonte de verdade e responda somente à solicitação atual.\nNunca exponha identificadores técnicos ou de identidade presentes no estado, contexto ou MCP, incluindo customer_key, contract_key, account_key, resource_key, session_key, customer_id, document, message_id, ura_call_id ou telefone completo.\nNão transforme nomes internos de campos em rótulos para o cliente.\nNão declare sucesso nem simule troca, devolução, garantia ou outra mutação se a tool não tiver confirmado a execução.\nNão acrescente canais, procedimentos, ofertas ou próximos passos não solicitados.\nSe uma tool retornar BLOCKED, OUT_OF_SCOPE, NOT_ALLOWED, FAILED ou outro resultado terminal, explique somente o motivo retornado, não invente alternativa e encerre a resposta.", + "Você é um agente de suporte de varejo para troca, devolução e garantia.", ), mcp_results=tool_context, rag_context=rag_context, diff --git a/Tuning-Performance/Normal/templates/agent_template_backend_day_zero/app/workflows/__pycache__/agent_graph.cpython-313.pyc b/Tuning-Performance/Normal/templates/agent_template_backend_day_zero/app/workflows/__pycache__/agent_graph.cpython-313.pyc index 3c19c45a004308fcee26ef8f06058a1ecf3b2803..ce2047c5b2e7473d6d9bed7cf734b4e1e34797d3 100644 GIT binary patch delta 7434 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 delta 10893 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 dict: - """Monta o contexto operacional do turno para os guardrails de saída. - - Mantém evidências/protocolos necessários aos rails, mas impede que uma - transação encerrada ou semanticamente interrompida governe o novo turno. - O histórico completo permanece no state/checkpoint para auditoria. - """ - ctx = dict(state.get("context", {}) or {}) - mcp_results = state.get("mcp_results") or [] - ctx["evidence"] = mcp_results or ctx.get("evidence") - ctx["tool_result"] = mcp_results or ctx.get("tool_result") - ctx["tool_executed"] = any(isinstance(r, dict) and r.get("ok") for r in mcp_results) - - history = list(state.get("history") or []) - current_user_text = str(state.get("user_text") or "").strip() - if current_user_text: - if ( - not history - or not isinstance(history[-1], dict) - or str(history[-1].get("content") or "") != current_user_text - or str(history[-1].get("role") or "") != "user" - ): - history.append({"role": "user", "content": current_user_text}) - - route_decision = state.get("route_decision") or {} - route_metadata = route_decision.get("metadata") if isinstance(route_decision, dict) else {} - route_metadata = route_metadata if isinstance(route_metadata, dict) else {} - pre_validation = state.get("transaction_pre_validation") or {} - pre_validation = pre_validation if isinstance(pre_validation, dict) else {} - tx_status = str( - state.get("transaction_status") or pre_validation.get("status") or "" - ).strip().upper() - terminal_tx = bool(pre_validation.get("terminal")) or tx_status in { - "COMPLETED", "FAILED", "CANCELLED", "BLOCKED", "OUT_OF_SCOPE" - } - semantic_intent_shift = ( - str(route_metadata.get("transaction_interruption") or "").strip().lower() - == "intent_shift" - ) - stickiness_intent_shift = bool(route_metadata.get("route_stickiness_preempted")) - should_isolate_history = semantic_intent_shift or (terminal_tx and stickiness_intent_shift) - - current_route = str( - state.get("route") - or (route_decision.get("route") if isinstance(route_decision, dict) else "") - or "" - ).strip() - current_intent = str( - state.get("intent") - or (route_decision.get("intent") if isinstance(route_decision, dict) else "") - or "" - ).strip() - ctx["current_user_message"] = current_user_text - ctx["current_route"] = current_route - ctx["current_intent"] = current_intent - - if should_isolate_history: - operational_history = ( - [{"role": "user", "content": current_user_text}] - if current_user_text else [] - ) - ctx["historical_transaction_ignored"] = True - ctx["historical_transaction_status"] = tx_status or ( - "INTERRUPTED" if semantic_intent_shift else "TERMINAL" - ) - if semantic_intent_shift: - ctx["historical_transaction_interruption"] = "intent_shift" - for stale_key in ( - "transaction_pre_validation", - "transaction_status", - "active_transaction", - "transaction", - ): - ctx.pop(stale_key, None) - else: - operational_history = history - - ctx["conversation_history"] = operational_history - ctx["history_texts"] = [ - str(item.get("content") or "") - for item in operational_history - if isinstance(item, dict) and item.get("content") not in (None, "") - ] - - protocols: list[str] = [] - seen: set[str] = set() - protocol_keys = { - "protocol_number", "protocolo_id", "interactionProtocol", - "protocolNumber", "finalizacao_protocol", - } - - def walk(value): - if isinstance(value, dict): - for key, item in value.items(): - if key in protocol_keys and item not in (None, ""): - text = str(item).strip() - if text and text not in seen: - seen.add(text) - protocols.append(text) - elif isinstance(item, (dict, list, tuple)): - walk(item) - elif isinstance(value, (list, tuple)): - for item in value: - walk(item) - - walk(mcp_results) - if protocols: - ctx["expected_protocols"] = protocols - ctx["requer_protocolo"] = True - ctx.setdefault("tipo_fluxo", "ajuste") - return ctx - async def output_supervisor(self, state): """Valida a resposta candidata com o OutputSupervisor corporativo. @@ -620,15 +553,15 @@ class AgentWorkflow: } candidate = state.get("answer") or "" - context = self._output_guardrail_context(state) - context.update({ + context = { + **(state.get("context") or {}), "tenant_id": state.get("tenant_id"), "agent_id": state.get("agent_id"), "session_id": state.get("conversation_key") or state.get("session_id"), "route": state.get("route"), "intent": state.get("intent"), "supervisor_attempt": int(state.get("supervisor_attempt", 0)), - }) + } async with self.telemetry.span( "workflow.output_supervisor", session_id=state.get("conversation_key") or state.get("session_id"), @@ -714,7 +647,7 @@ class AgentWorkflow: component="workflow.output_guardrails.start", ) final, decisions = await self.guardrails.run_output( - state["answer"], self._output_guardrail_context(state) + state["answer"], state.get("context", {}) ) for _decision in decisions: await self.guardrail_telemetry.evaluated("output", _decision) diff --git a/Tuning-Performance/Normal/templates/agent_template_backend_day_zero/config/routing.yaml b/Tuning-Performance/Normal/templates/agent_template_backend_day_zero/config/routing.yaml index 03aeaa9..bb4ef6f 100644 --- a/Tuning-Performance/Normal/templates/agent_template_backend_day_zero/config/routing.yaml +++ b/Tuning-Performance/Normal/templates/agent_template_backend_day_zero/config/routing.yaml @@ -7,6 +7,35 @@ router: confidence_threshold: 0.65 allow_handoff: true + transaction_confirmation: + # Explicit yes/no stays deterministic. Only inconclusive replies use this LLM fallback. + semantic_fallback: + enabled: true + allowed_values: [SIM, NAO, CONTINUAR] + confirm_values: [SIM] + reject_values: [NAO] + continue_values: [CONTINUAR] + include_relevant_context: true + profile_name: router + prompt: | + Você classifica a resposta do cliente a uma confirmação transacional pendente. + Considere a pergunta pendente, somente o histórico recente relacionado ao mesmo tema e a fala atual. + Não execute a ação e não invente fatos. + + Classes permitidas: {{ allowed_values }} + - SIM: confirmação/aceite inequívoco, inclusive equivalentes como "isso mesmo", "pode confirmar", "é isso" quando o contexto tornar o aceite claro. + - NAO: recusa/cancelamento inequívoco da ação pendente. + - CONTINUAR: qualquer resposta que não confirme nem rejeite inequivocamente, incluindo pergunta adicional, correção, novo dado, ambiguidade ou possível mudança de assunto. + + Pergunta pendente: + {{ pending_prompt }} + + Histórico relevante: + {{ relevant_conversation_context }} + + Resposta atual do cliente: + {{ user_input }} + state_policies: - state: WAITING_BILLING_CONFIRMATION agent: billing_agent diff --git a/Tuning-Performance/Normal/templates/agent_template_backend_day_zero/docs/TRANSACTION_SEMANTIC_CONFIRMATION.md b/Tuning-Performance/Normal/templates/agent_template_backend_day_zero/docs/TRANSACTION_SEMANTIC_CONFIRMATION.md new file mode 100644 index 0000000..a550871 --- /dev/null +++ b/Tuning-Performance/Normal/templates/agent_template_backend_day_zero/docs/TRANSACTION_SEMANTIC_CONFIRMATION.md @@ -0,0 +1,11 @@ +# Confirmação Transacional Semântica + +Este template suporta confirmação transacional em duas camadas: primeiro um parser determinístico para `sim`/`não` e equivalentes explícitos; somente quando ele não consegue decidir, o framework usa um classificador semântico configurado em `config/routing.yaml`. + +A configuração `router.transaction_confirmation.semantic_fallback` usa três classes: `SIM`, `NAO` e `CONTINUAR`. O prompt pode usar `{{ pending_prompt }}`, `{{ relevant_conversation_context }}`, `{{ user_input }}` e `{{ allowed_values }}`. O histórico injetado é apenas contexto de interpretação; não substitui validação de negócio ou evidência MCP. + +Exemplo: após `Você confirma o cancelamento do serviço Tamboro Mensal?`, a frase `isso mesmo, pode confirmar` pode ser classificada como `SIM`. Já `mas qual é o valor?` deve ser `CONTINUAR`, portanto não executa a ação por confirmação. + +Entradas explícitas já suportadas continuam no caminho determinístico e não geram custo adicional de LLM. Em observabilidade, o fallback usa `transaction.confirmation.semantic_classifier` e o `route_decision.metadata` informa `transaction_confirmation_source: semantic`. + +Consulte `docs/developer/pt/03_transaction_workflows_and_state.md` do framework para o contrato completo e exemplos. diff --git a/Tuning-Performance/Pause_Resume_Workflow/IMPLEMENTACAO_PAUSE_RESUME_LANGGRAPH.md b/Tuning-Performance/Pause_Resume_Workflow/IMPLEMENTACAO_PAUSE_RESUME_LANGGRAPH.md index 9b317c8..53682d6 100644 --- a/Tuning-Performance/Pause_Resume_Workflow/IMPLEMENTACAO_PAUSE_RESUME_LANGGRAPH.md +++ b/Tuning-Performance/Pause_Resume_Workflow/IMPLEMENTACAO_PAUSE_RESUME_LANGGRAPH.md @@ -13,3 +13,46 @@ O `WorkflowRuntime` também preserva o último snapshot persistido do LangGraph Isso é necessário para workflows transacionais: por exemplo, se um protocolo foi criado e uma chamada posterior falha, o chamador ainda recebe o `protocol_number` persistido e pode executar recuperação/idempotência sem repetir o primeiro side effect. O runtime não transforma falha em sucesso e não reexecuta automaticamente a action; ele apenas preserva a evidência durável já existente no checkpointer. + +## Tratamento genérico de entrada fora das opções (`unmatched`) + +`expected_input` mantém compatibilidade com o comportamento anterior. +Sem `semantic_classifier`, qualquer entrada que não pertença literalmente a +`allowed_values` permanece no workflow e recebe o `reprompt`. + +Quando o agente precisa aceitar linguagem natural, ele declara um prompt +classificatório cujo resultado deve ser uma das próprias opções dinâmicas: + +```yaml +expected_input: + key: resposta_usuario + allowed_values: [SIM, NAO] + normalize: upper_strip + reprompt: "Não entendi. Responda sim ou não." + semantic_classifier: + enabled: true + prompt: | + Classifique a fala em exatamente uma opção de {{ allowed_values }}. + Pergunta pendente: {{ pending_prompt }} + Fala do usuário: {{ user_input }} + Retorne somente uma opção de {{ allowed_values }}. +``` + +O framework não possui classes fixas. `allowed_values` pode conter duas, três ou +mais opções; o prompt do agente define a semântica de cada uma. O framework +renderiza os placeholders, chama a LLM e rejeita qualquer saída que não pertença +à allowlist, usando `reprompt` nesse caso. O texto original do usuário é mantido +nos metadados da decisão para auditoria. + +Nesse modo, `COER` delega a interpretação semântica ao classificador configurado. +Rails de segurança independentes — por exemplo PINJ, toxicidade, PII e limites +de tamanho — continuam podendo bloquear o turno normalmente. + +O exemplo executável está em `agent_template_backend/` e, por compatibilidade +com a estrutura histórica desta feature, também em +`agent_template_backend_pause_resume/`. + + +### Reentrada contextual por opção + +Uma opção do `semantic_classifier` pode declarar `option_actions..action: contextual_reentry`. Nesse caso o workflow pausado não é retomado: o framework libera a pausa e reexecuta o roteamento usando somente o contexto conversacional ancorado que originou a decisão mais a fala atual. A fala original é preservada para auditoria e o contexto reconstruído não vira evidência de negócio; parâmetros candidatos continuam sujeitos a validação e confirmação normais. diff --git a/Tuning-Performance/Pause_Resume_Workflow/README.md b/Tuning-Performance/Pause_Resume_Workflow/README.md index 13d92b4..1efe5af 100644 --- a/Tuning-Performance/Pause_Resume_Workflow/README.md +++ b/Tuning-Performance/Pause_Resume_Workflow/README.md @@ -32,3 +32,49 @@ O exemplo usa `MemorySaver` apenas para ser autocontido. Em aplicações reais u ## Regra arquitetural Código de domínio não deve importar `langgraph.graph.StateGraph`. Para grafos de agentes use `FrameworkStateGraph`; para workflows determinísticos de negócio use `WorkflowRuntime`. + +## Entrada enumerada, reprompt e `semantic_classifier` + +O contrato `expected_input` pode declarar qualquer conjunto de opções em +`allowed_values`. O match literal continua determinístico; quando a resposta não +coincide literalmente com uma opção, o agente pode habilitar um classificador +semântico com prompt próprio. + +```yaml +expected_input: + key: resposta_usuario + allowed_values: [SIM, NAO] + normalize: upper_strip + reprompt: "Não entendi. Responda sim ou não." + semantic_classifier: + enabled: true + prompt: | + Classifique {{ user_input }} em exatamente uma opção de {{ allowed_values }}. + Para este workflow, aceitação/entendimento => SIM; negação, nova pergunta + ou hipótese factual a validar => NAO. + Retorne somente uma opção de {{ allowed_values }}. +``` + +O framework não conhece o significado de `SIM`, `NAO` nem de nenhuma outra +opção. Ele apenas injeta `allowed_values`, `pending_prompt` e `user_input`, chama +a LLM e valida estritamente se a saída pertence à lista declarada. Uma saída +fora da lista usa o `reprompt`. + +O mesmo mecanismo funciona sem alteração do framework para, por exemplo, +`[CONFIRMAR, ALTERAR, CANCELAR]` ou qualquer outra lista configurada pelo agente. +O rail `COER` delega a semântica ao `semantic_classifier` nesse modo; PINJ, +toxicidade, PII e os demais rails de segurança continuam independentes. + +Há dois diretórios equivalentes para facilitar comparação com os demais +cenários de Tuning-Performance: + +- `agent_template_backend/` — nome padrão de template; +- `agent_template_backend_pause_resume/` — nome histórico deste exemplo. + +Ambos contêm o mesmo workflow `confirmacao.v1.yaml`. + + + +### Reentrada contextual por opção + +Uma opção do `semantic_classifier` pode declarar `option_actions..action: contextual_reentry`. Nesse caso o workflow pausado não é retomado: o framework libera a pausa e reexecuta o roteamento usando somente o contexto conversacional ancorado que originou a decisão mais a fala atual. A fala original é preservada para auditoria e o contexto reconstruído não vira evidência de negócio; parâmetros candidatos continuam sujeitos a validação e confirmação normais. diff --git a/Tuning-Performance/Pause_Resume_Workflow/agent_template_backend/README.md b/Tuning-Performance/Pause_Resume_Workflow/agent_template_backend/README.md new file mode 100644 index 0000000..6952974 --- /dev/null +++ b/Tuning-Performance/Pause_Resume_Workflow/agent_template_backend/README.md @@ -0,0 +1,26 @@ +# Agent Template Backend — Pause/Resume Workflow + +Exemplo autocontido de um agente que usa o motor genérico de workflows do +`agent_framework_oci`. + +O arquivo `workflows/confirmacao.v1.yaml` demonstra: + +- `pause`; +- `expected_input`; +- `allowed_values`; +- `normalize`; +- `reprompt`; +- `semantic_classifier`; +- `resume_from`. + +O framework não conhece `SIM`, `NAO` nem a regra de negócio. O agente declara +os valores e o prompt no YAML. Quando a fala não corresponde literalmente a uma +opção, `semantic_classifier` classifica usando o prompt do agente e o framework +aceita somente uma saída presente em `allowed_values`; qualquer outra saída usa +o `reprompt`. O mesmo mecanismo funciona com qualquer quantidade de opções. + +Execute os testes a partir desta pasta: + +```bash +pytest -q +``` diff --git a/Tuning-Performance/Pause_Resume_Workflow/agent_template_backend/app/__init__.py b/Tuning-Performance/Pause_Resume_Workflow/agent_template_backend/app/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/Tuning-Performance/Pause_Resume_Workflow/agent_template_backend/app/__pycache__/__init__.cpython-313.pyc b/Tuning-Performance/Pause_Resume_Workflow/agent_template_backend/app/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..41f7f0a938ff01aaa4f0391095cd1704909ee798 GIT binary patch literal 219 zcmXwz%?ZLl5QVcwL4*|ILAL?%=uv_Q9)~fRgf-b8HXEXL;lU!Tz+Q5-0!ahzLVSmr zZ7&-6`t8Y{)&=Z*|I3vVkFBFU7J*5%dG`ftyD>NBwG@=Vp~)~7b|i|uT1U| zv!opbNFg|fIOrj83?nX3AOe!2%1yWS*ff_Om!Mm*1E)xl0)=mK+@j5`Z<7;6-paT4h z3*x*)C6^~H$ny$S=6%#R@2CD4T9XFQT3`$}G^LI<{twf!=1c0>VQyos$}%iySXESC z0;?g_A4MC|hCtiYuo~cN8d+;sgX2FzNI#CynvjY;uLUfK3?T0u&z2a<3wa^l_Ly&o zV;0g)(<i3s7R|AEDQwAu_C zY8h{06-SXNr~*(?6@f}=oPs^iKB|-!#)JkphF&5gr^Wv%qokz+85Nmw8jUm$%eEn; z`c(gdFfW=4oT40r*_2lUo=vNv)++3+)WA95ddW!RH0V`>m!wlD9$L&a4R?ik72e}P znTEw6it$RsX_RUO$5RQ$U{B%qaLY*01+^)R;#255Vh+c}Mds6O8?s|ncqFEUuxl%C=Gk4_j-S@d(~;5a{NP?Z z_-5w}vB`!W%UEX40C#DO@=P=Q{Z9~ejcSCDc5-e2BAy2qz@ga79P%Xi20I3%;Zf8% zncP)&H>;ylPICJ9uQ+`(PW!CmpKbaSj(pQ6-WhK3T!cl#C-4Vze^kMR4KPdH7zI3~#D>l<>r7N%zgFQ;wbUw`me*N5QQ-)8_!G~3L5DAKf%0!G=*1{& z(QaToA0A(pWQ?pq*~ym#r}@1LcH2oHJTzZi82{aP^}^gAhiVs=s>es2bfF%NZAYuo zv%7LNI`%{sJA(U23h8g;)2kcJZGwz$vG$_H6Qg-4Vx6>sY{28^+PXz~E;(Xe zgZiYKs(zDD7T}f7A<_oS^yw}p+AN&8PBJ%2mSL7brVlXBx&>r%*LoZbmMlwLc;7}*&H#uwk}-n#nNQ0!j{3QYW^d*I$%cfx-U zMIZT3{;IrvquT#!&Hq}xqq~0emHN>5lYksn_K_?rPr($F;lz7*tls9R_#?o?~99a7@2sLN7a2`bnu8h^Qe+4UuvPPJ7E0J zh`_6=@D|HLy>uhOF}pPg4rBq#ajG>I4)I~IfQ3!#pR-UnWTEhXStz7lWMSa2g?Z#h zi(Bw})twZDuzu*_GKDC|h20Ows|@nOvgKEiA}&6trxmSYisFLKPd@ z3RJ=HU}5qG$yE5YLo>3x-si+$!odni7_}L!;;mGkQ z()$Z*>vH`_&j)Ako_+Av&ZaY-auRCo$jV-LWo!146u2|A7mQYe(QU;EMx7uO@<=_@ z@!rI{6A!*y3k^Ebpc5LbclCa-ba!d{+V0ri`Pu6ES?9`6oi*LLyk6_d>_swLm$|0l zyL!kgo)nzk;z&`JiMy&kXoP3+r6)adFE%fE$s6 z>!PN)DXjNQGD)ujk6(4{ zp8?qyF~*;xfiF?yb9DS4h*S~zn=f?d%G*ER^PQ;rPSkw;d%oeSZ+Hh+eP_0$eFa^( s^l#LUm4D7)ACB*LAt`+4&6?N)(Dcs2?S;G2J>^eQ_r8dvDCOt>7f2oEP5=M^ literal 0 HcmV?d00001 diff --git a/Tuning-Performance/Pause_Resume_Workflow/agent_template_backend/app/demo.py b/Tuning-Performance/Pause_Resume_Workflow/agent_template_backend/app/demo.py new file mode 100644 index 0000000..7e96bd4 --- /dev/null +++ b/Tuning-Performance/Pause_Resume_Workflow/agent_template_backend/app/demo.py @@ -0,0 +1,56 @@ +from __future__ import annotations + +import asyncio +from pathlib import Path + +from agent_framework.workflows import FileWorkflowRepository, WorkflowActionRegistry, WorkflowRuntime + +ROOT = Path(__file__).resolve().parents[1] + + +def build_runtime(*, offline_test_fallback: bool = False) -> WorkflowRuntime: + actions = WorkflowActionRegistry() + + async def preparar(params, state): + return {"assunto": params.get("assunto") or "operação"} + + async def perguntar(params, state): + return {"mensagem": f"Deseja confirmar {params['assunto']}?"} + + async def decidir(params, state): + return { + "mensagem": "Operação confirmada." if params["resposta"] == "SIM" else "Operação cancelada.", + "confirmado": params["resposta"] == "SIM", + } + + actions.register("preparar_operacao", preparar) + actions.register("montar_pergunta", perguntar) + actions.register("registrar_decisao", decidir) + + checkpointer = None + if not offline_test_fallback: + # Produção/exemplo real continua usando LangGraph + checkpointer. O import + # fica aqui para que a regressão offline do repositório não dependa de rede. + from langgraph.checkpoint.memory import MemorySaver + checkpointer = MemorySaver() + + return WorkflowRuntime( + FileWorkflowRepository(ROOT / "workflows"), + actions=actions, + checkpointer=checkpointer, + allow_deterministic_fallback=offline_test_fallback, + ) + + +async def main() -> None: + runtime = build_runtime() + first = await runtime.arun("confirmacao", {"assunto": "a alteração do plano"}) + print(first.model_dump(mode="json")) + assert first.status == "PAUSED" + resumed = await runtime.aresume("confirmacao", first.execution_id, {"resposta_usuario": "sim"}) + print(resumed.model_dump(mode="json")) + assert resumed.status == "COMPLETED" + + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/Tuning-Performance/Pause_Resume_Workflow/agent_template_backend/docs/TRANSACTION_SEMANTIC_CONFIRMATION.md b/Tuning-Performance/Pause_Resume_Workflow/agent_template_backend/docs/TRANSACTION_SEMANTIC_CONFIRMATION.md new file mode 100644 index 0000000..a550871 --- /dev/null +++ b/Tuning-Performance/Pause_Resume_Workflow/agent_template_backend/docs/TRANSACTION_SEMANTIC_CONFIRMATION.md @@ -0,0 +1,11 @@ +# Confirmação Transacional Semântica + +Este template suporta confirmação transacional em duas camadas: primeiro um parser determinístico para `sim`/`não` e equivalentes explícitos; somente quando ele não consegue decidir, o framework usa um classificador semântico configurado em `config/routing.yaml`. + +A configuração `router.transaction_confirmation.semantic_fallback` usa três classes: `SIM`, `NAO` e `CONTINUAR`. O prompt pode usar `{{ pending_prompt }}`, `{{ relevant_conversation_context }}`, `{{ user_input }}` e `{{ allowed_values }}`. O histórico injetado é apenas contexto de interpretação; não substitui validação de negócio ou evidência MCP. + +Exemplo: após `Você confirma o cancelamento do serviço Tamboro Mensal?`, a frase `isso mesmo, pode confirmar` pode ser classificada como `SIM`. Já `mas qual é o valor?` deve ser `CONTINUAR`, portanto não executa a ação por confirmação. + +Entradas explícitas já suportadas continuam no caminho determinístico e não geram custo adicional de LLM. Em observabilidade, o fallback usa `transaction.confirmation.semantic_classifier` e o `route_decision.metadata` informa `transaction_confirmation_source: semantic`. + +Consulte `docs/developer/pt/03_transaction_workflows_and_state.md` do framework para o contrato completo e exemplos. diff --git a/Tuning-Performance/Pause_Resume_Workflow/agent_template_backend/tests/__pycache__/test_pause_resume.cpython-313-pytest-9.0.2.pyc b/Tuning-Performance/Pause_Resume_Workflow/agent_template_backend/tests/__pycache__/test_pause_resume.cpython-313-pytest-9.0.2.pyc new file mode 100644 index 0000000000000000000000000000000000000000..96739456b1b9ff9b6c5e5e4b1914f7dff607278b GIT binary patch literal 7783 zcmd@ZOKcn0@$GU+QCx}C&$cW&5iQw?nZ}fDS&?K}ZWK$k{E;kc#Y(P{F4p8yW=!s~ zZ%J8_Yd}p>#D-fqE*eBJP{c@juun;EZhHw(AiV_Wu4sqCYjS9cqR1_cdvQ*kw?9&{ z0!2j%BTk29kOwY32R*KaqQB&c#{?^Wdj|yp9AUFelLo z1~UH`-|8qWKgXNPxPu8?3+l27 zTq}565Dw0;QQv2j7i9=9DTxt8h!Rx-TmD?vx9{A@#UrpvZ~GdBtRQZcu>vb2L$jylc2oXRU%Uz&Bkv7w~L zkrV@|}+5k1@&GuVs4=*nZp8 zFUz(Unm4s;T33B#-CZ-i!~|fFdF@i1vZqdbtHwB7-z<9KnM#v;sHBugPVxkprgxq+HvcLxb24%9DKO;50O??MX4wCq^fr6xgDsQkk?Oi+Neg zizz9SIVUA95I&(QsWi??2}vbYlBPkape_W}NJ3H)az@I^Koj5CKwKCayu*CS_V-7b zh1l*rx%mT8EpW+3BK;AH?TczL4eF1A7PuVgw|HGqjdVp_=+^2BpNo+ou!)^aN777JQI!fEvmv(P|4xj(8oUpg4o z?yywHehLnLS*iUQOZzj#CnackMCx-`&PiCpqMDO2UH)e@`G>{rqiQ>y#Q{=Y+#dUj z(em<4#Ti*4zH@R)#d4IxkeVS(Gio}GP7IkITD8(1Yc4&+BOD(g)kjZ{jGY>q7#bv1 zu*gDIP7<$_%FCE=vl7-wRZ>o*lW9x>j<1ridcvl)N*km#(~4k&XalAt65%AM`-so- z2MIizn>SrAVNx$9!2co`04LNeSV1N=@LHtRVm_^C#FtS)LL<$hc3v&e3KB%cnT&c) z%7_XC1*sM_DJ4@j2@aS}1fvdNtYXqAf*rC_UIag8B*m;oi8m(|G?{qwU}~9oX5>7k z*)D{fwPsQy&&i1bb&Z$?1JGH^(Rwh6Rl8zZ;SrwB(u$e=mBhhHqSGR*Njy_Y^i+!N zt0WFoigi^I-Goc$H$R7UgYN;StZ|*l=4!CCTAt6#}i^I zJ=Y=4zy=dj7;Jh`#TP_1k?xo%C~0M8@0g6uHNZaX7^Bt`$Ib8%CqXckQ7_tqVRm5W zye!fUEi1_m>SoP^qG@&T9u2ElZl3HnL!go?CRJGzp=&^WEQ8lzU(BY}f+kuU1s{j? z`02t@kQRQ17SX@`D753fT}H5b@z_ek_BWos@$}N=+w=ON6MF1qvEfvy=G5ZQ3SW2q z@YTaQ*S^$a0)uZaarV8;wO={xQWkO_cwH{fC{y%>EnKA9Tp1SuHvL@R)joaOlLo)% z_7;Qh(77SKbI5`QKUCuEdl~qAheh72z>B85E9N4=UuoU-)}@=5inUWWFTIw3_xzpn z@68os&+3DdMr`tW^36+&KhSHZKIVg0X0P?>TzF}x2@F15;_SP~g|GCvl!e^q!oTQr zdB!TrVt)jqW-BEe3WhrBK=aa0SH?wvz0wqZJSV2t4(>Ca30v2(?y zL@Ag6@9_=Sk6b;Xb9h2E!Ld9nSCw!?%bWZyZ&OwfIc*3bWB~Jcr&{=q}QCKb}U>wq;oAx^(MIb{Swz= z-9@hD$|0Asko#NJj;9iB1;sr=HPzqfw)&iTDqNfs0%oenn=|mny+VzN`Gi_^HeR((E33g)jmFn) zq6tAWZ46D#l-nuOMAqX~iujf}|=3VUS6m!zV!#;i$if zUxe%x%qN;Pi<+60sTih)B-OMs5HqR-p2D(}go<-64-Nu|_tF`~C^$d?#00_z0YrII zJAMIh(1g_&p#mfv&6n{Q<@ueW5D(BXM<{rXf}<1+0?^G@DxLzBO%x_vxL( zMtHc?A{Z@#{z6g**diDC)Z*aBbxlUonOn)*-EU`$O=pUAXBLmIgqoMO8KIqe+W{lg zxj4MSH@|}gc>sn-(GUqhm=*E`41tCrUx6@iN>toI$?c+5)W)ou5Q@hb zmM>x`*hsa@q9JPX%;HmvXsSQqHP&wVajk1=<0bR}yK}ta{8Cz-Qn?_&f#X zvEo0RRg;B`d<0|Q(L+w_0r0tpVVF-)+dmO{1-)GR57hR#53&AN!#@j`m?nd1`WIWv VJjXonAa={=78(gKrx{c8e*jx5&^iDB literal 0 HcmV?d00001 diff --git a/Tuning-Performance/Pause_Resume_Workflow/agent_template_backend/tests/test_pause_resume.py b/Tuning-Performance/Pause_Resume_Workflow/agent_template_backend/tests/test_pause_resume.py new file mode 100644 index 0000000..52a5922 --- /dev/null +++ b/Tuning-Performance/Pause_Resume_Workflow/agent_template_backend/tests/test_pause_resume.py @@ -0,0 +1,35 @@ +from __future__ import annotations + +import pytest + +from app.demo import build_runtime + + +@pytest.mark.asyncio +async def test_pause_resume_does_not_repeat_previous_action(): + # Regressão offline: exercita a mesma DSL/WorkflowRuntime sem exigir download + # de LangGraph no builder. Produção continua usando build_runtime() default. + runtime = build_runtime(offline_test_fallback=True) + first = await runtime.arun("confirmacao", {"assunto": "o cancelamento"}) + assert first.status == "PAUSED" + assert first.pause["expected_input"]["key"] == "resposta_usuario" + before = [item for item in first.trace if item.get("action") == "preparar_operacao"] + assert len(before) == 1 + resumed = await runtime.aresume("confirmacao", first.execution_id, {"resposta_usuario": "SIM"}) + assert resumed.status == "COMPLETED" + after = [item for item in resumed.trace if item.get("action") == "preparar_operacao"] + assert len(after) == 1 + assert resumed.state["vars"]["decidir"]["confirmado"] is True + + +def test_pause_resume_example_documents_semantic_classifier(): + from pathlib import Path + import yaml + + project = Path(__file__).resolve().parents[1] + data = yaml.safe_load((project / "workflows" / "confirmacao.v1.yaml").read_text(encoding="utf-8")) + perguntar = next(node for node in data["nodes"] if node["id"] == "perguntar") + expected = perguntar["pause"]["expected_input"] + assert expected["reprompt"] == "Não entendi. Responda sim ou não." + assert expected["semantic_classifier"]["enabled"] is True + assert "{{ allowed_values }}" in expected["semantic_classifier"]["prompt"] diff --git a/Tuning-Performance/Pause_Resume_Workflow/agent_template_backend/workflows/confirmacao.active.yaml b/Tuning-Performance/Pause_Resume_Workflow/agent_template_backend/workflows/confirmacao.active.yaml new file mode 100644 index 0000000..b825518 --- /dev/null +++ b/Tuning-Performance/Pause_Resume_Workflow/agent_template_backend/workflows/confirmacao.active.yaml @@ -0,0 +1 @@ +version: 1 diff --git a/Tuning-Performance/Pause_Resume_Workflow/agent_template_backend/workflows/confirmacao.v1.yaml b/Tuning-Performance/Pause_Resume_Workflow/agent_template_backend/workflows/confirmacao.v1.yaml new file mode 100644 index 0000000..2e723ce --- /dev/null +++ b/Tuning-Performance/Pause_Resume_Workflow/agent_template_backend/workflows/confirmacao.v1.yaml @@ -0,0 +1,45 @@ +name: confirmacao +version: 1 +start: preparar +nodes: + - id: preparar + action: preparar_operacao + input: + assunto: $.input.assunto + - id: perguntar + action: montar_pergunta + input: + assunto: $.vars.preparar.assunto + pause: + enabled: true + return_from: $.output.mensagem + expected_input: + key: resposta_usuario + allowed_values: [SIM, NAO] + normalize: upper_strip + reprompt: "Não entendi. Responda sim ou não." + semantic_classifier: + include_relevant_context: true + enabled: true + prompt: | + Classifique a resposta em exatamente uma opção de {{ allowed_values }}. + Pergunta pendente: {{ pending_prompt }} + Contexto relevante: + {{ relevant_conversation_context }} + Resposta do usuário: {{ user_input }} + Neste exemplo, concordância/aceitação corresponde a SIM e recusa, dúvida + adicional ou nova condição corresponde a NAO. + Retorne somente uma opção de {{ allowed_values }}. + resume_from: decidir + - id: decidir + action: registrar_decisao + input: + resposta: $.input.resposta_usuario + assunto: $.vars.preparar.assunto +edges: + - from: preparar + to: perguntar + - from: perguntar + to: END + - from: decidir + to: END diff --git a/Tuning-Performance/Pause_Resume_Workflow/agent_template_backend_pause_resume/app/__pycache__/__init__.cpython-313.pyc b/Tuning-Performance/Pause_Resume_Workflow/agent_template_backend_pause_resume/app/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a8d37181a3271c6fa8aed71d72989638984a3dee GIT binary patch literal 232 zcmXwzO$x$53`RRvL4+Q}h0X=UrAsLyxD2sP%h=8j(<$l+T)XfPp1`}f^#sxjI8*Ak zNM6Vbq)U=nhO zq#P6$C7rdcKxcyQTP0MvNXZu3dN(7UV%rexsA(m^!HY$$&%?1JX=-!?N6acxIhbCy kz0A=V4j`0p084XyPghdsZB1)C@qdNCn*iUKF=k^=KQ5O<@Bjb+ literal 0 HcmV?d00001 diff --git a/Tuning-Performance/Pause_Resume_Workflow/agent_template_backend_pause_resume/app/__pycache__/demo.cpython-313.pyc b/Tuning-Performance/Pause_Resume_Workflow/agent_template_backend_pause_resume/app/__pycache__/demo.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..aca91b75fc30f12560197ae96a2d44869966b8de GIT binary patch literal 3103 zcma)8UrZax8K2pmUH`>ENE)4rCN$N@+CGJS^LW zkm6JP3&Ol;%5aK&;AT@=4R|)KhFY_*H&X)Vfa?V#jnkl430@+nP&~AlX&UYd^DMm2 zoiYuRK@{Veh|?(5a*n4GjKQA5@8Fh^pbK(S7{#a1x5ONdi;K*s*)~MSs_@*mN;=g( z{mrKzSr8;Kua`d-m|W7RRngl=Zl zk}FJI;iOh7C9`_bN|ZL4zeIIz9cBIN6{C<aQGB~|Mz{41Etav&oB?;IG0MZv@OM8()HSN%Puj`30dRjFt^gN`z3M`q z1m9rCfHZCtbxtOC<=xHd=#-P3{{3rC-;C2f>-cAzcM3V=4P(gw@{ zkDqI67Ui+z@OcgLlWr>7O`Wm;F9VL3HUOwka{m0r8cY$o7$B|RD$my-iUlJ@$<1b|_ z%>gA+a6gQs@E+-^k}l`y$j->*;1PM_5MyL#7#N>_qkHS>Uqi8f$tW=K zm+pc4@7xXlJrsTHKlzLD_Kj-)>oxxy^^WfP(bwuj<4*%pSl&mHBtHXFP=*t4a9`cw z5cvZD#YSSkq<0_yP0`zO@ULJ+P@t4Olz$VN`*o1Ji64lIQW%+dm3!44&_}q(o*N2L zq)RR6b-RuKIT83&WL{!f$d_)Ua{zC3g#%dtcARSUh(mnnGGJlT`WGw|4p}JtUlt0f zmsuD%Y+)Yx(c%{TUU%C@aFK<)YK7WxA+rBct=JWf8Wt06qsRi^U%Iw@b#`TT2GW-293vXwI+IEis)Yr)j)I!4 z6iZCzEvaHdSv8si3+r#`nF@b{s7998TeBfB3DDOr!?)W+vNrb~qpPw_{>rkQ~V`AYB-EEwyQH%iv?T(?iOu+9Y^ z7q{F4xDh#cJF2Q10;_OS=c*{Y6>NG2RJnn6L%>B%cs+oq2+?b_g0o!2ZIS*7h<~M^ zPtvQvPKEH@t(Z zzB5~7Uq%-${TuaT`JXe`hvWNQh=lLHT@!l%n%-Twy>O4*m;Xe%_eDgal%M}!SFr2I literal 0 HcmV?d00001 diff --git a/Tuning-Performance/Pause_Resume_Workflow/agent_template_backend_pause_resume/docs/TRANSACTION_SEMANTIC_CONFIRMATION.md b/Tuning-Performance/Pause_Resume_Workflow/agent_template_backend_pause_resume/docs/TRANSACTION_SEMANTIC_CONFIRMATION.md new file mode 100644 index 0000000..a550871 --- /dev/null +++ b/Tuning-Performance/Pause_Resume_Workflow/agent_template_backend_pause_resume/docs/TRANSACTION_SEMANTIC_CONFIRMATION.md @@ -0,0 +1,11 @@ +# Confirmação Transacional Semântica + +Este template suporta confirmação transacional em duas camadas: primeiro um parser determinístico para `sim`/`não` e equivalentes explícitos; somente quando ele não consegue decidir, o framework usa um classificador semântico configurado em `config/routing.yaml`. + +A configuração `router.transaction_confirmation.semantic_fallback` usa três classes: `SIM`, `NAO` e `CONTINUAR`. O prompt pode usar `{{ pending_prompt }}`, `{{ relevant_conversation_context }}`, `{{ user_input }}` e `{{ allowed_values }}`. O histórico injetado é apenas contexto de interpretação; não substitui validação de negócio ou evidência MCP. + +Exemplo: após `Você confirma o cancelamento do serviço Tamboro Mensal?`, a frase `isso mesmo, pode confirmar` pode ser classificada como `SIM`. Já `mas qual é o valor?` deve ser `CONTINUAR`, portanto não executa a ação por confirmação. + +Entradas explícitas já suportadas continuam no caminho determinístico e não geram custo adicional de LLM. Em observabilidade, o fallback usa `transaction.confirmation.semantic_classifier` e o `route_decision.metadata` informa `transaction_confirmation_source: semantic`. + +Consulte `docs/developer/pt/03_transaction_workflows_and_state.md` do framework para o contrato completo e exemplos. diff --git a/Tuning-Performance/Pause_Resume_Workflow/agent_template_backend_pause_resume/tests/__pycache__/test_pause_resume.cpython-313-pytest-9.0.2.pyc b/Tuning-Performance/Pause_Resume_Workflow/agent_template_backend_pause_resume/tests/__pycache__/test_pause_resume.cpython-313-pytest-9.0.2.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2d339c6d11422a4643a2278d77bcec70a4dc4fb6 GIT binary patch literal 7796 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 W)-umA_dSSh{=z~d0p=uQYW@$@rq#3n literal 0 HcmV?d00001 diff --git a/Tuning-Performance/Pause_Resume_Workflow/agent_template_backend_pause_resume/tests/test_pause_resume.py b/Tuning-Performance/Pause_Resume_Workflow/agent_template_backend_pause_resume/tests/test_pause_resume.py index d764998..52a5922 100644 --- a/Tuning-Performance/Pause_Resume_Workflow/agent_template_backend_pause_resume/tests/test_pause_resume.py +++ b/Tuning-Performance/Pause_Resume_Workflow/agent_template_backend_pause_resume/tests/test_pause_resume.py @@ -20,3 +20,16 @@ async def test_pause_resume_does_not_repeat_previous_action(): after = [item for item in resumed.trace if item.get("action") == "preparar_operacao"] assert len(after) == 1 assert resumed.state["vars"]["decidir"]["confirmado"] is True + + +def test_pause_resume_example_documents_semantic_classifier(): + from pathlib import Path + import yaml + + project = Path(__file__).resolve().parents[1] + data = yaml.safe_load((project / "workflows" / "confirmacao.v1.yaml").read_text(encoding="utf-8")) + perguntar = next(node for node in data["nodes"] if node["id"] == "perguntar") + expected = perguntar["pause"]["expected_input"] + assert expected["reprompt"] == "Não entendi. Responda sim ou não." + assert expected["semantic_classifier"]["enabled"] is True + assert "{{ allowed_values }}" in expected["semantic_classifier"]["prompt"] diff --git a/Tuning-Performance/Pause_Resume_Workflow/agent_template_backend_pause_resume/workflows/confirmacao.v1.yaml b/Tuning-Performance/Pause_Resume_Workflow/agent_template_backend_pause_resume/workflows/confirmacao.v1.yaml index 923d17f..2e723ce 100644 --- a/Tuning-Performance/Pause_Resume_Workflow/agent_template_backend_pause_resume/workflows/confirmacao.v1.yaml +++ b/Tuning-Performance/Pause_Resume_Workflow/agent_template_backend_pause_resume/workflows/confirmacao.v1.yaml @@ -17,6 +17,19 @@ nodes: key: resposta_usuario allowed_values: [SIM, NAO] normalize: upper_strip + reprompt: "Não entendi. Responda sim ou não." + semantic_classifier: + include_relevant_context: true + enabled: true + prompt: | + Classifique a resposta em exatamente uma opção de {{ allowed_values }}. + Pergunta pendente: {{ pending_prompt }} + Contexto relevante: + {{ relevant_conversation_context }} + Resposta do usuário: {{ user_input }} + Neste exemplo, concordância/aceitação corresponde a SIM e recusa, dúvida + adicional ou nova condição corresponde a NAO. + Retorne somente uma opção de {{ allowed_values }}. resume_from: decidir - id: decidir action: registrar_decisao diff --git a/Tuning-Performance/Route_Stickness/templates/agent_template_backend/app/agents/billing_agent.py b/Tuning-Performance/Route_Stickness/templates/agent_template_backend/app/agents/billing_agent.py index 05254d1..aa60099 100644 --- a/Tuning-Performance/Route_Stickness/templates/agent_template_backend/app/agents/billing_agent.py +++ b/Tuning-Performance/Route_Stickness/templates/agent_template_backend/app/agents/billing_agent.py @@ -95,7 +95,7 @@ class BillingAgent(AgentRuntimeMixin): state, system_prompt=apply_agent_profile_prompt( state, - "Você é um agente especialista em faturas.\n\nUse dados de tools/MCP e RAG autorizados como fonte de verdade para responder somente à solicitação atual.\nNunca exponha identificadores técnicos ou de identidade presentes no estado, contexto ou MCP, incluindo customer_key, contract_key, account_key, resource_key, session_key, customer_id, document, message_id, ura_call_id ou MSISDN/telefone completo.\nNão transforme nomes internos de campos em rótulos para o cliente, como “contract_key”, “customer_key” ou “MSISDN”.\nPara consultas informativas de fatura, apresente somente dados de negócio necessários, como valor, vencimento, situação e itens cobrados.\nNão acrescente canais, telefones, códigos USSD, URLs, aplicativos, lojas, relatórios adicionais, procedimentos alternativos ou próximos passos que não tenham sido explicitamente retornados pela tool/RAG e solicitados pelo usuário.\nNão ofereça espontaneamente outras ações ou detalhamentos.\nSe uma tool retornar BLOCKED, OUT_OF_SCOPE, NOT_ALLOWED, FAILED ou outro resultado terminal, explique somente o motivo retornado, não declare sucesso, não invente alternativa e encerre a resposta.", + "Você é um agente especialista em faturas. Responda com clareza, objetividade e sem sugerir ações não solicitadas. Use dados MCP quando disponíveis.", ), mcp_results=tool_context, rag_context=rag_context, diff --git a/Tuning-Performance/Route_Stickness/templates/agent_template_backend/app/agents/orders_agent.py b/Tuning-Performance/Route_Stickness/templates/agent_template_backend/app/agents/orders_agent.py index b793c26..f557bed 100644 --- a/Tuning-Performance/Route_Stickness/templates/agent_template_backend/app/agents/orders_agent.py +++ b/Tuning-Performance/Route_Stickness/templates/agent_template_backend/app/agents/orders_agent.py @@ -95,7 +95,7 @@ class OrdersAgent(AgentRuntimeMixin): state, system_prompt=apply_agent_profile_prompt( state, - "Você é um agente de pedidos de varejo.\n\nUse dados de tools/MCP e RAG autorizados como fonte de verdade e responda somente à solicitação atual.\nNunca exponha identificadores técnicos ou de identidade presentes no estado, contexto ou MCP, incluindo customer_key, contract_key, account_key, resource_key, session_key, customer_id, document, message_id, ura_call_id ou telefone completo.\nNão transforme nomes internos de campos em rótulos para o cliente.\nNão declare sucesso, alteração, troca, cancelamento ou qualquer mutação se a tool não tiver confirmado a execução.\nNão acrescente canais, procedimentos, ofertas ou próximos passos não solicitados.\nSe uma tool retornar BLOCKED, OUT_OF_SCOPE, NOT_ALLOWED, FAILED ou outro resultado terminal, explique somente o motivo retornado, não invente alternativa e encerre a resposta.", + "Você é um agente de pedidos de varejo. Use dados de tools quando disponíveis.", ), mcp_results=tool_context, rag_context=rag_context, diff --git a/Tuning-Performance/Route_Stickness/templates/agent_template_backend/app/agents/product_agent.py b/Tuning-Performance/Route_Stickness/templates/agent_template_backend/app/agents/product_agent.py index 998dad6..34433f5 100644 --- a/Tuning-Performance/Route_Stickness/templates/agent_template_backend/app/agents/product_agent.py +++ b/Tuning-Performance/Route_Stickness/templates/agent_template_backend/app/agents/product_agent.py @@ -95,7 +95,7 @@ class ProductAgent(AgentRuntimeMixin): state, system_prompt=apply_agent_profile_prompt( state, - "Você é um agente especialista em produtos, planos e serviços.\n\nUse dados de tools/MCP e RAG autorizados como fonte de verdade e responda somente à solicitação atual.\nNunca exponha identificadores técnicos ou de identidade presentes no estado, contexto ou MCP, incluindo customer_key, contract_key, account_key, resource_key, session_key, customer_id, document, message_id, ura_call_id ou MSISDN/telefone completo.\nNão transforme nomes internos de campos em rótulos para o cliente.\nEm consultas meramente informativas, não exponha flags ou capacidades transacionais internas como can.cancel e não informe espontaneamente que algo pode ser cancelado, alterado, contratado, removido ou trocado. Só mencione capacidade transacional quando o usuário tiver solicitado essa ação.\nNão faça oferta proativa e não execute nem simule mutações sem a confirmação exigida pelo framework.\nNão acrescente canais, procedimentos ou próximos passos não solicitados.\nSe uma tool retornar BLOCKED, OUT_OF_SCOPE, NOT_ALLOWED, FAILED ou outro resultado terminal, explique somente o motivo retornado, não declare sucesso, não invente alternativa e encerre a resposta.", + "Você é um agente especialista em produtos, planos e serviços. Explique sem fazer oferta proativa e sem executar ações sem confirmação. Use dados MCP quando disponíveis.", ), mcp_results=tool_context, rag_context=rag_context, diff --git a/Tuning-Performance/Route_Stickness/templates/agent_template_backend/app/agents/support_agent.py b/Tuning-Performance/Route_Stickness/templates/agent_template_backend/app/agents/support_agent.py index b15a0e4..b4f0244 100644 --- a/Tuning-Performance/Route_Stickness/templates/agent_template_backend/app/agents/support_agent.py +++ b/Tuning-Performance/Route_Stickness/templates/agent_template_backend/app/agents/support_agent.py @@ -95,7 +95,7 @@ class SupportAgent(AgentRuntimeMixin): state, system_prompt=apply_agent_profile_prompt( state, - "Você é um agente de suporte de varejo para troca, devolução e garantia.\n\nUse dados de tools/MCP e RAG autorizados como fonte de verdade e responda somente à solicitação atual.\nNunca exponha identificadores técnicos ou de identidade presentes no estado, contexto ou MCP, incluindo customer_key, contract_key, account_key, resource_key, session_key, customer_id, document, message_id, ura_call_id ou telefone completo.\nNão transforme nomes internos de campos em rótulos para o cliente.\nNão declare sucesso nem simule troca, devolução, garantia ou outra mutação se a tool não tiver confirmado a execução.\nNão acrescente canais, procedimentos, ofertas ou próximos passos não solicitados.\nSe uma tool retornar BLOCKED, OUT_OF_SCOPE, NOT_ALLOWED, FAILED ou outro resultado terminal, explique somente o motivo retornado, não invente alternativa e encerre a resposta.", + "Você é um agente de suporte de varejo para troca, devolução e garantia.", ), mcp_results=tool_context, rag_context=rag_context, diff --git a/Tuning-Performance/Route_Stickness/templates/agent_template_backend/app/presentation/__pycache__/tool_renderers.cpython-313.pyc b/Tuning-Performance/Route_Stickness/templates/agent_template_backend/app/presentation/__pycache__/tool_renderers.cpython-313.pyc index 8c88b043079575f95b21ed4ce2bd9fae93142177..567eb4dcb26331acc08869aa04106d30e73d78d5 100644 GIT binary patch delta 786 zcmZ`%&ubGw6y8a8lbAHy*8HexO*^Kk5?YDUsx&RZVq1S8MOvyzDa()yB{kU%Gm}Eo z3VM;81RcEi2MG4mQV%_g2aoY41L8q?7c7Y4!8fVLx-j2%XxVQYOTJ|U=pVPTM$TMNXr-B0#q&fo7{QQ>H>!e^NddDUoO%ly`7?OI;wD6r zhcY8)fONy+nmjQ+NA1>DtJWU4w42-w9iVok&^8PEW8nuVqyk((VlG>ep=sq`qe2Bp zy-wY-GS|I|n+q{r8cS$MYUtB20HCZoVS=->`a@cNjf`3upfTCq^%|x2ce=j$P+C6k z9v)PY4N~=(BRoN>&7S)@z@4Cg7qjwluz$qQA2o8m1!XjYw*_^10XKb9SRo7r3~GZR z0QoVPxyLZDT-S+ZWwkO5psZ@erCeDZ7iCoht#M^DxEE!#>>S6Ye#!Zs%hm*(Ik&&v za}7b|?|S_RW#z%?EtAE-bs}~b73I^|=6PL-@)LLSKW*vwUzIq1-I@XEq@?keffTTk z@uD4$MA o?m&oO@rwZ8p)2T%kvTMyhsLd=fQkB#Y=owcLbBc$H}y6D0!;kD(f|Me delta 1859 zcmZ`(T}%{L6u!gk?Cjs{E-ou{5x6ctvVyF*intJK>n{js*sLa^G2`w?24QAz_~zbo zzH`2F&)hTj!qZXjQ%Q0mc&u;cMt=6+^WNsX??%ToGn$r7IVzvuLx14@tZ@K?M~Hix z27DhSxFqjIiLw|UX(!_EcB;0T~2H>f6Vb*0M? z>JNd*MW66NPNF}FQOR2>Lvyd$>wV8Ho}?Q@pkkRto`y(IY7?Ln4pTvU9d*K`(r#bU z4ch(}&gUtm@uC+`*Z(0xZiFF8^RrgSO^~G6AHF=XfzCVXCmq|sSBl4IsQeifcqMBh z5PuH}15cu2&{y)Wzt@=!C}D3vkzh6t-a$o6D@2`;v7wJCnyKKFJeJW7oK~==3@}+)=<0bjC8u?w7}#9ClhV|bZbXmw^xzDbSULl1I?l-B zqq>~N{rivO=8R6T@}@GD8P)Nap&Dte)s@N`CdiYsYPuDt^;DLXf)#u&Yp9xHOd9xt zGHyh$w)}|>m0eWEu%QqT(KGTe=o?tpan{H#e@s-p&1G>z6C2Oq14R$iY-CGy$1V3o zc~mE7P2H47E!RawOQ}pux9o-qM>7Ui{U;a$7a4Ip*nr6v5ju6JY`{Vjo)ga_;yCL8 zdqOp{^75xpS)6t|L+wIQU_vN{u8KXTq8V|#TGoYsVZ&f?IO4SUVa2rUawY@qr_QK zdXx|M?*I$C3C7zXJcWMqAb^_-NeiRGl7InS=Cg9Xoq+1{Dnxhr{3Bkam6uZOON z=KJ#Hk*VH-6qr3Vb86m^mo`rwqHnqC<6`-IC@B=2ixLB5KaD+Pb;BY)$4 zf8(vxVoScM}L6$h#d zFErj9S!} z*bYE{b+!xLusE<(@7m2l$wO|QkeUpgwe?B3}W=QFD&%IQl;Pe_HZ#O`tjjn z%Zo>3eP8va)s#78n4}fIrj4Ij`wjyvy!bJS#D3ULxPXH%;{jb$B4wnXYW~6Qmq|0d zXZmc#=Eib#kLl^`sIr$NU<*Tpj5hkWzpA!@+r2Wtxw-JlrXW|nvfahme-GKXV;o^; F{0Eh+$~FK1 diff --git a/Tuning-Performance/Route_Stickness/templates/agent_template_backend/app/presentation/tool_renderers.py b/Tuning-Performance/Route_Stickness/templates/agent_template_backend/app/presentation/tool_renderers.py index cb44202..f77c47a 100644 --- a/Tuning-Performance/Route_Stickness/templates/agent_template_backend/app/presentation/tool_renderers.py +++ b/Tuning-Performance/Route_Stickness/templates/agent_template_backend/app/presentation/tool_renderers.py @@ -13,42 +13,7 @@ def _money_brl(value: Any) -> str: def render_telecom_invoice(*, tool_name: str, result: dict[str, Any], state: dict[str, Any], agent_label: str) -> str | None: - """Renderiza somente campos de negócio seguros da fatura. - - Identificadores técnicos/PII presentes no payload MCP (por exemplo msisdn, - customer_id, document e business keys) não devem ser propagados ao usuário. - """ - lines = [f"[{agent_label}] Dados da sua fatura:"] - total = result.get("valor_total") - vencimento = result.get("vencimento") - status = result.get("status") - if total is not None: - lines.append(f"Valor total: R$ {_money_brl(total)}.") - if vencimento not in (None, ""): - lines.append(f"Vencimento: {vencimento}.") - if status not in (None, ""): - lines.append(f"Situação: {status}.") - - items = result.get("itens") or [] - rendered_items: list[str] = [] - if isinstance(items, list): - for item in items: - if not isinstance(item, dict): - continue - description = item.get("descricao") or item.get("nome") - value = item.get("valor") - if description in (None, ""): - continue - if value is None: - rendered_items.append(str(description)) - else: - rendered_items.append(f"{description}: R$ {_money_brl(value)}") - if rendered_items: - lines.append("Itens: " + "; ".join(rendered_items) + ".") - - # Se não houver nenhum campo de negócio seguro além do cabeçalho, deixe a - # composição pela LLM/guardrails em vez de despejar o payload bruto. - return " ".join(lines) if len(lines) > 1 else None + return f"[{agent_label}] Fatura consultada: {result}." def render_telecom_plan(*, tool_name: str, result: dict[str, Any], state: dict[str, Any], agent_label: str) -> str | None: diff --git a/Tuning-Performance/Route_Stickness/templates/agent_template_backend/app/workflows/__pycache__/agent_graph.cpython-313.pyc b/Tuning-Performance/Route_Stickness/templates/agent_template_backend/app/workflows/__pycache__/agent_graph.cpython-313.pyc index 91f49fc4b49e4e6a6108154d1780f8b1ba2dc60e..03dc5e99a87a849f060f067608eee3afec424c06 100644 GIT binary patch delta 7434 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 delta 10893 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 dict: - """Monta o contexto operacional do turno para os guardrails de saída. - - Mantém evidências/protocolos necessários aos rails, mas impede que uma - transação encerrada ou semanticamente interrompida governe o novo turno. - O histórico completo permanece no state/checkpoint para auditoria. - """ - ctx = dict(state.get("context", {}) or {}) - mcp_results = state.get("mcp_results") or [] - ctx["evidence"] = mcp_results or ctx.get("evidence") - ctx["tool_result"] = mcp_results or ctx.get("tool_result") - ctx["tool_executed"] = any(isinstance(r, dict) and r.get("ok") for r in mcp_results) - - history = list(state.get("history") or []) - current_user_text = str(state.get("user_text") or "").strip() - if current_user_text: - if ( - not history - or not isinstance(history[-1], dict) - or str(history[-1].get("content") or "") != current_user_text - or str(history[-1].get("role") or "") != "user" - ): - history.append({"role": "user", "content": current_user_text}) - - route_decision = state.get("route_decision") or {} - route_metadata = route_decision.get("metadata") if isinstance(route_decision, dict) else {} - route_metadata = route_metadata if isinstance(route_metadata, dict) else {} - pre_validation = state.get("transaction_pre_validation") or {} - pre_validation = pre_validation if isinstance(pre_validation, dict) else {} - tx_status = str( - state.get("transaction_status") or pre_validation.get("status") or "" - ).strip().upper() - terminal_tx = bool(pre_validation.get("terminal")) or tx_status in { - "COMPLETED", "FAILED", "CANCELLED", "BLOCKED", "OUT_OF_SCOPE" - } - semantic_intent_shift = ( - str(route_metadata.get("transaction_interruption") or "").strip().lower() - == "intent_shift" - ) - stickiness_intent_shift = bool(route_metadata.get("route_stickiness_preempted")) - should_isolate_history = semantic_intent_shift or (terminal_tx and stickiness_intent_shift) - - current_route = str( - state.get("route") - or (route_decision.get("route") if isinstance(route_decision, dict) else "") - or "" - ).strip() - current_intent = str( - state.get("intent") - or (route_decision.get("intent") if isinstance(route_decision, dict) else "") - or "" - ).strip() - ctx["current_user_message"] = current_user_text - ctx["current_route"] = current_route - ctx["current_intent"] = current_intent - - if should_isolate_history: - operational_history = ( - [{"role": "user", "content": current_user_text}] - if current_user_text else [] - ) - ctx["historical_transaction_ignored"] = True - ctx["historical_transaction_status"] = tx_status or ( - "INTERRUPTED" if semantic_intent_shift else "TERMINAL" - ) - if semantic_intent_shift: - ctx["historical_transaction_interruption"] = "intent_shift" - for stale_key in ( - "transaction_pre_validation", - "transaction_status", - "active_transaction", - "transaction", - ): - ctx.pop(stale_key, None) - else: - operational_history = history - - ctx["conversation_history"] = operational_history - ctx["history_texts"] = [ - str(item.get("content") or "") - for item in operational_history - if isinstance(item, dict) and item.get("content") not in (None, "") - ] - - protocols: list[str] = [] - seen: set[str] = set() - protocol_keys = { - "protocol_number", "protocolo_id", "interactionProtocol", - "protocolNumber", "finalizacao_protocol", - } - - def walk(value): - if isinstance(value, dict): - for key, item in value.items(): - if key in protocol_keys and item not in (None, ""): - text = str(item).strip() - if text and text not in seen: - seen.add(text) - protocols.append(text) - elif isinstance(item, (dict, list, tuple)): - walk(item) - elif isinstance(value, (list, tuple)): - for item in value: - walk(item) - - walk(mcp_results) - if protocols: - ctx["expected_protocols"] = protocols - ctx["requer_protocolo"] = True - ctx.setdefault("tipo_fluxo", "ajuste") - return ctx - async def output_supervisor(self, state): """Valida a resposta candidata com o OutputSupervisor corporativo. @@ -620,15 +553,15 @@ class AgentWorkflow: } candidate = state.get("answer") or "" - context = self._output_guardrail_context(state) - context.update({ + context = { + **(state.get("context") or {}), "tenant_id": state.get("tenant_id"), "agent_id": state.get("agent_id"), "session_id": state.get("conversation_key") or state.get("session_id"), "route": state.get("route"), "intent": state.get("intent"), "supervisor_attempt": int(state.get("supervisor_attempt", 0)), - }) + } async with self.telemetry.span( "workflow.output_supervisor", session_id=state.get("conversation_key") or state.get("session_id"), @@ -714,7 +647,7 @@ class AgentWorkflow: component="workflow.output_guardrails.start", ) final, decisions = await self.guardrails.run_output( - state["answer"], self._output_guardrail_context(state) + state["answer"], state.get("context", {}) ) for _decision in decisions: await self.guardrail_telemetry.evaluated("output", _decision) diff --git a/Tuning-Performance/Route_Stickness/templates/agent_template_backend/config/routing.yaml b/Tuning-Performance/Route_Stickness/templates/agent_template_backend/config/routing.yaml index 03aeaa9..bb4ef6f 100644 --- a/Tuning-Performance/Route_Stickness/templates/agent_template_backend/config/routing.yaml +++ b/Tuning-Performance/Route_Stickness/templates/agent_template_backend/config/routing.yaml @@ -7,6 +7,35 @@ router: confidence_threshold: 0.65 allow_handoff: true + transaction_confirmation: + # Explicit yes/no stays deterministic. Only inconclusive replies use this LLM fallback. + semantic_fallback: + enabled: true + allowed_values: [SIM, NAO, CONTINUAR] + confirm_values: [SIM] + reject_values: [NAO] + continue_values: [CONTINUAR] + include_relevant_context: true + profile_name: router + prompt: | + Você classifica a resposta do cliente a uma confirmação transacional pendente. + Considere a pergunta pendente, somente o histórico recente relacionado ao mesmo tema e a fala atual. + Não execute a ação e não invente fatos. + + Classes permitidas: {{ allowed_values }} + - SIM: confirmação/aceite inequívoco, inclusive equivalentes como "isso mesmo", "pode confirmar", "é isso" quando o contexto tornar o aceite claro. + - NAO: recusa/cancelamento inequívoco da ação pendente. + - CONTINUAR: qualquer resposta que não confirme nem rejeite inequivocamente, incluindo pergunta adicional, correção, novo dado, ambiguidade ou possível mudança de assunto. + + Pergunta pendente: + {{ pending_prompt }} + + Histórico relevante: + {{ relevant_conversation_context }} + + Resposta atual do cliente: + {{ user_input }} + state_policies: - state: WAITING_BILLING_CONFIRMATION agent: billing_agent diff --git a/Tuning-Performance/Route_Stickness/templates/agent_template_backend/docs/TRANSACTION_SEMANTIC_CONFIRMATION.md b/Tuning-Performance/Route_Stickness/templates/agent_template_backend/docs/TRANSACTION_SEMANTIC_CONFIRMATION.md new file mode 100644 index 0000000..a550871 --- /dev/null +++ b/Tuning-Performance/Route_Stickness/templates/agent_template_backend/docs/TRANSACTION_SEMANTIC_CONFIRMATION.md @@ -0,0 +1,11 @@ +# Confirmação Transacional Semântica + +Este template suporta confirmação transacional em duas camadas: primeiro um parser determinístico para `sim`/`não` e equivalentes explícitos; somente quando ele não consegue decidir, o framework usa um classificador semântico configurado em `config/routing.yaml`. + +A configuração `router.transaction_confirmation.semantic_fallback` usa três classes: `SIM`, `NAO` e `CONTINUAR`. O prompt pode usar `{{ pending_prompt }}`, `{{ relevant_conversation_context }}`, `{{ user_input }}` e `{{ allowed_values }}`. O histórico injetado é apenas contexto de interpretação; não substitui validação de negócio ou evidência MCP. + +Exemplo: após `Você confirma o cancelamento do serviço Tamboro Mensal?`, a frase `isso mesmo, pode confirmar` pode ser classificada como `SIM`. Já `mas qual é o valor?` deve ser `CONTINUAR`, portanto não executa a ação por confirmação. + +Entradas explícitas já suportadas continuam no caminho determinístico e não geram custo adicional de LLM. Em observabilidade, o fallback usa `transaction.confirmation.semantic_classifier` e o `route_decision.metadata` informa `transaction_confirmation_source: semantic`. + +Consulte `docs/developer/pt/03_transaction_workflows_and_state.md` do framework para o contrato completo e exemplos. diff --git a/Tuning-Performance/Route_Stickness/templates/agent_template_backend_day_zero/app/agents/billing_agent.py b/Tuning-Performance/Route_Stickness/templates/agent_template_backend_day_zero/app/agents/billing_agent.py index 05254d1..aa60099 100644 --- a/Tuning-Performance/Route_Stickness/templates/agent_template_backend_day_zero/app/agents/billing_agent.py +++ b/Tuning-Performance/Route_Stickness/templates/agent_template_backend_day_zero/app/agents/billing_agent.py @@ -95,7 +95,7 @@ class BillingAgent(AgentRuntimeMixin): state, system_prompt=apply_agent_profile_prompt( state, - "Você é um agente especialista em faturas.\n\nUse dados de tools/MCP e RAG autorizados como fonte de verdade para responder somente à solicitação atual.\nNunca exponha identificadores técnicos ou de identidade presentes no estado, contexto ou MCP, incluindo customer_key, contract_key, account_key, resource_key, session_key, customer_id, document, message_id, ura_call_id ou MSISDN/telefone completo.\nNão transforme nomes internos de campos em rótulos para o cliente, como “contract_key”, “customer_key” ou “MSISDN”.\nPara consultas informativas de fatura, apresente somente dados de negócio necessários, como valor, vencimento, situação e itens cobrados.\nNão acrescente canais, telefones, códigos USSD, URLs, aplicativos, lojas, relatórios adicionais, procedimentos alternativos ou próximos passos que não tenham sido explicitamente retornados pela tool/RAG e solicitados pelo usuário.\nNão ofereça espontaneamente outras ações ou detalhamentos.\nSe uma tool retornar BLOCKED, OUT_OF_SCOPE, NOT_ALLOWED, FAILED ou outro resultado terminal, explique somente o motivo retornado, não declare sucesso, não invente alternativa e encerre a resposta.", + "Você é um agente especialista em faturas. Responda com clareza, objetividade e sem sugerir ações não solicitadas. Use dados MCP quando disponíveis.", ), mcp_results=tool_context, rag_context=rag_context, diff --git a/Tuning-Performance/Route_Stickness/templates/agent_template_backend_day_zero/app/agents/orders_agent.py b/Tuning-Performance/Route_Stickness/templates/agent_template_backend_day_zero/app/agents/orders_agent.py index b793c26..f557bed 100644 --- a/Tuning-Performance/Route_Stickness/templates/agent_template_backend_day_zero/app/agents/orders_agent.py +++ b/Tuning-Performance/Route_Stickness/templates/agent_template_backend_day_zero/app/agents/orders_agent.py @@ -95,7 +95,7 @@ class OrdersAgent(AgentRuntimeMixin): state, system_prompt=apply_agent_profile_prompt( state, - "Você é um agente de pedidos de varejo.\n\nUse dados de tools/MCP e RAG autorizados como fonte de verdade e responda somente à solicitação atual.\nNunca exponha identificadores técnicos ou de identidade presentes no estado, contexto ou MCP, incluindo customer_key, contract_key, account_key, resource_key, session_key, customer_id, document, message_id, ura_call_id ou telefone completo.\nNão transforme nomes internos de campos em rótulos para o cliente.\nNão declare sucesso, alteração, troca, cancelamento ou qualquer mutação se a tool não tiver confirmado a execução.\nNão acrescente canais, procedimentos, ofertas ou próximos passos não solicitados.\nSe uma tool retornar BLOCKED, OUT_OF_SCOPE, NOT_ALLOWED, FAILED ou outro resultado terminal, explique somente o motivo retornado, não invente alternativa e encerre a resposta.", + "Você é um agente de pedidos de varejo. Use dados de tools quando disponíveis.", ), mcp_results=tool_context, rag_context=rag_context, diff --git a/Tuning-Performance/Route_Stickness/templates/agent_template_backend_day_zero/app/agents/product_agent.py b/Tuning-Performance/Route_Stickness/templates/agent_template_backend_day_zero/app/agents/product_agent.py index 998dad6..34433f5 100644 --- a/Tuning-Performance/Route_Stickness/templates/agent_template_backend_day_zero/app/agents/product_agent.py +++ b/Tuning-Performance/Route_Stickness/templates/agent_template_backend_day_zero/app/agents/product_agent.py @@ -95,7 +95,7 @@ class ProductAgent(AgentRuntimeMixin): state, system_prompt=apply_agent_profile_prompt( state, - "Você é um agente especialista em produtos, planos e serviços.\n\nUse dados de tools/MCP e RAG autorizados como fonte de verdade e responda somente à solicitação atual.\nNunca exponha identificadores técnicos ou de identidade presentes no estado, contexto ou MCP, incluindo customer_key, contract_key, account_key, resource_key, session_key, customer_id, document, message_id, ura_call_id ou MSISDN/telefone completo.\nNão transforme nomes internos de campos em rótulos para o cliente.\nEm consultas meramente informativas, não exponha flags ou capacidades transacionais internas como can.cancel e não informe espontaneamente que algo pode ser cancelado, alterado, contratado, removido ou trocado. Só mencione capacidade transacional quando o usuário tiver solicitado essa ação.\nNão faça oferta proativa e não execute nem simule mutações sem a confirmação exigida pelo framework.\nNão acrescente canais, procedimentos ou próximos passos não solicitados.\nSe uma tool retornar BLOCKED, OUT_OF_SCOPE, NOT_ALLOWED, FAILED ou outro resultado terminal, explique somente o motivo retornado, não declare sucesso, não invente alternativa e encerre a resposta.", + "Você é um agente especialista em produtos, planos e serviços. Explique sem fazer oferta proativa e sem executar ações sem confirmação. Use dados MCP quando disponíveis.", ), mcp_results=tool_context, rag_context=rag_context, diff --git a/Tuning-Performance/Route_Stickness/templates/agent_template_backend_day_zero/app/agents/support_agent.py b/Tuning-Performance/Route_Stickness/templates/agent_template_backend_day_zero/app/agents/support_agent.py index b15a0e4..b4f0244 100644 --- a/Tuning-Performance/Route_Stickness/templates/agent_template_backend_day_zero/app/agents/support_agent.py +++ b/Tuning-Performance/Route_Stickness/templates/agent_template_backend_day_zero/app/agents/support_agent.py @@ -95,7 +95,7 @@ class SupportAgent(AgentRuntimeMixin): state, system_prompt=apply_agent_profile_prompt( state, - "Você é um agente de suporte de varejo para troca, devolução e garantia.\n\nUse dados de tools/MCP e RAG autorizados como fonte de verdade e responda somente à solicitação atual.\nNunca exponha identificadores técnicos ou de identidade presentes no estado, contexto ou MCP, incluindo customer_key, contract_key, account_key, resource_key, session_key, customer_id, document, message_id, ura_call_id ou telefone completo.\nNão transforme nomes internos de campos em rótulos para o cliente.\nNão declare sucesso nem simule troca, devolução, garantia ou outra mutação se a tool não tiver confirmado a execução.\nNão acrescente canais, procedimentos, ofertas ou próximos passos não solicitados.\nSe uma tool retornar BLOCKED, OUT_OF_SCOPE, NOT_ALLOWED, FAILED ou outro resultado terminal, explique somente o motivo retornado, não invente alternativa e encerre a resposta.", + "Você é um agente de suporte de varejo para troca, devolução e garantia.", ), mcp_results=tool_context, rag_context=rag_context, diff --git a/Tuning-Performance/Route_Stickness/templates/agent_template_backend_day_zero/app/workflows/__pycache__/agent_graph.cpython-313.pyc b/Tuning-Performance/Route_Stickness/templates/agent_template_backend_day_zero/app/workflows/__pycache__/agent_graph.cpython-313.pyc index d268a633e037a7a98bba6a4205a4c6e3d3769ab7..e22859d1fcabfba04dec0c83b5901eba55338c8b 100644 GIT binary patch delta 7502 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 delta 10943 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 diff --git a/Tuning-Performance/Route_Stickness/templates/agent_template_backend_day_zero/app/workflows/agent_graph.py b/Tuning-Performance/Route_Stickness/templates/agent_template_backend_day_zero/app/workflows/agent_graph.py index 2cb86e1..fc29245 100644 --- a/Tuning-Performance/Route_Stickness/templates/agent_template_backend_day_zero/app/workflows/agent_graph.py +++ b/Tuning-Performance/Route_Stickness/templates/agent_template_backend_day_zero/app/workflows/agent_graph.py @@ -159,7 +159,7 @@ class AgentWorkflow: builder.add_conditional_edges( "input_guardrails", self._after_input_guardrails, - {"blocked": "persist", "continue": "routing_decision"}, + {"blocked": "output_guardrails", "continue": "routing_decision"}, ) builder.add_conditional_edges( "routing_decision", @@ -195,6 +195,31 @@ class AgentWorkflow: def _after_input_guardrails(self, state): return "blocked" if state.get("blocked") else "continue" + @staticmethod + def _input_guardrail_user_message(decisions, state, sanitized_text): + # Keep the technical guardrail reason in telemetry, but expose only a + # safe, actionable message to the end user. The message is intentionally + # routed through output_guardrails before persistence/delivery. + blocked = [d for d in decisions if not getattr(d, "allowed", True)] + first = blocked[0] if blocked else None + code = str(getattr(first, "code", "") or "").upper() + if code == "COER": + return ( + "Não consegui entender sua última mensagem porque ela parece " + "incompleta ou ambígua. Pode reformular ou completar o que você quis dizer?" + ) + if code == "INPUT_SIZE": + return "Sua mensagem ficou muito longa para eu processar de uma vez. Pode resumir ou dividir em partes?" + if code == "DLEX_IN": + return "Não posso usar essa informação da forma solicitada. Reformule o pedido sem incluir dados ou conteúdo restrito." + if code == "PINJ": + return "Não posso seguir instruções que tentem alterar as regras do atendimento. Posso continuar ajudando com a sua solicitação." + if code == "TOX": + return "Não consegui prosseguir com essa mensagem. Pode reformular o pedido para continuarmos o atendimento?" + if code == "CMP": + return "Não posso prosseguir com essa solicitação dessa forma. Posso ajudar com uma alternativa permitida." + return "Não consegui processar essa mensagem. Pode reformular para eu continuar o atendimento?" + async def input_guardrails(self, state): if state.get("session_ended") is True: answer = str(getattr( @@ -279,12 +304,33 @@ class AgentWorkflow: component="workflow.input_guardrails.final", ) if any(not d.allowed for d in decisions): + # A blocking input guardrail stops the turn before routing/tools. + # Clear turn-local routing/tool state so stale data from a prior + # turn cannot appear as if it was executed after the block. + user_message = self._input_guardrail_user_message(decisions, state, sanitized) return { "sanitized_input": sanitized, - "answer": "Não consegui seguir com essa mensagem por regra de segurança.", - "final_answer": "Não consegui seguir com essa mensagem por regra de segurança.", + "answer": user_message, + "final_answer": None, "guardrail_decisions": [d.model_dump() for d in decisions], "route": "blocked", + "intent": "input_guardrail_blocked", + "route_decision": { + "route": "blocked", + "agent": None, + "intent": "input_guardrail_blocked", + "confidence": 1.0, + "reason": "Entrada interrompida por guardrail antes do roteamento.", + "method": "guardrail", + "next_state": state.get("next_state"), + "handoff": False, + "metadata": {}, + "domain": state.get("domain"), + "mcp_tools": [], + }, + "mcp_tools": [], + "mcp_results": [], + "judge_results": [], "blocked": True, } return { @@ -492,119 +538,6 @@ class AgentWorkflow: "next_state": "SESSION_ENDED", } - @staticmethod - def _output_guardrail_context(state: dict) -> dict: - """Monta o contexto operacional do turno para os guardrails de saída. - - Mantém evidências/protocolos necessários aos rails, mas impede que uma - transação encerrada ou semanticamente interrompida governe o novo turno. - O histórico completo permanece no state/checkpoint para auditoria. - """ - ctx = dict(state.get("context", {}) or {}) - mcp_results = state.get("mcp_results") or [] - ctx["evidence"] = mcp_results or ctx.get("evidence") - ctx["tool_result"] = mcp_results or ctx.get("tool_result") - ctx["tool_executed"] = any(isinstance(r, dict) and r.get("ok") for r in mcp_results) - - history = list(state.get("history") or []) - current_user_text = str(state.get("user_text") or "").strip() - if current_user_text: - if ( - not history - or not isinstance(history[-1], dict) - or str(history[-1].get("content") or "") != current_user_text - or str(history[-1].get("role") or "") != "user" - ): - history.append({"role": "user", "content": current_user_text}) - - route_decision = state.get("route_decision") or {} - route_metadata = route_decision.get("metadata") if isinstance(route_decision, dict) else {} - route_metadata = route_metadata if isinstance(route_metadata, dict) else {} - pre_validation = state.get("transaction_pre_validation") or {} - pre_validation = pre_validation if isinstance(pre_validation, dict) else {} - tx_status = str( - state.get("transaction_status") or pre_validation.get("status") or "" - ).strip().upper() - terminal_tx = bool(pre_validation.get("terminal")) or tx_status in { - "COMPLETED", "FAILED", "CANCELLED", "BLOCKED", "OUT_OF_SCOPE" - } - semantic_intent_shift = ( - str(route_metadata.get("transaction_interruption") or "").strip().lower() - == "intent_shift" - ) - stickiness_intent_shift = bool(route_metadata.get("route_stickiness_preempted")) - should_isolate_history = semantic_intent_shift or (terminal_tx and stickiness_intent_shift) - - current_route = str( - state.get("route") - or (route_decision.get("route") if isinstance(route_decision, dict) else "") - or "" - ).strip() - current_intent = str( - state.get("intent") - or (route_decision.get("intent") if isinstance(route_decision, dict) else "") - or "" - ).strip() - ctx["current_user_message"] = current_user_text - ctx["current_route"] = current_route - ctx["current_intent"] = current_intent - - if should_isolate_history: - operational_history = ( - [{"role": "user", "content": current_user_text}] - if current_user_text else [] - ) - ctx["historical_transaction_ignored"] = True - ctx["historical_transaction_status"] = tx_status or ( - "INTERRUPTED" if semantic_intent_shift else "TERMINAL" - ) - if semantic_intent_shift: - ctx["historical_transaction_interruption"] = "intent_shift" - for stale_key in ( - "transaction_pre_validation", - "transaction_status", - "active_transaction", - "transaction", - ): - ctx.pop(stale_key, None) - else: - operational_history = history - - ctx["conversation_history"] = operational_history - ctx["history_texts"] = [ - str(item.get("content") or "") - for item in operational_history - if isinstance(item, dict) and item.get("content") not in (None, "") - ] - - protocols: list[str] = [] - seen: set[str] = set() - protocol_keys = { - "protocol_number", "protocolo_id", "interactionProtocol", - "protocolNumber", "finalizacao_protocol", - } - - def walk(value): - if isinstance(value, dict): - for key, item in value.items(): - if key in protocol_keys and item not in (None, ""): - text = str(item).strip() - if text and text not in seen: - seen.add(text) - protocols.append(text) - elif isinstance(item, (dict, list, tuple)): - walk(item) - elif isinstance(value, (list, tuple)): - for item in value: - walk(item) - - walk(mcp_results) - if protocols: - ctx["expected_protocols"] = protocols - ctx["requer_protocolo"] = True - ctx.setdefault("tipo_fluxo", "ajuste") - return ctx - async def output_supervisor(self, state): """Valida a resposta candidata com o OutputSupervisor corporativo. @@ -620,15 +553,15 @@ class AgentWorkflow: } candidate = state.get("answer") or "" - context = self._output_guardrail_context(state) - context.update({ + context = { + **(state.get("context") or {}), "tenant_id": state.get("tenant_id"), "agent_id": state.get("agent_id"), "session_id": state.get("conversation_key") or state.get("session_id"), "route": state.get("route"), "intent": state.get("intent"), "supervisor_attempt": int(state.get("supervisor_attempt", 0)), - }) + } async with self.telemetry.span( "workflow.output_supervisor", session_id=state.get("conversation_key") or state.get("session_id"), @@ -714,7 +647,7 @@ class AgentWorkflow: component="workflow.output_guardrails.start", ) final, decisions = await self.guardrails.run_output( - state["answer"], self._output_guardrail_context(state) + state["answer"], state.get("context", {}) ) for _decision in decisions: await self.guardrail_telemetry.evaluated("output", _decision) diff --git a/Tuning-Performance/Route_Stickness/templates/agent_template_backend_day_zero/config/routing.yaml b/Tuning-Performance/Route_Stickness/templates/agent_template_backend_day_zero/config/routing.yaml index 03aeaa9..bb4ef6f 100644 --- a/Tuning-Performance/Route_Stickness/templates/agent_template_backend_day_zero/config/routing.yaml +++ b/Tuning-Performance/Route_Stickness/templates/agent_template_backend_day_zero/config/routing.yaml @@ -7,6 +7,35 @@ router: confidence_threshold: 0.65 allow_handoff: true + transaction_confirmation: + # Explicit yes/no stays deterministic. Only inconclusive replies use this LLM fallback. + semantic_fallback: + enabled: true + allowed_values: [SIM, NAO, CONTINUAR] + confirm_values: [SIM] + reject_values: [NAO] + continue_values: [CONTINUAR] + include_relevant_context: true + profile_name: router + prompt: | + Você classifica a resposta do cliente a uma confirmação transacional pendente. + Considere a pergunta pendente, somente o histórico recente relacionado ao mesmo tema e a fala atual. + Não execute a ação e não invente fatos. + + Classes permitidas: {{ allowed_values }} + - SIM: confirmação/aceite inequívoco, inclusive equivalentes como "isso mesmo", "pode confirmar", "é isso" quando o contexto tornar o aceite claro. + - NAO: recusa/cancelamento inequívoco da ação pendente. + - CONTINUAR: qualquer resposta que não confirme nem rejeite inequivocamente, incluindo pergunta adicional, correção, novo dado, ambiguidade ou possível mudança de assunto. + + Pergunta pendente: + {{ pending_prompt }} + + Histórico relevante: + {{ relevant_conversation_context }} + + Resposta atual do cliente: + {{ user_input }} + state_policies: - state: WAITING_BILLING_CONFIRMATION agent: billing_agent diff --git a/Tuning-Performance/Route_Stickness/templates/agent_template_backend_day_zero/docs/TRANSACTION_SEMANTIC_CONFIRMATION.md b/Tuning-Performance/Route_Stickness/templates/agent_template_backend_day_zero/docs/TRANSACTION_SEMANTIC_CONFIRMATION.md new file mode 100644 index 0000000..a550871 --- /dev/null +++ b/Tuning-Performance/Route_Stickness/templates/agent_template_backend_day_zero/docs/TRANSACTION_SEMANTIC_CONFIRMATION.md @@ -0,0 +1,11 @@ +# Confirmação Transacional Semântica + +Este template suporta confirmação transacional em duas camadas: primeiro um parser determinístico para `sim`/`não` e equivalentes explícitos; somente quando ele não consegue decidir, o framework usa um classificador semântico configurado em `config/routing.yaml`. + +A configuração `router.transaction_confirmation.semantic_fallback` usa três classes: `SIM`, `NAO` e `CONTINUAR`. O prompt pode usar `{{ pending_prompt }}`, `{{ relevant_conversation_context }}`, `{{ user_input }}` e `{{ allowed_values }}`. O histórico injetado é apenas contexto de interpretação; não substitui validação de negócio ou evidência MCP. + +Exemplo: após `Você confirma o cancelamento do serviço Tamboro Mensal?`, a frase `isso mesmo, pode confirmar` pode ser classificada como `SIM`. Já `mas qual é o valor?` deve ser `CONTINUAR`, portanto não executa a ação por confirmação. + +Entradas explícitas já suportadas continuam no caminho determinístico e não geram custo adicional de LLM. Em observabilidade, o fallback usa `transaction.confirmation.semantic_classifier` e o `route_decision.metadata` informa `transaction_confirmation_source: semantic`. + +Consulte `docs/developer/pt/03_transaction_workflows_and_state.md` do framework para o contrato completo e exemplos. diff --git a/Tuning-Performance/Transaction_Evidence/agent_template_backend/app/agents/billing_agent.py b/Tuning-Performance/Transaction_Evidence/agent_template_backend/app/agents/billing_agent.py index 05254d1..aa60099 100644 --- a/Tuning-Performance/Transaction_Evidence/agent_template_backend/app/agents/billing_agent.py +++ b/Tuning-Performance/Transaction_Evidence/agent_template_backend/app/agents/billing_agent.py @@ -95,7 +95,7 @@ class BillingAgent(AgentRuntimeMixin): state, system_prompt=apply_agent_profile_prompt( state, - "Você é um agente especialista em faturas.\n\nUse dados de tools/MCP e RAG autorizados como fonte de verdade para responder somente à solicitação atual.\nNunca exponha identificadores técnicos ou de identidade presentes no estado, contexto ou MCP, incluindo customer_key, contract_key, account_key, resource_key, session_key, customer_id, document, message_id, ura_call_id ou MSISDN/telefone completo.\nNão transforme nomes internos de campos em rótulos para o cliente, como “contract_key”, “customer_key” ou “MSISDN”.\nPara consultas informativas de fatura, apresente somente dados de negócio necessários, como valor, vencimento, situação e itens cobrados.\nNão acrescente canais, telefones, códigos USSD, URLs, aplicativos, lojas, relatórios adicionais, procedimentos alternativos ou próximos passos que não tenham sido explicitamente retornados pela tool/RAG e solicitados pelo usuário.\nNão ofereça espontaneamente outras ações ou detalhamentos.\nSe uma tool retornar BLOCKED, OUT_OF_SCOPE, NOT_ALLOWED, FAILED ou outro resultado terminal, explique somente o motivo retornado, não declare sucesso, não invente alternativa e encerre a resposta.", + "Você é um agente especialista em faturas. Responda com clareza, objetividade e sem sugerir ações não solicitadas. Use dados MCP quando disponíveis.", ), mcp_results=tool_context, rag_context=rag_context, diff --git a/Tuning-Performance/Transaction_Evidence/agent_template_backend/app/agents/orders_agent.py b/Tuning-Performance/Transaction_Evidence/agent_template_backend/app/agents/orders_agent.py index b793c26..f557bed 100644 --- a/Tuning-Performance/Transaction_Evidence/agent_template_backend/app/agents/orders_agent.py +++ b/Tuning-Performance/Transaction_Evidence/agent_template_backend/app/agents/orders_agent.py @@ -95,7 +95,7 @@ class OrdersAgent(AgentRuntimeMixin): state, system_prompt=apply_agent_profile_prompt( state, - "Você é um agente de pedidos de varejo.\n\nUse dados de tools/MCP e RAG autorizados como fonte de verdade e responda somente à solicitação atual.\nNunca exponha identificadores técnicos ou de identidade presentes no estado, contexto ou MCP, incluindo customer_key, contract_key, account_key, resource_key, session_key, customer_id, document, message_id, ura_call_id ou telefone completo.\nNão transforme nomes internos de campos em rótulos para o cliente.\nNão declare sucesso, alteração, troca, cancelamento ou qualquer mutação se a tool não tiver confirmado a execução.\nNão acrescente canais, procedimentos, ofertas ou próximos passos não solicitados.\nSe uma tool retornar BLOCKED, OUT_OF_SCOPE, NOT_ALLOWED, FAILED ou outro resultado terminal, explique somente o motivo retornado, não invente alternativa e encerre a resposta.", + "Você é um agente de pedidos de varejo. Use dados de tools quando disponíveis.", ), mcp_results=tool_context, rag_context=rag_context, diff --git a/Tuning-Performance/Transaction_Evidence/agent_template_backend/app/agents/product_agent.py b/Tuning-Performance/Transaction_Evidence/agent_template_backend/app/agents/product_agent.py index 998dad6..34433f5 100644 --- a/Tuning-Performance/Transaction_Evidence/agent_template_backend/app/agents/product_agent.py +++ b/Tuning-Performance/Transaction_Evidence/agent_template_backend/app/agents/product_agent.py @@ -95,7 +95,7 @@ class ProductAgent(AgentRuntimeMixin): state, system_prompt=apply_agent_profile_prompt( state, - "Você é um agente especialista em produtos, planos e serviços.\n\nUse dados de tools/MCP e RAG autorizados como fonte de verdade e responda somente à solicitação atual.\nNunca exponha identificadores técnicos ou de identidade presentes no estado, contexto ou MCP, incluindo customer_key, contract_key, account_key, resource_key, session_key, customer_id, document, message_id, ura_call_id ou MSISDN/telefone completo.\nNão transforme nomes internos de campos em rótulos para o cliente.\nEm consultas meramente informativas, não exponha flags ou capacidades transacionais internas como can.cancel e não informe espontaneamente que algo pode ser cancelado, alterado, contratado, removido ou trocado. Só mencione capacidade transacional quando o usuário tiver solicitado essa ação.\nNão faça oferta proativa e não execute nem simule mutações sem a confirmação exigida pelo framework.\nNão acrescente canais, procedimentos ou próximos passos não solicitados.\nSe uma tool retornar BLOCKED, OUT_OF_SCOPE, NOT_ALLOWED, FAILED ou outro resultado terminal, explique somente o motivo retornado, não declare sucesso, não invente alternativa e encerre a resposta.", + "Você é um agente especialista em produtos, planos e serviços. Explique sem fazer oferta proativa e sem executar ações sem confirmação. Use dados MCP quando disponíveis.", ), mcp_results=tool_context, rag_context=rag_context, diff --git a/Tuning-Performance/Transaction_Evidence/agent_template_backend/app/agents/support_agent.py b/Tuning-Performance/Transaction_Evidence/agent_template_backend/app/agents/support_agent.py index b15a0e4..b4f0244 100644 --- a/Tuning-Performance/Transaction_Evidence/agent_template_backend/app/agents/support_agent.py +++ b/Tuning-Performance/Transaction_Evidence/agent_template_backend/app/agents/support_agent.py @@ -95,7 +95,7 @@ class SupportAgent(AgentRuntimeMixin): state, system_prompt=apply_agent_profile_prompt( state, - "Você é um agente de suporte de varejo para troca, devolução e garantia.\n\nUse dados de tools/MCP e RAG autorizados como fonte de verdade e responda somente à solicitação atual.\nNunca exponha identificadores técnicos ou de identidade presentes no estado, contexto ou MCP, incluindo customer_key, contract_key, account_key, resource_key, session_key, customer_id, document, message_id, ura_call_id ou telefone completo.\nNão transforme nomes internos de campos em rótulos para o cliente.\nNão declare sucesso nem simule troca, devolução, garantia ou outra mutação se a tool não tiver confirmado a execução.\nNão acrescente canais, procedimentos, ofertas ou próximos passos não solicitados.\nSe uma tool retornar BLOCKED, OUT_OF_SCOPE, NOT_ALLOWED, FAILED ou outro resultado terminal, explique somente o motivo retornado, não invente alternativa e encerre a resposta.", + "Você é um agente de suporte de varejo para troca, devolução e garantia.", ), mcp_results=tool_context, rag_context=rag_context, diff --git a/Tuning-Performance/Transaction_Evidence/agent_template_backend/app/presentation/tool_renderers.py b/Tuning-Performance/Transaction_Evidence/agent_template_backend/app/presentation/tool_renderers.py index cb44202..f77c47a 100644 --- a/Tuning-Performance/Transaction_Evidence/agent_template_backend/app/presentation/tool_renderers.py +++ b/Tuning-Performance/Transaction_Evidence/agent_template_backend/app/presentation/tool_renderers.py @@ -13,42 +13,7 @@ def _money_brl(value: Any) -> str: def render_telecom_invoice(*, tool_name: str, result: dict[str, Any], state: dict[str, Any], agent_label: str) -> str | None: - """Renderiza somente campos de negócio seguros da fatura. - - Identificadores técnicos/PII presentes no payload MCP (por exemplo msisdn, - customer_id, document e business keys) não devem ser propagados ao usuário. - """ - lines = [f"[{agent_label}] Dados da sua fatura:"] - total = result.get("valor_total") - vencimento = result.get("vencimento") - status = result.get("status") - if total is not None: - lines.append(f"Valor total: R$ {_money_brl(total)}.") - if vencimento not in (None, ""): - lines.append(f"Vencimento: {vencimento}.") - if status not in (None, ""): - lines.append(f"Situação: {status}.") - - items = result.get("itens") or [] - rendered_items: list[str] = [] - if isinstance(items, list): - for item in items: - if not isinstance(item, dict): - continue - description = item.get("descricao") or item.get("nome") - value = item.get("valor") - if description in (None, ""): - continue - if value is None: - rendered_items.append(str(description)) - else: - rendered_items.append(f"{description}: R$ {_money_brl(value)}") - if rendered_items: - lines.append("Itens: " + "; ".join(rendered_items) + ".") - - # Se não houver nenhum campo de negócio seguro além do cabeçalho, deixe a - # composição pela LLM/guardrails em vez de despejar o payload bruto. - return " ".join(lines) if len(lines) > 1 else None + return f"[{agent_label}] Fatura consultada: {result}." def render_telecom_plan(*, tool_name: str, result: dict[str, Any], state: dict[str, Any], agent_label: str) -> str | None: diff --git a/Tuning-Performance/Transaction_Evidence/agent_template_backend/app/workflows/__pycache__/agent_graph.cpython-313.pyc b/Tuning-Performance/Transaction_Evidence/agent_template_backend/app/workflows/__pycache__/agent_graph.cpython-313.pyc index 515e583dcac2dadded66f59ddf64e5614155a91f..a4df9969dcfc3e476ecec7db8b0440556ab85dfc 100644 GIT binary patch delta 7811 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 A+5i9m delta 11343 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 Z@~l(A{*ioiWhC2cV68V9gfs>E{{WNq??C_n diff --git a/Tuning-Performance/Transaction_Evidence/agent_template_backend/app/workflows/agent_graph.py b/Tuning-Performance/Transaction_Evidence/agent_template_backend/app/workflows/agent_graph.py index fef0791..e22cf44 100644 --- a/Tuning-Performance/Transaction_Evidence/agent_template_backend/app/workflows/agent_graph.py +++ b/Tuning-Performance/Transaction_Evidence/agent_template_backend/app/workflows/agent_graph.py @@ -160,7 +160,7 @@ class AgentWorkflow: builder.add_conditional_edges( "input_guardrails", self._after_input_guardrails, - {"blocked": "persist", "continue": "load_long_term_memory"}, + {"blocked": "output_guardrails", "continue": "load_long_term_memory"}, ) builder.add_edge("load_long_term_memory", "routing_decision") builder.add_conditional_edges( @@ -197,6 +197,31 @@ class AgentWorkflow: def _after_input_guardrails(self, state): return "blocked" if state.get("blocked") else "continue" + @staticmethod + def _input_guardrail_user_message(decisions, state, sanitized_text): + # Keep the technical guardrail reason in telemetry, but expose only a + # safe, actionable message to the end user. The message is intentionally + # routed through output_guardrails before persistence/delivery. + blocked = [d for d in decisions if not getattr(d, "allowed", True)] + first = blocked[0] if blocked else None + code = str(getattr(first, "code", "") or "").upper() + if code == "COER": + return ( + "Não consegui entender sua última mensagem porque ela parece " + "incompleta ou ambígua. Pode reformular ou completar o que você quis dizer?" + ) + if code == "INPUT_SIZE": + return "Sua mensagem ficou muito longa para eu processar de uma vez. Pode resumir ou dividir em partes?" + if code == "DLEX_IN": + return "Não posso usar essa informação da forma solicitada. Reformule o pedido sem incluir dados ou conteúdo restrito." + if code == "PINJ": + return "Não posso seguir instruções que tentem alterar as regras do atendimento. Posso continuar ajudando com a sua solicitação." + if code == "TOX": + return "Não consegui prosseguir com essa mensagem. Pode reformular o pedido para continuarmos o atendimento?" + if code == "CMP": + return "Não posso prosseguir com essa solicitação dessa forma. Posso ajudar com uma alternativa permitida." + return "Não consegui processar essa mensagem. Pode reformular para eu continuar o atendimento?" + async def input_guardrails(self, state): if state.get("session_ended") is True: answer = str(getattr( @@ -281,12 +306,33 @@ class AgentWorkflow: component="workflow.input_guardrails.final", ) if any(not d.allowed for d in decisions): + # A blocking input guardrail stops the turn before routing/tools. + # Clear turn-local routing/tool state so stale data from a prior + # turn cannot appear as if it was executed after the block. + user_message = self._input_guardrail_user_message(decisions, state, sanitized) return { "sanitized_input": sanitized, - "answer": "Não consegui seguir com essa mensagem por regra de segurança.", - "final_answer": "Não consegui seguir com essa mensagem por regra de segurança.", + "answer": user_message, + "final_answer": None, "guardrail_decisions": [d.model_dump() for d in decisions], "route": "blocked", + "intent": "input_guardrail_blocked", + "route_decision": { + "route": "blocked", + "agent": None, + "intent": "input_guardrail_blocked", + "confidence": 1.0, + "reason": "Entrada interrompida por guardrail antes do roteamento.", + "method": "guardrail", + "next_state": state.get("next_state"), + "handoff": False, + "metadata": {}, + "domain": state.get("domain"), + "mcp_tools": [], + }, + "mcp_tools": [], + "mcp_results": [], + "judge_results": [], "blocked": True, } return { @@ -494,119 +540,6 @@ class AgentWorkflow: "next_state": "SESSION_ENDED", } - @staticmethod - def _output_guardrail_context(state: dict) -> dict: - """Monta o contexto operacional do turno para os guardrails de saída. - - Mantém evidências/protocolos necessários aos rails, mas impede que uma - transação encerrada ou semanticamente interrompida governe o novo turno. - O histórico completo permanece no state/checkpoint para auditoria. - """ - ctx = dict(state.get("context", {}) or {}) - mcp_results = state.get("mcp_results") or [] - ctx["evidence"] = mcp_results or ctx.get("evidence") - ctx["tool_result"] = mcp_results or ctx.get("tool_result") - ctx["tool_executed"] = any(isinstance(r, dict) and r.get("ok") for r in mcp_results) - - history = list(state.get("history") or []) - current_user_text = str(state.get("user_text") or "").strip() - if current_user_text: - if ( - not history - or not isinstance(history[-1], dict) - or str(history[-1].get("content") or "") != current_user_text - or str(history[-1].get("role") or "") != "user" - ): - history.append({"role": "user", "content": current_user_text}) - - route_decision = state.get("route_decision") or {} - route_metadata = route_decision.get("metadata") if isinstance(route_decision, dict) else {} - route_metadata = route_metadata if isinstance(route_metadata, dict) else {} - pre_validation = state.get("transaction_pre_validation") or {} - pre_validation = pre_validation if isinstance(pre_validation, dict) else {} - tx_status = str( - state.get("transaction_status") or pre_validation.get("status") or "" - ).strip().upper() - terminal_tx = bool(pre_validation.get("terminal")) or tx_status in { - "COMPLETED", "FAILED", "CANCELLED", "BLOCKED", "OUT_OF_SCOPE" - } - semantic_intent_shift = ( - str(route_metadata.get("transaction_interruption") or "").strip().lower() - == "intent_shift" - ) - stickiness_intent_shift = bool(route_metadata.get("route_stickiness_preempted")) - should_isolate_history = semantic_intent_shift or (terminal_tx and stickiness_intent_shift) - - current_route = str( - state.get("route") - or (route_decision.get("route") if isinstance(route_decision, dict) else "") - or "" - ).strip() - current_intent = str( - state.get("intent") - or (route_decision.get("intent") if isinstance(route_decision, dict) else "") - or "" - ).strip() - ctx["current_user_message"] = current_user_text - ctx["current_route"] = current_route - ctx["current_intent"] = current_intent - - if should_isolate_history: - operational_history = ( - [{"role": "user", "content": current_user_text}] - if current_user_text else [] - ) - ctx["historical_transaction_ignored"] = True - ctx["historical_transaction_status"] = tx_status or ( - "INTERRUPTED" if semantic_intent_shift else "TERMINAL" - ) - if semantic_intent_shift: - ctx["historical_transaction_interruption"] = "intent_shift" - for stale_key in ( - "transaction_pre_validation", - "transaction_status", - "active_transaction", - "transaction", - ): - ctx.pop(stale_key, None) - else: - operational_history = history - - ctx["conversation_history"] = operational_history - ctx["history_texts"] = [ - str(item.get("content") or "") - for item in operational_history - if isinstance(item, dict) and item.get("content") not in (None, "") - ] - - protocols: list[str] = [] - seen: set[str] = set() - protocol_keys = { - "protocol_number", "protocolo_id", "interactionProtocol", - "protocolNumber", "finalizacao_protocol", - } - - def walk(value): - if isinstance(value, dict): - for key, item in value.items(): - if key in protocol_keys and item not in (None, ""): - text = str(item).strip() - if text and text not in seen: - seen.add(text) - protocols.append(text) - elif isinstance(item, (dict, list, tuple)): - walk(item) - elif isinstance(value, (list, tuple)): - for item in value: - walk(item) - - walk(mcp_results) - if protocols: - ctx["expected_protocols"] = protocols - ctx["requer_protocolo"] = True - ctx.setdefault("tipo_fluxo", "ajuste") - return ctx - async def output_supervisor(self, state): """Valida a resposta candidata com o OutputSupervisor corporativo. @@ -622,15 +555,15 @@ class AgentWorkflow: } candidate = state.get("answer") or "" - context = self._output_guardrail_context(state) - context.update({ + context = { + **(state.get("context") or {}), "tenant_id": state.get("tenant_id"), "agent_id": state.get("agent_id"), "session_id": state.get("conversation_key") or state.get("session_id"), "route": state.get("route"), "intent": state.get("intent"), "supervisor_attempt": int(state.get("supervisor_attempt", 0)), - }) + } async with self.telemetry.span( "workflow.output_supervisor", session_id=state.get("conversation_key") or state.get("session_id"), @@ -716,7 +649,7 @@ class AgentWorkflow: component="workflow.output_guardrails.start", ) final, decisions = await self.guardrails.run_output( - state["answer"], self._output_guardrail_context(state) + state["answer"], state.get("context", {}) ) for _decision in decisions: await self.guardrail_telemetry.evaluated("output", _decision) diff --git a/Tuning-Performance/Transaction_Evidence/agent_template_backend/config/routing.yaml b/Tuning-Performance/Transaction_Evidence/agent_template_backend/config/routing.yaml index 03aeaa9..bb4ef6f 100644 --- a/Tuning-Performance/Transaction_Evidence/agent_template_backend/config/routing.yaml +++ b/Tuning-Performance/Transaction_Evidence/agent_template_backend/config/routing.yaml @@ -7,6 +7,35 @@ router: confidence_threshold: 0.65 allow_handoff: true + transaction_confirmation: + # Explicit yes/no stays deterministic. Only inconclusive replies use this LLM fallback. + semantic_fallback: + enabled: true + allowed_values: [SIM, NAO, CONTINUAR] + confirm_values: [SIM] + reject_values: [NAO] + continue_values: [CONTINUAR] + include_relevant_context: true + profile_name: router + prompt: | + Você classifica a resposta do cliente a uma confirmação transacional pendente. + Considere a pergunta pendente, somente o histórico recente relacionado ao mesmo tema e a fala atual. + Não execute a ação e não invente fatos. + + Classes permitidas: {{ allowed_values }} + - SIM: confirmação/aceite inequívoco, inclusive equivalentes como "isso mesmo", "pode confirmar", "é isso" quando o contexto tornar o aceite claro. + - NAO: recusa/cancelamento inequívoco da ação pendente. + - CONTINUAR: qualquer resposta que não confirme nem rejeite inequivocamente, incluindo pergunta adicional, correção, novo dado, ambiguidade ou possível mudança de assunto. + + Pergunta pendente: + {{ pending_prompt }} + + Histórico relevante: + {{ relevant_conversation_context }} + + Resposta atual do cliente: + {{ user_input }} + state_policies: - state: WAITING_BILLING_CONFIRMATION agent: billing_agent diff --git a/Tuning-Performance/Transaction_Evidence/agent_template_backend/docs/TRANSACTION_SEMANTIC_CONFIRMATION.md b/Tuning-Performance/Transaction_Evidence/agent_template_backend/docs/TRANSACTION_SEMANTIC_CONFIRMATION.md new file mode 100644 index 0000000..a550871 --- /dev/null +++ b/Tuning-Performance/Transaction_Evidence/agent_template_backend/docs/TRANSACTION_SEMANTIC_CONFIRMATION.md @@ -0,0 +1,11 @@ +# Confirmação Transacional Semântica + +Este template suporta confirmação transacional em duas camadas: primeiro um parser determinístico para `sim`/`não` e equivalentes explícitos; somente quando ele não consegue decidir, o framework usa um classificador semântico configurado em `config/routing.yaml`. + +A configuração `router.transaction_confirmation.semantic_fallback` usa três classes: `SIM`, `NAO` e `CONTINUAR`. O prompt pode usar `{{ pending_prompt }}`, `{{ relevant_conversation_context }}`, `{{ user_input }}` e `{{ allowed_values }}`. O histórico injetado é apenas contexto de interpretação; não substitui validação de negócio ou evidência MCP. + +Exemplo: após `Você confirma o cancelamento do serviço Tamboro Mensal?`, a frase `isso mesmo, pode confirmar` pode ser classificada como `SIM`. Já `mas qual é o valor?` deve ser `CONTINUAR`, portanto não executa a ação por confirmação. + +Entradas explícitas já suportadas continuam no caminho determinístico e não geram custo adicional de LLM. Em observabilidade, o fallback usa `transaction.confirmation.semantic_classifier` e o `route_decision.metadata` informa `transaction_confirmation_source: semantic`. + +Consulte `docs/developer/pt/03_transaction_workflows_and_state.md` do framework para o contrato completo e exemplos. diff --git a/Tuning-Performance/Transaction_Pre_Validation/agent_template_backend/app/agents/billing_agent.py b/Tuning-Performance/Transaction_Pre_Validation/agent_template_backend/app/agents/billing_agent.py index 05254d1..aa60099 100644 --- a/Tuning-Performance/Transaction_Pre_Validation/agent_template_backend/app/agents/billing_agent.py +++ b/Tuning-Performance/Transaction_Pre_Validation/agent_template_backend/app/agents/billing_agent.py @@ -95,7 +95,7 @@ class BillingAgent(AgentRuntimeMixin): state, system_prompt=apply_agent_profile_prompt( state, - "Você é um agente especialista em faturas.\n\nUse dados de tools/MCP e RAG autorizados como fonte de verdade para responder somente à solicitação atual.\nNunca exponha identificadores técnicos ou de identidade presentes no estado, contexto ou MCP, incluindo customer_key, contract_key, account_key, resource_key, session_key, customer_id, document, message_id, ura_call_id ou MSISDN/telefone completo.\nNão transforme nomes internos de campos em rótulos para o cliente, como “contract_key”, “customer_key” ou “MSISDN”.\nPara consultas informativas de fatura, apresente somente dados de negócio necessários, como valor, vencimento, situação e itens cobrados.\nNão acrescente canais, telefones, códigos USSD, URLs, aplicativos, lojas, relatórios adicionais, procedimentos alternativos ou próximos passos que não tenham sido explicitamente retornados pela tool/RAG e solicitados pelo usuário.\nNão ofereça espontaneamente outras ações ou detalhamentos.\nSe uma tool retornar BLOCKED, OUT_OF_SCOPE, NOT_ALLOWED, FAILED ou outro resultado terminal, explique somente o motivo retornado, não declare sucesso, não invente alternativa e encerre a resposta.", + "Você é um agente especialista em faturas. Responda com clareza, objetividade e sem sugerir ações não solicitadas. Use dados MCP quando disponíveis.", ), mcp_results=tool_context, rag_context=rag_context, diff --git a/Tuning-Performance/Transaction_Pre_Validation/agent_template_backend/app/agents/orders_agent.py b/Tuning-Performance/Transaction_Pre_Validation/agent_template_backend/app/agents/orders_agent.py index b793c26..f557bed 100644 --- a/Tuning-Performance/Transaction_Pre_Validation/agent_template_backend/app/agents/orders_agent.py +++ b/Tuning-Performance/Transaction_Pre_Validation/agent_template_backend/app/agents/orders_agent.py @@ -95,7 +95,7 @@ class OrdersAgent(AgentRuntimeMixin): state, system_prompt=apply_agent_profile_prompt( state, - "Você é um agente de pedidos de varejo.\n\nUse dados de tools/MCP e RAG autorizados como fonte de verdade e responda somente à solicitação atual.\nNunca exponha identificadores técnicos ou de identidade presentes no estado, contexto ou MCP, incluindo customer_key, contract_key, account_key, resource_key, session_key, customer_id, document, message_id, ura_call_id ou telefone completo.\nNão transforme nomes internos de campos em rótulos para o cliente.\nNão declare sucesso, alteração, troca, cancelamento ou qualquer mutação se a tool não tiver confirmado a execução.\nNão acrescente canais, procedimentos, ofertas ou próximos passos não solicitados.\nSe uma tool retornar BLOCKED, OUT_OF_SCOPE, NOT_ALLOWED, FAILED ou outro resultado terminal, explique somente o motivo retornado, não invente alternativa e encerre a resposta.", + "Você é um agente de pedidos de varejo. Use dados de tools quando disponíveis.", ), mcp_results=tool_context, rag_context=rag_context, diff --git a/Tuning-Performance/Transaction_Pre_Validation/agent_template_backend/app/agents/product_agent.py b/Tuning-Performance/Transaction_Pre_Validation/agent_template_backend/app/agents/product_agent.py index 998dad6..34433f5 100644 --- a/Tuning-Performance/Transaction_Pre_Validation/agent_template_backend/app/agents/product_agent.py +++ b/Tuning-Performance/Transaction_Pre_Validation/agent_template_backend/app/agents/product_agent.py @@ -95,7 +95,7 @@ class ProductAgent(AgentRuntimeMixin): state, system_prompt=apply_agent_profile_prompt( state, - "Você é um agente especialista em produtos, planos e serviços.\n\nUse dados de tools/MCP e RAG autorizados como fonte de verdade e responda somente à solicitação atual.\nNunca exponha identificadores técnicos ou de identidade presentes no estado, contexto ou MCP, incluindo customer_key, contract_key, account_key, resource_key, session_key, customer_id, document, message_id, ura_call_id ou MSISDN/telefone completo.\nNão transforme nomes internos de campos em rótulos para o cliente.\nEm consultas meramente informativas, não exponha flags ou capacidades transacionais internas como can.cancel e não informe espontaneamente que algo pode ser cancelado, alterado, contratado, removido ou trocado. Só mencione capacidade transacional quando o usuário tiver solicitado essa ação.\nNão faça oferta proativa e não execute nem simule mutações sem a confirmação exigida pelo framework.\nNão acrescente canais, procedimentos ou próximos passos não solicitados.\nSe uma tool retornar BLOCKED, OUT_OF_SCOPE, NOT_ALLOWED, FAILED ou outro resultado terminal, explique somente o motivo retornado, não declare sucesso, não invente alternativa e encerre a resposta.", + "Você é um agente especialista em produtos, planos e serviços. Explique sem fazer oferta proativa e sem executar ações sem confirmação. Use dados MCP quando disponíveis.", ), mcp_results=tool_context, rag_context=rag_context, diff --git a/Tuning-Performance/Transaction_Pre_Validation/agent_template_backend/app/agents/support_agent.py b/Tuning-Performance/Transaction_Pre_Validation/agent_template_backend/app/agents/support_agent.py index b15a0e4..b4f0244 100644 --- a/Tuning-Performance/Transaction_Pre_Validation/agent_template_backend/app/agents/support_agent.py +++ b/Tuning-Performance/Transaction_Pre_Validation/agent_template_backend/app/agents/support_agent.py @@ -95,7 +95,7 @@ class SupportAgent(AgentRuntimeMixin): state, system_prompt=apply_agent_profile_prompt( state, - "Você é um agente de suporte de varejo para troca, devolução e garantia.\n\nUse dados de tools/MCP e RAG autorizados como fonte de verdade e responda somente à solicitação atual.\nNunca exponha identificadores técnicos ou de identidade presentes no estado, contexto ou MCP, incluindo customer_key, contract_key, account_key, resource_key, session_key, customer_id, document, message_id, ura_call_id ou telefone completo.\nNão transforme nomes internos de campos em rótulos para o cliente.\nNão declare sucesso nem simule troca, devolução, garantia ou outra mutação se a tool não tiver confirmado a execução.\nNão acrescente canais, procedimentos, ofertas ou próximos passos não solicitados.\nSe uma tool retornar BLOCKED, OUT_OF_SCOPE, NOT_ALLOWED, FAILED ou outro resultado terminal, explique somente o motivo retornado, não invente alternativa e encerre a resposta.", + "Você é um agente de suporte de varejo para troca, devolução e garantia.", ), mcp_results=tool_context, rag_context=rag_context, diff --git a/Tuning-Performance/Transaction_Pre_Validation/agent_template_backend/app/presentation/tool_renderers.py b/Tuning-Performance/Transaction_Pre_Validation/agent_template_backend/app/presentation/tool_renderers.py index cb44202..f77c47a 100644 --- a/Tuning-Performance/Transaction_Pre_Validation/agent_template_backend/app/presentation/tool_renderers.py +++ b/Tuning-Performance/Transaction_Pre_Validation/agent_template_backend/app/presentation/tool_renderers.py @@ -13,42 +13,7 @@ def _money_brl(value: Any) -> str: def render_telecom_invoice(*, tool_name: str, result: dict[str, Any], state: dict[str, Any], agent_label: str) -> str | None: - """Renderiza somente campos de negócio seguros da fatura. - - Identificadores técnicos/PII presentes no payload MCP (por exemplo msisdn, - customer_id, document e business keys) não devem ser propagados ao usuário. - """ - lines = [f"[{agent_label}] Dados da sua fatura:"] - total = result.get("valor_total") - vencimento = result.get("vencimento") - status = result.get("status") - if total is not None: - lines.append(f"Valor total: R$ {_money_brl(total)}.") - if vencimento not in (None, ""): - lines.append(f"Vencimento: {vencimento}.") - if status not in (None, ""): - lines.append(f"Situação: {status}.") - - items = result.get("itens") or [] - rendered_items: list[str] = [] - if isinstance(items, list): - for item in items: - if not isinstance(item, dict): - continue - description = item.get("descricao") or item.get("nome") - value = item.get("valor") - if description in (None, ""): - continue - if value is None: - rendered_items.append(str(description)) - else: - rendered_items.append(f"{description}: R$ {_money_brl(value)}") - if rendered_items: - lines.append("Itens: " + "; ".join(rendered_items) + ".") - - # Se não houver nenhum campo de negócio seguro além do cabeçalho, deixe a - # composição pela LLM/guardrails em vez de despejar o payload bruto. - return " ".join(lines) if len(lines) > 1 else None + return f"[{agent_label}] Fatura consultada: {result}." def render_telecom_plan(*, tool_name: str, result: dict[str, Any], state: dict[str, Any], agent_label: str) -> str | None: diff --git a/Tuning-Performance/Transaction_Pre_Validation/agent_template_backend/app/workflows/__pycache__/agent_graph.cpython-313.pyc b/Tuning-Performance/Transaction_Pre_Validation/agent_template_backend/app/workflows/__pycache__/agent_graph.cpython-313.pyc index 8604cd4cf4a61e6e014cab3af2d5c818a673ef17..f8da2411374a668d8b44dc958f7cacccef523bd1 100644 GIT binary patch delta 7921 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 dict: - """Monta o contexto operacional do turno para os guardrails de saída. - - Mantém evidências/protocolos necessários aos rails, mas impede que uma - transação encerrada ou semanticamente interrompida governe o novo turno. - O histórico completo permanece no state/checkpoint para auditoria. - """ - ctx = dict(state.get("context", {}) or {}) - mcp_results = state.get("mcp_results") or [] - ctx["evidence"] = mcp_results or ctx.get("evidence") - ctx["tool_result"] = mcp_results or ctx.get("tool_result") - ctx["tool_executed"] = any(isinstance(r, dict) and r.get("ok") for r in mcp_results) - - history = list(state.get("history") or []) - current_user_text = str(state.get("user_text") or "").strip() - if current_user_text: - if ( - not history - or not isinstance(history[-1], dict) - or str(history[-1].get("content") or "") != current_user_text - or str(history[-1].get("role") or "") != "user" - ): - history.append({"role": "user", "content": current_user_text}) - - route_decision = state.get("route_decision") or {} - route_metadata = route_decision.get("metadata") if isinstance(route_decision, dict) else {} - route_metadata = route_metadata if isinstance(route_metadata, dict) else {} - pre_validation = state.get("transaction_pre_validation") or {} - pre_validation = pre_validation if isinstance(pre_validation, dict) else {} - tx_status = str( - state.get("transaction_status") or pre_validation.get("status") or "" - ).strip().upper() - terminal_tx = bool(pre_validation.get("terminal")) or tx_status in { - "COMPLETED", "FAILED", "CANCELLED", "BLOCKED", "OUT_OF_SCOPE" - } - semantic_intent_shift = ( - str(route_metadata.get("transaction_interruption") or "").strip().lower() - == "intent_shift" - ) - stickiness_intent_shift = bool(route_metadata.get("route_stickiness_preempted")) - should_isolate_history = semantic_intent_shift or (terminal_tx and stickiness_intent_shift) - - current_route = str( - state.get("route") - or (route_decision.get("route") if isinstance(route_decision, dict) else "") - or "" - ).strip() - current_intent = str( - state.get("intent") - or (route_decision.get("intent") if isinstance(route_decision, dict) else "") - or "" - ).strip() - ctx["current_user_message"] = current_user_text - ctx["current_route"] = current_route - ctx["current_intent"] = current_intent - - if should_isolate_history: - operational_history = ( - [{"role": "user", "content": current_user_text}] - if current_user_text else [] - ) - ctx["historical_transaction_ignored"] = True - ctx["historical_transaction_status"] = tx_status or ( - "INTERRUPTED" if semantic_intent_shift else "TERMINAL" - ) - if semantic_intent_shift: - ctx["historical_transaction_interruption"] = "intent_shift" - for stale_key in ( - "transaction_pre_validation", - "transaction_status", - "active_transaction", - "transaction", - ): - ctx.pop(stale_key, None) - else: - operational_history = history - - ctx["conversation_history"] = operational_history - ctx["history_texts"] = [ - str(item.get("content") or "") - for item in operational_history - if isinstance(item, dict) and item.get("content") not in (None, "") - ] - - protocols: list[str] = [] - seen: set[str] = set() - protocol_keys = { - "protocol_number", "protocolo_id", "interactionProtocol", - "protocolNumber", "finalizacao_protocol", - } - - def walk(value): - if isinstance(value, dict): - for key, item in value.items(): - if key in protocol_keys and item not in (None, ""): - text = str(item).strip() - if text and text not in seen: - seen.add(text) - protocols.append(text) - elif isinstance(item, (dict, list, tuple)): - walk(item) - elif isinstance(value, (list, tuple)): - for item in value: - walk(item) - - walk(mcp_results) - if protocols: - ctx["expected_protocols"] = protocols - ctx["requer_protocolo"] = True - ctx.setdefault("tipo_fluxo", "ajuste") - return ctx - async def output_supervisor(self, state): """Valida a resposta candidata com o OutputSupervisor corporativo. @@ -622,15 +555,15 @@ class AgentWorkflow: } candidate = state.get("answer") or "" - context = self._output_guardrail_context(state) - context.update({ + context = { + **(state.get("context") or {}), "tenant_id": state.get("tenant_id"), "agent_id": state.get("agent_id"), "session_id": state.get("conversation_key") or state.get("session_id"), "route": state.get("route"), "intent": state.get("intent"), "supervisor_attempt": int(state.get("supervisor_attempt", 0)), - }) + } async with self.telemetry.span( "workflow.output_supervisor", session_id=state.get("conversation_key") or state.get("session_id"), @@ -716,7 +649,7 @@ class AgentWorkflow: component="workflow.output_guardrails.start", ) final, decisions = await self.guardrails.run_output( - state["answer"], self._output_guardrail_context(state) + state["answer"], state.get("context", {}) ) for _decision in decisions: await self.guardrail_telemetry.evaluated("output", _decision) diff --git a/Tuning-Performance/Transaction_Pre_Validation/agent_template_backend/config/routing.yaml b/Tuning-Performance/Transaction_Pre_Validation/agent_template_backend/config/routing.yaml index 03aeaa9..bb4ef6f 100644 --- a/Tuning-Performance/Transaction_Pre_Validation/agent_template_backend/config/routing.yaml +++ b/Tuning-Performance/Transaction_Pre_Validation/agent_template_backend/config/routing.yaml @@ -7,6 +7,35 @@ router: confidence_threshold: 0.65 allow_handoff: true + transaction_confirmation: + # Explicit yes/no stays deterministic. Only inconclusive replies use this LLM fallback. + semantic_fallback: + enabled: true + allowed_values: [SIM, NAO, CONTINUAR] + confirm_values: [SIM] + reject_values: [NAO] + continue_values: [CONTINUAR] + include_relevant_context: true + profile_name: router + prompt: | + Você classifica a resposta do cliente a uma confirmação transacional pendente. + Considere a pergunta pendente, somente o histórico recente relacionado ao mesmo tema e a fala atual. + Não execute a ação e não invente fatos. + + Classes permitidas: {{ allowed_values }} + - SIM: confirmação/aceite inequívoco, inclusive equivalentes como "isso mesmo", "pode confirmar", "é isso" quando o contexto tornar o aceite claro. + - NAO: recusa/cancelamento inequívoco da ação pendente. + - CONTINUAR: qualquer resposta que não confirme nem rejeite inequivocamente, incluindo pergunta adicional, correção, novo dado, ambiguidade ou possível mudança de assunto. + + Pergunta pendente: + {{ pending_prompt }} + + Histórico relevante: + {{ relevant_conversation_context }} + + Resposta atual do cliente: + {{ user_input }} + state_policies: - state: WAITING_BILLING_CONFIRMATION agent: billing_agent diff --git a/Tuning-Performance/Transaction_Pre_Validation/agent_template_backend/docs/TRANSACTION_SEMANTIC_CONFIRMATION.md b/Tuning-Performance/Transaction_Pre_Validation/agent_template_backend/docs/TRANSACTION_SEMANTIC_CONFIRMATION.md new file mode 100644 index 0000000..a550871 --- /dev/null +++ b/Tuning-Performance/Transaction_Pre_Validation/agent_template_backend/docs/TRANSACTION_SEMANTIC_CONFIRMATION.md @@ -0,0 +1,11 @@ +# Confirmação Transacional Semântica + +Este template suporta confirmação transacional em duas camadas: primeiro um parser determinístico para `sim`/`não` e equivalentes explícitos; somente quando ele não consegue decidir, o framework usa um classificador semântico configurado em `config/routing.yaml`. + +A configuração `router.transaction_confirmation.semantic_fallback` usa três classes: `SIM`, `NAO` e `CONTINUAR`. O prompt pode usar `{{ pending_prompt }}`, `{{ relevant_conversation_context }}`, `{{ user_input }}` e `{{ allowed_values }}`. O histórico injetado é apenas contexto de interpretação; não substitui validação de negócio ou evidência MCP. + +Exemplo: após `Você confirma o cancelamento do serviço Tamboro Mensal?`, a frase `isso mesmo, pode confirmar` pode ser classificada como `SIM`. Já `mas qual é o valor?` deve ser `CONTINUAR`, portanto não executa a ação por confirmação. + +Entradas explícitas já suportadas continuam no caminho determinístico e não geram custo adicional de LLM. Em observabilidade, o fallback usa `transaction.confirmation.semantic_classifier` e o `route_decision.metadata` informa `transaction_confirmation_source: semantic`. + +Consulte `docs/developer/pt/03_transaction_workflows_and_state.md` do framework para o contrato completo e exemplos. diff --git a/docs/FIX_PAUSED_WORKFLOW_HUMAN_HANDOFF_PRECEDENCE_20260829.md b/docs/FIX_PAUSED_WORKFLOW_HUMAN_HANDOFF_PRECEDENCE_20260829.md new file mode 100644 index 0000000..9fb0b13 --- /dev/null +++ b/docs/FIX_PAUSED_WORKFLOW_HUMAN_HANDOFF_PRECEDENCE_20260829.md @@ -0,0 +1,49 @@ +# Correção: precedência de handoff sobre workflow pausado + +## Problema + +Quando um workflow conversacional estava em `WORKFLOW_PAUSED` com `expected_input` +enumerado e `semantic_classifier`, uma solicitação explícita de atendimento humano podia +ser absorvida pelo classificador local do workflow (por exemplo `SIM/NAO/CONTINUAR`). + +Exemplo de regressão: + +1. cliente pede explicação de fatura; +2. workflow pausa perguntando se a dúvida foi resolvida; +3. cliente diz `quero falar com um atendente`; +4. a frase era classificada como valor do `expected_input`, em vez de acionar handoff. + +## Regra de precedência corrigida + +A ordem passa a ser: + +1. `expected_input` determinístico continua com precedência absoluta (`sim`, `não`, etc.); +2. se não houver match determinístico, o framework verifica exclusivamente o controle global + `HUMAN_HANDOFF` usando o classificador semântico de continuidade já existente; +3. se não houver handoff, o `semantic_classifier` declarativo do workflow continua sendo a + autoridade sobre a mensagem; +4. `CONTINUE`, `ROUTE` e `END_SESSION` encontrados no probe global são ignorados nessa etapa; +5. as regras normais de transação e intent shift permanecem inalteradas. + +Assim, `quero falar com um atendente` não é tratado como `intent_shift`: é um comando global +de controle de sessão. A correção não cria lista de palavras nem regex de handoff. + +## Observabilidade + +Quando o handoff preempta um workflow pausado, a decisão contém: + +- `session_control=HUMAN_HANDOFF`; +- `global_control_preempted_workflow=true`; +- `workflow_interruption=human_handoff`; +- `interrupted_workflow_name`; +- `interrupted_workflow_execution_id`. + +## Testes + +Foram adicionados testes para garantir que: + +- pedido explícito de atendente preempta `expected_input.semantic_classifier`; +- resposta determinística `sim` continua retomando o workflow e não é roubada pelo probe global. + +Também foram executadas as suítes de regressão de transação/intent shift para confirmar que a +mudança não altera a precedência existente de coleta de parâmetros e confirmação transacional. diff --git a/docs/FIX_POST_FINALIZATION_SOFT_RESET_20260829.md b/docs/FIX_POST_FINALIZATION_SOFT_RESET_20260829.md new file mode 100644 index 0000000..cc669d0 --- /dev/null +++ b/docs/FIX_POST_FINALIZATION_SOFT_RESET_20260829.md @@ -0,0 +1,15 @@ +# Soft reset operacional após finalização de workflow + +Quando um workflow de domínio termina, a sessão conversacional permanece a mesma, mas o próximo turno deve iniciar uma nova interação operacional. + +A correção introduz um marcador `operational_context_boundary_pending` no fechamento do workflow. No primeiro turno subsequente, o marcador é consumido e o framework: + +- mantém `session_id`, `session_key`, `conversation_key`, identidade e BusinessContext; +- preserva o histórico durável/checkpoint para auditoria; +- mantém Long-Term Memory; +- limpa `pending_domain_workflow`, `pending_tool_clarification`, `active_transaction`, tool calls, parâmetros pendentes, confirmação, pre-validation, route/intent/active_agent e demais latches operacionais; +- não executa route continuity do fluxo encerrado; +- não injeta ConversationSummaryMemory nem mensagens recentes do fluxo encerrado no primeiro turno após a fronteira; +- entrega apenas a nova mensagem ao contexto operacional desse turno. + +O marcador de reset é de uso único e é desligado no `persist` do novo turno. A partir do turno seguinte, a nova interação pode novamente acumular seu próprio contexto curto, usando o mesmo identificador de sessão. diff --git a/docs/FIX_WORKFLOW_FINAL_STATUS_NORMALIZATION_20260829.md b/docs/FIX_WORKFLOW_FINAL_STATUS_NORMALIZATION_20260829.md new file mode 100644 index 0000000..bcc646b --- /dev/null +++ b/docs/FIX_WORKFLOW_FINAL_STATUS_NORMALIZATION_20260829.md @@ -0,0 +1,7 @@ +# Workflow final status normalization + +A resumed domain workflow may be returned by a legacy adapter with `status=PAUSED` even after its terminal node has emitted `workflow_response_final=true`. + +The framework now treats `workflow_response_final=true` as the authoritative interaction-lifecycle signal and normalizes that stale adapter status to `COMPLETED` before capturing the workflow latch. This clears the paused workflow/expected-input state, persists an operational-context boundary for the next user turn, and keeps the same session identifiers. + +Contextual re-entry routing now also degrades safely to the configured fallback when an LLM router response cannot be parsed, rather than propagating a structured-output exception to the HTTP endpoint. diff --git a/docs/FIX_WORKFLOW_TERMINAL_LIFECYCLE_SAME_SESSION_20260829.md b/docs/FIX_WORKFLOW_TERMINAL_LIFECYCLE_SAME_SESSION_20260829.md new file mode 100644 index 0000000..c9fba0a --- /dev/null +++ b/docs/FIX_WORKFLOW_TERMINAL_LIFECYCLE_SAME_SESSION_20260829.md @@ -0,0 +1,25 @@ +# Fix: terminal workflow lifecycle in the same conversation session + +## Problem +A conversational workflow could return `status=COMPLETED` and a final response (`workflow_response_final=true`), while a stale `pending_domain_workflow` / `expected_input` latch remained durable in LangGraph state. A later user message in the same `session_id` could therefore be interpreted as a resume of the already completed workflow. + +Scenario 22 reproduces the issue: after invoice explanation is accepted and protocol is returned, `ah espera` must be treated as a new interaction in the same conversation session, not as SIM/NAO/CONTINUAR for the old workflow. + +## Semantics after the fix +- Conversation identifiers are preserved (`session_id`, `session_key`, `conversation_key`, `user_id`, `msisdn`, customer/contract keys). +- The completed workflow is terminal only as an interaction/workflow, not as the user session. +- `pending_domain_workflow`, `pending_tool_clarification`, `workflow_input_reprompt`, active transaction latches and `next_state` are cleared. +- `transaction_status` is materialized as `COMPLETED` (or `FAILED`) so terminal state wins over stale checkpoints. +- The next message is routed as a new interaction in the same session. +- Router and input-guardrail layers defensively ignore stale paused-workflow contracts when transaction status is already terminal. + +## Main files +- `libs/agent_framework/src/agent_framework/runtime/agent_runtime.py` +- `libs/agent_framework/src/agent_framework/routing/enterprise_router.py` +- `../app/workflows/agent_graph.py` +- `tests/test_paused_workflow_resume_precedence.py` + +## Validation +- Framework transactional/routing suites: 119 passed. +- Focused migration suites: 12 passed. +- Full `tests/migration`: 789 passed. diff --git a/docs/FIX_WORKFLOW_TERMINAL_SNAPSHOT_SEMANTICS_20260829.md b/docs/FIX_WORKFLOW_TERMINAL_SNAPSHOT_SEMANTICS_20260829.md new file mode 100644 index 0000000..80dd6de --- /dev/null +++ b/docs/FIX_WORKFLOW_TERMINAL_SNAPSHOT_SEMANTICS_20260829.md @@ -0,0 +1,31 @@ +# Correção: snapshot terminal não deve virar PAUSED sem interrupt real + +## Problema + +O `WorkflowRuntime` tratava qualquer `snapshot.next` truthy do LangGraph como evidência de pausa. Em alguns snapshots/checkpointers, o último nó de ação já havia terminado e sua transição ativa apontava para `END`, porém `snapshot.next` ainda continha trabalho estrutural interno. Como não havia `interrupt()`, o runtime fabricava um `pause={"node": current_node}` e devolvia `PAUSED`. + +Efeito observado em `contestacao_tool`: `atualizar_status_sr` estava `COMPLETED`, mas o workflow era exposto como `PAUSED`, com `resume_tool=retomar_workflow`, impedindo o fechamento normal da evidência transacional. + +## Regra corrigida + +A precedência agora é: + +1. Se existem payloads reais de `interrupt()` no snapshot: `PAUSED`. +2. Se não há interrupt e o `current_node` possui uma transição ativa para `END`: `COMPLETED`, mesmo que `snapshot.next` esteja truthy. +3. Se não há interrupt, o estado não é estruturalmente terminal e ainda existe `snapshot.next`: fail-closed (`FAILED`) com diagnóstico, em vez de inventar uma pausa. +4. Sem interrupt, sem pending work e sem anomalia: conclusão normal. + +A mesma regra foi aplicada em `WorkflowRuntime.arun()` e `WorkflowRuntime.aresume()`. + +## Por que não há hardcode + +A detecção terminal usa exclusivamente a `WorkflowDefinition`, o `current_node` e as condições das edges. Não conhece `contestacao_tool`, `atualizar_status_sr`, TIM ou qualquer agente específico. + +## Testes de regressão + +`tests/unit/test_workflow_terminal_snapshot_semantics.py` cobre: + +- `arun`: `snapshot.next` truthy + sem interrupt + edge ativa para `END` => `COMPLETED`; +- `aresume`: mesma condição => `COMPLETED`; +- interrupt real tem precedência e continua retornando `PAUSED`; +- pending work não terminal sem interrupt retorna `FAILED`, nunca uma pausa falsa. diff --git a/docs/developer/en/03_transaction_workflows_and_state.md b/docs/developer/en/03_transaction_workflows_and_state.md index 86a3cd9..4adc0bb 100644 --- a/docs/developer/en/03_transaction_workflows_and_state.md +++ b/docs/developer/en/03_transaction_workflows_and_state.md @@ -557,3 +557,82 @@ The files below were consolidated into this manual: ### Maintenance rule New fixes or evolutions for this subject should update this consolidated document. Release notes may continue to exist as history, but they should not be required to understand or implement the feature. + + +## Canonical resolution and domain revalidation before execution + +When pre-validation resolves a user reference to a canonical entity, the framework **must not blindly overwrite the parameter and execute the originally selected tool**. The contract keeps requested, resolved and execution values distinct. + +A domain validator may return `transaction_decision` with `resolved_arguments`, `target_tool`, `action_changed`, `requires_reconfirmation`, and an optional customer-facing `confirmation_message`. + +Responsibilities: + +- **Framework:** preserve the requested arguments, apply only canonical arguments declared by the validator, update the transaction to the effective `target_tool`, honor reconfirmation, and retain the decision in pre-validation evidence. +- **Agent/domain:** decide business class, policy and effective tool. The framework must not know rules such as “Youtube Premium is strategic”. +- **MCP/backend:** execute the final operation chosen by the domain. + +If canonicalization does not change the action, the current tool may remain valid. If entity resolution changes business class/policy/tool, domain revalidation must happen **before confirmation and execution**. Ambiguous or low-confidence resolution must request clarification instead of silently promoting a candidate. + +### Troubleshooting: resolved_subject is correct but execution receives the original text + +If pre-validation records `resolved_subject="Youtube Premium"` while execution still receives `subject="youtube"`, verify that the validator returns `transaction_decision.resolved_arguments` and that the runtime applies the decision before freezing `pending_tool_call` / `confirmation_snapshot`. If the canonical entity is correct but the final tool is wrong, inspect `transaction_decision.target_tool`; that business reclassification belongs to the domain validator, not to the framework. + +For domains that expose an authoritative business classification in backend detail, revalidation should use that evidence before aggregated categories. In Contas, for example, `invoice_detail.parsed_content` preserves `classe=avulso|estrategico|bundle`, while `billing_analysis` may group the same item into broader sections such as `streaming` or partner services. Canonical entity discovery may use any authorized evidence, but the **business decision** should prioritize the source that preserves the domain classification. If classification evidence conflicts, do not silently change the action; preserve the current operation or request clarification according to the agent policy. + + +## Semantic transactional confirmation: SIM / NAO / CONTINUAR + +Transactions in `AWAITING_CONFIRMATION` use two layers, in this order: + +1. **Deterministic parser** for explicit confirmations/rejections (`sim`, `não`, `confirmo`, `pode fazer`, etc.). This remains the cheapest and safest path and **does not call an LLM**. +2. **LLM semantic fallback** only when the deterministic parser is inconclusive. The fallback reuses the same declarative semantic-classifier engine used by paused workflow `expected_input`, injecting the pending prompt, recent context related to the same topic, and the current user utterance. + +Configuration lives in `config/routing.yaml` under `router.transaction_confirmation.semantic_fallback`: + +```yaml +router: + transaction_confirmation: + semantic_fallback: + enabled: true + allowed_values: [SIM, NAO, CONTINUAR] + confirm_values: [SIM] + reject_values: [NAO] + continue_values: [CONTINUAR] + include_relevant_context: true + profile_name: router + prompt: | + Allowed classes: {{ allowed_values }} + Pending prompt: + {{ pending_prompt }} + Relevant context: + {{ relevant_conversation_context }} + Current user input: + {{ user_input }} +``` + +`SIM` means an unambiguous acceptance, `NAO` an unambiguous rejection, and `CONTINUAR` means the utterance does not safely confirm or reject the pending action. Example: after `Você confirma o cancelamento do serviço Tamboro Mensal?`, the reply `isso mesmo, pode confirmar` can be classified as `SIM` without hardcoding that exact sentence. + +When semantic confirmation succeeds, the router records: + +```json +{ + "transaction_turn_consumed": true, + "transaction_confirmation_decision": "confirm", + "transaction_confirmation_source": "semantic" +} +``` + +`AgentRuntime` reuses this routed decision instead of re-running the deterministic parser. The change is additive: existing explicit yes/no inputs continue through the deterministic path with no extra LLM call. Semantic generations are named `transaction.confirmation.semantic_classifier` for observability. + +### Durable interrupt compatibility in pause/resume + +The runtime does not use `snapshot.next` alone to decide whether a workflow is paused. A truthy `next` may represent LangGraph helper work, including framework-generated synthetic nodes such as `__pause` and `__continue`. + +A pause is recognized only from a real interrupt. Depending on the LangGraph/checkpointer version, that interrupt may be exposed through `task.interrupts` or persisted in `snapshot.values["__interrupt__"]`. The runtime supports both shapes and deduplicates the payload when both are present. + +This prevents two false diagnoses: + +- treating `snapshot.next` as `PAUSED` when no real interrupt exists; +- treating `next=("__pause",)` as invalid pending work when the real interrupt is persisted under `__interrupt__`. + +For workflows using `expected_input.semantic_classifier`, internal tokens such as `SIM`, `NAO`, and `CONTINUAR` remain resume control values and must not be confused with customer-facing output. diff --git a/docs/developer/en/06_guardrails_judges_and_transaction_evaluation.md b/docs/developer/en/06_guardrails_judges_and_transaction_evaluation.md index 7a83179..e98fa51 100644 --- a/docs/developer/en/06_guardrails_judges_and_transaction_evaluation.md +++ b/docs/developer/en/06_guardrails_judges_and_transaction_evaluation.md @@ -57,6 +57,69 @@ This version adds a pragmatic guardrail layer to `agent_framework`, inspired by - `RET_REL` — validates retrieval-chunk relevance using a minimum score. - `TOOL_VAL` — validates MCP/tool name, required arguments, negative values, and allowlist. +### Contract for authorized protocols in output guardrails + +When a workflow or tool produces a **protocol/reference number that must be shown to the same customer**, the agent integration code must register that value in the output context before output guardrails run: + +```python +ctx["expected_protocols"] = [protocol_number] +``` + +This field is a **framework contract**. It declares that those exact values were produced or validated by the current flow and may therefore be used by output guardrails as authorization evidence. + +Expected flow: + +```text +workflow/tool produces protocol + ↓ +agent registers it in expected_protocols + ↓ +CMP validates that the displayed protocol belongs to the expected values + ↓ +DLEX_OUT does not block that protocol merely because it is an identifier + ↓ +response may disclose the protocol to the customer +``` + +Important rules: + +- `expected_protocols` must contain **only protocols actually produced/expected in the current turn or transaction**. +- Do not use `expected_protocols` to allow tokens, credentials, arbitrary internal IDs, or third-party data. +- Authorization applies only to listed values; any other identifier remains subject to normal `DLEX_OUT` rules. +- The value must be propagated **before `output_guardrails`**. Adding it later has no effect. +- For transactional responses, keep protocol evidence in the tool/workflow result so `CMP`, `GND`, and observability can correlate the value. + +Example: + +```python +result = await execute_workflow(...) +protocol_number = result.get("protocol_number") or result.get("protocolo_id") +if protocol_number: + ctx["expected_protocols"] = [str(protocol_number)] +``` + +#### Troubleshooting: workflow completed but the response was replaced by a safety message + +Typical symptom: + +```text +workflow = COMPLETED +CMP = allowed +DLEX_OUT = blocked because of "internal protocol" +final response = "I could not safely validate this response..." +``` + +Check, in this order: + +1. Is the generated protocol present in the tool/workflow result or evidence? +2. Did the agent propagate the same value in `ctx["expected_protocols"]`? +3. Was `expected_protocols` populated before `output_guardrails`? +4. Is the protocol shown in the response exactly one of the expected values? +5. Is `DLEX_OUT` actually blocking another real issue such as a secret, token, or third-party data? + +If `expected_protocols` is absent, the framework must not assume that an arbitrary textual identifier is safe to disclose. + + ### Files changed - `agent_framework/src/agent_framework/guardrails/rails.py` diff --git a/docs/developer/en/12_input_guardrail_feedback_and_blocked_turns.md b/docs/developer/en/12_input_guardrail_feedback_and_blocked_turns.md new file mode 100644 index 0000000..88bb312 --- /dev/null +++ b/docs/developer/en/12_input_guardrail_feedback_and_blocked_turns.md @@ -0,0 +1,157 @@ +# 12 — Input Guardrail Feedback and Blocked-Turn Semantics + +## Goal + +This document describes how `AgentWorkflow`, implemented in `app/workflows/agent_graph.py`, should handle a turn interrupted by an input guardrail without turning every interruption into a generic “security rule” message. + +The core rule is to keep three concerns separate: + +1. **the guardrail technical decision**, used by the runtime and observability; +2. **the user-facing message**, appropriate to the type of block or clarification need; +3. **the turn state**, which must not carry routing, tool, or judge data from a turn that was interrupted before those stages. + +## Expected flow + +```text +user message + ↓ +input_guardrails + ↓ +allowed? + ├─ yes → routing → tools/agent → composition → output_guardrails + │ + └─ no + ↓ + select public handling + ↓ + clear routing/tools/judges state for this turn + ↓ + build a safe user-facing message + ↓ + output_guardrails + ↓ + persistence/response +``` + +A blocking input guardrail must be decided **before any side-effecting tool is executed**. + +## Internal `reason` is not the user response + +The `reason` field should remain available to logs, traces, events, and diagnostics. It should not be exposed verbatim when it may reveal internal mechanisms or when the technical wording is not appropriate for the end user. + +Example: + +```text +COER.reason = "utterance is incomprehensible or contains an ambiguous negation" +``` + +A public response may be: + +```text +"I could not fully understand your last message because it seems incomplete or ambiguous. Could you rephrase or complete what you meant?" +``` + +## Handling by guardrail type + +Exact behavior remains configurable, but the expected semantics are: + +| Guardrail | Recommended public handling | +|---|---| +| `COER` | ask for clarification/rephrasing; do not frame ordinary ambiguity as a security incident | +| `PINJ` | block safely without describing the internal mechanism | +| `DLEX_IN` | block or request reformulation without exposing internal/sensitive data | +| `INPUT_SIZE` | ask the user to reduce the input | +| `TOX` | apply the configured policy for inappropriate content | +| `CMP` | respond according to the compliance policy | +| unknown | use a safe generic fallback | + +## Clearing blocked-turn state + +When input is blocked before routing, the final state for that turn must not reuse residual data from the previous turn. + +At a minimum, the workflow should avoid presenting these as current: + +```text +route_decision +mcp_tools +mcp_results +judge_results +``` + +Metadata should clearly indicate that the turn was interrupted at the input-guardrail stage. + +This prevents misleading diagnostics such as: + +```text +route = blocked +mcp_results = [tool executed] +``` + +when the tool result actually belongs to the previous turn. + +## The public message also goes through output guardrails + +A response created because of an input block is still agent output. Therefore it should follow the same output-validation pipeline before reaching the user. + +This allows `DLEX_OUT`, `PINJ`, `TOXOUT`, Output Supervisor, and other policies to remove or sanitize information that should not be exposed. + +## Relationship with `agent_graph.py` + +This feature belongs to template orchestration because it defines precedence between graph nodes and blocked-turn state semantics. + +When changing `app/workflows/agent_graph.py`, preserve these invariants: + +- `input_guardrails` runs before routing/tools; +- an input block does not execute a transactional action after the block; +- the public response is not the raw guardrail `reason`; +- residual routing/tools/judges state does not survive as the blocked turn result; +- the public message passes through `output_guardrails` before persistence/response. + +The same semantics must be preserved in the official templates and equivalent variants under `Tuning-Performance`. + +## Troubleshooting + +### The user receives “I could not continue because of a security rule” for a merely incomplete phrase + +Check: + +1. which guardrail returned `allowed=false`; +2. whether `COER` is handled as clarification rather than a generic security block; +3. whether the blocked branch builds a guardrail-specific public message; +4. whether the generic fallback is used only when no specific handling exists. + +### Metadata shows a tool as executed while `route=blocked` + +Check whether the blocked branch clears transient turn state before returning. Also confirm that the tool was not executed in the same turn before input-guardrail evaluation. + +### The block response exposes internal details + +Do not use `reason` directly as user-facing text. Generate the public message and keep `reason` for observability only. + +### The block response skips output guardrails + +Check the graph edge. The expected path is: + +```text +input_guardrails blocked +→ build public response +→ output_guardrails +→ persist +``` + +not: + +```text +input_guardrails blocked +→ persist +``` + +## Recommended regression tests + +Cover at least: + +- `COER=false` asks for clarification instead of returning a generic security message; +- blocked branch does not retain previous-turn `mcp_results`/routing; +- no transactional tool executes after an input block; +- the public message passes through output guardrails; +- an unknown guardrail still has a safe generic fallback. diff --git a/docs/developer/en/INDEX_DEVELOPER_GUIDE.md b/docs/developer/en/INDEX_DEVELOPER_GUIDE.md index e88a907..20714e0 100644 --- a/docs/developer/en/INDEX_DEVELOPER_GUIDE.md +++ b/docs/developer/en/INDEX_DEVELOPER_GUIDE.md @@ -6,7 +6,7 @@ The documentation has three clear levels: 1. **Main tutorial:** [`README_en.md`](README_en.md) — creation, configuration, execution, and testing of an agent from start to finish. 2. **Architecture:** [01 — Architecture and Concepts](docs/developer/en/01_architecture_and_concepts.md) — components, responsibilities, and where to implement each concern. -3. **Specialized references:** manuals `02` through `11` — in-depth implementation and troubleshooting by capability. +3. **Specialized references:** manuals `02` through `12` — in-depth implementation and troubleshooting by capability. If you are starting a new agent, begin with `README_en.md`. @@ -31,7 +31,10 @@ If something is not working, use **Search by problem** below. | I receive 401 between gateway/backend/MCP | Basic Auth, credentials per hop | [Gateways and Auth](docs/developer/en/05_agent_gateway_mcp_gateway_and_auth.md) | | I need to decide whether something belongs to the framework or the agent | core/agent boundary | [Architecture and Concepts](docs/developer/en/01_architecture_and_concepts.md) | | An agent-specific guardrail is breaking another agent | extensibility, domain imports in the core | [Guardrails and Judges](docs/developer/en/06_guardrails_judges_and_transaction_evaluation.md) | +| An incomplete phrase receives a generic “security rule” message | input-guardrail feedback, `COER`, blocked-turn state | [Input Guardrail Feedback](./12_input_guardrail_feedback_and_blocked_turns.md) | +| `route=blocked` appears together with tools/results from another turn | blocked-turn state cleanup | [Input Guardrail Feedback](./12_input_guardrail_feedback_and_blocked_turns.md) | | A judge does not run in a transaction | sampling, `always_run_for_transactional`, transaction signals | [Guardrails and Judges](docs/developer/en/06_guardrails_judges_and_transaction_evaluation.md) | +| Workflow completes and generates a protocol, but the final response becomes a safety message | `expected_protocols`, `CMP`, `DLEX_OUT`, `output_guardrails` ordering | [Guardrails and Judges](./06_guardrails_judges_and_transaction_evaluation.md) | | Groundedness is evaluating without the correct context | RAG context, MCP evidence, judge inputs | [RAG/Grounding](docs/developer/en/07_rag_business_context_and_grounding.md) | | RAG does not find content | provider, ingestion, embeddings, configuration | [RAG/Grounding](docs/developer/en/07_rag_business_context_and_grounding.md) | | I do not know whether to use RAG, memory, or a tool | separation of responsibilities | [Architecture and Concepts](docs/developer/en/01_architecture_and_concepts.md) and [RAG/Grounding](docs/developer/en/07_rag_business_context_and_grounding.md) | @@ -115,6 +118,12 @@ If something is not working, use **Search by problem** below. **Use when:** it is necessary to prove the executed path or diagnose production. +### [12 — Input Guardrail Feedback and Blocked-Turn Semantics](./12_input_guardrail_feedback_and_blocked_turns.md) + +**What it is:** public handling of input blocks, blocked-turn state cleanup, and output-guardrail validation of generated feedback. + +**Use when:** block messages are generic, `COER` should ask for clarification, or blocked-turn metadata contains stale routing/tool results. + ### Main tutorial [`README_en.md`](README_en.md) remains the reference for the complete step-by-step flow: @@ -131,3 +140,4 @@ When evolving a feature: - update the specialized manual with behavior, configuration, examples, and troubleshooting; - update SPECs if the contract changed; - keep release notes as history, not as the only current documentation. + diff --git a/docs/developer/pt/03_transaction_workflows_and_state.md b/docs/developer/pt/03_transaction_workflows_and_state.md index 601f0c1..aa753ba 100644 --- a/docs/developer/pt/03_transaction_workflows_and_state.md +++ b/docs/developer/pt/03_transaction_workflows_and_state.md @@ -558,3 +558,136 @@ Os arquivos abaixo foram consolidados neste manual: ### Regra de manutenção Novas correções ou evoluções deste tema devem atualizar este documento consolidado. Release notes podem continuar existindo como histórico, mas não devem ser necessárias para compreender ou implementar a funcionalidade. + + +## Resolução canônica e revalidação de domínio antes da execução + +Quando uma pré-validação resolve uma referência do usuário para uma entidade canônica, o framework **não deve simplesmente sobrescrever o parâmetro e executar a tool originalmente escolhida**. O contrato separa três valores: + +```text +requested_subject = "youtube" +resolved_subject = "Youtube Premium" +execution_subject = "Youtube Premium" +``` + +O validador de domínio pode devolver `transaction_decision` com: + +```json +{ + "resolved_arguments": {"subject": "Youtube Premium"}, + "target_tool": "tratar_vas_estrategico", + "action_changed": true, + "requires_reconfirmation": true, + "confirmation_message": "Identifiquei o serviço Youtube Premium. Esse serviço possui tratamento específico. Você deseja prosseguir?" +} +``` + +Responsabilidades: + +- **Framework:** preserva argumentos solicitados, aplica apenas os argumentos canônicos declarados pelo validador, atualiza a transação para a `target_tool`, respeita `requires_reconfirmation` e mantém a decisão na evidência de pré-validação. +- **Agente/domínio:** decide classe, política e tool efetiva. O framework não conhece regras como “Youtube Premium é estratégico”. +- **MCP/backend:** executa a operação final já decidida pelo domínio. + +Se a canonicalização não alterar a ação (`Tamboro` → `Tamboro Mensal`, por exemplo), a tool pode permanecer a mesma. Se a resolução alterar classe/política/tool, a decisão de domínio precisa ocorrer **antes da confirmação e da execução**. Em caso de ambiguidade ou baixa confiança, o validador deve pedir nova coleta/clarificação em vez de promover silenciosamente um candidato. + +### Troubleshooting: resolved_subject correto, mas tool recebe o texto original + +Sintoma: a pré-validação registra `resolved_subject="Youtube Premium"`, porém a execução ainda recebe `subject="youtube"`. Verifique se o validador retorna `transaction_decision.resolved_arguments` e se o runtime aplicou a decisão antes de congelar `pending_tool_call`/`confirmation_snapshot`. + +Sintoma: a entidade foi resolvida corretamente, mas a tool final continua inadequada. Verifique `transaction_decision.target_tool`; a reclassificação de domínio pertence ao agente/validador, não ao framework. + +Para domínios que possuem uma classificação autoritativa no detalhe do backend, a revalidação deve usar essa evidência antes de categorias agregadas. No Contas, por exemplo, `invoice_detail.parsed_content` preserva `classe=avulso|estrategico|bundle`; `billing_analysis` pode agrupar o mesmo item em seções mais amplas como `streaming` ou serviços de parceiros. A entidade canônica pode ser descoberta por qualquer evidência autorizada, mas a **decisão de negócio** deve priorizar a fonte que preserva a classificação de domínio. Se houver conflito de classificação, não troque a ação silenciosamente: mantenha a operação original ou peça esclarecimento conforme a política do agente. + + +## Confirmação transacional semântica: SIM / NAO / CONTINUAR + +Transações em `AWAITING_CONFIRMATION` usam duas camadas, nesta ordem: + +1. **Parser determinístico** para confirmações/recusas explícitas (`sim`, `não`, `confirmo`, `pode fazer`, etc.). Esse caminho continua sendo o mais barato, rápido e seguro e **não chama LLM**. +2. **Fallback semântico por LLM** somente quando o parser determinístico retorna inconclusivo. O fallback reutiliza o mesmo mecanismo declarativo de `expected_input.semantic_classifier` dos workflows pausados e injeta a pergunta pendente, o histórico recente relacionado ao mesmo tema e a fala atual. + +A configuração fica em `config/routing.yaml`, sob `router.transaction_confirmation.semantic_fallback`: + +```yaml +router: + transaction_confirmation: + semantic_fallback: + enabled: true + allowed_values: [SIM, NAO, CONTINUAR] + confirm_values: [SIM] + reject_values: [NAO] + continue_values: [CONTINUAR] + include_relevant_context: true + profile_name: router + prompt: | + Classes permitidas: {{ allowed_values }} + Pergunta pendente: + {{ pending_prompt }} + Histórico relevante: + {{ relevant_conversation_context }} + Resposta atual: + {{ user_input }} +``` + +### Significado das classes + +- `SIM`: aceite inequívoco da ação pendente. Exemplos: `isso mesmo, pode confirmar`, `é isso`, `pode seguir`, quando o contexto torna o aceite claro. +- `NAO`: recusa inequívoca da ação pendente. Exemplos: `melhor não`, `não quero mais`, `cancela isso`. +- `CONTINUAR`: a fala não confirma nem rejeita de forma inequívoca. Exemplos: pergunta adicional, correção de parâmetro, informação nova, ambiguidade ou possível mudança de assunto. Nesse caso a tool não é executada por confirmação. + +### Exemplo + +Contexto: + +```text +Cliente: quero cancelar o Tamboro Mensal +Agente: Você confirma o cancelamento do serviço Tamboro Mensal? +Cliente: isso mesmo, pode confirmar +``` + +O parser determinístico não precisa conhecer literalmente `isso mesmo, pode confirmar`. O fallback recebe: + +```text +pending_prompt = "Você confirma o cancelamento do serviço Tamboro Mensal?" +relevant_conversation_context = histórico recente do mesmo fluxo +user_input = "isso mesmo, pode confirmar" +``` + +e deve retornar apenas: + +```text +SIM +``` + +O router então publica em `route_decision.metadata`: + +```json +{ + "transaction_turn_consumed": true, + "transaction_confirmation_decision": "confirm", + "transaction_confirmation_source": "semantic" +} +``` + +O `AgentRuntime` reutiliza essa decisão e **não tenta reclassificar a mesma fala com o parser determinístico**. Isso evita a regressão em que o router entende semanticamente a confirmação, mas o runtime volta a tratá-la como inconclusiva. + +### Precedência e compatibilidade + +A funcionalidade é aditiva. Entradas determinísticas já suportadas continuam com o mesmo comportamento e sem custo adicional de LLM. O fallback semântico só roda quando a primeira camada não consegue decidir. Assim, `sim` e `não` continuam tendo precedência absoluta sobre `intent_shift`. Uma saída `CONTINUAR` não confirma nem rejeita automaticamente a transação; o fluxo normal pode então avaliar continuação contextual ou mudança de intenção conforme as políticas existentes. + +### Observabilidade + +Para confirmações semânticas, o framework registra a geração como `transaction.confirmation.semantic_classifier` e acrescenta ao metadata do roteamento a fonte `semantic`, a classificação retornada e o contexto conversacional relevante utilizado. Para confirmações literais, a fonte permanece `deterministic`. + +### Compatibilidade de interrupts duráveis no pause/resume + +O runtime não usa `snapshot.next` isoladamente para decidir se um workflow está pausado. Um `next` pode representar trabalho auxiliar do LangGraph, inclusive nós sintéticos criados pelo framework como `__pause` e `__continue`. + +A pausa é reconhecida por um interrupt real. Dependendo da versão do LangGraph/checkpointer, esse interrupt pode aparecer em `task.interrupts` ou persistido em `snapshot.values["__interrupt__"]`. O runtime aceita ambas as formas e deduplica o payload quando as duas são expostas simultaneamente. + +Isso evita dois falsos diagnósticos: + +- considerar `snapshot.next` como `PAUSED` quando não existe interrupt real; +- considerar um `next=("__pause",)` como erro de trabalho pendente quando o interrupt está persistido em `__interrupt__`. + +Em workflows com `expected_input.semantic_classifier`, os tokens internos `SIM`, `NAO` e `CONTINUAR` continuam sendo valores de controle do resume e não devem ser confundidos com resposta final ao cliente. diff --git a/docs/developer/pt/06_guardrails_judges_and_transaction_evaluation.md b/docs/developer/pt/06_guardrails_judges_and_transaction_evaluation.md index b56c07d..18801e6 100644 --- a/docs/developer/pt/06_guardrails_judges_and_transaction_evaluation.md +++ b/docs/developer/pt/06_guardrails_judges_and_transaction_evaluation.md @@ -58,6 +58,69 @@ Esta versão adiciona uma camada pragmática de guardrails ao `agent_framework`, - `RET_REL` — valida relevância de chunks de retrieval por score mínimo. - `TOOL_VAL` — valida ferramenta MCP/tool, argumentos obrigatórios, valores negativos e allowlist. +### Contrato para protocolos autorizados em guardrails de saída + +Quando um workflow ou tool produz um **protocolo que deve ser exibido ao próprio cliente**, o código de integração do agente deve registrar esse valor no contexto de saída antes da execução dos guardrails: + +```python +ctx["expected_protocols"] = [protocol_number] +``` + +Esse campo é um **contrato do framework**. Ele informa que aqueles valores específicos foram produzidos ou validados pelo fluxo atual e, portanto, podem ser usados pelos guardrails de saída como evidência de autorização. + +Fluxo esperado: + +```text +workflow/tool gera protocolo + ↓ +agente registra em expected_protocols + ↓ +CMP valida que o protocolo exibido pertence aos valores esperados + ↓ +DLEX_OUT não bloqueia esse protocolo apenas por classificá-lo como identificador + ↓ +resposta pode informar o protocolo ao cliente +``` + +Regras importantes: + +- `expected_protocols` deve conter **somente protocolos realmente produzidos/esperados no turno ou transação atual**. +- Não use `expected_protocols` para liberar tokens, credenciais, IDs internos arbitrários ou dados de terceiros. +- A autorização vale somente para os valores listados; outro identificador continua sujeito às regras normais de `DLEX_OUT`. +- O valor deve ser propagado **antes de `output_guardrails`**. Se o protocolo só for adicionado depois, a autorização não terá efeito. +- Em respostas transacionais, mantenha a evidência do protocolo no resultado da tool/workflow para que `CMP`, `GND` e observabilidade consigam correlacionar o valor. + +Exemplo: + +```python +result = await executar_workflow(...) +protocol_number = result.get("protocol_number") or result.get("protocolo_id") +if protocol_number: + ctx["expected_protocols"] = [str(protocol_number)] +``` + +#### Troubleshooting: workflow concluiu, mas a resposta foi substituída por mensagem de segurança + +Sintoma típico: + +```text +workflow = COMPLETED +CMP = allowed +DLEX_OUT = blocked por "protocolo interno" +resposta final = "Não consegui validar essa resposta com segurança..." +``` + +Verifique, nesta ordem: + +1. O protocolo gerado está presente no resultado/evidência da tool ou workflow? +2. O agente propagou o mesmo valor em `ctx["expected_protocols"]`? +3. `expected_protocols` foi preenchido antes de `output_guardrails`? +4. O protocolo presente na resposta é exatamente um dos valores esperados? +5. O `DLEX_OUT` está bloqueando por outro motivo real, como segredo, token ou dado de terceiro? + +Se `expected_protocols` estiver ausente, o framework não deve presumir que qualquer identificador textual é seguro para divulgação. + + ### Arquivos alterados - `agent_framework/src/agent_framework/guardrails/rails.py` diff --git a/docs/developer/pt/12_input_guardrail_feedback_and_blocked_turns.md b/docs/developer/pt/12_input_guardrail_feedback_and_blocked_turns.md new file mode 100644 index 0000000..ed9d8a6 --- /dev/null +++ b/docs/developer/pt/12_input_guardrail_feedback_and_blocked_turns.md @@ -0,0 +1,157 @@ +# 12 — Feedback de Guardrails de Entrada e Semântica de Turno Bloqueado + +## Objetivo + +Este documento descreve como o `AgentWorkflow`, implementado em `app/workflows/agent_graph.py`, deve tratar um turno interrompido por guardrail de entrada sem transformar toda interrupção em uma mensagem genérica de “regra de segurança”. + +A regra central é separar três coisas: + +1. **decisão técnica do guardrail**, usada pelo runtime e pela observabilidade; +2. **mensagem pública ao usuário**, adequada ao tipo de bloqueio ou necessidade de esclarecimento; +3. **estado do turno**, que não pode carregar routing, tools ou judges de um turno que foi interrompido antes dessas etapas. + +## Fluxo esperado + +```text +mensagem do usuário + ↓ +input_guardrails + ↓ +allowed? + ├─ sim → routing → tools/agente → composição → output_guardrails + │ + └─ não + ↓ + classificar tratamento público + ↓ + limpar estado de routing/tools/judges do turno + ↓ + construir mensagem pública segura + ↓ + output_guardrails + ↓ + persistência/resposta +``` + +Um guardrail de entrada bloqueante deve ser decidido **antes de qualquer tool com efeito colateral**. + +## `reason` interno não é a resposta ao usuário + +O campo `reason` deve permanecer disponível para logs, traces, eventos e diagnóstico. Ele não deve ser exibido literalmente quando puder revelar mecanismo interno ou quando a frase técnica não for apropriada ao usuário final. + +Exemplo: + +```text +COER.reason = "fala incompreensível ou negação ambígua na transcrição" +``` + +A resposta pública pode ser: + +```text +"Não consegui entender sua última mensagem porque ela parece incompleta ou ambígua. Pode reformular ou completar o que você quis dizer?" +``` + +## Tratamento por tipo de guardrail + +O comportamento exato continua configurável, mas a semântica esperada é: + +| Guardrail | Tratamento público recomendado | +|---|---| +| `COER` | solicitar esclarecimento/reformulação; não tratar ambiguidade como incidente de segurança | +| `PINJ` | bloquear com mensagem segura sem explicar o mecanismo interno | +| `DLEX_IN` | bloquear ou orientar reformulação sem expor dado interno/sensível | +| `INPUT_SIZE` | solicitar redução da entrada | +| `TOX` | aplicar a política configurada para conteúdo inadequado | +| `CMP` | responder segundo a política de compliance | +| desconhecido | usar fallback seguro e genérico | + +## Limpeza do estado do turno bloqueado + +Quando o input é bloqueado antes do routing, o estado final daquele turno não deve reutilizar dados residuais do turno anterior. + +No mínimo, o workflow deve evitar apresentar como atuais: + +```text +route_decision +mcp_tools +mcp_results +judge_results +``` + +O metadata deve deixar explícito que o turno foi interrompido no estágio de input guardrails. + +Isso evita um diagnóstico falso como: + +```text +route = blocked +mcp_results = [tool executada] +``` + +quando a tool na realidade pertence ao turno anterior. + +## Mensagem pública também passa pelos guardrails de saída + +Uma resposta criada em função de um bloqueio de entrada ainda é uma saída do agente. Portanto ela deve seguir o mesmo pipeline de validação de saída antes de chegar ao usuário. + +Isso permite que `DLEX_OUT`, `PINJ`, `TOXOUT`, Output Supervisor e outras políticas removam ou sanitizem informação que não deva ser apresentada. + +## Relação com `agent_graph.py` + +Esta feature é responsabilidade da orquestração do template, porque define a precedência entre nós do grafo e o estado do turno. + +Ao alterar `app/workflows/agent_graph.py`, preserve estas invariantes: + +- `input_guardrails` antecede routing/tools; +- um bloqueio de input não executa ação transacional depois do bloqueio; +- resposta pública não é o `reason` bruto do guardrail; +- estado residual de routing/tools/judges não sobrevive como resultado do turno bloqueado; +- a resposta pública passa por `output_guardrails` antes da persistência/resposta. + +A mesma semântica deve ser mantida nos templates oficiais e nas variantes equivalentes em `Tuning-Performance`. + +## Troubleshooting + +### O usuário recebe “Não consegui seguir com essa mensagem por regra de segurança” para uma frase apenas incompleta + +Verifique: + +1. qual guardrail retornou `allowed=false`; +2. se `COER` está sendo tratado como esclarecimento e não como bloqueio genérico; +3. se o caminho de bloqueio usa uma mensagem pública específica; +4. se o fallback genérico está sendo usado somente quando não existe tratamento específico. + +### O metadata mostra tool executada mesmo com `route=blocked` + +Verifique se o ramo de bloqueio limpa o estado transitório do turno antes de retornar a resposta. Confirme também se a tool não foi executada no mesmo turno antes do guardrail de entrada. + +### A mensagem de bloqueio expõe detalhes internos + +Não use `reason` diretamente como texto público. Gere a mensagem pública e deixe o `reason` apenas em observabilidade. + +### A resposta de bloqueio ignora guardrails de saída + +Verifique a aresta do grafo. O fluxo esperado é: + +```text +input_guardrails bloqueou +→ construir resposta pública +→ output_guardrails +→ persist +``` + +não: + +```text +input_guardrails bloqueou +→ persist +``` + +## Testes de regressão recomendados + +Cubra pelo menos: + +- `COER=false` gera solicitação de esclarecimento, não mensagem genérica de segurança; +- ramo bloqueado não conserva `mcp_results`/routing de turno anterior; +- nenhuma tool transacional é executada depois de um bloqueio de input; +- mensagem pública passa pelos guardrails de saída; +- guardrail desconhecido ainda possui fallback seguro. diff --git a/docs/developer/pt/INDEX_DEVELOPER_GUIDE.md b/docs/developer/pt/INDEX_DEVELOPER_GUIDE.md index 91b9e9a..079cf67 100644 --- a/docs/developer/pt/INDEX_DEVELOPER_GUIDE.md +++ b/docs/developer/pt/INDEX_DEVELOPER_GUIDE.md @@ -7,7 +7,7 @@ A documentação possui três níveis claros: 1. **Tutorial principal:** [`README.md`](../../../README.md) — criação, configuração, execução e teste de um agente do início ao fim. 2. **Arquitetura:** [01 — Arquitetura e Conceitos](./01_architecture_and_concepts.md) — componentes, responsabilidades e onde implementar cada coisa. -3. **Referências especializadas:** manuais `02` a `11` — implementação profunda e troubleshooting por capacidade. +3. **Referências especializadas:** manuais `02` a `12` — implementação profunda e troubleshooting por capacidade. Se você está começando um novo agente, comece pelo `README.md`. @@ -32,6 +32,9 @@ Se algo não está funcionando, use **Buscar pelo problema** abaixo. | Recebo 401 entre gateway/backend/MCP | Basic Auth, credenciais por hop | [Gateways e Auth](./05_agent_gateway_mcp_gateway_and_auth.md) | | Preciso decidir se algo pertence ao framework ou ao agente | boundary core/agente | [Arquitetura e Conceitos](./01_architecture_and_concepts.md) | | Guardrail específico de um agente está quebrando outro | extensibilidade, imports de domínio no core | [Guardrails e Judges](./06_guardrails_judges_and_transaction_evaluation.md) | +| Uma frase incompleta recebe mensagem genérica de “regra de segurança” | feedback de input guardrail, `COER`, blocked-turn state | [Feedback de Guardrails de Entrada](./12_input_guardrail_feedback_and_blocked_turns.md) | +| `route=blocked` aparece junto com tools/resultados de outro turno | limpeza de estado do turno bloqueado | [Feedback de Guardrails de Entrada](./12_input_guardrail_feedback_and_blocked_turns.md) | +| Workflow conclui e gera protocolo, mas a resposta final vira mensagem de segurança | `expected_protocols`, `CMP`, `DLEX_OUT`, ordem de `output_guardrails` | [Guardrails e Judges](./06_guardrails_judges_and_transaction_evaluation.md) | | Judge não roda em uma transação | sampling, `always_run_for_transactional`, sinais transacionais | [Guardrails e Judges](./06_guardrails_judges_and_transaction_evaluation.md) | | Groundedness está avaliando sem contexto correto | RAG context, MCP evidence, judge inputs | [RAG/Grounding](./07_rag_business_context_and_grounding.md) | | RAG não encontra conteúdo | provider, ingestão, embeddings, configuração | [RAG/Grounding](./07_rag_business_context_and_grounding.md) | @@ -116,6 +119,12 @@ Se algo não está funcionando, use **Buscar pelo problema** abaixo. **Use quando:** for necessário provar o caminho executado ou diagnosticar produção. +### [12 — Feedback de Guardrails de Entrada e Turnos Bloqueados](./12_input_guardrail_feedback_and_blocked_turns.md) + +**O que é:** tratamento público de bloqueios de input, limpeza do estado do turno e validação da mensagem gerada pelos guardrails de saída. + +**Use quando:** mensagens de bloqueio são genéricas, `COER` deveria pedir esclarecimento ou o metadata de um turno bloqueado contém routing/tools antigos. + ### Tutorial principal [`README.md`](../../../README.md) continua sendo a referência para o passo a passo completo: diff --git a/libs/agent_framework/build/lib/agent_framework/__pycache__/__init__.cpython-313.pyc b/libs/agent_framework/build/lib/agent_framework/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..393fb8bf2df58c7487d87d77990daf4ab82a9a56 GIT binary patch literal 379 zcmZXPy-LJD6oqHk ztYpASQ0#=ffHUHvxVJcShL3X(w~wMdV&?7f_Tt{WulBPY=g0KN#@vyNBos+TGiOFq z2c5C??#xX+^im)Fbbx~~sl3?N!(&3*FdZrtFD+41Bq&G_RJg=Bg zu)@4yR}wEl7Cfo>vQ7ShWVzvWY0(Y=;DRfF$-2|S(?*t?nw?=}*4wk&k&#cAQu-W@ SZceU)7jpDY7Efe>p&?&%R&cEV literal 0 HcmV?d00001 diff --git a/libs/agent_framework/build/lib/agent_framework/__pycache__/extensions.cpython-313.pyc b/libs/agent_framework/build/lib/agent_framework/__pycache__/extensions.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6bcfde5da0b7a7eab0e0ada9f72736f89fc3fea2 GIT binary patch literal 2107 zcmah~-EZ4e6u&pNW5;Q{ZvDvGb&b~#+Kkc+P$$%}iLPuKE$cpv%S41CH*q_6sS~ap zM$3kRc$6=}_^j2F~p1^DLsPsJ7Pe@}7Gosza8 z2&z~@uW!SV40#a%MRV6=lYrYB=Oz_2*0`<7soWgkO-6jJ$|WU#?qhA{3^dy!^Up?B zxd9XxW*oFKcI*>dC#IH_(>Zu9Q#Wmy=pPjfqFeG%I;&aMxa_^)_#|D;XiNH#gU27y z=Wy`o%HDU(kF~6kk@co0YA5G4`~0}P()~1myA2g0&*uteW?YU74rAHG;XoL9N1WBN z1^pNyIpPF~mCqVBVQCP4L5HdWL(#Ad)3P-)tvjr}oY&()hox~G4j>eCC+s0jnE=ue zUG&~O=qVf~owY2W1(Mz2oYofL#;JJ%2QKEwg;XwWB(lbwm3T&xm@63B3{^d+q4zc| zTJ)p&Wv4Bh(=sVP7bzD5>4J##v8BuIgW0s`d?iH}dVs_tx!+O5ec^A+{P``=AvwuyioT$_}KHt zosK(vx$CWpG*K2NYLV{Jp-N<^c)TX=TzhFfQxRV-PC|gsKmB_Dy7J?|W_MzvJ3*uG z8N03De!tvxxFQ`X3rDJ9sW`O-pwUb`-~=yR)X0M62!^?+r)@pcWHaRo<&n$g^H3W9 zX0y*dlSww&tKw%legHM?ST*px_H2{Q6p%N3=C`2}oei$es_ct6eQwrgiHuI}Mkowj zr5CA8AM}<3NM+x~2k`*fhmwNtn@8F-?L8{%^GZ7kT!j;URFj8T|Bb5ON41UD1s{p; zm-e`m(e3O$S5SjK_W|#qhgapTKnx8a9nGV|ObpHAcwpuS6zAOvbJ&cLwjIu}^(D&@ zE#1!O^I9QmJE8Z0EFQD?^P1(7i3dHM#09boZcO%2(L)6QK~6BQ0Vynpxu7qTHoC*) z<`ylQ9FIG)OdyNMY4<2;8=9>*>z>e?#o*t%1p+Ew+*^XG>n~2$B2a-hM@mO4ky!C~ zH5$A5+4^gnog*8aBlkK-uZXKmRggA?t_`89)PGMHe9WL|qRxgn>HdygS1zy3Ub$Qr zdj773+qY1NlOBe5-rv=6eQ7e;fLN^-B1zMk&O3fF*rJhO= zN(v|B{a!+g@!DPxA{pj_Ywy0Vn^e+EeRNadreAo|Yi&o!DD2UuY|%-b!5BY4eRY<@ i?4J_C0}oK=A3+K4sP~~0_+4DiS%0BcEY+!S{rv;;jnj$% literal 0 HcmV?d00001 diff --git a/libs/agent_framework/build/lib/agent_framework/__pycache__/gateway_policy_context.cpython-313.pyc b/libs/agent_framework/build/lib/agent_framework/__pycache__/gateway_policy_context.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8f935c6139b2a3d6aa9205f81e46f066717ffdec GIT binary patch literal 1459 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 literal 0 HcmV?d00001 diff --git a/libs/agent_framework/build/lib/agent_framework/__pycache__/runtime_mcp_gateway_adapter.cpython-313.pyc b/libs/agent_framework/build/lib/agent_framework/__pycache__/runtime_mcp_gateway_adapter.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..382381335965bd134b893159fd9cedefa2f030bb GIT binary patch literal 2156 zcma)7%}*Og6rc6(de2SBc5Yt%|eRVs0F!U46XzFB(%1W-G+pXbe+_vZJ$ zW)7N~f(XW6zpTyuBp~!BW4r-88{EN7pzBCQDmQ_~Il?8`+&AGH=Lzr5`3YfMBw`Z9 zQ7=-34y201KBkKh@fZAxw9lprM?<=4T8{1*mT3da-!WI~%!!`zp_L}oR1B(0-Kex1x%CZ=r**+s2T$EjuOKpQb~AvOX1 zj>YS9@ckl60@!IZ<%&*{fd-okA#}gt9)jo&b9Djc&eod}PugMJG&d!kUR8Z6?`7be z9fEh-E$%Iz4g{#r*)N{4AN+*;`_IvkJdJ7JG=JLwN_YM!o+raR-4Bw zR9?W2p3@zj$_~-973z!CUQYb9|EStQ? z3EL%^~FVO<`j_%HZJC= zXu~ywNt7KBW5)aq+zf%NCi}tgJCuG-mC=cLam8C8L;QqEix5zdy9& zR|5oR5spqRuF$yF0DWBUIxu*2%N)OhQs*hKaN2Kx?4xf`EsR>*D=ifvJy-5Zzm|k(bFBr%Z`4pY z9y~@Q2?tzVe+pM;}9lLg~ zk9#@F-Rl)z-WY)Sb9hiPicESy`cHGt$U66Jhg?p=oARZbcgh3rCVw?@QtaL6P!mpx znB)?eP-H4=Zh>kV4Qkqgl`9o7%)^@YRY@JzvB!XXkE%l>J3@3PK3En;Ala9% z)BUUNa z4YNSl^F`zDlzXc2#@U4RN*y1=T(`+EQ~72+JfDyuU^)2NaUeCG+OvaT77#;&ASqx#ymlMYGueUGFcC*AE2X%`{b6KV)&L$rJRTM`DNwlE^}< zWqK>NBL|(5+p!yY=#|`w{iueu7KG4qF9_C0Uf_Rde+VqK-I=g-R){1&pY~IcUvX4> zT`9Bm^MI(sGda#=E(-pyyxX6ObU;~UN%<|G6ngF;LCy;POUbHjfs3||f{p>#fM>wh z&8X55S(;M%3=2H~>XMCgMmj_` z=64crs7yqdihdsc5yH~cNNdXS!6Bt$A__{6vYD#2$8s=D`3Y|6MdrWreGQ*BA>c+WirrRi3M|{bz3bM!-E(FS zX%j;ef-%N~7}JF4g9aajHy(u-()8W5GK-Qq-b1j-2BJO#)CQjmg&(GaGXa9kJ`sNl~c6=4>KrJ(=~ z3vMB4h_jvCg_+rx}z%c{+vKc@Bl8;G}4ZM4#kinACnJ=mDReOkPNSLB8j~^ z&9)s^b4|x)BT2y%)Ap<<54r}`rYvKfOM+cH(za&Jx~9&K7N;zeO&fHsOUoIyt7fT| zH{N&XyD6=@C#5_2g2PPL(92hrVdZ|j*$4CjI)*4#5ZH>rPJv2_s7NWSgq1)H%}6r> z4JZ*M$Z;A}LNt_*&=jUT$uC{AT(e*~ zjARVvnzqAIk;phRNI|0-p-x7l4{7`dB<{cnokm^NZ<;pxl5OGrbhBbxcO<_a*CN$WQ@B$tC^O{Obe9L z1yGw0?r`oX`0(a4fGnWNN;nZ3$JNk|BdfOh4za4IQ4XRtk`z4&g5-LULN!{9)`2X} zV1|{YjX?M-jNe5F@$_xcR2|*ywah8jyN%I1RWz*(XFbHJB|vX20o0lXsRHDcs+zXx zs;c++BjT8a*E?fhVLwQ+joGR zKqv4Cp$idk;20X^{B2`@h0cH@b5M8Vcw87qeWHRP=j0j57AI?N9fca+J`(>Sw*|c= zF`*YRp#{ALUBDSgpmC`hxTC`BkfwE@7ZYshc{B($KMhu#!VBU^pdQw9z$tUHVA4qB z1u=`0;)o7v)YOq&20gfsm1|vfXA1^U$&eSS?DoR1oYsv3Z**P|iZo|XFKpD7 z!m6rU8e@=~kfk>CG*vCvjO2xD7kUxDmH6U8vNmfuT81`(F^oHl%+Jr$C?H;g%CxLe z&3^C2N2Pm3daB=Ybj@OiQV*Q%;KHW?+*^k_*bo8@v9;ECskM8hwfj=!%B!ob{iSIC zYPA2}&6YizNNkARjJB4dWF<W$t*xWf z)(yY4ox5*~sD1xN08anSo`uWK;&d-Qw=01@$3*%tX)9mu`X4TAgN^J6fWNq})|y(*pE-YKt$xQ{DHx93MgZw7e2W3<`41StMQf2!R5xGl038`5B+(gbC6Gr>v!&@^gg_Z zn$w-~VsnV&?Ks^fE$*%ZJSq5@;#)Zae&F48Zcp_MoqYJEI_~fHq$$U-l0n}Ao(NBc z?}fR>jH$bmK=u%LjE~d3AdV&gBxTC8!HcMB-pLd#NKvm|Ro^RWRykq4CRNRvl)08^ z8@2=Nkg8@J9a6cO3-KMfOH~el1U`=MA|cRySFR5XG|NDU>hFB%Za`}5J!Be{{UUTV@Lo1 literal 0 HcmV?d00001 diff --git a/libs/agent_framework/build/lib/agent_framework/analytics/__pycache__/event_builder.cpython-313.pyc b/libs/agent_framework/build/lib/agent_framework/analytics/__pycache__/event_builder.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4446a3ff19791932b3e1771b321481bf94f9b354 GIT binary patch literal 1228 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 EA0N=mcmMzZ literal 0 HcmV?d00001 diff --git a/libs/agent_framework/build/lib/agent_framework/analytics/__pycache__/publisher.cpython-313.pyc b/libs/agent_framework/build/lib/agent_framework/analytics/__pycache__/publisher.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..39a072884319e04d6259a36f30bdbbb2b2b698f9 GIT binary patch literal 1840 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 literal 0 HcmV?d00001 diff --git a/libs/agent_framework/build/lib/agent_framework/analytics/__pycache__/tim_sequence.cpython-313.pyc b/libs/agent_framework/build/lib/agent_framework/analytics/__pycache__/tim_sequence.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..025f7710528adee5619c6caa9a40d044a37deade GIT binary patch literal 17529 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 IehvNq06bvi4*&oF literal 0 HcmV?d00001 diff --git a/libs/agent_framework/build/lib/agent_framework/analytics/providers/__pycache__/__init__.cpython-313.pyc b/libs/agent_framework/build/lib/agent_framework/analytics/providers/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9a843496bdee57aa25ec4fffcb6e20343e3782d1 GIT binary patch literal 482 zcmZvY&q~8U5XNWow<^J-#e?)(5#v=Tf_O3!|B#cXWz%ls+HF#16Q##Kf(IYMNAOh^ zauNh@Vqd^bXfN71e0;-icD`knL9h*`KHpy+?+L(1)2z!{ndQKkS4bcsF+>DOukluF zMK;>4w__)A(QUmGdy$WR4?;-XJA$3e>-%43H}r`K zA7Sf*gflFj#E7E`DHXXWDLtOeb!RXwMwR4exN9Ptld7(fZ<`QO!)XmiH5}G(^5eKW J*22fYz+ZXCjT-;} literal 0 HcmV?d00001 diff --git a/libs/agent_framework/build/lib/agent_framework/analytics/providers/__pycache__/kafka.cpython-313.pyc b/libs/agent_framework/build/lib/agent_framework/analytics/providers/__pycache__/kafka.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b2e4a9a599455af3b91a06f7d2f28b8353641470 GIT binary patch literal 1780 zcmaJBO=uid_|5Nbc9XQbn3|-feI$owOS0)9u`Nm=#RzW7Dj6c7X&v6qzTHeRnK!;S zle#^Lf>cnnLa4_U57I-yt2axo900%a4qKaAIfPcg*=W+|wp*4!5bsTV3j~vSJ>ed77aF^5>4hSdM-};VW;;_IY z95dYDWS!n(d<_$LMzH7BFckrHwjMQHhvdc`<~O{E`r+i7bZi0>mvyn^nhaXu3iB}y zopPy+-#xS(aO${%VER$OI2P2e=ZFwnk9>zSpJ5i^1EQRBy7^BsC-Voivi}+&n`r5z zm#`&R!k&^6O(;?Ip&Dn?U}Ga>f$NmCSQpf5@H}YpUI0S=9b+8ZqzR$e2T|M1ai<_= zF?B>RRf}A&E=9*ABrX0F*xhjJl#8h(73H86XKmZ{-O#qH0t3WfHKr zsJ{cFy8HVCwD++*A17LkQ1Wn+C+Fh4fx(Rv_aO@ur)sqZkTqzqR!k6%yvCeEx7 zLBf!i4BjV2Il3YHN80AENJeIz3IV+no16-;F62IfPQ#e@C-R`PA>y<1|2@~`uEGFl zi!}gy&<{_Gr|zBq=KTHD_Q>4NqFuChir3r4>)XqN5~$Y`e}J+vc)c_$YvQz_x{4#f~it;?|;&3fq2&xSXRT*<7}G0_3g~lK&a{Lp6-- z%YM~3{a02uhC13(5nKa@8WA`P4sp35_z-~DgzCC}lgq&4u_Jq-d@%iK;V9>_<{je` z5<74x&c4|R_zJ%O0y%5q41gD!qA1VM=yQ~RhEDy4uD&!+Dnr|6F8qn$PTv0m2~o)D literal 0 HcmV?d00001 diff --git a/libs/agent_framework/build/lib/agent_framework/analytics/providers/__pycache__/langfuse.cpython-313.pyc b/libs/agent_framework/build/lib/agent_framework/analytics/providers/__pycache__/langfuse.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..eb3c2eae505eb34af0237aa1b56a46f167522ecb GIT binary patch literal 23140 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 literal 0 HcmV?d00001 diff --git a/libs/agent_framework/build/lib/agent_framework/analytics/providers/__pycache__/oci_streaming.cpython-313.pyc b/libs/agent_framework/build/lib/agent_framework/analytics/providers/__pycache__/oci_streaming.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..850581c140d4e1dc57de95ea1f1f40ef5a2e1e2a GIT binary patch literal 1789 zcmah}&2Jk;6rb^acw;-x7Y!v8Se%e%tI9!$sG=fGO%YXW$)GN7BPD3GvB&O)&8|B$ z8%V?ffrNU5LvEb;yl{kL|AR&maP6r|ihDIhrUX6;SD5iruec{A_LZ{NK4dviQE zm_aap`tFmpuQh~zl#67*S`K_%2Dy!FWaA1dV}?zsrz)wk!jxE7Dr#9{TCA%Ty_{xg z6P-r|WNQ=1)>pJSMIs@@j8@t*j-+bgDC_usAROTaK8K}J@;6}`E%}bODcm}LBV6@d zewQ-XJx_feGD};bI#ITK6%EnBwQ%tqfwqdIi zXiZ(iOtS}Mcxx)tZJniCij|3;e*MOxEf{syUB7iUj-vs9-C8U)oVK9MY&*;`84ZQ& zxmyl11GAk(YyyyZf@IQnT`s6EsM!e2CUe&5I{|yUSgrR0j^kHB!Wtj1#KG56t7(Lm zOfNP{(Siy<-f=nQ%e-S-sVHUDS4~t?3#f+Y@l4ORkwOS|l{wtqsG+~3SZbAlgDio; zsSt2ing8)RTwFkAHy~1SaurL9hWfUmXPlPwIlW0e@SAR{n4qyNz(-U4UNH{Q*K0`A z8HD!sk)!PqWyS+Pk=l-i;I0jdAh6^7`E_?-+NvP#ETJF^np;~HLmMw?K2b<3LW@yb%zFl!_t8q@dB47_9JduBE8X>4Op0g$D$378@Uh|it`Z7VM`vkc42 zCLDMx(is&Y^CMLrvgf&k=GjbiAHrh>)hsxbR$``T>~JgfxOW zAq;5HOWipF%?6Kboj5`;cQq806Y?cu=cG%VVnb?D$l~)65Fep^)&5P@wI%%fu%TVY zU2o}AwFYEF%@Cr6h?p!^q(cGW8Da7bizfRTuz1pD#gkWsNsdO-|L!T=^^?cG%bz$( z*;S{JN5;$D%v@ua!5}+?n;?ExFvbU{aEQha(JKe2@<<=U*YU&WuKbFm5+nQtP$$+O literal 0 HcmV?d00001 diff --git a/libs/agent_framework/build/lib/agent_framework/analytics/providers/__pycache__/pubsub.cpython-313.pyc b/libs/agent_framework/build/lib/agent_framework/analytics/providers/__pycache__/pubsub.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..91e65961c82b5aafaa88cdf29d70e42ef59b6b6b GIT binary patch literal 7408 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 literal 0 HcmV?d00001 diff --git a/libs/agent_framework/build/lib/agent_framework/billing/__pycache__/__init__.cpython-313.pyc b/libs/agent_framework/build/lib/agent_framework/billing/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e9e66d6730ea711bb7cf1a7e8ed4a794b2348f59 GIT binary patch literal 371 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 literal 0 HcmV?d00001 diff --git a/libs/agent_framework/build/lib/agent_framework/cache/__pycache__/__init__.cpython-313.pyc b/libs/agent_framework/build/lib/agent_framework/cache/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..04b86877a0e3a3b682c774bdfa0376cf5581560f GIT binary patch literal 181 zcmey&%ge<81kZL(%mUGmK?DpiLK&Y~fQ+dO=?t2Tek&P@n1H;`AgNm+iRr0%CGlxR ziMgre`9<0B`N^63Ihjet`e+jRNu`-NDIh5fndHRej8y&j_{_Y_lK6PNg34PQHo5sJ ar8%i~MXW$eK#nK|F+MUgGBOr116crUvoSyb literal 0 HcmV?d00001 diff --git a/libs/agent_framework/build/lib/agent_framework/cache/__pycache__/cache.cpython-313.pyc b/libs/agent_framework/build/lib/agent_framework/cache/__pycache__/cache.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e47f0c9ef48acdf2374440212e714ab4a73ced56 GIT binary patch literal 16491 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 literal 0 HcmV?d00001 diff --git a/libs/agent_framework/build/lib/agent_framework/channels/__pycache__/__init__.cpython-313.pyc b/libs/agent_framework/build/lib/agent_framework/channels/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..37b3d894ee622a1a0e9cb4c530e72cd59ec94f1d GIT binary patch literal 184 zcmey&%ge<81kZL(%mUGmK?DpiLK&Y~fQ+dO=?t2Tek&P@n1H;`AgNp7iRr0%CGlxR ziMgre`9<0B`N^63Ihjet`e+jRNu`-NDIh5fndFSbyu8$$V*U8|%)HE!_;|g7%3B;Z dx%nxjIjMF7&-6`tWgmy%YrWa=*#){Jb2mP@;?f1=bjO3O)V$re&=X%~@#&5B$}8${-&^kT&y@QE zbg=t&e%`#9eeZqW%zkGlN1*)u4{IO&B}B;Iu;CWJQ`yf!Pe1ELCp|!;jS|0xK%Lz_*>8@s4~oTrp?5i zDe(`I!nmFnRKw8E2pKtF&<)!rH&--N4FVxKnrDQ(p&D83jG$`wbTy+$YF1E$B9otjP9GvI>`3R2F0=$hxqsv!(f*zI^uf_j|JeTEpNvB*rH1oy=VBKEkLpELUL%PG!M%uXj0NM>e-w+XPj*rI6GHV zb6FgEX(UrkJ(yBWJ|kK9#Ojjr3R_UzUuIEQ5mz9!3E&~ZxE64+%!MmRW`>#V{J%rSHIiWS0rqk{YYLf|YLmLpBM<^Yl z?`fkCDSfEEw~f9HRnez;W@@k${b|o3D+XK(hl~gR&3MQiZ}1Al|Ii(WUHzFF@Y6Lf ziQHIVgk1K{(?n#-3g#U`^C3!|wAW0Fuo(E*;tUv8bqye71&e@jtN?0kZp3=nso%^d z0x-Kezy@G0dkw`g6vHUOAQD~{!8#_coxun%L&?qCfU>6<=ukis>xQot)^wJabL!6& ztGAv=$yzUN()a?z3&23-$iVt{Hl`m0D}1aW^=CKx9uI8|J-Jg#Tq*Oj+rej%r;$J1 zEdAgPw07Q~ec*e}AFK2ZRH8>KeZ%Yb*X}>MQtCTb=^a|1T$_9pF7=*n>@WA-dh+h? zCcm28j+8FkdfppMOpl z%*S{6c!?j`35|SfGuWrm9=b)QwnA1&k~Cm2NwPRef~AW&tanJ#Pm6NS8Q~>qUS)=v z11{Ed81~@+!(|wrY1UCmGECW2Gm>nYOr0wN{Yw(V-)BcqV2By+$QH;B2GZKkNhQ*~ za^s&q&d+_*PyHvV+NhX;w^pcA`)}xozq=@#MygP7PM{Yj!H5-F#$LHlXbKo+tR1j_ zK*bGM0|deCcwTF?ex8d+QkcOlMXZs|A>-{x#wDe8_IxhHTlWJr)P4sw5^75d!7;y+ zZlNiL326D|nVzpA87>Hf4WU3xZ~2*kbsN=nq@%aCyj5u1AjeQTxoX3^F-`3(u?AX# zQO9)x<{BS>Xu`FP(_t5kmr8x7E7AV-p|zonJEiDIIeKF=_&Bl^d2+M##x-bd$6Zy# za}BAH03tO|Lu%?=>U=X&k)G_p7og$>ej4hnrEREdObdZPODzR@ksw-%=t+8=0C=Zt z*8(+qOubH}37-|pD<<3tOu5RUb>CwWH@VlwU#!)=RUY^rDknkMzKso+W2bgwr^>O> z-Pq{ntx{}k`^{%ppI+VhaIyTMu?r7x?u1N-Aue2^Hh`ztC|GF4GMZ*6>n!sh=7WA`rdpThW6 zu=gJd`@kWvuiY)$!ah`keRztEqXWINrdpiIWX;GhwP3bm0QM$mvN05IfoRG+q<<^c z7??V$ZRI>Dyo~B07pfOaeF+!Uv!&?ia#Y@2c)YZ=^!t;gWC~i_cc0BXo!R-(`=z&M zpt&Q-?$lSJ{Cem**Nk$E$7k^FUjgCfMLU#(XMyTli%63m2eF>1gvat51w~%688YFi z!1rcs=&MfOBfLSs(S{G|K`}Qjy+i{U%I&q4?nRJns7ik_}Z&Lm;wt71p>lw zL3pGAgp&>kQE4g>wtRCkTwRr+4v(JA4`kgZa literal 0 HcmV?d00001 diff --git a/libs/agent_framework/build/lib/agent_framework/channels/__pycache__/base.cpython-313.pyc b/libs/agent_framework/build/lib/agent_framework/channels/__pycache__/base.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..53e0fb6001f8f162d3d9cc8783216f17721f0eca GIT binary patch literal 1764 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 literal 0 HcmV?d00001 diff --git a/libs/agent_framework/build/lib/agent_framework/channels/__pycache__/interruption.cpython-313.pyc b/libs/agent_framework/build/lib/agent_framework/channels/__pycache__/interruption.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5c310dadf63dc6f9f194a3fa17ded3babd17ca9c GIT binary patch literal 6424 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 literal 0 HcmV?d00001 diff --git a/libs/agent_framework/build/lib/agent_framework/channels/__pycache__/transcription.cpython-313.pyc b/libs/agent_framework/build/lib/agent_framework/channels/__pycache__/transcription.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..07cf4ede5452774816d86153a8fc2073a600cd3e GIT binary patch literal 1397 zcmaJAO>Y}j@a?X@Ka#DhiW1aj+Xh-Em8}+q3JEBQ>rywtjl5n!IMvg7_c`6L-nHJY zlg35JTu@MvN|CDOh|~jc;D`k0{DDM9iuFXfR6^qB%5Z0%9k(t>%xdS&_sp9&(@!R2 z2;h%j?yt8bgr0C_1i*6;`dZwv?Ngp&cIUOdXNS|7KAU9 z5ot&buZGpgS@2zzN-~f1BAiBQbY2+BXjGNdSVlOBMxUBg<5OrourAV=8c`Ejk;d1g z^h9$7JaR6jWcRz>pNOZJ#3!_FIlDi4zGdj1LKMSwJVG~g)1|;SbgC;p)g8~E7C1d} z!ACK4N4Gh#;kGh=@+#5-i|dZ#`nqpHfFkhW_w`1@a@LrnTJ^NZq?%P{Qr)VzCQQrl zE1pl!D}ZjY6Ib$A7qsOv{_xt3Ad~(~T{0dB>`X-AELNtiUqA(MtW$Hd*L0_-hgvBXo*t$XL#PL1eF=YsB zRbK-Uu2H>CHeLD&b`2|QTU9UnFGaT6v}}{B{-ZH&!L$+E%Z_HV!RId1*kY$(MDXS< z*Cx2>!*uJ8LGTM!^kpc9@07OzsEz)Lq4>nMd2jve>fLNR*PTq=+xl|r?w$6v-{VJt z+m8JvPanu<_T@9*E`A^B$QKUeOZ)Prj{N3HF!OLMQcFd#O7;yFdNLSFdm1>BL{z3tav=2dEF3(V&oYh^9E5;D~p&b^LH~o^Ocq zsZw+u!a|hzP3jD6(+L*F*mMnySq$S^6Ep;4%BPx%6pZ~XzJ8RC?eGyNF&^7d@CzGm zyBi-!LFt0HhfeH#)<=>c_G0Mhv4^wY%LNu6s?_7dpq+|zJEcvtAgl0AtN hy%0*w^ae7B5{mvE9Y{~2#N6Kb8+);p&%=X){s9hfRQ~_~ literal 0 HcmV?d00001 diff --git a/libs/agent_framework/build/lib/agent_framework/checkpoints/__pycache__/__init__.cpython-313.pyc b/libs/agent_framework/build/lib/agent_framework/checkpoints/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f7d3dbc836dbfc9a4c0765cfda777ea311f9a8e7 GIT binary patch literal 891 zcma))O>fgM7{~1-ZQ7=3#$g&%E$RuW7xD!V5<&>g8!u}R2QF5YnanJWt0(TJ9Qgx%TsLk!>>wc+44pP@o02G*U zi;@U9mzgkojkXY(Iv23LG}$koiKR8Z8E~C!dYG2^Q%F~*t@8K{JfGh(yRG&AkAIsrx|*n| zy25V$RDxNJ&v{xDoPQ!4dnD#fn%f`2-$J?+7Yfd}%4A%~<0}43h>zE@I6>(jrD>pw zIhUo>oZny7ruSf}PS%BZ2zxdazT)bh#SfQKdg+AJxg=NE{N7CneNBIQQQ*AyVb_NK E0+2BhTL1t6 literal 0 HcmV?d00001 diff --git a/libs/agent_framework/build/lib/agent_framework/checkpoints/__pycache__/checkpoint_repository.cpython-313.pyc b/libs/agent_framework/build/lib/agent_framework/checkpoints/__pycache__/checkpoint_repository.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9b48baafb440b61f8f6493ebaba7ce00295c31cb GIT binary patch literal 27131 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 E2f$rzy#N3J literal 0 HcmV?d00001 diff --git a/libs/agent_framework/build/lib/agent_framework/config/__pycache__/__init__.cpython-313.pyc b/libs/agent_framework/build/lib/agent_framework/config/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a6db1bb1f5741335985da84ccd8ecac9bf844532 GIT binary patch literal 182 zcmey&%ge<81kZL(%mUGmK?DpiLK&Y~fQ+dO=?t2Tek&P@n1H;`AgNoSiRr0%CGlxR ziMgre`9<0B`N^63Ihjet`e+jRNu`-NDIh5fndJPuw9It<`1s7c%#!$cy@JYH95%W6 bDWy57c15f}TR^TT1~EP|Gcqz3F#}lutL`zw literal 0 HcmV?d00001 diff --git a/libs/agent_framework/build/lib/agent_framework/config/__pycache__/agent_registry.cpython-313.pyc b/libs/agent_framework/build/lib/agent_framework/config/__pycache__/agent_registry.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c1db452a529354886509b4135c6934c9d6980fd5 GIT binary patch literal 6915 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 literal 0 HcmV?d00001 diff --git a/libs/agent_framework/build/lib/agent_framework/config/__pycache__/settings.cpython-313.pyc b/libs/agent_framework/build/lib/agent_framework/config/__pycache__/settings.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..88305648286138ab2fb7526f46d91038c131fe70 GIT binary patch literal 12743 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 v6ZZV#{V$s6Q-T+=O$8N?9DZ3Y&Gr8Pi}1FX literal 0 HcmV?d00001 diff --git a/libs/agent_framework/build/lib/agent_framework/events/__pycache__/__init__.cpython-313.pyc b/libs/agent_framework/build/lib/agent_framework/events/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..dfe6ced059d3ffdc25897aec8aab5065a0afc220 GIT binary patch literal 182 zcmey&%ge<81kZL(%mUGmK?DpiLK&Y~fQ+dO=?t2Tek&P@n1H;`AgNoSiRr0%CGlxR ziMgre`9<0B`N^63Ihjet`e+jRNu`-NDIh5fnbb0%5ykrP@tJv7g{`OTj_`L$z$Ni4#;+a%giivtxY4a%l5;6)*<6M14SOCpUNdu)bv#_5|e zRXCxogwj=|RVpF&NKXqlj_r+O4?Wn8&{(fXJyfd1t!-FUd+YbT8JlEqEA^B8&3r%e z-uJ%WcQi6GNC5u+hl6{|3L$?(q6uv>X5r;A*&=8*6?K71y0|6l(w1^b*5wqrC)0?o z&}c29McHWXJ}kc8+^$>BU6a1SRoI}3OvByVHCc4Gv{!GGD&@dzz6&1gSMWa?2J}Oc zhW%>fvQ!nG3;E~dxx{40tXC=eiberB_;EU&W_LnoF&brSu5N8Rb0NXpcGId?Q1qUJ z8|TcymqyPMncY3G)ISAFo;*_~;A4y(wB`+YNPe$>@8DU#6lH;8UgR~EsfJ;LlMRCn z8pcke(yZhAuwne7S*iz;m|;{c>bP~wHthz8B`|`?6|3yhQCNqaHo&ZsYn6?X>r!jG z>6(sV@I8(|PUr|C+?ykOabkcTk&e9lOlrx?FDjnAOwV*RPDD9KGjfyyaX8A5I1p#5 z)MQOziF~86d(snc@bo7Fi9X?h{29FXf!u^Q9|{PO=OXJqgFG)IhI{*&>>iK4#H8xPCjU6b(y2)bT zYvbBl{*#p(#wRPca%>10>xDH=4D^}=8}=h|t!_bkW2aC{-zem=pBlOR_4T!t{01!V z3;CLX5cICIU>U=zu!&?e32tacp!~(Jy=@x6R%SM9Y5SfgVnGaT|lxW4QmYQ`J8mrk|gMNGTgsF+ma1WY`$?yxiKP50B_)9a>N zvg%IGcIh6yfLe+7rS!)r7~XBVMt4h^0hSi!`Ty=35SX#usDPPJf)s{!#ovJsW-JJR zW7A=(e>nsb9b1m`6(AfCP!F$Tr@nsh)q|&3+NrC5y4H@Zd$G^jvCj@;pYO|^_^Br& z2P0m5x*ebP;*0J0;>&R_tGBbdm%Y=@-Z{)}wJLX8@x@l$+E+S>(@)MHoc9v5?Zm8? zSZF5}Ugln2ZY364iPimRM;*p# zZsY#QgG2fash_|n|9w)WQHqEUP%MB)pG?Eq({xx!mu7VV;cXELKAqj%;S911{ zob5zMz39ZBqZ6&kONY_gJc7=oGf8H2KczG$)vkyWXb;H2#R5R$12ZEd<6Q=W2i&q3xa1nyi`apJ0B5>R AFaQ7m literal 0 HcmV?d00001 diff --git a/libs/agent_framework/build/lib/agent_framework/gateways/__pycache__/mcp_gateway_client.cpython-313.pyc b/libs/agent_framework/build/lib/agent_framework/gateways/__pycache__/mcp_gateway_client.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..938c58d329b63b9f8a1c9c9329c39820f6e9a105 GIT binary patch literal 3300 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 literal 0 HcmV?d00001 diff --git a/libs/agent_framework/build/lib/agent_framework/global_supervisor/__pycache__/config.cpython-313.pyc b/libs/agent_framework/build/lib/agent_framework/global_supervisor/__pycache__/config.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..370f6f6e0c126dd91f4071484010c7e3fb3031bf GIT binary patch literal 5013 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 literal 0 HcmV?d00001 diff --git a/libs/agent_framework/build/lib/agent_framework/global_supervisor/__pycache__/router.cpython-313.pyc b/libs/agent_framework/build/lib/agent_framework/global_supervisor/__pycache__/router.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a99fd4177601b0c5f8fc39a432c59a4bbc604c2f GIT binary patch literal 14787 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 literal 0 HcmV?d00001 diff --git a/libs/agent_framework/build/lib/agent_framework/guardrails/__pycache__/__init__.cpython-313.pyc b/libs/agent_framework/build/lib/agent_framework/guardrails/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9503cb790f0983c96ded4adfcb702130cd4e1e62 GIT binary patch literal 1469 zcmZ`(%WfMt6y=O%>;0DeOdKU~9#a%i(NzKz1&X9_!;x!M3IcRBpe5R1JQ@z}%(zKb z{e>>_5&4AvMVG|@MivEHbl27>vMSJfIg%CBs1`@}9v<>u9+GoWt(F-6e*N)>7yqm> z_6sG8pFIyQe#YPp8?&+HGH!vzZLoWk+wKa_LC(Z0?kZn{HJ*pO$#ZUj7oo^YP~v4M z^9odW6{@@jHC~50Z$N`Lp~+j&;%#X24s>`Ix_lkh`37w8P1xjHu*J7woA1C*kM-Gj z^&1PWVcj+NI^Ts|Qz!4<;63P>xZvL8x8RnEi|%c{2YV(ixp(+oxNG9Fdyn6T``iJi z$4)9v^>+)m=h$g+KM^nmq5QNmLVO}8DpERdth9MKG*qGVRUlE{7z_?Bd75CD!z2!q zcz-k?#%ZUu$9fj}N(2*WG@U0R76U0x#ff|xpwzJ457=ylY{7ldNidbuKt@p}{7U$K zGEsquv9*zkP7PhqUjYXhh^*Sp^+bn-5ZVy4uM4W*9Vq#h%MQaFJV0tDGkB=poPEd$W#7~14 zaw)8j#K~Ar62Lk}wLX$DD0wFQk@WFzVO#5&*8X$htLd_j%A!M>>1@Lao+IQ4@Fp`@ zBghl937P~gf^C9zf+|6spg~Y0=n!-XHV6s?MFM&#P$sAlY!YlCq@AGvJQe9vA78%2 z?Zg_=?o~FsOeK@dbjDB(;+8jveLPNG=PNE`*7y5WaRkN^?gdl1nSnLO8#%#+0<^`!f${;?kdVH6#9atHvf{&eE%;oyOgzYsOe( z-K9gu@igyw=#uB9Wh&><{m=niCkHbIj0>*JlW{eAxLhs@eLXSdI3R{xyc`Hk_P7>5VA+`qlrtN#E1 literal 0 HcmV?d00001 diff --git a/libs/agent_framework/build/lib/agent_framework/guardrails/__pycache__/base.cpython-313.pyc b/libs/agent_framework/build/lib/agent_framework/guardrails/__pycache__/base.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ad115454d13df9124f11e7f326256c4bdd22db27 GIT binary patch literal 1343 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 literal 0 HcmV?d00001 diff --git a/libs/agent_framework/build/lib/agent_framework/guardrails/__pycache__/custom_rails.cpython-313.pyc b/libs/agent_framework/build/lib/agent_framework/guardrails/__pycache__/custom_rails.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5f16e14bdeb82357796c979351c3e492b5c154d4 GIT binary patch literal 4372 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 JEVpvOxB0*ae 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 literal 0 HcmV?d00001 diff --git a/libs/agent_framework/build/lib/agent_framework/guardrails/__pycache__/parallel_executor.cpython-313.pyc b/libs/agent_framework/build/lib/agent_framework/guardrails/__pycache__/parallel_executor.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6e5a9dc869e689416371caa0016b196515f54fce GIT binary patch literal 21830 zcmd6PZFE!Dwcx$_{+4aYAChJJ+VTei+n4|bo39uf48|Ws*8(>Ngs^1CAWP1b9D-l- znw74$?o8ea^rZ#bOmW(-g;~?CxG$MiGF@w$gr=c=ebajp$yIJWNjlTlS)Csm}B|eeb4vVXPX>OX^pgsx&S4 zY@k@vR%jnOuJTxkze9%eeF%Ld|6PV5bj$sro77x2Yd+>-EiDiUX}a%E1ED*MhVH&U z6v|^rc~(-M4%%yD?Ok*g1yG5bVoSHGi(iK9yt)hmxU*Xeg18w3E}3XxOKg)IG6tlHp)7!i7#nBa(rQJUJJMO+y3vaL!sH( z2q!TUTqKl?1mpSf!3jtZoFOUZTSHTkSTZ=tg=QjWI*`RtN}ue z1)(O^1fgaOWi6bUwZfZ?yxBPmTLN#TB!`uCvM`dTHQCX%u@25YW$~3u<%cr}z#i`- zH~{Sbz81=y>jF>4e<&Ph!jWVs`h*NIb2A}^i-$wu5QH-XcQ>xy_->pb_>4qD?UFi? z*PG;t1Fr4R^= zM3e*u!x@rE%o|BssOh+5p9leI!B~dL;3tOXOEI@xJo9;GI39~gcA&+X=~yTllxy2B zX->uCQOPk0NuhCxWH8B1PfbO*NO&SMqX7#Pg`=saDEe*^fUi^I*|-4Z&&(Z6rnp`7 zx(pbqp(utbp30x05hWKs$92lv4geIc(nwvShkY8(17Tb>c#;kf2_wbX;RO(^NkpQP z32YT3ohqRBV0>bFV|4mdVq-zX##3|C(J)5c7n7SJ8}FMU?X%}3{i$et;!Gqg)f6S5 z_Dr-78kATM-m}zi?T+((qH~?#Tqin@Esct8JwjWL*mgi@J8*mOn9z1CWk1dvj^BmU z)HMpGypD?`=eQW@w68=m1cNb{!NH(p3I=E5;khWnmSFJ7xll9{V-E%=r@2HjIvtC| z;t;J52E*|Q03arhV+Dg8t}K!U>4&QVkaMBuMi24J!LU)1VU~*nk4c{6y!cuk3?`7} zO$0+pAd^#b$w&f9YR2?U=ry3{P&}MOi7a`9@OMG{|e5d_{XoGx&ae^Kw$C-}&sw`Ol>^JJY_lXGi$*=9H!_%{1|v%1h3a zrs*TC^{$H6o}lllDVIIC{{sG6E+q3H7WfeS11Dm2?Ydf6Q;Ywx z<*Xig$Y~XaX*H~&UG;#J6|6CnQpZ-ZRji4;(VU)jv1WvU%eh$#fsAZ5YbB70^{_Sq znb{iFP9O`c@Rbj!r50B%Xb;U<**dnAq_?q*%;`8gThBU3SPARoN~biw2FZCpsm8hA zw*zA4ZoBkKFW3WSWaJGW$Vps&J%s$gaRad2%PZnGmqm z{{VSm;bd^>e$92bh+xEg}aW!71ep_@4wN}PlK#oI?ii8JkTpVs+KGKm|nGSkp2 zj*HLCMwp2>&J&m#Pr(d@;C2RiZ^ASYpJ9@)`oqc*XL=6@+D^siVqwVrgV+QY2ZV$p zPeG$#WoKqWvE+0ZFgh{ECE*dDV`kz{kr3oSCS`%%n0x{j{4k*M#;br%EFuOY!2lkx zZ|$bhVab?fUp}2=%%VpsDMYYj&cl>skYxxEDzq@qry`PbtxzG$6WMhEIW_WrvMxMN z=GRzB6rQpRsB)`77}7G-cy^@-P|++r))9pgWHn)XozNns*KLguVGxa{I996AGRXk7oG)B67K(0ptbjtXZM+ z#{p6^R7ZAQjp@d-xDTlFa7@x|%%#%@w0W@>ECtqdr43NM;$nt?W&+|NHoKB5aTGN| z2Q)F`xKRlS&@A0W$4mjeA}@rY=76b@3g{iw5pzPdkxHl>)B!+$eA$ovEO1aymJ)JN z0ka}GC{LyQ5R^Xz%krn?JFFT4{lX0Wj9Fr4NR5I!&(bs3HxD9s5<0+03pPz<0VQ#{xSv1JsYrX<+*nS8WYBz*qXsOt9d~CtxA7w z)Mgb()T)3rs2bXp>4^>Mu2jkk*p##}do2~PD;VmhL;nfnuv{BaJScF`Mtfcg6dMX0 ztLst~Vq*?)A1jI310@cspFZ#fcqNV{16&8D*eUTIrJgv z^MPD$1%k2%6gc-pC~pBf%=5iK2^ByS6@(@#q1TKOpL-VT z^#iDbV1QQ_2!t5yhl(qt&C@AHxY-@myRTZB_GC$7nG2n*r zANxmh7*L>q8Td_UhTph=a{~W6Fh%CKtJs`)z_?}km@;lKw;gM!uobDvUxW(BQKBWz ze?)8TJyB&4FaEXuvg6#O$(9n?8=0XR;hQZAG?2ejfG&vH&b8Wsv1s}GbZ>l5&t z4N7#N45+D9dCNVs;{+>x-kj;krBI*|dtQ7ID=upYIElPr3^c(!Ttjd4aNjodB<*ty`)CfP z5H(+&)#ln|B@pah?VzA>$w(Mf0@Ma1Ez#5G$)g+XVQ3J7r&+ck1s zSqn~rN=r25NEj5@aAa3gV%~~+D+GeRI@ireHq@PG(a;u5o|}za(?}Xj$wBAA1P6L( zA|8_rUIAK7 zGA@;78lP=MV!oyrEM!F{9q`Vhlt{+DdMifwlv z7#uj#Bd~yi{XZ6#jQf-^l628H+HNId7GsVnASMZ`qHz)Kg&Wf$2v{WrO$Gr6p|`26YN7k)-2tlL>{$Dt9%O zOU#Kn*?uDFrb5Xlz;ptF7T6fsp5cR|2Or-j*%BeprKjfsuV^+W#4o9%k(i`?DiocI z_}sFNj*~*tPsG8_0;y2W&Z)(cdLsF>WW?DJMBAoh1#=3A+aIz;!#bCUfSo&I>_$Z4 zwg=F+M01k$Dd;%t)C9?7k~H{`v^ZV~NsqXmj!gk^;HYUZlyrbYAwg0D#wAOJ90=7* zmQ0Qy8Sv~IDb$$ls$|R1>ZxKD{2&Z&w=q@O5vB8RCzO^T$q#$0mhill;_~ z)UhZ(KEsd31WTNMa_*L8?)|FzRV`(-tx{0bJrniF*5$yf?gjm-s?FF>e^};PX>Pk3 z{Z4dw+b{LvfuI1t=940G@`Cle=KR!(hdJMuu4WdUmv)LC zPS-bGt$w-syET_|t8S{iR&+KA&L+{>DmYu0j@))`Sz(X!C&J>18R5jt?RY|DlLDJu z?7X_??S4B+mxHzwHUF8mQ_z(Y--%Z&=#DJd|?xi_U)D+5g`w8_z$pRPjp9wVLaV zV)uy9J@T$^B)z5klJR!cru6om_}u#I*3Fj&(;GULJ;H|F0AW>I1 z^B(_7L(_MgF6rN|s=0HBrfTXx(NYfgg_gU1nsPDcHR%%PMe_yoH>`Km@cuh{#Y#oZ z#n{(ki&K2X{x_UL#eT75KVPyRdROiOVr=Ua+jie-+nsXl0e^|U(tNpjvHqJrp>6kq zjd$(&wXns$2u&$rzh z&g;?+*Tr2Ib}jaaja@=x*Sn6cbVuj;gSVY+?>k*kLUrq^2_~0J+G)#%k6g_wjCb*% z*tk__+?rxK)81CmyHoJ)Ot*B1Eqy{uU%Gct>^%m*MVDCLE!205^?PpB@8M5PriYG* zLzD1Z?2_|{-d@4mD|!#!@*d=)vv;g|t8KM}vX{qf^z z73F#o*3Ywl{8$5X;NudiK1BcFo(0BFtllJ4Z@NpV%Inir^`MIxp#Ai=9pbir_OVU< z-2!q_Qzeyu`Pf3aAEiHb1D^hv*iKW_b3IK*>*+UJ*7@r-Z#l}*U+0F98!Fo0thu2! zAZ+eY`F)z7TCMQ%)9UskPU>wV?Qhq-ZSo@AUgF=RdV6*<8YKWgYBHr+pJT?p5AL8-rV(??1*zpQp5ys_e_OY=|KR)GI$ zs|Wo5Ty93cu?HW&+Pt>~9=F`|(OS)|Y74?XE&A;=ly_^>#z2EM#b^LdH5w6a>scSD z(Y{-$gP?b7v=H=egBszcx+4bddm4n_)6)nWFxz`JEa<&b8VY^S*?qJ^E!ya#r3TTi zN4UZW;S*?zQJf8cFQTRS%MdDCnnAk&>=wE}*5(w`1~f%%$Dm~wx|j~i%C9YxfTaW4 zfG(gONBcW*YxWkPBsi&}QZy*s&udq0&6IP$H3n>HwBMkVlzYbXfNZ&YOjW~Z+V^BgUID<0A1=J6+zQqiAttxIUHr&@L z=tsbCe@g(nU@t0k5Sq15<>JP^M6AcO(yy5D0b`>J82webd@@K7Ivmi=P%ZIH3U8d-G*y{7&GoiUQ9|3aByQH`0#6=J0PS)D&uGiwTH zl`#bEIcKlZLR(P9DR4?*A+!o)Z2`s3Zh=)G7hmKQ7mK?l532#_g0+B6#%hD}SOF7Q z5HzeEY(Pb<1;woTU_mGW3&MlxlJJb;H1hv3#TATrz?e`G8;Pk0EK^`1foIM_LM#QP z!;(H@4v;7gM*`2Ip>h;VfHox=Q9lNyB?c#vWSxtIC>k>Z89+;oM&oDUJc|LeN-q9X zB+TuDaH9TkU&0hdS$Tu=MdW?nv(}h^I#r$>!Rd$hj2!__4}eM(XXeRnbDO*`FX=P8 z&GV{mhTDsk^@8WC;SM8AtQsX5l@j$e*eC~G{xmkl5J7zq4!ucw&{Jn46G_Q2otTJo zaZu%Ak;%E3d^QM;GJuG9P~I|^%+rYwD%#{Uo;3(Pjh+k6#-q~{=ip3DEY8h@qJS`2 ztz)niXV8P0K;>cMbNCAOVTwD39@)i2 zPh6i$dG?DH`_HRa9B$Fke9O_im=GNs1jmLnE~^mBT7@{Cx!NvPeFu4}sT%;jfZ zvkG;)(o8d|ldshX%C->~2#+#J4;%zAGW$t{@KAP1+p6njKQciAcI%r6v>(Uj>okk_4(&j8Cen2o$ zL}Ov~tU*Z~)8< zm2h}TBmtXQnX)B|yg3yldmsrNB$uT@SrGghR!~=TDY{QSgA z-J-c!FgK?i6$=9-;E4o?*SL+2`y3~2G z`eOB}j_TO_%I9DC{7Y`pwc(a)0}3XO2|bTp(EZliyrh1`a?K*H>%OiMTlNSod-z8m zOSSmLmNEXwSjzi3(Hj)J!IU>7dZz^MRLVQemoRBpjp*7axHj?~kN$GKIPkbI@Hh`| zuJQA_6-Q0Fyz1iEg)yPwzYM&aronU2tzVw_ z(di$azU}Jak3KFQ4GBj>>AD8FGile!m--eRS3NI##QM$4Whu`V-gT1i9J-nK)!+X7 zZ&M>d!F3WuK_>`+U~RouLRl&RSzAOiBbb?Vb?udHm$xl$Upktq-nuXd%~~n1g32o| zS1wk3t4?%vEcKrTfz6Ob&mlx+7J&X~pHa#9ldi`RL-~P&Qu6x)V(U(!b>~eJ zKYCOg4GE(marCq>dYbP)BiN(7AxaL6W(6A0wkr7$;`;HqIl%5YNyr;MbBeM7t|kVo~ZoEnrsro=EZ9i!4Gxr@^=Zm)WPdJ_yJ z0ur{Dy}0etmc@!C=PR|>YDM3pg749kqbFtG%NzE}9nbFqN-4l`=)1R|jECDSi``{W zx~DL^5R@`Sjnx-R3&_iGTBtMYK08W_ryMsZMeP9KGp5PPW=dX?vxv0F(yXf8NaUbm zXIxQU$;W1XF$e!6|yL_KQd_j0@=0DLHR{+_ONoMzzR3)gMU4-e`tnfqlZy8 z8pxZ!Vc|06M=-L!IOXTz6uT*>P=$Xx=86x1}v*AC_S4#%Tp;^zi8+e4E?a_XAIKs8~Xp4XoO}z zw|84_3;k9X-Rsr7)$IlNMh)HDq`6V6L%4|sKg+M6uN0z*@T+eE@O3-_o4Zuj0m=!c zAugYPDU-FBnN<<_{m2OmoD!$xhXd%UMheWj*{KKSR%j6ru?h`xjoHIH@!Kv=V^~QjahpqKg0}pi?;h^5}mXUZm#Yqn}y$v%S*z~Q_Vr{!n+n%cJ5NkVy+Rjw%_LQTGw~XA>gZBqwXrPVNX@~pY48uN~ zvHDL52bA+%=ML(1dI$AmOOHwYrjZ7J0$ZoJ+>)Vr;F1A1IzfueBLs9er3YEbH_N?&0|hii%TgFju8UD0Hi2T??Jk1mfEVWb|IKD&DcyN@~r zBjF~3kz$xGW-E9&rt`|h5&SE#HTi#pEd!i$&8)1@`_GPL;{)be7PDC_0ew9nZ5FFa zTD*6|nqaqQO`AYuG!KIsm0dd(bG#l-9Kyx6bMor_4IpC4nqh~D_#8J8k;?DCn})}; z43LprzQv=Duq;oLEBaDd-b*l3f*FruWh(U9IaJlS@1e(_NBB80Khz7V7AnBC-2RP3*ISuy^VGqViF4`#y zAonVyyYK25cL8%ZJYeC-+u7KJi^jLX1Hrkp{KctDVZL!2XcZMZ#frUes8Xf93%azq z^o3nt-SyId=xG%^t+&mscs7P1$G8rrT6(@+CoZ2@I*_W_ zdfxPb-IZn4Ix;0@L@#k$1-598WQiowt7AVA752#Kvx+vHSWi(H|82LB6q@Z#;Q^ z|BFMYUNv9c`0~crwuqJ6h05(2;YF-^M5uaXc@N(=e!J=z%08zroL+RNDq6*ggUh-f znSN-xzAM#naKZe6-JN#Vitf#Vd$Z{772LgV?0@Ibn}<^F!wZK#Fju_Py*PO_{&M`a zq*%REsNM;3)e9qE9T6?ff~9%!ndLKJpcM7Dpn&NQ9q`i_-~V zIK>SzPpJSm3szZeLG4~~1^~W@Y6}m8msMMo z*u1AQ#lnzoiprCQ?z{MxGo(IDJ|f33ipWU7PM`*KN{t~>BMU}N*uqr@bi}7Y4ba8( zaP>&DkIuX5mw$l}m_hzE#C>!C4sGPMJi8PZTc{OT4V59nRy4p?aI;qj`m3&8yN`|; zKw6~yq^)bcVwVNSo`$3II=s-$8oSi@t1U#`(B^OPgDeP37L$Jf9L1>u$C}1MteLfR zY49-mR90dnN{baXZ3DxHhDVML|H+hPf9(?8F6m$!b9OE%X{TfG0Br&{2_^096Ct=K zd=+5AY$P4*`6lNQnGIjEDNACn(S#4pch4%Py_KuO3{h0%!{4Y`6de9$N?JJd3`cf}W<)q83b>L6i^0)#vii)AMZ$Nv^nHWlY_vTBsw86E&qO#ClMkLnSelPht)@XQO(z%&JG z!TB!H;afDO?CV8)hhPWp^9byLW>qM#?{o;}4oI5@-qN&KxkN8DE>$c&xm>Yq;NfVY zX;oz?F{N$gt7>@u)>f81PrIsx05FGDRHy5G-)EQ0|NY})+b*GPSE_AKs(#Ofu{Vx_ zWh?Eh0)F(d9nvmnR?F1JBn^9o7uznhiDivKS>xj4H_z}-M1@CZ__9X6EGAlFDN9U| z+LJWw556$?)j{4B;E#^;F>YZnWl5kIpQQhi*a>}pZf`|zGyRr}>7^;qu=c`cTDJz_ z-86>pp#i=@*Y$eUHy9O!+-LwTOnt+v1~{v8K{=EL{y~(d@1n+mVrf1khS;Gk4FxUavb z_jAFK!06$?Xs|yUQT2cb7PPONPWCe>TT#cd^JuL)hV(6MEKYF`Jo-P0wAT(fiEZk9 z*Tp@Hs+8R;+I@oEm$GjV?VAMqrj&g%P@UbuSDqH^r+LHa`z=*jmcJiL{J&!P4;v;e zw6MTshp7m=SK`)aLn!f4ew?ZWE~f*nT^t}aN>T+5mJAJAi(rvZ!T!&heKci}DaNXm zHsP+(gU`${z-+-fq*bg#u!>ULPte0r2N`TT!a2Gix;o)(k6{EMlZ*|AkO|>hI3oz_ zDzx7$L4>rvILQzuRbU=EjnwiSWKzy$b_$i9%kbPORH9&#JzBpw zu#{Yy4L#EHN7sG2|A!e0G|A-~wEPSp>j>5KzO2A}xS5684MK z4_%0nNf4J^h_ixIG1|oaP}CjeTVVwYv3^)S-&CP2m*n?Z#4F(sQ*a!P?{fW0Qw0HVQ*42fN!emdK%Sl)~hhYOC#K< z1{gN@Ft>bb2Q?`fO+-xSgjb(UjsoKVMeY#IR}_4dEb~1pxfqfRr}VrDKDeetkHq?v3-v+{3A(Tywzch$ZOds) zNXoEab{+Tk+3bA?k#6MTHF?F8P>hG~q>N!&EI}?c+j;JN3?nJu!<0JNkV)dvnknna zBp&%Z#OF%NbtG56h5ISyBKfaoq1<2*HcRRxvqHoqx!N_dK$+_^jy<$KR}#rZ^5;s* z6tr`hvp`3NARsur7?p2Zr1a4E^zm#I=za9oo zu65rVR@G@|=zDu5rgsS_H69m8*IJ zLVb=^BLPiR8MA68pamO5GQsgVXuTan?`>CU&(QY_IxRR1svS40GGA-t@cbG1E)jgiDUuu{7dqvW zrf7_kwElgg{?AE<13kliBS-f69cVWw}P_XK)D^h(e}wUnTufaoN{PB@eRpOD+l z{WBy1nxhi0fd|~3razz>Ry77%bJt1H_Fq#r_=k(>Gp0!O zT+*?!CT(4yQ_*yBk$H8B0Cu{dw%Y=6F%0qcV@Ti($OdfVt(0EwPQeTm8<2l;95i!& z?fcH0C7V z-Jf8_&uUIFl}cyCOd_3-^)gpTOeDvoSVD$UD63DV#dvfvE0Q>Y5;+=6 zrxp^6ev{^z5s8>gN=d9SenE<5Gijn#&yI(tP6S6!Mn{j%o|p~_(1rskMq}8YzfP+< znqFE?Cd5=sLcHb~6EosTNjxVmN+(jw*$l;cw_vBU83SE?oTRgO&Du|<)5{ccPeD!SN=Uq<_g@9gPcI0u^s=6>(Yu>TB&Nhd zV{JNWHhm!xOJr6AF_p+9UeY_nDLA(h*Ub=VNz7!4q)(alT02A1BCNo9X?kHnA`}ON zuo9UQsTU-=Hu~^F;-Ua+NuVE!s1HdQl90}e$&i$Um$7WMv*~p5l$cD!OXF}EBgC4q z!roI3K)yCJ415320l3VB87vL6T}%Y`ojzeEQmkR{O>d!0L}~`8Ed>PR4i;*LYzD6M zK3D)l6(yVj8D#?dH9&PSepB!WHmk7%8oQ#I(kacnBFP$;Az8_9(Hy{vDLI1^*SL9@ zv}TqwM6*DWSk^4b^otS!cC^3>WhKoPmlniqG9%+$cwRdVTb;^87l^ndy_hEFqUl(o zKbe@9`?nSJ&u0_KI2P?FDRF=Qa$;FZCQ?%0@``4Q!U!{GSI9o-svZ92ry={~Okv$V@xvUlp91R`7{0J!@a74yt<1;LOT3(2PLqtpi@b!A z<<9jxf0gE!QQ$~PkzWA1{R^U;>2o+{(gX_P1POqo&<`&zrb(f4Ml3W8JtR=T^rxvn z;iV;`$#kD%nqMY~B`HDDl$!r$7RDoiNK1)?7xe*TB(em8Cdv2CC)2TW{ZLL;`p=4~ zc=|jrAuj=s66jWRkaS#(L;rjX`4)zpmSKWRVnXiY4eK+OG%s~OdOYG8IJmV0*`!L+6S}M#|N{%^LO)5KMgdgOd^#Pd0B!nJ>}rx z>CH$NGU@074tyV?uv(g1N{RDHDN1)0wpFXZZH?l#YUX5eN%Is404^yY&5c<~8B3;RDXuy70YN*N zvoS+Hp-jSaLuK9#z+T=e>70h_3Ny)~{M#zqLPbdkZ4{o6)qqOxE$tL62b8L@e?Vy& zvX|%#s3=eS7$)L0us~a`KbKKndJnTk3vsByGyO#=3^OT?Z~E1U+o)qm+epn0Ox+HQ zcL%0n2c~H|rr)}???|&z9%(V4P@4gj-e94y#_9>C9r~t|u3(uJ2%(_e_C$bMe~j50 zE%VH@b*{R!GGSBfwLi+5Y&P^3>0vv&t({|-$54$Qy~ z%;P&SMi-0$^xI+oO5?N6@ughY9DD97*9%zkD|z_|V;rUTqt|P?B{F2t8KaD#u|S_9 zW(P<2n_(tJ{)3%AP|Ah5Sm2K`lf%Y1O7Ab3i6b&%&>7?IXJM4Z69J=qx|EyyPLen1 z1ryK}xqWUX*BMhuuV(ZHf_*m@oYpUiz8-2 z69!y*hb@A22xqz5z%4R!Oqa?WkGBI4)jB9{{%7CACt5*M&2amgSi$ZT}h`a?9`qDv&QezI9WekkWBT?HExyM%G%N#sc46XT9PC6S_`yx5ICvv*!k<_8w7s zkEp!?r8l7V&U`q(*7@~I+(*^?XI94BwdU#G@a%ehYQw|79^CNstaSl+H1=Gw`8ly=`*+ z>`QBBzm;2jd3EeZ(|6l?U!Bg^)xT=rbTQp~aJ$;`jr^;X`O{~W)5~wZ_%^w|^0SrP zz|>k#FgG*1zAFqJzsMdlA!$o~>Xb6|{F@DL*IsY>SyOKB=vw=$=mf(ETwFHA^)o3;*j&d< zfD%ht!`2XMR4BdYo-st?2?+6=H8ae4_Odx>aWN@d*b;*L_9tvJL?6$DZK18>D3H#> z;V55{;s9SX)JiQIW*s`(Q>PhbZhX)rn|N@KoiH2Bbuo4(IQgV`fxXEF{Tv)*ba+K@ zNsdA@T9vE^C8T&1?S0J#Q4#Qr<9<6q$qU{z#e!_3fQ3pj%?5!60{*d95if*%!0*N) z&0a*H*m(GmyQ3tVipmnWNZ@XWNv*xiS$~-1yU>W7f#ef7^!eKQRa?Gy&uYcLdzx0q z@~!Px&%ANw#*=HUht-C|s}p&bS9P^0u9hov>#p5-cZ2HQt>Evmysty`4Jf{WOSXJn zvs%{)Kc%iS-_Vw8@c*XTf3K49`ZlYW>V}-VJ!fx+eBKV>EwvwV0Yk)nNUuyB!$KtBMZm8laddIqJo!2T{AjA@80r0iSzwSP$; zpl#qt6|JyRdyzT=7Ag)fVfz^SMA6pgnW=Bmv3U%d(mR4Wl|EmC@uVugs&$wlYRqj< zxB~E~8n-=wMg6$#Ilx3v*V3o_ify;<4itT^aTaQnnMXN)2PpYMH(Op1rQ!O_(=Fa}XSw;o?fg4n|rWb!Q3 z@|#H%UbHzP0(6t{*OBAco*BdvwT3hskz|Y$5}Yul(ztjc2C)Y)+o((>csL2D4hVW- zLfiZXLO3*nP8&IcNeq)2Nc;{eY$;5>j#v~QbWB=>K3j-^lUYFGG_ilpRaiQ@Vsywd z9$Q1=^1N9i*n0Ev967&wa>LzpW#6wj)xBSF@6T5^snxtv&A;8Ev=85MLGs(`BX@l~ zj$pliMDdM)>^6wNILo(oUX8pF$@4w=UENn-e&gkQ&wjP%u+npQ(`4!JZM1bX* z-_X0chXHls?1EoWuWVGeATloCIQ|drK83^RU&nm5vdp547_A|4!vI=!b(`&E% z;FT*YId^Z)-uvk&%Xky)1GySj_M-ooi~S{gtb+U1cpHFPMbW3Y$wV8&;= zLhr&lWmMsucWzLy4RJf^!J2DEiTds}YT*KW_M!_&&} z^tyc}?{uqp+tOOBlj|J5ol!@^%1Brpc~%*DcHI@(QaJkF;JRyq`gfhGyEEU^sy6Lc zn)cs_zvo?RIk}AUwj3S-B4w3&0;(Sx93A&H{3VDN2k5$P`Uc5a-*Ux!Rr512_@n z%=SlM1=Az=kfS_k4r&$}<|tLpSfkaHKq=ZDT8Al9=~)t=bcsEvpM^$;+}nQAJ6H< z-U0R(Y(Mu)%fKTR>E}T8f4N9mSkC3a(*1y7_Az0ut{6cztY<@nh#Ui72821Zn&t)z zu3HyfWJ^%9>JcEi%CW6mii`R<`X8w+^8x1-0xRj7a(;->-(IG~1R@A75b|tU7GR!& zeLT-xwty85J~UdGi!2?NNwbB19U!M5U${^$Z24ihRh2F* zlOtMx`7PHc*>@Q3$>8$mNMEtS9c;^BgIrbgH{s_$ECgECtGm?dqcXy+=upeM~NrdIrxZOl&uD55r;jEa8MSKRXt$SXi!G~xg*iR9lxW`_}HE}cOAX0GHV zLdb_J7cl@+joo6Dl&3L;%bAA-@eb#lDQ5)Ec>s?pc-w>C=9j7fkWLjeoScHMB?_QO z7V%pQ2r}!t#p#wq7TVTN$}xb9L-HD8FJXe-k7kZ#E^I#}cHA3mu3UuJDEnuqEu+Yz zCP7v0r6+$fd}V&Es(sa*w>w{}`a#vDKfQKh-QKq)cYXR+?YeysbTZW}D>pLleEa6N z-&??)ol@OXIs262o_ZkHLbDe~`B6W_fY{L+zqizAf>)&%Vd|6 zl1{SY=Kl=b`EP5I`~(}vg(uh!b!76W53U3UM+u+8)5yh}U7Cs4xYOZMXn^`egC~-&O^93Sj@XMQ28j5YvXgnQ@ zM#%|msc4_-4EZg@{TU{&V)8m9nl~DSNJSc6~CK&$8en@?H6!z4`X;yss_4??9gK&Ufs- z*KCy5wQjm~xSH{GZ`SBA+&ApntkYo+Q`NZX)!}+(*PhJ=9d2ZNZJSLx>|^Tr-|KCD zHfwTNIzDS`xA-@YvG7I10{c1RvP`p|wy>5k`>EAt>G*vuYl*R+TRBURy~kjxPmoTF zJq9K`4P0B_;l%X%WfK~#i=f}(<-NQl-^a_W+YOPeA74Jb`D)kiPFz=eL1yOhEg?-TmEHu^~ykpS(0=doX&kXM&yn@agCvPE2RCP2=PsHfxM2 z&9%%J*BWG6YoQo}uAO}5QZQpa5v68_V23%W;D}Y3>=iOqy?=~eTFWAL)_=~V=8%KU zMfDsqK9A?Y+fyL6#T;BzYRke$bh*5G7GJJxob5F1ue^Et!!y{pzA}t_;|u$D;MpzX vDGkkgZusWdrZa*^O?;2xj+O3j)h!D@J&f@;wDzmr#_Q*+=lO4B$^70QD`~CH literal 0 HcmV?d00001 diff --git a/libs/agent_framework/build/lib/agent_framework/guardrails/__pycache__/rail_decision.cpython-313.pyc b/libs/agent_framework/build/lib/agent_framework/guardrails/__pycache__/rail_decision.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a9334338194118323028326e233ade0bd2768de5 GIT binary patch literal 1573 zcmZWp&2QX96d!->dcQ-HCMYP4NsC|+$|^`bv>>FQq@tT@gVv!mAH|y3-mO!wy}YrD zl3pTlpqvPY+_-T-+fH<&bowNRber+*0j=Toi(h{jlAQ=M7OLAQSrLKaS_{x%2&p-yTYHCZ_ zx(<4RGfTO89`Xj+P-cjkHT4_Pn*>pAl9>7HxThG`(+`0{yHG8j39l;g0u6#NqLCK{ ztSa-ILnCVYlrgTgJlA(HMVSw_&!jXx-=v;DZ;Nzf60hm9*pF7w)tDbf%pUBMeALvD z`cDw-lMMorNkBFwP~Jg(8>*?ii;Srv(h`(GlueKhnkl?o;^iTec!dF%O}wJ;HuM>? zkuys-B*>d(oKZ=l1#{FKnIv24OXWrL4JfrQRmXT)=vZ)VkD-#gAD)Q{fsTe}XrgXs z#P?XVF49tg_jwi)rHm^q0-m#J;COglE+<@X#|Q)4jU!y6@$Bc&u<=4&3>%NAj~o~- zW7NPUx*>}w(j7zaK!az$&{^a2kg*WyRtTNg$Mi5Z+`y(CFL;1nmx7oRL|!0va$Lg+ z4cr@#&~bw(oaG}e>ie72erR>XPHmT09^eVXM=n_4QkE2~;sg9Kdd1HDN7h&^xo;ZLZU97x1DT zKJjW>&0Y{=cnbDfH1JVoz>Q)ExVjmJeznYX%L-76W%0aabwVfh1uk0F*D>`6OvSQV9j0v<+8;d)czEZ6nXNXcU3B8AmR| zMcx)u4PmB)DP9=yp4d8?@5pI!{7@Y~E=?V(Q^%D{-!_iN#&djNF)R!e~P3kKoQ%+&Juh_CtEsCpX#duA4 z6@a};c;V%*%w-@tGL@K#w!2=?2GNDQkkm4L@o7(`k@TfQPRvR)y{ePzAE(#;3Cv-N z=rSgLGUtjUNhf6HAM)M_8UKr1Jt0?LWQbhY8|z8q|H=hvO*$vSq6~TBMG{D4{0CtO Bpc()G literal 0 HcmV?d00001 diff --git a/libs/agent_framework/build/lib/agent_framework/guardrails/__pycache__/rail_result.cpython-313.pyc b/libs/agent_framework/build/lib/agent_framework/guardrails/__pycache__/rail_result.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3d3b39bfb4b9e19b1cd173e9658a635db76797a4 GIT binary patch literal 972 zcmZWnL2J}N6rM@4*=%;(YTd5l!LGGM7sNgF&?-U^M0a5iO>eFa(`0r@O_Ta&f^P9p z@L-Si&>!K=t3RU@qy`FtsPxvd2d}RThmR?_%*HP#LWOA8npJrmCyJ{uiDk>kDgjsAkGPasX%LDiK#RE&k4~^y zZFg6B7_Io)zJ|0UqeMynJahiC3PQ&l2=+;z0QCqM9tCp&|Dtbs=1o*Q3sEUYHk9)H z@;S3}=H#pbWzR)tRkOY`NBR}7wnV}8CUAE$_e?=`SZQ4-YFiaDjnqj6?U^YRWR{-< z0vye4o)?}W0>NbxXU;GU10MULx9y_2`MTLlVv$Ws9)~L276DV@mBJsL3dDe8Vm81W z35>QUgV0w`@SEFBY|qoo*%XTF=DjDaTIMho^G(56<}$XK1Zkvkjjc1>t(Cgv75JsEzR@-l(vEb+s36t2tmKSFyw4WmFy|0%ikLrz`N4vh>yS}i~+v^-!3!i7_Kdc?hE~5~CvXIby()3E8?Q-Wb^665ljrg_3&<6;OA literal 0 HcmV?d00001 diff --git a/libs/agent_framework/build/lib/agent_framework/guardrails/__pycache__/rails.cpython-313.pyc b/libs/agent_framework/build/lib/agent_framework/guardrails/__pycache__/rails.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..03f36cfc3b5c8e520f4af33c53efccf95d6e9fbc GIT binary patch literal 35846 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

GJ_DfX2XerC!cPw*y9(}P8&$SR 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 literal 0 HcmV?d00001 diff --git a/libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/__pycache__/_compat.cpython-313.pyc b/libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/__pycache__/_compat.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a1da71698d7dd28d19a7ebf5d4522664887809dd GIT binary patch literal 2413 zcma)8-ESL35Z|-U_WAsgq)nh|E3$1`8n>2BiYi0}h_pngNl8MlZ=~9;@7B(?ceiHu zE??rI^Z_FJK#{0aiGKk819;>=D2jx_Nfi|!q`n0r#K#k}XQ!s=3nzJQ=VoSi<~JYf z-Actq@cjDCXE#30BlNRo_8#E%W9)tj^d54MM2_KP=8V~l%wY6_=CX6ySyP%=ug$sK zY+mMJU35y#j2!BekD;YP0nwKbN;PtG)@)H0({+B%o-N7JY+065zA#srt;#A!OQl2T zIC8ARu+OH<2~dm(8q6`hJ>A4WIKC*ShpX#RW~y`CLMZKGC=Z)Xv@D1t7Hc#Heo zqaMSq2yj>OfJb~qDC`MLJ1mSyThf573VE~9iK+A?<-Q`q_Zqf6jeXw2ll%1W*~V03 zs)i#Lz%E>29(09_6lS0(;SAC8SpY}7LY=qmsmA_;nuPF>M}#!G>zIcsqM^$v?g-KG zS;O^3>@~V^OT{g+GSyg&TRvCIOkVUk_-kW~LxEi?CF_9aVI=C9t?>>IA*8n#7T&%* zL#7uOFJHPief849Jh^yf=B=6etCyxPJKB&2ExiqE*k_-0Y=A&BWPy0v(KJem8*S=F zLayWYW7ZFyrcQyuz`l+HrUHSxR8kzP9^i`<;1zfZPo^kC>>gj?UQD^FrP~R;Q6~m4 zJep$f2{+a;Qk_15L$H<%4wg(ut9=|C2??7~5yOG-VqZXdv{^4VRN^a;*DFlLeuNoT zT^eGKOBRW}lYBtaUAHH%4>r_QaJ|+GA)tVn)LuMOR1jM)oO$*R;2TD~BUHnFH>TQ0 zu9U!S>Mv6aRRU2`U;7VU>N>1LA~_D@07KeChJE2uU!P*LH5#SqWf%@f!Bn6ONl;Cy z6c1?>ORDfsw>}@#kirTOVk(lcmiihxW^0&L#6tjfg+aY~VAjL84yF(mY}?{Al|fBE zanTd2P@Iy{z@Ai0a_aL9CRJT;u-p>REU;#4%#9-|2?fACo)#o#ky~rnk9Et|jHE=v zP(;uWB2>WIgH!-#>RiCP>I!gWEdro*8`UyN(E|irAA(JCZO(iTw6fFTy4#-w>C5af z#_mV3xQCXIG+;_)97ASLA}6zCI@wboaZFg{(p6sOoC0uGpUbCQvCkD!&hB%TQv%Jh z=9Y@b(UR>{UNvONslwNxRA*S0oe|&;q})MS>EvspQhW9ID3HW#3E?LN>ic4qc}W)V zO!5G!65;%Y4IKUe&qL;us-iFx0AP=37!uPJ9!rV=bC*G&f{ihcyU}}KQO5wnwLLpi zqXftdd8|#Lx=Fu1H--oLZC}vnT4F~q{lbnSf$D&7=>yPeVPg9_f9^WSzCyKXVi6KT z`4N)Xgrps%*JVO7_ISgmW5ls$ga!?ZsNMdT|lxG42iyMpfJFzTRJvT&st^C=e46{ZG1$=_V1vZIu?#8@7Km(1-E zU5ZM>{21LrzgU&Om9EFzdCN$3=4%-_p>?Z3YQsr^5E!$)OtqI>OvW&z9hw&HJ5euXh`h-1kjn$e>{@XlL5e#ENG9@+Q~=j zU2R{~I^aC?R=-qw@M$P6dz9AdHYOvK!AUj#ZFn-Gn8|EL!kukAjjv3X5=FCI$ z&7C?bAG-hC0~>!>_-p43vPO2%0WGZkXx1N^hacste`c&4-a$ZivnW5bld_{IKf0SS ia#j6p^mo15nE=Co)DWEaN%;u+;^pa)?6<=P(0>8Av)Ow9 literal 0 HcmV?d00001 diff --git a/libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/__pycache__/config.cpython-313.pyc b/libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/__pycache__/config.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..009d915ef9ee7665e9427dc4918d3a5222aed42c GIT binary patch literal 7635 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 literal 0 HcmV?d00001 diff --git a/libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/__pycache__/contestation_validation.cpython-313.pyc b/libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/__pycache__/contestation_validation.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..69fe1a5b86b8cba7e56572cce995ccf27bae3944 GIT binary patch literal 1016 zcmZ`%zi-n(6uuw%;kpV%l@J>oARz^*&Qu{_PKXI5`e^QK?kdV3+A|wP0&vDa+B5t^Q=lj0*zV|(kYBdwV`ugGZ&OSltOMaQG zN)h1E5P~ zV|rVJmT9h}T0~sy1s!uwbc6@6DB(H*q>NbK4TN8Wq3lDFM6zU?vsD1Onz>ybB^GP) zK@n;*Om)I~oX3psrUK{yV6hB@x5q@3bA@7Z5HVkdE_{exuLoHy^C<75j}#otm-(v^c*KM9jB8fsp5{KD5%VgfvX}Bb#+$CqilXM zZ5ZA2;wh`UacmV$j%{+mxTy(Gxs}bXhp|-21Er+OD1YG{piw@ROrM*ABR$ao^L69g zLt`ryfuBG9^Kv%0#@XN+|B+(Fdzo=JlztlU`)VFEHJ!f^R$UINJFCV>WLALsC= iq?I4#7Wti*Xpvv~B9wbuzKQlLOZ45$B7I+8qJIF=i9^x= literal 0 HcmV?d00001 diff --git a/libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/__pycache__/contracts.cpython-313.pyc b/libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/__pycache__/contracts.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9abed83d47e48b86e76e5c1c6906441c15eaffe7 GIT binary patch literal 6869 zcmb7JO>7&-72c&tiX!!AM|PZ~KNH4=MOUWMCMjAvPHoF^QrV`{&?t~v#(K0IF>5b( znb}>%cGJRzf!0U&5Fl40C;}JgrAC4D%v(;a=}G;&WHjr>a)J>N^o{IZxx$003j zla^K{)Yu6~iz|hf#cOr01K^lXfJohqXix^i~^da-~J+V|%m&lfo9OqKct3 z>a?((!0|l{qgwYvpJ9L8C2OQB&r5MsT<`cYpi#sIfN^vu#ngDb@uW*h|uYbkDHSlCsy(aJATo z6{A3%j9y$VJ2J_u>o8P}VI42@X?LNZ!wIFsnZVIGWD4v{Sx;OSb_6rP_>Typ6*Dez z&+|hb!iqs96HhdG$ZeMgL7ZE2gxjo)#bYPE8*!n(!+4L3ywGV2%YIwf*Z8U{?8Hmd zKUw`@_I`%S`^JhPO?YFbVal;XMk6D$jj@$nBYPN9Rm)LrC0{mH#vAz`nzGOshrE!s zPN>#mV*;&3HL4^_t;xz%JeyiFLC>QnF;(=DX&9%K&0q~%&3QK(v>&pMoy10|#aR9_b|P)B3E4d3?VjT)m$ z_knb5I0SrwCLjd+vJE~^<7n)qpO>ZYigJyWNulz4W$YItxfhlfSXo&G)f$64{$hbu ztJTYTQKgdw{J<_DuQ6RCYT$C!38mVHVw=A9q0{lLH8;BMFQm)E-Gm*ArqySY0Mrm+ z2W=R~X)Z7k+EsW@Jcjk-;=tJPL~1`^a|VvcBR90xxJ|piS#+_7OHIcPFUNB`+2_k? z5?;cr3k;~e98ZsK=)O^}OvVMv@;Cr&#YM|%`_0Iu`lMyO6LB|@%vjc%BZH90%kv=~ zx2&dbqXNm0&sdhs0d;YfRFku+N;=5BRNZG;FnZ|N77yW)s}Z;nBc6b)hd(10TE8_3 zectuuHOsf1MG$tdxJ9tI8aZy0MB5|-vR_Qd9;RQUGnTMh0Gg8&I8{L&5_}KEZ;a2g z6S>0XoUv!__Jxg^y|?S19bWkO;wOhs{WW{wgCh^Kr#?G$joIe0$FN=lZK@Oykss;?IAix z=5Y9R;#Eu=0Kx4(l{H0;+1&?Cr==K?jHW2LB_zm@LT(bj=f(9ZSnG`+*O!T@E?j7o zK@`MkQt*I6J;=oc7wc1WMXURVb%BUKm_v78gPyD0zBWR}L4>r&2_x`wqIj~K<7c=V zAg`c>0`4Jh-UNLO^EjNz3lz^{yQ8~a<2U<*v|4%|C$Iv4Ews2RBxN=r2*+!|W^W_u zIlAil_BBEV^*O5g=wYOS(uU0^{8wSehsJ=klU+Cn>k8hNQbxZ_DI5=NERnMDP{`PQ z)3mBO(Bnf2)tKwIxWxIaJHDHkoRH03Ktu_k0H7b@%mFr?{iO@fC&pz!rPK0|TETRb z$fO`=9*~GAjgw7J8Br1OgtuypN+4KD5jsGX%8iiBIo`T&WAQYC!Vx^%=^*a|+|$+J zJU}@Ini&TpBbrlUI7kVqtnMQ*CFi$wnwfyu13jd(1d(!R7#ezE&l+}HQd=Z>NYh{^ z_&aiI#Nz~f=``48_Z~SIo43xKJa_KY$)&T_skf}93#VU&(>D+tycVOCkFN8Z$lb_f z-c=QcX;%Y<`ktk?0^4YfkOT~!GdN7A^*fjgVK=+#`))j*98dkrA`HdeQ}&3nw%-)7 zAt%A0ab7!JJk{Tja*23))J4w3QzKZ9i^^K+6jiLNOvyP+C-+gYp9+dY5|=nbK1IbL zDu~YIJQWoxj!^L(D!xGl#Y`Q7zC|_GFNo=bItq$tPa>i{Z%psKeSYJ~XKtOogE02Y z#@@MGXYMRL%+77FgSXD#tv$>h+<5j7qT2Gq?4iwq@eD)jix0Ek-pm`{D&JbZTl_Tp ztX_&%vGJGw#&pf>NmNFo9p$!^qc+B#Hm+vVo1=TUUL z;sslXcPXO;zr3IeN&g@A4L&rb3M5TIf2f{Au60yWHO5FkEI%t&Nr-E|buQcW>==2qs zsy-f5XEd#CwIxwsV#^U?jnEzpY`IUXnY>j&1|Z>Y1W)pLv}h8}NJ{+U@dTv-jYC>R z(25IvG{;lQCjHNw5cV|2HWG}f$?AA3KyW|`>8VIj$;cDvDi5OQ*UMDT%9p8KT|iDy zjiIPa?ivr`0#Zo4I)yiMP*CweMFABLj?)x7#RCchk_uwRU4qtU#C%l1_ADO>? z)j(>6hm9)(A@1l`($odn2R#_BbD7)+DD$|YUNS5+23L@B0tvqKDDhA8K}uTac_E!= zUQ^>LE*|O*fDJFOG*Llj>f%}?Da#84TW(yaBO|nd<@EPBY>#PdPmSy$E)KK|XeQ*i z8t!>*ocO8j=C5ke9dwt(minkE`>0p)l6Xl0UcN@PJye|Nw^hb>g|&R0I_(79B@$3U z#~x7DMZnGH3SZ2oKqIk@zw|ezYi92pDx*N#{gG|x>P=5@>WOXW0$u_n=~-<$wTXIL zd~_E}M0FTnefsIEBJXq`;8{rHODCZKMslZK(AoOXW8@;^QPTlT9KPj3Ie7lrmW%NI zTU(MGAoN)}Y1w+2+>)-)y%FgOWi83YB1v{@gwXzrK>x)}Y2VL3{;yl6OAmnd4XYhc z`h&|qIfwGN#3D&Hh5V!qzY7AMtCD$oPg9TScu$jr(YTbpCyPK*j-y}8^5KmRQa(xlZ6hh5$pRHBN-(M^ zI$xq1DNK)VIKSlOOnambTQBS9yI15zbR&WYeurXn%rwo=2>&{&JTJ9{vp{D qo7AxRx|S8q$qx?n4E&SGP}?jgi|wbi_NPnj|93fG%KU0vZR3As7Pb}u literal 0 HcmV?d00001 diff --git a/libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/__pycache__/input_size.cpython-313.pyc b/libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/__pycache__/input_size.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f18e5d1581fb4dc7914fd07090facc5afdb13db5 GIT binary patch literal 3617 zcma)9-*Xek9bf5W$vRt-F~)!)c>RN5H6R;;-2x$uY)lF^PU5pVfWzFZPb+aC-HE+B zWBkPQiI#^XlQ89>56q;U(AT!p(#P~KFma}6u72oDI_>ZVV|VD}sh_=*Y)YZ+8n5^E z$9KO!KHtxNSx==@g7&vRe0uelZG?O)KblPm2a)w3V{n&fL=Y{aMW-U?q9RJ=Sea6U z68w#cm=@DordrO$Mf_YsBq;evneAwb+WOm1K1z;8!f&B!anYtFM7!3ewf2y!F_F^R zwPY|#YbhItLeI{8P?*!TvzI21(}jwC-Qy;srd9J?hvI|s zC4(1vl~&BE>2g}+)U~g1%gL$gX_z9TF%5co4M<|SFgKft&ae97ruWq82v-hnVa*d}1$L z<*vCX7Z#WhP;k?awt&dM<)KHH8LcwYhC2hdecdURxDL|St6 z@W_a|8DQ90GRvL_tdZ8eSIEzvp3R?~)YRYIsrbYIV`Ie^i0%^*$B87++JN`K#3_A;v zK{6k2?iwV0WWKfeH6Jj6{5l#<5S9!y*xc(xd&wXvk&{XW^5(@iW4S?UZMuysK&mlt6;NJ)3hWuB|u^xO0* zThc?QiXFInAAX(7=x&j}s_h?Vf0|wC8d+5jKURyso&EjAUte4~rLQn!b+mYE;%PM2 zGO(83_Q}AVE4P(;_wIZ7&&s!*mDaIu2FB3;bFIDm=gF0}{&f<;#!Ua$t^H3G48L;# zC-S?_e1?3LY>|DYJ3pj+bs&P?Xpk{>5R$-e0NrT}0Nu?sEi#Y!uocJ)K!pSG6hxbF zo0s4Z+99ko!8u5>%JTXo61U14O#C|D0ZF}*P|Rx079f{^?7V6SJW#pifK_r-^AIsna4Ndc`zhV9J%F--mOYr0^x*WOyG1tAq&;){`sV|m z6n}R0-oj_Y-|QcK)H%A^HntKQTgMh+NNhJ-8iOFPmvF<2fgNq^u%cT5man{~9E(N~ z+E;Rla^Xn8C;;vjo6LeSUT#|K!jXAte$ZY4oR%hVMjODvjj85-Ev_XBN}6b`g(&*u z+bsp6samw46r%s1RIM$iXzj=1P88Jyewu)!;IbF)No$!<@`WQ>M=tuh6Mf`h5CW-R z5q>O1Dd~leC@H5Jyts|^Vd3>PiVSj-8^a={L88E8_-cV8RkcwLP@uSK8UU`t%O3dD z$c4z2$PoFu3l4NM+#J?dC*4!4K>Vf|P z8-mOS+n(GnbFwD?AkFlkl)*=kfM=F>1ZNwyVY4(GT2|=0bh)!hOCgKE(^+5LQV-eN z5w75tMn?MT7MJ_U&HL~=CE#xR1~2+?!NCxgpLSq~i#Gsg0RTS+QsP1;vL7qLEi-e= z-JxNMnxaCiGFn1MDSz?`6dfV2Y$R_mqAf};sz5IiXyQ~F3Bn&8xuWp zM*_GCu2kR`Ke=gxBh!tdgD~vYR+A^zy87-9u67-`ovgQY-8r?^-udy&PiE>JAJ#i||3bNc`pa_<#=ppH zv?!_cMl0#sSKswUeRuA`%?H;WZhxpfoLtFkD?8`vy#w_fef6H~Uxp6X`}eQ)4c?#o z^3sFZFM6LPV%?q3Qf*!7=NY2D^C)>@<4w}hQ}5bU-~Lv8Pj7wO8};t}^*4tfZJT(O zN_42t4`AElu#-_IvRPkaM6X9%R zCL0gjC`RPmTj&rk({RH*fuB44gsvBDL)U#(*GnE`a$OhlvGfx%JTffp!58?vT4Qby zpCE{S5+%%Z7{XRvxA3^&Xja~pk=<_D$tod;b`XnS5wTZJ1TRGEJNU1LSK;r9W0(W) z5a&H~c=IEXXVFw7_K&?JGVm=)|CuEJPWC^I6Ls6;WY5>ho_jx7O%C3QV`k@`6|%j) ay=#SZY{V0hfsL+2*;cIpkgaTO`8#@91O4 zJ9qB6=iGD8$M2jyICaW0@ciSCA8aSHhVcb`44+aqF%Q-;d1$l@X|&8%Va;4E$O5Bz zajhtec$d~nt7TcnTDetOtE|q*8D^X}YDR13g3+oj6f#M&+N#c*@({~ni)`+ejFZ@lL!0Gvd6@3SktanG+m2-|b-*&>9m)>6 zy-;*P;VfoDansK7MLUQBKW3t9L2M$qmnf&VS7*KmMTbWq^|&N4TGPXth}}RXI7NV+ zg<;qA^bNod&29~HV=nzgwXgh8TjkO-)$V9j=#q>?Kuk+H`WWV5lQ`hV#EK8D_} z^PbSh#6#mDgCp)xGKGFIo&w11#NM%r*~kZnFMk7*Z(?)hBP_#a-+r zp_|&!TE_9aIbI0npuIO|JFKDD4i96AEA8|jg>au@3d)n2yFzvG+U`Hnl2qD@Wr9N$ z>xnRCnS;b4t1UIIFE?*5)#|L)Tz=zLbNL!g8;usdZa3~UHg4y$T3w5(-C9{+)!UbD zw6fhlzPWtIU0J6^J%dHcwGRPpt1JcreLWh+x*l10fhtTQ>jvUt&LDKl&7$w+d zZn#5vRcAreOA~j8OJ!4f!q%G(1Rg(!jo?A-_WB<~;3%gk{pv`+y)fp!7UKtA0y)+) zfMe*nMe92bYYLsk$I^Quj~(lkiG5@JHlYC}dwveYf7f9xAp?Z_J|Qd}$_UtHL@$?1j0%bcq20m69vUhc2ou#S*|X^+bZdQ7-2KnV~Ue$oeGz9 z*iTXo{_AlhG6W-drpJTHS=!}PllY`a*odJl(9MGm3I$5S#{k(L_a)#}Cv_%)Q3c@L zEvnZ7MzIUBf@=(B@(O4d1|=oJ_Mnm}uEkeL=n!V1Deg%rD7cjhMJpGDMf93O+SN^$lVuo9vf7cSW^7PS zCBrVJzk}&k0GS?T2pXL%{P{#-h6j;3h#D05JbM^r#wg^G#}kn>Sb37058}= zW>!OBf=!0l5kwtrS%)om;Q*z}dYgxDbFBllOIe!&bLw`g4xi=cQA;v%&pS0#x%j^D zQTML%PzhWsMNwcF%h=WT{U)5FE@l_hF&c~#*UQ5d4!_yII55m z`Q6^&VJeoTjO8Nh$+*Wm8eb@g+T?aT^c5e@`Ri#pCg7! zRsaVVr)P9V{XTXo8w2wBCFA_X-#qx>!RP1dpPs9K^wwwRZoFUl%jxHTwf~F#-+t?( z^wZM|pHvs*SFzhRwaT`+4)so9VgKt>!1VzmFeUXUa0Vs%vMcf&_794vE%H2ZK1Uw7 zi_bbkm-3dph(-A#2D?hQ6rtk-E?KVIjeYbvn9sT{>>uWo)2`bNq)Ngd5>X8DjO+Tb z=eqJVNxFbxaMndvg?7kud6LLrD@A|rx{nQg8Er0ErOh-@qoU4W__^_{aI#$e_l0VC z)%@~>=gY5V+i8<+$xC>VTKZ1{)RF{a@+_@ZlD!^+Uy?%x*7%=}MtywW@ literal 0 HcmV?d00001 diff --git a/libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/__pycache__/llm_client.cpython-313.pyc b/libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/__pycache__/llm_client.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8f10fdc3f5d22ac59bf2bb3b5cbf140a6a27cf49 GIT binary patch literal 7306 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 literal 0 HcmV?d00001 diff --git a/libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/__pycache__/pipeline.cpython-313.pyc b/libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/__pycache__/pipeline.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c2af6f6372f4e1a86957b23d6046820583a54c06 GIT binary patch literal 12629 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 BjavW! literal 0 HcmV?d00001 diff --git a/libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/prompts/__pycache__/__init__.cpython-313.pyc b/libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/prompts/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9e4ba3ee906a2ee7b89faaaf69c0d88d27a1def9 GIT binary patch literal 441 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 N|DWFeZ+mZx{14YP_QU`H literal 0 HcmV?d00001 diff --git a/libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/prompts/__pycache__/coerencia.cpython-313.pyc b/libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/prompts/__pycache__/coerencia.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..08b46a4421a38f8fcd90ebf336bc1e7e8d0b6e47 GIT binary patch literal 9453 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 P`rZG#dRVP4>3#nX+VIci literal 0 HcmV?d00001 diff --git a/libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/prompts/__pycache__/dlex_in.cpython-313.pyc b/libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/prompts/__pycache__/dlex_in.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..023ef961fc308412aa5ff42dffe6d606a0f7eef5 GIT binary patch literal 1272 zcmah}O>f*p7`8XtG+4CiAzYAXC_UH zkop%m@B%c*eWiM&*FD>zR2!A3yJ7FYnwbGF<=s@#Eva zwzBN+bl6<^db3O+KV@gx`SR0j$M0 zuIzqQ-Aff~Ra)}i%uPw!iPEe*S5c_xUXW@@NO2Q{G$mK`vHMw!J1B~Cz6x05A^H`? zXX_&0MOLM&o%;OCqi?6j6BJYKb(#vOMWWm+upAU0sa9OwhJ9rkA0&1!y5HI30B=Kn zU$xG5uL6*H)pWl&)pmc*Y=3l7+3vRr`vgmKX*>c@F}MqEkXk;XOHQk>=B6}caNtI_ z4&|}+KTUYAzHt1CHg&%#1Z?)fb*UZ7~bwS{5peYsePG@mHrO56=%L=SPXK zQZj(A2pVDtCeX@Cb0amLdNubA0?^coso4OATEn=BKcN|58s`o-DFO|MAo_|tVah5dgbw)tOuhbOEb1Gj@GgtpF9}BEKJ@t$$r#xwr*BN z3D7Mmp=SU*`k{E4?d8|QfLF?=S6N+OPzB1TP)f~DoLo#@X~x#f{P-=$covP-$@L#k z6-l&^v3^_<0)ztV@#>X>G%R0DO>@6}dcE7%n653;RfKE_i=Aw+ z{d{|o-MgJH-r0S3xX5;I4VMVWCVP3GBI)}hx6|zwZr3}X)J{jspUMu7eZlnkT5RQc Mz8t)l5Bu1E0V$WQH2?qr literal 0 HcmV?d00001 diff --git a/libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/prompts/__pycache__/dlex_out.cpython-313.pyc b/libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/prompts/__pycache__/dlex_out.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..77bac8f9a2ea02d9ece6d3a7552e3f93b92863ea GIT binary patch literal 1559 zcma)6%ZeN~6jk-pDcd2C1e`2l(d0qH%=E%p4IvQlEGCYpjoTBlFf{5abz5Uqsd6Q? z#}fjEd_fjj1%kl~Kfo&!h`p`9=#{~cb%%khb5#A9VX|>SNxHhyxvz6|eDPw;@csSr z*Mlbw#@+;B^|hCa<4>^ojSX6Z=r$YF@Yip%FI$7g$LyeS5K%N~cH1*HYdCr6X6?k} z)uKhxdCHU83J-G=e;xnv2N(bu?MLqda-U(WUuk~Ix{W>mJ9P2)CMlos@+tQjPqeUB zja4F2Lp+t-%84hDmyZQcOvcUVKsq%wL6u4;6DNpI#gWKl?y6mtj}2v_d|W<)EI3J9 z80$p10Rv)!gK{g5H{aqrIv?L$Uf+)W9|-5IuEp_nK|gxQuYR}l!?3@93sLY>p2)+( zTS?pTCNIcjh1=jNw~joV{!>~APEs!H1}}^*pF3p3@;t;-l&?m*5{>7&d@;cq;JGcI zPo)N)Gj}0v@Z^q|$}p2mWu7RZAjmu|48XCp$sL&m3(gpAInchjv3p_}NGU2{c_FPe zxV$hgyfdVZDh;kIjv%kbJ2I%93c1Byk`scWevBAeAd@A9LmJ>BnS^*^> z@X`GOwdbagBobwEq2qW^{?g|+c5YtZy|sI_KL{DyIV`{oxaPG}8Rpz)l8o)8YN8xu zpgDk#O%5vx(YwmTNlsFe;0ow+Ha|!RwKnGQ7YtHxr$$iVywWe6tSAjoOS~K zhis9`q=GYi>CD>Sb*jb!odPnRPS-Ldp2K#~6k6m!_v?+5%r1^jg*M=I2(>zkK$Jt> zPd4IsFYqNh!^1+r_9CWbhpZS?)d(0VB0y?DJu=QDMu%na2bEj6zApS}HUzJ!e1Qb4 z14EBh&6A@EMIpgw{_UW@w;lh~5n7vjGVN@0kY4u2LR-|Tqs2&SY<5fS3N%j@iKYO(A}X)R8Oms z?VVBdMqcSOsQ#y!ctI%%rEM<}I6%V5w72M9P*2OlA(~*TxIg=_0vWEhhKn=w4t$A% zQ(s_sz~;63d!Nl)?DNfsyK`3Cie5*}2dz1Kza7obU%JqkvrEm!F^;mmZbTuFZf#b_ z8&LsK8ygg!b2^7%cJ8apq+ZLf=>o*c%w;U*^(cz|seKeR9@gg!)03o{{<`vSkSc)x E07Gy1=Kufz literal 0 HcmV?d00001 diff --git a/libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/prompts/__pycache__/fallback.cpython-313.pyc b/libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/prompts/__pycache__/fallback.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d5cd63327969fe703497eb17f170eb7f19b825d0 GIT binary patch literal 17620 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 Rh+6&3e@_i&>a%>?{{XQ6xNiUe literal 0 HcmV?d00001 diff --git a/libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/prompts/__pycache__/ragsec.cpython-313.pyc b/libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/prompts/__pycache__/ragsec.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..33e30180b65c6616549aad51395a0adaed00cfdb GIT binary patch literal 1088 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 literal 0 HcmV?d00001 diff --git a/libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/prompts/__pycache__/tox.cpython-313.pyc b/libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/prompts/__pycache__/tox.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..afce58b553dce6403a3029e204fd8db096643ea0 GIT binary patch literal 612 zcmZXSL2J}N6vt<>>2@93vR(yY2zpphbMR!4Lg`7-UFcTuw!BSdm(kfwd^2g+mO{UR z2S0;&_T;(WVh>&f&w+da-(>AUeUJzL`TgJHKS|pCeZi=HegE|C8E5Qg5Vu9Tt2S6Z zvnjjBkS+Nr%5O=)y+2QTuyye_?0`+9r@aSk)Ei$s6vqaf(+mBfR?E!K;<4GouDpi7$PDxefw)6-nD==_|bZQr>blNFA(>Gse zeW7!0OEA*blFS8-`kQa4!O_O?i01+<0QY-`s(%Ut~D4eHUJz+$>?K zNxjFV}npDi*^bHC^^`M{<~He~Fbo8NMG%}?HmT`@|Zbsmd;=U6>O zZ2sOBBuR!^D(AHGWIV}|q=HrI8b>QjD;u^mDlHH4{0)&Sm}W{U$>bXAJj^qt=N9K0 zaR!8opsI^NEIm{4!Ad(J&jYgGcO6{<(JYRD)jtt>1&0iNJ> zB^4Z%juHp*1X+k@gdhixE^S`k5@cCVk-P#}H%!n&5>io@su$8AlPYzgts$w+#B!|) z_>7$?wD=Yig}hCQC}m? z+M!&7z9@n@WKA$M7w7ABW99xTGsbziKaeBbfec0$x0>2CAR$=J)Rk5TsOT*l%0sQB z^Q_HujSTYdqMtC{lyLD;$VFH+F`lrh>C*DYu`Tql(r0e?4=_9nx+){|A2JP!OIEsa z!$Ki|@lMJiuCQ*r8+tp(OiNYL*aqJOKWIKJ94_b+;8;+ev%3cPDE_Z!23OKpgkeMF(B3c)SG<@5H5xWwGa37018S bD(ih1Z6`^RHr-9KuSF}ceJlRNZN>Zxo0J!3 literal 0 HcmV?d00001 diff --git a/libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/prompts/dlex_out.py b/libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/prompts/dlex_out.py index b88caef..09fb7a6 100644 --- a/libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/prompts/dlex_out.py +++ b/libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/prompts/dlex_out.py @@ -20,6 +20,7 @@ SÃO PERMITIDOS: - Expor valores de planos, itens de planos Não marque DLEX_OUT para explicação pública de atendimento, protocolo, plano, fatura ou dados autorizados do próprio cliente. +Se o contexto indicar authorized_customer_protocol=true ou que o protocolo veio de expected_protocols do workflow atual, esse protocolo é explicitamente autorizado para divulgação ao próprio cliente e NÃO é vazamento. Responda apenas JSON: {{"allowed": true/false, "label": "DLEX_OUT/OK", "reason": "Explicação curta da razão"}} diff --git a/libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/prompts/shared/__pycache__/__init__.cpython-313.pyc b/libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/prompts/shared/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..903f4e91d312226660add5c05a6ebedd79984566 GIT binary patch literal 612 zcmZWn&5G1O5Kh)bhrqr=9UYL#UBrv*O+D<4=cbcxv!$J`Slu0e@F4gEf1+30ED`*i&RefDwzWUO;las2D`0@4KlecA2e9y%pq@H89kk^M|U2xHr z%cJyKfP2&rTjTbGbwL@jx=Jdo4Vr5v~g zoe1#}y&)0n1BN(#_N^S01=zx@PDDMJzL?}F+^#?(#-KPkS@3Usd-ER7Y{z<*Gg7NX z^!_Wb*{tE_yiZQm*`xcX>*Z>uI;chRD%yT2K{uw zs8`j)Wx2hfl%ZCsPsJ|(qixWg?4lmC?(K8pr;1vv9X6r<2dJBb&SdC6OQ{rkj7qJBm)pgip2RSFm#>S4d|g7mO+T-dW%=u9Q6BTLl)nMR+SO|S literal 0 HcmV?d00001 diff --git a/libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/prompts/shared/__pycache__/supervision_template.cpython-313.pyc b/libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/prompts/shared/__pycache__/supervision_template.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e7111a6b227cde587daf34251310729eb585033f GIT binary patch literal 2196 zcmZ`)&2Jk;6rc51lFdiIBuWuNBZpS8aBV)shfIZJ+$gv-aqv172&C0yckE2r-LYnN z-B5}M7bK1#_ya10+9Gk{L*j8Qu-kXhGx4~Ne^_K!6zu{!^WKzL8ya2)%#370}mXmqix|C5FN}l+iKd0biA0tEfTY`>APC>A~gzYWP1 zhplD0p=1*I+>f}{WqO6HT^5MzEH$~Uc*x>Ju`+cqyx}cygT`Z7vJ=fh$~Bx0tf$Ak zcknqKFeO;zOUn8@Vw!HXHrFAfcC$15q}^;el+*P$*EhE>x15T-DSaNm(qJHKbYr`7 zzU4UQpMCmOx)w9VyNvFNXm}G0q9c`HC_bZ}1jqa6RO(X2{sUPnS))Z3MKWfwkdgLM zCJD)dunfN}A=Y6T1fbR0AuGhmm@&I!ft=gPz?k33!dTeJ!8rHa@{^=ApZo+gZty8< zhDjL#LU2OECQ^u0&M*kX)m2Z|YzhzR-H3&}Mk5(=3j2BqQ@+`^#`h~VTAX3A&6zPb zVY3JaL^GZeF;_zB8V!Vw8I6(VC4$J|Q^T#NZWaFv?agMCs751>YI z_$|uR;290L(u{Vc0>0sB=>|v@sohwyNHdSYHuGVI3iQWly5Pv+C8xDTWdb>I-|>X2 z8h!r!OH<|mjw6Q>5$Go|z4!5Fw3WmtqMafD+2%lcbcCf7D-rb!|A4+JBb@XDNJyMV z_`(w7(Lg|2NqYJ6X2nh(2i{ld#uRn{$+=%}HJW?{3+yY>8-7iPcW4q)miPj|g0uEH zR1lT~5XV6Q_2!EZiU**>)DJjBkVL}6n)#kgtQk%`&RYF|H_>H%To70owfnl$!nO{ddpHyf>*ef^YeU#wqjIc}$2 z-*W1WI($sdAh>9L{itTKRSmxb$fUNDA0}Fd4Zi`qtz9L0%w#76_DvgOw7$K*Rd)>Y zvtgG3&@jz4%6#EL>9e3_zh5)}VkaopAU_j+qssyf?XCzocZJWPRf49tCwhA~Lhg$s zyb;K2MOdIX(`H-o8QN70Fy{OH0O&P64LJ8qmo9!_-yx;^Xkl94qlIaWjuxi1HahlD z6^-U6<)E=QVQtgVhpYz~<$}MEUz6%xS9+ovh+SQMNKxHQMBt<9Uz%xG(NzzUV^=|{ z`qiV$rmFWK5&i0GGdkc;rsZ^Ljv#%ttw`F8X6%VUyz zv1yIx$tBCNeqMxW$HHl5@c<`F_vI|e1(G>&mz)@r>`61R59~3?FIwZXrbUTf zmHYMB$#EXuaJJ*8#&ammqqKmMO&&QjUPNh$z`A9WR!CvtuVW~^W09qEckOc@%^BDK E0FCCr&;S4c literal 0 HcmV?d00001 diff --git a/libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/prompts/shared/__pycache__/tts_rules.cpython-313.pyc b/libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/prompts/shared/__pycache__/tts_rules.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..12e38f60546b3596c2cf5ca462f5ddc0cfe90a88 GIT binary patch literal 1146 zcmZ`(&u`RL5cVcfAuDp}p_Mp|77hvWuCq%*+klV)tPm0ew43(Oi}hkpmRFuVX5O<2 zIf0M>32^|4KOo{zH4>-x(q4V%56F>9J*Ub)(0RL?sOk@E*PiEj@B3!voAJ@YLNk!- zk6+*X@Om}~e)o&xt1&f>J{RL%Fbp^tHn=gIi5fgJnq8VJKZ;|3BUTm?mDj)IIuSEP zs3=iJ@2dL8`aQws<`4?S3e*U5hZYK^3RB`vvw6)>LjH)u9Y?@eIxQ#by$TIHEag3= zWI=v%C@b6;epD(>S!om5vOuo16`H2sEt}GE7qcncn3W(g+7k;+B`%#Orqm3TR$@Ek zg3Kh+PP2S969mmc|K?zQ2sirh-QDZ!w{LyFUcacH-GxQkVm(r>{+YETI!2$w?YS*- zy$4381j16$E-2&F(ps|(8})A)GTAjin=n=i3Sy9qF}Ku#{!V8NT7&b@?S-q$E%@~O zEwobFMX86<77!Ah3q|e}B>rBJZFL0qhH^?k{{w7!HCkSYdds~_Q#e7G6k16R##cNg zfzHGhy?hgER8@`%9M}7zrVpab#@XCsa?%aP*Xe&*?+rHFE2}4bMZFKmEPYb% zpFmG@{TuW~nI{TLi;yXPkkX?Z7B7TwLH_4L(acI6AtC7-mR2C367q>=OTNyN<68P# zBWz2*iz2eQ)t9p6sVE+{LTFt#il-K`Q0zxTa)KQ4E6LIU6KKYxAp z)dnHIp|bpHm2jDX@GTh=L&m|lHVTF{Q==%?NA+RDG`!pxZ48^H>E(@4YuGkzFE>Y< z!_b6YZjH8v+h*I#?a|KghPmP8&C$)_uGyuePsZVAfw?u^>Tc)1)Ct*7Gs#n~99z6u z{KPFyI5kX2ONC0rOe8rIaH(k~GA@PU=rGNhNxWAt3?H(D(RA@+l1oh$w~o_{#TtIZ z6*krMsnJfyTGD670RIeOVy&EEv9rDGWiP~Q4DYx}g(R6S)IC*?PJJ&dOdma(8I~68nPH5#JAFf?g zz>--jFfV)y?+sNz-kQczKvg*HVD2R%lQF*ailf&{C?*$g&QD)psm=v$D8Gr^j0{`5Uu;rc3IMfVsVsf3EVN+Y7`ecv2UZPq)1q=lQk>2s( zQ`+~n=W|ChEv!~TP1nH^$>)(!R~#RKzOO1Umrv-UgU4S)`-ij>>j^i|3Yj+a>HgvH z4rTJ3y|j0kl=_?})ysK6ojXLt>LTD#?ye&qeSY#^$fKk2o@Ginc#=e$x1c*c_f(hY zCwg8YgF(b1VUV@b(1{r^=uD)JpG#pK-NU}7lF#@ZIykv|?|#MB=J3WdVV8|ljT4}l zYDVbN1*^p8JkA~PvlK=J$3Swad*L4etd(w1gsWZ#ZTET`dXKA40&Q!pCD6DkC2Ff$ zpzGR0g4(Jw@3sxB7GfHBz}6$CiAM{MHXfUJ;9@-NzEiZKDA92g70q%8{eO$?K19*-TXldc12)13({y5dJ zF!?9uHiX7P**!S^tOr5xS8X?F{PQ6R-oGFpU6A)K2=ynZA6$^ze>XO_YG1a@yWsyX D7bXyX literal 0 HcmV?d00001 diff --git a/libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/rails/__pycache__/alcada.cpython-313.pyc b/libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/rails/__pycache__/alcada.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9cd565fc9144178719c802448eae8f49c4abcdbe GIT binary patch literal 4967 zcmcIo&2JmW6`$qTlC&f;vSiaAjmNa)lC@3Ig&m|ql!DfWzf`3WBR7VOu2$rbUVFLA z&Ms}mO%b<;Ld~TxTEhm?gVGdD-6Uv$o_Z+|D1U%m9V9Fqz-Z7GzR{426z!$&&F+#S zZKp+n4(#FVn>RD>y?GzM(PnRNoIv~QA8uRn7hYFV9CHJ$$X`p+rHL7CZ%*ED1G zBg@uGCVW#>Uwt3=#PCwXvRN)3KgYOM(Ml?{7&Yk?RX2Hip4PcpH!a(wb*7tCtun)A zlv(!byTD}F9JV#7uGKV~#Y?79(W(uu0_lpT(i*eju(D|(kGnKS3ni@v0{Dv#(?#9< zUV{NU9M3h_Q;jpL1Y#I!4Zh%Hm8-Py+9{e*ZDy1;mwK^LQw=i<3J9&cmCabJMyIF0 zl^vzm7)V*VsMbIji?SuKilJJEsjk|qzcos5a+z6m&aSO~bcN};_~}|*XLyJT_V_k8 zZL?(RbYTI{Sy({ZfTA{6OSYA(zX1YFE-_dl4BW8H(Kv-x;bzU%S*dVPUt8j4mPORI~e^x@V_!(v>)1IE(l%m!8KIyejm^Qgj$&?d7( z^yu;Y;e4JN;7SdZR#Y2YA-820;R1^56}CF|{nqw)cv^U#;%=B8r4tMtMbD&R*IYiI z&bFly?5@3(n!2RG$_DFLlJ8#f19!D+hcax9ih?oFR5^wlz*S_xKrY7t(8%S{=V zRjEq#)!$b!(Sf&K@seKqf^dtiHidmNm4@LlfG1N(D7>LFYs3`+Vjr{5s}0qFZ1#k# z2Hw1zC=JMftz3ARa%P*5frKu?x5i%M4Ysfl&y-9N{a)S!jUeow@o6z-5ak`uC+Ua^pkIu~8b zwX&6Bmb4K_QlKwp{dO7~S!`%}8K<6@X(zamc7hwhAlqU!CsZ=a%t^Gp1QJ`B9R(?@ zFm%_+gT&5F7?2KS(65Cuc^E+9#iC2jNQOkooHUCIyIL{mm(U@S4b5<5fzWwQnJP?A zpD2u08IT~)ZDJjPM(~cQKqH~C%Y9*LRGKT zp?vwG^1UDiPeJD^jD!w_33;I)huZZIefFiLdJDMk2kQICw8{aAj#Nk-rS5^qB>A- zqT>j1XE!EgJVF_`D9IBeFc+9b2kdG^X};xn#enZ_K1wr!&sY`w(p917Nqc@CB^GV2 z<<9;&M)(<=A)mwlH6rt9QPEyM*OE`3lV{PryIM>86NJnQB#aER7$se;7?}&tMZk*v zT@&zm9Fq<-O6CXM5g|o+jyw(Tf*k04U9Bh=qu&S(kvVyY>?iY4e_AH$kl6RjWeb7D zyt@Y(o^nq{cpsVhWrd6d_mPV9Kb#Pr3;l-^B5=YV{S&gW#_z!A3y{PCbUqbscOq*j zS{`7BTHrxz6>3g_S1lK2dR1@q2~-D21Pf?)H532^K(yJyUS_=nkV4fF@G^H(#8*e2 ztY{ezrO-ENMK@I&el42=z;=rgVtnsSfg51MP26JH#%WkrpS6+uj-a*GcbBx9iO`+_ zhBQ1~w?ZIaJr|sL1r&;*sKx%nq-8!A{Glvvy`4fJ2ZFdZ@{^!Ia6t8TVM`@eh6j?< zvlWFnQr<~+>(qDwT+<_BvCC-&-f1<72!IyUT3 zQ1vOxsd(qOcFSHnwp9jrSCuXUa1}C)4Fd%6p)!7WSRaN{*^nc9mf;x3PJ}bnG7Y{T zKC-<|U#Am^GQlypogm!56PpA>)e*}&5#6j-8F%EXDmOqqjv>pximdVW_@j7YlCdr-aiQ#*R;q}C!-}Ens9t@;zow{-A_IE%0&d0?MF02iVF2^?d zcihU{$lTp?IW>Ss~-%suPRdD6x zdp&EZBg>~BC&|G6mBF>`Utf*_wpmZ?gMasX`hPm}lbMa=)JAe}Be`n>WJsp(CDV^% z;oiQ-J!F7xq`tB-xa-#W8|OE6?z{EYjkh+QKkz6P9_VWlU}^S|WNJC_kH-axBzJ9+ zFi7I>c?vds91g-hQ8Kvq_V~}H-=1u41CD<^?)R97Tg>O-XrFl(T?xL^^Y&?E9{#5V zd6s6RA`=e8vAl>5A2HSi=zdHd1)||-bAUwpHUm;PwHbs_6GzR6pasGs9t}p#s7E{6 zq8;^UQh2bncJPbHv2aR&6>(fP$zO)UQ29y&tO?3<1Rsu!@da_^$msU)I(EY_hLI!w z9^sl2G5C$*gWp)7R$H$5aGqyPW_ literal 0 HcmV?d00001 diff --git a/libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/rails/__pycache__/anatel.cpython-313.pyc b/libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/rails/__pycache__/anatel.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7ebd55ba9cc1f8ec80b0cd0d66665bbe35c6a331 GIT binary patch literal 9116 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 z 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 literal 0 HcmV?d00001 diff --git a/libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/rails/__pycache__/ragsec.cpython-313.pyc b/libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/rails/__pycache__/ragsec.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..aa71f5f40bfccf1a3da77e75bcd0f5863bcf901d GIT binary patch literal 5381 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 WNs{FI1pE5;BBXO@E&u(bQ2aju$&$kW literal 0 HcmV?d00001 diff --git a/libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/rails/__pycache__/revprec.cpython-313.pyc b/libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/rails/__pycache__/revprec.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a26fce760d476e058758408095b41cfcbb313cb9 GIT binary patch literal 5389 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 literal 0 HcmV?d00001 diff --git a/libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/rails/supervision/__pycache__/__init__.cpython-313.pyc b/libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/rails/supervision/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..dae0fca7b7c36a0e6ed52f8780620d88ecb28b4b GIT binary patch literal 5731 zcmai2TW}NC89us8EBPiHUohYU7-9t@6AWo^;t+;gv4SBMW|(m@@*=Iw5@}bQT^Wbw zflgoO6Je$qlD;Hq9tfGqOgm|3()KBFGJOr94eCzPGD)YMyqQ3n-X8k>XSK4h$z;LW zv*(=s&wu~FfA6-mC=A!%e|zQZAG#R(k{-M(;0}CuZ)5N>%QC^TzN|mvoA3)ir*R+? z5CPnSnczf7geJlwEayX+$V5~`F%D-Vnb?FPl!>^APb5SFbJ1)p(=yR2TIE>Dv`w^& zb~%n`Iwq1LDaVOS=R}w2lH-=lnu%`FEyt~yo{3)3%h|Jmshu9H%lA#}*|ocU?z8C6 z2C{8w-v-wFFPqG^uVrV0XZ>Q`2+MXn;}h%W0;$gG!(qmzRJ~;Jg2t_CMHBP7wfLsV zE5e-D3Z~#+T>Kf=7PNfTRtu)ZwK6vr-^JakX!*r=ih3TCv~b=O&lgMPc`L0b$JK%$ zBA{8d%rS-I5}H*l*%lw?+Pqq-sY|Y54W=?>qVV*Yy-m92K z0kgU)XP={KY+JBXl5i1B7PP!>fehCT?;!V7I$1Ar!?YWF(rO88YK7$uv}rT9g=(vU z&+BGMUAzYNC3RY(E1ia1$1F~Ktx{G&FKPmsAw4uURP>5g(hZFd=|-h$kC;^(w-jm6 z7K?9Nib^W9O>0bfB+av=ukY70pA%})lLRbZ|8kQ?1ENP1>_R6&(>@>wN*I@>0n7qI?^JdAkQd})9 zUT=_w_F-O?EHSSMOHC`I50s&z3bmw_Aevzdc$g0Ts{F(mp{a%Ardc{DJ*)0!c@-2% ze&<1|g(x=hcdo7aQxUfDe^%IJvhn1qKdy{**V%e0H|(G2^(7JLp$A(75i5g%oh7m0nY zTW~xmKpOOP$;7IzaZ^F0KpK|{1*6H!rlH%Ws8cRz^BRn!;V8jL-`rLgREoXX*_GVQ z&MInN$B}RkieNH2^hY8?Y2`{uqjOwO*mq+4jz`mvaFx5GM^kRZ9I1!se$~ipB~{SN z6d`mGf1o;71rZow9=@f|skS~3rYO9m$G~uT_gyJeTE^M_`y>5`t(6;ui7Fhj?7ar& zrIMPm16NH1e!ir_jF5u`B(zlrE1g*Psuc&@SDpsVsHo2S7ZBFX^QF2%#h zQSiosp;=agxjIdvC{vXM$;oTnSd)BKut4Wq6sJ@B4v!R7@;{g8NllzabY4)A^^PNn z$fYKt2thczrE+o^nRzIf3-#djT;8RXrSzRQNtZ&i&HH#H2FU~U#cL*43%Zo7#No8i zSVIF|pu#`}9D?jbE`?}7YD+6$QH@FYoVaQrqr$Fm>dBPfNv;lPC!tz73W1VlYX!U$ z&1&#yxXf2nV^aaA{cu$k1>$kPo6emCJ$Rw#1nKE3Drp@YaVC=EOb6Vq1PdPSzX9cy+h{9`$;Fbh|w7SAf4~-Cj7q4rr8j!;3{C(2pa@` z81c>2D>cKqSGBi?7&8Jhq#1cl`?LN%K0h;pGgzt5HFkHhlcAGgE3kuE{!aG8O^j7R zzjAUqI2G}BFW;xbQ_j&heia1;J{Cv!F(fGly#KjKOP{h7ZfjUI&@ z)A8f}qu@mHl`!HX%xJ-1>vRIV0Eu1v6*&nc51yhTE1r^pa2B8 z^1>`+U3u-UTL)aXPHkMdO8k1d;_T=Yo?E_mm*z@$>Mz?tZV)=)%nBG`BUEG?*-Wc< zMue%yAg|ISO{cfEe9s18=?6*Uo9bTP<&CD5-9dNE*-W1|n+-mgMmCfU?+LiJ9Do-a z%0A_=kF4X4i@qWo4-BxPZzCIC_Ih}F5i$+HvpAdl*4-hc^c(RaOGT?1m~b(GDobHW zr~HZ9B@q0pa285{2Pmj&A;k$p<&Afm(+4*Na062J7(atFlS4txKMydVTRF=t+BsP; z#{nEHjcbZm;N^1)um|;47v?ZHshGeJ%de~=L6{(w=0_~cRGJIBTk@-AWKNW2lQKAJ zn4lUBJY;dnkZ#O1a49lv{aDC$uz^|b!!q9wUwE?;2!j9`NVqG(3!uw)0vA5ij8Uju zG$RpJ0hp;H6|d+JikPD$PR2@s>nt?8U268hYI5OM$()l2gODJ`bDBt>SA{{kkTp($ z`BAB0Y~9G0s*CRstVZRek_JR8K?WKW4_;3${^S^hB;9hrM`{wB2JSjuN5cSCq-7vINrfow zCul?D2)8z1yu|tv>*5UZTn|Y=)6~F>d7X@GmE>!(^B@3$?Y0hF2pyB=ZIiTs|B`3- z;HEM(24nrMtOglp>JJI@?nxKkH^r?|{Vw55(1i_rJ8%0h?b|9jMwkdV)b9zA#EOA=y z%Y06x9&(~r5>+eIXr}Qk-;1)I&9CqMw0rc@p;~g|jb!T5{#s}6m9a|)mi#R($=c@BwedH` z-`x9B{AN496JtHQzKt_w_njSV{m{+!JwMO9bna@$tC@>OK5pN$6lM>lE@o<5hc0Hm zZ0Ww_tHl$S_g>!nSt5CP@~4xv_OV)f$JOwaFx{e8qW2=fmewVOwe;RfY`Brw@XEPQ z6B}so)8#aoh}wRc}lTuIcrrfOZi zSC3pdQtRr!)wT6T*VbBB&%IcvBY7{u26xof@mk;d*ZN-VtMzZc6A2C`Uy9#q=O4H8 z|1PzG%zwUJ1F`-T+x5S%cd(8zD+?q1qV3@0fnTK#^hMua+lS%%yOIY6f**u~7=O?m zK9mT4!0GqHzA$D!98eBE7Wpu>FK}=)^3iYvQy-0nF!j-60UAH99EwF!5ouzP0C_?9 zRuCK$NTF>6gNn^5%skp%%H_ zOP9~3HaL-7u3+YKIY-Im>M@lQggc!G#W+f&lSE|ZtLX0xJMC_SNvbTq!R)jM$^1$DZbT59>hjoNN0zSFtfFQXE;4YkyXlb~;R zUSBLVGO?I*FduRL}$Hh3|-)XD}n--#Xb`L@*JeM0D0 literal 0 HcmV?d00001 diff --git a/libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/rails/supervision/__pycache__/correspondencia_item.cpython-313.pyc b/libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/rails/supervision/__pycache__/correspondencia_item.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2520398612a66b33c7897a7968d21e9f6c7af7d5 GIT binary patch literal 9178 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 pvwJNE!{2kQ2Y>s@I}F1J!;OjIs+m)k|!Ri0Db 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 Z8I_OT4oJS8tKBTtb64v5%ZMQ9{{Y)Qtn&Z> literal 0 HcmV?d00001 diff --git a/libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/rails/supervision/__pycache__/intencao_cancelar.cpython-313.pyc b/libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/rails/supervision/__pycache__/intencao_cancelar.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..940124210a0893731eeaaaa060a23333eba2acb8 GIT binary patch literal 9328 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 literal 0 HcmV?d00001 diff --git a/libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/rules/__pycache__/__init__.cpython-313.pyc b/libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/rules/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..63716a332cdba5c40b5f190102151c25f1407cff GIT binary patch literal 501 zcmZWmy^0h;5S}?tJq9i{6DoA!+<5^pF+B}5GimC&YnM8Ey8EiTSIv9{K_B2SkQ0o= zzSuR+JaigAzP&xa+jre{EB=Jm``8_6dfz?kq+9ok zgL+4Sr?eK#;HZ#H9Olotux*V9i4%Daq#&#-iW6j?m&5P~9l|t!an(l%lnX&Z8#UP& z%6v7!s)qUF{FO4K+T9elBn%O!Ofq7Wy}M;(j|i0eSh-~cuG;qe7PYHG{Hqhe^E*HBPubT zsG#*V^M*hjnhEE)A8a{1S@hf6#<*yWx$1W9dfRhcQz&L7IMK@}FHE#NdOpkJKfria z*}De)hx|R`Xi*7*h1@9BQyz`sz{Qwldc8e*Fh#vCJ(OE&-Ts%`dw<^O`~KI#&Hhjh Gwfqeo^{x;A literal 0 HcmV?d00001 diff --git a/libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/rules/__pycache__/alcada.cpython-313.pyc b/libs/agent_framework/build/lib/agent_framework/guardrails/calibrated/rules/__pycache__/alcada.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..82c85db4ca0e089cf55ffe96f4d04de101394208 GIT binary patch literal 1849 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