From 9df2467deb3dc9a82e93b8c99e23c77d7a47c691 Mon Sep 17 00:00:00 2001 From: "cristiano.hoshikawa" Date: Thu, 20 Aug 2026 09:22:03 -0300 Subject: [PATCH] bugfix: route stickness precedences (transaction in the same intent) --- .idea/vcs.xml | 6 + .idea/workspace.xml | 194 ++++ .pytest_cache/v/cache/lastfailed | 7 + .pytest_cache/v/cache/nodeids | 291 ++++++ README.md | 4 + agent_framework_oci/.env | 207 ++++ .../.idea/agent_platform_oci.iml | 16 + agent_framework_oci/.idea/modules.xml | 8 + agent_framework_oci/.idea/vcs.xml | 6 + agent_framework_oci/.idea/workspace.xml | 130 +++ .../IMPLEMENTACAO_WORKFLOWS_TRANSACIONAIS.md | 64 ++ .../Documentacao/Implementando_Basic_Auth.md | 987 ++++++++++++++++++ .../app/agents/runtime.py | 3 + .../app/presentation/__init__.py | 3 + .../tool_renderers.cpython-313.pyc | Bin 0 -> 4405 bytes .../app/presentation/tool_renderers.py | 74 ++ .../config/mcp_parameter_mapping.yaml | 12 + .../config/routing.yaml | 19 + .../config/tool_policies.yaml | 6 + .../config/tools.yaml | 29 + .../app/presentation/__init__.py | 3 + .../tool_renderers.cpython-313.pyc | Bin 0 -> 4412 bytes .../app/presentation/tool_renderers.py | 74 ++ .../config/mcp_parameter_mapping.yaml | 12 + .../config/routing.yaml | 19 + .../config/tool_policies.yaml | 6 + .../agent_template_backend/config/tools.yaml | 29 + .../app/agents/runtime.py | 3 + .../app/presentation/__init__.py | 3 + .../tool_renderers.cpython-313.pyc | Bin 0 -> 4402 bytes .../app/presentation/tool_renderers.py | 74 ++ .../config/mcp_parameter_mapping.yaml | 12 + .../config/routing.yaml | 19 + .../config/tool_policies.yaml | 6 + .../agent_template_backend/config/tools.yaml | 29 + .../app/agents/runtime.py | 3 + .../app/presentation/__init__.py | 3 + .../tool_renderers.cpython-313.pyc | Bin 0 -> 4392 bytes .../app/presentation/tool_renderers.py | 74 ++ .../config/mcp_parameter_mapping.yaml | 12 + .../config/routing.yaml | 19 + .../config/tool_policies.yaml | 6 + .../agent_template_backend/config/tools.yaml | 29 + .../config/mcp_parameter_mapping.yaml | 12 + .../config/routing.yaml | 19 + .../config/tool_policies.yaml | 6 + .../config/tools.yaml | 17 + .../Offline_Workflow_Regression/README.md | 2 +- .../app/agents/runtime.py | 3 + .../app/presentation/__init__.py | 3 + .../tool_renderers.cpython-313.pyc | Bin 0 -> 4401 bytes .../app/presentation/tool_renderers.py | 74 ++ .../config/mcp_parameter_mapping.yaml | 12 + .../config/routing.yaml | 19 + .../config/tool_policies.yaml | 6 + .../agent_template_backend/config/tools.yaml | 29 + .../config/mcp_parameter_mapping.yaml | 12 + .../config/routing.yaml | 19 + .../config/tool_policies.yaml | 6 + .../config/tools.yaml | 17 + .../governance_middleware.cpython-313.pyc | Bin 0 -> 4700 bytes .../app/__pycache__/main.cpython-313.pyc | Bin 0 -> 17489 bytes .../app/__pycache__/settings.cpython-313.pyc | Bin 0 -> 3272 bytes .../governance_loader.cpython-313.pyc | Bin 0 -> 925 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 0 -> 142 bytes .../__pycache__/audit.cpython-313.pyc | Bin 0 -> 934 bytes .../evaluation_hooks.cpython-313.pyc | Bin 0 -> 881 bytes .../model_policies.cpython-313.pyc | Bin 0 -> 3383 bytes .../__pycache__/rate_limit.cpython-313.pyc | Bin 0 -> 2594 bytes .../__pycache__/usage.cpython-313.pyc | Bin 0 -> 963 bytes .../governed_proxy_example.cpython-313.pyc | Bin 0 -> 2404 bytes .../app/__pycache__/__init__.cpython-313.pyc | Bin 0 -> 129 bytes .../app/__pycache__/main.cpython-313.pyc | Bin 0 -> 28096 bytes .../docs/features/01_authentication.md | 165 +++ ...02_deterministic_transactional_workflow.md | 183 ++++ .../03_domain_requested_llm_composition.md | 157 +++ .../docs/features/04_domain_requested_rag.md | 167 +++ .../docs/features/05_long_term_memory.md | 167 +++ .../06_offline_workflow_regression.md | 163 +++ .../docs/features/07_pause_resume_workflow.md | 165 +++ .../docs/features/08_route_stickiness.md | 151 +++ .../features/09_voice_interruption_replay.md | 153 +++ .../features/10_workflow_error_recovery.md | 167 +++ .../docs/features/11_clarification.md | 169 +++ .../docs/features/12_durable_idempotency.md | 163 +++ .../features/13_dynamic_transaction_states.md | 157 +++ .../features/14_post_finalization_replay.md | 159 +++ .../features/15_retrieval_tool_guardrails.md | 171 +++ agent_framework_oci/docs/features/README.md | 64 +- .../__pycache__/__init__.cpython-313.pyc | Bin 424 -> 427 bytes .../gateway_policy_context.cpython-313.pyc | Bin 0 -> 1433 bytes .../__pycache__/idempotency.cpython-313.pyc | Bin 5708 -> 5711 bytes .../__pycache__/observer.cpython-313.pyc | Bin 17568 -> 17571 bytes ...untime_mcp_gateway_adapter.cpython-313.pyc | Bin 0 -> 2130 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 560 -> 563 bytes .../composite_publisher.cpython-313.pyc | Bin 2515 -> 2518 bytes .../__pycache__/event_builder.cpython-313.pyc | Bin 1273 -> 1276 bytes .../__pycache__/factory.cpython-313.pyc | Bin 4009 -> 4012 bytes .../__pycache__/publisher.cpython-313.pyc | Bin 1885 -> 1888 bytes .../tim_payload_mapper.cpython-313.pyc | Bin 9299 -> 9302 bytes .../__pycache__/tim_sequence.cpython-313.pyc | Bin 17577 -> 17577 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 530 -> 530 bytes .../__pycache__/kafka.cpython-313.pyc | Bin 1828 -> 1828 bytes .../__pycache__/langfuse.cpython-313.pyc | Bin 22399 -> 22399 bytes .../__pycache__/oci_streaming.cpython-313.pyc | Bin 1837 -> 1837 bytes .../__pycache__/pubsub.cpython-313.pyc | Bin 7456 -> 7456 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 416 -> 419 bytes .../usage_repository.cpython-313.pyc | Bin 15699 -> 15702 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 226 -> 229 bytes .../cache/__pycache__/cache.cpython-313.pyc | Bin 16536 -> 16539 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 229 -> 232 bytes .../__pycache__/adapters.cpython-313.pyc | Bin 4185 -> 4188 bytes .../channels/__pycache__/base.cpython-313.pyc | Bin 1809 -> 1812 bytes .../__pycache__/gateway.cpython-313.pyc | Bin 5784 -> 5787 bytes .../__pycache__/interruption.cpython-313.pyc | Bin 6469 -> 6472 bytes .../__pycache__/transcription.cpython-313.pyc | Bin 1442 -> 1445 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 936 -> 939 bytes .../checkpoint_repository.cpython-313.pyc | Bin 27176 -> 27179 bytes .../langgraph_saver.cpython-313.pyc | Bin 12847 -> 11254 bytes .../checkpoints/langgraph_saver.py | 122 +-- .../__pycache__/__init__.cpython-313.pyc | Bin 227 -> 230 bytes .../agent_registry.cpython-313.pyc | Bin 6960 -> 6963 bytes .../__pycache__/settings.cpython-313.pyc | Bin 12582 -> 12585 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 0 -> 156 bytes .../__pycache__/oci_streaming.cpython-313.pyc | Bin 0 -> 3260 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 319 -> 322 bytes .../mcp_gateway_client.cpython-313.pyc | Bin 3345 -> 3348 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 0 -> 662 bytes .../__pycache__/client.cpython-313.pyc | Bin 0 -> 4552 bytes .../__pycache__/config.cpython-313.pyc | Bin 0 -> 4987 bytes .../__pycache__/models.cpython-313.pyc | Bin 0 -> 4480 bytes .../__pycache__/router.cpython-313.pyc | Bin 0 -> 14761 bytes .../__pycache__/session_store.cpython-313.pyc | Bin 0 -> 3471 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 1514 -> 1517 bytes .../__pycache__/base.cpython-313.pyc | Bin 1388 -> 1391 bytes .../__pycache__/config_loader.cpython-313.pyc | Bin 7262 -> 7265 bytes .../__pycache__/custom_rails.cpython-313.pyc | Bin 4412 -> 4412 bytes .../__pycache__/executor.cpython-313.pyc | Bin 0 -> 295 bytes .../framework_llm_client.cpython-313.pyc | Bin 18079 -> 18079 bytes .../langgraph_adapters.cpython-313.pyc | Bin 0 -> 3763 bytes .../__pycache__/llm_rails.cpython-313.pyc | Bin 6658 -> 6658 bytes .../output_supervisor.cpython-313.pyc | Bin 16119 -> 16119 bytes .../parallel_executor.cpython-313.pyc | Bin 19924 -> 19927 bytes .../__pycache__/pipeline.cpython-313.pyc | Bin 10902 -> 10905 bytes .../__pycache__/rail_action.cpython-313.pyc | Bin 667 -> 670 bytes .../__pycache__/rail_decision.cpython-313.pyc | Bin 1621 -> 1621 bytes .../__pycache__/rail_result.cpython-313.pyc | Bin 1017 -> 1020 bytes .../__pycache__/rails.cpython-313.pyc | Bin 34730 -> 31612 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 2975 -> 2978 bytes .../__pycache__/_compat.cpython-313.pyc | Bin 2458 -> 2461 bytes .../__pycache__/config.cpython-313.pyc | Bin 0 -> 7579 bytes .../contestation_validation.cpython-313.pyc | Bin 21158 -> 22870 bytes .../__pycache__/contracts.cpython-313.pyc | Bin 6905 -> 6905 bytes .../__pycache__/input_size.cpython-313.pyc | Bin 3559 -> 3562 bytes .../__pycache__/llm_adapter.cpython-313.pyc | Bin 3815 -> 3815 bytes .../__pycache__/llm_client.cpython-313.pyc | Bin 7346 -> 7349 bytes .../__pycache__/llm_rails.cpython-313.pyc | Bin 8894 -> 8897 bytes .../output_sanitization.cpython-313.pyc | Bin 13926 -> 13926 bytes .../__pycache__/pipeline.cpython-313.pyc | Bin 12667 -> 12667 bytes .../calibrated/contestation_validation.py | 44 +- .../__pycache__/__init__.cpython-313.pyc | Bin 486 -> 489 bytes .../__pycache__/_context.cpython-313.pyc | Bin 5391 -> 5391 bytes .../ausencia_oferta_proativa.cpython-313.pyc | Bin 9577 -> 9580 bytes .../__pycache__/coerencia.cpython-313.pyc | Bin 9496 -> 9496 bytes .../__pycache__/dlex_in.cpython-313.pyc | Bin 1320 -> 1320 bytes .../__pycache__/dlex_out.cpython-313.pyc | Bin 1607 -> 1607 bytes .../__pycache__/fallback.cpython-313.pyc | Bin 17205 -> 17205 bytes .../__pycache__/fraseologia.cpython-313.pyc | Bin 6068 -> 6068 bytes .../__pycache__/out_of_scope.cpython-313.pyc | Bin 17099 -> 17099 bytes .../prompts/__pycache__/pinj.cpython-313.pyc | Bin 8323 -> 8323 bytes .../__pycache__/ragsec.cpython-313.pyc | Bin 1121 -> 1121 bytes .../__pycache__/revprec.cpython-313.pyc | Bin 5419 -> 5422 bytes .../__pycache__/safe_out.cpython-313.pyc | Bin 0 -> 984 bytes .../prompts/__pycache__/tox.cpython-313.pyc | Bin 645 -> 645 bytes .../toxicidade_output.cpython-313.pyc | Bin 939 -> 939 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 0 -> 581 bytes .../supervision_template.cpython-313.pyc | Bin 0 -> 2160 bytes .../__pycache__/tts_rules.cpython-313.pyc | Bin 0 -> 1115 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 1683 -> 1683 bytes .../rails/__pycache__/alcada.cpython-313.pyc | Bin 5015 -> 5015 bytes .../rails/__pycache__/anatel.cpython-313.pyc | Bin 9164 -> 9164 bytes .../__pycache__/confirmation.cpython-313.pyc | Bin 11032 -> 11032 bytes .../rails/__pycache__/dlex_in.cpython-313.pyc | Bin 3295 -> 3295 bytes .../__pycache__/dlex_out.cpython-313.pyc | Bin 3347 -> 3347 bytes .../rails/__pycache__/ragsec.cpython-313.pyc | Bin 5429 -> 5429 bytes .../rails/__pycache__/revprec.cpython-313.pyc | Bin 5437 -> 5437 bytes .../rails/__pycache__/tox.cpython-313.pyc | Bin 8252 -> 8252 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 0 -> 5685 bytes .../correspondencia_item.cpython-313.pyc | Bin 0 -> 9012 bytes .../__pycache__/groundedness.cpython-313.pyc | Bin 0 -> 8512 bytes .../intencao_cancelar.cpython-313.pyc | Bin 0 -> 9170 bytes .../quantidade_coerente.cpython-313.pyc | Bin 0 -> 8954 bytes .../servico_correto.cpython-313.pyc | Bin 0 -> 8662 bytes .../verbalizacao_prematura.cpython-313.pyc | Bin 0 -> 8497 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 553 -> 553 bytes .../rules/__pycache__/alcada.cpython-313.pyc | Bin 1897 -> 1897 bytes .../__pycache__/oos_blocklist.cpython-313.pyc | Bin 0 -> 3002 bytes .../__pycache__/pinj_patterns.cpython-313.pyc | Bin 3738 -> 3738 bytes .../__pycache__/tox_blocklist.cpython-313.pyc | Bin 1522 -> 1522 bytes .../src/agent_framework/guardrails/rails.py | 62 +- .../__pycache__/__init__.cpython-313.pyc | Bin 421 -> 424 bytes .../__pycache__/mcp_mapper.cpython-313.pyc | Bin 4705 -> 4708 bytes .../__pycache__/models.cpython-313.pyc | Bin 3157 -> 3160 bytes .../__pycache__/resolver.cpython-313.pyc | Bin 4726 -> 4729 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 634 -> 634 bytes .../judges/__pycache__/judge.cpython-313.pyc | Bin 36448 -> 36448 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 241 -> 241 bytes .../__pycache__/_compat.cpython-313.pyc | Bin 0 -> 2207 bytes .../__pycache__/llm_client.cpython-313.pyc | Bin 6118 -> 6118 bytes .../__pycache__/models.cpython-313.pyc | Bin 0 -> 880 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 249 -> 249 bytes .../prompts/__pycache__/aluc.cpython-313.pyc | Bin 6464 -> 6464 bytes .../prompts/__pycache__/csi.cpython-313.pyc | Bin 1333 -> 1333 bytes .../__pycache__/fallback.cpython-313.pyc | Bin 8029 -> 8029 bytes .../prompts/__pycache__/rqlt.cpython-313.pyc | Bin 1171 -> 1171 bytes .../prompts/__pycache__/vctn.cpython-313.pyc | Bin 642 -> 642 bytes .../llm/__pycache__/__init__.cpython-313.pyc | Bin 224 -> 227 bytes .../llm/__pycache__/base.cpython-313.pyc | Bin 832 -> 835 bytes .../profile_resolver.cpython-313.pyc | Bin 9292 -> 9295 bytes .../llm/__pycache__/providers.cpython-313.pyc | Bin 35979 -> 35982 bytes .../mcp/__pycache__/__init__.cpython-313.pyc | Bin 486 -> 489 bytes .../mcp/__pycache__/client.cpython-313.pyc | Bin 18439 -> 18442 bytes .../mcp/__pycache__/models.cpython-313.pyc | Bin 2095 -> 2116 bytes .../mcp/__pycache__/registry.cpython-313.pyc | Bin 4709 -> 4750 bytes .../__pycache__/tool_policy.cpython-313.pyc | Bin 4750 -> 4753 bytes .../__pycache__/tool_router.cpython-313.pyc | Bin 14031 -> 14034 bytes .../src/agent_framework/mcp/models.py | 5 + .../src/agent_framework/mcp/registry.py | 1 + .../__pycache__/__init__.cpython-313.pyc | Bin 1148 -> 1151 bytes .../long_term_extractor.cpython-313.pyc | Bin 2529 -> 2529 bytes .../long_term_memory.cpython-313.pyc | Bin 6855 -> 6855 bytes .../long_term_models.cpython-313.pyc | Bin 1764 -> 1764 bytes .../long_term_store.cpython-313.pyc | Bin 29202 -> 29202 bytes .../message_history.cpython-313.pyc | Bin 8372 -> 8375 bytes .../summary_memory.cpython-313.pyc | Bin 12523 -> 12520 bytes .../__pycache__/summary_store.cpython-313.pyc | Bin 9533 -> 9530 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 227 -> 224 bytes .../__pycache__/identity.cpython-313.pyc | Bin 3478 -> 3481 bytes .../__pycache__/session.cpython-313.pyc | Bin 2721 -> 2718 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 1407 -> 1410 bytes .../__pycache__/context.cpython-313.pyc | Bin 7399 -> 7402 bytes .../control_events.cpython-313.pyc | Bin 0 -> 2016 bytes .../__pycache__/decorators.cpython-313.pyc | Bin 0 -> 1727 bytes .../__pycache__/event_bus.cpython-313.pyc | Bin 3645 -> 3648 bytes .../__pycache__/grl_events.cpython-313.pyc | Bin 0 -> 437 bytes .../guardrail_events.cpython-313.pyc | Bin 2063 -> 2066 bytes .../__pycache__/ic_events.cpython-313.pyc | Bin 638 -> 641 bytes .../informational_events.cpython-313.pyc | Bin 0 -> 407 bytes .../__pycache__/judge_events.cpython-313.pyc | Bin 1423 -> 1426 bytes .../langfuse_enterprise.cpython-313.pyc | Bin 0 -> 3716 bytes .../langgraph_telemetry.cpython-313.pyc | Bin 4976 -> 4979 bytes .../__pycache__/llm_advisors.cpython-313.pyc | Bin 2950 -> 2953 bytes .../__pycache__/noc_contract.cpython-313.pyc | Bin 5087 -> 5090 bytes .../__pycache__/noc_events.cpython-313.pyc | Bin 0 -> 548 bytes .../__pycache__/noc_otel.cpython-313.pyc | Bin 6334 -> 6337 bytes .../__pycache__/observer.cpython-313.pyc | Bin 4706 -> 4709 bytes .../__pycache__/otel.cpython-313.pyc | Bin 3424 -> 3427 bytes .../streaming_events.cpython-313.pyc | Bin 1847 -> 1850 bytes .../streaming_exporter.cpython-313.pyc | Bin 0 -> 1295 bytes .../__pycache__/telemetry.cpython-313.pyc | Bin 51535 -> 51538 bytes .../tim_backoffice_contract.cpython-313.pyc | Bin 0 -> 1736 bytes .../__pycache__/token_cost.cpython-313.pyc | Bin 8609 -> 8612 bytes .../workflow_events.cpython-313.pyc | Bin 3342 -> 3345 bytes .../oci/__pycache__/__init__.cpython-313.pyc | Bin 227 -> 227 bytes .../oci/__pycache__/auth.cpython-313.pyc | Bin 3259 -> 3259 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 232 -> 229 bytes .../__pycache__/mongodb_store.cpython-313.pyc | Bin 0 -> 7621 bytes .../__pycache__/oracle_store.cpython-313.pyc | Bin 44971 -> 44971 bytes .../__pycache__/sqlite_store.cpython-313.pyc | Bin 15031 -> 15028 bytes .../agent_framework/presentation/__init__.py | 15 + .../__pycache__/__init__.cpython-313.pyc | Bin 0 -> 465 bytes .../__pycache__/renderers.cpython-313.pyc | Bin 0 -> 4328 bytes .../agent_framework/presentation/renderers.py | 104 ++ .../rag/__pycache__/__init__.cpython-313.pyc | Bin 725 -> 725 bytes .../embedding_provider.cpython-313.pyc | Bin 6542 -> 6542 bytes .../__pycache__/graph_store.cpython-313.pyc | Bin 5543 -> 5543 bytes .../rag/__pycache__/ingest.cpython-313.pyc | Bin 12596 -> 12596 bytes .../__pycache__/rag_service.cpython-313.pyc | Bin 10065 -> 10065 bytes .../__pycache__/vector_store.cpython-313.pyc | Bin 18671 -> 18671 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 233 -> 236 bytes .../session_repository.cpython-313.pyc | Bin 8602 -> 8605 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 441 -> 405 bytes .../__pycache__/config_loader.cpython-313.pyc | Bin 2312 -> 2276 bytes .../__pycache__/continuity.cpython-313.pyc | Bin 13254 -> 13218 bytes .../enterprise_router.cpython-313.pyc | Bin 14298 -> 14210 bytes .../__pycache__/models.cpython-313.pyc | Bin 2462 -> 2426 bytes .../routing/enterprise_router.py | 1 - .../__pycache__/__init__.cpython-313.pyc | Bin 364 -> 358 bytes .../__pycache__/agent_runtime.cpython-313.pyc | Bin 110529 -> 128150 bytes .../agent_framework/runtime/agent_runtime.py | 488 ++++++++- .../__pycache__/__init__.cpython-313.pyc | Bin 0 -> 1188 bytes .../authentication.cpython-313.pyc | Bin 0 -> 15408 bytes .../__pycache__/factory.cpython-313.pyc | Bin 0 -> 7977 bytes .../__pycache__/installer.cpython-313.pyc | Bin 0 -> 5595 bytes .../__pycache__/middleware.cpython-313.pyc | Bin 0 -> 8879 bytes .../sse/__pycache__/__init__.cpython-313.pyc | Bin 224 -> 227 bytes .../sse/__pycache__/events.cpython-313.pyc | Bin 9600 -> 9603 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 234 -> 234 bytes .../router_supervisor.cpython-313.pyc | Bin 0 -> 353 bytes .../__pycache__/supervisor.cpython-313.pyc | Bin 4704 -> 4704 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 891 -> 888 bytes .../__pycache__/graph.cpython-313.pyc | Bin 1428 -> 1425 bytes .../__pycache__/models.cpython-313.pyc | Bin 5245 -> 5242 bytes .../__pycache__/registry.cpython-313.pyc | Bin 2374 -> 2371 bytes .../__pycache__/repository.cpython-313.pyc | Bin 2727 -> 2724 bytes .../__pycache__/runtime.cpython-313.pyc | Bin 28933 -> 29137 bytes .../__pycache__/tool_executor.cpython-313.pyc | Bin 1979 -> 1976 bytes .../src/agent_framework/workflows/runtime.py | 19 +- .../mcp/servers/retail_mcp_server/main.py | 11 + .../servers/retail_mcp_server/main_fastmcp.py | 10 + .../app/__pycache__/__init__.cpython-313.pyc | Bin 0 -> 145 bytes .../app/__pycache__/main.cpython-313.pyc | Bin 0 -> 32297 bytes ...mcp_gateway_client_factory.cpython-313.pyc | Bin 0 -> 993 bytes .../app/__pycache__/state.cpython-313.pyc | Bin 0 -> 2526 bytes .../__pycache__/billing_agent.cpython-313.pyc | Bin 0 -> 5216 bytes .../__pycache__/orders_agent.cpython-313.pyc | Bin 0 -> 5124 bytes .../__pycache__/product_agent.cpython-313.pyc | Bin 0 -> 5240 bytes .../__pycache__/prompting.cpython-313.pyc | Bin 0 -> 1142 bytes .../__pycache__/runtime.cpython-313.pyc | Bin 0 -> 344 bytes .../__pycache__/support_agent.cpython-313.pyc | Bin 0 -> 5136 bytes .../app/agents/runtime.py | 3 + .../__pycache__/__init__.cpython-313.pyc | Bin 0 -> 216 bytes .../__pycache__/grl_examples.cpython-313.pyc | Bin 0 -> 1798 bytes .../__pycache__/ic_examples.cpython-313.pyc | Bin 0 -> 1754 bytes .../__pycache__/mcp_examples.cpython-313.pyc | Bin 0 -> 1896 bytes .../__pycache__/noc_examples.cpython-313.pyc | Bin 0 -> 1843 bytes .../observer_examples.cpython-313.pyc | Bin 0 -> 1352 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 0 -> 159 bytes .../telemetry_observer.cpython-313.pyc | Bin 0 -> 4770 bytes .../app/presentation/__init__.py | 3 + .../tool_renderers.cpython-313.pyc | Bin 0 -> 4366 bytes .../app/presentation/tool_renderers.py | 74 ++ .../__pycache__/__init__.cpython-313.pyc | Bin 0 -> 199 bytes .../__pycache__/devolucao.cpython-313.pyc | Bin 0 -> 977 bytes .../__pycache__/agent_graph.cpython-313.pyc | Bin 0 -> 54222 bytes .../config/mcp_parameter_mapping.yaml | 12 + .../config/routing.yaml | 19 + .../config/tool_policies.yaml | 6 + .../agent_template_backend/config/tools.yaml | 29 + .../app/__pycache__/__init__.cpython-313.pyc | Bin 0 -> 186 bytes .../app/__pycache__/main.cpython-313.pyc | Bin 0 -> 31083 bytes ...mcp_gateway_client_factory.cpython-313.pyc | Bin 0 -> 1034 bytes .../app/__pycache__/state.cpython-313.pyc | Bin 0 -> 1918 bytes .../__pycache__/billing_agent.cpython-313.pyc | Bin 0 -> 2541 bytes .../__pycache__/orders_agent.cpython-313.pyc | Bin 0 -> 2459 bytes .../__pycache__/product_agent.cpython-313.pyc | Bin 0 -> 2564 bytes .../__pycache__/prompting.cpython-313.pyc | Bin 0 -> 1183 bytes .../__pycache__/runtime.cpython-313.pyc | Bin 0 -> 385 bytes .../__pycache__/support_agent.cpython-313.pyc | Bin 0 -> 2461 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 0 -> 200 bytes .../telemetry_observer.cpython-313.pyc | Bin 0 -> 4811 bytes .../__pycache__/agent_graph.cpython-313.pyc | Bin 0 -> 44732 bytes .../config/mcp_parameter_mapping.yaml | 12 + .../config/routing.yaml | 19 + .../config/tool_policies.yaml | 6 + .../config/tools.yaml | 17 + .../conftest.cpython-313-pytest-9.0.2.pyc | Bin 789 -> 817 bytes ..._presentation.cpython-313-pytest-9.0.2.pyc | Bin 0 -> 5905 bytes ...ction_runtime.cpython-313-pytest-9.0.2.pyc | Bin 0 -> 8824 bytes ...saction_shift.cpython-313-pytest-9.0.2.pyc | Bin 0 -> 10512 bytes ...nal_tool_flow.cpython-313-pytest-9.0.2.pyc | Bin 0 -> 30594 bytes ...test_generic_tool_response_presentation.py | 72 ++ .../test_mcp_parameter_extraction_runtime.py | 51 + ...test_route_stickiness_transaction_shift.py | 82 ++ .../tests/test_transactional_tool_flow.py | 199 ++++ ...ckpoint_saver.cpython-313-pytest-9.0.2.pyc | Bin 0 -> 7140 bytes ..._checkpointer.cpython-313-pytest-9.0.2.pyc | Bin 0 -> 5311 bytes ...te_stickiness.cpython-313-pytest-9.0.2.pyc | Bin 0 -> 26265 bytes app/__pycache__/state.cpython-313.pyc | Bin 0 -> 2723 bytes .../contas_prompting.cpython-313.pyc | Bin 0 -> 1076 bytes .../contestacao_agent.cpython-313.pyc | Bin 0 -> 5317 bytes .../__pycache__/faturas_agent.cpython-313.pyc | Bin 0 -> 5243 bytes .../__pycache__/prompting.cpython-313.pyc | Bin 0 -> 1163 bytes .../__pycache__/runtime.cpython-313.pyc | Bin 0 -> 444 bytes .../suporte_contas_agent.cpython-313.pyc | Bin 0 -> 5913 bytes .../__pycache__/vas_agent.cpython-313.pyc | Bin 0 -> 5728 bytes app/agents/runtime.py | 3 + .../__pycache__/__init__.cpython-313.pyc | Bin 0 -> 248 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 0 -> 344 bytes .../contas/__pycache__/client.cpython-313.pyc | Bin 0 -> 43231 bytes .../contestation_rules.cpython-313.pyc | Bin 0 -> 13592 bytes .../__pycache__/ic_tags.cpython-313.pyc | Bin 0 -> 17242 bytes .../informational_context.cpython-313.pyc | Bin 0 -> 3511 bytes .../invoice_context.cpython-313.pyc | Bin 0 -> 16841 bytes .../invoice_models.cpython-313.pyc | Bin 0 -> 1819 bytes .../invoice_resolver.cpython-313.pyc | Bin 0 -> 54205 bytes .../__pycache__/item_matcher.cpython-313.pyc | Bin 0 -> 9932 bytes .../pro_rata_rules.cpython-313.pyc | Bin 0 -> 17689 bytes .../protocol_triplets.cpython-313.pyc | Bin 0 -> 7752 bytes .../__pycache__/rct_policy.cpython-313.pyc | Bin 0 -> 6345 bytes .../__pycache__/service.cpython-313.pyc | Bin 0 -> 19113 bytes .../string_metrics.cpython-313.pyc | Bin 0 -> 6318 bytes .../vas_cancellation_message.cpython-313.pyc | Bin 0 -> 16339 bytes .../__pycache__/vas_variation.cpython-313.pyc | Bin 0 -> 42144 bytes .../workflow_actions.cpython-313.pyc | Bin 0 -> 129646 bytes .../secure_pdf_crypto.cpython-313.pyc | Bin 0 -> 2484 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 0 -> 945 bytes .../__pycache__/bill_parser.cpython-313.pyc | Bin 0 -> 23749 bytes .../bill_processor.cpython-313.pyc | Bin 0 -> 36264 bytes app/domain/contas/service.py | 41 + .../__pycache__/__init__.cpython-313.pyc | Bin 0 -> 180 bytes .../telemetry_observer.cpython-313.pyc | Bin 0 -> 4791 bytes app/presentation/__init__.py | 3 + .../__pycache__/__init__.cpython-313.pyc | Bin 0 -> 267 bytes .../tool_renderers.cpython-313.pyc | Bin 0 -> 5440 bytes app/presentation/tool_renderers.py | 108 ++ .../__pycache__/agent_graph.cpython-313.pyc | Bin 58489 -> 58492 bytes config/mcp_parameter_mapping.yaml | 4 + config/prompts/billing.yaml | 12 + config/prompts/contestation.yaml | 46 +- config/prompts/vas.yaml | 9 + config/routing.yaml | 38 +- config/tools.yaml | 46 +- .../__pycache__/__init__.cpython-313.pyc | Bin 0 -> 173 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 0 -> 181 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 0 -> 199 bytes .../__pycache__/main.cpython-313.pyc | Bin 0 -> 59713 bytes contas_mcp/servers/contas_mcp_server/main.py | 133 ++- data/agent_framework.db | Bin 0 -> 20480 bytes .../conftest.cpython-313-pytest-9.0.2.pyc | Bin 0 -> 854 bytes ...ntract_parity.cpython-313-pytest-9.0.2.pyc | Bin 0 -> 37569 bytes ...nd_guardrails.cpython-313-pytest-9.0.2.pyc | Bin 0 -> 4284 bytes ...s_domain_mock.cpython-313-pytest-9.0.2.pyc | Bin 0 -> 64332 bytes ...ss_rules_full.cpython-313-pytest-9.0.2.pyc | Bin 0 -> 23212 bytes ...ilure_mapping.cpython-313-pytest-9.0.2.pyc | Bin 0 -> 7689 bytes ...ive_structure.cpython-313-pytest-9.0.2.pyc | Bin 0 -> 18987 bytes ...subject_guard.cpython-313-pytest-9.0.2.pyc | Bin 0 -> 9000 bytes ...on_validation.cpython-313-pytest-9.0.2.pyc | Bin 0 -> 42861 bytes ...n_adversarial.cpython-313-pytest-9.0.2.pyc | Bin 0 -> 43326 bytes ...eration_types.cpython-313-pytest-9.0.2.pyc | Bin 0 -> 6165 bytes ...onse_renderer.cpython-313-pytest-9.0.2.pyc | Bin 0 -> 4433 bytes .../test_mcp_contestation_subject_guard.py | 72 ++ .../test_original_contestation_validation.py | 76 ++ tests/migration/test_vas_response_renderer.py | 24 + 434 files changed, 7098 insertions(+), 281 deletions(-) create mode 100644 .idea/vcs.xml create mode 100644 .idea/workspace.xml create mode 100644 .pytest_cache/v/cache/lastfailed create mode 100644 .pytest_cache/v/cache/nodeids create mode 100644 agent_framework_oci/.env create mode 100644 agent_framework_oci/.idea/agent_platform_oci.iml create mode 100644 agent_framework_oci/.idea/modules.xml create mode 100644 agent_framework_oci/.idea/vcs.xml create mode 100644 agent_framework_oci/.idea/workspace.xml create mode 100644 agent_framework_oci/Documentacao/IMPLEMENTACAO_WORKFLOWS_TRANSACIONAIS.md create mode 100644 agent_framework_oci/Documentacao/Implementando_Basic_Auth.md create mode 100644 agent_framework_oci/Tuning-Performance/Authentication/agent_template_backend_authentication/app/presentation/__init__.py create mode 100644 agent_framework_oci/Tuning-Performance/Authentication/agent_template_backend_authentication/app/presentation/__pycache__/tool_renderers.cpython-313.pyc create mode 100644 agent_framework_oci/Tuning-Performance/Authentication/agent_template_backend_authentication/app/presentation/tool_renderers.py create mode 100644 agent_framework_oci/Tuning-Performance/Deterministic_Transactional_Workflow/agent_template_backend/app/presentation/__init__.py create mode 100644 agent_framework_oci/Tuning-Performance/Deterministic_Transactional_Workflow/agent_template_backend/app/presentation/__pycache__/tool_renderers.cpython-313.pyc create mode 100644 agent_framework_oci/Tuning-Performance/Deterministic_Transactional_Workflow/agent_template_backend/app/presentation/tool_renderers.py create mode 100644 agent_framework_oci/Tuning-Performance/Long_Term_Memory/templates/agent_template_backend/app/presentation/__init__.py create mode 100644 agent_framework_oci/Tuning-Performance/Long_Term_Memory/templates/agent_template_backend/app/presentation/__pycache__/tool_renderers.cpython-313.pyc create mode 100644 agent_framework_oci/Tuning-Performance/Long_Term_Memory/templates/agent_template_backend/app/presentation/tool_renderers.py create mode 100644 agent_framework_oci/Tuning-Performance/Normal/templates/agent_template_backend/app/presentation/__init__.py create mode 100644 agent_framework_oci/Tuning-Performance/Normal/templates/agent_template_backend/app/presentation/__pycache__/tool_renderers.cpython-313.pyc create mode 100644 agent_framework_oci/Tuning-Performance/Normal/templates/agent_template_backend/app/presentation/tool_renderers.py create mode 100644 agent_framework_oci/Tuning-Performance/Route_Stickness/templates/agent_template_backend/app/presentation/__init__.py create mode 100644 agent_framework_oci/Tuning-Performance/Route_Stickness/templates/agent_template_backend/app/presentation/__pycache__/tool_renderers.cpython-313.pyc create mode 100644 agent_framework_oci/Tuning-Performance/Route_Stickness/templates/agent_template_backend/app/presentation/tool_renderers.py create mode 100644 agent_framework_oci/apps/agent_gateway/app/__pycache__/governance_middleware.cpython-313.pyc create mode 100644 agent_framework_oci/apps/agent_gateway/app/__pycache__/main.cpython-313.pyc create mode 100644 agent_framework_oci/apps/agent_gateway/app/__pycache__/settings.cpython-313.pyc create mode 100644 agent_framework_oci/apps/agent_gateway/app/config/__pycache__/governance_loader.cpython-313.pyc create mode 100644 agent_framework_oci/apps/agent_gateway/app/governance/__pycache__/__init__.cpython-313.pyc create mode 100644 agent_framework_oci/apps/agent_gateway/app/governance/__pycache__/audit.cpython-313.pyc create mode 100644 agent_framework_oci/apps/agent_gateway/app/governance/__pycache__/evaluation_hooks.cpython-313.pyc create mode 100644 agent_framework_oci/apps/agent_gateway/app/governance/__pycache__/model_policies.cpython-313.pyc create mode 100644 agent_framework_oci/apps/agent_gateway/app/governance/__pycache__/rate_limit.cpython-313.pyc create mode 100644 agent_framework_oci/apps/agent_gateway/app/governance/__pycache__/usage.cpython-313.pyc create mode 100644 agent_framework_oci/apps/agent_gateway/app/routes/__pycache__/governed_proxy_example.cpython-313.pyc create mode 100644 agent_framework_oci/apps/mcp_gateway/app/__pycache__/__init__.cpython-313.pyc create mode 100644 agent_framework_oci/apps/mcp_gateway/app/__pycache__/main.cpython-313.pyc create mode 100644 agent_framework_oci/docs/features/01_authentication.md create mode 100644 agent_framework_oci/docs/features/02_deterministic_transactional_workflow.md create mode 100644 agent_framework_oci/docs/features/03_domain_requested_llm_composition.md create mode 100644 agent_framework_oci/docs/features/04_domain_requested_rag.md create mode 100644 agent_framework_oci/docs/features/05_long_term_memory.md create mode 100644 agent_framework_oci/docs/features/06_offline_workflow_regression.md create mode 100644 agent_framework_oci/docs/features/07_pause_resume_workflow.md create mode 100644 agent_framework_oci/docs/features/08_route_stickiness.md create mode 100644 agent_framework_oci/docs/features/09_voice_interruption_replay.md create mode 100644 agent_framework_oci/docs/features/10_workflow_error_recovery.md create mode 100644 agent_framework_oci/docs/features/11_clarification.md create mode 100644 agent_framework_oci/docs/features/12_durable_idempotency.md create mode 100644 agent_framework_oci/docs/features/13_dynamic_transaction_states.md create mode 100644 agent_framework_oci/docs/features/14_post_finalization_replay.md create mode 100644 agent_framework_oci/docs/features/15_retrieval_tool_guardrails.md create mode 100644 agent_framework_oci/libs/agent_framework/src/agent_framework/__pycache__/gateway_policy_context.cpython-313.pyc create mode 100644 agent_framework_oci/libs/agent_framework/src/agent_framework/__pycache__/runtime_mcp_gateway_adapter.cpython-313.pyc create mode 100644 agent_framework_oci/libs/agent_framework/src/agent_framework/events/__pycache__/__init__.cpython-313.pyc create mode 100644 agent_framework_oci/libs/agent_framework/src/agent_framework/events/__pycache__/oci_streaming.cpython-313.pyc create mode 100644 agent_framework_oci/libs/agent_framework/src/agent_framework/global_supervisor/__pycache__/__init__.cpython-313.pyc create mode 100644 agent_framework_oci/libs/agent_framework/src/agent_framework/global_supervisor/__pycache__/client.cpython-313.pyc create mode 100644 agent_framework_oci/libs/agent_framework/src/agent_framework/global_supervisor/__pycache__/config.cpython-313.pyc create mode 100644 agent_framework_oci/libs/agent_framework/src/agent_framework/global_supervisor/__pycache__/models.cpython-313.pyc create mode 100644 agent_framework_oci/libs/agent_framework/src/agent_framework/global_supervisor/__pycache__/router.cpython-313.pyc create mode 100644 agent_framework_oci/libs/agent_framework/src/agent_framework/global_supervisor/__pycache__/session_store.cpython-313.pyc create mode 100644 agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/__pycache__/executor.cpython-313.pyc create mode 100644 agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/__pycache__/langgraph_adapters.cpython-313.pyc create mode 100644 agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/__pycache__/config.cpython-313.pyc create mode 100644 agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/prompts/__pycache__/safe_out.cpython-313.pyc create mode 100644 agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/prompts/shared/__pycache__/__init__.cpython-313.pyc create mode 100644 agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/prompts/shared/__pycache__/supervision_template.cpython-313.pyc create mode 100644 agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/prompts/shared/__pycache__/tts_rules.cpython-313.pyc create mode 100644 agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/rails/supervision/__pycache__/__init__.cpython-313.pyc create mode 100644 agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/rails/supervision/__pycache__/correspondencia_item.cpython-313.pyc create mode 100644 agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/rails/supervision/__pycache__/groundedness.cpython-313.pyc create mode 100644 agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/rails/supervision/__pycache__/intencao_cancelar.cpython-313.pyc create mode 100644 agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/rails/supervision/__pycache__/quantidade_coerente.cpython-313.pyc create mode 100644 agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/rails/supervision/__pycache__/servico_correto.cpython-313.pyc create mode 100644 agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/rails/supervision/__pycache__/verbalizacao_prematura.cpython-313.pyc create mode 100644 agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/rules/__pycache__/oos_blocklist.cpython-313.pyc create mode 100644 agent_framework_oci/libs/agent_framework/src/agent_framework/judges/calibrated/__pycache__/_compat.cpython-313.pyc create mode 100644 agent_framework_oci/libs/agent_framework/src/agent_framework/judges/calibrated/__pycache__/models.cpython-313.pyc create mode 100644 agent_framework_oci/libs/agent_framework/src/agent_framework/observability/__pycache__/control_events.cpython-313.pyc create mode 100644 agent_framework_oci/libs/agent_framework/src/agent_framework/observability/__pycache__/decorators.cpython-313.pyc create mode 100644 agent_framework_oci/libs/agent_framework/src/agent_framework/observability/__pycache__/grl_events.cpython-313.pyc create mode 100644 agent_framework_oci/libs/agent_framework/src/agent_framework/observability/__pycache__/informational_events.cpython-313.pyc create mode 100644 agent_framework_oci/libs/agent_framework/src/agent_framework/observability/__pycache__/langfuse_enterprise.cpython-313.pyc create mode 100644 agent_framework_oci/libs/agent_framework/src/agent_framework/observability/__pycache__/noc_events.cpython-313.pyc create mode 100644 agent_framework_oci/libs/agent_framework/src/agent_framework/observability/__pycache__/streaming_exporter.cpython-313.pyc create mode 100644 agent_framework_oci/libs/agent_framework/src/agent_framework/observability/__pycache__/tim_backoffice_contract.cpython-313.pyc create mode 100644 agent_framework_oci/libs/agent_framework/src/agent_framework/persistence/__pycache__/mongodb_store.cpython-313.pyc create mode 100644 agent_framework_oci/libs/agent_framework/src/agent_framework/presentation/__init__.py create mode 100644 agent_framework_oci/libs/agent_framework/src/agent_framework/presentation/__pycache__/__init__.cpython-313.pyc create mode 100644 agent_framework_oci/libs/agent_framework/src/agent_framework/presentation/__pycache__/renderers.cpython-313.pyc create mode 100644 agent_framework_oci/libs/agent_framework/src/agent_framework/presentation/renderers.py create mode 100644 agent_framework_oci/libs/agent_framework/src/agent_framework/security/__pycache__/__init__.cpython-313.pyc create mode 100644 agent_framework_oci/libs/agent_framework/src/agent_framework/security/__pycache__/authentication.cpython-313.pyc create mode 100644 agent_framework_oci/libs/agent_framework/src/agent_framework/security/__pycache__/factory.cpython-313.pyc create mode 100644 agent_framework_oci/libs/agent_framework/src/agent_framework/security/__pycache__/installer.cpython-313.pyc create mode 100644 agent_framework_oci/libs/agent_framework/src/agent_framework/security/__pycache__/middleware.cpython-313.pyc create mode 100644 agent_framework_oci/libs/agent_framework/src/agent_framework/supervisor/__pycache__/router_supervisor.cpython-313.pyc create mode 100644 agent_framework_oci/templates/agent_template_backend/app/__pycache__/__init__.cpython-313.pyc create mode 100644 agent_framework_oci/templates/agent_template_backend/app/__pycache__/main.cpython-313.pyc create mode 100644 agent_framework_oci/templates/agent_template_backend/app/__pycache__/mcp_gateway_client_factory.cpython-313.pyc create mode 100644 agent_framework_oci/templates/agent_template_backend/app/__pycache__/state.cpython-313.pyc create mode 100644 agent_framework_oci/templates/agent_template_backend/app/agents/__pycache__/billing_agent.cpython-313.pyc create mode 100644 agent_framework_oci/templates/agent_template_backend/app/agents/__pycache__/orders_agent.cpython-313.pyc create mode 100644 agent_framework_oci/templates/agent_template_backend/app/agents/__pycache__/product_agent.cpython-313.pyc create mode 100644 agent_framework_oci/templates/agent_template_backend/app/agents/__pycache__/prompting.cpython-313.pyc create mode 100644 agent_framework_oci/templates/agent_template_backend/app/agents/__pycache__/runtime.cpython-313.pyc create mode 100644 agent_framework_oci/templates/agent_template_backend/app/agents/__pycache__/support_agent.cpython-313.pyc create mode 100644 agent_framework_oci/templates/agent_template_backend/app/examples/__pycache__/__init__.cpython-313.pyc create mode 100644 agent_framework_oci/templates/agent_template_backend/app/examples/__pycache__/grl_examples.cpython-313.pyc create mode 100644 agent_framework_oci/templates/agent_template_backend/app/examples/__pycache__/ic_examples.cpython-313.pyc create mode 100644 agent_framework_oci/templates/agent_template_backend/app/examples/__pycache__/mcp_examples.cpython-313.pyc create mode 100644 agent_framework_oci/templates/agent_template_backend/app/examples/__pycache__/noc_examples.cpython-313.pyc create mode 100644 agent_framework_oci/templates/agent_template_backend/app/examples/__pycache__/observer_examples.cpython-313.pyc create mode 100644 agent_framework_oci/templates/agent_template_backend/app/observability/__pycache__/__init__.cpython-313.pyc create mode 100644 agent_framework_oci/templates/agent_template_backend/app/observability/__pycache__/telemetry_observer.cpython-313.pyc create mode 100644 agent_framework_oci/templates/agent_template_backend/app/presentation/__init__.py create mode 100644 agent_framework_oci/templates/agent_template_backend/app/presentation/__pycache__/tool_renderers.cpython-313.pyc create mode 100644 agent_framework_oci/templates/agent_template_backend/app/presentation/tool_renderers.py create mode 100644 agent_framework_oci/templates/agent_template_backend/app/workflow_actions/__pycache__/__init__.cpython-313.pyc create mode 100644 agent_framework_oci/templates/agent_template_backend/app/workflow_actions/__pycache__/devolucao.cpython-313.pyc create mode 100644 agent_framework_oci/templates/agent_template_backend/app/workflows/__pycache__/agent_graph.cpython-313.pyc create mode 100644 agent_framework_oci/templates/agent_template_backend_day_zero/app/__pycache__/__init__.cpython-313.pyc create mode 100644 agent_framework_oci/templates/agent_template_backend_day_zero/app/__pycache__/main.cpython-313.pyc create mode 100644 agent_framework_oci/templates/agent_template_backend_day_zero/app/__pycache__/mcp_gateway_client_factory.cpython-313.pyc create mode 100644 agent_framework_oci/templates/agent_template_backend_day_zero/app/__pycache__/state.cpython-313.pyc create mode 100644 agent_framework_oci/templates/agent_template_backend_day_zero/app/agents/__pycache__/billing_agent.cpython-313.pyc create mode 100644 agent_framework_oci/templates/agent_template_backend_day_zero/app/agents/__pycache__/orders_agent.cpython-313.pyc create mode 100644 agent_framework_oci/templates/agent_template_backend_day_zero/app/agents/__pycache__/product_agent.cpython-313.pyc create mode 100644 agent_framework_oci/templates/agent_template_backend_day_zero/app/agents/__pycache__/prompting.cpython-313.pyc create mode 100644 agent_framework_oci/templates/agent_template_backend_day_zero/app/agents/__pycache__/runtime.cpython-313.pyc create mode 100644 agent_framework_oci/templates/agent_template_backend_day_zero/app/agents/__pycache__/support_agent.cpython-313.pyc create mode 100644 agent_framework_oci/templates/agent_template_backend_day_zero/app/observability/__pycache__/__init__.cpython-313.pyc create mode 100644 agent_framework_oci/templates/agent_template_backend_day_zero/app/observability/__pycache__/telemetry_observer.cpython-313.pyc create mode 100644 agent_framework_oci/templates/agent_template_backend_day_zero/app/workflows/__pycache__/agent_graph.cpython-313.pyc create mode 100644 agent_framework_oci/tests/__pycache__/test_generic_tool_response_presentation.cpython-313-pytest-9.0.2.pyc create mode 100644 agent_framework_oci/tests/__pycache__/test_mcp_parameter_extraction_runtime.cpython-313-pytest-9.0.2.pyc create mode 100644 agent_framework_oci/tests/__pycache__/test_route_stickiness_transaction_shift.cpython-313-pytest-9.0.2.pyc create mode 100644 agent_framework_oci/tests/__pycache__/test_transactional_tool_flow.cpython-313-pytest-9.0.2.pyc create mode 100644 agent_framework_oci/tests/test_generic_tool_response_presentation.py create mode 100644 agent_framework_oci/tests/unit/__pycache__/test_langgraph_checkpoint_saver.cpython-313-pytest-9.0.2.pyc create mode 100644 agent_framework_oci/tests/unit/__pycache__/test_resilient_checkpointer.cpython-313-pytest-9.0.2.pyc create mode 100644 agent_framework_oci/tests/unit/__pycache__/test_semantic_route_stickiness.cpython-313-pytest-9.0.2.pyc create mode 100644 app/__pycache__/state.cpython-313.pyc create mode 100644 app/agents/__pycache__/contas_prompting.cpython-313.pyc create mode 100644 app/agents/__pycache__/contestacao_agent.cpython-313.pyc create mode 100644 app/agents/__pycache__/faturas_agent.cpython-313.pyc create mode 100644 app/agents/__pycache__/prompting.cpython-313.pyc create mode 100644 app/agents/__pycache__/runtime.cpython-313.pyc create mode 100644 app/agents/__pycache__/suporte_contas_agent.cpython-313.pyc create mode 100644 app/agents/__pycache__/vas_agent.cpython-313.pyc create mode 100644 app/domain/__pycache__/__init__.cpython-313.pyc create mode 100644 app/domain/contas/__pycache__/__init__.cpython-313.pyc create mode 100644 app/domain/contas/__pycache__/client.cpython-313.pyc create mode 100644 app/domain/contas/__pycache__/contestation_rules.cpython-313.pyc create mode 100644 app/domain/contas/__pycache__/ic_tags.cpython-313.pyc create mode 100644 app/domain/contas/__pycache__/informational_context.cpython-313.pyc create mode 100644 app/domain/contas/__pycache__/invoice_context.cpython-313.pyc create mode 100644 app/domain/contas/__pycache__/invoice_models.cpython-313.pyc create mode 100644 app/domain/contas/__pycache__/invoice_resolver.cpython-313.pyc create mode 100644 app/domain/contas/__pycache__/item_matcher.cpython-313.pyc create mode 100644 app/domain/contas/__pycache__/pro_rata_rules.cpython-313.pyc create mode 100644 app/domain/contas/__pycache__/protocol_triplets.cpython-313.pyc create mode 100644 app/domain/contas/__pycache__/rct_policy.cpython-313.pyc create mode 100644 app/domain/contas/__pycache__/service.cpython-313.pyc create mode 100644 app/domain/contas/__pycache__/string_metrics.cpython-313.pyc create mode 100644 app/domain/contas/__pycache__/vas_cancellation_message.cpython-313.pyc create mode 100644 app/domain/contas/__pycache__/vas_variation.cpython-313.pyc create mode 100644 app/domain/contas/__pycache__/workflow_actions.cpython-313.pyc create mode 100644 app/domain/contas/integrations/__pycache__/secure_pdf_crypto.cpython-313.pyc create mode 100644 app/domain/contas/parsers/__pycache__/__init__.cpython-313.pyc create mode 100644 app/domain/contas/parsers/__pycache__/bill_parser.cpython-313.pyc create mode 100644 app/domain/contas/parsers/__pycache__/bill_processor.cpython-313.pyc create mode 100644 app/observability/__pycache__/__init__.cpython-313.pyc create mode 100644 app/observability/__pycache__/telemetry_observer.cpython-313.pyc create mode 100644 app/presentation/__init__.py create mode 100644 app/presentation/__pycache__/__init__.cpython-313.pyc create mode 100644 app/presentation/__pycache__/tool_renderers.cpython-313.pyc create mode 100644 app/presentation/tool_renderers.py create mode 100644 contas_mcp/__pycache__/__init__.cpython-313.pyc create mode 100644 contas_mcp/servers/__pycache__/__init__.cpython-313.pyc create mode 100644 contas_mcp/servers/contas_mcp_server/__pycache__/__init__.cpython-313.pyc create mode 100644 contas_mcp/servers/contas_mcp_server/__pycache__/main.cpython-313.pyc create mode 100644 data/agent_framework.db create mode 100644 tests/migration/__pycache__/conftest.cpython-313-pytest-9.0.2.pyc create mode 100644 tests/migration/__pycache__/test_backend_wrapper_contract_parity.cpython-313-pytest-9.0.2.pyc create mode 100644 tests/migration/__pycache__/test_business_events_and_guardrails.cpython-313-pytest-9.0.2.pyc create mode 100644 tests/migration/__pycache__/test_contas_domain_mock.cpython-313-pytest-9.0.2.pyc create mode 100644 tests/migration/__pycache__/test_contestation_business_rules_full.cpython-313-pytest-9.0.2.pyc create mode 100644 tests/migration/__pycache__/test_contestation_failure_mapping.cpython-313-pytest-9.0.2.pyc create mode 100644 tests/migration/__pycache__/test_framework_native_structure.cpython-313-pytest-9.0.2.pyc create mode 100644 tests/migration/__pycache__/test_mcp_contestation_subject_guard.cpython-313-pytest-9.0.2.pyc create mode 100644 tests/migration/__pycache__/test_original_contestation_validation.cpython-313-pytest-9.0.2.pyc create mode 100644 tests/migration/__pycache__/test_original_vas_variation_adversarial.cpython-313-pytest-9.0.2.pyc create mode 100644 tests/migration/__pycache__/test_tool_policy_operation_types.cpython-313-pytest-9.0.2.pyc create mode 100644 tests/migration/__pycache__/test_vas_response_renderer.cpython-313-pytest-9.0.2.pyc create mode 100644 tests/migration/test_mcp_contestation_subject_guard.py create mode 100644 tests/migration/test_vas_response_renderer.py diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/workspace.xml b/.idea/workspace.xml new file mode 100644 index 0000000..b449673 --- /dev/null +++ b/.idea/workspace.xml @@ -0,0 +1,194 @@ + + + + + + + + + + + + + { + "lastFilter": { + "state": "OPEN", + "assignee": "hoshikawa2" + } +} + { + "selectedUrlAndAccountId": { + "url": "https://github.com/hoshikawa2/agent_platform_oci.git", + "accountId": "bd799ac0-7624-42b2-999a-b96e6e11f98a" + } +} + {} + { + "isMigrated": true +} + + + + { + "customColor": "", + "associatedIndex": 2 +} + + + + { + "keyToString": { + "ASKED_SHARE_PROJECT_CONFIGURATION_FILES": "true", + "ModuleVcsDetector.initialDetectionPerformed": "true", + "RunOnceActivity.ShowReadmeOnStart": "true", + "RunOnceActivity.TerminalTabsStorage.copyFrom.TerminalArrangementManager.252": "true", + "RunOnceActivity.git.unshallow": "true", + "RunOnceActivity.typescript.service.memoryLimit.init": "true", + "SHARE_PROJECT_CONFIGURATION_FILES": "true", + "Shell Script.agent_contas.executor": "Run", + "Shell Script.agent_frontend.executor": "Run", + "Shell Script.agent_template_backend.executor": "Run", + "Shell Script.mcp gateway.executor": "Run", + "Shell Script.mcp servers.executor": "Run", + "git-widget-placeholder": "main", + "kotlin-language-version-configured": "true", + "last_opened_file_path": "D:/MSI_Projects/agent_framework_oci", + "node.js.detected.package.eslint": "true", + "node.js.detected.package.tslint": "true", + "node.js.selected.package.eslint": "(autodetect)", + "node.js.selected.package.tslint": "(autodetect)", + "nodejs_package_manager_path": "npm", + "settings.editor.selected.configurable": "project.propVCSSupport.DirectoryMappings", + "vue.rearranger.settings.migration": "true" + } +} + + + + + + + + + + + + + + + + + + + + + + + 1781996088468 + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.pytest_cache/v/cache/lastfailed b/.pytest_cache/v/cache/lastfailed new file mode 100644 index 0000000..d7b0ed7 --- /dev/null +++ b/.pytest_cache/v/cache/lastfailed @@ -0,0 +1,7 @@ +{ + "agent_framework_oci/tests/unit/test_langgraph_checkpoint_saver.py::test_repository_checkpoint_saver_put_get": true, + "agent_framework_oci/tests/unit/test_resilient_checkpointer.py::test_integrity_envelope_and_recovery_skips_corrupt_latest": true, + "agent_framework_oci/tests/unit/test_resilient_checkpointer.py::test_compaction_keeps_last_n_checkpoints": true, + "agent_framework_oci/tests/unit/test_resilient_checkpointer.py::test_recovery_raises_when_only_corrupt_checkpoints_exist": true, + "agent_framework_oci/tests/unit/test_langgraph_checkpoint_saver.py::test_put_writes_does_not_restore_older_checkpoint": true +} \ No newline at end of file diff --git a/.pytest_cache/v/cache/nodeids b/.pytest_cache/v/cache/nodeids new file mode 100644 index 0000000..4bd5d7b --- /dev/null +++ b/.pytest_cache/v/cache/nodeids @@ -0,0 +1,291 @@ +[ + "agent_framework_oci/tests/test_generic_tool_response_presentation.py::test_generic_lines_mode_preserves_order_shape", + "agent_framework_oci/tests/test_generic_tool_response_presentation.py::test_generic_list_mode_supports_contas_multiple_plans_without_none", + "agent_framework_oci/tests/test_generic_tool_response_presentation.py::test_generic_template_mode_preserves_template_backend_plan_contract", + "agent_framework_oci/tests/test_generic_tool_response_presentation.py::test_missing_renderer_falls_back_without_breaking_runtime", + "agent_framework_oci/tests/test_generic_tool_response_presentation.py::test_no_declared_response_keeps_legacy_fallback", + "agent_framework_oci/tests/test_generic_tool_response_presentation.py::test_renderer_mode_uses_application_registered_renderer", + "agent_framework_oci/tests/test_mcp_parameter_extraction_runtime.py::test_collection_turn_reuses_declarative_parameter_extraction", + "agent_framework_oci/tests/test_mcp_parameter_extraction_runtime.py::test_explicit_order_id_has_precedence_over_contract_key", + "agent_framework_oci/tests/test_mcp_parameter_extraction_runtime.py::test_new_transaction_current_message_overrides_stale_subject_from_context", + "agent_framework_oci/tests/test_mcp_parameter_extraction_runtime.py::test_runtime_extracts_order_id_from_current_message", + "agent_framework_oci/tests/test_mcp_parameter_extraction_runtime.py::test_transaction_extracts_required_fields_before_first_missing_check", + "agent_framework_oci/tests/test_mcp_parameter_extraction_runtime.py::test_unique_transactional_tool_is_selected_after_routing_constrains_allowlist", + "agent_framework_oci/tests/test_route_stickiness_transaction_shift.py::test_explicit_keyword_shift_preempts_stickiness", + "agent_framework_oci/tests/test_route_stickiness_transaction_shift.py::test_same_agent_explicit_intent_shift_must_preempt_stickiness", + "agent_framework_oci/tests/test_route_stickiness_transaction_shift.py::test_same_agent_transaction_keyword_preempts_continuity", + "agent_framework_oci/tests/test_route_stickiness_transaction_shift.py::test_short_generic_keyword_does_not_preempt", + "agent_framework_oci/tests/test_transactional_tool_flow.py::test_closed_transaction_is_not_operational_context_for_next_turn", + "agent_framework_oci/tests/test_transactional_tool_flow.py::test_collecting_parameters_does_not_replace_collected_subject_with_stale_context", + "agent_framework_oci/tests/test_transactional_tool_flow.py::test_new_contestation_does_not_inherit_subject_or_value_from_previous_transaction", + "agent_framework_oci/tests/test_transactional_tool_flow.py::test_runtime_source_contains_persisted_confirmation_contract", + "agent_framework_oci/tests/test_transactional_tool_flow.py::test_terminal_confirmation_closes_active_transaction_and_clears_latches", + "agent_framework_oci/tests/test_transactional_tool_flow.py::test_tool_policy_registry_reads_transactional_confirmation", + "agent_framework_oci/tests/test_transactional_tool_flow.py::test_transaction_waits_then_executes_after_confirmation", + "agent_framework_oci/tests/unit/test_langgraph_checkpoint_saver.py::test_put_writes_does_not_restore_older_checkpoint", + "agent_framework_oci/tests/unit/test_langgraph_checkpoint_saver.py::test_repository_checkpoint_saver_put_get", + "agent_framework_oci/tests/unit/test_resilient_checkpointer.py::test_compaction_keeps_last_n_checkpoints", + "agent_framework_oci/tests/unit/test_resilient_checkpointer.py::test_integrity_envelope_and_recovery_skips_corrupt_latest", + "agent_framework_oci/tests/unit/test_resilient_checkpointer.py::test_recovery_raises_when_only_corrupt_checkpoints_exist", + "agent_framework_oci/tests/unit/test_semantic_route_stickiness.py::test_continue_bypasses_router_without_regex_rules", + "agent_framework_oci/tests/unit/test_semantic_route_stickiness.py::test_continue_without_active_agent_falls_back_to_router", + "agent_framework_oci/tests/unit/test_semantic_route_stickiness.py::test_end_session_is_returned_as_global_route", + "agent_framework_oci/tests/unit/test_semantic_route_stickiness.py::test_global_session_actions_work_without_active_agent", + "agent_framework_oci/tests/unit/test_semantic_route_stickiness.py::test_human_handoff_is_returned_as_global_route", + "agent_framework_oci/tests/unit/test_semantic_route_stickiness.py::test_invalid_output_falls_back_safely", + "agent_framework_oci/tests/unit/test_semantic_route_stickiness.py::test_low_confidence_continue_falls_back_safely", + "agent_framework_oci/tests/unit/test_semantic_route_stickiness.py::test_no_active_agent_still_classifies_global_session_actions", + "agent_framework_oci/tests/unit/test_semantic_route_stickiness.py::test_route_result_falls_back_to_enterprise_router", + "tests/migration/test_backend_wrapper_contract_parity.py::test_cancelamento_aceita_alias_itens_para_contestacao", + "tests/migration/test_backend_wrapper_contract_parity.py::test_cancelamento_aceita_cpf_como_alias_social_sec_no", + "tests/migration/test_backend_wrapper_contract_parity.py::test_cancelamento_falha_operacional_com_candidato_dispara_contestacao", + "tests/migration/test_backend_wrapper_contract_parity.py::test_cancelamento_falha_workflow_preserva_output_parcial_nao_cancelados", + "tests/migration/test_backend_wrapper_contract_parity.py::test_cancelamento_sem_candidatos_nao_dispara_contestacao", + "tests/migration/test_backend_wrapper_contract_parity.py::test_cancelamento_sms_falho_preserva_sucesso_e_flag", + "tests/migration/test_backend_wrapper_contract_parity.py::test_contestacao_wrapper_mapeia_falha_tecnica_como_sistemica", + "tests/migration/test_backend_wrapper_contract_parity.py::test_contestacao_wrapper_preserva_erro_de_negocio_e_protocolo", + "tests/migration/test_backend_wrapper_contract_parity.py::test_contestacao_wrapper_preserva_tipo_atendimento_e_contexto_do_turno", + "tests/migration/test_backend_wrapper_contract_parity.py::test_invoice_explanation_branch_devolver_orquestrador_nao_auto_finaliza", + "tests/migration/test_backend_wrapper_contract_parity.py::test_invoice_explanation_branch_nao_sem_vas_recomenda_nao_resolvido", + "tests/migration/test_backend_wrapper_contract_parity.py::test_invoice_explanation_service_failure_preserva_fraseologia_sem_auto_finalize", + "tests/migration/test_backend_wrapper_contract_parity.py::test_pro_rata_aceite_e_nao_controle_recomendam_resolvido", + "tests/migration/test_backend_wrapper_contract_parity.py::test_pro_rata_branch_devolver_orquestrador_nao_auto_finaliza", + "tests/migration/test_backend_wrapper_contract_parity.py::test_vas_estrategico_rejeitado_declara_rag_para_cada_servico_estrategico", + "tests/migration/test_backend_wrapper_contract_parity.py::test_vas_estrategico_workflow_payload_preserva_tres_itens_e_action_agrupa_duas_linhas", + "tests/migration/test_business_events_and_guardrails.py::test_business_events_are_published_recursively_once", + "tests/migration/test_business_events_and_guardrails.py::test_cached_tool_result_does_not_republish_business_events", + "tests/migration/test_contas_domain_mock.py::test_cancel_vas_is_domain_operation_not_conversation_engine", + "tests/migration/test_contas_domain_mock.py::test_cancelamento_batch_emite_vaa004_quando_falha_operacional", + "tests/migration/test_contas_domain_mock.py::test_cancelamento_batch_emite_vaa_caminho_feliz_uma_vez", + "tests/migration/test_contas_domain_mock.py::test_cancelamento_nao_recancela_servico_inativo_do_historico", + "tests/migration/test_contas_domain_mock.py::test_cancelamento_usa_historico_como_fallback_quando_ativo_nao_encontra", + "tests/migration/test_contas_domain_mock.py::test_contestation_mock", + "tests/migration/test_contas_domain_mock.py::test_finalizacao_com_protocolo_existente_nao_cria_informacional", + "tests/migration/test_contas_domain_mock.py::test_finalizacao_cria_protocolo_informacional_quando_invoice_explanation_executou", + "tests/migration/test_contas_domain_mock.py::test_finalizacao_force_rt15_cria_novo_protocolo_mesmo_com_veb_fechado", + "tests/migration/test_contas_domain_mock.py::test_finalizacao_informacional_cria_protocolo_fechado_sem_duplicar_status", + "tests/migration/test_contas_domain_mock.py::test_finalizacao_informacional_notas_canonicas[types0-Explica\\xe7\\xe3o de VAS Bundle]", + "tests/migration/test_contas_domain_mock.py::test_finalizacao_informacional_notas_canonicas[types1-Explica\\xe7\\xe3o de VAS Estrat\\xe9gico]", + "tests/migration/test_contas_domain_mock.py::test_finalizacao_informacional_notas_canonicas[types2-Explica\\xe7\\xe3o de VAS Avulso]", + "tests/migration/test_contas_domain_mock.py::test_finalizacao_informacional_notas_canonicas[types3-Explica\\xe7\\xe3o de VAS Bundle, VAS Estrat\\xe9gico]", + "tests/migration/test_contas_domain_mock.py::test_finalizacao_informacional_notas_canonicas[types4-Explica\\xe7\\xe3o de VAS Bundle, VAS Avulso]", + "tests/migration/test_contas_domain_mock.py::test_finalizacao_informacional_notas_canonicas[types5-Explica\\xe7\\xe3o de VAS Estrat\\xe9gico, VAS Avulso]", + "tests/migration/test_contas_domain_mock.py::test_finalizacao_informacional_notas_canonicas[types6-Explica\\xe7\\xe3o de VAS Bundle, VAS Estrat\\xe9gico, VAS Avulso]", + "tests/migration/test_contas_domain_mock.py::test_finalizacao_nao_cria_protocolo_apenas_por_prefetch_invoice_explanation", + "tests/migration/test_contas_domain_mock.py::test_finalizacao_nao_duplica_protocolo_quando_contestacao_ja_existe", + "tests/migration/test_contas_domain_mock.py::test_finalizacao_normaliza_status_invalido_e_summary", + "tests/migration/test_contas_domain_mock.py::test_finalizacao_preserva_status_valido_e_prefixa_summary", + "tests/migration/test_contas_domain_mock.py::test_finalizacao_reusa_protocolo_veb_ja_fechado_sem_abrir_outro", + "tests/migration/test_contas_domain_mock.py::test_finalizacao_veb_deferido_suprime_evento_cvn_de_protocolo", + "tests/migration/test_contas_domain_mock.py::test_invoice_explanation_converte_retry_transport_em_rct_por_tentativa", + "tests/migration/test_contas_domain_mock.py::test_invoice_explanation_falha_preserva_rct_das_tres_tentativas", + "tests/migration/test_contas_domain_mock.py::test_read_only_integrations_with_fixtures", + "tests/migration/test_contestation_business_rules_full.py::test_abrir_contestacao_deriva_refund_manual_e_normaliza_barcode_zero", + "tests/migration/test_contestation_business_rules_full.py::test_check_invoice_status_enriquece_prefetch_sem_nova_api", + "tests/migration/test_contestation_business_rules_full.py::test_check_invoice_status_falha_sem_prefetch", + "tests/migration/test_contestation_business_rules_full.py::test_cutdate_da_fatura_define_manual", + "tests/migration/test_contestation_business_rules_full.py::test_cutdate_regra_um_mes", + "tests/migration/test_contestation_business_rules_full.py::test_cutoff_referencia_corrige_bug_mes_seguinte", + "tests/migration/test_contestation_business_rules_full.py::test_dependente_forca_conta_certa_manual", + "tests/migration/test_contestation_business_rules_full.py::test_due_day_iso_e_br", + "tests/migration/test_contestation_business_rules_full.py::test_refund_boleto_para_fatura_em_aberto_com_fatura_normal", + "tests/migration/test_contestation_business_rules_full.py::test_refund_credito_para_dacc_cartao_ou_parcelamento", + "tests/migration/test_contestation_business_rules_full.py::test_refund_credito_para_fatura_paga_ou_ja_contestada", + "tests/migration/test_contestation_failure_mapping.py::test_contestacao_failed_preserva_provider_message_e_protocolo", + "tests/migration/test_contestation_failure_mapping.py::test_contestacao_failed_sem_mensagem_provider_vira_falha_sistemica", + "tests/migration/test_framework_native_structure.py::test_agent_workflow_init_realmente_inicializa_router_agentes_e_graph", + "tests/migration/test_framework_native_structure.py::test_all_active_workflow_actions_registered", + "tests/migration/test_framework_native_structure.py::test_contestacao_workflow_encerra_imediatamente_quando_cval_bloqueia", + "tests/migration/test_framework_native_structure.py::test_domain_does_not_import_langgraph_directly", + "tests/migration/test_framework_native_structure.py::test_guardrail_config_declares_all_execution_stages", + "tests/migration/test_framework_native_structure.py::test_official_templates_use_framework_state_graph", + "tests/migration/test_framework_native_structure.py::test_workflow_runtime_preserva_snapshot_parcial_quando_action_posterior_falha", + "tests/migration/test_mcp_contestation_subject_guard.py::test_correct_subject_is_preserved", + "tests/migration/test_mcp_contestation_subject_guard.py::test_preflight_does_not_replace_explicit_plan_with_vas", + "tests/migration/test_mcp_contestation_subject_guard.py::test_recovers_explicit_contestation_subject_from_original_text", + "tests/migration/test_original_contestation_validation.py::test_contestation_action_calculates_totals_only_for_items_actually_contested", + "tests/migration/test_original_contestation_validation.py::test_contestation_action_classifies_already_contested_and_missing_requested_item", + "tests/migration/test_original_contestation_validation.py::test_validate_contestation_items_aprova_quando_total_ajustes_dentro_do_limite", + "tests/migration/test_original_contestation_validation.py::test_validate_contestation_items_bloqueia_classe_estrategico_canonica", + "tests/migration/test_original_contestation_validation.py::test_validate_contestation_items_bloqueia_item_fora_da_secao_vas", + "tests/migration/test_original_contestation_validation.py::test_validate_contestation_items_bloqueia_item_inexistente", + "tests/migration/test_original_contestation_validation.py::test_validate_contestation_items_bloqueia_quando_total_ajustes_excede_fatura", + "tests/migration/test_original_contestation_validation.py::test_validate_contestation_items_bloqueia_valor_maior_que_o_item", + "tests/migration/test_original_contestation_validation.py::test_validate_contestation_items_bloqueia_vas_estrategico", + "tests/migration/test_original_contestation_validation.py::test_validate_contestation_items_emite_span_quando_aprova", + "tests/migration/test_original_contestation_validation.py::test_validate_contestation_items_emite_spans_quando_bloqueia", + "tests/migration/test_original_contestation_validation.py::test_validate_contestation_items_prefere_evidencia_vas_quando_item_aparece_em_multiplas_visoes", + "tests/migration/test_original_contestation_validation.py::test_validate_contestation_items_reconhece_vas_por_type_do_billing_analysis", + "tests/migration/test_original_contestation_validation.py::test_validate_contestation_items_span_blocked_inclui_contagens", + "tests/migration/test_original_contestation_validation.py::test_validate_contestation_items_usa_classe_avulso_canonica", + "tests/migration/test_original_contestation_validation.py::test_validate_contestation_items_valida_todos_antes_de_retornar", + "tests/migration/test_original_vas_variation_adversarial.py::test_explicacao_sem_data_nao_altera_nenhum_dos_50[A01-fluid-light-x-premium]", + "tests/migration/test_original_vas_variation_adversarial.py::test_explicacao_sem_data_nao_altera_nenhum_dos_50[A02-fluid-premium-x-light]", + "tests/migration/test_original_vas_variation_adversarial.py::test_explicacao_sem_data_nao_altera_nenhum_dos_50[A03-aya-books-x-audiobooks]", + "tests/migration/test_original_vas_variation_adversarial.py::test_explicacao_sem_data_nao_altera_nenhum_dos_50[A04-aya-ensinah-x-books]", + "tests/migration/test_original_vas_variation_adversarial.py::test_explicacao_sem_data_nao_altera_nenhum_dos_50[A05-exa-seguranca-x-cloud]", + "tests/migration/test_original_vas_variation_adversarial.py::test_explicacao_sem_data_nao_altera_nenhum_dos_50[A06-bancah-jornais-x-premium]", + "tests/migration/test_original_vas_variation_adversarial.py::test_explicacao_sem_data_nao_altera_nenhum_dos_50[A07-itgame-light-x-premium]", + "tests/migration/test_original_vas_variation_adversarial.py::test_explicacao_sem_data_nao_altera_nenhum_dos_50[A08-aluguel-filme-1-x-2]", + "tests/migration/test_original_vas_variation_adversarial.py::test_explicacao_sem_data_nao_altera_nenhum_dos_50[A09-tim-games-mensal-x-semanal]", + "tests/migration/test_original_vas_variation_adversarial.py::test_explicacao_sem_data_nao_altera_nenhum_dos_50[A10-kids-plus-x-premium]", + "tests/migration/test_original_vas_variation_adversarial.py::test_explicacao_sem_data_nao_altera_nenhum_dos_50[A11-exa-premium-x-protecao]", + "tests/migration/test_original_vas_variation_adversarial.py::test_explicacao_sem_data_nao_altera_nenhum_dos_50[A12-tim-games-prefixo]", + "tests/migration/test_original_vas_variation_adversarial.py::test_explicacao_sem_data_nao_altera_nenhum_dos_50[A13-fit-app-x-fit-me-app]", + "tests/migration/test_original_vas_variation_adversarial.py::test_explicacao_sem_data_nao_altera_nenhum_dos_50[A14-tim-music-plus-x-premium]", + "tests/migration/test_original_vas_variation_adversarial.py::test_explicacao_sem_data_nao_altera_nenhum_dos_50[A15-kids-prefixo]", + "tests/migration/test_original_vas_variation_adversarial.py::test_explicacao_sem_data_nao_altera_nenhum_dos_50[B01-fitme-16.99-x-17.00]", + "tests/migration/test_original_vas_variation_adversarial.py::test_explicacao_sem_data_nao_altera_nenhum_dos_50[B02-fitme-16.99-x-16.98]", + "tests/migration/test_original_vas_variation_adversarial.py::test_explicacao_sem_data_nao_altera_nenhum_dos_50[B03-fluid-14.99-x-15.00]", + "tests/migration/test_original_vas_variation_adversarial.py::test_explicacao_sem_data_nao_altera_nenhum_dos_50[B04-exa-9.99-x-9.98]", + "tests/migration/test_original_vas_variation_adversarial.py::test_explicacao_sem_data_nao_altera_nenhum_dos_50[B05-fitme-prefixo-valor-errado]", + "tests/migration/test_original_vas_variation_adversarial.py::test_explicacao_sem_data_nao_altera_nenhum_dos_50[B06-aya-24.90-x-24.91]", + "tests/migration/test_original_vas_variation_adversarial.py::test_explicacao_sem_data_nao_altera_nenhum_dos_50[B07-itgame-12.90-x-12.09]", + "tests/migration/test_original_vas_variation_adversarial.py::test_explicacao_sem_data_nao_altera_nenhum_dos_50[B08-fitme-16.99-x-169.90]", + "tests/migration/test_original_vas_variation_adversarial.py::test_explicacao_sem_data_nao_altera_nenhum_dos_50[C01-hbo-secao-terceiros]", + "tests/migration/test_original_vas_variation_adversarial.py::test_explicacao_sem_data_nao_altera_nenhum_dos_50[C02-netflix-em-secao-avulsa]", + "tests/migration/test_original_vas_variation_adversarial.py::test_explicacao_sem_data_nao_altera_nenhum_dos_50[C03-youtube-mis-bucket]", + "tests/migration/test_original_vas_variation_adversarial.py::test_explicacao_sem_data_nao_altera_nenhum_dos_50[C04-deezer-em-secao-avulsa]", + "tests/migration/test_original_vas_variation_adversarial.py::test_explicacao_sem_data_nao_altera_nenhum_dos_50[C05-apple-music-em-secao-avulsa]", + "tests/migration/test_original_vas_variation_adversarial.py::test_explicacao_sem_data_nao_altera_nenhum_dos_50[C06-bundle-incluso]", + "tests/migration/test_original_vas_variation_adversarial.py::test_explicacao_sem_data_nao_altera_nenhum_dos_50[C07-fitme-classificado-estrategico]", + "tests/migration/test_original_vas_variation_adversarial.py::test_explicacao_sem_data_nao_altera_nenhum_dos_50[D01-fitme-dois-candidatos]", + "tests/migration/test_original_vas_variation_adversarial.py::test_explicacao_sem_data_nao_altera_nenhum_dos_50[D02-fitme-tres-candidatos]", + "tests/migration/test_original_vas_variation_adversarial.py::test_explicacao_sem_data_nao_altera_nenhum_dos_50[D03-aya-tres-marcas]", + "tests/migration/test_original_vas_variation_adversarial.py::test_explicacao_sem_data_nao_altera_nenhum_dos_50[D04-mesmo-nome-duas-linhas]", + "tests/migration/test_original_vas_variation_adversarial.py::test_explicacao_sem_data_nao_altera_nenhum_dos_50[D05-duplicata-mesma-linha]", + "tests/migration/test_original_vas_variation_adversarial.py::test_explicacao_sem_data_nao_altera_nenhum_dos_50[D06-fluid-familia]", + "tests/migration/test_original_vas_variation_adversarial.py::test_explicacao_sem_data_nao_altera_nenhum_dos_50[D07-exa-familia]", + "tests/migration/test_original_vas_variation_adversarial.py::test_explicacao_sem_data_nao_altera_nenhum_dos_50[D08-bancah-familia]", + "tests/migration/test_original_vas_variation_adversarial.py::test_explicacao_sem_data_nao_altera_nenhum_dos_50[E01-prefixo-invertido]", + "tests/migration/test_original_vas_variation_adversarial.py::test_explicacao_sem_data_nao_altera_nenhum_dos_50[E02-substring-no-meio]", + "tests/migration/test_original_vas_variation_adversarial.py::test_explicacao_sem_data_nao_altera_nenhum_dos_50[E03-sufixo-games-premium]", + "tests/migration/test_original_vas_variation_adversarial.py::test_explicacao_sem_data_nao_altera_nenhum_dos_50[E04-token-parcial-tube]", + "tests/migration/test_original_vas_variation_adversarial.py::test_explicacao_sem_data_nao_altera_nenhum_dos_50[E05-token-solto-app]", + "tests/migration/test_original_vas_variation_adversarial.py::test_explicacao_sem_data_nao_altera_nenhum_dos_50[E06-fitme-fail-closed-por-padrao]", + "tests/migration/test_original_vas_variation_adversarial.py::test_explicacao_sem_data_nao_altera_nenhum_dos_50[F01-msisdn-ausente]", + "tests/migration/test_original_vas_variation_adversarial.py::test_explicacao_sem_data_nao_altera_nenhum_dos_50[F02-item-na-linha-secundaria]", + "tests/migration/test_original_vas_variation_adversarial.py::test_explicacao_sem_data_nao_altera_nenhum_dos_50[F03-secao-sem-classe]", + "tests/migration/test_original_vas_variation_adversarial.py::test_explicacao_sem_data_nao_altera_nenhum_dos_50[F04-desc-vazia]", + "tests/migration/test_original_vas_variation_adversarial.py::test_explicacao_sem_data_nao_altera_nenhum_dos_50[F05-valor-nao-parseavel]", + "tests/migration/test_original_vas_variation_adversarial.py::test_explicacao_sem_data_nao_altera_nenhum_dos_50[F06-fatura-sem-o-item]", + "tests/migration/test_original_vas_variation_adversarial.py::test_flag_liga_a_segunda_passada_e_so_isso", + "tests/migration/test_original_vas_variation_adversarial.py::test_flag_ligada_nao_reabre_msisdn_nem_ambiguidade", + "tests/migration/test_original_vas_variation_adversarial.py::test_guards_de_prefixo_valem_com_a_flag_ligada[E01-prefixo-invertido]", + "tests/migration/test_original_vas_variation_adversarial.py::test_guards_de_prefixo_valem_com_a_flag_ligada[E02-substring-no-meio]", + "tests/migration/test_original_vas_variation_adversarial.py::test_guards_de_prefixo_valem_com_a_flag_ligada[E03-sufixo-games-premium]", + "tests/migration/test_original_vas_variation_adversarial.py::test_guards_de_prefixo_valem_com_a_flag_ligada[E04-token-parcial-tube]", + "tests/migration/test_original_vas_variation_adversarial.py::test_guards_de_prefixo_valem_com_a_flag_ligada[E05-token-solto-app]", + "tests/migration/test_original_vas_variation_adversarial.py::test_guards_de_prefixo_valem_com_a_flag_ligada[E06-fitme-fail-closed-por-padrao]", + "tests/migration/test_original_vas_variation_adversarial.py::test_matcher_determinístico_nao_produz_falso_positivo[A01-fluid-light-x-premium]", + "tests/migration/test_original_vas_variation_adversarial.py::test_matcher_determinístico_nao_produz_falso_positivo[A02-fluid-premium-x-light]", + "tests/migration/test_original_vas_variation_adversarial.py::test_matcher_determinístico_nao_produz_falso_positivo[A03-aya-books-x-audiobooks]", + "tests/migration/test_original_vas_variation_adversarial.py::test_matcher_determinístico_nao_produz_falso_positivo[A04-aya-ensinah-x-books]", + "tests/migration/test_original_vas_variation_adversarial.py::test_matcher_determinístico_nao_produz_falso_positivo[A05-exa-seguranca-x-cloud]", + "tests/migration/test_original_vas_variation_adversarial.py::test_matcher_determinístico_nao_produz_falso_positivo[A06-bancah-jornais-x-premium]", + "tests/migration/test_original_vas_variation_adversarial.py::test_matcher_determinístico_nao_produz_falso_positivo[A07-itgame-light-x-premium]", + "tests/migration/test_original_vas_variation_adversarial.py::test_matcher_determinístico_nao_produz_falso_positivo[A08-aluguel-filme-1-x-2]", + "tests/migration/test_original_vas_variation_adversarial.py::test_matcher_determinístico_nao_produz_falso_positivo[A09-tim-games-mensal-x-semanal]", + "tests/migration/test_original_vas_variation_adversarial.py::test_matcher_determinístico_nao_produz_falso_positivo[A10-kids-plus-x-premium]", + "tests/migration/test_original_vas_variation_adversarial.py::test_matcher_determinístico_nao_produz_falso_positivo[A11-exa-premium-x-protecao]", + "tests/migration/test_original_vas_variation_adversarial.py::test_matcher_determinístico_nao_produz_falso_positivo[A12-tim-games-prefixo]", + "tests/migration/test_original_vas_variation_adversarial.py::test_matcher_determinístico_nao_produz_falso_positivo[A13-fit-app-x-fit-me-app]", + "tests/migration/test_original_vas_variation_adversarial.py::test_matcher_determinístico_nao_produz_falso_positivo[A14-tim-music-plus-x-premium]", + "tests/migration/test_original_vas_variation_adversarial.py::test_matcher_determinístico_nao_produz_falso_positivo[A15-kids-prefixo]", + "tests/migration/test_original_vas_variation_adversarial.py::test_matcher_determinístico_nao_produz_falso_positivo[B01-fitme-16.99-x-17.00]", + "tests/migration/test_original_vas_variation_adversarial.py::test_matcher_determinístico_nao_produz_falso_positivo[B02-fitme-16.99-x-16.98]", + "tests/migration/test_original_vas_variation_adversarial.py::test_matcher_determinístico_nao_produz_falso_positivo[B03-fluid-14.99-x-15.00]", + "tests/migration/test_original_vas_variation_adversarial.py::test_matcher_determinístico_nao_produz_falso_positivo[B04-exa-9.99-x-9.98]", + "tests/migration/test_original_vas_variation_adversarial.py::test_matcher_determinístico_nao_produz_falso_positivo[B05-fitme-prefixo-valor-errado]", + "tests/migration/test_original_vas_variation_adversarial.py::test_matcher_determinístico_nao_produz_falso_positivo[B06-aya-24.90-x-24.91]", + "tests/migration/test_original_vas_variation_adversarial.py::test_matcher_determinístico_nao_produz_falso_positivo[B07-itgame-12.90-x-12.09]", + "tests/migration/test_original_vas_variation_adversarial.py::test_matcher_determinístico_nao_produz_falso_positivo[B08-fitme-16.99-x-169.90]", + "tests/migration/test_original_vas_variation_adversarial.py::test_matcher_determinístico_nao_produz_falso_positivo[C01-hbo-secao-terceiros]", + "tests/migration/test_original_vas_variation_adversarial.py::test_matcher_determinístico_nao_produz_falso_positivo[C02-netflix-em-secao-avulsa]", + "tests/migration/test_original_vas_variation_adversarial.py::test_matcher_determinístico_nao_produz_falso_positivo[C03-youtube-mis-bucket]", + "tests/migration/test_original_vas_variation_adversarial.py::test_matcher_determinístico_nao_produz_falso_positivo[C04-deezer-em-secao-avulsa]", + "tests/migration/test_original_vas_variation_adversarial.py::test_matcher_determinístico_nao_produz_falso_positivo[C05-apple-music-em-secao-avulsa]", + "tests/migration/test_original_vas_variation_adversarial.py::test_matcher_determinístico_nao_produz_falso_positivo[C06-bundle-incluso]", + "tests/migration/test_original_vas_variation_adversarial.py::test_matcher_determinístico_nao_produz_falso_positivo[C07-fitme-classificado-estrategico]", + "tests/migration/test_original_vas_variation_adversarial.py::test_matcher_determinístico_nao_produz_falso_positivo[D01-fitme-dois-candidatos]", + "tests/migration/test_original_vas_variation_adversarial.py::test_matcher_determinístico_nao_produz_falso_positivo[D02-fitme-tres-candidatos]", + "tests/migration/test_original_vas_variation_adversarial.py::test_matcher_determinístico_nao_produz_falso_positivo[D03-aya-tres-marcas]", + "tests/migration/test_original_vas_variation_adversarial.py::test_matcher_determinístico_nao_produz_falso_positivo[D04-mesmo-nome-duas-linhas]", + "tests/migration/test_original_vas_variation_adversarial.py::test_matcher_determinístico_nao_produz_falso_positivo[D05-duplicata-mesma-linha]", + "tests/migration/test_original_vas_variation_adversarial.py::test_matcher_determinístico_nao_produz_falso_positivo[D06-fluid-familia]", + "tests/migration/test_original_vas_variation_adversarial.py::test_matcher_determinístico_nao_produz_falso_positivo[D07-exa-familia]", + "tests/migration/test_original_vas_variation_adversarial.py::test_matcher_determinístico_nao_produz_falso_positivo[D08-bancah-familia]", + "tests/migration/test_original_vas_variation_adversarial.py::test_matcher_determinístico_nao_produz_falso_positivo[E01-prefixo-invertido]", + "tests/migration/test_original_vas_variation_adversarial.py::test_matcher_determinístico_nao_produz_falso_positivo[E02-substring-no-meio]", + "tests/migration/test_original_vas_variation_adversarial.py::test_matcher_determinístico_nao_produz_falso_positivo[E03-sufixo-games-premium]", + "tests/migration/test_original_vas_variation_adversarial.py::test_matcher_determinístico_nao_produz_falso_positivo[E04-token-parcial-tube]", + "tests/migration/test_original_vas_variation_adversarial.py::test_matcher_determinístico_nao_produz_falso_positivo[E05-token-solto-app]", + "tests/migration/test_original_vas_variation_adversarial.py::test_matcher_determinístico_nao_produz_falso_positivo[E06-fitme-fail-closed-por-padrao]", + "tests/migration/test_original_vas_variation_adversarial.py::test_matcher_determinístico_nao_produz_falso_positivo[F01-msisdn-ausente]", + "tests/migration/test_original_vas_variation_adversarial.py::test_matcher_determinístico_nao_produz_falso_positivo[F02-item-na-linha-secundaria]", + "tests/migration/test_original_vas_variation_adversarial.py::test_matcher_determinístico_nao_produz_falso_positivo[F03-secao-sem-classe]", + "tests/migration/test_original_vas_variation_adversarial.py::test_matcher_determinístico_nao_produz_falso_positivo[F04-desc-vazia]", + "tests/migration/test_original_vas_variation_adversarial.py::test_matcher_determinístico_nao_produz_falso_positivo[F05-valor-nao-parseavel]", + "tests/migration/test_original_vas_variation_adversarial.py::test_matcher_determinístico_nao_produz_falso_positivo[F06-fatura-sem-o-item]", + "tests/migration/test_original_vas_variation_adversarial.py::test_nenhum_item_devolvido_e_estrategico_ou_bundle[A01-fluid-light-x-premium]", + "tests/migration/test_original_vas_variation_adversarial.py::test_nenhum_item_devolvido_e_estrategico_ou_bundle[A02-fluid-premium-x-light]", + "tests/migration/test_original_vas_variation_adversarial.py::test_nenhum_item_devolvido_e_estrategico_ou_bundle[A03-aya-books-x-audiobooks]", + "tests/migration/test_original_vas_variation_adversarial.py::test_nenhum_item_devolvido_e_estrategico_ou_bundle[A04-aya-ensinah-x-books]", + "tests/migration/test_original_vas_variation_adversarial.py::test_nenhum_item_devolvido_e_estrategico_ou_bundle[A05-exa-seguranca-x-cloud]", + "tests/migration/test_original_vas_variation_adversarial.py::test_nenhum_item_devolvido_e_estrategico_ou_bundle[A06-bancah-jornais-x-premium]", + "tests/migration/test_original_vas_variation_adversarial.py::test_nenhum_item_devolvido_e_estrategico_ou_bundle[A07-itgame-light-x-premium]", + "tests/migration/test_original_vas_variation_adversarial.py::test_nenhum_item_devolvido_e_estrategico_ou_bundle[A08-aluguel-filme-1-x-2]", + "tests/migration/test_original_vas_variation_adversarial.py::test_nenhum_item_devolvido_e_estrategico_ou_bundle[A09-tim-games-mensal-x-semanal]", + "tests/migration/test_original_vas_variation_adversarial.py::test_nenhum_item_devolvido_e_estrategico_ou_bundle[A10-kids-plus-x-premium]", + "tests/migration/test_original_vas_variation_adversarial.py::test_nenhum_item_devolvido_e_estrategico_ou_bundle[A11-exa-premium-x-protecao]", + "tests/migration/test_original_vas_variation_adversarial.py::test_nenhum_item_devolvido_e_estrategico_ou_bundle[A12-tim-games-prefixo]", + "tests/migration/test_original_vas_variation_adversarial.py::test_nenhum_item_devolvido_e_estrategico_ou_bundle[A13-fit-app-x-fit-me-app]", + "tests/migration/test_original_vas_variation_adversarial.py::test_nenhum_item_devolvido_e_estrategico_ou_bundle[A14-tim-music-plus-x-premium]", + "tests/migration/test_original_vas_variation_adversarial.py::test_nenhum_item_devolvido_e_estrategico_ou_bundle[A15-kids-prefixo]", + "tests/migration/test_original_vas_variation_adversarial.py::test_nenhum_item_devolvido_e_estrategico_ou_bundle[B01-fitme-16.99-x-17.00]", + "tests/migration/test_original_vas_variation_adversarial.py::test_nenhum_item_devolvido_e_estrategico_ou_bundle[B02-fitme-16.99-x-16.98]", + "tests/migration/test_original_vas_variation_adversarial.py::test_nenhum_item_devolvido_e_estrategico_ou_bundle[B03-fluid-14.99-x-15.00]", + "tests/migration/test_original_vas_variation_adversarial.py::test_nenhum_item_devolvido_e_estrategico_ou_bundle[B04-exa-9.99-x-9.98]", + "tests/migration/test_original_vas_variation_adversarial.py::test_nenhum_item_devolvido_e_estrategico_ou_bundle[B05-fitme-prefixo-valor-errado]", + "tests/migration/test_original_vas_variation_adversarial.py::test_nenhum_item_devolvido_e_estrategico_ou_bundle[B06-aya-24.90-x-24.91]", + "tests/migration/test_original_vas_variation_adversarial.py::test_nenhum_item_devolvido_e_estrategico_ou_bundle[B07-itgame-12.90-x-12.09]", + "tests/migration/test_original_vas_variation_adversarial.py::test_nenhum_item_devolvido_e_estrategico_ou_bundle[B08-fitme-16.99-x-169.90]", + "tests/migration/test_original_vas_variation_adversarial.py::test_nenhum_item_devolvido_e_estrategico_ou_bundle[C01-hbo-secao-terceiros]", + "tests/migration/test_original_vas_variation_adversarial.py::test_nenhum_item_devolvido_e_estrategico_ou_bundle[C02-netflix-em-secao-avulsa]", + "tests/migration/test_original_vas_variation_adversarial.py::test_nenhum_item_devolvido_e_estrategico_ou_bundle[C03-youtube-mis-bucket]", + "tests/migration/test_original_vas_variation_adversarial.py::test_nenhum_item_devolvido_e_estrategico_ou_bundle[C04-deezer-em-secao-avulsa]", + "tests/migration/test_original_vas_variation_adversarial.py::test_nenhum_item_devolvido_e_estrategico_ou_bundle[C05-apple-music-em-secao-avulsa]", + "tests/migration/test_original_vas_variation_adversarial.py::test_nenhum_item_devolvido_e_estrategico_ou_bundle[C06-bundle-incluso]", + "tests/migration/test_original_vas_variation_adversarial.py::test_nenhum_item_devolvido_e_estrategico_ou_bundle[C07-fitme-classificado-estrategico]", + "tests/migration/test_original_vas_variation_adversarial.py::test_nenhum_item_devolvido_e_estrategico_ou_bundle[D01-fitme-dois-candidatos]", + "tests/migration/test_original_vas_variation_adversarial.py::test_nenhum_item_devolvido_e_estrategico_ou_bundle[D02-fitme-tres-candidatos]", + "tests/migration/test_original_vas_variation_adversarial.py::test_nenhum_item_devolvido_e_estrategico_ou_bundle[D03-aya-tres-marcas]", + "tests/migration/test_original_vas_variation_adversarial.py::test_nenhum_item_devolvido_e_estrategico_ou_bundle[D04-mesmo-nome-duas-linhas]", + "tests/migration/test_original_vas_variation_adversarial.py::test_nenhum_item_devolvido_e_estrategico_ou_bundle[D05-duplicata-mesma-linha]", + "tests/migration/test_original_vas_variation_adversarial.py::test_nenhum_item_devolvido_e_estrategico_ou_bundle[D06-fluid-familia]", + "tests/migration/test_original_vas_variation_adversarial.py::test_nenhum_item_devolvido_e_estrategico_ou_bundle[D07-exa-familia]", + "tests/migration/test_original_vas_variation_adversarial.py::test_nenhum_item_devolvido_e_estrategico_ou_bundle[D08-bancah-familia]", + "tests/migration/test_original_vas_variation_adversarial.py::test_nenhum_item_devolvido_e_estrategico_ou_bundle[E01-prefixo-invertido]", + "tests/migration/test_original_vas_variation_adversarial.py::test_nenhum_item_devolvido_e_estrategico_ou_bundle[E02-substring-no-meio]", + "tests/migration/test_original_vas_variation_adversarial.py::test_nenhum_item_devolvido_e_estrategico_ou_bundle[E03-sufixo-games-premium]", + "tests/migration/test_original_vas_variation_adversarial.py::test_nenhum_item_devolvido_e_estrategico_ou_bundle[E04-token-parcial-tube]", + "tests/migration/test_original_vas_variation_adversarial.py::test_nenhum_item_devolvido_e_estrategico_ou_bundle[E05-token-solto-app]", + "tests/migration/test_original_vas_variation_adversarial.py::test_nenhum_item_devolvido_e_estrategico_ou_bundle[E06-fitme-fail-closed-por-padrao]", + "tests/migration/test_original_vas_variation_adversarial.py::test_nenhum_item_devolvido_e_estrategico_ou_bundle[F01-msisdn-ausente]", + "tests/migration/test_original_vas_variation_adversarial.py::test_nenhum_item_devolvido_e_estrategico_ou_bundle[F02-item-na-linha-secundaria]", + "tests/migration/test_original_vas_variation_adversarial.py::test_nenhum_item_devolvido_e_estrategico_ou_bundle[F03-secao-sem-classe]", + "tests/migration/test_original_vas_variation_adversarial.py::test_nenhum_item_devolvido_e_estrategico_ou_bundle[F04-desc-vazia]", + "tests/migration/test_original_vas_variation_adversarial.py::test_nenhum_item_devolvido_e_estrategico_ou_bundle[F05-valor-nao-parseavel]", + "tests/migration/test_original_vas_variation_adversarial.py::test_nenhum_item_devolvido_e_estrategico_ou_bundle[F06-fatura-sem-o-item]", + "tests/migration/test_original_vas_variation_adversarial.py::test_nenhum_threshold_de_similaridade_zera_falso_positivo[0.85]", + "tests/migration/test_original_vas_variation_adversarial.py::test_nenhum_threshold_de_similaridade_zera_falso_positivo[0.95]", + "tests/migration/test_original_vas_variation_adversarial.py::test_nenhum_threshold_de_similaridade_zera_falso_positivo[0.97]", + "tests/migration/test_original_vas_variation_adversarial.py::test_nenhum_threshold_de_similaridade_zera_falso_positivo[0.99]", + "tests/migration/test_original_vas_variation_adversarial.py::test_nenhum_threshold_de_similaridade_zera_falso_positivo[0.9]", + "tests/migration/test_original_vas_variation_adversarial.py::test_shadow_similaridade_tem_overlap_irremovivel", + "tests/migration/test_original_vas_variation_adversarial.py::test_suite_tem_exatamente_50_casos_com_a_distribuicao_exigida", + "tests/migration/test_original_vas_variation_adversarial.py::test_valores_sao_decimal_nunca_float", + "tests/migration/test_tool_policy_operation_types.py::test_contas_tool_policies_accept_all_operation_types", + "tests/migration/test_vas_response_renderer.py::test_vas_renderer_does_not_invent_missing_value", + "tests/migration/test_vas_response_renderer.py::test_vas_renderer_includes_available_values" +] \ No newline at end of file diff --git a/README.md b/README.md index 178239a..c2cd3fe 100644 --- a/README.md +++ b/README.md @@ -35,3 +35,7 @@ grep -R "agente_contas_tim" app mcp config ``` Deve retornar zero ocorrências. + + +## V10 - VAS response renderer +`consultar_vas` agora usa `response.mode: renderer` com `renderer: contas.vas`. O renderer inclui o valor de cada serviço quando a tool o fornece (por exemplo `details.valor`) e nunca inventa preço quando ausente. diff --git a/agent_framework_oci/.env b/agent_framework_oci/.env new file mode 100644 index 0000000..4556734 --- /dev/null +++ b/agent_framework_oci/.env @@ -0,0 +1,207 @@ +############################################################################### +# AI AGENT PLATFORM - CONFIGURAÇÃO ÚNICA +# Este arquivo é lido por Pydantic Settings no framework e no backend template. +############################################################################### + +APP_NAME=ai-agent-template +APP_ENV=local +LOG_LEVEL=INFO +API_HOST=0.0.0.0 +API_PORT=8000 +CORS_ORIGINS=http://localhost:5173,http://127.0.0.1:5173 + +############################################################################### +# LLM - OCI Generative AI como provider principal +############################################################################### +# Opções: mock, oci_openai, oci_sdk, openai_compatible +LLM_PROVIDER=oci_sdk +LLM_TEMPERATURE=0.2 +LLM_MAX_TOKENS=2048 +LLM_TIMEOUT_SECONDS=120 + +# OCI OpenAI-compatible endpoint +OCI_GENAI_BASE_URL=https://inference.generativeai.us-chicago-1.oci.oraclecloud.com +OCI_GENAI_MODEL=openai.gpt-4.1 +OCI_GENAI_API_KEY=sk-ph3FgX6iP3fxAQCXb9IpPIDTadkeeYAWntUWhzcWysIM6zsS +OCI_GENAI_PROJECT_OCID= + +#OCI_GENAI_BASE_URL=https://pegruagntaiatenddev.pe.inference.generativeai.sa-saopaulo-1.oci.oraclecloud.com +#OCI_GENAI_MODEL=openai.gpt-4.1 +#OCI_GENAI_API_KEY= +#OCI_GENAI_PROJECT_OCID= + + +# OCI_AUTH_MODE=config_file|instance_principal|resource_principal +OCI_AUTH_MODE=config_file +# OCI SDK / signer / profiles +OCI_CONFIG_FILE=~/.oci/config +OCI_PROFILE=LATINOAMERICA-Chicago +OCI_COMPARTMENT_ID=ocid1.compartment.oc1..aaaaaaaaexpiw4a7dio64mkfv2t273s2hgdl6mgfvvyv7tycalnjlvpvfl3q +OCI_REGION=us-chicago-1 + +############################################################################### +# Persistência +############################################################################### +# Opções: memory, autonomous, mongodb +SESSION_REPOSITORY_PROVIDER=autonomous +MEMORY_REPOSITORY_PROVIDER=autonomous +CHECKPOINT_REPOSITORY_PROVIDER=autonomous + +# Autonomous Database +ADB_USER=admin +ADB_PASSWORD=Moniquinha19721972 +ADB_DSN=oradb23ai_high +ADB_WALLET_LOCATION=/mnt/d/Dropbox/ORACLE/LatinoAmerica/Wallet_ORADB23ai +ADB_WALLET_PASSWORD=Moniquinha1972 +ADB_TABLE_PREFIX=AGENTFW + +# MongoDB - também pode representar Autonomous usando API compatível com Mongo, se habilitada no ambiente +MONGODB_URI=mongodb://mongo:mongopassword@localhost:27017 +MONGODB_DATABASE=agent_platform + +# Redis +REDIS_URL=redis://localhost:6379/0 +ENABLE_REDIS_CACHE=false + +############################################################################### +# RAG / Vector / Graph +############################################################################### +VECTOR_STORE_PROVIDER=autonomous +GRAPH_STORE_PROVIDER=autonomous +RAG_TOP_K=5 +EMBEDDING_PROVIDER=oci +OCI_EMBEDDING_MODEL=cohere.embed-multilingual-v3.0 +RAG_FILE_GLOBS=*.md,*.txt,*.yaml,*.yml,*.json + +############################################################################### +# Observabilidade +############################################################################### +ENABLE_LANGFUSE=true + # Opcional: verbose, compact +LANGFUSE_TRACE_MODE=compact +# Nome customizado do trace pai, ex.: backoffice.checklist.workflow ou backoffice.emulador.workflow +LANGFUSE_COMPACT_VISIBLE_EVENT_PREFIXES=AGA.,NOC., IC. +LANGFUSE_COMPACT_SUPPRESSED_PREFIXES=llm.chat_completion +LANGFUSE_IGNORE_HEALTHCHECKS=true +LANGFUSE_IGNORED_PATHS=/health,/ready,/metrics +LANGFUSE_PUBLIC_KEY=pk-lf-4a1e3921-5158-4fd3-a16d-7a77549fb312 +LANGFUSE_SECRET_KEY=sk-lf-efc6fd59-c5ec-4858-b6ec-4aa129734915 +LANGFUSE_HOST=http://localhost:3005 +ENABLE_OTEL=false +OTEL_EXPORTER_OTLP_ENDPOINT= +OTEL_SERVICE_NAME=ai-agent-template +ENABLE_LANGFUSE_OPENAI_AUTO_INSTRUMENTATION=true +ENABLE_LANGFUSE_ANALYTICS_PUBLISHER=false + +############################################################################### +# Analytics / Observer corporativo +############################################################################### +# Quando true, AgentObserver publica eventos IC.*, NOC.* e GRL.* nos providers abaixo. +ENABLE_ANALYTICS=false +# Providers aceitos: oci_streaming,pubsub,noop +ANALYTICS_PROVIDERS=oci_streaming +# Compatibilidade FIRST/TIM: pode informar AGENT_PUBSUB_TOPIC diretamente. +AGENT_PUBSUB_TOPIC= +GCP_PUBSUB_TOPIC_PATH= +GCP_PROJECT_ID= +GCP_PUBSUB_TOPIC= +GCP_PUBSUB_TIMEOUT_SECONDS=30 +# Credencial GCP segue padrão Google: +# GOOGLE_APPLICATION_CREDENTIALS=/secrets/gcp-service-account.json + +############################################################################### +# OCI Streaming +############################################################################### +ENABLE_OCI_STREAMING=false +OCI_STREAM_ENDPOINT= +OCI_STREAM_OCID= +OCI_STREAM_PARTITION_KEY=agent-events + +############################################################################### +# Guardrails, Judges, Supervisor +############################################################################### +ENABLE_INPUT_GUARDRAILS=true +ENABLE_OUTPUT_GUARDRAILS=true +ENABLE_JUDGES=true +ENABLE_SUPERVISOR=true +ENABLE_OUTPUT_SUPERVISOR=true +ENABLE_PARALLEL_GUARDRAILS=true +GUARDRAILS_FAIL_FAST=true +OUTPUT_SUPERVISOR_MAX_RETRIES=3 +GUARDRAILS_CONFIG_PATH=./config/guardrails.yaml +JUDGES_CONFIG_PATH=./config/judges.yaml +PROMPT_POLICY_PATH=./config/prompt_policy.yaml + +############################################################################### +# Gateway de canais +############################################################################### +DEFAULT_CHANNEL=web +# embedded = backend may parse simple/native channel payloads. +# external = backend only accepts GatewayRequest normalized by an external Channel Gateway. +FRAMEWORK_CHANNEL_INPUT_MODE=embedded +ENABLE_VOICE_ADAPTER=true +ENABLE_WHATSAPP_ADAPTER=true +ENABLE_TEXT_ADAPTER=true + +################################################# +# ENTERPRISE ROUTING +################################################# +# Arquivo YAML com intents, keywords, políticas de estado e fallback. +ROUTING_CONFIG_PATH=./config/routing.yaml +# true = usa LLM para classificar quando keywords/estado não resolverem. +# Em produção, costuma ser útil; em desenvolvimento, false evita custo e latência. +ENABLE_LLM_ROUTER=true + +# Semantic route stickiness (optional). +# Uses a lightweight LLM profile to decide only CONTINUE vs ROUTE. +# There are no regexes or deterministic language rules. +ENABLE_ROUTE_STICKINESS=true +ROUTE_STICKINESS_LLM_PROFILE=route_continuity +ROUTE_STICKINESS_CONFIDENCE_THRESHOLD=0.90 +ROUTE_STICKINESS_HISTORY_TURNS=2 +ROUTE_STICKINESS_MAX_TOKENS=80 +HUMAN_HANDOFF_MESSAGE=Vou encaminhar seu atendimento para uma pessoa. +END_SESSION_MESSAGE=Atendimento encerrado. Obrigado pelo contato. + +############################################################################### +# MCP / Tools +############################################################################### +ENABLE_MCP_TOOLS=true +MCP_SERVERS_CONFIG_PATH=./config/mcp_servers.yaml +TOOLS_CONFIG_PATH=./config/tools.yaml +MCP_TOOL_TIMEOUT_SECONDS=30 + +# router = EnterpriseRouter seleciona um agente; supervisor = pode acionar múltiplos agentes +ROUTING_MODE=router + +# Usage/cost accounting +USAGE_REPOSITORY_PROVIDER=autonomous +IDENTITY_CONFIG_PATH=./config/identity.yaml +MCP_PARAMETER_MAPPING_PATH=./config/mcp_parameter_mapping.yaml + +# ----------------------------------------------------------------------------- +# ConversationSummaryMemory / compressão de contexto conversacional +# ----------------------------------------------------------------------------- +ENABLE_CONVERSATION_SUMMARY_MEMORY=true +MEMORY_CONTEXT_STRATEGY=summary +MEMORY_HISTORY_LIMIT=80 +MEMORY_RECENT_MESSAGES_LIMIT=8 +MEMORY_SUMMARY_TRIGGER_MESSAGES=20 +MEMORY_MAX_SUMMARY_CHARS=6000 +MEMORY_SUMMARY_USE_LLM=true +MEMORY_INJECT_RECENT_MESSAGES=true +MEMORY_INJECT_SUMMARY=true + +############################################################################### +# LONG-TERM MEMORY +############################################################################### +ENABLE_LONG_TERM_MEMORY=true +LONG_TERM_MEMORY_PROVIDER=sqlite +LONG_TERM_MEMORY_SQLITE_PATH=./data/agent_framework.db +LONG_TERM_MEMORY_TABLE=agentfw_long_term_memory +# For Autonomous/Oracle, defaults to ${ADB_TABLE_PREFIX}_LONG_TERM_MEMORY +# LONG_TERM_MEMORY_ORACLE_TABLE=AGENTFW_LONG_TERM_MEMORY +LONG_TERM_MEMORY_MAX_CONTEXT_ITEMS=20 +LONG_TERM_MEMORY_MIN_CONFIDENCE=0.70 +LONG_TERM_MEMORY_AUTO_EXTRACT=true +LONG_TERM_MEMORY_INJECT_CONTEXT=true diff --git a/agent_framework_oci/.idea/agent_platform_oci.iml b/agent_framework_oci/.idea/agent_platform_oci.iml new file mode 100644 index 0000000..853e1f0 --- /dev/null +++ b/agent_framework_oci/.idea/agent_platform_oci.iml @@ -0,0 +1,16 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/agent_framework_oci/.idea/modules.xml b/agent_framework_oci/.idea/modules.xml new file mode 100644 index 0000000..3fb2fd0 --- /dev/null +++ b/agent_framework_oci/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/agent_framework_oci/.idea/vcs.xml b/agent_framework_oci/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/agent_framework_oci/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/agent_framework_oci/.idea/workspace.xml b/agent_framework_oci/.idea/workspace.xml new file mode 100644 index 0000000..03a129f --- /dev/null +++ b/agent_framework_oci/.idea/workspace.xml @@ -0,0 +1,130 @@ + + + + + + + + + + + + + { + "lastFilter": { + "state": "OPEN", + "assignee": "hoshikawa2" + } +} + { + "selectedUrlAndAccountId": { + "url": "https://github.com/hoshikawa2/agent_platform_oci.git", + "accountId": "bd799ac0-7624-42b2-999a-b96e6e11f98a" + } +} + {} + { + "isMigrated": true +} + + + + { + "customColor": "", + "associatedIndex": 2 +} + + + + + + + + + + + + + + 1781996088468 + + + + + + + + + + + + + + \ No newline at end of file diff --git a/agent_framework_oci/Documentacao/IMPLEMENTACAO_WORKFLOWS_TRANSACIONAIS.md b/agent_framework_oci/Documentacao/IMPLEMENTACAO_WORKFLOWS_TRANSACIONAIS.md new file mode 100644 index 0000000..79d8405 --- /dev/null +++ b/agent_framework_oci/Documentacao/IMPLEMENTACAO_WORKFLOWS_TRANSACIONAIS.md @@ -0,0 +1,64 @@ +# Implementação — workflows transacionais determinísticos + +## Entrega + +Foi adicionada ao `agent_framework_oci` uma capacidade opcional para executar transações multi-etapas como workflows determinísticos compilados em LangGraph. + +### Módulo novo + +`libs/agent_framework/src/agent_framework/workflows/` + +- `models.py`: contratos Pydantic e validação estrutural; +- `repository.py`: resolução de versão ativa e leitura de YAML imutável; +- `registry.py`: registro desacoplado de actions sync/async; +- `runtime.py`: compilação, cache e execução do StateGraph; +- `tool_executor.py`: integração com a política da tool; +- `__init__.py`: API pública. + +### Política expandida + +`ToolPolicy` agora aceita: + +```yaml +execution: + mode: direct_tool | workflow | agent + workflow: nome_do_workflow + version: active | 1 +``` + +O default permanece `direct_tool`, preservando compatibilidade. + +### Configuração + +Foram adicionados: + +- `ENABLE_TRANSACTIONAL_WORKFLOWS=false`; +- `WORKFLOWS_PATH=./workflows`. + +### Template + +Inclui um exemplo completo de devolução de pedido com: + +- confirmação e campos obrigatórios pela política; +- workflow YAML versionado; +- actions de domínio no backend; +- bifurcação determinística baseada no resultado da validação. + +## Validação realizada + +- `tests/unit/test_tool_policies.py`: 4 testes aprovados; +- compilação Python de framework, template e novos testes: aprovada; +- o teste funcional novo do LangGraph foi criado, mas não pôde ser executado neste container porque `langgraph` não está instalado no ambiente. A dependência já está declarada no `pyproject.toml` do framework. + +## Escopo e segurança + +Esta entrega cria o motor e a integração de política. Para operações críticas em produção ainda é necessário conectar: + +- execution store persistente; +- idempotência de negócio nas actions/APIs; +- autorização por escopo; +- telemetria IC/NOC específica de workflow; +- compensação/Saga quando aplicável; +- estratégia corporativa de timeout e retry. + +Esses itens foram explicitamente documentados para evitar a falsa impressão de que retry por si só garante segurança transacional. diff --git a/agent_framework_oci/Documentacao/Implementando_Basic_Auth.md b/agent_framework_oci/Documentacao/Implementando_Basic_Auth.md new file mode 100644 index 0000000..d6ff282 --- /dev/null +++ b/agent_framework_oci/Documentacao/Implementando_Basic_Auth.md @@ -0,0 +1,987 @@ +# Implementando Basic Auth + +Para validar **todo o circuito com Basic Auth**, você precisa configurar três relações distintas: + +```text +Cliente de teste + └─ Basic Auth A ─► Agent Gateway :8010 + └─ Basic Auth B ─► Agent Backend :8000 + └─ Basic Auth C ─► MCP Gateway :8300 +``` + +Há um detalhe importante: no pacote atual, a autenticação Basic já funciona para chamadas **de entrada**, mas os clientes internos ainda não enviam Basic Auth: + +* `Agent Gateway → Agent Backend` não envia credencial; +* `Agent Backend → MCP Gateway` envia apenas Bearer Token. + +Portanto, para testar o circuito inteiro com Basic Auth, faça os dois pequenos ajustes de código descritos abaixo. + +--- + +# 1. Preparar o ambiente + +Considere que o ZIP foi extraído em: + +```bash +cd agent_framework_oci_authentication_v2_1 +``` + +Crie um único ambiente virtual para facilitar o teste: + +```bash +python -m venv .venv +source .venv/bin/activate +``` + +No Windows PowerShell: + +```powershell +python -m venv .venv +.\.venv\Scripts\Activate.ps1 +``` + +Instale o framework e as dependências dos três componentes: + +```bash +pip install -U pip + +pip install -e ./libs/agent_framework + +pip install \ + -r ./Tuning-Performance/Authentication/agent_template_backend_authentication/requirements.txt \ + -r ./apps/agent_gateway/requirements.txt \ + -r ./apps/mcp_gateway/requirements.txt +``` + +Confirme a importação: + +```bash +python -c "from agent_framework.security import install_authentication; print('framework ok')" +``` + +--- + +# 2. Criar três pares de Client ID e Secret + +Use credenciais diferentes para cada trecho. Para teste local: + +| Fluxo | Client ID | Secret de teste | +| ----------------------- | -------------------- | --------------------------- | +| Cliente → Agent Gateway | `tia-test` | `TiaGateway-Test-2026!` | +| Agent Gateway → Backend | `agent-gateway-test` | `GatewayBackend-Test-2026!` | +| Backend → MCP Gateway | `agent-backend-test` | `BackendMcp-Test-2026!` | + +Esses valores são apenas para ambiente local. Não os reutilize em produção. + +## Gerar os hashes + +O script está em: + +```text +Tuning-Performance/Authentication/ + agent_template_backend_authentication/ + scripts/generate_secret_hash.py +``` + +Execute: + +```bash +python Tuning-Performance/Authentication/agent_template_backend_authentication/scripts/generate_secret_hash.py \ + --secret 'TiaGateway-Test-2026!' +``` + +Depois: + +```bash +python Tuning-Performance/Authentication/agent_template_backend_authentication/scripts/generate_secret_hash.py \ + --secret 'GatewayBackend-Test-2026!' +``` + +E: + +```bash +python Tuning-Performance/Authentication/agent_template_backend_authentication/scripts/generate_secret_hash.py \ + --secret 'BackendMcp-Test-2026!' +``` + +Você receberá três valores semelhantes a: + +```text +pbkdf2_sha256:310000:: +``` + +Guarde-os temporariamente: + +```bash +HASH_CLIENT_GATEWAY='pbkdf2_sha256:310000:...' +HASH_GATEWAY_BACKEND='pbkdf2_sha256:310000:...' +HASH_BACKEND_MCP='pbkdf2_sha256:310000:...' +``` + +O hash muda a cada execução porque o salt é aleatório. Isso é esperado. + +--- + +# 3. Configurar o Agent Gateway + +Entre no diretório: + +```bash +cd apps/agent_gateway +``` + +Copie o exemplo: + +```bash +cp .env.example .env +``` + +Adicione ao final do `.env`: + +```env +# Entrada: cliente/TIA -> Agent Gateway +AGENT_GATEWAY_AUTH_ENABLED=true +AGENT_GATEWAY_AUTH_MODE=basic +AGENT_GATEWAY_AUTH_BASIC_CLIENT_ID=tia-test +AGENT_GATEWAY_AUTH_BASIC_SECRET_HASH=COLE_AQUI_HASH_CLIENT_GATEWAY +AGENT_GATEWAY_AUTH_BASIC_REALM=agent-gateway + +AGENT_GATEWAY_AUTH_PUBLIC_PATHS=/health,/docs,/openapi.json,/redoc +AGENT_GATEWAY_AUTH_PUBLIC_PREFIXES= + +# Saída: Agent Gateway -> Agent Backend +BACKEND_AUTH_MODE=basic +BACKEND_AUTH_CLIENT_ID=agent-gateway-test +BACKEND_AUTH_SECRET=GatewayBackend-Test-2026! +``` + +Não coloque aspas no `.env`: + +```env +BACKEND_AUTH_SECRET=GatewayBackend-Test-2026! +``` + +O arquivo de backends já aponta o backend Contas para: + +```yaml +contas: + url: http://localhost:8000 +``` + +Arquivo: + +```text +apps/agent_gateway/config/backends.yaml +``` + +Para este teste, mantenha apenas o backend `contas` ou force o backend no payload. Caso contrário, pedidos sobre ofertas e suporte podem ser roteados para portas em que nenhum backend está rodando. + +--- + +# 4. Fazer o Agent Gateway enviar Basic Auth ao backend + +Abra: + +```text +libs/agent_framework/src/agent_framework/global_supervisor/client.py +``` + +Substitua a classe `BackendClient` por uma versão que aceite autenticação Basic. + +No início do arquivo, adicione: + +```python +import os +``` + +Altere o construtor: + +```python +class BackendClient: + def __init__( + self, + timeout_seconds: float = 120.0, + basic_client_id: str | None = None, + basic_secret: str | None = None, + ): + self.timeout_seconds = timeout_seconds + self.basic_client_id = basic_client_id + self.basic_secret = basic_secret + + def _auth(self) -> httpx.BasicAuth | None: + if self.basic_client_id and self.basic_secret: + return httpx.BasicAuth( + username=self.basic_client_id, + password=self.basic_secret, + ) + return None +``` + +No método `call_message`, troque: + +```python +resp = await client.post(url, json=payload) +``` + +por: + +```python +resp = await client.post( + url, + json=payload, + auth=self._auth(), +) +``` + +No método `health`, você pode manter `/health` público. Caso queira enviar autenticação também, use: + +```python +resp = await client.get(url, auth=self._auth()) +``` + +Agora abra: + +```text +apps/agent_gateway/app/main.py +``` + +Adicione: + +```python +import os +``` + +Troque: + +```python +backend_client = BackendClient( + timeout_seconds=settings.BACKEND_TIMEOUT_SECONDS +) +``` + +por: + +```python +backend_client = BackendClient( + timeout_seconds=settings.BACKEND_TIMEOUT_SECONDS, + basic_client_id=os.getenv("BACKEND_AUTH_CLIENT_ID"), + basic_secret=os.getenv("BACKEND_AUTH_SECRET"), +) +``` + +Isso implementa: + +```text +Agent Gateway → Agent Backend +Authorization: Basic base64(agent-gateway-test:GatewayBackend-Test-2026!) +``` + +--- + +# 5. Configurar o Agent Backend autenticado + +Entre no diretório: + +```bash +cd Tuning-Performance/Authentication/agent_template_backend_authentication +``` + +Copie o exemplo: + +```bash +cp .env.example .env +``` + +Ajuste a seção de autenticação: + +```env +# Entrada: Agent Gateway -> Agent Backend +AGENT_AUTH_ENABLED=true +AGENT_AUTH_MODE=basic +AGENT_AUTH_BASIC_CLIENT_ID=agent-gateway-test +AGENT_AUTH_BASIC_SECRET_HASH=COLE_AQUI_HASH_GATEWAY_BACKEND +AGENT_AUTH_BASIC_REALM=agent-contas + +AGENT_AUTH_PUBLIC_PATHS=/health,/docs,/openapi.json,/redoc +AGENT_AUTH_PUBLIC_PREFIXES= +``` + +Para usar o MCP Gateway: + +```env +MCP_GATEWAY_ENABLED=true +MCP_GATEWAY_URL=http://localhost:8300 +MCP_GATEWAY_TIMEOUT_SECONDS=60 + +# Saída: Agent Backend -> MCP Gateway +MCP_GATEWAY_AUTH_MODE=basic +MCP_GATEWAY_BASIC_CLIENT_ID=agent-backend-test +MCP_GATEWAY_BASIC_SECRET=BackendMcp-Test-2026! +``` + +Para evitar dependências externas durante o primeiro teste, configure também: + +```env +LLM_PROVIDER=mock +ENABLE_LANGFUSE=false +ENABLE_ANALYTICS=false + +SESSION_REPOSITORY_PROVIDER=memory +MEMORY_REPOSITORY_PROVIDER=memory +CHECKPOINT_REPOSITORY_PROVIDER=memory +CACHE_PROVIDER=memory +USAGE_REPOSITORY_PROVIDER=memory +``` + +Os nomes exatos de alguns providers podem depender do arquivo de configuração atual do framework. Caso o `.env.example` já contenha valores locais ou mock, preserve-os. + +--- + +# 6. Fazer o Backend enviar Basic Auth ao MCP Gateway + +Abra: + +```text +libs/agent_framework/src/agent_framework/gateways/mcp_gateway_client.py +``` + +Substitua a implementação por: + +```python +from __future__ import annotations + +import base64 +from typing import Any + +import httpx + + +class MCPGatewayClient: + def __init__( + self, + base_url: str, + token: str | None = None, + timeout_seconds: int = 60, + auth_mode: str | None = None, + basic_client_id: str | None = None, + basic_secret: str | None = None, + ): + self.base_url = base_url.rstrip("/") + self.token = token + self.timeout_seconds = timeout_seconds + self.auth_mode = (auth_mode or "").strip().lower() + self.basic_client_id = basic_client_id + self.basic_secret = basic_secret + + def _headers(self) -> dict[str, str]: + if ( + self.auth_mode == "basic" + and self.basic_client_id + and self.basic_secret + ): + raw = f"{self.basic_client_id}:{self.basic_secret}".encode("utf-8") + encoded = base64.b64encode(raw).decode("ascii") + return {"Authorization": f"Basic {encoded}"} + + if self.token: + return {"Authorization": f"Bearer {self.token}"} + + return {} + + async def list_tools(self) -> dict[str, Any]: + async with httpx.AsyncClient( + timeout=self.timeout_seconds + ) as client: + response = await client.get( + f"{self.base_url}/v1/tools", + headers=self._headers(), + ) + response.raise_for_status() + return response.json() + + async def invoke_tool( + self, + *, + tenant_id: str, + agent_id: str, + channel: str | None, + tool_name: str, + arguments: dict[str, Any] | None = None, + business_context: dict[str, Any] | None = None, + metadata: dict[str, Any] | None = None, + ) -> dict[str, Any]: + payload = { + "tenant_id": tenant_id, + "agent_id": agent_id, + "channel": channel, + "tool_name": tool_name, + "arguments": arguments or {}, + "business_context": business_context or {}, + "metadata": metadata or {}, + } + + async with httpx.AsyncClient( + timeout=self.timeout_seconds + ) as client: + response = await client.post( + f"{self.base_url}/v1/tools/{tool_name}/invoke", + json=payload, + headers=self._headers(), + ) + response.raise_for_status() + return response.json() +``` + +Agora abra: + +```text +libs/agent_framework/src/agent_framework/mcp/tool_router.py +``` + +Localize: + +```python +MCPGatewayClient( + base_url=getattr( + settings, + "MCP_GATEWAY_URL", + "http://localhost:8300", + ), + token=getattr(settings, "MCP_GATEWAY_TOKEN", None), + timeout_seconds=getattr( + settings, + "MCP_GATEWAY_TIMEOUT_SECONDS", + settings.MCP_TOOL_TIMEOUT_SECONDS, + ), +) +``` + +Altere para: + +```python +MCPGatewayClient( + base_url=getattr( + settings, + "MCP_GATEWAY_URL", + "http://localhost:8300", + ), + token=getattr(settings, "MCP_GATEWAY_TOKEN", None), + timeout_seconds=getattr( + settings, + "MCP_GATEWAY_TIMEOUT_SECONDS", + settings.MCP_TOOL_TIMEOUT_SECONDS, + ), + auth_mode=getattr( + settings, + "MCP_GATEWAY_AUTH_MODE", + None, + ), + basic_client_id=getattr( + settings, + "MCP_GATEWAY_BASIC_CLIENT_ID", + None, + ), + basic_secret=getattr( + settings, + "MCP_GATEWAY_BASIC_SECRET", + None, + ), +) +``` + +Adicione estes campos em: + +```text +libs/agent_framework/src/agent_framework/config/settings.py +``` + +Próximo das configurações existentes de MCP Gateway: + +```python +MCP_GATEWAY_AUTH_MODE: str | None = None +MCP_GATEWAY_BASIC_CLIENT_ID: str | None = None +MCP_GATEWAY_BASIC_SECRET: str | None = None +``` + +Há também uma factory local em: + +```text +Tuning-Performance/Authentication/ + agent_template_backend_authentication/ + app/mcp_gateway_client_factory.py +``` + +Ajuste para: + +```python +from __future__ import annotations + +import os + +from agent_framework.gateways import MCPGatewayClient + + +def build_mcp_gateway_client() -> MCPGatewayClient | None: + if os.getenv("MCP_GATEWAY_ENABLED", "true").lower() != "true": + return None + + return MCPGatewayClient( + base_url=os.getenv( + "MCP_GATEWAY_URL", + "http://localhost:8300", + ), + token=os.getenv("MCP_GATEWAY_TOKEN") or None, + timeout_seconds=int( + os.getenv("MCP_GATEWAY_TIMEOUT_SECONDS", "60") + ), + auth_mode=os.getenv("MCP_GATEWAY_AUTH_MODE"), + basic_client_id=os.getenv( + "MCP_GATEWAY_BASIC_CLIENT_ID" + ), + basic_secret=os.getenv( + "MCP_GATEWAY_BASIC_SECRET" + ), + ) +``` + +--- + +# 7. Configurar o MCP Gateway + +Entre no diretório: + +```bash +cd apps/mcp_gateway +``` + +Crie `.env`: + +```bash +cp .env.example .env +``` + +Adicione: + +```env +# Entrada: Agent Backend -> MCP Gateway +MCP_GATEWAY_AUTH_ENABLED=true +MCP_GATEWAY_AUTH_MODE=basic +MCP_GATEWAY_AUTH_BASIC_CLIENT_ID=agent-backend-test +MCP_GATEWAY_AUTH_BASIC_SECRET_HASH=COLE_AQUI_HASH_BACKEND_MCP +MCP_GATEWAY_AUTH_BASIC_REALM=mcp-gateway + +MCP_GATEWAY_AUTH_PUBLIC_PATHS=/health,/ready,/docs,/openapi.json,/redoc +MCP_GATEWAY_AUTH_PUBLIC_PREFIXES= + +MCP_GATEWAY_CONFIG_PATH=config/mcp_gateway.yaml +``` + +## Desabilitar o mecanismo Bearer legado + +O MCP Gateway ainda possui um segundo mecanismo antigo, configurado dentro de: + +```text +apps/mcp_gateway/config/mcp_gateway.yaml +``` + +Localize a seção: + +```yaml +auth: + enabled: true +``` + +Altere para: + +```yaml +auth: + enabled: false +``` + +Isso é necessário porque o novo middleware já faz a autenticação Basic. Caso o `auth_check()` legado continue habilitado, a requisição passará pelo Basic e depois será rejeitada por não possuir Bearer Token. + +--- + +# 8. Subir os componentes + +Use quatro terminais. + +## Terminal 1 — MCP Servers + +O MCP Gateway precisa ter pelo menos um servidor MCP disponível para demonstrar uma chamada real. + +Na raiz do projeto: + +```bash +source .venv/bin/activate +``` + +Suba o servidor telecom: + +```bash +uvicorn mcp.servers.telecom_mcp_server.main:app \ + --host 0.0.0.0 \ + --port 8100 \ + --reload +``` + +Em outro terminal, caso queira também o retail: + +```bash +uvicorn mcp.servers.retail_mcp_server.main:app \ + --host 0.0.0.0 \ + --port 8200 \ + --reload +``` + +Confira as URLs configuradas em: + +```text +apps/mcp_gateway/config/mcp_gateway.yaml +``` + +Para execução local, devem apontar para: + +```yaml +url: http://localhost:8100 +``` + +e: + +```yaml +url: http://localhost:8200 +``` + +--- + +## Terminal 2 — MCP Gateway + +```bash +cd apps/mcp_gateway +source ../../.venv/bin/activate +``` + +Suba usando `--env-file`. Isso é importante porque o middleware lê variáveis com `os.getenv()`: + +```bash +uvicorn app.main:app \ + --host 0.0.0.0 \ + --port 8300 \ + --reload \ + --env-file .env +``` + +Teste a saúde pública: + +```bash +curl http://localhost:8300/health +``` + +Teste um endpoint protegido sem credencial: + +```bash +curl -i http://localhost:8300/v1/tools +``` + +Esperado: + +```text +HTTP/1.1 401 Unauthorized +``` + +Teste com Basic Auth: + +```bash +curl -i \ + -u 'agent-backend-test:BackendMcp-Test-2026!' \ + http://localhost:8300/v1/tools +``` + +Esperado: + +```text +HTTP/1.1 200 OK +``` + +--- + +## Terminal 3 — Agent Backend + +```bash +cd Tuning-Performance/Authentication/agent_template_backend_authentication +source ../../../.venv/bin/activate +``` + +Suba: + +```bash +uvicorn app.main:app \ + --host 0.0.0.0 \ + --port 8000 \ + --reload \ + --env-file .env +``` + +Teste saúde: + +```bash +curl http://localhost:8000/health +``` + +Teste endpoint protegido sem credencial: + +```bash +curl -i http://localhost:8000/agents +``` + +Esperado: + +```text +HTTP/1.1 401 Unauthorized +``` + +Teste com a credencial usada pelo Agent Gateway: + +```bash +curl -i \ + -u 'agent-gateway-test:GatewayBackend-Test-2026!' \ + http://localhost:8000/agents +``` + +Esperado: + +```text +HTTP/1.1 200 OK +``` + +Teste mensagem diretamente: + +```bash +curl -X POST http://localhost:8000/gateway/message \ + -u 'agent-gateway-test:GatewayBackend-Test-2026!' \ + -H 'Content-Type: application/json' \ + -d '{ + "channel": "web", + "agent_id": "telecom_contas", + "tenant_id": "default", + "payload": { + "text": "Quero consultar minha fatura", + "session_id": "teste-backend-001", + "user_id": "user-001", + "customer_id": "12345", + "message_id": "msg-001" + } + }' +``` + +--- + +## Terminal 4 — Agent Gateway + +```bash +cd apps/agent_gateway +source ../../.venv/bin/activate +``` + +Suba: + +```bash +uvicorn app.main:app \ + --host 0.0.0.0 \ + --port 8010 \ + --reload \ + --env-file .env +``` + +Teste saúde: + +```bash +curl http://localhost:8010/health +``` + +Teste endpoint protegido sem credencial: + +```bash +curl -i http://localhost:8010/backends +``` + +Esperado: + +```text +HTTP/1.1 401 Unauthorized +``` + +Teste com a credencial externa: + +```bash +curl -i \ + -u 'tia-test:TiaGateway-Test-2026!' \ + http://localhost:8010/backends +``` + +Esperado: + +```text +HTTP/1.1 200 OK +``` + +--- + +# 9. Validar o circuito completo + +Force o backend `contas` para evitar que o roteador selecione um backend não iniciado: + +```bash +curl -X POST http://localhost:8010/gateway/message \ + -u 'tia-test:TiaGateway-Test-2026!' \ + -H 'Content-Type: application/json' \ + -d '{ + "channel": "web", + "backend_id": "contas", + "tenant_id": "default", + "agent_id": "telecom_contas", + "session_id": "circuito-basic-001", + "payload": { + "text": "Quero consultar minha fatura", + "session_id": "circuito-basic-001", + "user_id": "user-001", + "customer_id": "12345", + "message_id": "msg-circuito-001" + } + }' +``` + +O circuito esperado é: + +```text +curl + │ Basic tia-test + ▼ +Agent Gateway :8010 + │ Basic agent-gateway-test + ▼ +Agent Backend :8000 + │ Basic agent-backend-test + ▼ +MCP Gateway :8300 + ▼ +MCP Server :8100 ou :8200 +``` + +--- + +# 10. Como comprovar cada autenticação + +Faça testes negativos em cada trecho. + +## Secret externo incorreto + +```bash +curl -i \ + -u 'tia-test:senha-errada' \ + http://localhost:8010/backends +``` + +Resultado esperado: + +```text +401 Unauthorized +``` + +## Secret do gateway para backend incorreto + +Altere temporariamente no `apps/agent_gateway/.env`: + +```env +BACKEND_AUTH_SECRET=senha-errada +``` + +Reinicie o Agent Gateway e envie uma mensagem. + +O gateway deverá retornar erro de backend, normalmente: + +```text +502 Bad Gateway +``` + +O erro interno será originado por um: + +```text +401 Unauthorized +``` + +do Agent Backend. + +## Secret do backend para MCP incorreto + +Altere temporariamente: + +```env +MCP_GATEWAY_BASIC_SECRET=senha-errada +``` + +Reinicie o backend e execute uma frase que acione uma ferramenta MCP. + +O backend deverá registrar falha na chamada ao MCP Gateway com: + +```text +401 Unauthorized +``` + +--- + +# 11. Verificação rápida de portas + +No Linux ou WSL: + +```bash +ss -lntp | grep -E ':8000|:8010|:8100|:8200|:8300' +``` + +No Windows PowerShell: + +```powershell +Get-NetTCPConnection -State Listen | + Where-Object LocalPort -in 8000,8010,8100,8200,8300 | + Sort-Object LocalPort +``` + +Você deverá ver: + +```text +8000 Agent Backend +8010 Agent Gateway +8100 Telecom MCP Server +8200 Retail MCP Server +8300 MCP Gateway +``` + +## Observação importante + +O segredo original precisa existir no componente cliente: + +```text +TIA ou curl: + TiaGateway-Test-2026! + +Agent Gateway: + GatewayBackend-Test-2026! + +Agent Backend: + BackendMcp-Test-2026! +``` + +Os componentes servidores armazenam apenas os hashes: + +```text +Agent Gateway: + hash de TiaGateway-Test-2026! + +Agent Backend: + hash de GatewayBackend-Test-2026! + +MCP Gateway: + hash de BackendMcp-Test-2026! +``` + +Em produção, os segredos originais e hashes devem vir de Vault ou Kubernetes Secret, não de arquivos `.env`. diff --git a/agent_framework_oci/Tuning-Performance/Authentication/agent_template_backend_authentication/app/agents/runtime.py b/agent_framework_oci/Tuning-Performance/Authentication/agent_template_backend_authentication/app/agents/runtime.py index e6429c4..7a1a9be 100644 --- a/agent_framework_oci/Tuning-Performance/Authentication/agent_template_backend_authentication/app/agents/runtime.py +++ b/agent_framework_oci/Tuning-Performance/Authentication/agent_template_backend_authentication/app/agents/runtime.py @@ -3,5 +3,8 @@ from __future__ import annotations # Compatibilidade local do template/backend. # A implementação oficial agora fica no framework para evitar duplicação entre agentes. from agent_framework.runtime import AgentRuntimeMixin, MessageBuilder, RuntimeContext +from app.presentation import register_tool_renderers + +register_tool_renderers() __all__ = ["AgentRuntimeMixin", "MessageBuilder", "RuntimeContext"] diff --git a/agent_framework_oci/Tuning-Performance/Authentication/agent_template_backend_authentication/app/presentation/__init__.py b/agent_framework_oci/Tuning-Performance/Authentication/agent_template_backend_authentication/app/presentation/__init__.py new file mode 100644 index 0000000..c0eba0d --- /dev/null +++ b/agent_framework_oci/Tuning-Performance/Authentication/agent_template_backend_authentication/app/presentation/__init__.py @@ -0,0 +1,3 @@ +from .tool_renderers import register_tool_renderers + +__all__ = ["register_tool_renderers"] diff --git a/agent_framework_oci/Tuning-Performance/Authentication/agent_template_backend_authentication/app/presentation/__pycache__/tool_renderers.cpython-313.pyc b/agent_framework_oci/Tuning-Performance/Authentication/agent_template_backend_authentication/app/presentation/__pycache__/tool_renderers.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0c79403de000304b0a34d273486421308878347d GIT binary patch literal 4405 zcmb_fO>7&-6`tkpa+m-5qpZJ5D_gQnS3hN+gJjk91*M{zJ*ctIgcq$1XIjJOqBv8o(l1L?Y#20Z<$+O@N`M)Ad zh8W8utEy(mMoLq4XtLw#3jB3pWg(>-3XU6^mX2dZUxI!G1U0E(1t%CXyj(c=XAxqa z=0JFaI#I0J8$}~!Il=_cP0%`AB8~_?L>P9g#8!a(sMH+SpNcJNnp_r@kZGUFn z(S>@@JQ`!W&^#03!dZ6UrFn}Pu$aCOZ}IbKO*Sk6D@$oPp;)e4D@)1*#u~QV-;>js zvdroRhK=*f_0Qa0p4c|lQ)ctTSRS&xIP;8bGYEz2YEdm6r5)|$ui zqC(nnEs+|$l~GgbLjUUup4afAtR|Gf@r>~%OqWVfx0gp5$|4wODDgQtaTnYimk((z zEe$TgLBK$JSovh^1JMVTRxEdXQB#$b_#95-I@o~-KYbjk9D3ql`L?}=V|o5(eRkmf%B$#{$G3E;Lo$B=lD~^fM%d!edOKjXJYFU7Mfq{UYOfGEvqKu#GZMvqO9jfW zQXZAC0HZzz9m_?xq=NS>C+rjyEMAA*Du7bz|Fk@(q;;~S1O*2`u$pa5#tkK{B(%kN zN?q1c2?e)6CsELekV7S(|G^I)ESl|Sx0<)aZN~JBn%wA9=tH&lA_4{;p(t~cVBt`S zFcnySgtzOd4vXE)exf2xgbJOzUI|&MxC&tFvM2$ zB@`9r;1G_`7o!5$=GfPcxNefOJ5-|8^&{?n=!5g~ge@M>scN_ZK4gerXQhaek?2S1 z@yC+oNvXgWs$#?!<}4>Uwv3+T;6$V>D_wsjE7+f;tfS99@(^pW3yNVm<)tOSyT#qn zQff%V1Vk7%jc_xmj*+SzDzHGthK@VPhi^co6MPdOkYaHOFxYXx7w{H32Ecs&I-{$I#iIhiGkUU6nP)nA6|@ zQj)NL2@N7ugr6%${6b4qjFF?Kr4ls6tedlNwCXR%hNHRy?f}du2`8# zLN{^FN7gkfy{;rvNlnVSMx`<*&=6pGAogk`<1plOwhm&mh9%k+Y=AJ-7IF>*E{*~vL>y3^3 z8+W!`+b6eMKB+f-ubSSgz+h#vd#mW}rDRtSTFS&^9y|4G_tr@9^hNX3=ytamyu2fh zRrCot?s|JSUV=f=@mzRMs9*2>Mboa(38eSurq%~n_X4f?o{zZQKyM+?TWaa}Kzv`^ zXfL+(@3!39YWiKvZ(Fuc7SD}C>yul5ocY7dr^@5_L;j1Fj&;5iXv$B09ynR5>)fsD zE!6dXl-TV3@Xnv=&i&nof^GlwBeA){o^Nb4{i^kst(#Yh-J^xz=ys$K{PvDGUh??Y zF05WypLq9MCfD{NheC#JbLd||_&;%IZQiOf+mY|(2}VI zEskZ#ZJ+xyy4ij92pS}v!3wJ%({@(3}w@vA6F?cQ)E?<4KB~z)*{yoW@Lj`CSeADlyhdOd;^0S9k#|6N^xVTP!okxD#g2$j-|*cDOLe8{wVd>pR@! zLDAOuoD0(h!Xb{v2TUAH9y{ str: + try: + return f"{float(value):.2f}".replace(".", ",") + except (TypeError, ValueError): + return str(value) + + +def render_telecom_invoice(*, tool_name: str, result: dict[str, Any], state: dict[str, Any], agent_label: str) -> str | 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: + plano = result.get("plano") + if plano is None: + return None + parts = [f"[{agent_label}] Seu plano é {plano}"] + internet_gb = result.get("internet_gb") + status = result.get("status") + if internet_gb is not None: + parts.append(f"com {internet_gb} GB") + if status is not None: + parts.append(f"status {status}") + return ", ".join(parts) + "." + + +def render_retail_order(*, tool_name: str, result: dict[str, Any], state: dict[str, Any], agent_label: str) -> str | None: + order_id = result.get("order_id") + status = result.get("status") + if order_id is None or status is None: + return None + lines = [f"[{agent_label}] Pedido {order_id}: status {status}."] + total = result.get("valor_total") + if total is not None: + lines.append(f"Valor total: R$ {_money_brl(total)}.") + items = result.get("itens") or [] + rendered_items: list[str] = [] + if isinstance(items, list): + for item in items: + if isinstance(item, dict): + value = item.get("descricao") or item.get("nome") or item.get("sku") + else: + value = item + if value not in (None, ""): + rendered_items.append(str(value)) + if rendered_items: + lines.append("Itens: " + "; ".join(rendered_items) + ".") + return " ".join(lines) + + +def render_retail_delivery(*, tool_name: str, result: dict[str, Any], state: dict[str, Any], agent_label: str) -> str | None: + order_id = result.get("order_id") + transportadora = result.get("transportadora") + codigo = result.get("codigo_rastreio") + previsao = result.get("previsao_entrega") + if any(v is None for v in (order_id, transportadora, codigo, previsao)): + return None + return ( + f"[{agent_label}] Entrega do pedido {order_id}: transportadora {transportadora}, " + f"rastreio {codigo}, previsão {previsao}." + ) + + +def register_tool_renderers() -> None: + register_tool_response_renderer("telecom.invoice", render_telecom_invoice) + register_tool_response_renderer("telecom.plan", render_telecom_plan) + register_tool_response_renderer("retail.order", render_retail_order) + register_tool_response_renderer("retail.delivery", render_retail_delivery) diff --git a/agent_framework_oci/Tuning-Performance/Authentication/agent_template_backend_authentication/config/mcp_parameter_mapping.yaml b/agent_framework_oci/Tuning-Performance/Authentication/agent_template_backend_authentication/config/mcp_parameter_mapping.yaml index 5b29ccf..91d57af 100644 --- a/agent_framework_oci/Tuning-Performance/Authentication/agent_template_backend_authentication/config/mcp_parameter_mapping.yaml +++ b/agent_framework_oci/Tuning-Performance/Authentication/agent_template_backend_authentication/config/mcp_parameter_mapping.yaml @@ -60,6 +60,18 @@ mcp_parameter_mapping: mensagem. pattern: (?i)\\b(?:pedido|order)\\s*[:#-]?\\s*([A-Z0-9-]+)\\b group: 1 + cancelar_pedido: + map: + session_key: session_id + extract: + order_id: + from: message + type: string + strategy: hybrid + description: Extraia somente o identificador do pedido informado explicitamente pelo usuário. Retorne null quando não houver identificador de pedido na mensagem. + pattern: (?i)\\b(?:pedido|order)\\s*[:#-]?\\s*([A-Z0-9-]+)\\b + group: 1 + solicitar_troca: map: session_key: session_id diff --git a/agent_framework_oci/Tuning-Performance/Authentication/agent_template_backend_authentication/config/routing.yaml b/agent_framework_oci/Tuning-Performance/Authentication/agent_template_backend_authentication/config/routing.yaml index 2dbe95e..03aeaa9 100644 --- a/agent_framework_oci/Tuning-Performance/Authentication/agent_template_backend_authentication/config/routing.yaml +++ b/agent_framework_oci/Tuning-Performance/Authentication/agent_template_backend_authentication/config/routing.yaml @@ -79,6 +79,25 @@ intents: - Quero saber sobre meu pacote de internet. - Tenho roaming internacional? + + - name: retail_order_cancel + domain: retail + agent: orders_agent + description: Cancelamento explícito de pedido ou compra. + priority: 20 + mcp_tools: + - consultar_pedido + - cancelar_pedido + keywords: + - cancelar pedido + - cancelamento do pedido + - cancelar a compra + - cancelar compra + examples: + - Quero cancelar meu pedido. + - Cancele o pedido. + - Quero cancelar a compra. + - name: retail_order_tracking domain: retail agent: orders_agent diff --git a/agent_framework_oci/Tuning-Performance/Authentication/agent_template_backend_authentication/config/tool_policies.yaml b/agent_framework_oci/Tuning-Performance/Authentication/agent_template_backend_authentication/config/tool_policies.yaml index 3c4fd05..9b1ab9e 100644 --- a/agent_framework_oci/Tuning-Performance/Authentication/agent_template_backend_authentication/config/tool_policies.yaml +++ b/agent_framework_oci/Tuning-Performance/Authentication/agent_template_backend_authentication/config/tool_policies.yaml @@ -7,6 +7,12 @@ defaults: require_confirmation: false tool_policies: + cancelar_pedido: + operation_type: transactional + require_confirmation: true + requires: [order_id] + + solicitar_troca: operation_type: transactional require_confirmation: true diff --git a/agent_framework_oci/Tuning-Performance/Authentication/agent_template_backend_authentication/config/tools.yaml b/agent_framework_oci/Tuning-Performance/Authentication/agent_template_backend_authentication/config/tools.yaml index d85fae1..f8a53ca 100644 --- a/agent_framework_oci/Tuning-Performance/Authentication/agent_template_backend_authentication/config/tools.yaml +++ b/agent_framework_oci/Tuning-Performance/Authentication/agent_template_backend_authentication/config/tools.yaml @@ -10,6 +10,9 @@ tools: - fatura - conta - boleto + response: + mode: renderer + renderer: telecom.invoice consultar_pagamentos: description: Consulta histórico de pagamentos do cliente. mcp_server: telecom @@ -28,6 +31,9 @@ tools: asset_id: string selection_keywords: - plano + response: + mode: renderer + renderer: telecom.plan listar_servicos: description: Lista serviços ativos e adicionais VAS. mcp_server: telecom @@ -49,6 +55,9 @@ tools: - consultar pedido - status do pedido - pedido + response: + mode: renderer + renderer: retail.order consultar_entrega: description: Consulta entrega e rastreamento do pedido. mcp_server: retail @@ -61,6 +70,26 @@ tools: - rastreamento - transportadora - previsão + response: + mode: renderer + renderer: retail.delivery + cancelar_pedido: + description: Simula o cancelamento de um pedido de varejo. + mcp_server: retail + enabled: true + tool_type: action + requires: + - order_id + confirmation_required: true + args_schema: + order_id: string + selection_keywords: + - cancelar pedido + - cancelamento do pedido + - cancelar compra + - cancelar a compra + + solicitar_troca: description: Simula abertura de solicitação de troca. mcp_server: retail diff --git a/agent_framework_oci/Tuning-Performance/Deterministic_Transactional_Workflow/agent_template_backend/app/presentation/__init__.py b/agent_framework_oci/Tuning-Performance/Deterministic_Transactional_Workflow/agent_template_backend/app/presentation/__init__.py new file mode 100644 index 0000000..c0eba0d --- /dev/null +++ b/agent_framework_oci/Tuning-Performance/Deterministic_Transactional_Workflow/agent_template_backend/app/presentation/__init__.py @@ -0,0 +1,3 @@ +from .tool_renderers import register_tool_renderers + +__all__ = ["register_tool_renderers"] diff --git a/agent_framework_oci/Tuning-Performance/Deterministic_Transactional_Workflow/agent_template_backend/app/presentation/__pycache__/tool_renderers.cpython-313.pyc b/agent_framework_oci/Tuning-Performance/Deterministic_Transactional_Workflow/agent_template_backend/app/presentation/__pycache__/tool_renderers.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..009b7c12fbc13a60978eabb33f4e2eeba0d9df9c GIT binary patch literal 4412 zcmb_fO>7&-6`tkpa+m-5qfGr&TG^6qy85vr$+2ZitrN>urJ4y$vr$Y4#EM+0w5eTT zb|qVEQ?Nl$SO^NqXpJyHfv8A;DnJkFp{Nc$r0}6RE<>dvwki;`$RRfuc8fNrzL_N{ zOQwn*Isk`ncHaEG_s#d-JoWk92+DZkCwB%t2>p#TD#c+7%+nMIk5CjvnJF~MU`8Uc zW6CkfVwTG66gSCZ9%N6HYejcB?2LM&Je35HoKzA)5~$WjLlOyfc8!d5XMH+GlNcJNnp}4E^ZGUFn z(TTdz92#Xi(Hs-zB3ZWor8$e~x0v2AZ}D>(O*Sk6D~lO9saURCD~rlF#u~QV-;*;- zWtr6t3f5=lfn)@SKJhWHqS_Tvfob3uzTB471$AvZ~8T;sH66cmu}4j_;M{ zGL!|_wxJ|u<>Xy3{(!u=IIsx*fbCGH4U`>Z`$g|xT(R7V1x-~}60);?F{PZhO z<&@$C{fXT`Zz0gT8QnTj44gN`^Z(lO27jJ4J;$FS1~dZ=>%;G6 zKNDM?u+aQk_rff1w|Als+D6&mGox%0+O!a_@$jQKXaWIH%*0qfpf|=q%?|S22z+BP z@oaELx+WV-SeC$^`clS_Q}T#}1sL@)=vXd#Bo&NkIpL(BVDUPfRspb5H)P~lC8Lui zB`7!mg4Jw8GhrwhC8;eW((1C7PAWJAokT$=LJpOD{s%vJuwb^G-D=(vw;9tjVsax- zp%2wQiwID7gksE10*ON<%2d#;axsqFiFtBfa%wil`OzRZz^MEYW4Y>B=MfrwRYQn5 zXM+gE_?kD!8FRvl!XR7GmrzWY1t%P#FUADen`2))>bgmMcc{dw>qp&v&1>dBw1tfNTJ`#of`;YFNYsL>LZ@a5Jfnk*W#lbzH5Lzl-_wvj6@0-C>JL2h*C$M&L_2PQ0=xNI*3!W~M>%uLts{;@u_kmugZJ@{h z34*mjT6Hu)k(-4XV|*E^EQKmS7vRIkc&MF&0zmdCKnfMer~&}217>p81f&?R!YNiA zLuY>;qP2JHs;n`}oCX7sl7jO~XaK1q{9JKj7g}OsoVcErN(iZpk>7#ciH&IDM+m9z z=f=3>Gz^nLFN}Ew#<*)bnGlLe738 z1^aTMpC0wk;?str>Xs{|=t&5|vSx9r2BCu0?=FQM5esF7?+}dtL;UUoPB4hf&{XkQJ;97Pyn?F+w^yDTE zb5Eck9Lt}7f9yHtdUNCc#+@zK_Q~zgC-tW9RnvPF7_3ZoZxy{glc=dM8OlUskB{=@XA%HzaC{)Uus(ZuWe5=TCL#{_aD;)_?ku*j!=HH#eGo)$+@h&9P$F zNFg|~9W4aEy(3;JdHib^RxhlNzxyqdYkiSJApB|r{AL1I(aQR#1_Ec{z009yUCuM7avb9Lr+C>Aun}qYIXV3$;%^Sf4q?X?x zN#&x3A-B@7Yz2~9Dm||yuncLglGdy`$RU^0x~wH2k%VMlK9JFq?G2KQo^0U+Pzaa~ zV&{a2kX9c>-$l#l5f20dR7wbD9=*&$=FLPfiLYUY<>)_aG0Qq|7pjD0*JYA5-(SRI zR=6CU%dk%=ne?)PSNbn!w4|KT$NHUcG=-G)K;lt0gS12v+Fr>v#^VpQa!TT$jA5}dJcep# zBE-u0JXDs`HmxOAELtNUsU)X|PK>X>1Q+3_uR`_0T@SXscl+UOQ#xA=p36nbSKkbU zi@r0Eci6mOw)PeSeYuG}!Ci1qY6(+a_Km9CJIkd-}FuR9$ zUcRxzML^z&>w#MgNgf0*Xb2L6+Vqo&vfme}A!%*05M<5!KNEZCHpM&RrUGW|NJ}CHWvw>HEl+0aoBL;6z$Zjz4P;GHuV!x*6v`S~=!5hMMU=9`vsK literal 0 HcmV?d00001 diff --git a/agent_framework_oci/Tuning-Performance/Deterministic_Transactional_Workflow/agent_template_backend/app/presentation/tool_renderers.py b/agent_framework_oci/Tuning-Performance/Deterministic_Transactional_Workflow/agent_template_backend/app/presentation/tool_renderers.py new file mode 100644 index 0000000..f77c47a --- /dev/null +++ b/agent_framework_oci/Tuning-Performance/Deterministic_Transactional_Workflow/agent_template_backend/app/presentation/tool_renderers.py @@ -0,0 +1,74 @@ +from __future__ import annotations + +from typing import Any + +from agent_framework.presentation import register_tool_response_renderer + + +def _money_brl(value: Any) -> str: + try: + return f"{float(value):.2f}".replace(".", ",") + except (TypeError, ValueError): + return str(value) + + +def render_telecom_invoice(*, tool_name: str, result: dict[str, Any], state: dict[str, Any], agent_label: str) -> str | 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: + plano = result.get("plano") + if plano is None: + return None + parts = [f"[{agent_label}] Seu plano é {plano}"] + internet_gb = result.get("internet_gb") + status = result.get("status") + if internet_gb is not None: + parts.append(f"com {internet_gb} GB") + if status is not None: + parts.append(f"status {status}") + return ", ".join(parts) + "." + + +def render_retail_order(*, tool_name: str, result: dict[str, Any], state: dict[str, Any], agent_label: str) -> str | None: + order_id = result.get("order_id") + status = result.get("status") + if order_id is None or status is None: + return None + lines = [f"[{agent_label}] Pedido {order_id}: status {status}."] + total = result.get("valor_total") + if total is not None: + lines.append(f"Valor total: R$ {_money_brl(total)}.") + items = result.get("itens") or [] + rendered_items: list[str] = [] + if isinstance(items, list): + for item in items: + if isinstance(item, dict): + value = item.get("descricao") or item.get("nome") or item.get("sku") + else: + value = item + if value not in (None, ""): + rendered_items.append(str(value)) + if rendered_items: + lines.append("Itens: " + "; ".join(rendered_items) + ".") + return " ".join(lines) + + +def render_retail_delivery(*, tool_name: str, result: dict[str, Any], state: dict[str, Any], agent_label: str) -> str | None: + order_id = result.get("order_id") + transportadora = result.get("transportadora") + codigo = result.get("codigo_rastreio") + previsao = result.get("previsao_entrega") + if any(v is None for v in (order_id, transportadora, codigo, previsao)): + return None + return ( + f"[{agent_label}] Entrega do pedido {order_id}: transportadora {transportadora}, " + f"rastreio {codigo}, previsão {previsao}." + ) + + +def register_tool_renderers() -> None: + register_tool_response_renderer("telecom.invoice", render_telecom_invoice) + register_tool_response_renderer("telecom.plan", render_telecom_plan) + register_tool_response_renderer("retail.order", render_retail_order) + register_tool_response_renderer("retail.delivery", render_retail_delivery) diff --git a/agent_framework_oci/Tuning-Performance/Deterministic_Transactional_Workflow/agent_template_backend/config/mcp_parameter_mapping.yaml b/agent_framework_oci/Tuning-Performance/Deterministic_Transactional_Workflow/agent_template_backend/config/mcp_parameter_mapping.yaml index 5b29ccf..91d57af 100644 --- a/agent_framework_oci/Tuning-Performance/Deterministic_Transactional_Workflow/agent_template_backend/config/mcp_parameter_mapping.yaml +++ b/agent_framework_oci/Tuning-Performance/Deterministic_Transactional_Workflow/agent_template_backend/config/mcp_parameter_mapping.yaml @@ -60,6 +60,18 @@ mcp_parameter_mapping: mensagem. pattern: (?i)\\b(?:pedido|order)\\s*[:#-]?\\s*([A-Z0-9-]+)\\b group: 1 + cancelar_pedido: + map: + session_key: session_id + extract: + order_id: + from: message + type: string + strategy: hybrid + description: Extraia somente o identificador do pedido informado explicitamente pelo usuário. Retorne null quando não houver identificador de pedido na mensagem. + pattern: (?i)\\b(?:pedido|order)\\s*[:#-]?\\s*([A-Z0-9-]+)\\b + group: 1 + solicitar_troca: map: session_key: session_id diff --git a/agent_framework_oci/Tuning-Performance/Deterministic_Transactional_Workflow/agent_template_backend/config/routing.yaml b/agent_framework_oci/Tuning-Performance/Deterministic_Transactional_Workflow/agent_template_backend/config/routing.yaml index 2dbe95e..03aeaa9 100644 --- a/agent_framework_oci/Tuning-Performance/Deterministic_Transactional_Workflow/agent_template_backend/config/routing.yaml +++ b/agent_framework_oci/Tuning-Performance/Deterministic_Transactional_Workflow/agent_template_backend/config/routing.yaml @@ -79,6 +79,25 @@ intents: - Quero saber sobre meu pacote de internet. - Tenho roaming internacional? + + - name: retail_order_cancel + domain: retail + agent: orders_agent + description: Cancelamento explícito de pedido ou compra. + priority: 20 + mcp_tools: + - consultar_pedido + - cancelar_pedido + keywords: + - cancelar pedido + - cancelamento do pedido + - cancelar a compra + - cancelar compra + examples: + - Quero cancelar meu pedido. + - Cancele o pedido. + - Quero cancelar a compra. + - name: retail_order_tracking domain: retail agent: orders_agent diff --git a/agent_framework_oci/Tuning-Performance/Deterministic_Transactional_Workflow/agent_template_backend/config/tool_policies.yaml b/agent_framework_oci/Tuning-Performance/Deterministic_Transactional_Workflow/agent_template_backend/config/tool_policies.yaml index 3c4fd05..9b1ab9e 100644 --- a/agent_framework_oci/Tuning-Performance/Deterministic_Transactional_Workflow/agent_template_backend/config/tool_policies.yaml +++ b/agent_framework_oci/Tuning-Performance/Deterministic_Transactional_Workflow/agent_template_backend/config/tool_policies.yaml @@ -7,6 +7,12 @@ defaults: require_confirmation: false tool_policies: + cancelar_pedido: + operation_type: transactional + require_confirmation: true + requires: [order_id] + + solicitar_troca: operation_type: transactional require_confirmation: true diff --git a/agent_framework_oci/Tuning-Performance/Deterministic_Transactional_Workflow/agent_template_backend/config/tools.yaml b/agent_framework_oci/Tuning-Performance/Deterministic_Transactional_Workflow/agent_template_backend/config/tools.yaml index d85fae1..f8a53ca 100644 --- a/agent_framework_oci/Tuning-Performance/Deterministic_Transactional_Workflow/agent_template_backend/config/tools.yaml +++ b/agent_framework_oci/Tuning-Performance/Deterministic_Transactional_Workflow/agent_template_backend/config/tools.yaml @@ -10,6 +10,9 @@ tools: - fatura - conta - boleto + response: + mode: renderer + renderer: telecom.invoice consultar_pagamentos: description: Consulta histórico de pagamentos do cliente. mcp_server: telecom @@ -28,6 +31,9 @@ tools: asset_id: string selection_keywords: - plano + response: + mode: renderer + renderer: telecom.plan listar_servicos: description: Lista serviços ativos e adicionais VAS. mcp_server: telecom @@ -49,6 +55,9 @@ tools: - consultar pedido - status do pedido - pedido + response: + mode: renderer + renderer: retail.order consultar_entrega: description: Consulta entrega e rastreamento do pedido. mcp_server: retail @@ -61,6 +70,26 @@ tools: - rastreamento - transportadora - previsão + response: + mode: renderer + renderer: retail.delivery + cancelar_pedido: + description: Simula o cancelamento de um pedido de varejo. + mcp_server: retail + enabled: true + tool_type: action + requires: + - order_id + confirmation_required: true + args_schema: + order_id: string + selection_keywords: + - cancelar pedido + - cancelamento do pedido + - cancelar compra + - cancelar a compra + + solicitar_troca: description: Simula abertura de solicitação de troca. mcp_server: retail diff --git a/agent_framework_oci/Tuning-Performance/Long_Term_Memory/templates/agent_template_backend/app/agents/runtime.py b/agent_framework_oci/Tuning-Performance/Long_Term_Memory/templates/agent_template_backend/app/agents/runtime.py index e6429c4..7a1a9be 100644 --- a/agent_framework_oci/Tuning-Performance/Long_Term_Memory/templates/agent_template_backend/app/agents/runtime.py +++ b/agent_framework_oci/Tuning-Performance/Long_Term_Memory/templates/agent_template_backend/app/agents/runtime.py @@ -3,5 +3,8 @@ from __future__ import annotations # Compatibilidade local do template/backend. # A implementação oficial agora fica no framework para evitar duplicação entre agentes. from agent_framework.runtime import AgentRuntimeMixin, MessageBuilder, RuntimeContext +from app.presentation import register_tool_renderers + +register_tool_renderers() __all__ = ["AgentRuntimeMixin", "MessageBuilder", "RuntimeContext"] diff --git a/agent_framework_oci/Tuning-Performance/Long_Term_Memory/templates/agent_template_backend/app/presentation/__init__.py b/agent_framework_oci/Tuning-Performance/Long_Term_Memory/templates/agent_template_backend/app/presentation/__init__.py new file mode 100644 index 0000000..c0eba0d --- /dev/null +++ b/agent_framework_oci/Tuning-Performance/Long_Term_Memory/templates/agent_template_backend/app/presentation/__init__.py @@ -0,0 +1,3 @@ +from .tool_renderers import register_tool_renderers + +__all__ = ["register_tool_renderers"] diff --git a/agent_framework_oci/Tuning-Performance/Long_Term_Memory/templates/agent_template_backend/app/presentation/__pycache__/tool_renderers.cpython-313.pyc b/agent_framework_oci/Tuning-Performance/Long_Term_Memory/templates/agent_template_backend/app/presentation/__pycache__/tool_renderers.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..32cbdf804cb8637d1026aa386d7d188a32214831 GIT binary patch literal 4402 zcmb_fO>7&-6`tkpa+m-5qpZJ5D_gQnS3hP6lxF@7J@=DS|bclASx1|3fhBust!G*@S!;_L!~0NDiE~DAvYIxi#DgenI$Pp zrivaq0EcgO-psst^Ue3(JPicA2+ElJlRE=Gg#Jbv<>GP#=4lFqM<|A3%p{s%Fe4G! zHR+mQF-v83lAGW$53(=DwV*p3cE|iNo=O5pZYqf&2~_fcBvQ#63&cEB^38c8!LP`Y z5yti@nx>nInbtJ}n(P&A8U8x3I+r#~70afsXJo7z3(&8Eprur-;v_?cmkI~}EJDoF z6%Zbwc9f{}#?eqojxiy06SNMOm@CE(mG<9-I#GhmMoYq7mIhq{Qi2FcDB&r8+n?ER zb)YUZi$>TEG|NP|XqN4JY1U@?Y^Eo|+x%=sS4>;L>Ow|Is;GN)>$oYXZ_F=UWcoKEh$Wobyhr{lXNty!$h ztE4UK$#nm%MJ=t(^}eCvSsl+ST2k$QP1ok+TPmKHZ>aM+UhX&5c`(jYjnWL|wmhRG z?}E$wm4$`=1vmvTf*w_W=~$f8F!~mjZLd79YwEH*gEP1W%opKjT!Cr@J#n#o%U<2F z9RIVPoMF|T*bVjMLp__ZtrLaNc}qP1uRVYG=UK~l{3&8UGgP-e^ltVuvH1xL&94nV z%<^_y2l}9Og#A4;!X}|j3ppzue)RMkKmhDAaW)8;jWbZQ1AG^P6S0{@Hasm|Q_MxI zNZ>_dF=HwzWmv)jjQSXKY!BU%2ClQ+uv1X5c>{K<0z|3vGs=vbG02h<6dVGhp41Thh}>6*oaAQ80+Gf{KCQgC9JYw_49`HExO9jO81)xZ$VJhpO*I1OPlj zapoog!l4pl%9z%;I7e>69N90~H5=!GXn^ZyH2#ROTxG2L2o1iXA;jG?VT9s*)qCTP zyJ1CPfGz7wC@##vAsnGE#s#p=wXYrX+$3jrsKhJl$GpAJ2j}OD+C0Eh({UYqSR{U( zmSXCnL_bQ8KbCA?S_87sR8yXtvEAg@7L6G~^K!TBU*T|Lf`M_8MkQ%&0q z$OeGh+#NlwMMO+MgkjSNHgb7)!R9-5a?XFRut;;LVHmRtoc{{>t=2;H?qlE;hr6_wvUR;kCe66`;-q&eyowymSIsid(ALw=322%W=AXpuwm4gN- zax*YvoG(F@rBDUv0(|&554C$h0LUH%NTCcFO#pzk!%Xg~fD{uIIK?Yt=b53DcHY+`jIBW&yyg2p(QRR$kEeM4jkn%$~$14SdYekgplTaZj3iUgD)BM z!kAZJjJN7V_g1kgLaaJM-&aMy_P^-+%lew{bywW0`QpA<;1UoD+53$Y*yX9_=|sTU zJ@i*rEYBpN8!HI;h>f0#S5AUv^)m~`LO02MK2+kB^B@!ubCY_1g;-71G48SkP)2Rk z7Ih4%f}Bp#>q@C3>zS6`P*drYE@eH#Qi&622(Wz+cy*F)m`WyF1A$q`5^W4iH@hU8 zPn)V{*q)SXBq8)Fy3J`igbLQUyBKjrZIl(hLo|kgVlGKGBLSBHR1xkV6^VzoH*KUf zSQ8?!&1E3FvAI+_X=36{EI}3VSEZjW(oZPI<}+zcHEf>RMNOJF>|iM;O37d%v^nyJ zAzMK-ZaM_z)CXw_tEQ69$ka`E5cE6Am_9gups7%JExVe{ohgL6SH=%>Pbe=O%bkCJ z^f~5wbL0NToh{Gy$?c|3YOTPlmj5a+Sc&Z3D)_r8+2w_%5;0lFPW{HaHB>l#(KSOsK|3y>VI$sPmVa6UY|9m|Km zy(3;J`hsg0RxhlNz56YTYk84FA-#4u^sgZNpE$HSZ&jG>NcP+h_(B3$*eN7opBkH* z8|3QIQ0ZIw_Ec^y009yUH)U&qvb9Lr+Cu}smxS|}Z@>q)%^$@Cq;}B6iUyfFhTKZW ziXBSosq~yKV+E31HLcqVf%XkSHj6eci8BJdU51j{@5S^Gq;cAfj_MG*c?6Tr7?>KKPn8m6T& zXDbr0%0h`;YKNtRu8^`mNIXhzkQPZo+ao#7c>JMWN=aOlF>F?WCs6fFgm@XBhst(4 zuC>LoN2}x`<>d6xj`0*3b-Za=(jNoNb;b1Tu()wh}=g}@oeI~-oH zT6zkh-j(q^!JGF^=I(Dd=G!L<-pO5IGA~R5EqvkiJ(zqjVm0+_PHj$D=dXVnw61^e z31X(0hGIj@`i0!(O>rZ;RSOxuXYdKj^6rDz2rNS!{Aeoj4hWB)d)3951UY0{%Hb5= zW&l{H#9aHYxT^i^{@boi3mW{j9(Ifuws`zvJva%BtB=sZ|DB z1fI@dB7Gjv%#iXfJrD|F>H~+Rj~#vim!4YqRhZx!{EV|ut)M;bgw-{)^YV=yE(-ES zbZ7AT4mW;KbTmHaqI7|1gro5R69<#W4!nvq8ipcXCj!xsM6%$ogCs;H;QIDR@G_rv zvf?r5aZ+QdcomviFX%`=l%ntkjJPoQWOKCPhnJx|y9jHjvW&?cx83IQ0=!9`_1m1+ zRprsz_xwB4aTf`nReeT$aoBO<<#|1|m{CXZ1oRS27`;#d&=}?~==hhY@k=!R%*`<^ f&w>nd>6z$bjz4P)Gp*0gdKvdWS~%u)hPvrLX|1Y{ literal 0 HcmV?d00001 diff --git a/agent_framework_oci/Tuning-Performance/Long_Term_Memory/templates/agent_template_backend/app/presentation/tool_renderers.py b/agent_framework_oci/Tuning-Performance/Long_Term_Memory/templates/agent_template_backend/app/presentation/tool_renderers.py new file mode 100644 index 0000000..f77c47a --- /dev/null +++ b/agent_framework_oci/Tuning-Performance/Long_Term_Memory/templates/agent_template_backend/app/presentation/tool_renderers.py @@ -0,0 +1,74 @@ +from __future__ import annotations + +from typing import Any + +from agent_framework.presentation import register_tool_response_renderer + + +def _money_brl(value: Any) -> str: + try: + return f"{float(value):.2f}".replace(".", ",") + except (TypeError, ValueError): + return str(value) + + +def render_telecom_invoice(*, tool_name: str, result: dict[str, Any], state: dict[str, Any], agent_label: str) -> str | 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: + plano = result.get("plano") + if plano is None: + return None + parts = [f"[{agent_label}] Seu plano é {plano}"] + internet_gb = result.get("internet_gb") + status = result.get("status") + if internet_gb is not None: + parts.append(f"com {internet_gb} GB") + if status is not None: + parts.append(f"status {status}") + return ", ".join(parts) + "." + + +def render_retail_order(*, tool_name: str, result: dict[str, Any], state: dict[str, Any], agent_label: str) -> str | None: + order_id = result.get("order_id") + status = result.get("status") + if order_id is None or status is None: + return None + lines = [f"[{agent_label}] Pedido {order_id}: status {status}."] + total = result.get("valor_total") + if total is not None: + lines.append(f"Valor total: R$ {_money_brl(total)}.") + items = result.get("itens") or [] + rendered_items: list[str] = [] + if isinstance(items, list): + for item in items: + if isinstance(item, dict): + value = item.get("descricao") or item.get("nome") or item.get("sku") + else: + value = item + if value not in (None, ""): + rendered_items.append(str(value)) + if rendered_items: + lines.append("Itens: " + "; ".join(rendered_items) + ".") + return " ".join(lines) + + +def render_retail_delivery(*, tool_name: str, result: dict[str, Any], state: dict[str, Any], agent_label: str) -> str | None: + order_id = result.get("order_id") + transportadora = result.get("transportadora") + codigo = result.get("codigo_rastreio") + previsao = result.get("previsao_entrega") + if any(v is None for v in (order_id, transportadora, codigo, previsao)): + return None + return ( + f"[{agent_label}] Entrega do pedido {order_id}: transportadora {transportadora}, " + f"rastreio {codigo}, previsão {previsao}." + ) + + +def register_tool_renderers() -> None: + register_tool_response_renderer("telecom.invoice", render_telecom_invoice) + register_tool_response_renderer("telecom.plan", render_telecom_plan) + register_tool_response_renderer("retail.order", render_retail_order) + register_tool_response_renderer("retail.delivery", render_retail_delivery) diff --git a/agent_framework_oci/Tuning-Performance/Long_Term_Memory/templates/agent_template_backend/config/mcp_parameter_mapping.yaml b/agent_framework_oci/Tuning-Performance/Long_Term_Memory/templates/agent_template_backend/config/mcp_parameter_mapping.yaml index 5b29ccf..91d57af 100644 --- a/agent_framework_oci/Tuning-Performance/Long_Term_Memory/templates/agent_template_backend/config/mcp_parameter_mapping.yaml +++ b/agent_framework_oci/Tuning-Performance/Long_Term_Memory/templates/agent_template_backend/config/mcp_parameter_mapping.yaml @@ -60,6 +60,18 @@ mcp_parameter_mapping: mensagem. pattern: (?i)\\b(?:pedido|order)\\s*[:#-]?\\s*([A-Z0-9-]+)\\b group: 1 + cancelar_pedido: + map: + session_key: session_id + extract: + order_id: + from: message + type: string + strategy: hybrid + description: Extraia somente o identificador do pedido informado explicitamente pelo usuário. Retorne null quando não houver identificador de pedido na mensagem. + pattern: (?i)\\b(?:pedido|order)\\s*[:#-]?\\s*([A-Z0-9-]+)\\b + group: 1 + solicitar_troca: map: session_key: session_id diff --git a/agent_framework_oci/Tuning-Performance/Long_Term_Memory/templates/agent_template_backend/config/routing.yaml b/agent_framework_oci/Tuning-Performance/Long_Term_Memory/templates/agent_template_backend/config/routing.yaml index 2dbe95e..03aeaa9 100644 --- a/agent_framework_oci/Tuning-Performance/Long_Term_Memory/templates/agent_template_backend/config/routing.yaml +++ b/agent_framework_oci/Tuning-Performance/Long_Term_Memory/templates/agent_template_backend/config/routing.yaml @@ -79,6 +79,25 @@ intents: - Quero saber sobre meu pacote de internet. - Tenho roaming internacional? + + - name: retail_order_cancel + domain: retail + agent: orders_agent + description: Cancelamento explícito de pedido ou compra. + priority: 20 + mcp_tools: + - consultar_pedido + - cancelar_pedido + keywords: + - cancelar pedido + - cancelamento do pedido + - cancelar a compra + - cancelar compra + examples: + - Quero cancelar meu pedido. + - Cancele o pedido. + - Quero cancelar a compra. + - name: retail_order_tracking domain: retail agent: orders_agent diff --git a/agent_framework_oci/Tuning-Performance/Long_Term_Memory/templates/agent_template_backend/config/tool_policies.yaml b/agent_framework_oci/Tuning-Performance/Long_Term_Memory/templates/agent_template_backend/config/tool_policies.yaml index 66c9854..48a83d5 100644 --- a/agent_framework_oci/Tuning-Performance/Long_Term_Memory/templates/agent_template_backend/config/tool_policies.yaml +++ b/agent_framework_oci/Tuning-Performance/Long_Term_Memory/templates/agent_template_backend/config/tool_policies.yaml @@ -7,6 +7,12 @@ defaults: require_confirmation: false tool_policies: + cancelar_pedido: + operation_type: transactional + require_confirmation: true + requires: [order_id] + + solicitar_troca: operation_type: transactional require_confirmation: true diff --git a/agent_framework_oci/Tuning-Performance/Long_Term_Memory/templates/agent_template_backend/config/tools.yaml b/agent_framework_oci/Tuning-Performance/Long_Term_Memory/templates/agent_template_backend/config/tools.yaml index d85fae1..f8a53ca 100644 --- a/agent_framework_oci/Tuning-Performance/Long_Term_Memory/templates/agent_template_backend/config/tools.yaml +++ b/agent_framework_oci/Tuning-Performance/Long_Term_Memory/templates/agent_template_backend/config/tools.yaml @@ -10,6 +10,9 @@ tools: - fatura - conta - boleto + response: + mode: renderer + renderer: telecom.invoice consultar_pagamentos: description: Consulta histórico de pagamentos do cliente. mcp_server: telecom @@ -28,6 +31,9 @@ tools: asset_id: string selection_keywords: - plano + response: + mode: renderer + renderer: telecom.plan listar_servicos: description: Lista serviços ativos e adicionais VAS. mcp_server: telecom @@ -49,6 +55,9 @@ tools: - consultar pedido - status do pedido - pedido + response: + mode: renderer + renderer: retail.order consultar_entrega: description: Consulta entrega e rastreamento do pedido. mcp_server: retail @@ -61,6 +70,26 @@ tools: - rastreamento - transportadora - previsão + response: + mode: renderer + renderer: retail.delivery + cancelar_pedido: + description: Simula o cancelamento de um pedido de varejo. + mcp_server: retail + enabled: true + tool_type: action + requires: + - order_id + confirmation_required: true + args_schema: + order_id: string + selection_keywords: + - cancelar pedido + - cancelamento do pedido + - cancelar compra + - cancelar a compra + + solicitar_troca: description: Simula abertura de solicitação de troca. mcp_server: retail diff --git a/agent_framework_oci/Tuning-Performance/Normal/templates/agent_template_backend/app/agents/runtime.py b/agent_framework_oci/Tuning-Performance/Normal/templates/agent_template_backend/app/agents/runtime.py index e6429c4..7a1a9be 100644 --- a/agent_framework_oci/Tuning-Performance/Normal/templates/agent_template_backend/app/agents/runtime.py +++ b/agent_framework_oci/Tuning-Performance/Normal/templates/agent_template_backend/app/agents/runtime.py @@ -3,5 +3,8 @@ from __future__ import annotations # Compatibilidade local do template/backend. # A implementação oficial agora fica no framework para evitar duplicação entre agentes. from agent_framework.runtime import AgentRuntimeMixin, MessageBuilder, RuntimeContext +from app.presentation import register_tool_renderers + +register_tool_renderers() __all__ = ["AgentRuntimeMixin", "MessageBuilder", "RuntimeContext"] diff --git a/agent_framework_oci/Tuning-Performance/Normal/templates/agent_template_backend/app/presentation/__init__.py b/agent_framework_oci/Tuning-Performance/Normal/templates/agent_template_backend/app/presentation/__init__.py new file mode 100644 index 0000000..c0eba0d --- /dev/null +++ b/agent_framework_oci/Tuning-Performance/Normal/templates/agent_template_backend/app/presentation/__init__.py @@ -0,0 +1,3 @@ +from .tool_renderers import register_tool_renderers + +__all__ = ["register_tool_renderers"] diff --git a/agent_framework_oci/Tuning-Performance/Normal/templates/agent_template_backend/app/presentation/__pycache__/tool_renderers.cpython-313.pyc b/agent_framework_oci/Tuning-Performance/Normal/templates/agent_template_backend/app/presentation/__pycache__/tool_renderers.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..23b52e138221f8fc623622c7fe8fe767b8579417 GIT binary patch literal 4392 zcmb_fO>7&-6`tkpa+m-5qfGr&TG^6qy85vr$+2ZisT0dqrJ4y$vsFw8#EM+0w5eTT zb|qVEQ?Nl$SO^NqXpJyHfhb6TDnJkFsXFwK!iVO#43&!5szA^phumD)E!v#=W|pKZ znJRkd035#AdGq()H{W~n)aP>}DC3Er-5K;C^f%I|6o)M^Pg5W~LQxcDrqCpV8Hvb_ zDaRy>St_$r+$4{AkUdeZ72V;mGwO}@w5&9Jn)Rcl1oMg!Ga^c{gMTmKt z1K| z6w*#;$@IXjB{i+i_r0OuISnt!YEl`95Fs;QC=0M9L($9QD(%FqoV*K$9*`Fo2NuEh zurzhhK-n3#5A^=U70aDi&{Sn5F^e;}4mK^qPrm|H4n1+OeCuAru{{5a-n?$spV$rb z76QGS(XA83zbFt+K3(aqIFU<0Gdnfv!ZIt~z zGs-5RO$+f54?pVjCJ+FzOpNsdQezC%>>%Hbzz-G^&jx3tYqGI~WeIGjFJ%llC67p0 zfKi`-j^(09Qo&%B6HW>W7O%r;6#ynRc}AX9GCEmOf`S7eSj{#J6NZvelG;KdtuAZn zq=G}xNfdM<!Ipn=w5jCO7gF`cUn&h~V}|D8}3*?mtwbOa;j* z7vl*2=gE1=so5CkM}yn|qw+_L<*H+yM`-X>4I$>74I&idYu*-T%n2(BgKR}#LNQ?$ zoN$D`7!zP`j(zQ@>n8Etp%SaEA9eRZANbD`v3P)|s^JFsute-SBSn=ZiGGwGe{)^ZZJE$LYfJR)UT>H4c#!Tuy=9lf^8!>q;5D~9C+WCOr0?v9pL!y+ai z!fg~K(^mXN~m4t?Z&`}b7Yu;7wx{;sCk8ZMNuy;r7D+#`W&{FBTmtW5R&OA(sq#Va%&A#$EHGyKC$! zOm=mIzNdzM{eRK-R`gZR>yDUP^~5|;-z6Xva`qc3*q5u8rQ<&P^w3{ju`-i{ZsZX1 zkUhGpRyhfpwSDG~25yr3e5k~#{vZ?(b&`62g=k&PG0utxP)2>k5;Y77LL!}_*OgL7 z)-@x&p`_9&P0G4Pq%tSa5MX&A+-fArFyu_O4#Kg9CE6H~Zgxu+pEeX#w_GVjPeQV1FyttR#!Z``?D`;0 zVa1TsnFKWx9s>O?GNvEg4>T1Bu4PxV`7^~pPj2Ec_XG;UvHbb>$DU)ZH#hEY+}Uz% zpWF_8T5tMZGrd=V!OCR!R?*u-$*v%T%EV+IJM|m))^PFkMf23ic9$8vyd#cQ^a(lc zdV4lrfa%Ze35IuIJ-c4{ih#^%@y{1bEE0kEg!aQjupE`3c-=>Xd(EW9q~%Z<6pb5dSQM1 z-B(Pm^+gVaq}t}tzk=|8;?UZ>Rb{p#*>gYO3vpm!yO1<}dVG3*h-*Z{o4EvOlNiQpSrT=n9OUfC2 ztiP%{1{3Hc5%?Nzg6W?6ykjz7zs~*qA_)Jc3E4rz8%_7#1tT!>4v8LadC>LuEN_(^_K1qBZi7N^*MW z#P|wKa1nm`DpW7r^>hs_ISYi}{omz&rV+y(bk z{{D7zp<}Y>p4t_r3c?i7!k2E(gQ*9jW~g^_dUMh|fBiGRdHn}Z5Hrm*m6}@DFXS(8 ziW}LjddToyLr++icOJY(urtKLkESB;fbi(Kw_KEo6DQMB38(NP1HjrP>ezp~)$C{Y zUvxG5xfeq`!CRP*WCP_?zrUR7XT6mVB;Ct;ZDaRSR?P;=tqRz}@L+~5(&quq3@PtY zhfokx8`vy;?C`s{{M5p)!35Xfr=Nu?hxWJ=X7}*U%Qtqo2*?|eouTVH+{8iA*7$;p z&;=r4j>ZQ}3``z7@G4Si7z(@X2t-2?$%4P}lMoe$>)R{Adwj;uipQbHPK~MJRcL12 zpdn?8pHer9sde7e}yKVIXR~FnV(@UJrh05@n`Kp TrtR5TH{<+AE62RfP&54pPN=4j literal 0 HcmV?d00001 diff --git a/agent_framework_oci/Tuning-Performance/Normal/templates/agent_template_backend/app/presentation/tool_renderers.py b/agent_framework_oci/Tuning-Performance/Normal/templates/agent_template_backend/app/presentation/tool_renderers.py new file mode 100644 index 0000000..f77c47a --- /dev/null +++ b/agent_framework_oci/Tuning-Performance/Normal/templates/agent_template_backend/app/presentation/tool_renderers.py @@ -0,0 +1,74 @@ +from __future__ import annotations + +from typing import Any + +from agent_framework.presentation import register_tool_response_renderer + + +def _money_brl(value: Any) -> str: + try: + return f"{float(value):.2f}".replace(".", ",") + except (TypeError, ValueError): + return str(value) + + +def render_telecom_invoice(*, tool_name: str, result: dict[str, Any], state: dict[str, Any], agent_label: str) -> str | 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: + plano = result.get("plano") + if plano is None: + return None + parts = [f"[{agent_label}] Seu plano é {plano}"] + internet_gb = result.get("internet_gb") + status = result.get("status") + if internet_gb is not None: + parts.append(f"com {internet_gb} GB") + if status is not None: + parts.append(f"status {status}") + return ", ".join(parts) + "." + + +def render_retail_order(*, tool_name: str, result: dict[str, Any], state: dict[str, Any], agent_label: str) -> str | None: + order_id = result.get("order_id") + status = result.get("status") + if order_id is None or status is None: + return None + lines = [f"[{agent_label}] Pedido {order_id}: status {status}."] + total = result.get("valor_total") + if total is not None: + lines.append(f"Valor total: R$ {_money_brl(total)}.") + items = result.get("itens") or [] + rendered_items: list[str] = [] + if isinstance(items, list): + for item in items: + if isinstance(item, dict): + value = item.get("descricao") or item.get("nome") or item.get("sku") + else: + value = item + if value not in (None, ""): + rendered_items.append(str(value)) + if rendered_items: + lines.append("Itens: " + "; ".join(rendered_items) + ".") + return " ".join(lines) + + +def render_retail_delivery(*, tool_name: str, result: dict[str, Any], state: dict[str, Any], agent_label: str) -> str | None: + order_id = result.get("order_id") + transportadora = result.get("transportadora") + codigo = result.get("codigo_rastreio") + previsao = result.get("previsao_entrega") + if any(v is None for v in (order_id, transportadora, codigo, previsao)): + return None + return ( + f"[{agent_label}] Entrega do pedido {order_id}: transportadora {transportadora}, " + f"rastreio {codigo}, previsão {previsao}." + ) + + +def register_tool_renderers() -> None: + register_tool_response_renderer("telecom.invoice", render_telecom_invoice) + register_tool_response_renderer("telecom.plan", render_telecom_plan) + register_tool_response_renderer("retail.order", render_retail_order) + register_tool_response_renderer("retail.delivery", render_retail_delivery) diff --git a/agent_framework_oci/Tuning-Performance/Normal/templates/agent_template_backend/config/mcp_parameter_mapping.yaml b/agent_framework_oci/Tuning-Performance/Normal/templates/agent_template_backend/config/mcp_parameter_mapping.yaml index 5b29ccf..91d57af 100644 --- a/agent_framework_oci/Tuning-Performance/Normal/templates/agent_template_backend/config/mcp_parameter_mapping.yaml +++ b/agent_framework_oci/Tuning-Performance/Normal/templates/agent_template_backend/config/mcp_parameter_mapping.yaml @@ -60,6 +60,18 @@ mcp_parameter_mapping: mensagem. pattern: (?i)\\b(?:pedido|order)\\s*[:#-]?\\s*([A-Z0-9-]+)\\b group: 1 + cancelar_pedido: + map: + session_key: session_id + extract: + order_id: + from: message + type: string + strategy: hybrid + description: Extraia somente o identificador do pedido informado explicitamente pelo usuário. Retorne null quando não houver identificador de pedido na mensagem. + pattern: (?i)\\b(?:pedido|order)\\s*[:#-]?\\s*([A-Z0-9-]+)\\b + group: 1 + solicitar_troca: map: session_key: session_id diff --git a/agent_framework_oci/Tuning-Performance/Normal/templates/agent_template_backend/config/routing.yaml b/agent_framework_oci/Tuning-Performance/Normal/templates/agent_template_backend/config/routing.yaml index 2dbe95e..03aeaa9 100644 --- a/agent_framework_oci/Tuning-Performance/Normal/templates/agent_template_backend/config/routing.yaml +++ b/agent_framework_oci/Tuning-Performance/Normal/templates/agent_template_backend/config/routing.yaml @@ -79,6 +79,25 @@ intents: - Quero saber sobre meu pacote de internet. - Tenho roaming internacional? + + - name: retail_order_cancel + domain: retail + agent: orders_agent + description: Cancelamento explícito de pedido ou compra. + priority: 20 + mcp_tools: + - consultar_pedido + - cancelar_pedido + keywords: + - cancelar pedido + - cancelamento do pedido + - cancelar a compra + - cancelar compra + examples: + - Quero cancelar meu pedido. + - Cancele o pedido. + - Quero cancelar a compra. + - name: retail_order_tracking domain: retail agent: orders_agent diff --git a/agent_framework_oci/Tuning-Performance/Normal/templates/agent_template_backend/config/tool_policies.yaml b/agent_framework_oci/Tuning-Performance/Normal/templates/agent_template_backend/config/tool_policies.yaml index 66c9854..48a83d5 100644 --- a/agent_framework_oci/Tuning-Performance/Normal/templates/agent_template_backend/config/tool_policies.yaml +++ b/agent_framework_oci/Tuning-Performance/Normal/templates/agent_template_backend/config/tool_policies.yaml @@ -7,6 +7,12 @@ defaults: require_confirmation: false tool_policies: + cancelar_pedido: + operation_type: transactional + require_confirmation: true + requires: [order_id] + + solicitar_troca: operation_type: transactional require_confirmation: true diff --git a/agent_framework_oci/Tuning-Performance/Normal/templates/agent_template_backend/config/tools.yaml b/agent_framework_oci/Tuning-Performance/Normal/templates/agent_template_backend/config/tools.yaml index d85fae1..f8a53ca 100644 --- a/agent_framework_oci/Tuning-Performance/Normal/templates/agent_template_backend/config/tools.yaml +++ b/agent_framework_oci/Tuning-Performance/Normal/templates/agent_template_backend/config/tools.yaml @@ -10,6 +10,9 @@ tools: - fatura - conta - boleto + response: + mode: renderer + renderer: telecom.invoice consultar_pagamentos: description: Consulta histórico de pagamentos do cliente. mcp_server: telecom @@ -28,6 +31,9 @@ tools: asset_id: string selection_keywords: - plano + response: + mode: renderer + renderer: telecom.plan listar_servicos: description: Lista serviços ativos e adicionais VAS. mcp_server: telecom @@ -49,6 +55,9 @@ tools: - consultar pedido - status do pedido - pedido + response: + mode: renderer + renderer: retail.order consultar_entrega: description: Consulta entrega e rastreamento do pedido. mcp_server: retail @@ -61,6 +70,26 @@ tools: - rastreamento - transportadora - previsão + response: + mode: renderer + renderer: retail.delivery + cancelar_pedido: + description: Simula o cancelamento de um pedido de varejo. + mcp_server: retail + enabled: true + tool_type: action + requires: + - order_id + confirmation_required: true + args_schema: + order_id: string + selection_keywords: + - cancelar pedido + - cancelamento do pedido + - cancelar compra + - cancelar a compra + + solicitar_troca: description: Simula abertura de solicitação de troca. mcp_server: retail diff --git a/agent_framework_oci/Tuning-Performance/Normal/templates/agent_template_backend_day_zero/config/mcp_parameter_mapping.yaml b/agent_framework_oci/Tuning-Performance/Normal/templates/agent_template_backend_day_zero/config/mcp_parameter_mapping.yaml index 5b29ccf..91d57af 100644 --- a/agent_framework_oci/Tuning-Performance/Normal/templates/agent_template_backend_day_zero/config/mcp_parameter_mapping.yaml +++ b/agent_framework_oci/Tuning-Performance/Normal/templates/agent_template_backend_day_zero/config/mcp_parameter_mapping.yaml @@ -60,6 +60,18 @@ mcp_parameter_mapping: mensagem. pattern: (?i)\\b(?:pedido|order)\\s*[:#-]?\\s*([A-Z0-9-]+)\\b group: 1 + cancelar_pedido: + map: + session_key: session_id + extract: + order_id: + from: message + type: string + strategy: hybrid + description: Extraia somente o identificador do pedido informado explicitamente pelo usuário. Retorne null quando não houver identificador de pedido na mensagem. + pattern: (?i)\\b(?:pedido|order)\\s*[:#-]?\\s*([A-Z0-9-]+)\\b + group: 1 + solicitar_troca: map: session_key: session_id diff --git a/agent_framework_oci/Tuning-Performance/Normal/templates/agent_template_backend_day_zero/config/routing.yaml b/agent_framework_oci/Tuning-Performance/Normal/templates/agent_template_backend_day_zero/config/routing.yaml index 2dbe95e..03aeaa9 100644 --- a/agent_framework_oci/Tuning-Performance/Normal/templates/agent_template_backend_day_zero/config/routing.yaml +++ b/agent_framework_oci/Tuning-Performance/Normal/templates/agent_template_backend_day_zero/config/routing.yaml @@ -79,6 +79,25 @@ intents: - Quero saber sobre meu pacote de internet. - Tenho roaming internacional? + + - name: retail_order_cancel + domain: retail + agent: orders_agent + description: Cancelamento explícito de pedido ou compra. + priority: 20 + mcp_tools: + - consultar_pedido + - cancelar_pedido + keywords: + - cancelar pedido + - cancelamento do pedido + - cancelar a compra + - cancelar compra + examples: + - Quero cancelar meu pedido. + - Cancele o pedido. + - Quero cancelar a compra. + - name: retail_order_tracking domain: retail agent: orders_agent diff --git a/agent_framework_oci/Tuning-Performance/Normal/templates/agent_template_backend_day_zero/config/tool_policies.yaml b/agent_framework_oci/Tuning-Performance/Normal/templates/agent_template_backend_day_zero/config/tool_policies.yaml index 66c9854..48a83d5 100644 --- a/agent_framework_oci/Tuning-Performance/Normal/templates/agent_template_backend_day_zero/config/tool_policies.yaml +++ b/agent_framework_oci/Tuning-Performance/Normal/templates/agent_template_backend_day_zero/config/tool_policies.yaml @@ -7,6 +7,12 @@ defaults: require_confirmation: false tool_policies: + cancelar_pedido: + operation_type: transactional + require_confirmation: true + requires: [order_id] + + solicitar_troca: operation_type: transactional require_confirmation: true diff --git a/agent_framework_oci/Tuning-Performance/Normal/templates/agent_template_backend_day_zero/config/tools.yaml b/agent_framework_oci/Tuning-Performance/Normal/templates/agent_template_backend_day_zero/config/tools.yaml index d85fae1..2329dc7 100644 --- a/agent_framework_oci/Tuning-Performance/Normal/templates/agent_template_backend_day_zero/config/tools.yaml +++ b/agent_framework_oci/Tuning-Performance/Normal/templates/agent_template_backend_day_zero/config/tools.yaml @@ -61,6 +61,23 @@ tools: - rastreamento - transportadora - previsão + cancelar_pedido: + description: Simula o cancelamento de um pedido de varejo. + mcp_server: retail + enabled: true + tool_type: action + requires: + - order_id + confirmation_required: true + args_schema: + order_id: string + selection_keywords: + - cancelar pedido + - cancelamento do pedido + - cancelar compra + - cancelar a compra + + solicitar_troca: description: Simula abertura de solicitação de troca. mcp_server: retail diff --git a/agent_framework_oci/Tuning-Performance/Offline_Workflow_Regression/README.md b/agent_framework_oci/Tuning-Performance/Offline_Workflow_Regression/README.md index bbd3250..f3bc196 100644 --- a/agent_framework_oci/Tuning-Performance/Offline_Workflow_Regression/README.md +++ b/agent_framework_oci/Tuning-Performance/Offline_Workflow_Regression/README.md @@ -2,7 +2,7 @@ O backend de produção de `WorkflowRuntime` continua sendo **LangGraph**. A ausência do pacote `langgraph` em produção é erro de configuração. -Para builders restritos/offline, o runtime aceita `allow_deterministic_fallback=True`. Esse modo é deliberadamente opt-in e existe somente para exercitar a DSL do framework (actions, edges, condições, pause/resume e trace) de forma reproduzível em testes offline/regressão. Quando `allow_deterministic_fallback=True`, o backend determinístico é selecionado explicitamente mesmo que LangGraph esteja instalado. Ele nunca é selecionado automaticamente em produção. +Para builders restritos/offline, o runtime aceita `allow_deterministic_fallback=True`. Esse modo é deliberadamente opt-in e existe somente para exercitar a DSL do framework (actions, edges, condições, pause/resume e trace) quando a dependência externa não pode ser instalada. Ele não é selecionado automaticamente. Exemplo de teste: diff --git a/agent_framework_oci/Tuning-Performance/Route_Stickness/templates/agent_template_backend/app/agents/runtime.py b/agent_framework_oci/Tuning-Performance/Route_Stickness/templates/agent_template_backend/app/agents/runtime.py index e6429c4..7a1a9be 100644 --- a/agent_framework_oci/Tuning-Performance/Route_Stickness/templates/agent_template_backend/app/agents/runtime.py +++ b/agent_framework_oci/Tuning-Performance/Route_Stickness/templates/agent_template_backend/app/agents/runtime.py @@ -3,5 +3,8 @@ from __future__ import annotations # Compatibilidade local do template/backend. # A implementação oficial agora fica no framework para evitar duplicação entre agentes. from agent_framework.runtime import AgentRuntimeMixin, MessageBuilder, RuntimeContext +from app.presentation import register_tool_renderers + +register_tool_renderers() __all__ = ["AgentRuntimeMixin", "MessageBuilder", "RuntimeContext"] diff --git a/agent_framework_oci/Tuning-Performance/Route_Stickness/templates/agent_template_backend/app/presentation/__init__.py b/agent_framework_oci/Tuning-Performance/Route_Stickness/templates/agent_template_backend/app/presentation/__init__.py new file mode 100644 index 0000000..c0eba0d --- /dev/null +++ b/agent_framework_oci/Tuning-Performance/Route_Stickness/templates/agent_template_backend/app/presentation/__init__.py @@ -0,0 +1,3 @@ +from .tool_renderers import register_tool_renderers + +__all__ = ["register_tool_renderers"] diff --git a/agent_framework_oci/Tuning-Performance/Route_Stickness/templates/agent_template_backend/app/presentation/__pycache__/tool_renderers.cpython-313.pyc b/agent_framework_oci/Tuning-Performance/Route_Stickness/templates/agent_template_backend/app/presentation/__pycache__/tool_renderers.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..567eb4dcb26331acc08869aa04106d30e73d78d5 GIT binary patch literal 4401 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 literal 0 HcmV?d00001 diff --git a/agent_framework_oci/Tuning-Performance/Route_Stickness/templates/agent_template_backend/app/presentation/tool_renderers.py b/agent_framework_oci/Tuning-Performance/Route_Stickness/templates/agent_template_backend/app/presentation/tool_renderers.py new file mode 100644 index 0000000..f77c47a --- /dev/null +++ b/agent_framework_oci/Tuning-Performance/Route_Stickness/templates/agent_template_backend/app/presentation/tool_renderers.py @@ -0,0 +1,74 @@ +from __future__ import annotations + +from typing import Any + +from agent_framework.presentation import register_tool_response_renderer + + +def _money_brl(value: Any) -> str: + try: + return f"{float(value):.2f}".replace(".", ",") + except (TypeError, ValueError): + return str(value) + + +def render_telecom_invoice(*, tool_name: str, result: dict[str, Any], state: dict[str, Any], agent_label: str) -> str | 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: + plano = result.get("plano") + if plano is None: + return None + parts = [f"[{agent_label}] Seu plano é {plano}"] + internet_gb = result.get("internet_gb") + status = result.get("status") + if internet_gb is not None: + parts.append(f"com {internet_gb} GB") + if status is not None: + parts.append(f"status {status}") + return ", ".join(parts) + "." + + +def render_retail_order(*, tool_name: str, result: dict[str, Any], state: dict[str, Any], agent_label: str) -> str | None: + order_id = result.get("order_id") + status = result.get("status") + if order_id is None or status is None: + return None + lines = [f"[{agent_label}] Pedido {order_id}: status {status}."] + total = result.get("valor_total") + if total is not None: + lines.append(f"Valor total: R$ {_money_brl(total)}.") + items = result.get("itens") or [] + rendered_items: list[str] = [] + if isinstance(items, list): + for item in items: + if isinstance(item, dict): + value = item.get("descricao") or item.get("nome") or item.get("sku") + else: + value = item + if value not in (None, ""): + rendered_items.append(str(value)) + if rendered_items: + lines.append("Itens: " + "; ".join(rendered_items) + ".") + return " ".join(lines) + + +def render_retail_delivery(*, tool_name: str, result: dict[str, Any], state: dict[str, Any], agent_label: str) -> str | None: + order_id = result.get("order_id") + transportadora = result.get("transportadora") + codigo = result.get("codigo_rastreio") + previsao = result.get("previsao_entrega") + if any(v is None for v in (order_id, transportadora, codigo, previsao)): + return None + return ( + f"[{agent_label}] Entrega do pedido {order_id}: transportadora {transportadora}, " + f"rastreio {codigo}, previsão {previsao}." + ) + + +def register_tool_renderers() -> None: + register_tool_response_renderer("telecom.invoice", render_telecom_invoice) + register_tool_response_renderer("telecom.plan", render_telecom_plan) + register_tool_response_renderer("retail.order", render_retail_order) + register_tool_response_renderer("retail.delivery", render_retail_delivery) diff --git a/agent_framework_oci/Tuning-Performance/Route_Stickness/templates/agent_template_backend/config/mcp_parameter_mapping.yaml b/agent_framework_oci/Tuning-Performance/Route_Stickness/templates/agent_template_backend/config/mcp_parameter_mapping.yaml index 5b29ccf..91d57af 100644 --- a/agent_framework_oci/Tuning-Performance/Route_Stickness/templates/agent_template_backend/config/mcp_parameter_mapping.yaml +++ b/agent_framework_oci/Tuning-Performance/Route_Stickness/templates/agent_template_backend/config/mcp_parameter_mapping.yaml @@ -60,6 +60,18 @@ mcp_parameter_mapping: mensagem. pattern: (?i)\\b(?:pedido|order)\\s*[:#-]?\\s*([A-Z0-9-]+)\\b group: 1 + cancelar_pedido: + map: + session_key: session_id + extract: + order_id: + from: message + type: string + strategy: hybrid + description: Extraia somente o identificador do pedido informado explicitamente pelo usuário. Retorne null quando não houver identificador de pedido na mensagem. + pattern: (?i)\\b(?:pedido|order)\\s*[:#-]?\\s*([A-Z0-9-]+)\\b + group: 1 + solicitar_troca: map: session_key: session_id diff --git a/agent_framework_oci/Tuning-Performance/Route_Stickness/templates/agent_template_backend/config/routing.yaml b/agent_framework_oci/Tuning-Performance/Route_Stickness/templates/agent_template_backend/config/routing.yaml index 2dbe95e..03aeaa9 100644 --- a/agent_framework_oci/Tuning-Performance/Route_Stickness/templates/agent_template_backend/config/routing.yaml +++ b/agent_framework_oci/Tuning-Performance/Route_Stickness/templates/agent_template_backend/config/routing.yaml @@ -79,6 +79,25 @@ intents: - Quero saber sobre meu pacote de internet. - Tenho roaming internacional? + + - name: retail_order_cancel + domain: retail + agent: orders_agent + description: Cancelamento explícito de pedido ou compra. + priority: 20 + mcp_tools: + - consultar_pedido + - cancelar_pedido + keywords: + - cancelar pedido + - cancelamento do pedido + - cancelar a compra + - cancelar compra + examples: + - Quero cancelar meu pedido. + - Cancele o pedido. + - Quero cancelar a compra. + - name: retail_order_tracking domain: retail agent: orders_agent diff --git a/agent_framework_oci/Tuning-Performance/Route_Stickness/templates/agent_template_backend/config/tool_policies.yaml b/agent_framework_oci/Tuning-Performance/Route_Stickness/templates/agent_template_backend/config/tool_policies.yaml index 66c9854..48a83d5 100644 --- a/agent_framework_oci/Tuning-Performance/Route_Stickness/templates/agent_template_backend/config/tool_policies.yaml +++ b/agent_framework_oci/Tuning-Performance/Route_Stickness/templates/agent_template_backend/config/tool_policies.yaml @@ -7,6 +7,12 @@ defaults: require_confirmation: false tool_policies: + cancelar_pedido: + operation_type: transactional + require_confirmation: true + requires: [order_id] + + solicitar_troca: operation_type: transactional require_confirmation: true diff --git a/agent_framework_oci/Tuning-Performance/Route_Stickness/templates/agent_template_backend/config/tools.yaml b/agent_framework_oci/Tuning-Performance/Route_Stickness/templates/agent_template_backend/config/tools.yaml index d85fae1..f8a53ca 100644 --- a/agent_framework_oci/Tuning-Performance/Route_Stickness/templates/agent_template_backend/config/tools.yaml +++ b/agent_framework_oci/Tuning-Performance/Route_Stickness/templates/agent_template_backend/config/tools.yaml @@ -10,6 +10,9 @@ tools: - fatura - conta - boleto + response: + mode: renderer + renderer: telecom.invoice consultar_pagamentos: description: Consulta histórico de pagamentos do cliente. mcp_server: telecom @@ -28,6 +31,9 @@ tools: asset_id: string selection_keywords: - plano + response: + mode: renderer + renderer: telecom.plan listar_servicos: description: Lista serviços ativos e adicionais VAS. mcp_server: telecom @@ -49,6 +55,9 @@ tools: - consultar pedido - status do pedido - pedido + response: + mode: renderer + renderer: retail.order consultar_entrega: description: Consulta entrega e rastreamento do pedido. mcp_server: retail @@ -61,6 +70,26 @@ tools: - rastreamento - transportadora - previsão + response: + mode: renderer + renderer: retail.delivery + cancelar_pedido: + description: Simula o cancelamento de um pedido de varejo. + mcp_server: retail + enabled: true + tool_type: action + requires: + - order_id + confirmation_required: true + args_schema: + order_id: string + selection_keywords: + - cancelar pedido + - cancelamento do pedido + - cancelar compra + - cancelar a compra + + solicitar_troca: description: Simula abertura de solicitação de troca. mcp_server: retail diff --git a/agent_framework_oci/Tuning-Performance/Route_Stickness/templates/agent_template_backend_day_zero/config/mcp_parameter_mapping.yaml b/agent_framework_oci/Tuning-Performance/Route_Stickness/templates/agent_template_backend_day_zero/config/mcp_parameter_mapping.yaml index 5b29ccf..91d57af 100644 --- a/agent_framework_oci/Tuning-Performance/Route_Stickness/templates/agent_template_backend_day_zero/config/mcp_parameter_mapping.yaml +++ b/agent_framework_oci/Tuning-Performance/Route_Stickness/templates/agent_template_backend_day_zero/config/mcp_parameter_mapping.yaml @@ -60,6 +60,18 @@ mcp_parameter_mapping: mensagem. pattern: (?i)\\b(?:pedido|order)\\s*[:#-]?\\s*([A-Z0-9-]+)\\b group: 1 + cancelar_pedido: + map: + session_key: session_id + extract: + order_id: + from: message + type: string + strategy: hybrid + description: Extraia somente o identificador do pedido informado explicitamente pelo usuário. Retorne null quando não houver identificador de pedido na mensagem. + pattern: (?i)\\b(?:pedido|order)\\s*[:#-]?\\s*([A-Z0-9-]+)\\b + group: 1 + solicitar_troca: map: session_key: session_id diff --git a/agent_framework_oci/Tuning-Performance/Route_Stickness/templates/agent_template_backend_day_zero/config/routing.yaml b/agent_framework_oci/Tuning-Performance/Route_Stickness/templates/agent_template_backend_day_zero/config/routing.yaml index 2dbe95e..03aeaa9 100644 --- a/agent_framework_oci/Tuning-Performance/Route_Stickness/templates/agent_template_backend_day_zero/config/routing.yaml +++ b/agent_framework_oci/Tuning-Performance/Route_Stickness/templates/agent_template_backend_day_zero/config/routing.yaml @@ -79,6 +79,25 @@ intents: - Quero saber sobre meu pacote de internet. - Tenho roaming internacional? + + - name: retail_order_cancel + domain: retail + agent: orders_agent + description: Cancelamento explícito de pedido ou compra. + priority: 20 + mcp_tools: + - consultar_pedido + - cancelar_pedido + keywords: + - cancelar pedido + - cancelamento do pedido + - cancelar a compra + - cancelar compra + examples: + - Quero cancelar meu pedido. + - Cancele o pedido. + - Quero cancelar a compra. + - name: retail_order_tracking domain: retail agent: orders_agent diff --git a/agent_framework_oci/Tuning-Performance/Route_Stickness/templates/agent_template_backend_day_zero/config/tool_policies.yaml b/agent_framework_oci/Tuning-Performance/Route_Stickness/templates/agent_template_backend_day_zero/config/tool_policies.yaml index 66c9854..48a83d5 100644 --- a/agent_framework_oci/Tuning-Performance/Route_Stickness/templates/agent_template_backend_day_zero/config/tool_policies.yaml +++ b/agent_framework_oci/Tuning-Performance/Route_Stickness/templates/agent_template_backend_day_zero/config/tool_policies.yaml @@ -7,6 +7,12 @@ defaults: require_confirmation: false tool_policies: + cancelar_pedido: + operation_type: transactional + require_confirmation: true + requires: [order_id] + + solicitar_troca: operation_type: transactional require_confirmation: true diff --git a/agent_framework_oci/Tuning-Performance/Route_Stickness/templates/agent_template_backend_day_zero/config/tools.yaml b/agent_framework_oci/Tuning-Performance/Route_Stickness/templates/agent_template_backend_day_zero/config/tools.yaml index d85fae1..2329dc7 100644 --- a/agent_framework_oci/Tuning-Performance/Route_Stickness/templates/agent_template_backend_day_zero/config/tools.yaml +++ b/agent_framework_oci/Tuning-Performance/Route_Stickness/templates/agent_template_backend_day_zero/config/tools.yaml @@ -61,6 +61,23 @@ tools: - rastreamento - transportadora - previsão + cancelar_pedido: + description: Simula o cancelamento de um pedido de varejo. + mcp_server: retail + enabled: true + tool_type: action + requires: + - order_id + confirmation_required: true + args_schema: + order_id: string + selection_keywords: + - cancelar pedido + - cancelamento do pedido + - cancelar compra + - cancelar a compra + + solicitar_troca: description: Simula abertura de solicitação de troca. mcp_server: retail diff --git a/agent_framework_oci/apps/agent_gateway/app/__pycache__/governance_middleware.cpython-313.pyc b/agent_framework_oci/apps/agent_gateway/app/__pycache__/governance_middleware.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9ef1c4ff02adf89c9979a533d7e72f3935e6c6f3 GIT binary patch literal 4700 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 literal 0 HcmV?d00001 diff --git a/agent_framework_oci/apps/agent_gateway/app/__pycache__/main.cpython-313.pyc b/agent_framework_oci/apps/agent_gateway/app/__pycache__/main.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fffdb5d24b75991d2a2f0b23e0413c51a3ce87e7 GIT binary patch literal 17489 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 G_kRE(wtz4I literal 0 HcmV?d00001 diff --git a/agent_framework_oci/apps/agent_gateway/app/__pycache__/settings.cpython-313.pyc b/agent_framework_oci/apps/agent_gateway/app/__pycache__/settings.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0331ed76b6d7e65a13dddb4adae5fa0dd427b93b GIT binary patch literal 3272 zcmZ8k-A^0Y6(8d<7%(5*<9 zbFVK~0|R{=eE#_B`kOzyIqqLbIv9q=^CtWdAqEtg&)U%`Ls-zl5rB>GINJolm zwc|=TQ7IWEdoA{-+aivutuD;%fFllxBVCe%ID^~)4^ekXPKlRXkDSCMb(3zX=b%S& zFTpUWm$(`0W2~P*E@1O8HbD9q8)R&V^h?8FyT#ZD@i5ycV`F51v2n(3lR;?$JiUxf zk|D_lY|3WCj7>A-u+1_SAR}yrImYJ6D6`#RY=MkPLGWB;Y>A9B+cIMza+{4? zVQiI5Ft)~6n0Q%a5yqlqlCisttrMSg59Ykj*an$mk!{+xX=eM(W`4#VF!qqluvs42 zwpnJ|V(c*qFxwNxHpm>C^K-_w$vm??wa49I}}zV+pdvau*nz zB+G1tUB)&@h_R$SZiS6|ZnIU!M8;BNjm5IZSek^(>!A!CN-Bo>bLFhlaPNDeN1A*@ zt(`Vq4dXcckakzfHI1ktCv}5XKCV<%daEPJYOSOlLDN!~`U`_7%~_?a){Jo3nl@an zYKKZStT*Z^Ij!g#p-$Z()E&#`P4`;Ujjhe~2luHbo-0Ult{^7G ztkk?6iI&)jiXJMZuhiO+9ywD^s&s587T*)H2}zFUvb$nZ&c}++Y4_{1LsB_vhU{bd z#S+mPaA23#0!tqgLS{KG{e+Gt)482kS}x@Fi()n@XL1RlNclret5TnB+Y^Mm9E%sl z7lLfBOXqCcz9h)feqJcN5T#r}&ShCZX)#_b|L(W=`R7yWI<9JpL8t8@88OS26AD)F z2_YL7D#L@YMV%ETL6St6t5{6Sk^m_tq_TB`{PY=}uw#&mVn%?lJ06rj(Mn%6Kfg{M zDJH9xDza8rYf7cV^drl_lyXTssl$DDSXE&|Jn3{s&KGho#Dq|=7lp`%P+b%rm)&Nl)F+pRtfZ=8iBThyVR(hs!AoI zD`8#H>Pn-kh1VkxaYQ3Zsj8N$TH`1J5k{>HqNnS0Bo`Ouq>zn?P!8Dt{X)7qXqhAB zx)I)ptka>7K3LLpw%G@59Qb7*tJUB%e6(VZ?g_7U=@3k~lNRK3ESubgvO*rVB$2t`yjeVyd2Xsb%CeB97g44V#I&w?j`-eS?f28(e)l2cMH+jMS5?o!Xb zl#q7{(1@|3K!@#EV%b>wRZ)yfbO4J88K}w$p54)F%XO_JI-ZQ@F;;1R2MUshh}o$a ziNRhKKQYij=32<5gm_UF6Lk28L+#3MKZBmUG3%#QrQ;vN*o}$Mt700KqGNXWxXV(p zAjF{MlXUbWg^MGR&xzp5>SX!IU{5s1KE00AQ@EUT>b)^GA1f5aA|4Oe`#*4@2zASH zO*v6znfA%@iFVYeqU@37pEZ=KZ5fi`A|$#|t<=<-Cd;G;d({KpY86fZeruCqRDt7- z7XUbpfR>CQj3Z1Sco8NMrV#uHGYA2MIfQwH1%x2NBEm942w??b6=4k_j1WPHBHTq- zN4STufq<_S@)^Pdgog-^5VjB=BjE8PpCfDo&~X_$1`b$BRt$qw4&f@)A)lvUyMkYi z&MWo09%UOY+xLGIR8if2)Nm%{mgF_P(ew1hoi-o+F7U9$doMwJ zXbPDYKhc`pY4aI#X|=`AyyM&asu{W0;)CyuHh<4tiM05@yI`A-n2Rgu;B50NW)Q@w z%Y6_(bi~(p1S};!1VdgvlsC;?>A@XV3o_!Ha}<1ylL^bFJX>1 z=F}>9Lg1_B!g7lrzi77kWpjECltuK!)g~@|xY`YIa`QZMaUb)(G05w;Qu9MFGk042 z*u_zspEqYAbhd27TwZJOlb2goNB{lvNsw#kpc57X4~q(*N9?$NTm6uiPxJ{{!qBhjIV_ literal 0 HcmV?d00001 diff --git a/agent_framework_oci/apps/agent_gateway/app/config/__pycache__/governance_loader.cpython-313.pyc b/agent_framework_oci/apps/agent_gateway/app/config/__pycache__/governance_loader.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..49664df5a589248984e78ed7e0a29d793ce239e5 GIT binary patch literal 925 zcmY*YL2DC16rR~^Hc8i7TA|fIo27VgQM)1(6toaanl_QGWUC@UmTfYLDamY@ozy0H zD0mSsdMStq9z}nFM}I;}4=F=?>dBjsgIC`q*|g5#z3>flbzM{^p}M)??vIhqr5qDi!) z?qC+LDrWq*BsHw1+9H+CX6!9Do8HPiPrq=po6j-@J8iFK+|^BcZ6n)R zDEYKft6Ei$lhD1IQcD&d6g z3XSa50v-re_J~B_Rft>ny|PF!;+0)a_PD7CwF!TS(1#OU83b~5h9T~H&1PVERYJKt zQewfC6^a{+8n6-=Z zm&wn8CBTT7+(x~&JzTBE+fCRsi^}{ZY2=Ujj@T86r@@H$gN9#j)yWFG2BCa;K@!ZL b2*&snEuNvoDY|-!X3voRS5xr@9`ybLIepg{ literal 0 HcmV?d00001 diff --git a/agent_framework_oci/apps/agent_gateway/app/governance/__pycache__/__init__.cpython-313.pyc b/agent_framework_oci/apps/agent_gateway/app/governance/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9facf8795a781ba428b2ecfb9810fc68fa779592 GIT binary patch literal 142 zcmey&%ge<81gn}0vKWE%V-N=hKms7}nFUBpWk_exWb|9fP{afh0*T+!O)MxV)=x}N z%`1sdPb^6-Pps4j3hAfkm!%fvCFUik>c_`t=4F<|$LkeT-r}&y%}*)KNwq6t1?mQw QUJPP?TdW#8OKOb&a;VBF(8n(W=Gbp^>6laxs==$WFE?$?P(-sU)Y0 z2Mb<$uplC+AXxni`bT)M2C0lKh&_1|f_G=?Zi91pzu$ZF=6z0gV4x4k^YKZz_8bCm zq?F|7{|M|pkYpP;z<~v@1R1mx*9scbj!|d2M7@BPQY>YGhkCI;3DLtGaL}yGpbj$~ z!%2;UHN?`sW}Cm1(S{<6DGeeV)dI?wrLHf~R(lNlghsB9Bk~BhX8d5CFp6n~R5bN0 zKB@~@FYNx5WE+&@OaPQ%l9g%>ENR!|JqC3W%J{wnT0Uy}rvM?Kj zb2%IVL^h^wozQk_id$3sj;)D)LV1%B7xPN3CQOf1akC!TX@R_2B@(*y7CMiZ(8C}U zMm_L-!UU?(Y9P=W52#3a%|^&=T_B1ZM3^CN)dTDa#Br5yRgh&_;xZ0Hp8s!8d1=b` zc9q9XuNKXOExBXGT(T~g%Ff6DYID3O#RfRY4sDsw<~J66^R7PVQD`a$yr~uI!~J4p86I!sEi0`C{Z%^t%1By>nr=^y&8A*?V8n z{jQ7(Y=fPazy_2Uk)l1Qx-ZMVuUPVftq6mWsL7~6%K;^JM)bLEwJ9ycb(w0BosvSB zYCJXS3nOZU5}8_#$oM3>dptKbq+C@;9{?Lud{jB4uQvj(StmD`B~|q;x%x!EbqL`h l$Q^;~cQAMeMt@|6_cP;PGUJ~oW;>ay8^#|4!6H14^cV4^)@}d* literal 0 HcmV?d00001 diff --git a/agent_framework_oci/apps/agent_gateway/app/governance/__pycache__/evaluation_hooks.cpython-313.pyc b/agent_framework_oci/apps/agent_gateway/app/governance/__pycache__/evaluation_hooks.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..473f2bc23ba05bb08b2b4ae247c6a493206c7e19 GIT binary patch literal 881 zcmah|O=}cE5Urk>oviuVkdPobBt!JzK*)N@O+*iZB#_JCNu}w`_O6>udM4F9k-Z6m z{~$ji{+b-6!IOB%Oepq0iK?4-iaC}T>e+^{s3-0-;> zR9YSg8z?w~x;Xq3rySKl<3@3{L`HS$aQx?iG}`zk-wrYCb%6#l^-nOpxLO;KCh zCi4Nlbk@$>Yh%Lyodxd^3Hkie0B7jq7f{=ZezU$a5YBOQQT3h1+v+y%s{5P64Q|A( zpSRa>fp#W+_tFSw$@x9s8|Ln{b-0<(@xJvjYFDGdWeO5!krNo>$~8)-d|OJRjFKw}meoeYb2GYF&AG=XCGy~+9&{Voz-M61Kx}V}2 cQTV=D9`i>ig!l>@-(lr4Zi(b4keT%Q14yUXu>b%7 literal 0 HcmV?d00001 diff --git a/agent_framework_oci/apps/agent_gateway/app/governance/__pycache__/model_policies.cpython-313.pyc b/agent_framework_oci/apps/agent_gateway/app/governance/__pycache__/model_policies.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1141210aa6d44d7e51b11311330f8ef4c8bb4e6d GIT binary patch literal 3383 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 literal 0 HcmV?d00001 diff --git a/agent_framework_oci/apps/agent_gateway/app/governance/__pycache__/rate_limit.cpython-313.pyc b/agent_framework_oci/apps/agent_gateway/app/governance/__pycache__/rate_limit.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..507ee7d0c458eba75cb7aebebd8889216840fe78 GIT binary patch literal 2594 zcmb7GO>7fK6rSDn+UsA4W0Kej&6Yr02NH*$P{~jzv}x4@qSjlNfGI0uPs|c$ZD!XA z300|737OIgIG{LcrKGpCm-fhk14oXIT$E@OC=$KoRyC+dJ@w7{CzOV&jO5wp@4b2R ze&)TIHLur&VEp)H{=8pA=rQ|KAMl?IZtV=rw~&GqZU_x>gp(P~5AlSDuP`JG+K6pX zB%+1ehU|k5;*e1r+J+P{gcSQ}sb6545F$0-F)A&LGgOqSYpGsAiS7)yFSqlJh3!O%UQxMq45kcXJEhB_& zv?-P}@iA>&GY2lFFizw2ssz$Mpy9AcB~{gv<5*RxOI62n=|Yy#9#y?iNM>uCO{zMo z5yQ-CI@WW*-lD1ovo)nAO_OM63nn&Hm9UVmF@tC%na>-MWCrV|nt|OXlT!?eWO5Uj z=t(_=BLrYI%dG0nPZ4I2H8H|q8MuO|O(L7?_&>a^MUY#21K7`bZCCgZIuDsq9ExC3 zqGBWVj2M<^^9TBIJf0&{jfh~f>H!_8nnoZIVmX5!w{{GOTPV)G#j$|txomV@&a-VZU)jk4C%0^a{8#2AxxMsPpKVGK%flBy3N4ZQPKjS!7P$x z(!>NHNt&*i5c!S`Jm{@+y=+|&rZ3QPOUF!ho-f+IcCSRDcls-lBSqUcZY!RtnsJt+ z4iLATb-@hIq8I?rk66Qrb&kT-o&0xrHk9XIB(Dg%?IrfLy+}_V(#4n1BmRdTd)%fw z;(R^rNeJr5jsxI)66$Ou#8Q{#a)Vp z$DN9^2dY2nhY0Opc+6d2x&E#1Ap^gm#rFa&aQu&hrUX0F)`+|6`ATeRV2(N#y#qVL z?g>^e)=*q=31Z@ov&eY%HnNR5u&%i-wf>De>$+qFrRp7~j#>+*&4jgI!!*=9ChEAR zL%-8Tz(Q)bTAV?p)H&$iIBQTYO1W;rig)!OOw;oF)%GW|ekWV~PR6x1ERW`hJk3Yt zXd_rz&9?Wl&#Ds>(E|XyH^C!&6kybCcA5wvZabromDx zua9br5>w}JYK#Uq>Q5GnCB}FMS`Rd*&?|F0XLrs;W+MyXN@(9wD0-V;3Lahz9xlHf zuLM6?YCBU-oGE&jTia(Y-Mln&`R3*MiCrPlpFA1!*8gInj?XWQpGXFC@{mEgXm zAgnL?9&O%Q6d$^qOH!q+Z#f_@2D+C5y^Dd~a^&5+xDq&49C+yV- zg%zLwy7rZJZLBCPH*J||zu8_=7Morz+8_D?rIvYaHaM>=?D>AA66{&__^%IN9sb4B z@uz?`ZF!b^KiKn|+gF^pcHq0N68^Tk;@-aE?<&9c-d*D^zPINdzIUSh@kn|5$%_9} z*>h@H@?G~{_1;L`mqJz>5A)V>v5p747_2|jKK5Qn7$(^z!&BkYutd7qu@C?uJAwMk z1(f`mJe<=p*#!W3lkx2Yn*{;~j^SYkVJRl;VkE5o2oxzI>|!DN*u?73y6mghGs`St z6=h9qmBChBK~H#IJjy+l{9=1mk_m;~?4>bUfc@a5LD%{ zDzE7o!rB(~#0omAi2*`##43R5#_Z*>ZVZ(UR$nrQ$RS{`>&|!`rr!mQ;~t=GkCFRV c)cpXpJh5|}v*dY#;PX^!<=X#1Fj@rcL_ zB8b=_957@9$Gt=Ez(;=ocVG`9e;1gOKEkTWe55N|#qZuSHXX81{JsW75O>MgnRhEm1c6SB?`#=|E6`FgFiOv7RSQ?-SLNwNgA71+TgG?aHD{&$@w`-hJ zZ)N8AP0mkCku`sMoKI8KCQFr6Ip^4Of_(=&1a^ya?RGTg!Wc}CN+UI8)zfi>8f(=boq$)wTiOX_VC2Z&EvV&*1 dM=5S|^%lWTpE33g_I|+jMc85eUqDc6{RUW0>cjv5 literal 0 HcmV?d00001 diff --git a/agent_framework_oci/apps/agent_gateway/app/routes/__pycache__/governed_proxy_example.cpython-313.pyc b/agent_framework_oci/apps/agent_gateway/app/routes/__pycache__/governed_proxy_example.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e4d8952b0c138830e2bd0db6ff5bd465717ce6f4 GIT binary patch literal 2404 zcmaJ@O>7fK6rR~#uh+jM*#P-*!X^QNp~3+gLilM(9TSq!h}!rac6I{^ zr?ec3)Kgng)Lz=EstUansXg=vq)6?lHmT%v6jW8T2W~;B%7GsG#`fZfs$F^KeKYUP z`8mihxiL(jZ@Hl-wv$5kt=+ABAjALxwNnYvP0_h)g^QJF8Dpa#5XjL&j5L ze@(^|CS{kG^tq@`)7Z_}9PF@O>_n55bLJAsU|r5dpj}FN1~EpX_&L8kX-{&KD_5s! zA=y};xu||pVU+S75Yl2=N-2ZlzoM1Xa#D47)v0@~8Up_RWY6?&h<|f^zl+jdH-1}4 zK}0F+W^NSb8}qKA?MOirci_DQ?*zPoF7yJb$iX>O&qqN)w5z5(3x4GU4Q+!{*3c9_ zCT>GH+_f>oTUcJuWw`xcPcsLk?Br8xV6i8o2y=V&0gwW{Boifo9Rd{DMY#eeL!8 z(>BozTcadLD1rLXoPuT%p zG?JJ&qrWl~A5TmS>*?gF%bTYi$2uH~%@i`m%yhwa4j=04>w9z-!hjO?I{8@welQ%n z-0-}GsKBHPHm~_Od(5{oF$HtpUM9P#~W>;VbIBhg3aV9;t=y9 z^H(G0O@VE-D6tGm^z%mM4Ps_>TJ0mu!yTMwfgyXr%*1E%&{CLWful^OwnOt4YoJEn zCVH+w^{RE&0vXIeZ`q*CwxEL%wuyJERK>>xr3FfP%`=6PDxWs+spOD(hxzJFO$0+x zAM?6CN#_gM1r~5!oue}>*Gn=(-daa?--C%&bVDE#}KSGOWEsVOOUq(KQ zeBN1Zk1YtJ`lR%WB_!weQx6mDX*aw13pTqIQU&v8^ZC3d^dau@RA&a z^`#~p@06ERiQ}yT>|JWZ97iyh>8xN)jt_X3cH($6xYQfu_yE_rbP#j-feJp{oahz5 z4va?`8 zhoJluNO>P+-kbrIV&y6PKS7lesAyoVaP9Wii&CG>XQ72$g0iGaMN{QUQrgV7weW#o zw3}!hMnt19Fy-iMAv-riUZVS93bzm0qcA{bF@Au$A0poawB;cR{)+lbsQ(Xi^fzDA tyX}keFQK00(2hm_nv4YHo%Xldi=kc1IJz#h;1RqoB4PLA3Z(l$+dm&_EO!6^ literal 0 HcmV?d00001 diff --git a/agent_framework_oci/apps/mcp_gateway/app/__pycache__/__init__.cpython-313.pyc b/agent_framework_oci/apps/mcp_gateway/app/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0e96f67474edd480be6afb954d87866dc0e523d5 GIT binary patch literal 129 zcmey&%ge<81go11vKWE%V-N=hKms7}nFUBpWk_exWb|9fP{afh0*T*JNGvEQ*3V5Y zh)+)}Ni9#T)CUUa$H!;pWtPOp>lIYq;;_lhPbtkwwJTx;Y5*Bn3}Sp_W@Kb6Vg|AR DoBJFR literal 0 HcmV?d00001 diff --git a/agent_framework_oci/apps/mcp_gateway/app/__pycache__/main.cpython-313.pyc b/agent_framework_oci/apps/mcp_gateway/app/__pycache__/main.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..83107d4891762a1fb9b2a09a78e2ec9bcdd99fca GIT binary patch literal 28096 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 Feature do `agent_framework_oci` — guia bilíngue PT-BR / EN. + +**Implementação principal / Main implementation:** `security/authentication.py` + +--- + +## Português (PT-BR) + +### 1. O que é + +Verifica quem pode acessar APIs, gateways e serviços protegidos antes que a requisição chegue ao agente. + +### 2. Problema que resolve + +Em agentes de produção, não é suficiente pedir ao LLM que “faça a coisa certa”. Esta feature move uma responsabilidade específica para uma camada controlada do framework, reduzindo comportamento imprevisível e código duplicado nos agentes de domínio. + +### 3. Fluxo simplificado + +```text +Cliente/Sistema + ↓ +Authentication Provider + ↓ +credencial válida? + ├─ não → 401/nega acesso + └─ sim → principal autenticado → agente +``` + +### 4. Como funciona internamente + +O framework contém uma abstração `AuthenticationProvider` e implementações para cenários diferentes. Entre as implementações atuais estão `NoAuthenticationProvider`, `DenyAuthenticationProvider`, `BasicAuthenticationProvider`, `ApiKeyAuthenticationProvider`, `StaticBearerAuthenticationProvider`, `JwtAuthenticationProvider`, `OAuth2IntrospectionAuthenticationProvider` e `TrustedProxyAuthenticationProvider`. + +A autenticação produz um `AuthenticatedPrincipal` com `subject`, `scheme` e, quando aplicável, `claims`. A regra de negócio do agente não deve validar senha/token diretamente. + +### 5. Como ativar/configurar + +A ativação exata depende do template/agente. Verifique o arquivo de settings, YAMLs de configuração e o template usado pelo serviço. Nem toda feature precisa de uma flag global: algumas são ativadas pelo contrato retornado por uma tool/workflow. + +### 6. Exemplo + +```python +from agent_framework.security.authentication import BasicAuthenticationProvider + +provider = BasicAuthenticationProvider( + client_id="client-a", + secret_hash="pbkdf2_sha256:...", +) +result = await provider.authenticate(request) +if not result.authenticated: + # negar acesso + ... +``` + +Segredos podem ser verificados em formato simples, SHA-256 ou PBKDF2; em produção, prefira hashes fortes e secret stores. + +### 7. Telemetria e observabilidade + +Quando a feature participa de uma execução de agente, preserve `request_id`, `trace_id`, `session_id`, `agent_id`, `message_id` e demais chaves de correlação no estado/eventos. Isso permite acompanhar a decisão no Langfuse/Observer sem colocar lógica de observabilidade dentro do domínio. + +### 8. Como testar + +1. Crie um teste unitário do comportamento principal. +2. Crie um teste de integração do runtime quando houver estado entre turns. +3. Verifique o caso feliz e pelo menos um caso de falha/negação. +4. Confirme que não há side effects duplicados em retry/replay quando a feature toca transações. +5. Em produção, valide também telemetria e correlação de IDs. + +### 9. Erros comuns + +- Basic auth retornando 401: validar `Authorization: Basic ...` e o secret configurado. +- Confundir autenticação do usuário com `OCI_AUTH_MODE`: são problemas diferentes. +- Usar `NoAuthenticationProvider` em produção sem decisão explícita de arquitetura. + +### 10. Relação com outras features + +Esta feature deve ser usada junto das demais capacidades horizontais do framework, em vez de criar uma implementação paralela no agente de domínio. Em fluxos transacionais, considere especialmente **Clarification**, **Pause/Resume**, **Durable Idempotency**, **Workflow Error Recovery** e **Guardrails**. + +### 11. Referências no repositório + +- `libs/agent_framework/src/agent_framework/security/authentication.py` +- `Tuning-Performance/` +- `Documentacao/` +- `libs/agent_framework/docs/` + +--- + +## English (EN) + +### 1. What it is + +Checks who may access protected APIs, gateways, and services before the request reaches the agent. + +### 2. Problem it solves + +Production agents should not rely on prompts alone to “do the right thing”. This feature moves a specific responsibility into a controlled framework layer, reducing unpredictable behavior and duplicate domain-agent code. + +### 3. Simplified flow + +```text +Client/System + ↓ +Authentication Provider + ↓ +valid credential? + ├─ no → 401/deny + └─ yes → authenticated principal → agent +``` + +### 4. How it works internally + +The framework exposes an `AuthenticationProvider` abstraction with multiple implementations. Current providers include `NoAuthenticationProvider`, `DenyAuthenticationProvider`, `BasicAuthenticationProvider`, `ApiKeyAuthenticationProvider`, `StaticBearerAuthenticationProvider`, `JwtAuthenticationProvider`, `OAuth2IntrospectionAuthenticationProvider`, and `TrustedProxyAuthenticationProvider`. + +Authentication produces an `AuthenticatedPrincipal` containing `subject`, `scheme`, and optional `claims`. Domain code should not validate credentials directly. + +### 5. How to enable/configure + +Exact activation depends on the template/agent. Check framework settings, YAML configuration, and the service template. Not every feature requires a global flag: some are activated by the contract returned from a tool/workflow. + +### 6. Example + +```python +from agent_framework.security.authentication import BasicAuthenticationProvider + +provider = BasicAuthenticationProvider( + client_id="client-a", + secret_hash="pbkdf2_sha256:...", +) +result = await provider.authenticate(request) +if not result.authenticated: + # deny access + ... +``` + +Secrets may be verified as plain, SHA-256, or PBKDF2 values; for production, prefer strong hashes and managed secret stores. + +### 7. Telemetry and observability + +When the feature participates in an agent execution, preserve `request_id`, `trace_id`, `session_id`, `agent_id`, `message_id`, and other correlation keys in state/events. This makes the decision observable through Langfuse/Observer without embedding observability logic in the domain. + +### 8. How to test + +1. Add a unit test for the core behavior. +2. Add a runtime integration test when state spans multiple turns. +3. Test the happy path and at least one failure/rejection path. +4. Confirm retries/replays do not duplicate side effects for transactional features. +5. In production, also validate telemetry and ID correlation. + +### 9. Common mistakes + +- Basic auth returns 401: validate the `Authorization: Basic ...` header and configured secret. +- Do not confuse API authentication with `OCI_AUTH_MODE`; they solve different problems. +- Avoid `NoAuthenticationProvider` in production unless explicitly accepted by architecture. + +### 10. Relationship with other features + +Use this feature together with the framework's horizontal capabilities rather than creating a parallel implementation in domain-agent code. For transactional journeys, pay special attention to **Clarification**, **Pause/Resume**, **Durable Idempotency**, **Workflow Error Recovery**, and **Guardrails**. + +### 11. Repository references + +- `libs/agent_framework/src/agent_framework/security/authentication.py` +- `Tuning-Performance/` +- `Documentacao/` +- `libs/agent_framework/docs/` diff --git a/agent_framework_oci/docs/features/02_deterministic_transactional_workflow.md b/agent_framework_oci/docs/features/02_deterministic_transactional_workflow.md new file mode 100644 index 0000000..5485b94 --- /dev/null +++ b/agent_framework_oci/docs/features/02_deterministic_transactional_workflow.md @@ -0,0 +1,183 @@ +# Workflow Transacional Determinístico / Deterministic Transactional Workflow + +> Feature do `agent_framework_oci` — guia bilíngue PT-BR / EN. + +**Implementação principal / Main implementation:** `workflows/runtime.py + mcp/tool_policy.py` + +--- + +## Português (PT-BR) + +### 1. O que é + +Garante que operações que alteram estado sigam passos previsíveis, com confirmação e controle de execução, em vez de depender da criatividade do LLM. + +### 2. Problema que resolve + +Em agentes de produção, não é suficiente pedir ao LLM que “faça a coisa certa”. Esta feature move uma responsabilidade específica para uma camada controlada do framework, reduzindo comportamento imprevisível e código duplicado nos agentes de domínio. + +### 3. Fluxo simplificado + +```text +Mensagem do cliente + ↓ +LLM entende intenção + ↓ +Tool policy = transactional + ↓ +Workflow determinístico + ↓ +confirmação + ↓ +execução controlada + ↓ +resultado +``` + +### 4. Como funciona internamente + +O LLM pode ajudar a interpretar a intenção e extrair parâmetros, mas não deve decidir a sequência crítica de uma transação. O `ToolPolicyRegistry` classifica tools, e `operation_type: transactional` ativa a política transacional. O `WorkflowRuntime` executa o workflow, mantém estado e integra pause/resume e recuperação de erro. + +A configuração `ENABLE_TRANSACTIONAL_WORKFLOWS` controla a capability global, e `WORKFLOWS_PATH` aponta para os YAMLs. + +### 5. Como ativar/configurar + +A ativação exata depende do template/agente. Verifique o arquivo de settings, YAMLs de configuração e o template usado pelo serviço. Nem toda feature precisa de uma flag global: algumas são ativadas pelo contrato retornado por uma tool/workflow. + +### 6. Exemplo + +```yaml +tools: + cancelar_servico: + operation_type: transactional + requires_confirmation: true +``` + +```text +1. localizar serviço +2. validar elegibilidade +3. pedir confirmação +4. PAUSE +5. receber confirmação +6. RESUME +7. executar side effect +``` + +### 7. Telemetria e observabilidade + +Quando a feature participa de uma execução de agente, preserve `request_id`, `trace_id`, `session_id`, `agent_id`, `message_id` e demais chaves de correlação no estado/eventos. Isso permite acompanhar a decisão no Langfuse/Observer sem colocar lógica de observabilidade dentro do domínio. + +### 8. Como testar + +1. Crie um teste unitário do comportamento principal. +2. Crie um teste de integração do runtime quando houver estado entre turns. +3. Verifique o caso feliz e pelo menos um caso de falha/negação. +4. Confirme que não há side effects duplicados em retry/replay quando a feature toca transações. +5. Em produção, valide também telemetria e correlação de IDs. + +### 9. Erros comuns + +- Marcar uma tool de escrita como `read_only` elimina proteções transacionais. +- Reexecutar steps anteriores ao pause pode duplicar side effects; use o runtime oficial. +- Não use prompt como única garantia de confirmação. + +### 10. Relação com outras features + +Esta feature deve ser usada junto das demais capacidades horizontais do framework, em vez de criar uma implementação paralela no agente de domínio. Em fluxos transacionais, considere especialmente **Clarification**, **Pause/Resume**, **Durable Idempotency**, **Workflow Error Recovery** e **Guardrails**. + +### 11. Referências no repositório + +- `libs/agent_framework/src/agent_framework/workflows/runtime.py` +- `libs/agent_framework/src/agent_framework/mcp/tool_policy.py` +- `Tuning-Performance/` +- `Documentacao/` +- `libs/agent_framework/docs/` + +--- + +## English (EN) + +### 1. What it is + +Ensures state-changing operations follow predictable steps with confirmation and execution control instead of depending on LLM creativity. + +### 2. Problem it solves + +Production agents should not rely on prompts alone to “do the right thing”. This feature moves a specific responsibility into a controlled framework layer, reducing unpredictable behavior and duplicate domain-agent code. + +### 3. Simplified flow + +```text +Customer message + ↓ +LLM understands intent + ↓ +Tool policy = transactional + ↓ +Deterministic workflow + ↓ +confirmation + ↓ +controlled execution + ↓ +result +``` + +### 4. How it works internally + +The LLM may help interpret intent and extract parameters, but it should not decide the critical sequence of a transaction. `ToolPolicyRegistry` classifies tools, and `operation_type: transactional` activates transactional behavior. `WorkflowRuntime` executes the workflow, preserves state, and integrates pause/resume and error recovery. + +`ENABLE_TRANSACTIONAL_WORKFLOWS` controls the capability globally, while `WORKFLOWS_PATH` points to workflow YAML files. + +### 5. How to enable/configure + +Exact activation depends on the template/agent. Check framework settings, YAML configuration, and the service template. Not every feature requires a global flag: some are activated by the contract returned from a tool/workflow. + +### 6. Example + +```yaml +tools: + cancel_service: + operation_type: transactional + requires_confirmation: true +``` + +```text +1. locate service +2. validate eligibility +3. ask for confirmation +4. PAUSE +5. receive confirmation +6. RESUME +7. execute side effect +``` + +### 7. Telemetry and observability + +When the feature participates in an agent execution, preserve `request_id`, `trace_id`, `session_id`, `agent_id`, `message_id`, and other correlation keys in state/events. This makes the decision observable through Langfuse/Observer without embedding observability logic in the domain. + +### 8. How to test + +1. Add a unit test for the core behavior. +2. Add a runtime integration test when state spans multiple turns. +3. Test the happy path and at least one failure/rejection path. +4. Confirm retries/replays do not duplicate side effects for transactional features. +5. In production, also validate telemetry and ID correlation. + +### 9. Common mistakes + +- Marking a write tool as `read_only` bypasses transactional protections. +- Re-running steps before a pause can duplicate side effects; use the official runtime. +- Do not use prompts as the only confirmation guarantee. + +### 10. Relationship with other features + +Use this feature together with the framework's horizontal capabilities rather than creating a parallel implementation in domain-agent code. For transactional journeys, pay special attention to **Clarification**, **Pause/Resume**, **Durable Idempotency**, **Workflow Error Recovery**, and **Guardrails**. + +### 11. Repository references + +- `libs/agent_framework/src/agent_framework/workflows/runtime.py` +- `libs/agent_framework/src/agent_framework/mcp/tool_policy.py` +- `Tuning-Performance/` +- `Documentacao/` +- `libs/agent_framework/docs/` diff --git a/agent_framework_oci/docs/features/03_domain_requested_llm_composition.md b/agent_framework_oci/docs/features/03_domain_requested_llm_composition.md new file mode 100644 index 0000000..4d70018 --- /dev/null +++ b/agent_framework_oci/docs/features/03_domain_requested_llm_composition.md @@ -0,0 +1,157 @@ +# Composição por LLM Solicitada pelo Domínio / Domain Requested LLM Composition + +> Feature do `agent_framework_oci` — guia bilíngue PT-BR / EN. + +**Implementação principal / Main implementation:** `runtime/agent_runtime.py` + +--- + +## Português (PT-BR) + +### 1. O que é + +Permite que a regra de negócio calcule o resultado e peça ao LLM apenas para redigir a resposta final. + +### 2. Problema que resolve + +Em agentes de produção, não é suficiente pedir ao LLM que “faça a coisa certa”. Esta feature move uma responsabilidade específica para uma camada controlada do framework, reduzindo comportamento imprevisível e código duplicado nos agentes de domínio. + +### 3. Fluxo simplificado + +```text +Regra de negócio calcula + ↓ +requires_llm_composition=true + ↓ +framework impede resposta MCP direta + ↓ +LLMProvider oficial + ↓ +redação natural +``` + +### 4. Como funciona internamente + +O domínio retorna dados confiáveis e uma instrução de composição. O `AgentRuntimeMixin` detecta `requires_llm_composition` de forma recursiva no resultado da tool/workflow e não encerra a resposta pelo caminho direto de MCP. A composição segue pelo LLM oficial do agente, preservando profiles, tracing, usage e políticas do framework. + +O LLM deve redigir; ele não deve recalcular valores nem decidir regras de negócio já resolvidas. + +### 5. Como ativar/configurar + +A ativação exata depende do template/agente. Verifique o arquivo de settings, YAMLs de configuração e o template usado pelo serviço. Nem toda feature precisa de uma flag global: algumas são ativadas pelo contrato retornado por uma tool/workflow. + +### 6. Exemplo + +```json +{ + "success": true, + "refund_amount": "38,00", + "requires_llm_composition": true, + "response_instruction": "Explique a devolução usando somente os valores calculados." +} +``` + +### 7. Telemetria e observabilidade + +Quando a feature participa de uma execução de agente, preserve `request_id`, `trace_id`, `session_id`, `agent_id`, `message_id` e demais chaves de correlação no estado/eventos. Isso permite acompanhar a decisão no Langfuse/Observer sem colocar lógica de observabilidade dentro do domínio. + +### 8. Como testar + +1. Crie um teste unitário do comportamento principal. +2. Crie um teste de integração do runtime quando houver estado entre turns. +3. Verifique o caso feliz e pelo menos um caso de falha/negação. +4. Confirme que não há side effects duplicados em retry/replay quando a feature toca transações. +5. Em produção, valide também telemetria e correlação de IDs. + +### 9. Erros comuns + +- Instrução muito aberta pode fazer o LLM adicionar conteúdo não autorizado. +- Não envie ao LLM a responsabilidade de recalcular valores determinísticos. +- Se não houver necessidade de redação livre, prefira resposta determinística direta. + +### 10. Relação com outras features + +Esta feature deve ser usada junto das demais capacidades horizontais do framework, em vez de criar uma implementação paralela no agente de domínio. Em fluxos transacionais, considere especialmente **Clarification**, **Pause/Resume**, **Durable Idempotency**, **Workflow Error Recovery** e **Guardrails**. + +### 11. Referências no repositório + +- `libs/agent_framework/src/agent_framework/runtime/agent_runtime.py` +- `Tuning-Performance/` +- `Documentacao/` +- `libs/agent_framework/docs/` + +--- + +## English (EN) + +### 1. What it is + +Lets domain logic compute the authoritative result and ask the LLM only to compose the final user-facing response. + +### 2. Problem it solves + +Production agents should not rely on prompts alone to “do the right thing”. This feature moves a specific responsibility into a controlled framework layer, reducing unpredictable behavior and duplicate domain-agent code. + +### 3. Simplified flow + +```text +Domain logic computes + ↓ +requires_llm_composition=true + ↓ +framework prevents direct MCP answer + ↓ +official LLMProvider + ↓ +natural-language response +``` + +### 4. How it works internally + +The domain returns authoritative data plus a composition instruction. `AgentRuntimeMixin` recursively detects `requires_llm_composition` in tool/workflow results and avoids terminating through the direct MCP-answer path. Composition then uses the agent's official LLM provider, preserving profiles, tracing, usage accounting, and framework policies. + +The LLM should compose language, not recalculate values or override already-resolved business rules. + +### 5. How to enable/configure + +Exact activation depends on the template/agent. Check framework settings, YAML configuration, and the service template. Not every feature requires a global flag: some are activated by the contract returned from a tool/workflow. + +### 6. Example + +```json +{ + "success": true, + "refund_amount": "38.00", + "requires_llm_composition": true, + "response_instruction": "Explain the refund using only the computed values." +} +``` + +### 7. Telemetry and observability + +When the feature participates in an agent execution, preserve `request_id`, `trace_id`, `session_id`, `agent_id`, `message_id`, and other correlation keys in state/events. This makes the decision observable through Langfuse/Observer without embedding observability logic in the domain. + +### 8. How to test + +1. Add a unit test for the core behavior. +2. Add a runtime integration test when state spans multiple turns. +3. Test the happy path and at least one failure/rejection path. +4. Confirm retries/replays do not duplicate side effects for transactional features. +5. In production, also validate telemetry and ID correlation. + +### 9. Common mistakes + +- An overly broad instruction may let the LLM add unauthorized content. +- Do not delegate deterministic calculations back to the LLM. +- If free-form wording is unnecessary, prefer a deterministic direct response. + +### 10. Relationship with other features + +Use this feature together with the framework's horizontal capabilities rather than creating a parallel implementation in domain-agent code. For transactional journeys, pay special attention to **Clarification**, **Pause/Resume**, **Durable Idempotency**, **Workflow Error Recovery**, and **Guardrails**. + +### 11. Repository references + +- `libs/agent_framework/src/agent_framework/runtime/agent_runtime.py` +- `Tuning-Performance/` +- `Documentacao/` +- `libs/agent_framework/docs/` diff --git a/agent_framework_oci/docs/features/04_domain_requested_rag.md b/agent_framework_oci/docs/features/04_domain_requested_rag.md new file mode 100644 index 0000000..745397f --- /dev/null +++ b/agent_framework_oci/docs/features/04_domain_requested_rag.md @@ -0,0 +1,167 @@ +# RAG Solicitado pelo Domínio / Domain Requested RAG + +> Feature do `agent_framework_oci` — guia bilíngue PT-BR / EN. + +**Implementação principal / Main implementation:** `runtime/agent_runtime.py` + +--- + +## Português (PT-BR) + +### 1. O que é + +Permite que uma tool ou workflow declare que a resposta precisa consultar conhecimento externo, mesmo quando já existe resultado MCP. + +### 2. Problema que resolve + +Em agentes de produção, não é suficiente pedir ao LLM que “faça a coisa certa”. Esta feature move uma responsabilidade específica para uma camada controlada do framework, reduzindo comportamento imprevisível e código duplicado nos agentes de domínio. + +### 3. Fluxo simplificado + +```text +Tool/Workflow + ↓ +requires_rag=true + ↓ +rag_query / rag_queries + ↓ +RagService do framework + ↓ +Retrieval Guardrails + ↓ +LLM/resposta +``` + +### 4. Como funciona internamente + +Normalmente o framework pode pular RAG quando MCP já trouxe informação suficiente (`SKIP_RAG_WHEN_MCP_SUFFICIENT`). Esta feature permite que o domínio substitua essa decisão para um caso específico. O resultado pode declarar `requires_rag`, `rag_query` ou `rag_queries`; o runtime usa essas queries como override e executa o `RagService`. + +O domínio informa **o que precisa saber**. Ele não implementa cliente de vetor, retriever ou prompt RAG paralelo. + +### 5. Como ativar/configurar + +A ativação exata depende do template/agente. Verifique o arquivo de settings, YAMLs de configuração e o template usado pelo serviço. Nem toda feature precisa de uma flag global: algumas são ativadas pelo contrato retornado por uma tool/workflow. + +### 6. Exemplo + +```json +{ + "requires_rag": true, + "rag_queries": [ + "Como cancelar YouTube Premium?", + "Como cancelar Aya Books?" + ] +} +``` + +Configurações relacionadas incluem `RAG_TOP_K` e `SKIP_RAG_WHEN_MCP_SUFFICIENT`. + +### 7. Telemetria e observabilidade + +Quando a feature participa de uma execução de agente, preserve `request_id`, `trace_id`, `session_id`, `agent_id`, `message_id` e demais chaves de correlação no estado/eventos. Isso permite acompanhar a decisão no Langfuse/Observer sem colocar lógica de observabilidade dentro do domínio. + +### 8. Como testar + +1. Crie um teste unitário do comportamento principal. +2. Crie um teste de integração do runtime quando houver estado entre turns. +3. Verifique o caso feliz e pelo menos um caso de falha/negação. +4. Confirme que não há side effects duplicados em retry/replay quando a feature toca transações. +5. Em produção, valide também telemetria e correlação de IDs. + +### 9. Erros comuns + +- Declarar RAG para fatos transacionais já resolvidos pela API pode aumentar custo e latência. +- Query genérica demais reduz relevância. +- Nunca confie no retrieval sem `Retrieval Guardrails` quando o dado influencia resposta crítica. + +### 10. Relação com outras features + +Esta feature deve ser usada junto das demais capacidades horizontais do framework, em vez de criar uma implementação paralela no agente de domínio. Em fluxos transacionais, considere especialmente **Clarification**, **Pause/Resume**, **Durable Idempotency**, **Workflow Error Recovery** e **Guardrails**. + +### 11. Referências no repositório + +- `libs/agent_framework/src/agent_framework/runtime/agent_runtime.py` +- `Tuning-Performance/` +- `Documentacao/` +- `libs/agent_framework/docs/` + +--- + +## English (EN) + +### 1. What it is + +Allows a tool or workflow to declare that external knowledge retrieval is required even when an MCP result already exists. + +### 2. Problem it solves + +Production agents should not rely on prompts alone to “do the right thing”. This feature moves a specific responsibility into a controlled framework layer, reducing unpredictable behavior and duplicate domain-agent code. + +### 3. Simplified flow + +```text +Tool/Workflow + ↓ +requires_rag=true + ↓ +rag_query / rag_queries + ↓ +framework RagService + ↓ +Retrieval Guardrails + ↓ +LLM/response +``` + +### 4. How it works internally + +Normally the framework may skip RAG when MCP already provides sufficient data (`SKIP_RAG_WHEN_MCP_SUFFICIENT`). This feature lets the domain override that decision for a specific case. A result may declare `requires_rag`, `rag_query`, or `rag_queries`; the runtime uses those queries as overrides and invokes `RagService`. + +The domain declares **what knowledge is needed**. It does not implement its own vector client, retriever, or parallel RAG prompt stack. + +### 5. How to enable/configure + +Exact activation depends on the template/agent. Check framework settings, YAML configuration, and the service template. Not every feature requires a global flag: some are activated by the contract returned from a tool/workflow. + +### 6. Example + +```json +{ + "requires_rag": true, + "rag_queries": [ + "How to cancel YouTube Premium?", + "How to cancel Aya Books?" + ] +} +``` + +Related settings include `RAG_TOP_K` and `SKIP_RAG_WHEN_MCP_SUFFICIENT`. + +### 7. Telemetry and observability + +When the feature participates in an agent execution, preserve `request_id`, `trace_id`, `session_id`, `agent_id`, `message_id`, and other correlation keys in state/events. This makes the decision observable through Langfuse/Observer without embedding observability logic in the domain. + +### 8. How to test + +1. Add a unit test for the core behavior. +2. Add a runtime integration test when state spans multiple turns. +3. Test the happy path and at least one failure/rejection path. +4. Confirm retries/replays do not duplicate side effects for transactional features. +5. In production, also validate telemetry and ID correlation. + +### 9. Common mistakes + +- Requesting RAG for transactional facts already resolved by an API adds unnecessary cost and latency. +- Queries that are too broad reduce relevance. +- Do not trust retrieved content for critical responses without Retrieval Guardrails. + +### 10. Relationship with other features + +Use this feature together with the framework's horizontal capabilities rather than creating a parallel implementation in domain-agent code. For transactional journeys, pay special attention to **Clarification**, **Pause/Resume**, **Durable Idempotency**, **Workflow Error Recovery**, and **Guardrails**. + +### 11. Repository references + +- `libs/agent_framework/src/agent_framework/runtime/agent_runtime.py` +- `Tuning-Performance/` +- `Documentacao/` +- `libs/agent_framework/docs/` diff --git a/agent_framework_oci/docs/features/05_long_term_memory.md b/agent_framework_oci/docs/features/05_long_term_memory.md new file mode 100644 index 0000000..e9e43e3 --- /dev/null +++ b/agent_framework_oci/docs/features/05_long_term_memory.md @@ -0,0 +1,167 @@ +# Memória de Longo Prazo / Long Term Memory + +> Feature do `agent_framework_oci` — guia bilíngue PT-BR / EN. + +**Implementação principal / Main implementation:** `memory/long_term_memory.py + memory/long_term_store.py` + +--- + +## Português (PT-BR) + +### 1. O que é + +Permite lembrar informações úteis entre sessões diferentes, sem depender do histórico completo de uma conversa. + +### 2. Problema que resolve + +Em agentes de produção, não é suficiente pedir ao LLM que “faça a coisa certa”. Esta feature move uma responsabilidade específica para uma camada controlada do framework, reduzindo comportamento imprevisível e código duplicado nos agentes de domínio. + +### 3. Fluxo simplificado + +```text +Sessão A + ↓ +extração de memória relevante + ↓ +Long Term Memory Store + ↓ +... dias depois ... + ↓ +Sessão B + ↓ +recupera contexto relevante + ↓ +agente +``` + +### 4. Como funciona internamente + +A memória de longo prazo é diferente de histórico de mensagens e de checkpoint. Ela persiste fatos/preferências úteis e os recupera como contexto de uma nova sessão. O framework oferece providers `memory`, `sqlite`, `autonomous` e `oracle`. + +Configurações importantes: `ENABLE_LONG_TERM_MEMORY`, `LONG_TERM_MEMORY_PROVIDER`, `LONG_TERM_MEMORY_MAX_CONTEXT_ITEMS`, `LONG_TERM_MEMORY_MIN_CONFIDENCE`, `LONG_TERM_MEMORY_AUTO_EXTRACT` e `LONG_TERM_MEMORY_INJECT_CONTEXT`. + +### 5. Como ativar/configurar + +A ativação exata depende do template/agente. Verifique o arquivo de settings, YAMLs de configuração e o template usado pelo serviço. Nem toda feature precisa de uma flag global: algumas são ativadas pelo contrato retornado por uma tool/workflow. + +### 6. Exemplo + +```env +ENABLE_LONG_TERM_MEMORY=true +LONG_TERM_MEMORY_PROVIDER=oracle +LONG_TERM_MEMORY_MAX_CONTEXT_ITEMS=20 +LONG_TERM_MEMORY_MIN_CONFIDENCE=0.70 +LONG_TERM_MEMORY_AUTO_EXTRACT=true +LONG_TERM_MEMORY_INJECT_CONTEXT=true +``` + +### 7. Telemetria e observabilidade + +Quando a feature participa de uma execução de agente, preserve `request_id`, `trace_id`, `session_id`, `agent_id`, `message_id` e demais chaves de correlação no estado/eventos. Isso permite acompanhar a decisão no Langfuse/Observer sem colocar lógica de observabilidade dentro do domínio. + +### 8. Como testar + +1. Crie um teste unitário do comportamento principal. +2. Crie um teste de integração do runtime quando houver estado entre turns. +3. Verifique o caso feliz e pelo menos um caso de falha/negação. +4. Confirme que não há side effects duplicados em retry/replay quando a feature toca transações. +5. Em produção, valide também telemetria e correlação de IDs. + +### 9. Erros comuns + +- Não confundir LTM com replay de toda conversa. +- Memória irrelevante ou de baixa confiança não deveria ser injetada. +- Em múltiplas réplicas, prefira storage durável compartilhado em vez de memória local. + +### 10. Relação com outras features + +Esta feature deve ser usada junto das demais capacidades horizontais do framework, em vez de criar uma implementação paralela no agente de domínio. Em fluxos transacionais, considere especialmente **Clarification**, **Pause/Resume**, **Durable Idempotency**, **Workflow Error Recovery** e **Guardrails**. + +### 11. Referências no repositório + +- `libs/agent_framework/src/agent_framework/memory/long_term_memory.py` +- `libs/agent_framework/src/agent_framework/memory/long_term_store.py` +- `Tuning-Performance/` +- `Documentacao/` +- `libs/agent_framework/docs/` + +--- + +## English (EN) + +### 1. What it is + +Allows useful information to persist across different sessions without depending on the full transcript of a previous conversation. + +### 2. Problem it solves + +Production agents should not rely on prompts alone to “do the right thing”. This feature moves a specific responsibility into a controlled framework layer, reducing unpredictable behavior and duplicate domain-agent code. + +### 3. Simplified flow + +```text +Session A + ↓ +extract relevant memory + ↓ +Long Term Memory Store + ↓ +... days later ... + ↓ +Session B + ↓ +retrieve relevant context + ↓ +agent +``` + +### 4. How it works internally + +Long-term memory is different from message history and checkpoints. It persists useful facts/preferences and retrieves them as context for a future session. The framework supports `memory`, `sqlite`, `autonomous`, and `oracle` providers. + +Important settings include `ENABLE_LONG_TERM_MEMORY`, `LONG_TERM_MEMORY_PROVIDER`, `LONG_TERM_MEMORY_MAX_CONTEXT_ITEMS`, `LONG_TERM_MEMORY_MIN_CONFIDENCE`, `LONG_TERM_MEMORY_AUTO_EXTRACT`, and `LONG_TERM_MEMORY_INJECT_CONTEXT`. + +### 5. How to enable/configure + +Exact activation depends on the template/agent. Check framework settings, YAML configuration, and the service template. Not every feature requires a global flag: some are activated by the contract returned from a tool/workflow. + +### 6. Example + +```env +ENABLE_LONG_TERM_MEMORY=true +LONG_TERM_MEMORY_PROVIDER=oracle +LONG_TERM_MEMORY_MAX_CONTEXT_ITEMS=20 +LONG_TERM_MEMORY_MIN_CONFIDENCE=0.70 +LONG_TERM_MEMORY_AUTO_EXTRACT=true +LONG_TERM_MEMORY_INJECT_CONTEXT=true +``` + +### 7. Telemetry and observability + +When the feature participates in an agent execution, preserve `request_id`, `trace_id`, `session_id`, `agent_id`, `message_id`, and other correlation keys in state/events. This makes the decision observable through Langfuse/Observer without embedding observability logic in the domain. + +### 8. How to test + +1. Add a unit test for the core behavior. +2. Add a runtime integration test when state spans multiple turns. +3. Test the happy path and at least one failure/rejection path. +4. Confirm retries/replays do not duplicate side effects for transactional features. +5. In production, also validate telemetry and ID correlation. + +### 9. Common mistakes + +- Do not confuse LTM with replaying the entire transcript. +- Irrelevant or low-confidence memories should not be injected. +- For multiple replicas, prefer shared durable storage over local memory. + +### 10. Relationship with other features + +Use this feature together with the framework's horizontal capabilities rather than creating a parallel implementation in domain-agent code. For transactional journeys, pay special attention to **Clarification**, **Pause/Resume**, **Durable Idempotency**, **Workflow Error Recovery**, and **Guardrails**. + +### 11. Repository references + +- `libs/agent_framework/src/agent_framework/memory/long_term_memory.py` +- `libs/agent_framework/src/agent_framework/memory/long_term_store.py` +- `Tuning-Performance/` +- `Documentacao/` +- `libs/agent_framework/docs/` diff --git a/agent_framework_oci/docs/features/06_offline_workflow_regression.md b/agent_framework_oci/docs/features/06_offline_workflow_regression.md new file mode 100644 index 0000000..5569f63 --- /dev/null +++ b/agent_framework_oci/docs/features/06_offline_workflow_regression.md @@ -0,0 +1,163 @@ +# Regressão Offline de Workflow / Offline Workflow Regression + +> Feature do `agent_framework_oci` — guia bilíngue PT-BR / EN. + +**Implementação principal / Main implementation:** `workflows/runtime.py + Tuning-Performance/Offline_Workflow_Regression` + +--- + +## Português (PT-BR) + +### 1. O que é + +Permite testar a lógica de workflows sem exigir toda a infraestrutura de produção. + +### 2. Problema que resolve + +Em agentes de produção, não é suficiente pedir ao LLM que “faça a coisa certa”. Esta feature move uma responsabilidade específica para uma camada controlada do framework, reduzindo comportamento imprevisível e código duplicado nos agentes de domínio. + +### 3. Fluxo simplificado + +```text +Teste + ↓ +backend determinístico explicitamente habilitado + ↓ +run → PAUSED + ↓ +resume → COMPLETED + ↓ +asserts de estado/side effects +``` + +### 4. Como funciona internamente + +O `WorkflowRuntime` possui um caminho determinístico/offline **explicitamente opt-in para testes**. Ele permite validar DSL, condições, pause/resume e proteção contra reexecução sem exigir LangGraph, banco, OCI ou APIs externas. + +O comportamento de produção continua usando LangGraph. O modo offline não deve virar fallback silencioso quando LangGraph falha ou está ausente em produção. + +### 5. Como ativar/configurar + +A ativação exata depende do template/agente. Verifique o arquivo de settings, YAMLs de configuração e o template usado pelo serviço. Nem toda feature precisa de uma flag global: algumas são ativadas pelo contrato retornado por uma tool/workflow. + +### 6. Exemplo + +```text +run(workflow) + action_a = 1 execução + status = PAUSED + +resume(workflow) + action_a continua com 1 execução + action_b = 1 execução + status = COMPLETED +``` + +### 7. Telemetria e observabilidade + +Quando a feature participa de uma execução de agente, preserve `request_id`, `trace_id`, `session_id`, `agent_id`, `message_id` e demais chaves de correlação no estado/eventos. Isso permite acompanhar a decisão no Langfuse/Observer sem colocar lógica de observabilidade dentro do domínio. + +### 8. Como testar + +1. Crie um teste unitário do comportamento principal. +2. Crie um teste de integração do runtime quando houver estado entre turns. +3. Verifique o caso feliz e pelo menos um caso de falha/negação. +4. Confirme que não há side effects duplicados em retry/replay quando a feature toca transações. +5. Em produção, valide também telemetria e correlação de IDs. + +### 9. Erros comuns + +- Usar o backend offline em produção mascara problemas reais. +- Mockar tanto que o teste deixa de validar a DSL real. +- Não verificar side effects anteriores ao pause pode esconder duplicações. + +### 10. Relação com outras features + +Esta feature deve ser usada junto das demais capacidades horizontais do framework, em vez de criar uma implementação paralela no agente de domínio. Em fluxos transacionais, considere especialmente **Clarification**, **Pause/Resume**, **Durable Idempotency**, **Workflow Error Recovery** e **Guardrails**. + +### 11. Referências no repositório + +- `libs/agent_framework/src/agent_framework/workflows/runtime.py` +- `libs/agent_framework/src/agent_framework/Tuning-Performance/Offline_Workflow_Regression` +- `Tuning-Performance/` +- `Documentacao/` +- `libs/agent_framework/docs/` + +--- + +## English (EN) + +### 1. What it is + +Allows workflow logic to be regression-tested without requiring the full production infrastructure. + +### 2. Problem it solves + +Production agents should not rely on prompts alone to “do the right thing”. This feature moves a specific responsibility into a controlled framework layer, reducing unpredictable behavior and duplicate domain-agent code. + +### 3. Simplified flow + +```text +Test + ↓ +explicit deterministic test backend + ↓ +run → PAUSED + ↓ +resume → COMPLETED + ↓ +state/side-effect assertions +``` + +### 4. How it works internally + +`WorkflowRuntime` includes an **explicitly opt-in deterministic/offline test backend**. It can validate DSL rules, conditions, pause/resume behavior, and duplicate-execution protection without requiring LangGraph, a database, OCI, or external APIs. + +Production behavior still uses LangGraph. Offline mode must never become a silent fallback when LangGraph fails or is unavailable in production. + +### 5. How to enable/configure + +Exact activation depends on the template/agent. Check framework settings, YAML configuration, and the service template. Not every feature requires a global flag: some are activated by the contract returned from a tool/workflow. + +### 6. Example + +```text +run(workflow) + action_a = executed once + status = PAUSED + +resume(workflow) + action_a remains executed once + action_b = executed once + status = COMPLETED +``` + +### 7. Telemetry and observability + +When the feature participates in an agent execution, preserve `request_id`, `trace_id`, `session_id`, `agent_id`, `message_id`, and other correlation keys in state/events. This makes the decision observable through Langfuse/Observer without embedding observability logic in the domain. + +### 8. How to test + +1. Add a unit test for the core behavior. +2. Add a runtime integration test when state spans multiple turns. +3. Test the happy path and at least one failure/rejection path. +4. Confirm retries/replays do not duplicate side effects for transactional features. +5. In production, also validate telemetry and ID correlation. + +### 9. Common mistakes + +- Using the offline backend in production hides real issues. +- Over-mocking can stop the test from validating real DSL behavior. +- Failing to assert pre-pause side effects may hide duplicate execution. + +### 10. Relationship with other features + +Use this feature together with the framework's horizontal capabilities rather than creating a parallel implementation in domain-agent code. For transactional journeys, pay special attention to **Clarification**, **Pause/Resume**, **Durable Idempotency**, **Workflow Error Recovery**, and **Guardrails**. + +### 11. Repository references + +- `libs/agent_framework/src/agent_framework/workflows/runtime.py` +- `libs/agent_framework/src/agent_framework/Tuning-Performance/Offline_Workflow_Regression` +- `Tuning-Performance/` +- `Documentacao/` +- `libs/agent_framework/docs/` diff --git a/agent_framework_oci/docs/features/07_pause_resume_workflow.md b/agent_framework_oci/docs/features/07_pause_resume_workflow.md new file mode 100644 index 0000000..b600937 --- /dev/null +++ b/agent_framework_oci/docs/features/07_pause_resume_workflow.md @@ -0,0 +1,165 @@ +# Pause / Resume de Workflow / Pause / Resume Workflow + +> Feature do `agent_framework_oci` — guia bilíngue PT-BR / EN. + +**Implementação principal / Main implementation:** `workflows/runtime.py + workflows/graph.py` + +--- + +## Português (PT-BR) + +### 1. O que é + +Permite interromper um workflow em um ponto seguro, persistir o estado e continuar depois com a resposta do usuário ou outro evento. + +### 2. Problema que resolve + +Em agentes de produção, não é suficiente pedir ao LLM que “faça a coisa certa”. Esta feature move uma responsabilidade específica para uma camada controlada do framework, reduzindo comportamento imprevisível e código duplicado nos agentes de domínio. + +### 3. Fluxo simplificado + +```text +Workflow + ↓ +ações prévias + ↓ +PAUSE + ↓ +checkpoint/estado + ↓ +nova mensagem + ↓ +RESUME + ↓ +ações seguintes +``` + +### 4. Como funciona internamente + +`WorkflowRuntime` expõe `arun(...)` e `aresume(...)`. O nó de pause é separado da action anterior para evitar reexecutar side effects quando o workflow retoma. O mesmo `execution_id/thread_id` identifica a execução pausada e retomada. + +O runtime suporta condições declarativas como `all`, `any`, `not`, `eq`, `neq` e `exists`, permitindo definir quando pausar ou continuar sem colocar lógica conversacional no prompt. + +### 5. Como ativar/configurar + +A ativação exata depende do template/agente. Verifique o arquivo de settings, YAMLs de configuração e o template usado pelo serviço. Nem toda feature precisa de uma flag global: algumas são ativadas pelo contrato retornado por uma tool/workflow. + +### 6. Exemplo + +```text +status = await runtime.arun(...) +# status == PAUSED + +status = await runtime.aresume(execution_id, input={"confirmed": true}) +# status == COMPLETED +``` + +### 7. Telemetria e observabilidade + +Quando a feature participa de uma execução de agente, preserve `request_id`, `trace_id`, `session_id`, `agent_id`, `message_id` e demais chaves de correlação no estado/eventos. Isso permite acompanhar a decisão no Langfuse/Observer sem colocar lógica de observabilidade dentro do domínio. + +### 8. Como testar + +1. Crie um teste unitário do comportamento principal. +2. Crie um teste de integração do runtime quando houver estado entre turns. +3. Verifique o caso feliz e pelo menos um caso de falha/negação. +4. Confirme que não há side effects duplicados em retry/replay quando a feature toca transações. +5. Em produção, valide também telemetria e correlação de IDs. + +### 9. Erros comuns + +- Perder o `execution_id` impede retomar a execução correta. +- Reexecutar o workflow do zero após confirmação pode repetir side effects. +- Pause sem storage/checkpoint compartilhado é frágil em múltiplas réplicas. + +### 10. Relação com outras features + +Esta feature deve ser usada junto das demais capacidades horizontais do framework, em vez de criar uma implementação paralela no agente de domínio. Em fluxos transacionais, considere especialmente **Clarification**, **Pause/Resume**, **Durable Idempotency**, **Workflow Error Recovery** e **Guardrails**. + +### 11. Referências no repositório + +- `libs/agent_framework/src/agent_framework/workflows/runtime.py` +- `libs/agent_framework/src/agent_framework/workflows/graph.py` +- `Tuning-Performance/` +- `Documentacao/` +- `libs/agent_framework/docs/` + +--- + +## English (EN) + +### 1. What it is + +Allows a workflow to stop at a safe point, persist state, and continue later using user input or another event. + +### 2. Problem it solves + +Production agents should not rely on prompts alone to “do the right thing”. This feature moves a specific responsibility into a controlled framework layer, reducing unpredictable behavior and duplicate domain-agent code. + +### 3. Simplified flow + +```text +Workflow + ↓ +pre-pause actions + ↓ +PAUSE + ↓ +checkpoint/state + ↓ +new message + ↓ +RESUME + ↓ +remaining actions +``` + +### 4. How it works internally + +`WorkflowRuntime` exposes `arun(...)` and `aresume(...)`. The pause node is separated from the preceding action so previous side effects are not executed again on resume. The same `execution_id/thread_id` identifies the paused and resumed execution. + +The runtime supports declarative conditions such as `all`, `any`, `not`, `eq`, `neq`, and `exists`, so pause/continue decisions do not need to live in the prompt. + +### 5. How to enable/configure + +Exact activation depends on the template/agent. Check framework settings, YAML configuration, and the service template. Not every feature requires a global flag: some are activated by the contract returned from a tool/workflow. + +### 6. Example + +```text +status = await runtime.arun(...) +# status == PAUSED + +status = await runtime.aresume(execution_id, input={"confirmed": true}) +# status == COMPLETED +``` + +### 7. Telemetry and observability + +When the feature participates in an agent execution, preserve `request_id`, `trace_id`, `session_id`, `agent_id`, `message_id`, and other correlation keys in state/events. This makes the decision observable through Langfuse/Observer without embedding observability logic in the domain. + +### 8. How to test + +1. Add a unit test for the core behavior. +2. Add a runtime integration test when state spans multiple turns. +3. Test the happy path and at least one failure/rejection path. +4. Confirm retries/replays do not duplicate side effects for transactional features. +5. In production, also validate telemetry and ID correlation. + +### 9. Common mistakes + +- Losing the `execution_id` prevents resuming the right execution. +- Restarting the workflow from scratch after confirmation may duplicate side effects. +- Pause without shared checkpoint/state storage is fragile across multiple replicas. + +### 10. Relationship with other features + +Use this feature together with the framework's horizontal capabilities rather than creating a parallel implementation in domain-agent code. For transactional journeys, pay special attention to **Clarification**, **Pause/Resume**, **Durable Idempotency**, **Workflow Error Recovery**, and **Guardrails**. + +### 11. Repository references + +- `libs/agent_framework/src/agent_framework/workflows/runtime.py` +- `libs/agent_framework/src/agent_framework/workflows/graph.py` +- `Tuning-Performance/` +- `Documentacao/` +- `libs/agent_framework/docs/` diff --git a/agent_framework_oci/docs/features/08_route_stickiness.md b/agent_framework_oci/docs/features/08_route_stickiness.md new file mode 100644 index 0000000..264a17e --- /dev/null +++ b/agent_framework_oci/docs/features/08_route_stickiness.md @@ -0,0 +1,151 @@ +# Aderência de Rota / Route Stickiness + +> Feature do `agent_framework_oci` — guia bilíngue PT-BR / EN. + +**Implementação principal / Main implementation:** `routing/enterprise_router.py + runtime/agent_runtime.py` + +--- + +## Português (PT-BR) + +### 1. O que é + +Evita que pequenas mensagens de continuação façam a conversa trocar de agente sem necessidade. + +### 2. Problema que resolve + +Em agentes de produção, não é suficiente pedir ao LLM que “faça a coisa certa”. Esta feature move uma responsabilidade específica para uma camada controlada do framework, reduzindo comportamento imprevisível e código duplicado nos agentes de domínio. + +### 3. Fluxo simplificado + +```text +mensagem atual + + histórico curto + + rota anterior + ↓ +continuidade semântica + ↓ +manter rota ou handoff +``` + +### 4. Como funciona internamente + +Route Stickiness avalia se a nova mensagem continua semanticamente ligada ao assunto/agente atual. Isso reduz ping-pong de agentes em mensagens como “e esse valor?”, “sim”, “o segundo” ou “e no mês passado?”. + +Configurações existentes incluem `ENABLE_ROUTE_STICKINESS`, `ROUTE_STICKINESS_LLM_PROFILE`, `ROUTE_STICKINESS_CONFIDENCE_THRESHOLD`, `ROUTE_STICKINESS_HISTORY_TURNS` e `ROUTE_STICKINESS_MAX_TOKENS`. A decisão pode permitir handoff quando há evidência suficiente de mudança de assunto. + +### 5. Como ativar/configurar + +A ativação exata depende do template/agente. Verifique o arquivo de settings, YAMLs de configuração e o template usado pelo serviço. Nem toda feature precisa de uma flag global: algumas são ativadas pelo contrato retornado por uma tool/workflow. + +### 6. Exemplo + +```env +ENABLE_ROUTE_STICKINESS=true +ROUTE_STICKINESS_CONFIDENCE_THRESHOLD=0.90 +ROUTE_STICKINESS_HISTORY_TURNS=2 +ROUTE_STICKINESS_MAX_TOKENS=80 +``` + +### 7. Telemetria e observabilidade + +Quando a feature participa de uma execução de agente, preserve `request_id`, `trace_id`, `session_id`, `agent_id`, `message_id` e demais chaves de correlação no estado/eventos. Isso permite acompanhar a decisão no Langfuse/Observer sem colocar lógica de observabilidade dentro do domínio. + +### 8. Como testar + +1. Crie um teste unitário do comportamento principal. +2. Crie um teste de integração do runtime quando houver estado entre turns. +3. Verifique o caso feliz e pelo menos um caso de falha/negação. +4. Confirme que não há side effects duplicados em retry/replay quando a feature toca transações. +5. Em produção, valide também telemetria e correlação de IDs. + +### 9. Erros comuns + +- Threshold muito baixo pode prender o cliente no agente errado. +- Threshold alto demais perde continuidade em mensagens curtas. +- Stickiness não deve bloquear handoff explícito quando a intenção realmente mudou. + +### 10. Relação com outras features + +Esta feature deve ser usada junto das demais capacidades horizontais do framework, em vez de criar uma implementação paralela no agente de domínio. Em fluxos transacionais, considere especialmente **Clarification**, **Pause/Resume**, **Durable Idempotency**, **Workflow Error Recovery** e **Guardrails**. + +### 11. Referências no repositório + +- `libs/agent_framework/src/agent_framework/routing/enterprise_router.py` +- `libs/agent_framework/src/agent_framework/runtime/agent_runtime.py` +- `Tuning-Performance/` +- `Documentacao/` +- `libs/agent_framework/docs/` + +--- + +## English (EN) + +### 1. What it is + +Prevents short follow-up messages from unnecessarily switching the conversation to another agent. + +### 2. Problem it solves + +Production agents should not rely on prompts alone to “do the right thing”. This feature moves a specific responsibility into a controlled framework layer, reducing unpredictable behavior and duplicate domain-agent code. + +### 3. Simplified flow + +```text +current message + + short history + + previous route + ↓ +semantic continuity + ↓ +keep route or handoff +``` + +### 4. How it works internally + +Route Stickiness evaluates whether a new message is semantically continuous with the current subject/agent. It reduces agent ping-pong for messages such as “what about that amount?”, “yes”, “the second one”, or “and last month?”. + +Existing settings include `ENABLE_ROUTE_STICKINESS`, `ROUTE_STICKINESS_LLM_PROFILE`, `ROUTE_STICKINESS_CONFIDENCE_THRESHOLD`, `ROUTE_STICKINESS_HISTORY_TURNS`, and `ROUTE_STICKINESS_MAX_TOKENS`. The decision may still allow handoff when there is enough evidence of a topic change. + +### 5. How to enable/configure + +Exact activation depends on the template/agent. Check framework settings, YAML configuration, and the service template. Not every feature requires a global flag: some are activated by the contract returned from a tool/workflow. + +### 6. Example + +```env +ENABLE_ROUTE_STICKINESS=true +ROUTE_STICKINESS_CONFIDENCE_THRESHOLD=0.90 +ROUTE_STICKINESS_HISTORY_TURNS=2 +ROUTE_STICKINESS_MAX_TOKENS=80 +``` + +### 7. Telemetry and observability + +When the feature participates in an agent execution, preserve `request_id`, `trace_id`, `session_id`, `agent_id`, `message_id`, and other correlation keys in state/events. This makes the decision observable through Langfuse/Observer without embedding observability logic in the domain. + +### 8. How to test + +1. Add a unit test for the core behavior. +2. Add a runtime integration test when state spans multiple turns. +3. Test the happy path and at least one failure/rejection path. +4. Confirm retries/replays do not duplicate side effects for transactional features. +5. In production, also validate telemetry and ID correlation. + +### 9. Common mistakes + +- A threshold that is too low may trap the user on the wrong agent. +- A threshold that is too high may lose continuity on short follow-ups. +- Stickiness should not block explicit handoff when the user clearly changes intent. + +### 10. Relationship with other features + +Use this feature together with the framework's horizontal capabilities rather than creating a parallel implementation in domain-agent code. For transactional journeys, pay special attention to **Clarification**, **Pause/Resume**, **Durable Idempotency**, **Workflow Error Recovery**, and **Guardrails**. + +### 11. Repository references + +- `libs/agent_framework/src/agent_framework/routing/enterprise_router.py` +- `libs/agent_framework/src/agent_framework/runtime/agent_runtime.py` +- `Tuning-Performance/` +- `Documentacao/` +- `libs/agent_framework/docs/` diff --git a/agent_framework_oci/docs/features/09_voice_interruption_replay.md b/agent_framework_oci/docs/features/09_voice_interruption_replay.md new file mode 100644 index 0000000..85bd363 --- /dev/null +++ b/agent_framework_oci/docs/features/09_voice_interruption_replay.md @@ -0,0 +1,153 @@ +# Replay em Interrupções de Voz / Voice Interruption Replay + +> Feature do `agent_framework_oci` — guia bilíngue PT-BR / EN. + +**Implementação principal / Main implementation:** `channels/interruption.py` + +--- + +## Português (PT-BR) + +### 1. O que é + +Decide se um áudio recebido durante a fala do agente representa uma nova intenção, um ruído/backchannel ou algo que deve apenas repetir/continuar a última fala. + +### 2. Problema que resolve + +Em agentes de produção, não é suficiente pedir ao LLM que “faça a coisa certa”. Esta feature move uma responsabilidade específica para uma camada controlada do framework, reduzindo comportamento imprevisível e código duplicado nos agentes de domínio. + +### 3. Fluxo simplificado + +```text +áudio durante fala + ↓ +InterruptionPolicy + ├─ process → nova mensagem + ├─ classify → classificador leve + └─ replay → última fala +``` + +### 4. Como funciona internamente + +A política fica no framework, não no domínio. Ela diferencia sessão terminal, `idle_nudge`, fala não interrompível e fala potencialmente interrompível. Quando necessário, pode usar um classificador leve baseado no `LLMProvider`; quando a classificação falha, a política é conservadora e pode optar por replay. + +O objetivo é evitar que “aham”, ruído, eco ou fragmentos residuais sejam tratados como uma nova intenção completa. + +### 5. Como ativar/configurar + +A ativação exata depende do template/agente. Verifique o arquivo de settings, YAMLs de configuração e o template usado pelo serviço. Nem toda feature precisa de uma flag global: algumas são ativadas pelo contrato retornado por uma tool/workflow. + +### 6. Exemplo + +```text +Agente: "Sua fatura possui..." +Cliente: "aham" +→ replay/continua + +Agente: "Sua fatura possui..." +Cliente: "espera, quero falar de outra coisa" +→ processa nova intenção +``` + +### 7. Telemetria e observabilidade + +Quando a feature participa de uma execução de agente, preserve `request_id`, `trace_id`, `session_id`, `agent_id`, `message_id` e demais chaves de correlação no estado/eventos. Isso permite acompanhar a decisão no Langfuse/Observer sem colocar lógica de observabilidade dentro do domínio. + +### 8. Como testar + +1. Crie um teste unitário do comportamento principal. +2. Crie um teste de integração do runtime quando houver estado entre turns. +3. Verifique o caso feliz e pelo menos um caso de falha/negação. +4. Confirme que não há side effects duplicados em retry/replay quando a feature toca transações. +5. Em produção, valide também telemetria e correlação de IDs. + +### 9. Erros comuns + +- Classificar todo ruído com LLM aumenta latência e custo. +- Permitir interrupção em fala transacional não interrompível pode corromper UX/estado. +- Replay deve usar uma fala real anterior, não um envelope técnico. + +### 10. Relação com outras features + +Esta feature deve ser usada junto das demais capacidades horizontais do framework, em vez de criar uma implementação paralela no agente de domínio. Em fluxos transacionais, considere especialmente **Clarification**, **Pause/Resume**, **Durable Idempotency**, **Workflow Error Recovery** e **Guardrails**. + +### 11. Referências no repositório + +- `libs/agent_framework/src/agent_framework/channels/interruption.py` +- `Tuning-Performance/` +- `Documentacao/` +- `libs/agent_framework/docs/` + +--- + +## English (EN) + +### 1. What it is + +Decides whether audio received while the agent is speaking represents a new intent, a backchannel/noise event, or something that should simply replay/continue the previous speech. + +### 2. Problem it solves + +Production agents should not rely on prompts alone to “do the right thing”. This feature moves a specific responsibility into a controlled framework layer, reducing unpredictable behavior and duplicate domain-agent code. + +### 3. Simplified flow + +```text +audio during speech + ↓ +InterruptionPolicy + ├─ process → new message + ├─ classify → lightweight classifier + └─ replay → previous speech +``` + +### 4. How it works internally + +The policy lives in the framework rather than domain code. It distinguishes terminal sessions, `idle_nudge`, non-interruptible speech, and potentially interruptible speech. When needed, it may use a lightweight classifier backed by `LLMProvider`; on classification failure, it can fail safely to replay. + +The goal is to prevent “uh-huh”, noise, echo, or residual audio fragments from being interpreted as a full new intent. + +### 5. How to enable/configure + +Exact activation depends on the template/agent. Check framework settings, YAML configuration, and the service template. Not every feature requires a global flag: some are activated by the contract returned from a tool/workflow. + +### 6. Example + +```text +Agent: "Your invoice contains..." +User: "uh-huh" +→ replay/continue + +Agent: "Your invoice contains..." +User: "wait, I want to ask something else" +→ process new intent +``` + +### 7. Telemetry and observability + +When the feature participates in an agent execution, preserve `request_id`, `trace_id`, `session_id`, `agent_id`, `message_id`, and other correlation keys in state/events. This makes the decision observable through Langfuse/Observer without embedding observability logic in the domain. + +### 8. How to test + +1. Add a unit test for the core behavior. +2. Add a runtime integration test when state spans multiple turns. +3. Test the happy path and at least one failure/rejection path. +4. Confirm retries/replays do not duplicate side effects for transactional features. +5. In production, also validate telemetry and ID correlation. + +### 9. Common mistakes + +- Sending every noise fragment to an LLM increases latency and cost. +- Allowing interruption during non-interruptible transactional speech may corrupt UX/state. +- Replay should use a real previous utterance, not a technical envelope. + +### 10. Relationship with other features + +Use this feature together with the framework's horizontal capabilities rather than creating a parallel implementation in domain-agent code. For transactional journeys, pay special attention to **Clarification**, **Pause/Resume**, **Durable Idempotency**, **Workflow Error Recovery**, and **Guardrails**. + +### 11. Repository references + +- `libs/agent_framework/src/agent_framework/channels/interruption.py` +- `Tuning-Performance/` +- `Documentacao/` +- `libs/agent_framework/docs/` diff --git a/agent_framework_oci/docs/features/10_workflow_error_recovery.md b/agent_framework_oci/docs/features/10_workflow_error_recovery.md new file mode 100644 index 0000000..e5ef8d6 --- /dev/null +++ b/agent_framework_oci/docs/features/10_workflow_error_recovery.md @@ -0,0 +1,167 @@ +# Recuperação de Erro em Workflow / Workflow Error Recovery + +> Feature do `agent_framework_oci` — guia bilíngue PT-BR / EN. + +**Implementação principal / Main implementation:** `workflows/runtime.py` + +--- + +## Português (PT-BR) + +### 1. O que é + +Preserva o estado parcial de uma execução quando um passo posterior falha, permitindo entender o que já aconteceu e evitar repetir side effects. + +### 2. Problema que resolve + +Em agentes de produção, não é suficiente pedir ao LLM que “faça a coisa certa”. Esta feature move uma responsabilidade específica para uma camada controlada do framework, reduzindo comportamento imprevisível e código duplicado nos agentes de domínio. + +### 3. Fluxo simplificado + +```text +passo A ✅ +passo B ✅ +passo C ❌ + ↓ +FAILED + snapshot parcial + ↓ +recovery decide o que pode continuar/repetir +``` + +### 4. Como funciona internamente + +O runtime preserva o snapshot parcial do LangGraph quando uma etapa posterior falha e produz `error_details` genérico. Quando a exceção externa possui informações estruturadas, podem ser preservados status HTTP, body, número de tentativas, code e metadata. + +A feature não significa “tentar tudo de novo”. Recuperação segura depende de conhecer o estado já executado, a idempotência e a natureza do erro. + +### 5. Como ativar/configurar + +A ativação exata depende do template/agente. Verifique o arquivo de settings, YAMLs de configuração e o template usado pelo serviço. Nem toda feature precisa de uma flag global: algumas são ativadas pelo contrato retornado por uma tool/workflow. + +### 6. Exemplo + +```json +{ + "status": "FAILED", + "error_details": { + "status": 503, + "attempts": 3, + "code": "UPSTREAM_UNAVAILABLE" + }, + "state": { + "protocol_created": true, + "operation_completed": true, + "sms_sent": false + } +} +``` + +### 7. Telemetria e observabilidade + +Quando a feature participa de uma execução de agente, preserve `request_id`, `trace_id`, `session_id`, `agent_id`, `message_id` e demais chaves de correlação no estado/eventos. Isso permite acompanhar a decisão no Langfuse/Observer sem colocar lógica de observabilidade dentro do domínio. + +### 8. Como testar + +1. Crie um teste unitário do comportamento principal. +2. Crie um teste de integração do runtime quando houver estado entre turns. +3. Verifique o caso feliz e pelo menos um caso de falha/negação. +4. Confirme que não há side effects duplicados em retry/replay quando a feature toca transações. +5. Em produção, valide também telemetria e correlação de IDs. + +### 9. Erros comuns + +- Retry indiscriminado pode repetir transações. +- Se a exceção externa perde metadata, a recuperação fica menos precisa. +- Combine sempre com Durable Idempotency em side effects críticos. + +### 10. Relação com outras features + +Esta feature deve ser usada junto das demais capacidades horizontais do framework, em vez de criar uma implementação paralela no agente de domínio. Em fluxos transacionais, considere especialmente **Clarification**, **Pause/Resume**, **Durable Idempotency**, **Workflow Error Recovery** e **Guardrails**. + +### 11. Referências no repositório + +- `libs/agent_framework/src/agent_framework/workflows/runtime.py` +- `Tuning-Performance/` +- `Documentacao/` +- `libs/agent_framework/docs/` + +--- + +## English (EN) + +### 1. What it is + +Preserves partial execution state when a later step fails, making it possible to know what already happened and avoid repeating side effects. + +### 2. Problem it solves + +Production agents should not rely on prompts alone to “do the right thing”. This feature moves a specific responsibility into a controlled framework layer, reducing unpredictable behavior and duplicate domain-agent code. + +### 3. Simplified flow + +```text +step A ✅ +step B ✅ +step C ❌ + ↓ +FAILED + partial snapshot + ↓ +recovery decides what may continue/retry +``` + +### 4. How it works internally + +The runtime preserves the partial LangGraph snapshot when a later step fails and produces generic `error_details`. When an external exception provides structured information, HTTP status, body, attempt count, code, and metadata may be preserved. + +This feature does not mean “retry everything”. Safe recovery depends on knowing what already executed, idempotency guarantees, and the nature of the failure. + +### 5. How to enable/configure + +Exact activation depends on the template/agent. Check framework settings, YAML configuration, and the service template. Not every feature requires a global flag: some are activated by the contract returned from a tool/workflow. + +### 6. Example + +```json +{ + "status": "FAILED", + "error_details": { + "status": 503, + "attempts": 3, + "code": "UPSTREAM_UNAVAILABLE" + }, + "state": { + "protocol_created": true, + "operation_completed": true, + "sms_sent": false + } +} +``` + +### 7. Telemetry and observability + +When the feature participates in an agent execution, preserve `request_id`, `trace_id`, `session_id`, `agent_id`, `message_id`, and other correlation keys in state/events. This makes the decision observable through Langfuse/Observer without embedding observability logic in the domain. + +### 8. How to test + +1. Add a unit test for the core behavior. +2. Add a runtime integration test when state spans multiple turns. +3. Test the happy path and at least one failure/rejection path. +4. Confirm retries/replays do not duplicate side effects for transactional features. +5. In production, also validate telemetry and ID correlation. + +### 9. Common mistakes + +- Blind retries may repeat transactions. +- If external exceptions discard metadata, recovery becomes less precise. +- Always combine with Durable Idempotency for critical side effects. + +### 10. Relationship with other features + +Use this feature together with the framework's horizontal capabilities rather than creating a parallel implementation in domain-agent code. For transactional journeys, pay special attention to **Clarification**, **Pause/Resume**, **Durable Idempotency**, **Workflow Error Recovery**, and **Guardrails**. + +### 11. Repository references + +- `libs/agent_framework/src/agent_framework/workflows/runtime.py` +- `Tuning-Performance/` +- `Documentacao/` +- `libs/agent_framework/docs/` diff --git a/agent_framework_oci/docs/features/11_clarification.md b/agent_framework_oci/docs/features/11_clarification.md new file mode 100644 index 0000000..6ef6a15 --- /dev/null +++ b/agent_framework_oci/docs/features/11_clarification.md @@ -0,0 +1,169 @@ +# Clarificação / Clarification + +> Feature do `agent_framework_oci` — guia bilíngue PT-BR / EN. + +**Implementação principal / Main implementation:** `runtime/agent_runtime.py` + +--- + +## Português (PT-BR) + +### 1. O que é + +Quando faltam dados ou uma tool encontra múltiplas opções, o framework pergunta ao usuário em vez de adivinhar. + +### 2. Problema que resolve + +Em agentes de produção, não é suficiente pedir ao LLM que “faça a coisa certa”. Esta feature move uma responsabilidade específica para uma camada controlada do framework, reduzindo comportamento imprevisível e código duplicado nos agentes de domínio. + +### 3. Fluxo simplificado + +```text +pedido ambíguo + ↓ +NEEDS_CLARIFICATION + ↓ +pergunta + opções + ↓ +usuário responde + ↓ +framework resolve + ↓ +retoma mesma tool/workflow +``` + +### 4. Como funciona internamente + +O runtime suporta clarificação tanto de parâmetros faltantes quanto de resultados de tools. Para tool-result clarification, um resultado com `status: NEEDS_CLARIFICATION` pode trazer opções; o runtime persiste `pending_tool_clarification`, entra em `TOOL_RESULT_CLARIFICATION` e consegue resolver respostas por ordinal ou nome. + +Depois da escolha, o framework reutiliza a mesma tool e injeta os argumentos resolvidos, evitando que o roteador trate a resposta curta como uma intenção nova. + +### 5. Como ativar/configurar + +A ativação exata depende do template/agente. Verifique o arquivo de settings, YAMLs de configuração e o template usado pelo serviço. Nem toda feature precisa de uma flag global: algumas são ativadas pelo contrato retornado por uma tool/workflow. + +### 6. Exemplo + +```json +{ + "status": "NEEDS_CLARIFICATION", + "question": "Qual serviço?", + "options": [ + {"id": "tim_music", "label": "TIM Music"}, + {"id": "hbo_max", "label": "HBO Max"} + ] +} +``` + +Usuário: `o segundo` → `hbo_max`. + +### 7. Telemetria e observabilidade + +Quando a feature participa de uma execução de agente, preserve `request_id`, `trace_id`, `session_id`, `agent_id`, `message_id` e demais chaves de correlação no estado/eventos. Isso permite acompanhar a decisão no Langfuse/Observer sem colocar lógica de observabilidade dentro do domínio. + +### 8. Como testar + +1. Crie um teste unitário do comportamento principal. +2. Crie um teste de integração do runtime quando houver estado entre turns. +3. Verifique o caso feliz e pelo menos um caso de falha/negação. +4. Confirme que não há side effects duplicados em retry/replay quando a feature toca transações. +5. Em produção, valide também telemetria e correlação de IDs. + +### 9. Erros comuns + +- Não descarte `pending_tool_clarification` entre turns. +- Uma resposta curta deve ser resolvida contra as opções antes do roteamento normal. +- Opções sem identificador/label consistente pioram a resolução. + +### 10. Relação com outras features + +Esta feature deve ser usada junto das demais capacidades horizontais do framework, em vez de criar uma implementação paralela no agente de domínio. Em fluxos transacionais, considere especialmente **Clarification**, **Pause/Resume**, **Durable Idempotency**, **Workflow Error Recovery** e **Guardrails**. + +### 11. Referências no repositório + +- `libs/agent_framework/src/agent_framework/runtime/agent_runtime.py` +- `Tuning-Performance/` +- `Documentacao/` +- `libs/agent_framework/docs/` + +--- + +## English (EN) + +### 1. What it is + +When required information is missing or a tool finds multiple options, the framework asks the user instead of guessing. + +### 2. Problem it solves + +Production agents should not rely on prompts alone to “do the right thing”. This feature moves a specific responsibility into a controlled framework layer, reducing unpredictable behavior and duplicate domain-agent code. + +### 3. Simplified flow + +```text +ambiguous request + ↓ +NEEDS_CLARIFICATION + ↓ +question + options + ↓ +user answers + ↓ +framework resolves + ↓ +resume same tool/workflow +``` + +### 4. How it works internally + +The runtime supports clarification for both missing parameters and ambiguous tool results. For tool-result clarification, a result with `status: NEEDS_CLARIFICATION` may include options; the runtime persists `pending_tool_clarification`, moves to `TOOL_RESULT_CLARIFICATION`, and can resolve responses by ordinal or name. + +After selection, the framework reuses the same tool and injects resolved arguments, preventing the router from treating a short reply as a brand-new intent. + +### 5. How to enable/configure + +Exact activation depends on the template/agent. Check framework settings, YAML configuration, and the service template. Not every feature requires a global flag: some are activated by the contract returned from a tool/workflow. + +### 6. Example + +```json +{ + "status": "NEEDS_CLARIFICATION", + "question": "Which service?", + "options": [ + {"id": "tim_music", "label": "TIM Music"}, + {"id": "hbo_max", "label": "HBO Max"} + ] +} +``` + +User: `the second one` → `hbo_max`. + +### 7. Telemetry and observability + +When the feature participates in an agent execution, preserve `request_id`, `trace_id`, `session_id`, `agent_id`, `message_id`, and other correlation keys in state/events. This makes the decision observable through Langfuse/Observer without embedding observability logic in the domain. + +### 8. How to test + +1. Add a unit test for the core behavior. +2. Add a runtime integration test when state spans multiple turns. +3. Test the happy path and at least one failure/rejection path. +4. Confirm retries/replays do not duplicate side effects for transactional features. +5. In production, also validate telemetry and ID correlation. + +### 9. Common mistakes + +- Do not discard `pending_tool_clarification` between turns. +- A short answer should be resolved against pending options before normal routing. +- Options without stable identifiers/labels reduce resolution quality. + +### 10. Relationship with other features + +Use this feature together with the framework's horizontal capabilities rather than creating a parallel implementation in domain-agent code. For transactional journeys, pay special attention to **Clarification**, **Pause/Resume**, **Durable Idempotency**, **Workflow Error Recovery**, and **Guardrails**. + +### 11. Repository references + +- `libs/agent_framework/src/agent_framework/runtime/agent_runtime.py` +- `Tuning-Performance/` +- `Documentacao/` +- `libs/agent_framework/docs/` diff --git a/agent_framework_oci/docs/features/12_durable_idempotency.md b/agent_framework_oci/docs/features/12_durable_idempotency.md new file mode 100644 index 0000000..98969e3 --- /dev/null +++ b/agent_framework_oci/docs/features/12_durable_idempotency.md @@ -0,0 +1,163 @@ +# Idempotência Durável / Durable Idempotency + +> Feature do `agent_framework_oci` — guia bilíngue PT-BR / EN. + +**Implementação principal / Main implementation:** `idempotency.py` + +--- + +## Português (PT-BR) + +### 1. O que é + +Impede que a mesma operação crítica seja executada duas vezes, inclusive quando outra réplica/pod recebe a repetição. + +### 2. Problema que resolve + +Em agentes de produção, não é suficiente pedir ao LLM que “faça a coisa certa”. Esta feature move uma responsabilidade específica para uma camada controlada do framework, reduzindo comportamento imprevisível e código duplicado nos agentes de domínio. + +### 3. Fluxo simplificado + +```text +requisição + ↓ +idempotency key + ↓ +store durável + ├─ existe → retorna resultado anterior + └─ não existe → executa → persiste resultado +``` + +### 4. Como funciona internamente + +`create_idempotency_store(settings, ...)` escolhe o backend conforme configuração/plataforma. O framework possui `IdempotencyStore` e `InMemoryIdempotencyStore`, mas produção distribuída deve preferir storage compartilhado. As configurações incluem `IDEMPOTENCY_PROVIDER`, `IDEMPOTENCY_REQUIRE_DURABLE` e `IDEMPOTENCY_TTL_SECONDS`. + +Idempotência é diferente de retry: retry repete a tentativa; idempotência garante que a repetição não produza um novo side effect. + +### 5. Como ativar/configurar + +A ativação exata depende do template/agente. Verifique o arquivo de settings, YAMLs de configuração e o template usado pelo serviço. Nem toda feature precisa de uma flag global: algumas são ativadas pelo contrato retornado por uma tool/workflow. + +### 6. Exemplo + +```text +Pod A recebe cancelamento +→ key=cliente:servico:operacao +→ executa +→ grava resultado + +Pod A cai + +Pod B recebe retry +→ mesma key +→ encontra resultado +→ NÃO cancela de novo +``` + +### 7. Telemetria e observabilidade + +Quando a feature participa de uma execução de agente, preserve `request_id`, `trace_id`, `session_id`, `agent_id`, `message_id` e demais chaves de correlação no estado/eventos. Isso permite acompanhar a decisão no Langfuse/Observer sem colocar lógica de observabilidade dentro do domínio. + +### 8. Como testar + +1. Crie um teste unitário do comportamento principal. +2. Crie um teste de integração do runtime quando houver estado entre turns. +3. Verifique o caso feliz e pelo menos um caso de falha/negação. +4. Confirme que não há side effects duplicados em retry/replay quando a feature toca transações. +5. Em produção, valide também telemetria e correlação de IDs. + +### 9. Erros comuns + +- Usar store em memória com múltiplos pods não é idempotência durável. +- Chave ampla demais pode bloquear operações legítimas; estreita demais permite duplicidade. +- TTL deve ser compatível com a janela real de retry/replay. + +### 10. Relação com outras features + +Esta feature deve ser usada junto das demais capacidades horizontais do framework, em vez de criar uma implementação paralela no agente de domínio. Em fluxos transacionais, considere especialmente **Clarification**, **Pause/Resume**, **Durable Idempotency**, **Workflow Error Recovery** e **Guardrails**. + +### 11. Referências no repositório + +- `libs/agent_framework/src/agent_framework/idempotency.py` +- `Tuning-Performance/` +- `Documentacao/` +- `libs/agent_framework/docs/` + +--- + +## English (EN) + +### 1. What it is + +Prevents the same critical operation from executing twice, including when a retry lands on another replica/pod. + +### 2. Problem it solves + +Production agents should not rely on prompts alone to “do the right thing”. This feature moves a specific responsibility into a controlled framework layer, reducing unpredictable behavior and duplicate domain-agent code. + +### 3. Simplified flow + +```text +request + ↓ +idempotency key + ↓ +durable store + ├─ exists → return previous result + └─ missing → execute → persist result +``` + +### 4. How it works internally + +`create_idempotency_store(settings, ...)` chooses a backend according to configuration/platform. The framework provides `IdempotencyStore` and `InMemoryIdempotencyStore`, but distributed production should prefer shared storage. Settings include `IDEMPOTENCY_PROVIDER`, `IDEMPOTENCY_REQUIRE_DURABLE`, and `IDEMPOTENCY_TTL_SECONDS`. + +Idempotency is different from retry: retry repeats an attempt; idempotency guarantees that repetition does not create another side effect. + +### 5. How to enable/configure + +Exact activation depends on the template/agent. Check framework settings, YAML configuration, and the service template. Not every feature requires a global flag: some are activated by the contract returned from a tool/workflow. + +### 6. Example + +```text +Pod A receives cancellation +→ key=customer:service:operation +→ executes +→ stores result + +Pod A crashes + +Pod B receives retry +→ same key +→ finds stored result +→ DOES NOT cancel again +``` + +### 7. Telemetry and observability + +When the feature participates in an agent execution, preserve `request_id`, `trace_id`, `session_id`, `agent_id`, `message_id`, and other correlation keys in state/events. This makes the decision observable through Langfuse/Observer without embedding observability logic in the domain. + +### 8. How to test + +1. Add a unit test for the core behavior. +2. Add a runtime integration test when state spans multiple turns. +3. Test the happy path and at least one failure/rejection path. +4. Confirm retries/replays do not duplicate side effects for transactional features. +5. In production, also validate telemetry and ID correlation. + +### 9. Common mistakes + +- An in-memory store across multiple pods is not durable idempotency. +- A key that is too broad may block legitimate operations; too narrow may allow duplicates. +- TTL should match the real retry/replay window. + +### 10. Relationship with other features + +Use this feature together with the framework's horizontal capabilities rather than creating a parallel implementation in domain-agent code. For transactional journeys, pay special attention to **Clarification**, **Pause/Resume**, **Durable Idempotency**, **Workflow Error Recovery**, and **Guardrails**. + +### 11. Repository references + +- `libs/agent_framework/src/agent_framework/idempotency.py` +- `Tuning-Performance/` +- `Documentacao/` +- `libs/agent_framework/docs/` diff --git a/agent_framework_oci/docs/features/13_dynamic_transaction_states.md b/agent_framework_oci/docs/features/13_dynamic_transaction_states.md new file mode 100644 index 0000000..6cd06ce --- /dev/null +++ b/agent_framework_oci/docs/features/13_dynamic_transaction_states.md @@ -0,0 +1,157 @@ +# Estados Transacionais Dinâmicos / Dynamic Transaction States + +> Feature do `agent_framework_oci` — guia bilíngue PT-BR / EN. + +**Implementação principal / Main implementation:** `runtime/agent_runtime.py + mcp/tool_policy.py` + +--- + +## Português (PT-BR) + +### 1. O que é + +Permite criar estados de confirmação baseados no agente/domínio atual sem hardcode de todos os domínios dentro do framework. + +### 2. Problema que resolve + +Em agentes de produção, não é suficiente pedir ao LLM que “faça a coisa certa”. Esta feature move uma responsabilidade específica para uma camada controlada do framework, reduzindo comportamento imprevisível e código duplicado nos agentes de domínio. + +### 3. Fluxo simplificado + +```text +tool transactional + ↓ +agente/domínio atual + ↓ +WAITING__CONFIRMATION + ↓ +confirmação/rejeição + ↓ +estado seguinte +``` + +### 4. Como funciona internamente + +Em vez de manter estados fixos como `WAITING_BILLING_CONFIRMATION`, `WAITING_PRODUCT_CONFIRMATION` etc. para cada domínio conhecido, o runtime deriva o prefixo do agente atual e gera o estado dinamicamente. A função interna de estado transacional mantém o framework genérico. + +A classificação `operation_type` aceita `read_only`, `transactional`, `conversational` e `internal`; somente `transactional` entra no caminho de confirmação transacional. + +### 5. Como ativar/configurar + +A ativação exata depende do template/agente. Verifique o arquivo de settings, YAMLs de configuração e o template usado pelo serviço. Nem toda feature precisa de uma flag global: algumas são ativadas pelo contrato retornado por uma tool/workflow. + +### 6. Exemplo + +```text +VasAgent + cancelar_vas +→ WAITING_VAS_CONFIRMATION + +AddressAgent + alterar_endereco +→ WAITING_ADDRESS_CONFIRMATION +``` + +### 7. Telemetria e observabilidade + +Quando a feature participa de uma execução de agente, preserve `request_id`, `trace_id`, `session_id`, `agent_id`, `message_id` e demais chaves de correlação no estado/eventos. Isso permite acompanhar a decisão no Langfuse/Observer sem colocar lógica de observabilidade dentro do domínio. + +### 8. Como testar + +1. Crie um teste unitário do comportamento principal. +2. Crie um teste de integração do runtime quando houver estado entre turns. +3. Verifique o caso feliz e pelo menos um caso de falha/negação. +4. Confirme que não há side effects duplicados em retry/replay quando a feature toca transações. +5. Em produção, valide também telemetria e correlação de IDs. + +### 9. Erros comuns + +- Hardcode de estados no domínio reduz reutilização. +- Classificar uma tool como `conversational` não deve ativar confirmação transacional. +- Mudanças no identificador do agente podem mudar o prefixo; mantenha IDs estáveis. + +### 10. Relação com outras features + +Esta feature deve ser usada junto das demais capacidades horizontais do framework, em vez de criar uma implementação paralela no agente de domínio. Em fluxos transacionais, considere especialmente **Clarification**, **Pause/Resume**, **Durable Idempotency**, **Workflow Error Recovery** e **Guardrails**. + +### 11. Referências no repositório + +- `libs/agent_framework/src/agent_framework/runtime/agent_runtime.py` +- `libs/agent_framework/src/agent_framework/mcp/tool_policy.py` +- `Tuning-Performance/` +- `Documentacao/` +- `libs/agent_framework/docs/` + +--- + +## English (EN) + +### 1. What it is + +Allows confirmation states to be derived from the current agent/domain instead of hardcoding every business domain into the framework. + +### 2. Problem it solves + +Production agents should not rely on prompts alone to “do the right thing”. This feature moves a specific responsibility into a controlled framework layer, reducing unpredictable behavior and duplicate domain-agent code. + +### 3. Simplified flow + +```text +transactional tool + ↓ +current agent/domain + ↓ +WAITING__CONFIRMATION + ↓ +confirm/reject + ↓ +next state +``` + +### 4. How it works internally + +Instead of maintaining fixed states such as `WAITING_BILLING_CONFIRMATION`, `WAITING_PRODUCT_CONFIRMATION`, and so on for every known domain, the runtime derives a prefix from the current agent and builds the confirmation state dynamically. This keeps the framework generic. + +`operation_type` accepts `read_only`, `transactional`, `conversational`, and `internal`; only `transactional` enters the transactional confirmation path. + +### 5. How to enable/configure + +Exact activation depends on the template/agent. Check framework settings, YAML configuration, and the service template. Not every feature requires a global flag: some are activated by the contract returned from a tool/workflow. + +### 6. Example + +```text +VasAgent + cancel_vas +→ WAITING_VAS_CONFIRMATION + +AddressAgent + change_address +→ WAITING_ADDRESS_CONFIRMATION +``` + +### 7. Telemetry and observability + +When the feature participates in an agent execution, preserve `request_id`, `trace_id`, `session_id`, `agent_id`, `message_id`, and other correlation keys in state/events. This makes the decision observable through Langfuse/Observer without embedding observability logic in the domain. + +### 8. How to test + +1. Add a unit test for the core behavior. +2. Add a runtime integration test when state spans multiple turns. +3. Test the happy path and at least one failure/rejection path. +4. Confirm retries/replays do not duplicate side effects for transactional features. +5. In production, also validate telemetry and ID correlation. + +### 9. Common mistakes + +- Hardcoding states in domain code reduces reuse. +- Classifying a tool as `conversational` should not trigger transactional confirmation. +- Changing agent identifiers may change state prefixes; keep IDs stable. + +### 10. Relationship with other features + +Use this feature together with the framework's horizontal capabilities rather than creating a parallel implementation in domain-agent code. For transactional journeys, pay special attention to **Clarification**, **Pause/Resume**, **Durable Idempotency**, **Workflow Error Recovery**, and **Guardrails**. + +### 11. Repository references + +- `libs/agent_framework/src/agent_framework/runtime/agent_runtime.py` +- `libs/agent_framework/src/agent_framework/mcp/tool_policy.py` +- `Tuning-Performance/` +- `Documentacao/` +- `libs/agent_framework/docs/` diff --git a/agent_framework_oci/docs/features/14_post_finalization_replay.md b/agent_framework_oci/docs/features/14_post_finalization_replay.md new file mode 100644 index 0000000..8175336 --- /dev/null +++ b/agent_framework_oci/docs/features/14_post_finalization_replay.md @@ -0,0 +1,159 @@ +# Replay Após Finalização / Post Finalization Replay + +> Feature do `agent_framework_oci` — guia bilíngue PT-BR / EN. + +**Implementação principal / Main implementation:** `channels/interruption.py + config/settings.py` + +--- + +## Português (PT-BR) + +### 1. O que é + +Evita que áudio residual ou mensagens tardias reabram uma sessão já finalizada. + +### 2. Problema que resolve + +Em agentes de produção, não é suficiente pedir ao LLM que “faça a coisa certa”. Esta feature move uma responsabilidade específica para uma camada controlada do framework, reduzindo comportamento imprevisível e código duplicado nos agentes de domínio. + +### 3. Fluxo simplificado + +```text +sessão terminal + ↓ +entrada residual + ↓ +policy detecta finalização + ↓ +replay última fala/fallback + ↓ +NÃO reabre LangGraph +``` + +### 4. Como funciona internamente + +A política de interrupção verifica metadata de sessão terminal antes de tratar uma entrada como nova intenção. Quando há texto terminal disponível, usa `last_assistant_text`/`terminal_replay_text`; caso contrário, pode usar a mensagem configurada em `POST_FINALIZE_REPLAY_MESSAGE`. + +O objetivo é proteger o fechamento lógico da sessão, especialmente em canais de voz onde pacotes de áudio podem chegar depois do evento de finalização. + +### 5. Como ativar/configurar + +A ativação exata depende do template/agente. Verifique o arquivo de settings, YAMLs de configuração e o template usado pelo serviço. Nem toda feature precisa de uma flag global: algumas são ativadas pelo contrato retornado por uma tool/workflow. + +### 6. Exemplo + +```text +Agente: "Atendimento concluído." +→ sessão finalizada + +chega fragmento: "ã..." +→ replay "Atendimento concluído." +→ nenhum routing / tool / LLM novo +``` + +### 7. Telemetria e observabilidade + +Quando a feature participa de uma execução de agente, preserve `request_id`, `trace_id`, `session_id`, `agent_id`, `message_id` e demais chaves de correlação no estado/eventos. Isso permite acompanhar a decisão no Langfuse/Observer sem colocar lógica de observabilidade dentro do domínio. + +### 8. Como testar + +1. Crie um teste unitário do comportamento principal. +2. Crie um teste de integração do runtime quando houver estado entre turns. +3. Verifique o caso feliz e pelo menos um caso de falha/negação. +4. Confirme que não há side effects duplicados em retry/replay quando a feature toca transações. +5. Em produção, valide também telemetria e correlação de IDs. + +### 9. Erros comuns + +- Se o estado terminal não for persistido, outra réplica pode reabrir a jornada. +- Não use replay técnico/JSON como fala do cliente. +- Essa feature não substitui política de nova sessão intencional. + +### 10. Relação com outras features + +Esta feature deve ser usada junto das demais capacidades horizontais do framework, em vez de criar uma implementação paralela no agente de domínio. Em fluxos transacionais, considere especialmente **Clarification**, **Pause/Resume**, **Durable Idempotency**, **Workflow Error Recovery** e **Guardrails**. + +### 11. Referências no repositório + +- `libs/agent_framework/src/agent_framework/channels/interruption.py` +- `libs/agent_framework/src/agent_framework/config/settings.py` +- `Tuning-Performance/` +- `Documentacao/` +- `libs/agent_framework/docs/` + +--- + +## English (EN) + +### 1. What it is + +Prevents residual audio or late messages from reopening a session that has already been finalized. + +### 2. Problem it solves + +Production agents should not rely on prompts alone to “do the right thing”. This feature moves a specific responsibility into a controlled framework layer, reducing unpredictable behavior and duplicate domain-agent code. + +### 3. Simplified flow + +```text +terminal session + ↓ +residual input + ↓ +policy detects finalization + ↓ +replay last utterance/fallback + ↓ +DO NOT reopen LangGraph +``` + +### 4. How it works internally + +The interruption policy checks terminal-session metadata before treating an input as a new intent. When terminal speech is available, it uses `last_assistant_text`/`terminal_replay_text`; otherwise it may use `POST_FINALIZE_REPLAY_MESSAGE`. + +The purpose is to protect the logical end of a session, especially on voice channels where audio packets may arrive after the finalization event. + +### 5. How to enable/configure + +Exact activation depends on the template/agent. Check framework settings, YAML configuration, and the service template. Not every feature requires a global flag: some are activated by the contract returned from a tool/workflow. + +### 6. Example + +```text +Agent: "The interaction is complete." +→ session finalized + +late fragment arrives: "uh..." +→ replay "The interaction is complete." +→ no new routing / tool / LLM call +``` + +### 7. Telemetry and observability + +When the feature participates in an agent execution, preserve `request_id`, `trace_id`, `session_id`, `agent_id`, `message_id`, and other correlation keys in state/events. This makes the decision observable through Langfuse/Observer without embedding observability logic in the domain. + +### 8. How to test + +1. Add a unit test for the core behavior. +2. Add a runtime integration test when state spans multiple turns. +3. Test the happy path and at least one failure/rejection path. +4. Confirm retries/replays do not duplicate side effects for transactional features. +5. In production, also validate telemetry and ID correlation. + +### 9. Common mistakes + +- If terminal state is not persisted, another replica may reopen the journey. +- Do not replay technical/JSON envelopes as user-facing speech. +- This feature does not replace an intentional new-session policy. + +### 10. Relationship with other features + +Use this feature together with the framework's horizontal capabilities rather than creating a parallel implementation in domain-agent code. For transactional journeys, pay special attention to **Clarification**, **Pause/Resume**, **Durable Idempotency**, **Workflow Error Recovery**, and **Guardrails**. + +### 11. Repository references + +- `libs/agent_framework/src/agent_framework/channels/interruption.py` +- `libs/agent_framework/src/agent_framework/config/settings.py` +- `Tuning-Performance/` +- `Documentacao/` +- `libs/agent_framework/docs/` diff --git a/agent_framework_oci/docs/features/15_retrieval_tool_guardrails.md b/agent_framework_oci/docs/features/15_retrieval_tool_guardrails.md new file mode 100644 index 0000000..0a565a0 --- /dev/null +++ b/agent_framework_oci/docs/features/15_retrieval_tool_guardrails.md @@ -0,0 +1,171 @@ +# Guardrails de Retrieval e Tools / Retrieval / Tool Guardrails + +> Feature do `agent_framework_oci` — guia bilíngue PT-BR / EN. + +**Implementação principal / Main implementation:** `guardrails/pipeline.py + guardrails/rails.py` + +--- + +## Português (PT-BR) + +### 1. O que é + +Aplica proteção não apenas na mensagem do usuário e na resposta final, mas também no conhecimento recuperado por RAG e nos argumentos/resultados de ferramentas. + +### 2. Problema que resolve + +Em agentes de produção, não é suficiente pedir ao LLM que “faça a coisa certa”. Esta feature move uma responsabilidade específica para uma camada controlada do framework, reduzindo comportamento imprevisível e código duplicado nos agentes de domínio. + +### 3. Fluxo simplificado + +```text +Usuário + ↓ +Input Guardrails + ↓ +RAG → Retrieval Guardrails + ↓ +LLM/Tool call → Tool Guardrails + ↓ +API + ↓ +Output Guardrails +``` + +### 4. Como funciona internamente + +O framework possui stages distintos de guardrails. Para retrieval, rails como `RAGSEC` e `RET_REL` podem validar segurança e relevância do conteúdo recuperado. Para tools, `TOOL_VAL` valida o uso/argumentos antes ou ao redor da execução. + +As configurações globais incluem `ENABLE_INPUT_GUARDRAILS`, `ENABLE_OUTPUT_GUARDRAILS`, `ENABLE_PARALLEL_GUARDRAILS`, `GUARDRAILS_FAIL_FAST` e `GUARDRAILS_CONFIG_PATH`. O YAML é a fonte de verdade dos rails ativados por agente. + +### 5. Como ativar/configurar + +A ativação exata depende do template/agente. Verifique o arquivo de settings, YAMLs de configuração e o template usado pelo serviço. Nem toda feature precisa de uma flag global: algumas são ativadas pelo contrato retornado por uma tool/workflow. + +### 6. Exemplo + +```yaml +retrieval: + rails: + - RAGSEC + - RET_REL + +tool: + rails: + - TOOL_VAL +``` + +Exemplo: a pergunta é sobre cancelamento de um serviço, mas o RAG retorna documentação de modem. `RET_REL` pode rejeitar o contexto antes que ele seja usado na resposta. + +### 7. Telemetria e observabilidade + +Quando a feature participa de uma execução de agente, preserve `request_id`, `trace_id`, `session_id`, `agent_id`, `message_id` e demais chaves de correlação no estado/eventos. Isso permite acompanhar a decisão no Langfuse/Observer sem colocar lógica de observabilidade dentro do domínio. + +### 8. Como testar + +1. Crie um teste unitário do comportamento principal. +2. Crie um teste de integração do runtime quando houver estado entre turns. +3. Verifique o caso feliz e pelo menos um caso de falha/negação. +4. Confirme que não há side effects duplicados em retry/replay quando a feature toca transações. +5. Em produção, valide também telemetria e correlação de IDs. + +### 9. Erros comuns + +- Ter a implementação do rail não significa que ele está ativo: confira `guardrails.yaml`. +- Fail-fast deve ser escolhido conscientemente para cada stage. +- Tool guardrail não substitui validação de negócio dentro da própria API/action. + +### 10. Relação com outras features + +Esta feature deve ser usada junto das demais capacidades horizontais do framework, em vez de criar uma implementação paralela no agente de domínio. Em fluxos transacionais, considere especialmente **Clarification**, **Pause/Resume**, **Durable Idempotency**, **Workflow Error Recovery** e **Guardrails**. + +### 11. Referências no repositório + +- `libs/agent_framework/src/agent_framework/guardrails/pipeline.py` +- `libs/agent_framework/src/agent_framework/guardrails/rails.py` +- `Tuning-Performance/` +- `Documentacao/` +- `libs/agent_framework/docs/` + +--- + +## English (EN) + +### 1. What it is + +Applies safety and validation not only to user input and final output, but also to RAG-retrieved knowledge and tool arguments/results. + +### 2. Problem it solves + +Production agents should not rely on prompts alone to “do the right thing”. This feature moves a specific responsibility into a controlled framework layer, reducing unpredictable behavior and duplicate domain-agent code. + +### 3. Simplified flow + +```text +User + ↓ +Input Guardrails + ↓ +RAG → Retrieval Guardrails + ↓ +LLM/Tool call → Tool Guardrails + ↓ +API + ↓ +Output Guardrails +``` + +### 4. How it works internally + +The framework has distinct guardrail stages. For retrieval, rails such as `RAGSEC` and `RET_REL` can validate retrieved-content safety and relevance. For tools, `TOOL_VAL` validates usage/arguments before or around execution. + +Global settings include `ENABLE_INPUT_GUARDRAILS`, `ENABLE_OUTPUT_GUARDRAILS`, `ENABLE_PARALLEL_GUARDRAILS`, `GUARDRAILS_FAIL_FAST`, and `GUARDRAILS_CONFIG_PATH`. The agent YAML is the source of truth for enabled rails. + +### 5. How to enable/configure + +Exact activation depends on the template/agent. Check framework settings, YAML configuration, and the service template. Not every feature requires a global flag: some are activated by the contract returned from a tool/workflow. + +### 6. Example + +```yaml +retrieval: + rails: + - RAGSEC + - RET_REL + +tool: + rails: + - TOOL_VAL +``` + +Example: the question concerns canceling a service, but RAG retrieves modem documentation. `RET_REL` can reject that context before it is used in the answer. + +### 7. Telemetry and observability + +When the feature participates in an agent execution, preserve `request_id`, `trace_id`, `session_id`, `agent_id`, `message_id`, and other correlation keys in state/events. This makes the decision observable through Langfuse/Observer without embedding observability logic in the domain. + +### 8. How to test + +1. Add a unit test for the core behavior. +2. Add a runtime integration test when state spans multiple turns. +3. Test the happy path and at least one failure/rejection path. +4. Confirm retries/replays do not duplicate side effects for transactional features. +5. In production, also validate telemetry and ID correlation. + +### 9. Common mistakes + +- Having a rail implementation does not mean it is enabled: check `guardrails.yaml`. +- Fail-fast behavior should be chosen intentionally for each stage. +- Tool guardrails do not replace business validation inside the API/action itself. + +### 10. Relationship with other features + +Use this feature together with the framework's horizontal capabilities rather than creating a parallel implementation in domain-agent code. For transactional journeys, pay special attention to **Clarification**, **Pause/Resume**, **Durable Idempotency**, **Workflow Error Recovery**, and **Guardrails**. + +### 11. Repository references + +- `libs/agent_framework/src/agent_framework/guardrails/pipeline.py` +- `libs/agent_framework/src/agent_framework/guardrails/rails.py` +- `Tuning-Performance/` +- `Documentacao/` +- `libs/agent_framework/docs/` diff --git a/agent_framework_oci/docs/features/README.md b/agent_framework_oci/docs/features/README.md index d09ad96..f925f85 100644 --- a/agent_framework_oci/docs/features/README.md +++ b/agent_framework_oci/docs/features/README.md @@ -1,10 +1,62 @@ -# Feature Guides / Guias de Features +# Feature Guide — agent_framework_oci -Escolha o idioma / Choose a language: +Guia consolidado e bilíngue das principais capabilities horizontais do framework. Cada página contém **Português (PT-BR)** e **English (EN)** no mesmo arquivo. -- [Português (PT-BR)](pt-BR/README.md) -- [English (EN)](en/README.md) +Consolidated bilingual guide for the framework's main horizontal capabilities. Each page contains **Portuguese (PT-BR)** and **English (EN)** in the same file. -Os 15 arquivos bilíngues originais continuam neste diretório para compatibilidade, mas as árvores `pt-BR/` e `en/` são as versões recomendadas para leitura e distribuição. +| # | Feature | +|---:|---| +| 01 | [Autenticação / Authentication](01_authentication.md) | +| 02 | [Workflow Transacional Determinístico / Deterministic Transactional Workflow](02_deterministic_transactional_workflow.md) | +| 03 | [Composição por LLM Solicitada pelo Domínio / Domain Requested LLM Composition](03_domain_requested_llm_composition.md) | +| 04 | [RAG Solicitado pelo Domínio / Domain Requested RAG](04_domain_requested_rag.md) | +| 05 | [Memória de Longo Prazo / Long Term Memory](05_long_term_memory.md) | +| 06 | [Regressão Offline de Workflow / Offline Workflow Regression](06_offline_workflow_regression.md) | +| 07 | [Pause / Resume de Workflow / Pause / Resume Workflow](07_pause_resume_workflow.md) | +| 08 | [Aderência de Rota / Route Stickiness](08_route_stickiness.md) | +| 09 | [Replay em Interrupções de Voz / Voice Interruption Replay](09_voice_interruption_replay.md) | +| 10 | [Recuperação de Erro em Workflow / Workflow Error Recovery](10_workflow_error_recovery.md) | +| 11 | [Clarificação / Clarification](11_clarification.md) | +| 12 | [Idempotência Durável / Durable Idempotency](12_durable_idempotency.md) | +| 13 | [Estados Transacionais Dinâmicos / Dynamic Transaction States](13_dynamic_transaction_states.md) | +| 14 | [Replay Após Finalização / Post Finalization Replay](14_post_finalization_replay.md) | +| 15 | [Guardrails de Retrieval e Tools / Retrieval / Tool Guardrails](15_retrieval_tool_guardrails.md) | -The original 15 bilingual files remain in this directory for backward compatibility, but the `pt-BR/` and `en/` trees are the recommended versions for reading and distribution. +## Mapa conceitual / Conceptual map + +```text +LLM +│ +├── Conversation +│ ├── Clarification +│ ├── Route Stickiness +│ └── Long Term Memory +│ +├── Knowledge +│ ├── Domain Requested RAG +│ └── Retrieval Guardrails +│ +├── Transactions +│ ├── Deterministic Transactional Workflow +│ ├── Pause / Resume +│ ├── Dynamic Transaction States +│ ├── Durable Idempotency +│ └── Workflow Error Recovery +│ +├── Response +│ └── Domain Requested LLM Composition +│ +├── Voice +│ ├── Voice Interruption Replay +│ └── Post Finalization Replay +│ +└── Platform + ├── Authentication + └── Offline Workflow Regression +``` + +## Princípio de arquitetura / Architecture principle + +**PT-BR:** o LLM entende e redige; o framework controla estado, segurança, memória, roteamento e transações; o domínio contém regras específicas de negócio. + +**EN:** the LLM understands and writes; the framework controls state, security, memory, routing, and transactions; the domain contains business-specific rules. diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/__pycache__/__init__.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/__pycache__/__init__.cpython-313.pyc index 91d91f9cce7f766a91d94c6caa8894c4ef6d824b..12a77f9b9177c1a78f47349bf55e78751f603d7e 100644 GIT binary patch delta 64 zcmZ3%yqcNoGcPX}0}%ZCHj(RtW}SX+UWtB+zHhK+d_YltR%&udv3^=+QE^Fpa(-S( SVsU(KW_nR#O8#U8#ts0?>K88n delta 61 zcmZ3@yn>nQGcPX}0}$jqnaK4)ty(`fuS7pZ-=!$OASu5>-#^IF*~eAiw=z7xC|f_E PC_gJTxukfqGGhk-Rk9RH diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/__pycache__/gateway_policy_context.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/__pycache__/gateway_policy_context.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..83fa4b8bd48b2a6fdc7e976962ebe66811ddbb10 GIT binary patch literal 1433 zcmaJ>&u`pB6n^9J+9q3Po2c71t0c8b`ol}pEzm-#00D;xrD6}Y_LLyY*>zS<9D6l( z2#z=`ClW4g4-w&jw8tWG;7{pl4{KRaAwdtlt(1yGPrPyL5ZchU+BfswoAPQJhN#t-zYd#91)pS;&8e zVidT4jj%#n)Zci9D4>(1XnCF=TA|~60h;tvFKQAV%S6NxOOu1|ak2*uxOY67Ei%Zh z%=;0!n)zA+fCe|fBMow5j*#bg!culPfQGQdE2eS_5xC@t7TOJA4v#wrI;|(lh84={O{M+G%kaw|F#4eIod76XcEZpO$FUjjzKB`0; z!il*@Z0Gy16wan0@Ino02v_)caxTr$U&^IfE`3d|_&>Q~mMf;Y6mL|ao{V)YPCVX_ zAStBuB}#|+UpXzCB{I%d9oN=rN+#n^mEj>k7a8^xlGCe}>#kVMbu(MZPI0%Cf(8M< z*Lcq~rgHC9tJ86#6Yq){`ljn{nCn{>YX|HcF6ThOLsVUOuE6-^o;^^nbr+r#C*snD zVd+xuoyW?hzto8bmw%`}tnM!lCac5A8;@27>f7CgSXRH={&xGpm7!ee%aypI_0IiR z+mUv*c1wAzI+SPn@=QGQW^b`S!-Ly>rIJVWp*-D}r{n31y$|}+^B9f#%2ZsO=zhUU zxT~xKFUI*ZTM9yUO~dcVmx;veaFcm2%K!Ci-)ME;vvpF}rL=YIJc6(?R~4?NxZ*xt zO2$lcbrVr+(`5XqCQ=x69IwrIKM$GU9r_v4og6k-`4Gw5bnTDXEQa`l2yUVpQ9{V? qaPcXeeJ)XQdvqFV?~V#3G8q@AMij?C&c2n}BMGE4f6M4eQU3wu%Pq|S literal 0 HcmV?d00001 diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/__pycache__/idempotency.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/__pycache__/idempotency.cpython-313.pyc index 61332e2a66a19ff443bd48d177caed55972bd668..dafbb1f2ef69f884445f930c11269075ec52c715 100644 GIT binary patch delta 66 zcmX@3b6$t*GcPX}0}%ZCwvp>JlV+oSZeEFgioS2KXM8|WepYI7NwI!fW>IlTd~$wX UNn&w)Zf1H>VoLtz-%NqR02I?0p#T5? delta 63 zcmX@Fb4G{jGcPX}0}$jq*~oR8Nv%#lH?KrLMc<_;zaS~ULf=2g(b>mU-?uV6zbIQj RpeR2pHMyjC^FO9QVE~vl6}$id diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/__pycache__/observer.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/__pycache__/observer.cpython-313.pyc index e98a68af7562da2600b17311c18b84283efd9fee..7d09d8707cbdc33a7e9b6a796c4b7dd450346e7d 100644 GIT binary patch delta 68 zcmZ3`$+)z{v zNkBbR?V-8m5Rn|Jq^FWY)f{uIlz#x^O14I=gjD6g%?St8p896(4J2T-WBYmDym@ba z?`vkSt1F0L{5WAP{~{pt7h}8uJR98JWuOm{id1eE-QWn9WOLuF?*>nJch1iWH$);P zQ5=mRRTx03IO$`$2oZnDuSmOWs&F)2Ks4gPxPGGAWT9eh_`%ajdl zI(fF;8+>cR?Olb*Lv#xfPDRA0a)dt(Fo>Y?w?tJK1L+V_r6HgPA5~Vx0kkYEbHuOu ziB$3_0UA9xZ@y|e#wwmO?iuE;3?_2xu>)xfP4b&$&N4CWTg_LrQVXY+Zvkz`$c5Mi z^m`VsFTnRxC<$N}(7Y>pmyEaBLI|OoZTApFcam!fFn7G(y!fsi#w~F3($Q7br}AC~ zI_wa<)26w%cm@!l?yz4xWwjwmJdF-Gg8v~8 zdGezt9vj=Rw_oi_@oM))DGU8@8}fLEd&uX+Ffs)|5;!I+Jrl^w$~@%${ju;iCy)hU z6v-$zcAhVCN^frcBvfUx-6Y9Y@g<>^l6lK48l@`11sZU$shf^w6sT0dMZH>fsH~Tu zpV*Q}tg3^lR5e#j>#j+q{B3APT&BHCRogJJZEIl5!S@^*w1I;bWoo^!cn1^P?OAOF zuTgmwJ96dD)UQ`6*eoa_6>MBC zQqhKM29qc|AjXXO+s0WBCE1|Y%f^yD(F#zJ0J6IlS(&g&{>U0>-4fd23jjh;fdf*N zH5%92&<@L8m=gzg$>EzO)k%Q`&3*%97k!JGVbt4S@A(+MfAkG)4PUMGWwyeZo!E(b zEVUg=)nilJv8hJ%#D?*}cpBPVtVPc^A_E(X4;CM-*CLKRV`yl(ssP&IGqQmgru%4zHiIFFZj~BPbF4huL^~B7JrJbQuPmIULX1F#q*%(!R z&i<6$O3l0b08vg9ivR!s diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/analytics/__pycache__/composite_publisher.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/analytics/__pycache__/composite_publisher.cpython-313.pyc index 20d5e8d2e4083a86b8f4233d98bab3cbdcfadfd1..a4bf51cfcf337efdd03bae7573ef8300bce21f40 100644 GIT binary patch delta 66 zcmcaCd`+0^GcPX}0}%ZCwvlTEljdao+`JO~6n)=d&-j3%{H)aEl4AX|%%b9w_~iV& VlEmWp+|2Z%#FYHaH<*620RRal80G)~ delta 63 zcmca6d|8<5GcPX}0}$js*~qnmNo|6DZeEFgioQ!xenC=xg}#4~qqC2zzHeoCeo?l5 RKv8~HYH~^O=G#oa*#M1L76JeO diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/analytics/__pycache__/event_builder.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/analytics/__pycache__/event_builder.cpython-313.pyc index c168703bb5f16f3b14ac6a8fe25e9998bf17a818..855087154c89378f3c7ca6b5a7d6fde039ddeee0 100644 GIT binary patch delta 66 zcmey#`G=G1GcPX}0}%ZCwvp>4lV-1eZeEFgioS2KXM8|WepYI7NwI!fW>IlTd~$wX UNn&w)Zf1H>VoLsIN#+NP03VtddjJ3c delta 63 zcmeyv`ID3DGcPX}0}$js*~s;hNv%siH?KrLMc<_;zaS~ULf=2g(b>mU-?uV6zbIQj RpeR2pHMyjCvkdbCMgXF86_)@2 diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/analytics/__pycache__/factory.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/analytics/__pycache__/factory.cpython-313.pyc index 208b638147fb1c52c62bcd68b6c76aac6922b9f6..7aa94cb6f05036ffc9f7d24f35f8a2fc730387d2 100644 GIT binary patch delta 66 zcmZ1}zeb+xGcPX}0}%ZCwvo$~NwZx)H?KrLMc+5rGd`dwKPxr4q*y;Kv#7WvJ~=FlV+!WZeEFgioS2KXM8|WepYI7NwI!fW>IlTd~$wX UNn&w)Zf1H>VoLtz&rDe?01jXni2wiq delta 63 zcmaFBcbAXrGcPX}0}$js*~oR6Nv%ykH?KrLMc<_;zaS~ULf=2g(b>mU-?uV6zbIQj RpeR2pHMyjC^Eaj}766h$6{P?G diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/analytics/__pycache__/tim_payload_mapper.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/analytics/__pycache__/tim_payload_mapper.cpython-313.pyc index f5d7804827d550e5f2a2ca4000643a14c9b0e930..02c8aaed6e7264a116ff223eb8127e7211707c12 100644 GIT binary patch delta 66 zcmccYam|D4GcPX}0}%ZCwvnrxQFD@hZeEFgioS2KXM8|WepYI7NwI!fW>IlTd~$wX UNn&w)Zf1H>VoLtz<&0~T02rMZxBvhE delta 63 zcmccSaoL0GGcPX}0}$js*~nGSsMfEan^&TrqVH0aUyzhvq3<8$=>!|1qT2C delta 19 ZcmbQlGKq!jGcPX}0}$js*~rDg1OP6q1Y`gJ diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/analytics/providers/__pycache__/kafka.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/analytics/providers/__pycache__/kafka.cpython-313.pyc index a235c8b6e50a5811ebaedd44a233e480f814fad9..a0b1b2e0954bc8a1106b91dfa3068fe7c644b210 100644 GIT binary patch delta 19 ZcmZ3&w}g-DGcPX}0}%ZCwvkJU9RN0Q1y%q6 delta 19 ZcmZ3&w}g-DGcPX}0}$js*~lfu4gfN-1hW7D diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/analytics/providers/__pycache__/langfuse.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/analytics/providers/__pycache__/langfuse.cpython-313.pyc index d76f4f50cfbffeb3156ce28c802a6608b47c6616..4126c1128bdec4987889f2b921737ec7b3cdc22b 100644 GIT binary patch delta 21 bcmeyrj`9CGMy}7iyj%=G@bBA3uF`M-UatrF delta 21 bcmeyrj`9CGMy}7iyj%=Gko#mKS7|r^TJHx| diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/analytics/providers/__pycache__/oci_streaming.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/analytics/providers/__pycache__/oci_streaming.cpython-313.pyc index 29fb75c35bc68ebab49123ea33ee5611de811099..845679941d7318147b0afe7f1072a38098b365d5 100644 GIT binary patch delta 19 ZcmZ3>x0a9VGcPX}0}%ZCwvkJj9RN4S1#tiX delta 19 ZcmZ3>x0a9VGcPX}0}$js*~q2L4gfR<1kL~e diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/analytics/providers/__pycache__/pubsub.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/analytics/providers/__pycache__/pubsub.cpython-313.pyc index 397f7c981506dbbb1fd3ea9d893180de7451a2e0..b7d99e41bf2eca7ed441ae2bbef326d2bbd6e646 100644 GIT binary patch delta 19 ZcmZ2rwZMw&GcPX}0}%ZCwvkIr763cP1-JkJ delta 19 ZcmZ2rwZMw&GcPX}0}$js*~ld(3jjC=1r-1Q diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/billing/__pycache__/__init__.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/billing/__pycache__/__init__.cpython-313.pyc index 91cee2eca0f64db59a6e5bc82a00b59bdb435226..f4a8983e928abc9bfa99e8918c760487eaf3018f 100644 GIT binary patch delta 64 zcmZ3$yqKBmGcPX}0}%ZCHj(RzW}AL)UWtB+zHhK+d_YltR%&udv3^=+QE^Fpa(-S( SVsU(KW_nR#O8#UK#vTC34i^&u delta 61 zcmZ3?ynvbOGcPX}0}$jsnaK4-tyw=euS7pZ-=!$OASu5>-#^IF*~eAiw=z7xC|f_E PC_gJTxukfqIAae0Q9=|i diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/billing/__pycache__/usage_repository.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/billing/__pycache__/usage_repository.cpython-313.pyc index 865873c205c9a517c16136ce169a00e9238ef9d6..67c4c0c652ce177c8b73fff5f4f0ac0ae078173e 100644 GIT binary patch delta 66 zcmcayb*+l)GcPX}0}%ZCwvj8JU9(R=H?KrLMc+5rGd`dwKPxr4q*y;Kv#7WvJ~=__BGcPX}0}%ZCHj&Fjvqe8QuS7pZ-#6GZKAb>KSU)YZsJJ9PIX|x? Ru{b_AGrcG=C4XW{9RRT&7a#xt delta 60 zcmaFL_=u6~GcPX}0}$jqnaE|L)~KJGSE8Sy?^2Xskd$Ac?;qso?BlBMTN$2Tl&v37 Ol%JKFTv9wSy$%39ofJC& diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/cache/__pycache__/cache.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/cache/__pycache__/cache.cpython-313.pyc index c70523c2a70485807c3b99cd20d01780f185b540..1778a22acb8463ea0c8006e2e4eafa5564d23da3 100644 GIT binary patch delta 68 zcmbQy$T+)^k?S)rFBbz4{QI_%ON2?YQ9n1YL_bB}H`p^ipeR2pHMyi%KP|JUxFkL~ WKd&UQI6gNsy(lpyf3piyh#dd}3KyjS delta 65 zcmbQ;$T*{sk?S)rFBbz4b>KSU)YZsJJ9PIX|x? Ru{b_AGrcG=C4XW{BLK4*7c2k( delta 60 zcmaFC_>__BGcPX}0}$jsnaE|L)}o)ASE8Sy?^2Xskd$Ac?;qso?BlBMTN$2Tl&v37 Ol%JKFTv9wSy%7LEtQ1H9 diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/channels/__pycache__/adapters.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/channels/__pycache__/adapters.cpython-313.pyc index e045b4c559387634ded4ba015222a89f498925c6..df8eb6f901dee950808700d852a36ce3bb4ccbaa 100644 GIT binary patch delta 66 zcmcbqa7TgbGcPX}0}%ZCwvp=`lV-bqZeEFgioS2KXM8|WepYI7NwI!fW>IlTd~$wX UNn&w)Zf1H>VoLtze@xN502eM8vj6}9 delta 63 zcmcbka8rTnGcPX}0}$js*~oQ{Nv%acH?KrLMc<_;zaS~ULf=2g(b>mU-?uV6zbIQj RpeR2pHMyjCGb3{}F94RL6wm+w diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/channels/__pycache__/base.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/channels/__pycache__/base.cpython-313.pyc index 073a05fd1c218ebece2d122f7c5f54552671f1f7..337545bc9bad56af04b3b296c7c3d2ef77da118b 100644 GIT binary patch delta 66 zcmbQpH-(SuGcPX}0}%ZCwvo%4NwZl$H?KrLMc+5rGd`dwKPxr4q*y;Kv#7WvJ~=3jk7B6f*z- diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/channels/__pycache__/gateway.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/channels/__pycache__/gateway.cpython-313.pyc index 58373c17e17d6f1be5a1bde79008ccc9ff504321..3871ce3533a72d6f597c784b09de06fc3c3a2e61 100644 GIT binary patch delta 66 zcmbQCJ6o6QGcPX}0}%ZCwvlTAyJnkyZeEFgioS2KXM8|WepYI7NwI!fW>IlTd~$wX UNn&w)Zf1H>VoLtz3+yNO0QAEcW&i*H delta 63 zcmbQOJ42W2GcPX}0}$js*~qnkU9DL^H?KrLMc<_;zaS~ULf=2g(b>mU-?uV6zbIQj RpeR2pHMyjC^JVrEd;od-6@mZ& diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/channels/__pycache__/interruption.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/channels/__pycache__/interruption.cpython-313.pyc index 266a8cf0f3d405ca3d2435136cfce59a4dc5765d..3e20c90c65eaa7813186958fc3cd52acec98a8dd 100644 GIT binary patch delta 66 zcmX?Vbi#=1GcPX}0}%ZCwvlT(lV-PmZeEFgioS2KXM8|WepYI7NwI!fW>IlTd~$wX UNn&w)Zf1H>VoLtz<4kp801K)ZaR2}S delta 63 zcmX?MbkvCJGcPX}0}$js*~m4WNv%UaH?KrLMc<_;zaS~ULf=2g(b>mU-?uV6zbIQj RpeR2pHMyjC^C_k}F#wOk6^#G@ diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/channels/__pycache__/transcription.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/channels/__pycache__/transcription.cpython-313.pyc index 5396652ee2d3e2c9e65e88f7b4a8e53cd7246b00..ebad7aea0b867a8a77f695e372861465e7d5f8de 100644 GIT binary patch delta 66 zcmZ3)y_B2lGcPX}0}%ZCwvkJZS+hq!H?KrLMc+5rGd`dwKPxr4q*y;Kv#7WvJ~=@4#6Wjm* diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/checkpoints/__pycache__/__init__.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/checkpoints/__pycache__/__init__.cpython-313.pyc index 209342c7a1db8b894a6437dee423c7e8a42d28c0..c0e39fddda8471bb59580f24c1b4a390d1545b92 100644 GIT binary patch delta 65 zcmZ3%zM7ruGcPX}0}%ZCwvp>HlV+EGZeEFgioS2KXM8|WepYI7NwI!fW>IlTd~$wX TNn&w)Zf1H>VoLsGX6B^;*YFog delta 62 zcmZ3@zJi_WGcPX}0}$jq*~oR7Nv&N!H?KrLMc<_;zaS~ULf=2g(b>mU-?uV6zbIQj QpeR2pHMyjCG8^+!0AI-zWdHyG diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/checkpoints/__pycache__/checkpoint_repository.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/checkpoints/__pycache__/checkpoint_repository.cpython-313.pyc index 52e8bdbbae206251b4656329cc536a55f8e965f0..9111f5b4d3b526c5e5334b5a2c74fa854710a16d 100644 GIT binary patch delta 68 zcmZ2+g>m&2My}7iyj%=G@bBA3E){0Y>H4{OCHg7)zQLaH0Y&*)smUe9`e~U(#U=5{ X`FSOY#qqhB=|zbt`I|$SucQG0K5`jL delta 65 zcmZ2|g>l6dMy}7iyj%=Gkn?0CmkP7m6#d-168#i?m!kZFr2Gnf{~$+aA6I?f%JBT6 TZ2f?u{H)aElH$$b%vaI?z-bm{ diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/checkpoints/__pycache__/langgraph_saver.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/checkpoints/__pycache__/langgraph_saver.cpython-313.pyc index 42367beb7f873861f536d9ea1bc1d3154e6221a7..3612f13c404d4871e1f5c1a85675c912cd390db2 100644 GIT binary patch delta 2554 zcmZ`*eP~p zWand{b~e_9rX#4gO;QG1I!f0-p=$-BgE5+PgAB%ImO|Y3N7;X)>>sZ&rHpOtoGT?w zO8emb-nr+Vb9C?ToO`a`$$Wm;d)MP}5_nE$UO3LX%HA-&Rqp-%RDHq`A;%TwP52W| zA^8#w373%S6M=+VNd7SCBneN1B)muDQ5oY9!Wt632w{QpUwT}JmdUu>PL`?GSpMG) zdXaxXL*cAZFjy|FGs7&d6ih>3dt5)Y!cJ5^p^Fk}^rIzvrA9i+( zS#s7Wu`tBfB+FKvW^FJuC4g9rdEsL@_0lnBq%wLg!@5AxUHP%|GPPMsCYLVpm^-cx zfL5z4yU!^ty&$qabhD+3MWc{m9XL?(IkUw7TR&nOM1vu|*B@8+gE&+<>-SRn9-p8= z8}On;2!Ffbsx2#P5v!TUL(S5sbNoc$XaJdjm)?CAgjdOYeV*|D1fqLu3=xu~qZFp# zNs>HnKs*T?-M7h->vUFA`1!`Je%Vq?BfrezV8O1(s{O!Kk3(8Brt+D+Vl%G182aGBU!3w1l+!tDk z8R&_0ez8H`IQ*-HUoQN*@uQx{gq`MKGrSz?rcd$TguY`t2v+QAE{A975q>EAJNhE` zH3y|6gEhh05q1GsbtjEdDw8UuEKf1T zj6zAT)y^22AoUuxd{f7a^oin1u27m=E#?hPWg-?vU`G(1LqHdp!YW}{5LRW%I))rs_G0QxekGOp#<=V#zZ8A)u`C#yw*WTC zC%&ewKxoS!z7j1*ug>50KXS*Pe(T%sKXohg*XW<3o5{u7Po_5aFKzaxc~eWDdn?@j z3)gF|YtP&c@8!?5oUCv6OztK(cQ;H)@`sd8N&L?(*ZLWlV5I)(;x7y*0&mjlf=Gb5|R-Wsv{wj%*X9)ypqAL;SZL8@_?bF?w^5PL3)!hwPJM+}*nvpMU^bEfqzS z)mpkh78PHuS6q#$0zi+bbqQ90q16fvBBH=vE?4Yb|D;uZ9_9o>ihVq+71duo0t&;< zXgNwL^MqbZLCYP2F^d8KIf6W-jA0{TdlAHu*@F@?C|065apA*6@Mzgiu^g132+UT| z2A5#js)Y&12ikM4kcDpide5`;waRBbXKCLAnB3#y49X93u?C7-IQ~lSLHaiTxc9@V z3l&9t-Sz-;&!hD^!Un=V{)fK(^qrTr&7KJuYm^;F^$!6|8-QT7dgq7@@{w?hiucC* zys7^{XbO!51#y%n0AQUdp6hR&LstLo#rtRhPTW8&UO4ldCe6+Qb2!B=Ac)2zB+-3- zf;v%PC_%$Qp1-tS<5qukRNPj0L00(_SEaLRCH%z}g(UVVqz&G`YfuxBzS#ytzKC#< zpWhW&_cN?!=0I>F;5oJIx}I4{>pGi8mFN^pC}j}@d04F?^9*yv&LR8=K~#tvB|8FM zN8&bT<0v7_!E0hdUmzbll;n;gs|P-F@}YqyHK0a6@8>fEGw!=YRzp?q@yfMB>M7dX_Xnkjf@jIf`YJ!FoV#9pz-dJ13__oMDM{X zrpmz;es-kQ`7;<(c+DbzePmCcL>K9fQ>Lvu?oQgYGefhKhBjk+b_fc0=i~-D^u_k7 U%ITvqub15L*2g>K8!-y_e+9HL;Q#;t delta 4053 zcmZ`+YfxLq72cKZm4qY&l0XPy;DW&*Z1XU2?D&BLhH*`7(m_$;m?Y9gx`JzqD`oE$ z1UIe7WX2`0HgxOO(`FjdAFVypX)@)Hr_Q9Y(?@=Fph^SLkWAW{PMbEV7_9L&yUAIb0?Fh#2oEOjC49>ay_z!a}XHUCBB>{9!Ag+)n zWanI2$QyESt~^u`a&pccstlEK&f`aoDC7#DP}yVV{br^SA>s{{2N0>4`*pM9kpwzw zu15(R^v$i`sK3xLp&1=<*^oQrF-0>Xv6N=WdPLRqv=TEG{(_^XeiugQ5(=Xje8=zz z(836#{TsY?*X&W;x*-uaAta$rG;F5s@(LQY+30n_K@SDW_GqRNaZ8bDQ;`>aL8KOzXxFV$$qN}z@tlPqE5<&l9iOFlvu`4Q<{_-Ei7fUxI(086cB~o8NxJ0qf)DuVrNd< zqtQqtO_VVu86g?XP$ytD*e*RZp3;>qB{ET@Nja&;rIePOmJ%t#ZI5LL0dGlT%uc(i zWhYZHnV&9eacLr>8!ttY9_f+E2=rmj}Hm=0Zr&FqCD5PB)3_UoscT|p@SK@Y} zq*J5Ml5P-H8&eb0?7WG?aJ)nm9Tt@$fM7|JbVbp#ASD|cn{BUnK9NjK!KS#vOw_@z{RQt7 zVIzTU;1gq7N~)6phgygkEk!2eq*Uxu>AW(nXYH-VI8o$yM2&ZBBOKB6;$LbU{2SI4 zvNx_IR1G|Gmm=_U295%k+aWGMY*L9c;KA=(f!DGXa)9Di{Iq4^s@oCBEMjWFV-o;I zyxl&OcNQO&FWK4}wB&`j8Z+|dF~!IWNyrG|hn&gVAvK7hPpQUu-keUQgF@a?(2=*s zl8OxGlR747hU2ojz%ma8ak06wNW1_kt0xfsge5NIE7B){%%HV8WOF_9jg>O*s>}28 zy)PtZPON&XF8f~HF~4uw-?rp$yV8^MA6oX`e{D49?VUNbTIPNE)ca)(v*uNYYgT{Z z;IgA`$x(OtYs-$^Imhm%6{mmMxns$><8o-e>3wI*XCf+ZT(hA1-LpeWLd}Z9Gc!bg zCDzaZ;Wr|;oBG8DH)#NK_(fF_ zC$M}WZ;{h!MT-~IG&0e@JGv}T!4Nq>8=SpjAFwAE#+)wP^fs_hKplMy5gbCq6vD(D zG7%x<4x@W;NPzlnqjRN~ondqo6E~EsK)#xOwzJywiAD!qPjoYgp`znkF9XwqFQGa# z0$gD{WDcXpp`h;H_zl&sJZYxaT{YQ~O_?y>EVE&h+$z2ysO(A0rpy>>KqKrVKCDQF z6D3rShPpQ!$5lKOwB|)U0|hj1i$JSTjYx!4!-l*Ks;B`;tP?N$$x8~YFLQMXc|li_ z2{H)Nw@As9=_x*mya#?B0n9deSbHp0aN*-hn7!jygj$Q=kBo4Lfj>U2MM0=)g6 zvkshG-SA@RN}y>uF!Ww)|J!GBtwXcIi)AYZ4$lfN+3&2Epz`Wl2$#4&aF(x`;rqE> z2D+Yg9Yojcy`uSsfPu!KJ8TUGhZ!yWvTPpX6LiEqiZ9Z)+;uoaKXfCDZqCKh$nO*NT{JvHV*L916Ab|`<5B(!p< ze=Ps6nz;F-nf|P*7r#RPS#`z3H<`#N+mvP`MX≥aBP3{73O5?X9h+1Jyo9kr(KE zbxpZu?F8%xa0s*SuoXPsPOn$HMOzpR+vrlY7xPCp;>*IBiZXh%)=!#@U2|1FSDz^AJf zb(be|6}x6jR{gu?FXa6DW=mIn&GU(zZ|}0N`wh>mW6fl(vah(R*Ua$!*cn(uLal4X zTlf8AbI0a;a^8K*-h*$9(uJCtvi83F@Xb!#cR;w=W$n971Mr*FFf(ig z)EUe~W2BK0-gpi(j-gJbfCTN#;7-IdC2yG`Dnuh!OtMUdnUJ>>VieK}`VLfD=rcd8 z|0=$|@M--8+**vmvrJ_%1~W_v?@d|yt%iR5dzx!_r?3U{c)n^WLX71jd5)3i8M&Xn z)p!^$(a#$f8~G`i=xqK)AUZ3T9L^0q8|kMzcj7!PZ#uI76qDkYA7tEyh3A0(yplaU zMp(j0z1sBS($msVN>f-Trq475vfKyXVVigya!z4C=NRD;$+#fSGmy8XXJGO|C40$? z7@2fZ**@X%!u8qvrT{790Cv8YYvs4*+;es&#o6a+Q*-;#FBRIBVcd5axdh}w=}CBA z%kW$tVK)nU=(n5evaGWest2z-yo7KNS-A2LAk1mxA|o#`!b8OgT)uRpUB;ATG7<@5 zG6b_abQpAhA%^>zJR>Z|bQVu{E}{>F@P7omc;sLH60z5h*L@z*wcd)whw-`vi~DX{ zD#V)GduZ3LLFa8`7OMy=Kcs)*o4fvM^1Q-$l}`YHYB@+}g4Iw9e-P{vS#p0&7lW4` zW%nhlp@PIVMtqjL=L@qObfMr>jxU$pm}Sj{Ya^HFl{RT_W!@f%Br@=?O@T)SJVp>1 zXGCCx8y8}nkC86=@3teot&C+Qyin-+7{|e3CKD?o{FeNoYCAFk|2vXO5BUi!FgW!L zo!H&Iw+egL?=j&hUbmZZ?YgrO`_>0>3gfCpse2tU=2qP7!5w$jrY-c{-IB|TZg|Uk LcbRWAW1#;7D&zb- diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/checkpoints/langgraph_saver.py b/agent_framework_oci/libs/agent_framework/src/agent_framework/checkpoints/langgraph_saver.py index c82da75..f060ccd 100644 --- a/agent_framework_oci/libs/agent_framework/src/agent_framework/checkpoints/langgraph_saver.py +++ b/agent_framework_oci/libs/agent_framework/src/agent_framework/checkpoints/langgraph_saver.py @@ -26,104 +26,11 @@ from .checkpoint_repository import create_checkpoint_repository def _jsonable(value: Any) -> Any: - """Convert a value to a JSON-safe tree without collapsing containers to strings. - - The previous implementation used ``json.dumps(..., default=str)`` only as a - probe and then returned the *original* object. Because ``default=str`` makes - virtually every object serializable, the fallback branch was never reached. - JSON repositories could therefore stringify arbitrary nested LangGraph objects - later, and restored checkpoints would contain strings where mappings were - required (for example ``metadata``, ``versions_seen`` or ``checkpoint_map``). - - Keep dict/list structure durable and stringify only unsupported leaf objects. - """ - if value is None or isinstance(value, (str, int, float, bool)): + try: + json.dumps(value, default=str) return value - if isinstance(value, dict): - return {str(k): _jsonable(v) for k, v in value.items()} - if isinstance(value, (list, tuple, set, frozenset)): - return [_jsonable(v) for v in value] - - model_dump = getattr(value, "model_dump", None) - if callable(model_dump): - try: - return _jsonable(model_dump(mode="python")) - except TypeError: - return _jsonable(model_dump()) - except Exception: - pass - - # Unsupported runtime objects are not durable. At this point the object is a - # leaf; converting only the leaf to text cannot destroy an enclosing mapping. - return str(value) - - -def _mapping(value: Any, *, default: dict[str, Any] | None = None) -> dict[str, Any]: - """Recover a mapping from native or legacy JSON-string values. - - Legacy rows written with permissive ``default=str`` serializers may contain a - JSON object encoded as text. Parse that representation when possible; if the - value is an opaque string, return a safe empty/default mapping instead of - letting LangGraph fail with ``'str' object has no attribute 'items'``. - """ - if isinstance(value, dict): - return value - if isinstance(value, str): - try: - decoded = json.loads(value) - except Exception: - decoded = None - if isinstance(decoded, dict): - return decoded - return dict(default or {}) - - -def _normalize_checkpoint(checkpoint: Any) -> dict[str, Any]: - """Normalize LangGraph checkpoint mapping fields after JSON persistence.""" - cp = _mapping(checkpoint) - if not cp: - return {} - cp = dict(cp) - cp["channel_values"] = _mapping(cp.get("channel_values")) - cp["channel_versions"] = _mapping(cp.get("channel_versions")) - - versions_seen = _mapping(cp.get("versions_seen")) - cp["versions_seen"] = { - str(node): _mapping(versions) for node, versions in versions_seen.items() - } - - pending_sends = cp.get("pending_sends") - if pending_sends is None: - cp["pending_sends"] = [] - elif not isinstance(pending_sends, list): - cp["pending_sends"] = [pending_sends] - return cp - - -def _durable_config(config: dict[str, Any] | None) -> dict[str, Any] | None: - """Return the persistable subset of a LangGraph RunnableConfig. - - LangGraph injects private execution objects under ``configurable`` (notably - ``__pregel_runtime``). Those objects are valid only for the current graph - invocation and must never be persisted by a checkpointer. JSON-backed - repositories stringify them; on restore LangGraph then sees that string as - its runtime object and calls ``.override(...)``, producing errors such as - ``AttributeError: 'str' object has no attribute 'override'`` before the first - workflow node runs. - - Durable checkpoint identity lives in the normal configurable keys - (thread_id/checkpoint_ns/checkpoint_id). User-defined configurable values are - preserved; only LangGraph's private ``__pregel_*`` execution keys are removed. - """ - if config is None: - return None - cleaned = dict(_mapping(config)) - configurable = dict(_mapping(cleaned.get("configurable"))) - for key in list(configurable): - if str(key).startswith("__pregel_"): - configurable.pop(key, None) - cleaned["configurable"] = configurable - return cleaned + except TypeError: + return json.loads(json.dumps(value, default=str)) def _thread_id(config: dict[str, Any] | None) -> str: @@ -178,13 +85,6 @@ class RepositoryCheckpointSaver(BaseCheckpointSaver): """Checkpoint saver nativo para LangGraph usando os repositories do framework.""" def __init__(self, settings, repository=None): - # BaseCheckpointSaver initializes LangGraph serializer state in current - # checkpoint releases. Keep compatibility with the lightweight fallback - # class used by framework-only unit tests. - try: - super().__init__() - except TypeError: - pass self.settings = settings self.repository = repository or create_checkpoint_repository(settings) self._loop: asyncio.AbstractEventLoop | None = None @@ -203,10 +103,10 @@ class RepositoryCheckpointSaver(BaseCheckpointSaver): def _make_tuple(self, payload: dict[str, Any] | None): if not payload: return None - config = _durable_config(payload.get("config")) or {"configurable": {"thread_id": payload.get("thread_id")}} - checkpoint = _normalize_checkpoint(payload.get("checkpoint")) - metadata = _mapping(payload.get("metadata")) - parent_config = _durable_config(payload.get("parent_config")) + config = payload.get("config") or {"configurable": {"thread_id": payload.get("thread_id")}} + checkpoint = payload.get("checkpoint") or {} + metadata = payload.get("metadata") or {} + parent_config = payload.get("parent_config") pending_writes = _normalize_pending_writes(payload.get("pending_writes") or []) try: from langgraph.checkpoint.base import CheckpointTuple @@ -229,13 +129,11 @@ class RepositoryCheckpointSaver(BaseCheckpointSaver): async def aput(self, config: dict[str, Any], checkpoint: dict[str, Any], metadata: dict[str, Any] | None = None, new_versions: dict[str, Any] | None = None): thread_id = _thread_id(config) checkpoint_id = _checkpoint_id(checkpoint) - base_config = _durable_config(config) or {} next_config = { - **base_config, + **(config or {}), "configurable": { - **_mapping(base_config.get("configurable")), + **((config or {}).get("configurable") or {}), "thread_id": thread_id, - "checkpoint_ns": str(_mapping(base_config.get("configurable")).get("checkpoint_ns") or ""), "checkpoint_id": checkpoint_id, }, } diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/config/__pycache__/__init__.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/config/__pycache__/__init__.cpython-313.pyc index 62b2e6fadade1ee7d5ba137dcbe7fdf04f495cf7..762487faec8320b30dd79eb4781512216964ad95 100644 GIT binary patch delta 63 zcmaFN_>7V3GcPX}0}%ZCHj&FjvsFJguS7pZ-#6GZKAb>KSU)YZsJJ9PIX|x? Ru{b_AGrcG=C4XW{Jpi%C7bE}x delta 60 zcmaFH_?VIFGcPX}0}$jsnaE|L)})`CSE8Sy?^2Xskd$Ac?;qso?BlBMTN$2Tl&v37 Ol%JKFTv9wSy&eEQY!pBM diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/config/__pycache__/agent_registry.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/config/__pycache__/agent_registry.cpython-313.pyc index 1971422aa0e3f8f1f0fd37c403fcdc03365cb29e..600ca2f01c6b9f942328057d6327cbe6d26d1229 100644 GIT binary patch delta 66 zcmdmBw%Ls9GcPX}0}%ZCwvo$;S+iR|H?KrLMc+5rGd`dwKPxr4q*y;Kv#7WvJ~=IlTd~$wX UNn&w)Zf1H>VoLtz+iKoi03Eg%z5oCK delta 63 zcmZ3Pv@D71GcPX}0}$js*~qn8O|3~kH?KrLMc<_;zaS~ULf=2g(b>mU-?uV6zbIQj RpeR2pHMyjC^F1|hE&!m?71{s* diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/events/__pycache__/__init__.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/events/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..25db31fdecf9f31c03d0db97008a77806f73b4d8 GIT binary patch literal 156 zcmey&%ge<81atNCvq1D?5CH>>P{wB#AY&>+I)f&o-%5reCLr%KNa~h#PG(ZEeqwrR zUP*jfQDSatd45s0esNJUhFEGDP))IZe0*kJW=VX!UP0w84x8Nkl+v73yCPPgSs=TL PL5z>gjEsy$%s>_Z$&MzV literal 0 HcmV?d00001 diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/events/__pycache__/oci_streaming.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/events/__pycache__/oci_streaming.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6f0b4bf43705b019007a2cec755ccba482b099d7 GIT binary patch literal 3260 zcmb6bOKcm*b@oTDzNBcGmI%vXQ%T68HDwo892tr#+GY${4kd6!#EAqfC~`@!LoJor zr33k7B!Hm=1p)^!oJ#=rRQu**k3RO$16jdXVrrm=o_uR72SsjuZ+1ybYqmfi$hZ4G zJM-p!=Wt|XkO2HR*SNi`5b}24(;6^w%3S9LFH>wY$2vuu>Huwq^^LHmpHPd#D zDlP4pUpDCH8ONn&X~(i_Wq&0f%K>pX3oj4J7D2PAs0&om#VuKvwv-F9E~m(CnMQPl zMr#o*%0_c{VDa_lcHMGrne-K|!Uj!b8t&e%$)dZZy?UcmDF$X(HI=D`VS_6TgAE$SPNUMS`%>M#*)lwcT`0$1wOFhae|( z1QG7d5xzJvK=(;UUVb9ATNT-0aNjdaX=Wbm+I(uL*ERw#%G@lzEBr~=uM=$(TmVH zXwor62}CCl;TANB2xIK~l>2`YNklve5#1+0iGuQ>uY;2Qeoup>zu&?8iVhW2Q?v*> zxprkm?^ffRB0?vWgW`u*LNEa6=0gIJh4uoKxk_xYC>D-tp(a3~+l+jYiagd0)ua41}O}l?BTf zR)tL*`EWg3*jU+ES<4%%xlh^1Zi%{)zwjo{w?Laf`&kIyB{vhgm=QO76H=EJ#KJ&G4aoU` zWy?jWZ-Vxc<;}MRY@Q(~k^**v5d5zli!cBeL|gek_QeJhf}%1f=*og%N5BH?Tp=i6 zQx5@XPJ~!M79-ta?RD8mP#hwYasKl036&D9nAK9V?n1+rAnBNLr&Mp6AW(Nq$AN+B zXd^uFn0(u5*i5N3cXl0$*0G3bmm3w6YMg+HXVx8dYQ5=x9DI7!bW2v<$=NR5qvud7 z@wSxy8U@3!nCRGY zoNoc)fPi{<89VXa-EZ$czSK@#{_~Y~Y~71}(vE#{5c_mr?!-?#8hJ3{#i!fxX)nIm zjxRnR_p*9Bt9#kc+S$(zvRkdntyX-o6}R@4PU7UFvk%UCiP?5y)=Mn36ARCC&o8zT z3$4WJezcV>-Svx7PQ)#dri7X?k?j^S?O{>Xzv`VFby zz$gEGQl(Lfh!0RKfcxZMqN4ovr(s38j=40l}@1_Zy61{q;edJR-?d^>Z1?vYM3=0&IB_hiD; za`5}pd*1bJ_`QrxKfZYo%e2(Y%b}@*p?6yHJKUSv0KEjCvdDJHG2g$yqIivg_RR)r zrh9{5X(;$3xWn;_L>fulICRZm>Y{&*T%xNWMeCg$pnph$ApDJ-J|L$%(NQlt@t5dC vYx2TDbpBrC-?AWNg?|#nuOp)H;SXnC6L`Eb>KSU)YZsJJ9PIX|x? Ru{b_AGrcG=C4b`P9ssZg7mEM@ delta 60 zcmX@aw4aIVGcPX}0}$jqnaI_w)}o)ASE8Sy?^2Xskd$Ac?;qso?BlBMTN$2Tl&v37 Ol%JKFTv9x7TMqy{TNI`M diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/gateways/__pycache__/mcp_gateway_client.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/gateways/__pycache__/mcp_gateway_client.cpython-313.pyc index 4c5a88a2053f5c71a138d6fb8dd7e079b541c0df..ee7cc1503be024325dc3721be7e334a291891831 100644 GIT binary patch delta 66 zcmbOzHARZ+GcPX}0}%ZCwvp>3qvk~Y+`JO~6n)=d&-j3%{H)aEl4AX|%%b9w_~iV& UlEmWp+|2Z%#FYHaKN%&s0q>U=&;S4c delta 63 zcmbOtHBpM|GcPX}0}$jq*~oR0QLRruH?KrLMc<_;zaS~ULf=2g(b>mU-?uV6zbIQj RpeR2pHMyjC^B+bDZUA(z6zc#0 diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/global_supervisor/__pycache__/__init__.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/global_supervisor/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6bfab5ac6ffa49967ab12f64a2af07fe2e9141f4 GIT binary patch literal 662 zcmaJ;%Wl*#6t$C?B=bmHUR|&%f=z@(R_qW9T7hr`5|b^Gl}ociIO)J7E z&;xHrRm5V5gB@1`HiRKdAYmz_EQ5@VV8q5S4)23%!lp0{_OQy?4(uF|lGMpN3cGDu zWZx;aD5%R{H1jjjog6ADI*Wnb>%dI3(pXp(iMzGsG)m2c>6N_+9f^hPq?NjJ_x?&e z)ZIe1?#?Tvj~g}9y%k4dE{*5j{v$XO7riic8>@x!l-f2{;5hqN%(_1p@Ie|4p%CE9 z{ny>1A2EAbrmv8?}E^9bQbOetNH2W#^1GD>N5Nf3VR5&C#d Pp8gz6Cef!9?jrFwC?~mN literal 0 HcmV?d00001 diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/global_supervisor/__pycache__/client.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/global_supervisor/__pycache__/client.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7c4d8561a9b2a64593478ada038178ee41ac28c1 GIT binary patch literal 4552 zcmb7HU2Gf25#GIj{z#-m$)f(LpIExYmg*l_QryJ0*;1^pV-4 z5-S1PAOQjuMO!C<5vOSpKROQu{L&&tUlPlKgFcbATCxWRNRa}q-{>lh0yhtxz2i|o zVT*PN?#<24&hE_3elxpPSLa30el?sqpYmWdgOEuTL?YJFbZX8V))rt9HA%D!`b!z|{IE$9 z-{LLUo>9%ktWI7`nHe&iu=h5UU9u!qr5;pOYsZ#-54n6lT~dPXRaEL8`lHmb1~f|W zw68RX8}vH0=nr65ABuo?W87e6Py+=q9Cc+kJx}<6zu7aDF@pzwCH6Lnqk0tM>(M^O z5aOcCk1-=ON}w5HOpMZzG#oDY2)eo0DSF>_HFQ8${jcA;t#pJ+Fz~qNdT=o-FX|&SY3>b`4!)| z(2pcE`yTw?fd9oFvK~%xX*Nj5cot0hIJaPM=rj9Ei4>D_BD)46E}M9JaXgX2t+m=PqRC zbpSZA0&p@WGz3zAhfggFmbapYF5+|PMUu9BCgg@iQ%%5hOCq|Ng*>5K_1l*5>S--& z!gem0aue*%)YS{RX@U)ER?D5U{9E3nISmA;dTu_I$XQ-f&&}&ejV732g;1;ZvkN+i zKw2?iFGfNqU9fS>OASh^^NSa<7DtV;_;a~j_M+uGVlEkpNgHQv*tWQA#>`o4$^h*| zOTp5~3{f4!Y%dUs4I~1cTu&&XSfcCJ0MTDq)Xf~2VSAqR+QW;W1dIgL)H)VSAuV)( zPZ@?zED@9w_&S#0;Jw9B&k-7sV6v9eOqx$3TN|~A2V|1J5 z&me^EL4NqE9_`w<{8BM6a62&Yp;#PyvM~1KGFNH{7aMvC4L$i_@74WRcjoKmW%h34 zj!Qqf(>Sm!el7)yQd>c4yYlGOmx=?23Im5$rNgBv_u#caaqwVa@Zg6tcLu+=Dox)V zIrNcu%lEPG)9E{hzrT9wx#Gy#!pPZ6VlmiTfF;JS&8-Ia_g`|anv)T#31n3=I}53 z-Rgq&OM%eOmwvqTlUJ6xyMailrK{K? z7h2>}xVso0EQAM3;f@N?+*)dvOD#S3>%^e9j6{$3zK<^T=g??%O;|P`n)t?y!*_Y@ z=tEO|_~rnfVuhQ7ETta_O?lXxkK-v`xOs>J`V-a%{7>rfl*oM&I5Gk+w|EQ#w?s^7 zk1!PxZw2sFqyJXWPw5U3_*)7Znv7qk>Hh)5K_&gyO!$z%YbJa|&_KP8BZR>`KP?>YDrzYck!iqQM{GYp%W} z2}DqTMK+0($btUQ>WMxO2F4Bj)GOQJ~v` zXrslx1BJc=`QFid{TKk-Ca4JQy&c+nJy~YBx-+=c+4ugLch6j7-&2b%yDo91ox6)W z#|k^gK5Z&apDs+F&TD#6%NDe3{^cL8BlHSB&fIq%WrSv!6U-WYdzv!C&oJvEYT8!} z?Y$G)`>yS97(0#IHWB;>rM?eAvG-=%@645oERi4h0G*81UL05SQVm28S7-XM1z2tbPQ?s(R0WV+BVH zDzln*3^=TqgDX}y91QnB$jof&OVAI2ON$k93_3{m`o)~gI3Y%3s&Xx}Ly0^=MZ#O- zXd_a`sQ6y!UPWbw_4JiOE$@uKIsW#+yua(~yMZu#!7B60$t#IVhi?0O%PcS-m=vB~ z3pAp)T8G$Q;~|#N>jvDID@X4Khha|?tSmkWC0b6#$7HW_1Sm|C{m?zAr{zu@j>xVE zT(i&G#RQS)Fm)L{rkS)Q5Iwg@47(_SlWdujCRwsvz^(j z+NDw|p=!AtNzFldX{zc6h=iyJEm{agNxP$0Zu2SV-aub5m>(_&QEOM(*Ts83Z|E)a z@GJ|cZLlm-N${tF2QR5C&sMvm`uR-%i@K59*J5&Q$z z5C}y?c0*?gxutB%SRmAR8^0{Ut`AM8w6oo3``O;=vs9|OeM|bTiq)wK0`acK>oj>rwZt)bzu+g`v-!~R`GA6$Gq|Y literal 0 HcmV?d00001 diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/global_supervisor/__pycache__/config.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/global_supervisor/__pycache__/config.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..16c4b37651b9c02c8aff6c909fbdfe43576eac48 GIT binary patch literal 4987 zcma)AYitzP6~6P@x4pZ5zlaB8LpB&pUM9vijRPT$9ZcfMLWFTfA5pIYkOHo zy;|KlckVgo-Z_u&p1W%m6&?ibS6#_7zjq__H5u5AwFqkMWgr%ifCOq74N;il2~7{v zLkwn2ni*z?ILw(eJM6#?ffF3V&LJ0e4Y{$KM-8YA3C<=YxSpgft=KckhTM0_AVe8n zNmY}&q{ox021E8mNk0uwW_hDa6EP3!`$Y7xlu2j6s-KO`x7E$jQ_sXtK1$z*i%g-Vs?nolfu*me2Up z(nMT|>rynyt4SUg{KdoYIVCwEDZG$Q$@ulSmc)BQoZ*O=o-|wqdChRjsx+aAWpU}FbNmX!Sj?)Q$(4qSNQofj@`fA`o`@gA9*W#6w@b)Z1ag*Pv}xl+}V-F7lxHJ0^_ ztuiRE?T2rjz@w2YU8ot@!F~{gZc{9g;4)+BJMhK=8e8{e(LX9ZR*b1~annX3#R+;! znm`G3Pf<%hRg44B#-n{mWx~v8F&@^11;&nyQkgEKvSVb&W(%`p#A;@InmghCQ~Xc01$Tka4b&442kpd!7Q&bjfNY8I7xx7_=h{YLMZN$}uUe z=wcyxZqT@qOcIV8DCENgObm8LN+^a~lVY-{B&Dd~#yBf7!GbvdCK9!=H@OBfC*l>(T?F0ud#s*u-UB8q0PDL{3DN`a`PONI|iXYKuf z1~rKjk`m9zQESWG>m;`gmMnmYFU-u=NbEpb+YQ&i*l@>iG9j9~Z!AsE;uPW3zJTsL z`o<0Kj;M8ma z6{afDho_!*MIj8P%n(h7jEa6WULpJC9ar#{DX_TwQ;$f4+aQ zDOcT@^>zMx#b3XMD41BOYRYaqayxTd$uezkH?Zv(MFL3Ky>&;n!W3b7-b%tcHGSxl`p0kN>fhqt2})ChsF6pklxT%Wl? znW?W4Y2M0pSDzv!CZf_oBUI}D0s`&rQ<4!$(GCJ(vF-zLjo{IF^yh(FLmv&T0S#*z z%#=KX$&!iNBEP9|K}5he8|?zLNF?-HtF>0n)x39%h!~{XlInFMbNf#?DgHDp2S@=-|hREIHJ{ z!7tr9`Qgbs!B1O0Y032+H?4z7o`e|O4-e~9gu@$Qf)g87G+3hCs42H3`ABUWbmvhy ze;m*GPh?#u9&`mMUCiRF%|r<(Xeh7=3Fne#8ypInI00O^1{5K8ofW{BE{6k^kbC8e zeVAbcwp``{zj^mt*G?!K)?neN;aV`CC=s& zXS36p>`W$`IG2ySk)3!m8+hwGhOVf*$DpchP*lKuV&f-acmUtB7%X ze)vbjphgUHyYMvXFTwK1%xvBqr-4uSx;j%6Wmo2R=a@P z3}ptm@d={CEU4)R=uADquCapr;o@H;N((pzUNz)RtemWV&NBc zas=1t0N1?60JTb}`|T|EDs|t-aKqGn55>Jg-FG-R{`&ySc`T(w72H7JyJBguGJF>{ z5yMGtBk0RhtTfZ$)?LQj+2-9Eu0G3J2XO?12(D`nK?hYN fMSY3d{)rmCM0H;y@4ryr_l|DL^DTnT+}QsBCAS85 literal 0 HcmV?d00001 diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/global_supervisor/__pycache__/models.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/global_supervisor/__pycache__/models.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..527a4a1ff875ea144d43a64f76aa4ec26361f371 GIT binary patch literal 4480 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 b8U|n2{)|yMRj=DVF~-$2`!fnl^3neV(`0~E literal 0 HcmV?d00001 diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/global_supervisor/__pycache__/session_store.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/global_supervisor/__pycache__/session_store.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..43f44539c7289a674dba7e88f3d735f3e789aec3 GIT binary patch literal 3471 zcmb7HT}&L;6~1?Vc4vRs#r!w~Vmt<7v+e?JYbUZzAe$Pc0U1?{HnmEn(Rg=&F}pL{ zduMIgs-nu3DoE6lrm?bpsN|{-DeXfl^|4QpU;1ba6=>vCs8K8V4VNg9`_yyp>@Jv4 zq+a06x%ZxX=iKw1@62Vlr6o?F{bt0waXCuJ=h$g9B~<9{6;SRGgBWy*Oj1U5)TJqj zN$`}XQ!!oQQ78YPiJ<;(wee5bTv6+OM^as9egShU?Dj}PXmzUO*n zugdi+Z;V{^+<9+g#x6QM6TY=raI|<2F(t%nR@E& zAI{SY_2{@#UK*@V6=7_ilqX4l#cdQo!KYcH3Y!OyFQh4WAXC=F`rNGeSG11+yMEDrhv zE7Sp^k?HTjpN6!_NKp6$7D3FnT_~@nQ_Ms}<}=K^AY~PN=caAei*%rsZQsJuh#Upnu&QU%-C=LL|WP?vECJ zxlp^ae*ElaEBux=hF|~db`+0b6v(ppwh%c)K61Y}5UVM9B!m1V$&p5v0Zf7n_KccxorIw3<`spc}JF9%!7e)On1zFgi zA6U8sJ%0g8GlM`s*bXbd4f?f{x9Qswm(Kw^+R1mJ)QHmCmZ!6rp`zvCj)0v8=B9M@ zI3WqhI4--AO9xK|8H3Le>+?`FEV9 z7Qvm^Ps?i)qW;0V4z|36wGQdD_w@-w${_q95$dD}QeLSD_X=_I15N}f*S@u{&$@8I zizp7|NQwb5%XVW$kU0W|=S{P)C;tuz1Y{>kT05FwC-?Wo_4K!wlz)lu({}iM+U^00 zbZws=ygys7m1ApK-}e6R5Y5R@G{O>&cOtmzI;{X2jA1vB9oNq&VI7dU&w>cEvHt(( z#RC^is2uu_^=Z$w!5q&m$_;x3H&Mhe4WdPR&Z?IDj3zc@$P0EFh0sK85gM)%>%on1 z2fTYj{LeLwzuDA;@vG3yB=PnoVrvF*(=5a7wPeFhENPlQs#>M`OxiT(9LD{UkiY_7C|Mk`QgAOZeEFgioS2KXM8|WepYI7NwI!fW>IlTd~$wX TNn&w)Zf1H>VoLsGCDs!F0el!b delta 62 zcmaFM{fe9GGcPX}0}$js*~s;YMXgOgH?KrLMc<_;zaS~ULf=2g(b>mU-?uV6zbIQj QpeR2pHMyjCvMTEd0EcrGRsaA1 diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/__pycache__/base.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/__pycache__/base.cpython-313.pyc index 61d7d961da0cc0f5fbd0d36d972e32deadc7f2c6..8a466f4afb13e3adf086ca5a582581813087896c 100644 GIT binary patch delta 66 zcmaFE^`49CGcPX}0}%ZCwvmgENwZZyH?KrLMc+5rGd`dwKPxr4q*y;Kv#7WvJ~=9rXnT(W__k2 z=5!WK)|ZSxC7MjPL<16w5_57=bAl2xb6hJ@lS@l7^Yd+g&SFfP*7Kcr4eoARhs$CJt`yj^`3j>J{%#4hT_Zhq%a4TL= Pwz|M&-N;_V0Tc%SNkLMl literal 0 HcmV?d00001 diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/__pycache__/framework_llm_client.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/__pycache__/framework_llm_client.cpython-313.pyc index ef2258ffb0a172a2b4841382d8a5856f93614d8d..3ac51858ed79bc5fdf56683fc432676c9802d92d 100644 GIT binary patch delta 21 bcmbQ=%Q(N6k?S)rFBbz4{QI_%YpNRnOL+$d delta 21 bcmbQ=%Q(N6k?S)rFBbz47&-6`tktXZa&h6h*m|0%`T=rhDjSbt2JCNO9*o?4a5VIU`A_#6lf*LF#NT{ z9weAJI&W#`YJ5AHWQR$_wwN1-5szn1(R7;o=$(&#C2M?2=94O=GO#~U`IO3QhjC4L zATkH&rn9gZXO^lvS>5C|bLo_%BxMZ)<#}^1lU~@M ziKZy5REuRKWpk5C*)35@Nm*T{S~R<7`qRp`oYcko6to?taKoQA4BbBYlQ&rQhw^RZ z_OASLA$0jS%fDOu?OJg*QMi1g;JsO}-#h?4Vs<7aB?VFHvPfku3#TEQuB58y^0#$Z zN?SvGN8U5NHHipJvc8YFxWnD&fmtJK%$f~y&X!;jwgfrL3Jl}`w{2J01nw`pcxVjj zR@iUh(dFR)r`aLG;{lT64rZ)_cdl&42;~Z`_w7R!C&yyur9FM=HEqB&6=Ai7i zApTwE0lVn%5ru7DP2HbjPq1+dRE|1|`;PL+CG3LpdHk|*Oum)|Qddpd(INsCq#R0@ z&kF9E)-kiLcGfN9U3IGQomwVD8X)BV**C#+1{^^Y_S)>-4Zn4&4j>Y5t?^6s@y0h{ zUvkv!kCh6HCA9w}zZZPxk%*4)pv%Bd;#J6a2hmhcu6zz4HngAFL)DtCLmjUP~CZ!o@7FhUf2AhWJKxOtc4Q>JWsJk)+ z?2$B8Ibx8KlW7f5o;tz%-Ps#zj+d3Bw3Al0B+6@Yjt9^J?Aie|Rr#z$C4gr|Pb&zz z7FO@@xg8!r4ID|Cw5ChZNQcR8%DQP!rIWhp(PTX(Z%Da}Zn9|w09)RbGC6Q-I;H9g z95^6T%zo3~5-o)*mza+D>{5Kitd6 z;NRrFIMtJ<)m16i(DR?Q* zJr0EK$#3=Mo#oTfchn!NrPCLT(--p2f`8E9hRUN8rP1@o=y@C%Hn@>;?4?rdsu8=2 z17ij^4jMIyH~8koH!l8QyVMso`l3Z|^zm5q-P|ws-rFmj|JujjD#pHE9E(FV#@LPg zl|t}&!#7&?220-O;D32|yfplxG5liw%Dq<%-#~dFQW}^v1}1@@GJJg%59#R6w^iJv zz57k^4e_U*5yh^eXvKhN zqzIh=R>S-F_U+qzH7^3sWCX<*j~_J=SU=k*|MmqP-A@U0l~LmB*k7P1HQ7vN$K>jX zZ@NSgN=_6btm%U==$@!c6bq_R8?^xs>Q(6^II()f^zy;E^-6#%QC?EgmyOy9V8-Q09T| zhvEC-LT|Jfh(Wb^18;w$6dEx?Bc;%o5gIFc$I8L}g0H_O88t$qrBKueVI`G=g9YDU z*&i-&VJk0cxoPDforD=o77~=61qwtMbv1r#CHNq3Nyy+a!P6Pg!%b+Uq|?#!lt5Q$ zC%(Y`HEZg{h?9D8f=k%>pu6jVx%uz#i>e}9!C0aQS1k+|s#ySP8DOzhO)>1d{q>(5 ztE)%L>{hkfz>BpS%hoy)i?Y^bQD5iO)HxebCTi_ zn*lgi__ZT8Af96IrWbz)h}8?JnmhR1vMSixGi%$ey{T3^_wtUK%4OtfdIj_V=ZUrt zU4>;B<`XjbH^Tpw#6BTI|8TO*GE?a!J<;+h{;9i%=_q&b6&Ah~C+Rv>aUsQ#&QJwq yfPv1De|nLcCgHwv??}13|Ear;3H%u}9PkCJ?r_D06h{JG6_i<4|MCK5MfhK0AUVeX literal 0 HcmV?d00001 diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/__pycache__/llm_rails.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/__pycache__/llm_rails.cpython-313.pyc index 1e613f4c525cbea1b9891b6d20faa86564ae00a8..f78d6e3e7b0de80c87056eba054b62d094a39e1c 100644 GIT binary patch delta 19 ZcmZoNX)@vZ%*)Hg00jTOZRGkP2>>{Q22KC~ delta 19 ZcmZoNX)@vZ%*)Hg00g;DHgf%t1OPO{1*-r6 diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/__pycache__/output_supervisor.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/__pycache__/output_supervisor.cpython-313.pyc index b1ab5e7fc7fd1184517df8e79e37967137581450..03df7c18c9f1a5a5b415d444b5200ad6879325ff 100644 GIT binary patch delta 19 Zcmexf`@NRyGcPX}0}%ZCwvp?t9RO0e2jl<% delta 19 Zcmexf`@NRyGcPX}0}$js*~s diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/__pycache__/pipeline.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/__pycache__/pipeline.cpython-313.pyc index 581e2469e1da7bb6fd750ae22261047c77e99780..2e0eef0dc500f18f0ea92ca550a100ce0d8923c0 100644 GIT binary patch delta 66 zcmbOhIy02(GcPX}0}%ZCwvp=zvu3A$ZeEFgioS2KXM8|WepYI7NwI!fW>IlTd~$wX UNn&w)Zf1H>VoLsI5tb%301+=32mk;8 delta 63 zcmbOkIxUpzGcPX}0}$js*~s;TS*=Y!H?KrLMc<_;zaS~ULf=2g(b>mU-?uV6zbIQj RpeR2pHMyjCvp7qW8UU256(j%v diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/__pycache__/rail_action.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/__pycache__/rail_action.cpython-313.pyc index 2f1e12bce3186561650a6c2503b7de0f22a2442b..083aa866cf066140f3aecb4e4a1847ad3ba117db 100644 GIT binary patch delta 65 zcmbQuI**m>GcPX}0}%ZCwvnrVQL{%sH?KrLMc+5rGd`dwKPxr4q*y;Kv#7WvJ~=<9}z&IDX delta 62 zcmbQoI-8a2GcPX}0}$js*~nGEsMe{Un^&TrqVH0aUyzhvq3<8$=^t# delta 19 Zcmcc0bCrkdGcPX}0}$js*~sP11^_v-1wjA+ diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/__pycache__/rail_result.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/__pycache__/rail_result.cpython-313.pyc index 95396b8dbe030197d16070678b609343608fb67a..d026f5c65ebd3945e6a641e5d7de4375a397cad7 100644 GIT binary patch delta 66 zcmey#{)e6GGcPX}0}%ZCwvj7^NwY^kH?KrLMc+5rGd`dwKPxr4q*y;Kv#7WvJ~=li2Iu**L(b$@f!rwTxn-1_@Rvg1pn6Tp_Xb z1cB_}w2ad7IBMavg3?`aw3O4`lvc*kot#!tS{+BrIIW@7`XBYM<;pp(rFc)Aa|Ne+ zDcu)GcX9eGrM5V_+ifP5?h;bvE+f_Ma#G{2Al6>V&WrEe#lTq=OS@9X+aI z_5<9;drdAhSj?E`%u8$qK?q+!OQiwZom=p-WqVe~T-^tbdB+vU@-x=2ayoA9>sZe0 z#MI_o{KK-Xe=Q40Nv`nmYrgn zKqrt6%40ARgNSNsJq%I|jQB>|rh-_acW}_J9EqiQn(Z!^z1`#5@9Es%ULQ*c9t|jX zqs<9KO>h4i#3aB6a>N)D%@!iDBt#n1Xe4{^g_P`d6?3*Ky|UJf$Be9HpoZY!2x(py>f68DBA6QJ8LVOr)84NgvZLq z68~oH3fm)-ZZ)<02Y?m)c}pIqc^q(A?ey3sF$?hB9)p+-c)iC0@8kWRQ<|9MRYsBc zoQVz=t^t*R0l)DXU|xOfD+g%ep-b5qlgsGxZ-r948f?H%{W)+|UGv`tT{Ro8VN#3N zdc8^esA-Z2U9g~UBU{kgR{@Ji`ij7Y=lfa<>#0L5qt6=(9rpzk?@-{V;vs=>KdGYw zE|W+Tc`{%Y8v)Py3iadwbJrbLe10!Wm|VqkK_j%#>^fmd zP3nII;1JG+X5cfmct8i*Zsy2j39A$%bn|UoRI9iMx^zV<>QgAhjYXgP?y7s2m@#v?uI_RIBXTyK)o}( z10aa0ks@7)MP;%=%MvMo5V|8F{ap%TPqf=zo_2dP@z6J)h?g{a{3&9F5iA(37QYAe z#Zem+jj;eDOg^G1nG%VaHNK2WO!HFcsCS5r;3p>vU<|)KQ7isPdoVVYH%$GXH$m@P z7udD7mzJ1^7{{eC6GT{-bzv5h$z8zo@nQ(`U5$_H#Rs6yj!P1h{A#QJeS+sHrFCVfzF_OdinZ|2k%|I%ceYplu23b)3NO zPTe)kGXHwEsUjwRChQ;BRIC1Vnt+La^Zc~)bIIG!Tgw~9>&v$?f$zNR*1kuh(OU?= YsY;U?NKOOoxxhn#{yZ$kjZ@SA0y@i@m;e9( delta 4610 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 UNn&w)Zf1H>VoLtzL{2*<0N5ZF<^TWy delta 63 zcmZ1^K3|;cGcPX}0}$js*~n$csWwqRH?KrLMc<_;zaS~ULf=2g(b>mU-?uV6zbIQj RpeR2pHMyjCa|)*&698V%6aoMM diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/__pycache__/_compat.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/__pycache__/_compat.cpython-313.pyc index 9e5f483c554a26eb82ee85794912058684c1f20c..ddeb740429d222f81c60df34a2270c981c6fea6e 100644 GIT binary patch delta 66 zcmbOwJXe_OGcPX}0}%ZCwvlTto91Nw+`JO~6n)=d&-j3%{H)aEl4AX|%%b9w_~iV& VlEmWp+|2Z%#FYHaXW7m&0RZYr7&HI? delta 63 zcmbO$JWH7CGcPX}0}$js*~m4QO>KgHZeEFgioQ!xenC=xg}#4~qqC2zzHeoCeo?l5 RKv8~HYH~^O<_m0RnE-G06;J>G diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/__pycache__/config.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/__pycache__/config.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1d50f432141d72aaa1bb95b8133cbd066cee403b GIT binary patch literal 7579 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 XBacWuV>!l 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 diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/__pycache__/contracts.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/__pycache__/contracts.cpython-313.pyc index 0076f8ea06cb6b33a612eab6efb162a2c79793c5..2e8ea4348f99956453b4ee34384b06336ef3ea1f 100644 GIT binary patch delta 19 Zcmexq`qPx_GcPX}0}%ZCwvp?-6aYz32Q~lz delta 19 Zcmexq`qPx_GcPX}0}$js*~s-?3IIir29p2) diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/__pycache__/input_size.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/__pycache__/input_size.cpython-313.pyc index f8e3ae60bae24284f511da1a4a4c72abacb1e0ba..d149e1a8615d0ee908ab75bbb6c06aff1c62a9e5 100644 GIT binary patch delta 66 zcmaDZ{YskaGcPX}0}%ZCwvlTMi{>=_+`JO~6n)=d&-j3%{H)aEl4AX|%%b9w_~iV& UlEmWp+|2Z%#FYHacUZVN0T(nFKmY&$ delta 63 zcmaDQ{al*sGcPX}0}$js*~qnqMQyTvZeEFgioQ!xenC=xg}#4~qqC2zzHeoCeo?l5 RKv8~HYH~^O=KCz%oB*1n6D9{@vW2E+gW delta 19 ZcmaDZ`&^dmGcPX}0}$js*~oR54*)-?1|a|d diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/__pycache__/llm_client.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/__pycache__/llm_client.cpython-313.pyc index 001cf91808560432a5244f9266951d2c7e5a5626..d75d2edf8066f03abceb45caed9eb8c2e5179f18 100644 GIT binary patch delta 66 zcmdmFxz&>EGcPX}0}%ZCwvj80LvxybZeEFgioS2KXM8|WepYI7NwI!fW>IlTd~$wX UNn&w)Zf1H>VoLtzHVz#T0Q!a(ng9R* delta 63 zcmdmLxyh32GcPX}0}$js*~k^fp*C4RH?KrLMc<_;zaS~ULf=2g(b>mU-?uV6zbIQj RpeR2pHMyjCb0>$62mpVD6t(~W diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/__pycache__/llm_rails.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/__pycache__/llm_rails.cpython-313.pyc index 1be5ca8e99dd9dfa04d6b89275e501eed32a4a6a..13361936cb530e7898fd9d268c1123b208b79eaf 100644 GIT binary patch delta 66 zcmdnzdeD{YGcPX}0}%ZCwvo$-S#zp>ZeEFgioS2KXM8|WepYI7NwI!fW>IlTd~$wX UNn&w)Zf1H>VoLtzB<2`-0RCtfvH$=8 delta 63 zcmX@;y3dvCGcPX}0}$js*~n$YtTstMH?KrLMc<_;zaS~ULf=2g(b>mU-?uV6zbIQj RpeR2pHMyjCb1HL;JOG1L6wUwu diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/__pycache__/output_sanitization.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/__pycache__/output_sanitization.cpython-313.pyc index 29e50e62189a3601ea7c1c23cbb8e209be5d0b51..cff1ad31e6ef5c20edc5efb4d2cf90a5bc371b62 100644 GIT binary patch delta 19 ZcmaEs^DKw!GcPX}0}%ZCwvj8w3;;~%2L}KE delta 19 ZcmaEs^DKw!GcPX}0}$js*~k@R1^`JY24nyL diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/__pycache__/pipeline.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/__pycache__/pipeline.cpython-313.pyc index 765f02335dcd200f0c22a79d194265a9d9d65eae..6aef87ca030a9c9b3cc27c4f38ee18b1689ffa9f 100644 GIT binary patch delta 19 ZcmeyJ^gD^`GcPX}0}%ZCwvnsQ5CBfC2Q2^q delta 19 ZcmeyJ^gD^`GcPX}0}$js*~nFB2mng$28sXx diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/contestation_validation.py b/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/contestation_validation.py index dc3d302..58bdc74 100644 --- a/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/contestation_validation.py +++ b/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/contestation_validation.py @@ -129,6 +129,8 @@ def _is_vas_section_name(section_name: str) -> bool: or "servicos de valor adicionado" in normalized or "servicos valor adicionado" in normalized or "sva detalhe total" in normalized + or "servicos contratados de parceiros" in normalized + or "servico contratado de parceiro" in normalized ) @@ -185,13 +187,23 @@ def _extract_contestation_invoice_items( "validatedAmount", ) if candidate_name and candidate_amount is not None and candidate_amount > 0: + payload_type = str(payload.get("type") or payload.get("tipo") or "").strip() + payload_desc = str(payload.get("desc") or "").strip() + classe = str(payload.get("classe", "")).strip().lower() + is_vas = ( + _is_vas_section_name(section_name) + or _is_vas_section_name(payload_type) + or classe in {"avulso", "estrategico"} + ) found.append( { "name": candidate_name, "amount": _money(candidate_amount), - "is_vas": _is_vas_section_name(section_name), + "is_vas": is_vas, "section": section_name, - "classe": str(payload.get("classe", "")).strip().lower(), + "source_type": payload_type, + "source_desc": payload_desc, + "classe": classe, "estrategico": bool(payload.get("estrategico")), "verb": str(payload.get("verb", "")).strip().lower(), } @@ -397,14 +409,25 @@ def validate_contestation_items( "vas_estrategico": False, "status": "em_validacao", } - matched_candidate = next( - ( - candidate - for candidate in candidates - if _is_same_plan_name(candidate.get("name", ""), item_name) - ), - None, + matching_candidates = [ + candidate + for candidate in candidates + if _is_same_plan_name(candidate.get("name", ""), item_name) + ] + # A mesma cobrança pode aparecer em múltiplas visões da fatura. + # Prefira a evidência que traz classificação explícita de VAS em vez + # de aceitar a primeira ocorrência genérica e concluir incorretamente + # que o item está fora da seção VAS. + matching_candidates.sort( + key=lambda candidate: ( + 0 if ( + str(candidate.get("classe", "")).strip().lower() in {"avulso", "estrategico"} + or bool(candidate.get("is_vas")) + ) else 1, + 0 if _normalize_match_text(candidate.get("name", "")) == _normalize_match_text(item_name) else 1, + ) ) + matched_candidate = matching_candidates[0] if matching_candidates else None if matched_candidate is None: _record_failure( item_log, @@ -414,6 +437,9 @@ def validate_contestation_items( continue item_log["item_na_fatura"] = True item_log["item_confirmado"] = True + item_log["item_fatura_resolvido"] = str(matched_candidate.get("name", "") or "") + item_log["secao_fatura"] = str(matched_candidate.get("section", "") or "") + item_log["tipo_fatura"] = str(matched_candidate.get("source_type", "") or "") classe = str(matched_candidate.get("classe", "")).strip().lower() is_strategic = ( diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/prompts/__pycache__/__init__.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/prompts/__pycache__/__init__.cpython-313.pyc index 37db4aaa3ed4f9beea7d39cd02188ea9c2baf9d9..68e8eefa30c57b2534f37fec3cc47c34a107e1d5 100644 GIT binary patch delta 65 zcmaFH{F0gLGcPX}0}%ZCwvkJKQFD%dZeEFgioS2KXM8|WepYI7NwI!fW>IlTd~$wX TNn&w)Zf1H>VoLsG2gYRp)E5^> delta 62 zcmaFK{EV6FGcPX}0}$js*~lfps5VnSH?KrLMc<_;zaS~ULf=2g(b>mU-?uV6zbIQj QpeR2pHMyjCvNPi{09@M?WB>pF diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/prompts/__pycache__/_context.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/prompts/__pycache__/_context.cpython-313.pyc index 905bf3d8968e6e9790ca5dbe78f63cce930f30fa..3f7f8da5116d84a54fececd489f4dca5ed2de8de 100644 GIT binary patch delta 19 ZcmeCz>eu4>%*)Hg00jTOZRBDV1pqf01zi9D delta 19 ZcmeCz>eu4>%*)Hg00g;DHgd6w0su2v1iAnK diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/prompts/__pycache__/ausencia_oferta_proativa.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/prompts/__pycache__/ausencia_oferta_proativa.cpython-313.pyc index 592eec54492130923859c47d9d59daab4bb4ad20..3c8735dd361d60cc5068bf28a84bc5573c0d7daf 100644 GIT binary patch delta 66 zcmaFq^~Q_qGcPX}0}%ZCwvp?vvgR87+`JO~6n)=d&-j3%{H)aEl4AX|%%b9w_~iV& UlEmWp+|2Z%#FYHax+*q|07m;5!TCF23P<9 delta 19 Zcmdm@zeS(xGcPX}0}$js*~qm@8~{3l1+@SG diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/prompts/__pycache__/out_of_scope.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/prompts/__pycache__/out_of_scope.cpython-313.pyc index 4274e7e44e7ef2b70218d8cdbbe962ce7ce99dc7..27f4eadb3c08782fa51c38b59e3de09ca48822ab 100644 GIT binary patch delta 21 bcmX@z%6Ph!k?S)rFBbz4{QI_%>!1?=QCSCe delta 21 bcmX@z%6Ph!k?S)rFBbz4JM diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/prompts/__pycache__/pinj.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/prompts/__pycache__/pinj.cpython-313.pyc index 7c189e0375af5078cb6a281b5d6a13b137dd0132..c73d15905d589bae080ed279799084899100553e 100644 GIT binary patch delta 19 ZcmZp6Y1gh5Wce=Fc$hLEE-EDSI}7qi6Rt4*iuYrt?}O2*|4{J% zNlQZ!1&NABuy_f#ynrRY0JHw#N1SwfcQfD2eBaF6VrM5y`1+jNvmdo2`58YpSGs;# zM98OPklalunWXKS+;}3OzP=Z`D^z-t>?VWS!}|TCUGIgDY|UO;IsGc8*CLccYH&`C zm4w2QC{Q?@1OhX?0wHZF?C1==I=9hPphxL}gjQw}V1n!p!jeMcVR|+FVudOzntrcH zfiNHlU1gnz7|gXe!gxFoS$4d3bhEHv_F48E=ygDG(i=Q^dN}N#yb#Wo5zTzWUx}nO z%m%5OJrH(`#z9A%hEnO%6@iW@l#`@NWi|!}B*B%I%QGJrwJ>WakpUpUatopWyjKTBx7(Pbw5dlV` zX0^sIbysA)l~%`r8c+PN0-dy#Jy?&$u+C?Ley^LoZ-LhK0*h8xcnX-0K|Ab-mWB~( zHn#rEEAJn**h2`;n&>)wQ)%9+)mq5FWCSNBc*hNGeaNnpb~yaq+`$-!Hu!_;?d;AdC|wLUrr`=h zH@ILd>hAGznapdA{dC?;YT0ErPqw$y`K`U%jd`-S)mShf>9x~k2*v-4ZpLGak6H6k bX^WuoF*W&fnK1sI^Lm=5i`stLSYm$xGh0I1 literal 0 HcmV?d00001 diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/prompts/__pycache__/tox.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/prompts/__pycache__/tox.cpython-313.pyc index eb9a0aed4d2dad5fa3525d3c1d1a30cd1a6b26a8..0bc035c94b430c6348ad6618f533a4a5dffb6a20 100644 GIT binary patch delta 19 ZcmZo=ZDr;9%*)Hg00jTOZRDzE0st|f1!4dI delta 19 ZcmZo=ZDr;9%*)Hg00g;DHgZ)n0RS!F1it_P diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/prompts/__pycache__/toxicidade_output.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/prompts/__pycache__/toxicidade_output.cpython-313.pyc index 48bd0920e0fee0182c454c05d5bdf900d65dffee..22fd64c49f05ed98266bd3808eda913f077dcde1 100644 GIT binary patch delta 19 ZcmZ3@zM7ruGcPX}0}%ZCwvlTgGXOV<1=#=q delta 19 ZcmZ3@zM7ruGcPX}0}$js*~qn!82~fM1vUTx diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/prompts/shared/__pycache__/__init__.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/prompts/shared/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..eb1d9a31ca9add96051e751aa3941f59c3ad8a50 GIT binary patch literal 581 zcmZWny-ve05Kf?iDiZH-Bb89IBgBFjkSGH!1C!;(CN(&AI6L8IKs*GjNQeQ!$|K}0 zI>HMe`U0F&3Iiugx$k`b{M{GN*4C1U;vu!CH*pkw1h5FgZOpp#xsQesMtR&@sxD|_ z#}=hE(s=10qnx8xdcuWuAS9GXB@a~PkXIZ9a-|)N_6GeV*}W_+dJbc4Gipa!(NT5X zJl0YR$0TmEK1G2gupdgfRYO&sdKmHMv;Y!b75z!O!J6}_mhKO zJY8i>*o?84Xcm6Y^jNF0OLeRyf{;4=2`E} zq@ffkY>?O@*di(xZIM{kHn9WmvY~N<qcQ|AYHhP6=48?_yKOCPI7ZxfOY^TIIzl7F$xJ=EiImaX~WU zYCo3RSEkAX-^7APNru0PCiZYnY2O9ZB=)}}nWuP0 z`%)Xhca;X;xZ3CdQbn0gtVLvmD{w5Gn4*IG2|n6z?C^@y+~g`jPCRrx=BmnHy!gt5 zIlyu3P!R&XB<2r3`HVM{m_)Ku1duHW(xYQ6oml%(H{~Dbrxip>FF-<)9?^@cOGf)X z(n|5GS5ZdEli+=suTNkHNY2ArtMcS4Y_P8>xBm_A-{VQhMdJAY3wP~FR1lQ}h?7`A zy?K6!;sJD&`hi3QN#wg!Ge1akT)E53yq%`7eVOP$l^DqdH-4NP7ndgu@kZ$!nHcjv z91D)XgYk~(R4FDJK?0Imgm7R?O|uATM6>uQuQ_8SeS-E1}L&8mI#jBQ`8U2Zy^cB{7O)ao@%Cg%uO zGQW0QuGFRa-vcdW?BvJssw4W}!fta%`(2SHrU3D22NS%uwYFJvQqrfxE(6eTlxAFb zzKg0CLDl}Sm;y*mpjbs}Ci2#<2n;%15jgMqo{rHf?91+f93O@gw^lE9D1slhPi{P0DjHHz~8hiGLK(V0K&yhT0O9 zH6O^p-!T=@MMibtG?X`#e!pV0`>(l4+b|UuDX^oFi(cjULsBt&NH?!CZbP_#XWW-p zdmjuQ-%0$y>r5|?PU;1OGLN5m7sDYNuCSBkyN$cA4q5KyhBcgJS1iZ+c^+!pA~iFA zNXo)PISaYKGN;=5t3d&r)xjr3H(~6eW%maK>?o~w1QLt`ZJx5r`%3wV0SvZ^ktBpjz*Usxu9hc1ehYEHGKgz zU2-scDO6q($k+54sA%rYyn|twwJht8Ou@?iwZyFDVc{7o_v?w%!#v)&+sQM-8Iop6 nnj^_(kDVLNleECFZ;_-WR+#(q1WE5%Y~jLv`@+XFsq4Q1fb6hs literal 0 HcmV?d00001 diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/prompts/shared/__pycache__/tts_rules.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/prompts/shared/__pycache__/tts_rules.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bbf441d315485a760200227c7d048b2f5e84b671 GIT binary patch literal 1115 zcmZ`(&ud^v>6@>~j~XIAP635jl4q(DF=;88Vko47MB*DE*^gsT)6nM{p&gYLbg8ukOOnx literal 0 HcmV?d00001 diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/rails/__pycache__/__init__.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/rails/__pycache__/__init__.cpython-313.pyc index 2f1934b9be1c76007dfb1052e79086c44e8bed92..401d5550729549f169e3178a3290dbcf93f8d524 100644 GIT binary patch delta 19 ZcmbQtJDHd3GcPX}0}%ZCwvnro4FELA1)u-` delta 19 ZcmbQtJDHd3GcPX}0}$js*~rz&1^_V#1pNR2 diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/rails/__pycache__/alcada.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/rails/__pycache__/alcada.cpython-313.pyc index 5e3a91726edb9657892e9b8b8ed73d8c5c483767..d2b661521682a6acfc16a3b36bcc74a57157c802 100644 GIT binary patch delta 19 ZcmbQPK3$#bGcPX}0}%ZCwvnq>7yvlo1?>O; delta 19 ZcmbQPK3$#bGcPX}0}$js*~rx^3;;DD1xf$_ diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/rails/__pycache__/anatel.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/rails/__pycache__/anatel.cpython-313.pyc index 1f3bf04d64f7df2040efa2a7a57aaaa4512119d4..6a18f89abc16a42ce2c9fd974a3fc381d4486241 100644 GIT binary patch delta 19 ZcmX@(e#V{aGcPX}0}%ZCwvp?QG5|#n2HXGu delta 19 ZcmX@(e#V{aGcPX}0}$js*~oQB82~{~1~~u# diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/rails/__pycache__/confirmation.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/rails/__pycache__/confirmation.cpython-313.pyc index 3402eaee1032f64716620f113295a75f289bdb17..c26f95a4d602f9e08d9ed8f5517dcc5222c47f2a 100644 GIT binary patch delta 19 ZcmbOcHY1GdGcPX}0}%ZCwvmfZ8vs6C1?B(% delta 19 ZcmbOcHY1GdGcPX}0}$js*~rDG4FEcw1w#M; diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/rails/__pycache__/dlex_in.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/rails/__pycache__/dlex_in.cpython-313.pyc index 3cf3cf820efbbd054cfa7958be818db631076acf..8039453c61cb1f262d72c8f0446fa4a4dce981d4 100644 GIT binary patch delta 19 ZcmcaFd0&$2GcPX}0}%ZCwvp>94*)@~2BH7} delta 19 ZcmcaFd0&$2GcPX}0}$js*~oR32LL_p1^)m5 diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/rails/__pycache__/dlex_out.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/rails/__pycache__/dlex_out.cpython-313.pyc index a8f32591272b261ad5136e499e2da6336d2a8fab..1694530201f3c8726ba8c385ea5a331807e4354f 100644 GIT binary patch delta 19 ZcmbO%HCc-5GcPX}0}%ZCwvmgI7XUSh1wjA+ delta 19 ZcmbO%HCc-5GcPX}0}$js*~rDo3ji_61fBo@ diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/rails/__pycache__/ragsec.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/rails/__pycache__/ragsec.cpython-313.pyc index 4810ab0b4728909a0c3e0e35727949284fe2e092..76358fb3768b7541b24bf87808c77ba23bcc8f75 100644 GIT binary patch delta 19 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 literal 0 HcmV?d00001 diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/rails/supervision/__pycache__/groundedness.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/rails/supervision/__pycache__/groundedness.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ab54fd4bfb8f85f1a608aed5e1e4cdce8c09c277 GIT binary patch literal 8512 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 literal 0 HcmV?d00001 diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/rails/supervision/__pycache__/quantidade_coerente.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/rails/supervision/__pycache__/quantidade_coerente.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8a5d4ee38f97758807fd137121cb4161889dd620 GIT binary patch literal 8954 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 literal 0 HcmV?d00001 diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/rules/__pycache__/__init__.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/rules/__pycache__/__init__.cpython-313.pyc index 4a547bd2dca2b1c422dd3db3c8fb9b6df888dec5..3f3f905daa25b42028f47e0d9cfd7cdbabddcdd0 100644 GIT binary patch delta 19 ZcmZ3>IqAwxfCwr%W6&{k?oLkNMUP2*s@7m{i<-W@yBu6Nv- zT~mUQ3J0L4N{CA30zw?BR_cjA!T&%J2g)Al35i2!K)v#2y>Xp1X{9idcV=ha`@J{s zSb+2CkSb)AL$6)LI+R@2~^Tb`g!e~E_AHciSr4OSWFZL z)|8&kdr_$mPGXd&`v}4AVDEcpJ)T177+6wcOT_-o5nrg6+@@Y?n|cG=)Jt!!2fHtb zSUxFIC1Y`*lsWjk_zi9sAM`fQadvaWwT$F-k&gV@q5LYnRNDC(y4)v>JSq)+sEJH1 zVeSfcYY4sTa{G$Qq>mlyQ&DGL`@Zylzd3C&G^9Ics z#`{G2;|=03VdD7|BsiX(y?_gaQVtiX&xJ>DSp*c52K9*S1!W$+8no{>xy@zHmv~vTz)m6j9@q?70KPeCv^(8u}y`~bH*elfo$LNY>)we z>%_O0y0~-Pqj-#YHur2dkP-Hm-(c!B84;L7&YL;oPly>ZwJ<|GkNd=D+>>+5M{MHR z)Fon39?l(_7@IiR1b~(eJG{kN%cK5c1)kS@>YB^P8iH3`S|@S>Z(uO9a5#UAZTu$_)tFHrEtWWDqNVKF3*$;MQeVtT%In@m4X%obg=?gX$UHrqY~Dt z@g`^xhl>_L0VJcv09`;f;IJZy*S)6mZ-O&fDgyQSlu(*X5x(CDP>>h+X?V?tM^Nr&oIu@gh z#YYaX@CDGosHSD$xuB4v@qdwOx|s-?0Kcv!p@TT~pAi9t)1rXG6waW(U$%OazeM}}f9JRc$zU8A%hrYF$RIq!QH!c;`>{S-% zwNBGQV{*KdElNML}6~N5pn7XkUNwDgg5R(y0 zbrhBIKHMQ1U$o>^lBXp++&A_VA1p>HHGq=jy$Or>69~v&%Nm$fjcaouI)uo;mB=> zPE28nF?l}bg(!nZFb}Z9q#ej8@(u2`??>MOdaVIVoB0HoQN<=Ih}fUrqKIg^!~YI# z(kP1#gX@&%%!E+I93~|t!d?>n@M7v=pYknC!S_QotW^I(Fb*%etRnNI20mI{mfo1Ai`0FAoDf>EkS(h)$944N z5E>c#I`uHK>*kpoXKwHREi?LSX7u;rSN`sYgC|Kea&W8DgDXiiIJ62dD86WP!N`Ky zC)5W#Oh{jZNho&6>vE>TxrAQ}FF*FqekL z%m;IY;`G#HX*x{4S13=;&UT`@)3SO#RG_QE8(CM-#C0v}E)wdWj8K0I!-3Ov?m&>v zh*#lNv5*{v=So7;w8whC*7xrq()K+<>6H=GpZe?tk(^raG?9qy@ yr>8Z@OggjP?{q)-y`$^*#5#M!Srg!fAM8G`in5yi58k5FDu delta 19 ZcmbOwJ4=@9GcPX}0}$js*~m444*)be1v&r# diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/rules/__pycache__/tox_blocklist.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/rules/__pycache__/tox_blocklist.cpython-313.pyc index 940bc024c9782985c92c9da1aa95e1477ea60b38..4e1446acbdd12b42943479c0505b05848fc31112 100644 GIT binary patch delta 19 Zcmeyw{fV3FGcPX}0}%ZCwvp=vD*!^B2DktK delta 19 Zcmeyw{fV3FGcPX}0}$js*~s;R6#zcn1{DAR diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/rails.py b/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/rails.py index 810e694..87f4d73 100644 --- a/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/rails.py +++ b/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/rails.py @@ -328,47 +328,6 @@ class ProactiveOfferRail(Guardrail): ) -def _sanitize_low_risk_phraseology(text: str, reason: str) -> str | None: - """Remove apenas fechamentos/redirecionamentos de baixo risco. - - FRASEOLOGIA continua fail-closed para conteúdo material. Para B4 e ofertas - genéricas de continuação, porém, bloquear toda uma resposta grounded piora a - UX; nesses casos removemos somente a sentença ofensora. - """ - normalized_reason = (reason or "").casefold() - low_risk = any(token in normalized_reason for token in ( - "viola b4", "outro canal", "atendimento especializado", - "realizar alguma ação", "oferta de ação", "orienta o cliente", - )) - if not low_risk: - return None - - forbidden = ( - "entre em contato", "fale com um atendente", "procure uma loja", - "acesse o app", "acesse o site", "atendimento especializado", - "área de planos", "area de planos", "é só me avisar", - "e so me avisar", "realizar alguma ação", "realizar alguma acao", - "gerenciar esses serviços", "gerenciar esses servicos", - ) - sentences = re.split(r"(?<=[.!?])\s+", (text or "").strip()) - kept: list[str] = [] - removed = False - for sentence in sentences: - normalized = sentence.casefold() - proactive = ( - ("se quiser" in normalized or "caso queira" in normalized or "se desejar" in normalized) - and any(token in normalized for token in ("realizar", "gerenciar", "cancelar", "contratar", "alterar", "ação", "acao")) - ) - if proactive or any(token in normalized for token in forbidden): - removed = True - continue - kept.append(sentence.strip()) - sanitized = " ".join(x for x in kept if x).strip() - if removed and sanitized: - return sanitized - return None - - class PhraseologyRail(Guardrail): """FRASEOLOGIA calibrado: bloqueia fraseados proibidos do agente.""" code = "FRASEOLOGIA" @@ -380,26 +339,9 @@ class PhraseologyRail(Guardrail): _llm(ctx), "FRASEOLOGIA", {"text": text or "", "context": ctx}, profile_name="grl", component_name="guardrail.fraseologia", generation_name="guardrail.fraseologia", ) - allowed = bool(out.get("allowed", True)) - reason = str(out.get("reason") or out.get("label") or "FRASEOLOGIA avaliado") - if not allowed: - sanitized = _sanitize_low_risk_phraseology(text or "", reason) - if sanitized: - return RailDecision( - code=self.code, - allowed=True, - reason=f"FRASEOLOGIA sanitizada: {reason}", - sanitized_text=sanitized, - metadata={ - "mechanism": "llm_rail+deterministic_sanitize", - "data": out, - "calibrated": True, - "original_allowed": False, - }, - ) return RailDecision( - code=self.code, allowed=allowed, - reason=reason, + code=self.code, allowed=bool(out.get("allowed", True)), + reason=str(out.get("reason") or out.get("label") or "FRASEOLOGIA avaliado"), sanitized_text=text, metadata={"mechanism": "llm_rail", "data": out, "calibrated": True}, ) diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/identity/__pycache__/__init__.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/identity/__pycache__/__init__.cpython-313.pyc index aedbf7cd5610e09f8b1e17ff244883e8aa937cae..d5d9eca75463abadba4b7564acd49d164ebf7d62 100644 GIT binary patch delta 64 zcmZ3=yn>nQGcPX}0}%ZCHj(R@X1jiFUWtB+zHhK+d_YltR%&udv3^=+QE^Fpa(-S( SVsU(KW_nR#O8#Uq#(n_H7#Ae~ delta 61 zcmZ3%yp);iGcPX}0}$jqnaK4_twldKuS7pZ-=!$OASu5>-#^IF*~eAiw=z7xC|f_E PC_gJTxukfqBx64SQ}q-; diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/identity/__pycache__/mcp_mapper.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/identity/__pycache__/mcp_mapper.cpython-313.pyc index cd27ee8227824f85e2b0659cd9fa4719c20c752a..e7dc3ac3707bc2be4387918e51c4dd3cab307985 100644 GIT binary patch delta 66 zcmaE;@7NDGcPX}0}%ZCwvj7@S+iX~H?KrLMc+5rGd`dwKPxr4q*y;Kv#7WvJ~=?Od20s7* delta 19 Zcmeyx@{5J*GcPX}0}$jq*~nGE1OPr31)Bf> diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/judges/__pycache__/judge.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/judges/__pycache__/judge.cpython-313.pyc index 4e3cad467063b1f37bf0dab391904f6e3c2c038c..1bb78aa9a8aeb4126321a9f5c62fe188a66efb53 100644 GIT binary patch delta 21 bcmaDbhv~r_Ca%xCyj%=G@bBA3uCP7;S9k}p delta 21 bcmaDbhv~r_Ca%xCyj%=Gkn?0CS6CkaQ?dsQ diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/judges/calibrated/__pycache__/__init__.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/judges/calibrated/__pycache__/__init__.cpython-313.pyc index adef51837be53b426b95f4ce6516fe9b0ca31c17..23d17df5df010f0702915172c3ad2619eea17b47 100644 GIT binary patch delta 18 Ycmey!_>qz8GcPX}0}%ZCHj(Q&06HQDd;kCd delta 18 Ycmey!_>qz8GcPX}0}$jqnaK4V05<>y*Z=?k diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/judges/calibrated/__pycache__/_compat.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/judges/calibrated/__pycache__/_compat.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..24ca7be0c617a09a3e43dba7e5cd355bb3b598ca GIT binary patch literal 2207 zcma)7&2Jk;6rZ)%YkM6#DQ!`e0vXzd#%;7#DpjBg5K*wICdCbPZv<_}yJKh4-5oQt zn~#b^>4k`1I8dn)5+^SF8T<#8DxqklNELAD&0rxuPQ15v8k$}hY2Us#GjHa--}{(h zwQ3U>-!#usaTvqzfj%T{qDb3l=T?m6oXS!121@yr{IaP`ioCf}Shkb} ze7Rj|7? z#aq{IwA`he%@3QcTh|t^w^5OW9Xy6R_NA8%J4B!n@ld{KXyzrOPM3MHR6F#ugpXZk znNgr{s6S6bu0u)tOfj115#Xx~;FWZN&SfZr@4na+e!_&VXU9oAsFwg3KFhH8rI(ISr+s1QNo7YNOaNMQ=h}Z*rXkG38YESwwxIcq|WY z3II)S$DX@=cpzrM?fS@tkO5{2t#~P^z_*b*E&dVU8^xk0wPSyrFtkxx@E{ zfR`*l`@u@g!+8j#pivT12z$h7AUzh~EjHg~aTZ=q;erfI4Vxhdy1}#-5sMSWH2wMB zH-|Z-sRo3&j#YxI0Yb-ZgjvTT0$?{e1>!DOdL9p0??@;X;Q2Q9l9(x%0pPyK5|Z-Rt2_2HEZMq|R#+6t7z#p08btdr z6d;)x3;5SO38rkv05p~n%#?jVzze`x5b}%BjyG-r*$*llhcWB`eMr`bGN3i(+J?%{ zl6G#*Z0FCzO4|gkka3nOw2L5>#*&pu<*`)EBzr8C+7;M2kx5lm?pgJkGU2#quK`KT zj+8-KWI-UexS!?$q|^eOw2WGJZII~av<2ZzYnnl!18TmDzNMxoeV&#>?ybXu4)31y zg%^JU8uJt!{PaN2MAv^HbvrG&ZUkxIx~c8DS!N?Y;kp>5@yev@c7@V$AR-<~ScZxJ zK<>I~60BBJNRAt z<4I{|kDl8te|_ai>D=C17k16ZwX;8!E~shH%+B!);0^}94i_;EP5^Tj-WPnKHp#;R zB|Y+X9$o{ZmHAZ9r6%H)T6eaX>S>Ldl&aJ4Q-uRE3ydxSc}DJ$UrW`$HAeluRWh>XT{Fb)iFzg44y4gWxF4%=E$$+>Smj*t#5uCl7SyRC@9MD8!0+P{)}q zX}P)W@jg~nYLANt@yGW%tvs(Cu2m6dtazu7s^}cr4aqx>_6S+TAuYW-O0oCV9Egas zz5`^CHw@#q+>~MdafTRY2j+33wr@7~%?}21Wa8ALS0CH-i{f8{^Q3faNTzVHzHiR% zo6}DVwLf!K;o^V*8Rm&KImpB*Vx1V~j6x0PPW+DCUYj2JQd= delta 19 ZcmaE+|4g6jGcPX}0}$jq*~oQA8~{P-21)<` diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/judges/calibrated/__pycache__/models.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/judges/calibrated/__pycache__/models.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ca31105315949a3554b8916077b57ab539470557 GIT binary patch literal 880 zcmZWo&1(}u6rcUb<~#ALDyE0EP&6XVsg;5VVlQqm2lr@XnC?!}t()EYW|o@Zq0oap zdg;}>H~$qWNE|2#9;CNQ4qkn;NsHjXzWM#;&3p6SZ)RupdWGQl)Jb+^{~ap<&* zXPUJQRb@$%N+zQ;5p7eILnc`eGa*!A5b-#~E!NXy94vzK$(|Eqwu|7H^a&U~0n<0Y zTE(LJwr|}-k8dL?>a*@UItca1y-cHk46SRhjvPa0tq$XA%;p^Iv~R<_pZGildU ziPD6PIHjsW=_n1eSmPR{Z!;DzJWWam5eOMa2~SdVQwk020Gird(MDf8o`Gk= zH4T?275b6_%A|y7JCj^s)OGaD@FQvqWf2`VnvusglGdeHmmo!G0>TdjkwqX#E;Yr57;@?7qejw+TVHl@m B>+%2q literal 0 HcmV?d00001 diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/judges/calibrated/prompts/__pycache__/__init__.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/judges/calibrated/prompts/__pycache__/__init__.cpython-313.pyc index e9f611423e71640aec15c3f9e26cc1bb696f5746..ceebfe041734e45dc07e0a67418be705d33e4efd 100644 GIT binary patch delta 18 Ycmey#_>++?5-1z-RG diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/judges/calibrated/prompts/__pycache__/csi.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/judges/calibrated/prompts/__pycache__/csi.cpython-313.pyc index 1255fb1e5ec179af7fe9b3f9842980fc350ccacc..2558fb8e1e0a5d3ef64574aacdfef1b386cbde21 100644 GIT binary patch delta 19 ZcmdnWwUvwOGcPX}0}%ZCwvkJl6#zJG1%Chl delta 19 ZcmdnWwUvwOGcPX}0}$jq*~q2M3IH^x1ls@r diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/judges/calibrated/prompts/__pycache__/fallback.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/judges/calibrated/prompts/__pycache__/fallback.cpython-313.pyc index b9acc234a607c84b3e8f9fd114b65e4d01739bed..9d4070db146bd8fe13600fd17b9124bb02dc5256 100644 GIT binary patch delta 19 Zcmca>ch`>VGcPX}0}%ZCwvj7X9sosO26+Gg delta 19 Zcmca>ch`>VGcPX}0}$jq*~k?v4*)@#1=Rom diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/judges/calibrated/prompts/__pycache__/rqlt.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/judges/calibrated/prompts/__pycache__/rqlt.cpython-313.pyc index 98476253c4c89e1478fb2a383e24f1324c2a3fc3..4bd6ec7572f7054871b94b1ed2b3982d50b0015a 100644 GIT binary patch delta 19 ZcmbQtIhm8|GcPX}0}%ZCwvnro1pqWY1(pB+ delta 19 ZcmbQtIhm8|GcPX}0}$jq*~rz&0st_01o8j? diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/judges/calibrated/prompts/__pycache__/vctn.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/judges/calibrated/prompts/__pycache__/vctn.cpython-313.pyc index 6de755a3782e7233e8be867c6721c77ae7beef86..86e84c3c4c7755f64a48fa1177e55d18439bd2c9 100644 GIT binary patch delta 19 ZcmZo-ZDQs6%*)Hg00jTOZRDz80st{C1z7+9 delta 19 ZcmZo-ZDQs6%*)Hg00cQtHgZ)k0RSy%1hoJF diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/llm/__pycache__/__init__.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/llm/__pycache__/__init__.cpython-313.pyc index 680bdc2df37b82a7797de136a3d9ccfdbe05db16..0e67c293283afe19fbb2c0dd4b6bed3a47f73df6 100644 GIT binary patch delta 63 zcmaFB_?VIFGcPX}0}%ZCHj&Fjvq?WUuS7pZ-#6GZKAb>KSU)YZsJJ9PIX|x? Ru{b_AGrcG=C4XW{4FIpq7Z?Bl delta 60 zcmaFN_<)h?GcPX}0}$jqnaE|LR4Kv8~HYH~@jep+TxaY=k~ WeqKppaeQuOdQoCZ{^o+*3 diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/mcp/__pycache__/__init__.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/mcp/__pycache__/__init__.cpython-313.pyc index aad2b4beb6f794a260bc9c15e97be79f21fbf855..7abd6a959fe1b45b76c79c7ef33d4495d28ac82f 100644 GIT binary patch delta 65 zcmaFH{F0gLGcPX}0}%ZCwvkJlQL{-uH?KrLMc+5rGd`dwKPxr4q*y;Kv#7WvJ~=pF diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/mcp/__pycache__/client.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/mcp/__pycache__/client.cpython-313.pyc index 0231a98bf9b6d8781e9be21994745f9fef3938b9..758845179a5006f11e533eb0c558c82a3241e9df 100644 GIT binary patch delta 68 zcmZplz}Pi`k?S)rFBbz4{QI_%YZ0?%gMMyaiGGT{Z?I>4Kv8~HYH~@jep+TxaY=k~ WeqKppaeQuOdQoCZ{^m=}rY-;<6&R%e delta 65 zcmeC0z}P;4k?S)rFBbz4XgcqBRx3 diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/mcp/__pycache__/models.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/mcp/__pycache__/models.cpython-313.pyc index f0a67bc504c6db73385ec2f52c81b6479c115807..f028303a1516dd000b426ebaad6c669526b74a4b 100644 GIT binary patch delta 248 zcmZ24a72LbGcPX}0}!~xw`J+FZ{%}j5{l8!%`4GQNi0d!FV8Q^PRp#A+{Uz)@!7<; zN|VEwSIfn)D>1}y1anz376}G($FKy8s{;)PmM9WR=hc*)%*k?FoTDhUxFA2TIQ155 za$<5uYLN&~g{JW2k1P?4I+NwuB__wR@-a@IoWoivz{Q}Tx*_DEyj6ooN8V)?tI1DT z*D`8Pp2SumY6{diuwH=gGcPX}0}$jqX~|+>+sNn2WL&GCn^&TrqVH0aUyzhvq3<8$=pO~JSR}!C`pI4GtJUNwVE#rlWZ!viAk9V6AVLO2=)(xL$zklyjQW#jv3tma1yL2=;;_lhPbtkwwJWlk%*df3Ey`#y X!Sf3Pkouy>#%Mjk^D6_80-Fo~?BPXl diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/mcp/__pycache__/registry.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/mcp/__pycache__/registry.cpython-313.pyc index fe91e2736b90ee8302466e0fad140b525af20b82..2f4014bbee7cbcce7600415373156e336c8ef4d3 100644 GIT binary patch delta 353 zcmaE=(x=M%nU|M~0SH_|+Ol44_44O=Sn%tA`@|Fv6z^u8&nw*%Nk*X;$IfgHQ zsmN*aO1@&ogOg?X7s@H9EazRwdqY-ne$>pUkK#NsLf;s81cg6xGKfljP?~&|--ywB zGKYW;qt9eh0aZ3{pp8X7lM@6KVa#>`WeGQ+Xq7-tW^qY$aY<3ELXCo7KG35+lMe|L zGkQ)o6O2<3VHN(!03?c(K_-X+2~CzF0T3H%jKZH7fCN}602{Mg ANdN!< delta 314 zcmeBEeX7FynU|M~0SI!Qv}Enx$ScHTT(6&-SE8Sy?^2Xskd$Ac?;qso?BlBMTN$2T zl&v37l%JKFTvDu`n4X$f5}%x(SCUw~*`H}HCl?>k7-j|r#?N;qf8$PL+`c)MCyr4* zm{E_*lo4bF1A_vC?@k5=ZXg}XtiqtlNl~mqje=i(UMf)CYk^`$kIC_ZaSFn$!XFucM3FMc j1Ti3?$x;M1& delta 63 zcmbQJ+Na9(nU|M~0SI!QY~+e%Qft!B%`4GQ(RV4zFG$L-(Dx5=boO!8_pJ=iFUr;r RD9X=DO)e?kJb{T(003cR6bAqR diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/mcp/__pycache__/tool_router.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/mcp/__pycache__/tool_router.cpython-313.pyc index e17ae95489bf079d379e99233f81fc6b05fa92e8..8fe790a71038e422a5c9b163bfad15f5b731b71e 100644 GIT binary patch delta 66 zcmX?~dnuReGcPX}0}%ZCwvp=qmu9PeZeEFgioS2KXM8|WepYI7NwI!fW>IlTd~$wX UNn&w)Zf1H>VoLtz4_x=P0XP;J%>V!Z delta 63 zcmcbVdp?)zGcPX}0}$jq*~oQ(ORY&iH?KrLMc<_;zaS~ULf=2g(b>mU-?uV6zbIQj RpeR2pHMyjC^JlL6+5oxT7U%!~ diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/mcp/models.py b/agent_framework_oci/libs/agent_framework/src/agent_framework/mcp/models.py index 98f1529..97046c3 100644 --- a/agent_framework_oci/libs/agent_framework/src/agent_framework/mcp/models.py +++ b/agent_framework_oci/libs/agent_framework/src/agent_framework/mcp/models.py @@ -28,6 +28,11 @@ class MCPToolConfig(BaseModel): execution_policy: dict[str, Any] = Field(default_factory=dict) selection_keywords: list[str] = Field(default_factory=list) + # Política declarativa opcional de apresentação da resposta da tool. + # Para novos projetos prefira mode=renderer + renderer=. + # O framework resolve o nome no registry; a regra de negócio fica na aplicação. + response: dict[str, Any] = Field(default_factory=dict) + # Política declarativa de cache da tool, lida diretamente de config/tools.yaml. # Exemplo: # cache: diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/mcp/registry.py b/agent_framework_oci/libs/agent_framework/src/agent_framework/mcp/registry.py index 6ac4308..b37efc8 100644 --- a/agent_framework_oci/libs/agent_framework/src/agent_framework/mcp/registry.py +++ b/agent_framework_oci/libs/agent_framework/src/agent_framework/mcp/registry.py @@ -70,6 +70,7 @@ class MCPRegistry: "confirmation_required": tool.confirmation_required, "execution_policy": tool.execution_policy, "selection_keywords": tool.selection_keywords, + "response": tool.response, "cache": tool.cache, }) return out diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/memory/__pycache__/__init__.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/memory/__pycache__/__init__.cpython-313.pyc index 2e2302f422631658b75313f6feb1e601e9dbb659..fba6fecc6f532b0a00a6bc64b7b94ddae811b46e 100644 GIT binary patch delta 65 zcmeyv@t=e1GcPX}0}%ZCwvlTdvu3M)ZeEFgioS2KXM8|WepYI7NwI!fW>IlTd~$wX TNn&w)Zf1H>VoLtxbIj`i`ZgGk delta 62 zcmey*@rQ%!GcPX}0}$jq*~m4IS*=MwH?KrLMc<_;zaS~ULf=2g(b>mU-?uV6zbIQj QpeR2pHMyjC@PCjdb!2AKc= delta 19 ZcmaDT{7{(dGcPX}0}$jq*~oRB697GB1@!;` diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/memory/__pycache__/long_term_memory.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/memory/__pycache__/long_term_memory.cpython-313.pyc index 579d73a9f04687956bced4a850fc4aad7ed05d81..8e27b87b4d628f0dff11a2e0d45066e142f1cc61 100644 GIT binary patch delta 19 ZcmX?Zdfb%jGcPX}0}%ZCwvlVE6aYcw2A}`{ delta 19 ZcmX?Zdfb%jGcPX}0}$jq*~qn53IIMH1^fU2 diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/memory/__pycache__/long_term_models.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/memory/__pycache__/long_term_models.cpython-313.pyc index e18196faf404fdee0a42680d01fb61a30a580ff2..334f559c38f02153e352fa1cea485f30b79daa10 100644 GIT binary patch delta 19 ZcmaFD`-GS4GcPX}0}%ZCwvp==8vsDg29p2) delta 19 ZcmaFD`-GS4GcPX}0}$jq*~oQ^4FEj|1@8a= diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/memory/__pycache__/long_term_store.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/memory/__pycache__/long_term_store.cpython-313.pyc index d699e33e7d89641fc1acad4d05de69402a8516cc..d7f8b961716d7940898191504ef4d4a0df030212 100644 GIT binary patch delta 21 bcmbRAgmKanMy}7iyj%=G@bBA3E{-AqRU-#E delta 21 bcmbRAgmKanMy}7iyj%=Gkn?0C7e^5QQC$X= diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/memory/__pycache__/message_history.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/memory/__pycache__/message_history.cpython-313.pyc index 15c7fcab25336936f9eb6c359d4b315a913d95c4..739b11cf76b2290e92644277fc51c6512c0b9ba9 100644 GIT binary patch delta 66 zcmdnuxZRQKGcPX}0}%ZCwvp>Uqh^nOZeEFgioS2KXM8|WepYI7NwI!fW>IlTd~$wX UNn&w)Zf1H>VoLsIeWq49030M3OaK4? delta 63 zcmdn)xW$p{GcPX}0}$jq*~s;uQLR%yH?KrLMc<_;zaS~ULf=2g(b>mU-?uV6zbIQj RpeR2pHMyjCvk_CP8~~o)6=whd diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/memory/__pycache__/summary_memory.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/memory/__pycache__/summary_memory.cpython-313.pyc index 0e22a97ddc586d5365cb35746adf974cd77193d3..6f30a8a0f9ed682aeb95a14999a99d0cca3508ba 100644 GIT binary patch delta 73 zcmaEz_#%<(GcPX}0}%ZCwvp=?vq7tVZeEFgN@7W(eqwrRUP*j%eqKppaXgTnT9la_ aUzA#0ke^qa8ee7_U!Gr-y_uQig$@7=njBOB delta 75 zcmaEn_&Sm6GcPX}0}$jq*~oQ_*|mU-?uV6zbIQj dpeR2pHMyi%KQTQuuOvP>Kd&UQcoWMD9RTUp8%Y2F diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/memory/__pycache__/summary_store.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/memory/__pycache__/summary_store.cpython-313.pyc index 49ed10aab499074de9b8f25f8b98a4cb04b3c61e..5580736d20c5a0415cd3d161e7ef79c92052dff4 100644 GIT binary patch delta 73 zcmdn%wabg^GcPX}0}%ZCwvkJY$)H6)H?KrLC9xz?KQTQuuOvP>Kd&UQI3CDOEy_%e aFG?*g$j>WIjW08eFV8Q^-W<*JNC^PK0UKrj delta 76 zcmdnxwbzU5GcPX}0}$jq*~lfwWZbTwn^&TrqVH0aUyzhvq3<8$=pO~JSR}!C`pI4Gtyg7pDkrDv4<{Df8 diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/models/__pycache__/__init__.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/models/__pycache__/__init__.cpython-313.pyc index 468a8c224997aa810d40c77aa0740f719222b9a0..b6e6beb9f92ded6b7d24bed492199eb18ff55f2a 100644 GIT binary patch delta 70 zcmaFN_<)h?GcPX}0}%ZCHj&H3pk6;WuS7p3u_RGHF+DY}BtAJmuOzWJ9>`8D%1n+g XN-ZwP&nr%iFEfoV&o9cJSXcxAZ;Tpm delta 73 zcmaFB_?VIFGcPX}0}$jqnaE{g+@znISE8Sy?^2Xskd$Ac?;qso?BlBMTN$2Tl&v37 bl%JKFTvDu`n4X$f5}%x(SCUvfF|P;!Wh5D8 diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/models/__pycache__/identity.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/models/__pycache__/identity.cpython-313.pyc index a2de6710013adc1dc1edff9a2ea06617b4cf0e3e..1b50229a4123a52caeb0d5b78db7837cb4c4d816 100644 GIT binary patch delta 66 zcmbOxJyV+NGcPX}0}%ZGwvp=?qh_mqZeEFgioS2KXM8|WepYI7NwI!fW>IlTd~$wX UNn&w)Zf1H>VoLtzZ;T7L0r4LgQvd(} delta 63 zcmbO!Jx!YHGcPX}0}$jq*~oQ_QLRZoH?KrLMc<_;zaS~ULf=2g(b>mU-?uV6zbIQj RpeR2pHMyjC^H0VF+yHh96>R_j diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/models/__pycache__/session.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/models/__pycache__/session.cpython-313.pyc index 19e39b409c755bb32106525df08271d67ce9208b..134e279c26c497c573a4cd1471d75c244061f45a 100644 GIT binary patch delta 73 zcmZ1|I!~1AGcPX}0}%ZCwvmg4*`Q88H?KrLC9xz?KQTQuuOvP>Kd&UQI3CDOEy_%e aFG?*g$j>WIjW08eFV8Q^-t5SnzzzV6pc(G~ delta 76 zcmbOyx=@tsGcPX}0}$jq*~rDhY}}}yn^&TrqVH0aUyzhvq3<8$=pO~JSR}!C`pI4GtyxER9fgJ#TLKx)$ diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/observability/__pycache__/__init__.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/observability/__pycache__/__init__.cpython-313.pyc index 75e29dce17f0f0f484bc962bc6bb76aa1abfca6a..58b217750bbfba898a30df081672480452b1bb38 100644 GIT binary patch delta 65 zcmey*)x^#9nU|M~0SNwo+sGBgqS>RLn^&TrqVF5*86QxTpOu(+{^M609i5={Qv*} diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/observability/__pycache__/context.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/observability/__pycache__/context.cpython-313.pyc index 3c92f8d57b469ec75219da3dc29ebacfe45593a9..bd4ee00a8bb6114fa8a5f80ddfcdacbb49904ceb 100644 GIT binary patch delta 66 zcmaEE`O1>(GcPX}0}%ZGwvp=$n`XCuZeEFgioS2KXM8|WepYI7NwI!fW>IlTd~$wX UNn&w)Zf1H>VoLtzKWwi>0WCopq5uE@ delta 63 zcmaE5`P`E0GcPX}0}$jq*~oQmU-?uV6zbIQj RpeR2pHMyjC^MAJ2q5!W^7Q6re diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/observability/__pycache__/control_events.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/observability/__pycache__/control_events.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3e8308d771c937951fd4b546592cceeb4b01a72e GIT binary patch literal 2016 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 literal 0 HcmV?d00001 diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/observability/__pycache__/event_bus.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/observability/__pycache__/event_bus.cpython-313.pyc index bb7f2632ae1e3ef04806b5306a9f12face068486..e1b3cb813888993af431b53ddacf4f3968631c67 100644 GIT binary patch delta 66 zcmdlhb3lgcGcPX}0}%ZGwvp>6vu3Y;ZeEFgioS2KXM8|WepYI7NwI!fW>IlTd~$wX UNn&w)Zf1H>VoLsIO%@R@01V3)i2wiq delta 63 zcmX>gvsZ@eGcPX}0}$jq*~s;iS*=SyH?KrLMc<_;zaS~ULf=2g(b>mU-?uV6zbIQj RpeR2pHMyjCvkr?07XXj}6r%tD diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/observability/__pycache__/grl_events.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/observability/__pycache__/grl_events.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a7c7b45760b1a6fdf61a34661c19340c161d2a13 GIT binary patch literal 437 zcmey&%ge<81atNCv#tQ?#~=<2FhUuhHGqt%48aUV48e>=jKNGrOu@`W%)u;0EWxZr ztifzWY{BeB?78t42`3+aXKx5I$TcJ=5~9Y#(a*&{%r)p1 zH%N!SQ?P4LnCmTm5Xa5Y(lIYq;;_lhPbtkwwJYKS v8VU;6Vk02&ftit!@dl4*11E&wmuTQY=kkd+aNiJ;Zr}$>G;$X40JQ-Cj462Y literal 0 HcmV?d00001 diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/observability/__pycache__/guardrail_events.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/observability/__pycache__/guardrail_events.cpython-313.pyc index 36a06447c123824027d4b8d1fffd1accd1a7f596..a550677f1880474d3f7785455b8f3335259a1cdf 100644 GIT binary patch delta 66 zcmeAdm?XgUnU|M~0SNwo+sLKNs5wPHH?KrLMc+5rGd`dwKPxr4q*y;Kv#7WvJ~==jKNGrOu@`W%)u;0Ea|M8 zY*hlD&U%jSu6`l$!6A-8A+9b}LO>BuzYvg+i))ChGf0dNC>G-H?-TFr=;H(A3j+B; zj_&c!9-)5T@u9&`Z4iT;{e1&`fI40LG+A!}&5uVh{}#~vcr^2G0nLv`GXECP{CHIJ z!P?NwU&-(pPQiAk9`nI)C_ znR#jXMY)M3nfZB%Iq|7wK>fvf1(mlrY;yBcN^?@}ia_BD3dv$6An}2jk&*F+u<8W{ gfg7Tl7Z`+Y2r4%4-4Ic~z#s?|xX2(>!~s+W04UgX0RR91 literal 0 HcmV?d00001 diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/observability/__pycache__/judge_events.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/observability/__pycache__/judge_events.cpython-313.pyc index 4690c0cc6e0b4a2646b24b74efa4e010b07411b5..bec5fe8c28f4fa86770a2b2a24ecbf1e57b05f2e 100644 GIT binary patch delta 66 zcmeC@p2W@dnU|M~0SNwo+sGx#s5wDDH?KrLMc+5rGd`dwKPxr4q*y;Kv#7WvJ~=-< diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/observability/__pycache__/langfuse_enterprise.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/observability/__pycache__/langfuse_enterprise.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1a3b13ed3cc77c96be4b1070f965f2f12744ef7f GIT binary patch literal 3716 zcmcInO>Er86&`Yz@jvOK2pv>0+AE}(o1d|tAzud`rdH4k|n!o zie?sg^Ekh6-hAJCv+G@51p?*IWB$U$JRx7;M_RIpBCVeXXwy5rmS@)*0W+bQ@j7<`R!LS%WG<mPa-ML> zAYiP-GltBwMy8)|#mL_GQ%1D`vh`T4l82FV^AA^N#COE%;6+)1~s* z(&Na-GW-g}TCMqh7T_c9;egpEJs6ox_?T<;-@1 zkT27KEm9WLE%&0uVapH{7SO6sjb|ncb>{kX)4g7rXOFnupj_rnoc#=0Dc@5#qsKmFjoCWh;l z`lL+BAXr=@Co_YjCY7}5xF_L(S!r+%6fp%kIASqYgns#{6b1=#%wz&}Y|rNw0K4vU z3Yg!<$b=}fh+g)31t3-POPauKtX;GMD-1c`54-Sw+$#U<>lIeVAQr2xZ`+K=N|ntw z>{5<*;HYjCyHV^x(Su?yihU@+10+C~&{pA{@DX>41GEf|N78fbg!9&MxKr>K5LZc4 zC3?@bE7z{PQ)|j<-j+Ts?)zi-_LVoUL?b6wizio#C)f0zx4Yi#TGh)ddiihJ=#^@d zkY7s^GE{T2DMxzwE+O3)U8&RR2r?Hd6);H@W4Ddc7+ z%3I37sgcaBMrIMT~#wtTw?gSs~m6!A^g-1Uv9;2?peX1o=Oa>*0Gngk0%f z|6gM55sBq~UX`)}$g#3yxedmL!TaJ)VnqzTd^Ckfm1`7TZbf&zy;N{=9wGBDx~L{V?US;e}^M|hv^1F-h)%q!_o~R^btsH0--7x zCrUf?x0AsP#>#EQ$YAi_5&G5XxU0e$Jb}#Q<&$DlO+I-E*5N+{(LgN)!j5N>hmWkP z6V!e02SMe*of-u)n?Cb|7MJ+40?Za~9i8YPH#-I<4rgvYCV}L6Xf5p$T;C|bYm)wkPWv89 z64)4YCRt2qB9&n*PV$-1FivmmtvZ!(4rU*w@TPwyT?0e?hVH^675ma=$dhPFoPjou z%#M|s>sw($aIuldlt-YeHI|n_=fe3y6E`r9ZFuWkj4a@D5TA1J94wgTqF-&esCSy? zrH19UdWxo5b9fNCj>kM7x;4|R`W4gU_!QxXP>5(G?sBhb2Ka}iV&WsfnQw$FFwGl; z7jYaWZjKNa0+AimLHw3{C1;h~-GZbXg0x&d9-Wzu-1^$k$cNSF)%ms2@>fbhv8A=| z4K_1EIr4Z*d2TLIK0ol-zr>hkA9-Gylp>GcBRS=Q)a)Ts(ithb)VN19rROe+#2B=r zl*5zP8exOO$vI?85^MNIaXdR#!{s{E9B(bo+bofeUJKLY>& literal 0 HcmV?d00001 diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/observability/__pycache__/langgraph_telemetry.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/observability/__pycache__/langgraph_telemetry.cpython-313.pyc index 9e1f8eac83ad14d0fa1d4367ac34e8726bd14b67..70ae7b12d75721ea4832cfeea0fcf5ecfd3b4294 100644 GIT binary patch delta 65 zcmeyM_F0YVGcPX}0}%ZGwvo$$S#!F6ZeEFgioS2KXM8|WepYI7NwI!fW>IlTd~$wX TNn&w)Zf1H>VoLtv0%idK^FSAT delta 62 zcmeyY_Cby7GcPX}0}$jq*~sOmU-?uV6zbIQj QpeR2pHMyjCaWS(10D1}(mH+?% diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/observability/__pycache__/llm_advisors.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/observability/__pycache__/llm_advisors.cpython-313.pyc index 061ef4b430fc7ba3994c241909e88dbbf9f13dca..a52834f7e978ad60d59b3429632e04e04ad7fae3 100644 GIT binary patch delta 66 zcmZn@?-b|y%*)Hg00jTPZRA?as5wDDH?KrLMc+5rGd`dwKPxr4q*y;Kv#7WvJ~=IlTd~$wX UNn&w)Zf1H>VoLtzVx}BH00Qh6)&Kwi delta 63 zcmaE)eqWvIGcPX}0}$jq*~sP0q}HpSn^&TrqVH0aUyzhvq3<8$=g2A!Ttf5M8 zJ@Nn?d4Rr+kI`QH0#)+@tPSpkIgEb$&CI9S-PP9C22$~0#Fuv(LVvPD5v6BXbrswr zf&dW>G*W^R(LpC=D3c0Q3`EwxXs|Y`_SSz^y@7Sm?;jR$RKRfo?+SQdz=z(Ztla>! zSQt8IvL?6?K^$c`SIA~uVIu(+i75ov$x}_AiMiBS6i7W`Gg(z_QIgF}FIW`u+=<^R z&1MOg^}IahkU4w3s%)u6sXsC;Oo?xfd~D0TOme)j={hzwhYlTKG8}jW%T89YP2c=v z5=>pw$DZ~5Np(C+wKzmcK6TyCvYqvws$Q4kZx$Z<&cKt+TyzIt{|`5Et6X-lYm?t- zl|8q#!(bwed|P@BY|ekgaAgRXzR=={;Bd<(K^PIlTd~$wX UNn&w)Zf1H>VoLtz`^@)601fIG^Z)<= delta 63 zcmX?TxX+O5GcPX}0}$jq*~qn?S*=q)H?KrLMc<_;zaS~ULf=2g(b>mU-?uV6zbIQj RpeR2pHMyjC^CRZ_A^?$n77hRa diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/observability/__pycache__/observer.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/observability/__pycache__/observer.cpython-313.pyc index 2b6482edc44232cf69a0a997d159de42fd279bfe..66abde1d75c35d7877c1e341a7ade3b8802fd2a1 100644 GIT binary patch delta 66 zcmaE)@>GTEGcPX}0}%ZGwvj88S+hq!H?KrLMc+5rGd`dwKPxr4q*y;Kv#7WvJ~=IlTd~$wX UNn&w)Zf1H>VoLtz+ib0D01^2ZoB#j- delta 63 zcmaDX^+1a2GcPX}0}$jq*~qn;O|4ZwH?KrLMc<_;zaS~ULf=2g(b>mU-?uV6zbIQj RpeR2pHMyjC^F6j!HUO1b6}A8X diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/observability/__pycache__/streaming_events.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/observability/__pycache__/streaming_events.cpython-313.pyc index 5e0102f4f76b3d07c820b2ea2d47788ac7a62521..f096622b1a7fe6487c5784efebcbb681636465a4 100644 GIT binary patch delta 66 zcmdnaw~LSKGcPX}0}%ZGwvo$_QFDrZZeEFgioS2KXM8|WepYI7NwI!fW>IlTd~$wX UNn&w)Zf1H>VoLtzM8<2Z0NmU-?uV6zbIQj RpeR2pHMyjCa|+`%RsdzD6siCK diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/observability/__pycache__/streaming_exporter.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/observability/__pycache__/streaming_exporter.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5fcb1d7acb582b3595ccadde0211437632facf15 GIT binary patch literal 1295 zcma)5&1(}u6rb6TB>hTNXe$MAsYPAU#3H3Vs1Vy8+DZytb1A~GNhj&n&2D@%sn(My zNIi(B9tAzAH_!T4lpbmqdh*nZNOLIOe6yQ=3gWQ)c<;^o_`Q#5_4ITSJn!=1@=r?0 z4<#HNBVlOkCNk^9Ar74-GZd($cx_gj(LuM!c``&CeULcDsFrwuQ8Vq-t`ck-b-6(h zN>_SeAW+Oc;6AT&39C~pJdl;dC82G9+PaGJI(bNdIs`O_g6?Qws4QSQX~!5O%Lb$z z6VkPmorx~YO-wryxLfyv+EM(cjSwVY)7D3q@)dz5*@_`s#7BVphTNI zrjN@BKiXCutm-tb@)E{eq3e3l?8eMBk|9NNOs`U#7HtE%&?8E>n;sbfPAKZEhl|{2 zi_Ln&)}UKin90P{q%8}wN`)P(xW4~C9ZT%ge8qJnyV$eu*>i7$*TGhHcq2RfzVvb7 z!@`%ot&zgUNMUniVlz9rm6_bkO#T+V=)UciG8uhWbzh84y@<$(btQ6Iyl#0Onru9V=F zo01F0J`+&Wj%x=s{FtcJ;tY~kWZSs2r)lQ+eu|n?G%;3oMcY(>s!iDh1O#ft(Unts zn>(?i$@^gCrig1x(p^NqBM4FEc2eS97{UwnHibg}OQ)3Xkf9xNZ{JAKDY{1#jUE30 DoM1*| literal 0 HcmV?d00001 diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/observability/__pycache__/telemetry.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/observability/__pycache__/telemetry.cpython-313.pyc index 68cf9aab6fb8a56402d73ec704df1cded5dee8e6..5795c3fe7c4c9402379549586c78ae85d05b50f6 100644 GIT binary patch delta 68 zcmX>rFFLy+f(o7h z8VV3R02R*wPr#)Btwe#S=ps?kF=p~ZK}E?(p8Y(t=lkcP{oc`G3*BDigIlj!h4|Y1 zgO)O2eLrpq@kEdyYeSs3*qRVyf)bpd7H**=C#jWNDa9#DbDG+?jSlbuve~8#XQ-Xq zse?PHlRK%4yQrJHsfT;0mwPG8S?c3H>gRqs$Oq{VAEE&spg|s_As(V(9;OiC zF&?9F9;XSOpu>EaCV7&kc#5WZnr3*0W_gz8c#h_Io^qU{1zw;nq9c5SmU)@- zoTma8$YJNYoD{|Voo2-~5hn8bmlfwmgb2iyEgZt1C&{8dhi02M4{;+Q#O9C?SH-2o z=9mx}F`*p|!S0p{6NalI=YDIxpR?kO-)IDpAJu|Jct5>%c5S&(Z~zjZ04|^iI0{$+ z90RQGgHr&&?7-|m=s@V8+(EfSxkR}{xx~UGJQ5y>^+*UMgbG3hp@L9Bs324jD(qCj ztYB6!yD+;jyD+=jeBt70bG!!hl!4zpz$|cGr z$|cGr7AE15@JOsjLMS0r5Gn{2gbG3hp@L9hrwV2Tvx3=$*@fAK+12Le!T&m51A5B9 z?Ms%nF9cn;_8qlEzbm&$+DEaj;w!_HhDBP_@H{-PD`SrTz>CZLU@V6^r^P4Zk zm+Q4snD@6TjmWFA9^Vc4c0T0tUt>WjtngjGRIAsbd-+kH1hv^^h?TxTqpVn(<@YF!^O=n8?KLHSk B$EN@Q literal 0 HcmV?d00001 diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/observability/__pycache__/token_cost.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/observability/__pycache__/token_cost.cpython-313.pyc index a2024239ed2f3c73db998031c23c75a18aae59e4..da822db243ca3d4472d447851ff657501e921c96 100644 GIT binary patch delta 66 zcmZ4Jyu_L7GcPX}0}%ZGwvo%6Q?pM$H?KrLMc+5rGd`dwKPxr4q*y;Kv#7WvJ~=__BGcPX}0}%ZCHj&H3phZ77uS7p3u_RGHF+DY}BtAJmuOzWJ9>`8D%1n+g XN-ZwP&nr%iFEfoV&o9cJSXd4Kb3z(} delta 73 zcmaFL_=1t^GcPX}0}$jsnaE{g+^(OSSE8Sy?^2Xskd$Ac?;qso?BlBMTN$2Tl&v37 bl%JKFTvDu`n4X$f5}%x(SCUvfF|Ql|X+s%$ diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/persistence/__pycache__/mongodb_store.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/persistence/__pycache__/mongodb_store.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1f4357f02685267d61423287cc0d45a84d57d0f9 GIT binary patch literal 7621 zcmb_hZ){W9m4EmBv9JF<8z)YJfe?a2V&WvsOo1T-Lk*-fp#;doMJm%;#&&{3Vu$za zVPLh=ib|`nU1^}wXo9*cQthgferc<=ACS6QZ3b2v?WgDQtZd$P)Y;t+E53z4TEu?Y zo^#*xOPs&0+6O*4@7{CIyZ4@Re&@XVUif@&4z9l+C``Ho9QWUNQ@=!$AuqlI%txHU zDdY?{LR8X$Jb#8C;Z=S_Pz81`oDoMPRbsqÞlos5^xP?ai(dko!n(>wH!C*SlMIp2Z{MN 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 CxCO)j literal 0 HcmV?d00001 diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/persistence/__pycache__/oracle_store.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/persistence/__pycache__/oracle_store.cpython-313.pyc index 9bbbadada0bec3049d3943fc45091a6761e9c3ea..d2992682cd2b83259087f615fd9ae5d789664c00 100644 GIT binary patch delta 21 bcmZ2|pK0}dCa%xCyj%=G@c-LJu7&FXSKd&UQI3CDOEy_%e aFG?*g$j>WIjW08eFV8Q^-n@uW)Di&ZHXDin delta 76 zcmdl|y1kU^GcPX}0}$js*~pd3Xxy!zn^&TrqVH0aUyzhvq3<8$=pO~JSR}!C`pI4Gtym>yOs3id078-#7 diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/presentation/__init__.py b/agent_framework_oci/libs/agent_framework/src/agent_framework/presentation/__init__.py new file mode 100644 index 0000000..a96f24f --- /dev/null +++ b/agent_framework_oci/libs/agent_framework/src/agent_framework/presentation/__init__.py @@ -0,0 +1,15 @@ +from .renderers import ( + ToolResponseRenderer, + ToolResponseRendererRegistry, + register_tool_response_renderer, + render_tool_response, + tool_response_renderers, +) + +__all__ = [ + "ToolResponseRenderer", + "ToolResponseRendererRegistry", + "register_tool_response_renderer", + "render_tool_response", + "tool_response_renderers", +] diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/presentation/__pycache__/__init__.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/presentation/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c0db8033c914df779afabdd5b03df4e1a277161d GIT binary patch literal 465 zcmZutJx{|h5Vf5q0jf$26)Z?F(gnkgn3#fuM9Y3MiKz^!U7Zc6BTN4QKZ3vHm5B{e zAyzJs3h{Bn(|h;s*=H|$y){O44D+jsGxpSoWr>z7c8NT&5gYLnR&eBnKv5)^6dmjo zDW*G2l6S^28;e2mOy{sc8vEzY)kE#4&U!u6w$i9EZvEFC>ap-JzD?i^mXW0$BVy3ycDBWrWve;d+c`KLFfchW5?7-uDbu_gfQO=ofC laN??)S|4GL)@uIMZxFmBobz{)aq-3oUe~j(xX-am)(0-Rk;4E0 literal 0 HcmV?d00001 diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/presentation/__pycache__/renderers.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/presentation/__pycache__/renderers.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ea3f4c95d5f6a53e3eb6d3fe00e10ccbf7e631c8 GIT binary patch literal 4328 zcmb^!OKcm*b(XtJE|=s|BK7}RtB;-1b|j~+YB{N_*s+4bZk3iRCWhr=K~XD(_G*`% zUAdLugHEmjw^4#Xu#U;0D0J#FL zDRTU$DO#+H+!gMIX#Dv6aa>Dkaa=ZDv9sUr88{`h5oJMF!<0yap>?*E_T8Q02 z(0D2?2$`_gGHu&t)^JL20V8Wza|Si&GYQxgxXMWa^oWC!xI-LlkOi{EO>L2k=n0Nt z&U;Z8xad}X(eT35aF$Hh6CDuC009>a%hf?B!*tMWDmL$TBa4FXhb& zC8_K4Me4X_(K0Ms*J%s#Yt?nsIOs0#y0kdEa3zq!T0({*)T|xwoDCyrI$xNu9T;nlF{iVj*ynIeRf*w16J?As|6$IK#3${i&hW98q;# z8&;{dWiG4E^5U!wJZj5Tw3#!kUR!d&T8{I!Q!)z0`C>ta0~f(kMQcGdi}!&6oaO@K zW0!z&-mP5GpbjHf?=dXb;uC}-mW z9$c=<-Juw&o~WCcf;g(c$iW<-GB-juEm}nvT=Vps6b{i7EbGGk==-ar{NDJQ@cZO` zYu8twtOZKo&^w+-QZG zt#YW)v8yI9cjZWyJy}&+(1+k| zIli{LmylcUXHnw~?L8RhLD4gqOjy(4t_rzWyMe*oQcv2M6W)UL@bJN}`fRCS*M4%I z)XoLn%!gFc2e(1mINwL+xr{jFk(Iux*_pShi%X8H!mFgt8mh5aa+g;+YYP|+<}qjD zJGIhVBjrsDtL2)%8guWe87WA1@EFiy$&)|Mn@h$dr8f1XDhn?1mLI4gv6_ zo5nI*m=T%xc>;S~r0Q`rgRA&^#&Z2tsrY6P(+2%7zFA#%3K%&L0IZTDg(Op73_U)( zIq=BdQwDdG!CmF_8vlJVwV&$Q?!B^`n%Is{>?hkdrM+bTPO^VL)xF(wX*V^t9Um(v zn%8eXy8V5+Yt#9Y{f)ibH@e?;YPy%pojyeGbS5Y8Ya$vE^!6%L?bhnA5=);Q^8h<@lVC6E*I# zU`29~fKt!oxkxqdWNR6$&byZFq@46xo+LwLD>Ri6Sk=M`mY_hv{0#a<9oF@qi5^op zW~PP>6e~|pypMtH39j*5*Fnz!iv%r*Nho&k`Sb?gXqsTrk72v>F#xEvQlzEh@z|GR zo7ca(vL=;d>77_N*yA5f9p$#Za=NpeYA<&T9z?}vc};{OCEonmIMDYYibo%<>?Qkl zl6||${xzYTOs_xq!rhj-*?W@-)%|J;2AwE`fHl~b6!;c%K$I;gnOL?FW}(VuYv}|~ zK!eN;@o{6bE8QoFS1Inc;>T7qMY1EXUJOdZ6N<#(EaVS0W;d?vK>$w(p_sP3h_27s z1t{~*;M9*0F!PNg)`y^>{_Dp%1Xv0=s{kI7gODIfNAZx@3;OQtJ%}a6^G}s#UxXgY z!t`5y1TmSU+I*yeo@M2E0uyXd3 zh&5pu*$h}vM&gyGDW;@a;)77ACq7ICkoW)w?W8CE7MFuBpUXTxZy87>$PGT9+FkrM zsTOj_N*q)d_&c*9vosp{m3-pC%ZR0;LG_cF&<|nDFL4_h6CRK_5qtK8p&eo9>**(- zYzsqw7bcm6wQ3DBg9Lw;8G>r<&0^(94g|w&0K$nwguV;A!DlC-qiASImrRBeqO2#)VwtiOFQ>Z8$=0%xF1LU=N&Ku&!tpQwG0X&; zqVK~ldJRBE!LOG2CHSs^uNI1#*-OGFt7#P22kvlwwm?yS_+Df+I26A@p&53UOE|!X zhGO0fqKmJ>dY$Wvv&7ZCx!R#HAAf@6o} z=P@>$Qn+wgZt;2OAyk^uegrXzB)a`5Vls($`7y-eB-QFC5K~CF>3I?`roaCHZ^@xD literal 0 HcmV?d00001 diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/presentation/renderers.py b/agent_framework_oci/libs/agent_framework/src/agent_framework/presentation/renderers.py new file mode 100644 index 0000000..528359a --- /dev/null +++ b/agent_framework_oci/libs/agent_framework/src/agent_framework/presentation/renderers.py @@ -0,0 +1,104 @@ +from __future__ import annotations + +from collections.abc import Callable +from threading import RLock +from typing import Any, Protocol + + +class ToolResponseRenderer(Protocol): + def __call__( + self, + *, + tool_name: str, + result: dict[str, Any], + state: dict[str, Any], + agent_label: str, + ) -> str | None: ... + + +class ToolResponseRendererRegistry: + """Thread-safe registry for application/domain response renderers. + + The framework stores only symbolic renderer names. Business-specific + formatting lives in the application that registers the renderer. + """ + + def __init__(self) -> None: + self._renderers: dict[str, ToolResponseRenderer] = {} + self._lock = RLock() + + def register( + self, + name: str, + renderer: ToolResponseRenderer, + *, + replace: bool = True, + ) -> None: + key = str(name or "").strip() + if not key: + raise ValueError("renderer name must not be empty") + if not callable(renderer): + raise TypeError("renderer must be callable") + with self._lock: + if not replace and key in self._renderers: + raise KeyError(f"renderer already registered: {key}") + self._renderers[key] = renderer + + def get(self, name: str | None) -> ToolResponseRenderer | None: + key = str(name or "").strip() + if not key: + return None + with self._lock: + return self._renderers.get(key) + + def render( + self, + name: str | None, + *, + tool_name: str, + result: dict[str, Any], + state: dict[str, Any], + agent_label: str, + ) -> str | None: + renderer = self.get(name) + if renderer is None: + return None + value = renderer( + tool_name=tool_name, + result=result, + state=state, + agent_label=agent_label, + ) + if value is None: + return None + text = str(value).strip() + return text or None + + +tool_response_renderers = ToolResponseRendererRegistry() + + +def register_tool_response_renderer( + name: str, + renderer: ToolResponseRenderer, + *, + replace: bool = True, +) -> None: + tool_response_renderers.register(name, renderer, replace=replace) + + +def render_tool_response( + name: str | None, + *, + tool_name: str, + result: dict[str, Any], + state: dict[str, Any], + agent_label: str, +) -> str | None: + return tool_response_renderers.render( + name, + tool_name=tool_name, + result=result, + state=state, + agent_label=agent_label, + ) diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/rag/__pycache__/__init__.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/rag/__pycache__/__init__.cpython-313.pyc index 94023bb78444013dd8bb145b697d1a2c607645e3..7c9bf3f93e44ed77a08112138da57e4c8ca7b2d9 100644 GIT binary patch delta 19 Zcmcc0dX<&yGcPX}0}%ZGwvp>J697Gi22%h4 delta 19 Zcmcc0dX<&yGcPX}0}$js*~oR82>?031+M@A diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/rag/__pycache__/embedding_provider.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/rag/__pycache__/embedding_provider.cpython-313.pyc index fc5aed89f8d7c0049847aa5a46d82c04793ec637..47239beda4220e52b80f7eccfa9956b1d3255033 100644 GIT binary patch delta 19 ZcmeA(?lb24%*)Hg00jTPZRBc^1OPcN1@Qm? delta 19 ZcmeA(?lb24%*)Hg00g;DHgdH{0su8>1x)|| diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/rag/__pycache__/graph_store.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/rag/__pycache__/graph_store.cpython-313.pyc index d2e385b8d0609496fb541c915d75231db26d2a3e..25ef9ea09e89ce6e3dfcfb538ffd51c02c77c404 100644 GIT binary patch delta 19 ZcmZ3kyb>KSU)YZsJJ9PIX|x? Ru{b_AGrcG=C4XW{D*(0c7d-#~ delta 60 zcmaFE_>z(9GcPX}0}$jsnaE|L)}f!9SE8Sy?^2Xskd$Ac?;qso?BlBMTN$2Tl&v37 Ol%JKFTv9wSy%hjLEEHG( diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/repositories/__pycache__/session_repository.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/repositories/__pycache__/session_repository.cpython-313.pyc index 7804b80e07de9c5f2e86330003fab11d2c7a0880..4d042e31c102bbb5c33b75ca778315a67f888a2e 100644 GIT binary patch delta 66 zcmbQ`JlC1)GcPX}0}%ZGwvkJYNpq@xZeEFgioS2KXM8|WepYI7NwI!fW>IlTd~$wX UNn&w)Zf1H>VoLsIKPDe}0OsBoEdT%j delta 63 zcmbR1JjmU-?uV6zbIQj RpeR2pHMyjCb0CwCJOFID6i5I7 diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/routing/__pycache__/__init__.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/routing/__pycache__/__init__.cpython-313.pyc index 25cb799287e2d0638b4dd4f5c516f4d3f22509d6..6a14a96f00acdfbb73e395bdee5f418d2a887513 100644 GIT binary patch delta 41 vcmdnVJe8U2GcPX}0}%ZCHj(R_P?CObUWtB6Vo9QYd45rLT4u#$Gsb2B8Fvmm delta 77 zcmbQrypx&hGcPX}0}$jsnaK6ctW7^RuS7pZ-#6GZKAb>KSU)YZsJJ9PIX|x? Zu{b_AGrcG=C0{==Jv9#|I9Z6X836pu8?*ob diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/routing/__pycache__/config_loader.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/routing/__pycache__/config_loader.cpython-313.pyc index 66b593c4d945298153cf4b435e7c7717868d12a9..883a239b5b93e182f55edad8e70b0991c09ac4f4 100644 GIT binary patch delta 43 xcmeAWdLqd6nU|M~0SNwm+sHM6Q7BzMH?KrLC9xz?zdXMvJ1w(f^94o=b^tQz4y^zH delta 79 zcmaDN*dfIAnU|M~0SI!RY~-52Xx6Qtn^&TrqVF5*86QxTpOuz9^mRGcPX}0}%ZCwvj7>Nhn1>H?KrLC9xz?zdXMvJ1w(f^9&|ELjXsB4+8)I delta 79 zcmZ3Kek`5qGcPX}0}$js*~k^aWY(ddn^&TrqVF5*86QxTpOuD-E5PXk8RV0rmeQwbYo&`TWZDX!MY2TNI~$leiSsA&<}}T zQt?m`dQb*Dc@xCyMVYJMA%~{PB6tu#z>B>o2-ezOi!*P&On7q*H5F=`@A-mJ=$BwOzJ$$+&SC z>`B~ElblVkr*I>iXS|sN2jR_BALFJJc6_KA2S>n7BgQ!o4#v%b#Chx_^Rz5*3b>W? za~=n-lWm;>9_Jz6cml8m54Y8)I62YNBTh#21|)u)k@zHsoe^4#E(makZpUW?xKAg# z$3%EWmy#~PWBMtzBEu^>H@GLjcWRp*;M-#VvSg8qW`f+y{)S(~Hq-Rc@Dl<4(5~Y@ t1lXth1tLUenQs;S6%d6_Cx+nR)EQ?(6N=%R%Qttkb;MNE@eT1Y~ZPx9X53o;O*@wZTv}NVxkIG6ak4Bj$&AG&DB#p?1-QmxE*Qw6m1$&P)%GT zHcENd2dahJ^#^sH1Xbd8lX1#>G$V6+vD1{BPKWA3&9k7|xaP2ja*F}g!L?XkXX7}{ zw5~vkswnIlAgHrx2@!TAiiK0;0d`CsvBXO{2ltkz*lUI3}W}_59qu-CjtB<*2p^s4#~&Z vHwI3~)_Kf$=ILMEN52>|Z#?$6dGm363V6@qG`W@tgSF0rbcA%RjL_gemUW~Y diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/routing/__pycache__/models.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/routing/__pycache__/models.cpython-313.pyc index 9e388b37ce45564cfa6f0f10d77576626730c04f..4068e3d9a84dbbd3adb9aa83de41164e6095e1ac 100644 GIT binary patch delta 43 xcmbOy{7Z=IGcPX}0}%ZCwvkJnStvn2H?KrLC9xz?zdXMvJ1w(fb2_s*8vrf24g>%I delta 79 zcmew*G*6i8GcPX}0}$js*~q2NY}TTmn^&TrqVF5*86QxTpOub>KSU)YZsJJ9PIX|x? Yu{b_AGrcG=C0{==Jv9#|IPpat0Qj05y8r+H diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/runtime/__pycache__/agent_runtime.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/runtime/__pycache__/agent_runtime.cpython-313.pyc index 9320eaad68fb435f0a12ac7635a1af299c1da314..cfe0d87b83839abec9025443772296236a1d9f42 100644 GIT binary patch delta 36832 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 MW dict[str, Any]: + """Remove valores herdados para campos cujo contrato diz ``from: message``. + + Em uma NOVA transação, ``context.tool_arguments`` pode ainda carregar + parâmetros de uma operação anterior. Campos declarados pelo mapper como + extraídos da mensagem corrente não podem nascer desse contexto antigo. + Valores explicitamente extraídos deterministicamente do turno atual são + preservados. Durante coleta incremental este helper não é usado. + """ + router = getattr(self, "tool_router", None) + if not router or not hasattr(router, "parameter_extract_rules"): + return dict(arguments or {}) + rules = router.parameter_extract_rules(tool_name) or {} + explicit = {str(name) for name in explicit_fields} + cleaned = dict(arguments or {}) + for field_name, rule in rules.items(): + if ( + str(rule.get("from") or "message").lower() == "message" + and str(field_name) not in explicit + ): + cleaned.pop(str(field_name), None) + return cleaned + async def _extract_mcp_parameters( self, tool_name: str, arguments: dict[str, Any], state: dict[str, Any], + *, + overwrite_from_message: bool = False, ) -> dict[str, Any]: """Executa regras ``extract`` declaradas para a tool escolhida. @@ -544,9 +591,13 @@ class AgentRuntimeMixin: llm = getattr(self, "llm", None) for field_name, rule in rules.items(): - if resolved.get(field_name) not in _EMPTY_VALUES: + from_message = str(rule.get("from") or "message").lower() == "message" + if not from_message: continue - if str(rule.get("from") or "message").lower() != "message": + # Em uma nova transação, a mensagem atual prevalece para campos + # declarados como ``from: message``. Durante COLLECTING_PARAMETERS + # o default permanece False para congelar valores já coletados. + if resolved.get(field_name) not in _EMPTY_VALUES and not overwrite_from_message: continue strategy = str(rule.get("strategy") or "llm").lower() value: Any = None @@ -1167,19 +1218,13 @@ class AgentRuntimeMixin: return None def _select_transactional_tool(self, tools: list[str], text: str) -> str | None: - """Seleciona a ação transacional da intent atual. - - O match por ``selection_keywords`` continua tendo precedência. Porém, depois - que o EnterpriseRouter já restringiu ``tools`` às capabilities da intent, - uma única tool transacional é uma escolha determinística e segura. Isso - evita perder frases naturais como ``quero cancelar TIM Fashion Mensal`` ou - ``não contratei esse serviço`` só porque elas não repetem literalmente uma - keyword de ``tools.yaml``. - """ matched = self._transactional_action_match(text, tools) if matched: return matched + # Generic fallback: once routing has constrained the allowlist, a single + # transactional capability is unambiguous even when the user's wording + # does not contain one of the tool-specific selection keywords. transactional = [ tool for tool in tools @@ -1348,12 +1393,112 @@ class AgentRuntimeMixin: state["transaction_status"] = "COMPLETED" if result.get("ok") else "FAILED" return result + @staticmethod + def _transaction_is_active(state: dict[str, Any]) -> bool: + return str(state.get("transaction_status") or "") in _ACTIVE_TRANSACTION_STATUSES + + @staticmethod + def _transaction_is_terminal(state: dict[str, Any]) -> bool: + return str(state.get("transaction_status") or "") in _TERMINAL_TRANSACTION_STATUSES + + def _active_transaction(self, state: dict[str, Any]) -> dict[str, Any] | None: + """Return only the operationally active transaction. + + Closed transactions are history and must never provide tool/arguments for + a later turn. For backward compatibility, an old checkpoint that has the + legacy selected/pending fields but an ACTIVE status is lazily hydrated into + ``active_transaction``. + """ + if not self._transaction_is_active(state): + return None + current = state.get("active_transaction") + if isinstance(current, dict) and current.get("tool_name"): + return current + legacy = state.get("pending_tool_call") or state.get("selected_tool_call") or {} + if not isinstance(legacy, dict) or not legacy.get("tool_name"): + return None + current = { + "transaction_id": str(uuid.uuid4()), + "tool_name": legacy.get("tool_name"), + "arguments": dict(legacy.get("arguments") or {}), + "status": state.get("transaction_status"), + "started_from_intent": state.get("intent"), + } + state["active_transaction"] = current + return current + + def _set_active_transaction( + self, + state: dict[str, Any], + *, + tool_name: str, + arguments: dict[str, Any], + status: str, + transaction_id: str | None = None, + ) -> dict[str, Any]: + current = state.get("active_transaction") if isinstance(state.get("active_transaction"), dict) else {} + txid = transaction_id or current.get("transaction_id") or str(uuid.uuid4()) + tx = { + "transaction_id": txid, + "tool_name": tool_name, + "arguments": dict(arguments or {}), + "status": status, + "started_from_intent": current.get("started_from_intent") or state.get("intent"), + } + state["active_transaction"] = tx + return tx + + def _finish_active_transaction(self, state: dict[str, Any], status: str) -> None: + """Close the active transaction without leaving operational state behind.""" + active = self._active_transaction(state) + if isinstance(active, dict): + state["last_transaction"] = { + **active, + "status": status, + } + state["active_transaction"] = None + state["selected_tool_call"] = {} + state["pending_tool_call"] = {} + state["missing_parameters"] = [] + state["confirmation_required"] = False + state["confirmation_received"] = status == "COMPLETED" + state["next_state"] = None + state["transaction_status"] = status + + def _normalize_transaction_lifecycle(self, state: dict[str, Any]) -> None: + """Ensure closed transactions cannot leak into a later user turn.""" + if self._transaction_is_terminal(state): + # Preserve a compact audit snapshot, but remove every operational latch. + active = state.get("active_transaction") + if not isinstance(active, dict): + legacy = state.get("pending_tool_call") or state.get("selected_tool_call") + if isinstance(legacy, dict) and legacy.get("tool_name"): + active = { + "transaction_id": str(uuid.uuid4()), + "tool_name": legacy.get("tool_name"), + "arguments": dict(legacy.get("arguments") or {}), + "status": state.get("transaction_status"), + "started_from_intent": state.get("intent"), + } + if isinstance(active, dict): + state["last_transaction"] = {**active, "status": state.get("transaction_status")} + state["active_transaction"] = None + state["selected_tool_call"] = {} + state["pending_tool_call"] = {} + state["missing_parameters"] = [] + state["confirmation_required"] = False + state["confirmation_received"] = False + state["next_state"] = None + return + if self._transaction_is_active(state): + self._active_transaction(state) + def transaction_state_patch(self, state: dict[str, Any]) -> dict[str, Any]: keys = ( "available_mcp_tools", "selected_tool_call", "pending_tool_call", "transaction_status", "confirmation_required", "confirmation_received", "tool_policy_result", "missing_parameters", "next_state", "pending_domain_workflow", "pending_tool_clarification", - "business_workflows_executed", + "business_workflows_executed", "active_transaction", "last_transaction", ) return {key: state.get(key) for key in keys if key in state} @@ -1411,6 +1556,9 @@ class AgentRuntimeMixin: "next_state": collecting_state, "tool_policy_result": {**policy, "tool_name": tool_name, "action": "collecting_parameters"}, }) + self._set_active_transaction( + state, tool_name=tool_name, arguments=arguments, status="COLLECTING_PARAMETERS" + ) def transaction_confirmation_message(self, state: dict[str, Any]) -> str | None: if state.get("transaction_status") != "AWAITING_CONFIRMATION": @@ -1446,6 +1594,185 @@ class AgentRuntimeMixin: matches.append(name) return matches or available_tools[:1] + @staticmethod + def _response_path_get(data: Any, path: str | None) -> Any: + """Resolve caminho simples ``a.b.c`` em dicts sem conhecer o domínio.""" + if not path: + return data + current = data + for part in str(path).split("."): + if isinstance(current, Mapping): + current = current.get(part) + else: + return None + return current + + @staticmethod + def _response_format_value(value: Any, formatter: str | None) -> Any: + """Formatadores genéricos permitidos pela política declarativa de resposta.""" + if formatter in (None, "", "raw"): + return value + if formatter == "decimal_2_comma": + try: + return f"{float(value):.2f}".replace(".", ",") + except (TypeError, ValueError): + return value + if formatter == "decimal_2": + try: + return f"{float(value):.2f}" + except (TypeError, ValueError): + return value + if formatter == "str": + return "" if value is None else str(value) + return value + + @classmethod + def _response_template(cls, template: str, data: Mapping[str, Any], formats: Mapping[str, Any] | None = None) -> str | None: + """Renderiza template somente se todos os placeholders existirem. + + Isso evita respostas como ``None`` quando o contrato da tool não corresponde + à configuração. Nesse caso o runtime cai no fallback legado/LLM. + """ + formats = formats or {} + names = set(re.findall(r"\{([A-Za-z_][A-Za-z0-9_]*)\}", str(template))) + values: dict[str, Any] = {} + for name in names: + if name not in data or data.get(name) is None: + return None + values[name] = cls._response_format_value(data.get(name), formats.get(name)) + try: + return str(template).format(**values) + except Exception: + return None + + def _render_declared_tool_response(self, tool_name: str | None, data: dict[str, Any], *, agent_label: str, state: dict[str, Any] | None = None) -> str | None: + """Renderiza resposta MCP por configuração, sem regras de negócio no core. + + A configuração vive em ``tools.yaml`` e suporta primitives genéricas: + ``template``, ``list`` e ``lines``. Se não houver política, retorna ``None`` + para preservar integralmente o comportamento legado. + """ + router = getattr(self, "tool_router", None) + registry = getattr(router, "registry", None) + cfg = registry.get_tool(str(tool_name)) if registry and tool_name else None + policy = dict(getattr(cfg, "response", None) or {}) if cfg else {} + if not policy: + return None + + mode = str(policy.get("mode") or "").strip().lower() + + # Extensão preferencial: o core conhece apenas um nome simbólico. + # O código do renderer é registrado pela aplicação/domínio. + if mode == "renderer": + renderer_name = str(policy.get("renderer") or "").strip() + if not renderer_name: + return None + try: + from agent_framework.presentation import render_tool_response + + return render_tool_response( + renderer_name, + tool_name=str(tool_name or ""), + result=data, + state=state or {}, + agent_label=agent_label, + ) + except Exception: + # Compatibilidade/fail-open: renderer ausente ou com erro não quebra + # agentes legados; o fluxo continua para o fallback existente. + return None + + # Modos declarativos da versão anterior são preservados apenas por + # compatibilidade. Novos projetos devem usar mode=renderer. + base: dict[str, Any] = {**data, "agent_label": agent_label, "result": data} + + if mode == "template": + template = policy.get("template") + if not template: + return None + # ``result`` pode ser usado para debug/compatibilidade; demais campos + # precisam existir para impedir None em texto de cliente. + if "{result}" in str(template): + try: + return str(template).replace("{result}", str(data)).replace("{agent_label}", agent_label) + except Exception: + return None + return self._response_template(str(template), base, policy.get("formats")) + + if mode == "list": + items = self._response_path_get(data, policy.get("source")) + if not isinstance(items, list) or not items: + return str(policy.get("empty_message") or "").strip() or None + rendered_items: list[str] = [] + item_template = str(policy.get("item_template") or "{item}") + item_formats = policy.get("item_formats") or {} + for raw in items: + if isinstance(raw, Mapping): + item_data = dict(raw) + else: + item_data = {"item": raw} + item_data["agent_label"] = agent_label + line = self._response_template(item_template, item_data, item_formats) + if line: + rendered_items.append(line) + if not rendered_items: + return None + count = len(rendered_items) + heading_template = policy.get("heading_singular") if count == 1 else policy.get("heading_plural") + heading = None + if heading_template: + heading = self._response_template( + str(heading_template), + {"agent_label": agent_label, "count": count}, + ) + sep = str(policy.get("separator") or "\n") + body = sep.join(rendered_items) + return f"{heading}\n{body}" if heading else body + + if mode == "lines": + lines: list[str] = [] + for spec in policy.get("lines") or []: + if not isinstance(spec, Mapping): + continue + kind = str(spec.get("kind") or "template") + if kind == "template": + when = spec.get("when_present") + if when and self._response_path_get(data, str(when)) is None: + continue + line = self._response_template(str(spec.get("template") or ""), base, spec.get("formats")) + if line: + lines.append(line) + elif kind == "list": + values = self._response_path_get(data, spec.get("source")) + if not isinstance(values, list) or not values: + continue + fields = list(spec.get("item_fields") or ["item"]) + rendered: list[str] = [] + for value in values: + if isinstance(value, Mapping): + chosen = next((value.get(f) for f in fields if value.get(f) not in _EMPTY_VALUES), None) + else: + chosen = value + if chosen not in _EMPTY_VALUES: + rendered.append(str(chosen)) + if rendered: + lines.append( + str(spec.get("prefix") or "") + + str(spec.get("separator") or "; ").join(rendered) + + str(spec.get("suffix") or "") + ) + if not lines: + return None + return str(policy.get("joiner") or " ").join(lines) + + if mode == "field": + value = self._response_path_get(data, policy.get("field")) + return str(value).strip() if value not in _EMPTY_VALUES else None + + if mode in {"llm", "none"}: + return None + return None + def build_direct_mcp_answer(self, state: dict[str, Any], mcp_results: list[dict[str, Any]], *, agent_label: str) -> str | None: """Resposta determinística para consultas estruturadas simples.""" requires_rag, _ = self._mcp_rag_directive(mcp_results) @@ -1475,6 +1802,14 @@ class AgentRuntimeMixin: return None tool = ok[0].get("tool_name") data = ok[0]["result"] + + # Primeiro tenta o contrato genérico e declarativo de apresentação. + # Se a aplicação não o configurou, preserva exatamente o fallback legado + # abaixo para não quebrar projetos existentes. + declared = self._render_declared_tool_response(tool, data, agent_label=agent_label, state=state) + if declared is not None: + return declared + if tool == "consultar_pedido": oid=data.get("order_id"); status=data.get("status"); total=data.get("valor_total") lines=[f"[{agent_label}] Pedido {oid}: status {status}."] @@ -1509,6 +1844,7 @@ class AgentRuntimeMixin: available_tools = list(tools if tools is not None else (state.get("mcp_tools") or [])) state["available_mcp_tools"] = available_tools text = state.get("sanitized_input") or state.get("user_text") or "" + self._normalize_transaction_lifecycle(state) # Clarificação de resultado de tool tem precedência: reutiliza a mesma tool # e argumentos, alterando apenas o parâmetro escolhido pelo usuário. @@ -1524,7 +1860,7 @@ class AgentRuntimeMixin: # Antes de confirmar, complete os parâmetros obrigatórios da ação. if state.get("transaction_status") == "COLLECTING_PARAMETERS": - selected = dict(state.get("selected_tool_call") or {}) + selected = dict(self._active_transaction(state) or state.get("selected_tool_call") or {}) tool_name = selected.get("tool_name") if tool_name: previous_args = dict(selected.get("arguments") or {}) @@ -1535,14 +1871,20 @@ class AgentRuntimeMixin: aliases=aliases, extra_args=self._extract_action_arguments(text), ) - arguments = { - **previous_args, - **{k: v for k, v in new_args.items() if v not in (None, "", [], {})}, - } - # Execute parameter extraction before deciding whether the workflow - # must enter COLLECTING_PARAMETERS. Otherwise parameters declared - # with strategy=llm in mcp_parameter_mapping.yaml are invisible to - # the deterministic transaction state machine. + # Durante coleta incremental, valores de contexto podem ainda conter + # parâmetros de uma operação anterior. O que já foi coletado para a + # transação pendente prevalece; o turno atual só preenche lacunas. + non_empty_new = {k: v for k, v in new_args.items() if v not in (None, "", [], {})} + arguments = {**non_empty_new, **previous_args} + + # Campos de envelope pertencem ao turno corrente e devem permanecer + # atualizados, mesmo quando os parâmetros de negócio ficam congelados. + for per_turn_key in ("query", "operator_instructions", "interaction_key"): + if non_empty_new.get(per_turn_key) not in (None, "", [], {}): + arguments[per_turn_key] = non_empty_new[per_turn_key] + + # Reutiliza o contrato declarativo para preencher somente os campos + # ainda faltantes; campos previamente coletados não são sobrescritos. arguments = await self._extract_mcp_parameters(tool_name, arguments, state) policy = self._resolve_tool_execution_policy(tool_name, arguments) missing = self._missing_required_arguments(policy, arguments) @@ -1562,6 +1904,9 @@ class AgentRuntimeMixin: selected = {"tool_name": tool_name, "arguments": arguments} state["selected_tool_call"] = selected + self._set_active_transaction( + state, tool_name=tool_name, arguments=arguments, status="COLLECTING_PARAMETERS" + ) state["missing_parameters"] = [] if policy.get("require_confirmation"): waiting_state = self._waiting_state_name(state) @@ -1573,6 +1918,9 @@ class AgentRuntimeMixin: "next_state": waiting_state, "tool_policy_result": {**policy, "tool_name": tool_name}, }) + self._set_active_transaction( + state, tool_name=tool_name, arguments=arguments, status="AWAITING_CONFIRMATION" + ) return [{ "ok": True, "executed": False, @@ -1586,27 +1934,29 @@ class AgentRuntimeMixin: result = await self._call_mcp_tool(tool_name, arguments, state) self._capture_pending_domain_workflow(state, result) self._capture_pending_tool_clarification(state, result, tool_name=tool_name, arguments=arguments) - state.update({ - "transaction_status": ("WORKFLOW_PAUSED" if state.get("pending_domain_workflow") else ("TOOL_RESULT_CLARIFICATION" if state.get("pending_tool_clarification") else ("COMPLETED" if result.get("ok") else "FAILED"))), - "confirmation_required": False, - "confirmation_received": True, - "pending_tool_call": {}, - "missing_parameters": [], - }) + final_status = ("WORKFLOW_PAUSED" if state.get("pending_domain_workflow") else ("TOOL_RESULT_CLARIFICATION" if state.get("pending_tool_clarification") else ("COMPLETED" if result.get("ok") else "FAILED"))) + if final_status in _TERMINAL_TRANSACTION_STATUSES: + self._finish_active_transaction(state, final_status) + else: + state.update({ + "transaction_status": final_status, + "confirmation_required": False, + "confirmation_received": True, + "pending_tool_call": {}, + "missing_parameters": [], + }) + self._set_active_transaction( + state, tool_name=tool_name, arguments=arguments, status=final_status + ) return [result] - pending = state.get("pending_tool_call") or {} + active_tx = self._active_transaction(state) + pending = (active_tx if isinstance(active_tx, dict) and active_tx.get("status") == "AWAITING_CONFIRMATION" else state.get("pending_tool_call")) or {} if pending: decision = self._confirmation_decision(text) if decision == "reject": - state.update({ - "transaction_status": "CANCELLED", - "confirmation_received": False, - "confirmation_required": False, - "selected_tool_call": pending, - "pending_tool_call": {}, - "tool_policy_result": {"action": "cancelled", "tool_name": pending.get("tool_name")}, - }) + state["tool_policy_result"] = {"action": "cancelled", "tool_name": pending.get("tool_name")} + self._finish_active_transaction(state, "CANCELLED") return [{"ok": True, "tool_name": pending.get("tool_name"), "transaction_status": "CANCELLED", "cancelled": True}] if decision == "confirm": tool_name = pending.get("tool_name") @@ -1616,17 +1966,26 @@ class AgentRuntimeMixin: result = await self._call_mcp_tool(tool_name, arguments, state) self._capture_pending_domain_workflow(state, result) self._capture_pending_tool_clarification(state, result, tool_name=tool_name, arguments=arguments) - state.update({ - "transaction_status": ("WORKFLOW_PAUSED" if state.get("pending_domain_workflow") else ("TOOL_RESULT_CLARIFICATION" if state.get("pending_tool_clarification") else ("COMPLETED" if result.get("ok") else "FAILED"))), - "confirmation_required": False, - "selected_tool_call": pending, - "pending_tool_call": {}, - "tool_policy_result": {"action": "executed_after_confirmation", "tool_name": tool_name}, - }) + final_status = ("WORKFLOW_PAUSED" if state.get("pending_domain_workflow") else ("TOOL_RESULT_CLARIFICATION" if state.get("pending_tool_clarification") else ("COMPLETED" if result.get("ok") else "FAILED"))) + state["tool_policy_result"] = {"action": "executed_after_confirmation", "tool_name": tool_name} + if final_status in _TERMINAL_TRANSACTION_STATUSES: + self._finish_active_transaction(state, final_status) + else: + state.update({ + "transaction_status": final_status, + "confirmation_required": False, + "pending_tool_call": {}, + }) + self._set_active_transaction( + state, tool_name=tool_name, arguments=arguments, status=final_status + ) results.append(result) return results state["transaction_status"] = "AWAITING_CONFIRMATION" state["confirmation_required"] = True + self._set_active_transaction( + state, tool_name=str(pending.get("tool_name") or ""), arguments=dict(pending.get("arguments") or {}), status="AWAITING_CONFIRMATION" + ) return [{"ok": False, "tool_name": pending.get("tool_name"), "awaiting_confirmation": True, "transaction_status": "AWAITING_CONFIRMATION"}] read_only_tools = [ @@ -1669,19 +2028,30 @@ class AgentRuntimeMixin: if not selected_action: return results + explicit_action_args = self._extract_action_arguments(text) action_args = self.build_tool_arguments( state, tool_name=selected_action, intent=state.get("intent"), aliases=aliases, - extra_args=self._extract_action_arguments(text), + extra_args=explicit_action_args, + ) + # Nova transação: parâmetros declarados ``from: message`` não podem ser + # herdados de context.tool_arguments de uma operação anterior. + action_args = self._drop_stale_message_extracted_arguments( + selected_action, action_args, explicit_fields=explicit_action_args.keys() + ) + # A mensagem atual é a fonte de verdade para esses campos no primeiro + # turno transacional. + action_args = await self._extract_mcp_parameters( + selected_action, action_args, state, overwrite_from_message=True ) - # Extract parameters (including LLM-declared extraction rules) before - # validating required fields and before persisting the pending call. - action_args = await self._extract_mcp_parameters(selected_action, action_args, state) policy = self._resolve_tool_execution_policy(selected_action, action_args) selected = {"tool_name": selected_action, "arguments": action_args} state["selected_tool_call"] = selected + self._set_active_transaction( + state, tool_name=selected_action, arguments=action_args, status="COLLECTING_PARAMETERS" + ) state["tool_policy_result"] = {**policy, "tool_name": selected_action} missing = self._missing_required_arguments(policy, action_args) @@ -1718,6 +2088,9 @@ class AgentRuntimeMixin: "confirmation_required": True, "confirmation_received": False, }) + self._set_active_transaction( + state, tool_name=selected_action, arguments=action_args, status="AWAITING_CONFIRMATION" + ) state["next_state"] = self._waiting_state_name(state) if emit_events: await self._emit_ic("IC.TRANSACTION_CONFIRMATION_REQUIRED", state, {"tool_name": selected_action, **policy}, component="agent_runtime.tool_policy") @@ -1727,12 +2100,19 @@ class AgentRuntimeMixin: action_args["confirmed"] = True result = await self._call_mcp_tool(selected_action, action_args, state) self._capture_pending_domain_workflow(state, result) - state.update({ - "transaction_status": ("WORKFLOW_PAUSED" if state.get("pending_domain_workflow") else ("TOOL_RESULT_CLARIFICATION" if state.get("pending_tool_clarification") else ("COMPLETED" if result.get("ok") else "FAILED"))), - "confirmation_required": False, - "confirmation_received": True, - "pending_tool_call": {}, - }) + final_status = ("WORKFLOW_PAUSED" if state.get("pending_domain_workflow") else ("TOOL_RESULT_CLARIFICATION" if state.get("pending_tool_clarification") else ("COMPLETED" if result.get("ok") else "FAILED"))) + if final_status in _TERMINAL_TRANSACTION_STATUSES: + self._finish_active_transaction(state, final_status) + else: + state.update({ + "transaction_status": final_status, + "confirmation_required": False, + "confirmation_received": True, + "pending_tool_call": {}, + }) + self._set_active_transaction( + state, tool_name=selected_action, arguments=action_args, status=final_status + ) results.append(result) return results diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/security/__pycache__/__init__.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/security/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d5ac65c5cd0f5f492149d65fb7b3c95a3d6b71f6 GIT binary patch literal 1188 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 J3{q+X{ud#jYhM5W literal 0 HcmV?d00001 diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/security/__pycache__/factory.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/security/__pycache__/factory.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1c721f3e3d5ee299411c1f1fb6d0bbdb35894c14 GIT binary patch literal 7977 zcmbU`OKclQmi?pnC-t@Uv24ncCDT8}maXwWk}29E^|RTeZCP?Cifl=g`BAEylI2Vs zE#{)k9PC|8u*ys@F%|*V0Tvh?b=bqqVRmK~3#6GgV4h zhA;rxAvVYnPQ!6SreGDRg0_jT8Zrkh#1ga;YtTk)K|8Sr9mElI5@*mwTtPQ+1D%UE zH&gQ*spc&_!&^@=yqmWnW}YE6d^K;^dTaR_zLs}rc$(C~R~_#xeAUk~-umxQRWGgD zW0_1=ib=_AMjVB2^GIxAA(@$lCflD`{*Fd6i+Z4cAvq*0_vfTJAtNQ@+JKuRyO>M} zL~Xei6O-`@oy`M6rqaNs;F45fSmS86LXUS0JI(|$63L1SLL7CkKzf)*)8f~J7!gP% znlQ~ z97#&c-7~SclqJij7M4|KloSk$f_9`4WY@t@JP*|hwdHU<3H&_pH1UhE75}E$@ed!a z`9B}}bm;SuPe-;~jdDv^j*QFUdveo+;+m8#lbiPHmEmm|OI-)EECz4YoDgPWxs(() zCJ!M_k2b}tFm<266oz&N05X9Rp^68PjUO zj48qtd3Ay;lNLCpkaZUu`23rJV>jq{Cc^Cs9Md#t7BO{D5f*-b)3&>H=L*`FX>v)^ z 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 F{{snLn-Ty3 literal 0 HcmV?d00001 diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/security/__pycache__/installer.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/security/__pycache__/installer.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2e80012498690c30d4337eece76a5fb6c9814996 GIT binary patch literal 5595 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 literal 0 HcmV?d00001 diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/security/__pycache__/middleware.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/security/__pycache__/middleware.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..57c4c9c1fb3d04b3e3ca6008392564b716b3e584 GIT binary patch literal 8879 zcmbVRYj6`+mcFfSy(P;JZ2Y$H3xvToU?3#K2@e~vV;kHSnAkzct+p*JOPbp<46dZs z6S6ZXs~vOlogQx6ggQ&iT$c_pZ6!4g%r5e^)L{mJ{-4Oz6R^5!_lQN5~B#5|JAu103bN zNSg*t)Wp6#<>AW@3Ik?p912$?Kuv0rrn+F{OPU>W|WzaR?rfx=C2TKM# z)H6^@OIg}BST;~j%Yn9wj=_q7O?1;hC9U+5Nq%&PKDFGpnM`ip3-iN3t0!&EM0AR- z16(x$%3VvulD#Iabg%Xyv_`BFJ+DkL`6=)sHEr;BSyxe-xG}+Kh z^j`95aZ@KRZWb%C&kH8nIAiivKf=y@oazilqp?IV5spQbVV_C0ok++uI2Dmqn<)Qa zL5@l?#n! zF;y z(2r%B#uj15+CFKqpnbTt_kg%TCJE(40*t{?z73dUQV{vAP$CLInHgoFX3+{M8>S{L zaDZ0Pet@Gk(E+*6f?Qw%$aNLuI#{lo^;agAu)}nU9_pGY^_8oe3YHLygr&=mfW3*z zD+#I!(crvHOE7JVXV(tP zh|$Y`DbY4VkrP<`E!8?NCuUnGy<7_nfXk~O$LnEuZh}?9 zXf!LJMg|bgWX$B}bkV&?ZkWAfsF4sS^fE*C^V8fN4#mkj9i0y*q*>LOB_xmxAFrA^ zyHzWk9SB=g71$x-HhH~E>P**sG|`0u*A)aY2waNMxvt<0h(lnS0%Kr05R<}Pk?@pK zSkR?VX=9!&Ezoe{a@V{ej-Bz#s{J5zD*rG}d)2OD9NEccE-Re}BQYr$QF=R#25_`Q zX@Th5M`Vd4+ob#BQ@=m+(M+cO!2R|EcU!-(X4;P@+mA!`a|LPz@}JM$O?>|LXK$x=4qh!;@ib&S(nl>1+N9+8WM+H{ z=ALeo(#=xRCapmq zhQW@dd||Oc21AcY5WE{?!Vo`Q{-Yp7AaK8A@=l5&g`d|YI4b1Hzc67)y)J}0?gU=~ zd@zmLVeEo{h~XDTodwyD6ip(p_cQ9=Sgy}^Bd&nh2T49M2@?q1EKHOdlunQyV;p_H zA=t5@D=(b0fO9T7?mud9<2M1enb%_*9s;7CvlQ4&C%E`+mb~Q1)(hE$6d?rj`>bKLe2?tc0T= zfM6V z!AlBiC@%&L^W5t;nvP&8{FNU;v_w`n*ZzEAssE3ql~;w8l1=YlxOQQAQ@W(_D!=Ni zye@sXC*y2NIh$5osdD#7y5sdsM}MlL|3Sy`bj_(hxK6FQ zH!t%ahCb^1)t+QSSH|6)c6S>sdw$KQYkL0R>UrWMWmS(|#8tjD#1KG&nHT}j4Fb1z z9O82YwwGw4f@l>%eS;$BQIUgb%7Nu&7lGly^tFf%(ab2TXrWN=RgT($(Vc4bdc@C} zn2$POpvA7kL1_*w&d^RNHV=w547RKn4rnGK@6?ScZ=NEQaF_J}V5I?89Ee^pcXC$1 znAuO>g1R|A^OA9I#DKdAL~0gtkmV@EOA7_j3PbWVkG1IA{E#-mo?mIc(0phUva zZ~}lFWrrSsNOi>*rodPXFoS_2hN~Vui^|jCAIb`-DBK57ukpCn@-#L-gL(Dg9?DwuY5z?@!&U^=-Ez>H0la zg$K5p)uz^4fppW}tHOWU>NWN-HVZnyje+gv)}lb5WjV&Z*c!}Pf+5Wk#DijCoh4{& zwqE-EEJ19>5T+l9b(SFPe3TnAjT$JE>o~^;S-b&LW&_@+4!{MPP%ecNvp!yfQA?bi z6f-0gTn89^+8Ho7-S^@%2rB{Yu#12!YA6NvCTo#(&D}qJ;rIQY3jgBywdV^RTwu4bYT#= zm&XYS!8(9{@_Wcu^mC&{_@bECpo^uhAcLS{{HEqSkv{=93$rlBMeYVaY<7`WGGW*m zAKT(ckAaJpLJwj9!R}Bkl8+%+CKQOruo+XbWKO5q9f_*SgqWC zdp{W1?|k-7x^gJv8A{rQp73PTj)$J1=SnN|`|csjp)T&8jXTsK+_N_z-Oe4_Dcsv? zMtUa)F|3Tip8;aPrp&O#2sVlpqQ%9y`7dt$`hq#VjIZehtSPWP)b#&utPTQC?pWwF z(rAIu8H^C5DJypY<#SMEW{Sc^_hE#4qFMuiP)q_~M$n|^F`C8bWr$RF7GotD4j^!c zqh}#kK>&GOlk!to6(c+`r5U1ce@q?<2c8LndEXNP(Nh;^j&RQ`ym^@WhG4AO*Vssc zzY(&0&8_u9R#6pe5v?0ktj$odW(uXCSZ$zK?P}vmb`kL+34erU(_+6UM`S6Xc;SM^ z%N!UlbHzZxdT9(i4{x0H;tfVa-h6)5T4edNQ_2@f6k7OmYY89*l!uCS7Df zlVUF{sLuCaKpis%KRyQoq{?c<*_^Erv+nw>A ze9$wT?m3AXwqYZJ;-atMww?y=JI84lI`$nHs^i_5VM=ertclz<;~k7Cdk2$$oG>hg zoX;W>-M7M99SN>Ua>mjaH|`xp`6~!7M$P=Tev_XshPjZ7@>>uf*YM49MUZRwX}MgH zKVaFodO+(d@IMNF8$)ejm`c!Sox_4h&&-Lx2V$K$0TL7|D`rf9iIHy`Wv5Y0Z$VAN zWXx8BkG{XU=3+i2Sd4~i2hL5QaU!tG0~&(n8a5)wWsMYyfWok`h=uaD2gi=D^G^5eOI{-LvHGLwt6oIpGEsG@mAtGOmQlB~ulZm^AKBKrJ8&Ygzym zfNIhDU4Pxg;Qgka@7ozF1*j3Al zv+P>$YE9?uOLy&=Bjc$fYFq5yHoYMpSZ16j%UPL>Ud17cE=MtsNE+Pvgu9ki3u{FD?Kp1EA@wc+)eIq zi*V}@0rH-gJKQGR+wv;Vzis3WZxw#qWJbD;!+0ykpnch1GPLtTC$NJ^FE;A01rzJ_ zhsG;!u~v%>1!dX0ZSULO;aF6rbJ(A~n98LQDAJJG(6n?O^U!<9*RJTeQH+?Aj|a`P z>&a&VZ$8C60d0DUd**PP9p4a$G`-5&T!yN~)i;8i75)r9KL*jv8lc5J0itW6LcoYx z{FY*Zt&3?8u9~1m5%83bu#zI8ZnOm`6FF#Iq)s|e(<{w@L=E?*I~tHS`1P}s}4v}+yAS*&1i4;3&x6DVNZn7vVsLb(r?pG zK(8Bu-N{=$ywZqHZC&vA1{Y?2vtBcZy_$>mYX2U+y4Uqu^en+GfV-%|5HZeTyt`;Q znxZWDIdDN<$YZUm+HcmWSIJbuqJbe+qu(FC|A$U$w4!>TdI2lqAQ`WyV9P@la;`VsiH4V?vIYhD}ch z**9W>#97mMOq2#OVGo-A+f}pNo~hlQs@CCkQ;mB+l{1Y8Q;i3;p`A&81UkLU9c9Dyv2ps@IQ^zS zS*w=+CeyS()wKVvCDZg;s_8YO)jYIXlUB3_N8M#8T!%C1HrrE z?a-)(hh??P`_pAD8D~pUX!)jrlxRA557SxMKnQRBGnp+&CGyMs2(W>d@Hes`Oe^!L{UpnGuCk$ukqlT zApC2uMAqpbaBw`#+*!3Oo9YCPWbg8dCIB^fBNdV1<*_sG7IX@pB`G2j^MKWgT%}xd zw5T=d$UV)oS8B~Yvcp~Y8!&kgFtjdI3$6qbh<%#8q5sNsGrP>BOaOLaUN=VV5UI9< z+H+Yi{RomE6GZtZh#vDC$9+kf|4d5$NJ_pUonMh{|3m7&B-_6tr@kcH{+A4YZ7*LY&8e#|nS*4nu8r&S(qm`gV8dPgU(+bDW1%gkQi^gulc;gI2ANF=A`@Ke>;E5C8xG literal 0 HcmV?d00001 diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/sse/__pycache__/__init__.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/sse/__pycache__/__init__.cpython-313.pyc index fe525257ccbc5ff02b92d033fb39a784d4aad1c9..a9019c88e26379c2ff436c1605729a148374fa96 100644 GIT binary patch delta 63 zcmaFB_?VIFGcPX}0}%ZGHj&Fjvq?WUuS7pZ-#6GZKAb>KSU)YZsJJ9PIX|x? Ru{b_AGrcG=C4XW{4FIqH7a0Hm delta 60 zcmaFN_<)h?GcPX}0}$jqnaE|LR>; zBZ`>!WF!KLXK|LS+OZ7%K$oShbd}rEt=Jo~z^Afa7`o4$B|qx$MWIW-d1>p)P^VJN zL+4rIQ>CVLRg+PQLe_lh);1KeKuMe0cAqGvi$bYaXqbXOEAlHR^vsl%nv$NI2TOOt z(e;0A?J4Nz64h-vSUmdv@!a0jg*l-S8@CU+El!^yBEG@iS0C^c-v`^v9kEOgpAy>O F>NoG+WHSH& literal 0 HcmV?d00001 diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/supervisor/__pycache__/supervisor.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/supervisor/__pycache__/supervisor.cpython-313.pyc index b8d541d185bc3d2e4f03ce3d69ccda859b86f954..054da5c93ac9c4e4980b804581c0435623799a3d 100644 GIT binary patch delta 19 ZcmaE$@<4^_GcPX}0}%ZGwvj7L2mnG>20{P; delta 19 ZcmaE$@<4^_GcPX}0}$jq*~k?p1OPsY1)Tr@ diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/workflows/__pycache__/__init__.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/workflows/__pycache__/__init__.cpython-313.pyc index d4aef40cb4f621cb1beef6326642df361a694581..8a90d5ea743a73f75e330fadfc9e35efa4b72d4c 100644 GIT binary patch delta 72 zcmey(_JfVmU-?uV6zbIQj dpeR2pHMyi%KQTQuuOvP>Kd&UQc=9c#c>uOz8q5Fy diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/workflows/__pycache__/graph.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/workflows/__pycache__/graph.cpython-313.pyc index 9d19af52929e371b5a2312ac2b811702b00b9b00..90cd52552ed64943fc1da1a6ce067e9212df1aa5 100644 GIT binary patch delta 73 zcmbQjJ&~L1GcPX}0}%ZCwvo%7*`QuOH?KrLC9xz?KQTQuuOvP>Kd&UQI3CDOEy_%e aFG?*g$j>WIjW08gFV8Q^-rT}0zytt~9vSrj delta 76 zcmbQpJ%yX=GcPX}0}$jq*~sP2Y}}-un^&TrqVH0aUyzhvq3<8$=pO~JSR}!C`pI4Gtyt$ECfC&JA>=@|) diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/workflows/__pycache__/models.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/workflows/__pycache__/models.cpython-313.pyc index 0d5f670b8354fe8d368847d090910329a2f41455..bef74f60265e89ebebcc3a05d9f7db5ccc4e68f2 100644 GIT binary patch delta 73 zcmeyX@k@j2GcPX}0}%ZCwvp=^lR<-iZeEFgN@7W(eqwrRUP*j%eqKppaXgTnT9la_ aUzA#0ke^qa8ee7}U!Gr-y;+z!OAr9~i5rLj delta 76 zcmeyR@mGWEGcPX}0}$jq*~oQ`$+%fRH?KrLMc<_;zaS~ULf=2g(b>mU-?uV6zbIQj epeR2pHMyi%KQTQuuOvP>Kd&UQc(VX=mLLG{C>neK diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/workflows/__pycache__/registry.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/workflows/__pycache__/registry.cpython-313.pyc index 22a2878aa1b2d8edc4a98ed14262789f3919a04b..32218f89d1c069fe771d9791f50b02d8db06e62e 100644 GIT binary patch delta 73 zcmX>mbXbV%GcPX}0}%ZCwvp>Jqd}8?ZeEFgN@7W(eqwrRUP*j%eqKppaXgTnT9la_ aUzA#0ke^qa8ee7}U!Gr-y_ti_jvWBXpBkb7 delta 76 zcmX>sbWDirGcPX}0}$jq*~oR8(YRGVH?KrLMc<_;zaS~ULf=2g(b>mU-?uV6zbIQj epeR2pHMyi%KQTQuuOvP>Kd&UQcrz=L9XkNOQW=&2 diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/workflows/__pycache__/repository.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/workflows/__pycache__/repository.cpython-313.pyc index ee44ad84a695dc97db10afda44be58b7d49359c1..f1bf091036ebc00b307e5c440416bafe588d12dd 100644 GIT binary patch delta 73 zcmZ23xmU-?uV6zbIQj epeR2pHMyi%KQTQuuOvP>Kd&UQc(Vx81P%bRsu|G$ diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/workflows/__pycache__/runtime.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/workflows/__pycache__/runtime.cpython-313.pyc index fec117d12684026e5dee65db80411e6038ae82ac..45e15b4224a6ab7aefd576daba78803718b00c84 100644 GIT binary patch delta 2772 zcmah~T})eL82-MVp0=m$>FF<}gF_32@!Pd98G??9o1?%S8^^Q1vk7HuVQwq4MZGbi zMiZ}0<`=Krg^TgR#OMqc#u%fpM9Q`c*bV+<$<$~x-c+5sXfl1@(;g^hi6`Va&-cAQ z-+SJd@9E3m($(*%_?sx&2|RcIcwsV2Z#MG(-jtrNdE4(prtQy4!^&ADcK5Vwckn z$)UBc+uT|UyOjvlm>{)#l!HUv397}`?RW&lQV;uPYgF*|+8T*U#^Q`_^+gYWFX#Nr>#7a`lgharTeY4wdIdWL#$Ew+dJ%JN^uUYT5+32>7I7!|Vh6EY1lM9m! zwUI%(e^SSNkTg+|vU#Z-F6#$^>~E-$lgExiuVhLwC3o5zoLl~ zXX)4O$o$z8UG#xFw`0WL{2QUL`Gs7+CdXIh_+|Ubfn#e2CRPtjtjy$A7|+UTNe9^6hA8=}b=xx&+Av-ygp8hIT}wwbSl z_fS|YMJTu~)q9Y4>3n-jvXLv)&}5yZP|G8)H-S$fN|85m$eS^?(57R|zOR`p^qBTF zaD~3TiQ!t)avL3rS(e+8U#+2FxLWHRZs)JIpwrbhioAWG6BgHNDMVkFdB}Rbfk)m9 zC$P?mAic|mCf=(rsSF1yW6oMZZ#ab?u@2j^wg{*X+!G&)$bV!ffO}C}15r7}+Dlc7 zV!O8l;oV^uPf6^f6bevi{eQ~|VgdpriJSK9Y};hmQ<9zyUl;3`Y~ny}Sft1At_YAo zKkltBuCl&JARIDYeh?0!O4k;UuF|8LR0@|mf@aC1txK5^^4d{>y_v27scBjdacd2m zq(;=G285!V(m3sAx{-Zy(necRWSYkQBQpAr1V(_!)RshMOhnH)?~(fy^Z)A$T;a+b z9?%p)bCio9ip99Ns*pCpWfKO3jZ3Dh(o;H)L!LGx3TpYO4ihEdc7iyq>!)$~OO5me zjO4mP^`kxTM_K^kIG8iQbjV(zlS#;7QH7|&HP*EVsvhp@~&GhPmxDbv=DEkXw|8mcx#IeojOUdz9{O{MeH@dOFBJeBH`#S z;?8nBydgZerD#QFLna_|VjlD=V(gz1G6Il;yH0ZRqccY-?O^Yme^lCSrLJEIqHg;a DzdkCm delta 2539 zcmZuyU2GIp6ux(6XMbkrXJ>cY{pq&bvP*wh=V-fxzE!EfHf;vb^OBl5HevrqdTkW@h)XhmHu_tq4U>HM)*8mdp(|lk5wB zF%d+rjQFgB0~*)wC38EyKGo7<=|n1;Vi9@;UuSzc0Yy<2d415=s&P#ivOy^A&>a1N z0xp$TqzU9g((5X*lT==l-WiBg3iaz7j&KNRg6gCL>T|1t#`o8d z8&;1jnl&bHTGk`v{;`NG>6?pruG?Xm{5<9--wilrUau>z%6gPsvj!>{8eQ&V>9%qL z>kY;Ab#L;~K!Eh9&eKYZJ&H8cA2TgB#=)Z+-$c6wzbLY!6z&}`WYUloHAvrDSVhQ& zM)I_Bmu5>VRY;GU`lfYIsLkUxYlHI}JxFsj&n49G_*r;VWbU1Im(=Gj)VJ3`eci=g zLbdL+(&v66C)(U<1UZFKpJf8=Wy5F!7kb+4)oo^$n#;^fPd-Jr(R-y(M@jFMlHRVb zn!Vjz*5a69!t^euU2U%D`Z$5jJet`F+)z&L9q%GZeTocCD&!Nrk}T_|u!l4c?If9@ zR*F6!DkrywYVk6;GSy6?Cyq4b1thqZom=UDB~ZB>h%E(TE3V)d{BmOdQeuB@CeNba z);wZ@(j&xpC5l98_N^1!v28U@=c_zTnxoIFX(eVLk9UCFPn=pJu;iCOLRGy z1t0DVS{M9)Z`(1|-*yOHe(rWzJs92gVVL;al611@z|?z@=V;VLnFH))dwk^mVIN*0 zUk-nU{Ujm#8wcHkJ5=_mG=Wr$%5`&H*0ik}Rl&tp$b+Cqew;Wwpu;xu%}AJ|)X-l> z=DI@U?-50I>b~LyaHTD1y8_>ZqfS|7pZj;vuP`!37mh za)CszD{z6V@szE+Rci5C8dR`BRg8u;j#SrrB~{UDiU}KDq+wz+WrRpkE9=$32mzB3 zM1v7F?sUQHr?G9McDwg-|Nq|n7=2Tc8I8Vkg}!sUE}I(FYQ7!KKF-j)Zf~=1+;M{` z`V84Z%>s!!i$7OdIL)HZ0YM7MDqE;vLu4$)OY-v#aT zMBGUmWsm|L$;T5R>$h}=3`6crTx;@YCSj5VkpnRfViCk65Ptd@%&Y-IfJ6`yd3SQB zO9tqHm6KF7xXF)`(OrhQ4$6N)z;`p_21BP|4FVWD(+k22)7L1PaZ~OoBkEM0^>?b9 z`I-_??>HxN{HdCfqd&tjroni3hc^dC(TYdKyJhug> zM9W;v0ytq!xzJp5eQF1q593s$Wxm=Eco$A3E%Pnym`-l(#?E6WV@S#L!h{+{!#|~?5djrJ_6__q8goMr* zw@?p83tKSYSX+`#?u0P)zEjE3sCPDTfa~ZEB!2cB4w3iH9>mU-?uV6zbIQj epeR2pHMyi%KQTQuuOvP>Kd&UQc=I*JN2~y`?i#`X diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/workflows/runtime.py b/agent_framework_oci/libs/agent_framework/src/agent_framework/workflows/runtime.py index bc8a1b6..f818233 100644 --- a/agent_framework_oci/libs/agent_framework/src/agent_framework/workflows/runtime.py +++ b/agent_framework_oci/libs/agent_framework/src/agent_framework/workflows/runtime.py @@ -434,15 +434,11 @@ class WorkflowRuntime: "current_node": None, } config = {"configurable": {"thread_id": eid}} - # Explicit offline-regression mode. When enabled, always use the - # deterministic backend, regardless of whether LangGraph happens to be - # installed in the current environment. This keeps regression results - # reproducible across developer machines and CI while production - # (the default) continues to require/use LangGraph. if self.allow_deterministic_fallback: - return await self._run_fallback( - definition, initial, start_node=definition.start, execution_id=eid - ) + try: + import langgraph # noqa: F401 + except ModuleNotFoundError: + return await self._run_fallback(definition, initial, start_node=definition.start, execution_id=eid) try: graph = self._compile(definition) state = await graph.ainvoke(initial, config=config) @@ -503,9 +499,10 @@ class WorkflowRuntime: definition = self.repository.get_version(name, version) if version else self.repository.get_active(name) config = {"configurable": {"thread_id": execution_id}} if self.allow_deterministic_fallback: - return await self._resume_fallback( - name, execution_id, resume_value, version=version - ) + try: + import langgraph # noqa: F401 + except ModuleNotFoundError: + return await self._resume_fallback(name, execution_id, resume_value, version=version) try: from langgraph.types import Command except ModuleNotFoundError as exc: diff --git a/agent_framework_oci/mcp/servers/retail_mcp_server/main.py b/agent_framework_oci/mcp/servers/retail_mcp_server/main.py index 6f4e3e9..5d8d57e 100644 --- a/agent_framework_oci/mcp/servers/retail_mcp_server/main.py +++ b/agent_framework_oci/mcp/servers/retail_mcp_server/main.py @@ -17,6 +17,10 @@ TOOLS = { "description": "Consulta entrega e rastreamento do pedido.", "input_schema": {"order_id": "string"}, }, + "cancelar_pedido": { + "description": "Simula o cancelamento de um pedido de varejo.", + "input_schema": {"order_id": "string"}, + }, "solicitar_troca": { "description": "Simula abertura de solicitação de troca.", "input_schema": {"order_id": "string", "reason": "string"}, @@ -77,6 +81,13 @@ async def call_tool(call: ToolCall): {"data": "2026-05-29", "descricao": "Em trânsito para o centro de distribuição"}, ], } + elif name == "cancelar_pedido": + result = { + "protocolo": "CANCEL-2026-001", + "order_id": args.get("order_id") or "PED-1001", + "status": "CANCELAMENTO_SOLICITADO", + "orientacao": "Cancelamento registrado para processamento.", + } elif name == "solicitar_troca": result = { "protocolo": "TROCA-2026-001", diff --git a/agent_framework_oci/mcp/servers/retail_mcp_server/main_fastmcp.py b/agent_framework_oci/mcp/servers/retail_mcp_server/main_fastmcp.py index 5abf44d..7972f95 100644 --- a/agent_framework_oci/mcp/servers/retail_mcp_server/main_fastmcp.py +++ b/agent_framework_oci/mcp/servers/retail_mcp_server/main_fastmcp.py @@ -30,6 +30,16 @@ def consultar_entrega(order_id: str | None = None) -> dict[str, Any]: } +@mcp.tool() +def cancelar_pedido(order_id: str | None = None) -> dict[str, Any]: + """Solicita o cancelamento de um pedido de varejo.""" + return { + "order_id": order_id or "ORD-001", + "protocolo": "CANCEL-123456", + "status": "CANCELAMENTO_SOLICITADO", + } + + @mcp.tool() def solicitar_troca(order_id: str | None = None, reason: str | None = None) -> dict[str, Any]: """Abre solicitação de troca para um pedido.""" diff --git a/agent_framework_oci/templates/agent_template_backend/app/__pycache__/__init__.cpython-313.pyc b/agent_framework_oci/templates/agent_template_backend/app/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f6a2b79f0ac62dab88b9458890c4272746a21aa0 GIT binary patch literal 145 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 literal 0 HcmV?d00001 diff --git a/agent_framework_oci/templates/agent_template_backend/app/__pycache__/state.cpython-313.pyc b/agent_framework_oci/templates/agent_template_backend/app/__pycache__/state.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7828b8e7af944e51ee205a0802a1b3d3553efd3c GIT binary patch literal 2526 zcmZ`)&rcgi6kgkdu>nJD<6!e61PlS15So%oiBv_3l16Q!(t~s80cEu84$g%2?q+5e z;vRb8P~~P0m6n@xqkl{fXr*d3s?Y*Jk8QKwW_wLHPX{sBeR`upvKTc#4^q7 z+VDpiww4x|$97xfU$$LhKBb0d#M#sjiWg^prDf`EjinkIOE*$1v#f2S?V(0`1tol%T9aSzr#|PY=nMp~i6H%_S(GppgWPDs(<}Eb$f+G_Fu?dw>~Nnz$sxwJX`h zD?KIUk^3$uXfkG_xK`!L=uc*_a8m7tY`x0;|eg+?Ir7m4k*LYJN29p#aI ztY68wo8;M0XkcFu_hsU}m!PjCYHYI6=KZy=#mM6(vAu?;d*q|ky~umS)@=_{Q{;5% zlW2q!&Z%Qde9ds|eZsizNy8p#i_rsz?d@95fpiyoK`wK4sYOKI=Y(O8yz|5a*KO+2 zpNWa7?fRY=Vvg?-k)<}&^u)MYVv`tD))HCW<_Cm{v0ZBG7LHfLuPOH&))vFihss-S z`Z_b2POT)Ci^3bzc@;>03`2ffP(Z0MFHiY~EDYBvW=C67U$x}jzx%lTYXpwV5*TD^fW^46z}m>0|j zq5EJisr;^EQKKEVBuXs`$d6a?m~ZWeZpZX zVtB`Lj6IojppD)fM0vo}^r@-a207QR?s=r;dSZHjs7ip&poY#t4K>gThz1W(`nz0+ zU5O4j)-4D#+gNv9i$Yf=%aP|qSPQpE%VCsoQT@!;#(hQ2UGN+*>h;wmW-qw8zw-vv zp>D&>1+V4kCMJwI?00QzZA|1aw&55t79$w99McD-VKIjBTVJW`#YGle41sn)o+1NRN>s2CJT)-Pm(d-#YY@U70{INS znpl@px8O?fjozj0uknr!XK9-oFuo0SY3{mh2LHgCddT+#|0AVoziQD$>2NC=FCP97 zT`M2{7+tT0s1_9`Lo^wcr-Dq-2y#b{LbT8$R;nSYMx*10&!e%4!xzzHH7Ey0P(9iT z(PGb3s)VQ#6^fmu4iBDm-W}aNEiA|cV5)a`XZ8K75Y0rjxxnmho@BZYj_uRhdWhC# zJrp#$_28%D@ze53h*o+%sY(;&&Xf0TS-n{4n89W@6FfMwPm9YTT9(O-W9WP_s?PQ^ zgy>c@H4{APmV@t(evz!|j4V7eAENpAd7dp-$9dUmr54l!9;_Zgt96<4Ww+kt-PPk) zr`0`zDRFE<*5)&MRW1KVYpM%A)1bAvmu&|`?y(`x##QMrzhnTvVoIM4Qpd?GW9*tmqAuuD)`TIcc2aKESEmix$=X7nc4+OYGbJ`951qi6IYEW^Jt@ zk@eaxynB?$m^}KP5TuNHA+twDlS-xj))qcx@1>SIweIqn I20+FA2cIMF1ONa4 literal 0 HcmV?d00001 diff --git a/agent_framework_oci/templates/agent_template_backend/app/agents/__pycache__/billing_agent.cpython-313.pyc b/agent_framework_oci/templates/agent_template_backend/app/agents/__pycache__/billing_agent.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4e27b2050509f616535e4eeacb5853c87efd3d19 GIT binary patch literal 5216 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 literal 0 HcmV?d00001 diff --git a/agent_framework_oci/templates/agent_template_backend/app/agents/__pycache__/product_agent.cpython-313.pyc b/agent_framework_oci/templates/agent_template_backend/app/agents/__pycache__/product_agent.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..104fb209ce4a99b382d87c8eeade62720bf96d77 GIT binary patch literal 5240 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 OI9F&1eu;2H!~HL*XXGmY literal 0 HcmV?d00001 diff --git a/agent_framework_oci/templates/agent_template_backend/app/agents/__pycache__/prompting.cpython-313.pyc b/agent_framework_oci/templates/agent_template_backend/app/agents/__pycache__/prompting.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..eda48f56cae61bf11461b26c11974f94f0c0418c GIT binary patch literal 1142 zcma)5%}X0W6rcS_VmI!l7LisE29aVk#(p4(^aCl>en=0d3-wTz>Fy+~?iVu~FnYU&n4Nj^-uu1Z?=jocbq#@C+l)3o z$_V`u&Z&VfOzMrp_Y zr8VkRHI>Yon8XEJNc})H)id3|%ao>&sT!z~H6;VxSEf)gSN{#k%Z_WqhzSmH#Awys z3b8}s82V9+?J%giwK^jXLJAsCY~Z*Zu#2F)<_(^881Ktqoqfm}1kAN5P+-*@&))IX{9E4R}k0v>g7SpXb89F7F=;xRvXj|5_ zqMRr-8YdYZGdC(`!~tX{2FN0HF9sQ6P)RPuWjPpWk{yWS8E~+$Wbt%he4z7efYv)= zZ_>b-CsCA+V19t<2DNh3NX8-HHLP>&)2?g;@Ksp637;l98AgTCJ$Kh_6*|Ur*Rc1^ z&+7;4UmBgc=q#tPVZ#FN@_S63XIMy7q literal 0 HcmV?d00001 diff --git a/agent_framework_oci/templates/agent_template_backend/app/agents/__pycache__/runtime.cpython-313.pyc b/agent_framework_oci/templates/agent_template_backend/app/agents/__pycache__/runtime.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..df7bf1540128d98ce4730c2b8fec5005d9603a10 GIT binary patch literal 344 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 Va%3^cfghL|85wUem=>`BIRF61JrV!_ literal 0 HcmV?d00001 diff --git a/agent_framework_oci/templates/agent_template_backend/app/examples/__pycache__/grl_examples.cpython-313.pyc b/agent_framework_oci/templates/agent_template_backend/app/examples/__pycache__/grl_examples.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8fc575e974f16282f77fcefc646c95e92424d76c GIT binary patch literal 1798 zcmdUv&2Jk;6u@V^ANH=}kTz-(Cn;=`9_j*)ky5It6v;q@_>e1km4c9^WwJYUwzhXy zGwaZBLhv{AkW(sgfZVtsB_|x^${{F+T63zzh29*Q3c-mt>)H`PRU~eVH1A{H+xO<< zr|su*CW2u!qWeFq2>mLZ;YcFj^gR#{k&PI#v7Pz|f0$w^3)xC7Wvex%rq)u+DGhRL zt)|*K%(R_ZHf>`T-B+1*Zl0Os>Gez@+x`v8tUjQvs2Ot0qt^S?kBg=W(qc4Xl+z$4 z7Tp9jh}YYMd5ri?UbI$QkW^>nwdAW(>5XDheqJiASp4wY(4s9r_Pvms5p9N6Fnor@ZsDOo14z@%lT<6e>GNJL9#8epa zRE`^ZROpNn9tKj!Z5C8qc&X7a!1@MezYAg!S@2S8sESANkzwOCTvbNy$gop4o@d|2 z*PgF>7Z6l>LB2A~e?eS5C$5d+sWrvci<;zRMfm^-+kpLT;)hB_8-xCJltC5krg9G# zjEYF#dB$EDSenMPUF>w3`wc$&3R5q10)-t1@}>OtOAjfy*@uhPWL| zaN+Uz(xCIuch-s9pn-+1F*Od>tPw z;PN%~U{MGAANn^jfKKvmOz{A zdl&T~ga#+fywwW5c9Xu%7GX{Pdw3f}Pr(?Uq%^EP8%KD$r)RPLgVIBw_TKAEcHGX) zekE~_KKX2*z4|~mqu*s(Z+;Bx-@n^Kp!U=~yR*3W>Hc`)9@%#X`g3=nH=5668e4$Q Fe**?%p%4H7 literal 0 HcmV?d00001 diff --git a/agent_framework_oci/templates/agent_template_backend/app/examples/__pycache__/ic_examples.cpython-313.pyc b/agent_framework_oci/templates/agent_template_backend/app/examples/__pycache__/ic_examples.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8253000ac8f1de60e9f21de0a2a0b01952f538f0 GIT binary patch literal 1754 zcmdUvO>Y}T7{_N{?Oi8T^Fo_Aq8Zu<>MFGlv{X?G(&83js8W%QK}d#WydFE7tasg+ zb%;421fQXYoYEt?fsl}UA`xF8RU~Td35ip0jzWdt#4~HVR1p=38zb%WGSC0nnVtFB z$K&HBf?;g5)~hN)zldZsk_sfppMbfCY{ZZ)+48&6J2I0ovXzQ#s}-f9R^%(P1{zzd zsJ3pWuB7dB7OksH`x}h`8ndD&I@8W1x>O^T8*6_Lueh~En=L=&xJGfQh%e((M4KWh zhC#$apXN=oROFb^7NeX75ouz&34YKL(8iD7xn7vZw|vSm@xA6iQwr)KYZ530#9ze4 zHY2r=d1TQfFwu!TmoMTsy~cZO$~rh~1Ck{efXQW9# z4cSKCd<;8BIVo1GpcALVDyM9dvRLC0iD+zk!Di^W)bVPu&S=zT!LqA}mf=W){|cVt zpTJx|7!JFPR-|F|8D~pnY313@Va=AW4%M$q7l(7T2?TF?j$Rq*pHo-=p{_lx%eJ0Z z?UbEfQc8fx8tiUUx~D8_W3YMyrO~o>O{q&cWBIe`QZfIQwOU@WoZ_8jyL@}qx@pCy z;aK6YIEmnHoDJHEO-?x%37nS^(SQVz2-BnicL`BWWdco>5oSyn9n2pYxE4-B@YRD5o$$9WjAy(#pk=VvOS(09(t4JL84HVx!!t5_f|J zwE}6i3Zr!jp6iU_e5(`B(gD0qoxmLv2R@9q{fN{En}!9%o;d~c7=3|y=Hw$Y`_Rnx z(&v88&hO;5a|a8r9cHgR%C2;;{;>35X|Hm4eWf>hZfACT_Wt$5*+OsT#T{eYxPR$z z=5jB)aAatP*&jnwxIck1bA4oF^xu%7>BqwS&L?4|FRghiC+)u^S+A)3=XHqV3~`f# z4glU*4mVtJ6r*84kbu~O;Qt0aU{Q&t^dSY9E37Ch8XVrn+x``+1Tc UtbQ=?ACZBtuRjqoHV-TQ2}o>>ssI20 literal 0 HcmV?d00001 diff --git a/agent_framework_oci/templates/agent_template_backend/app/examples/__pycache__/mcp_examples.cpython-313.pyc b/agent_framework_oci/templates/agent_template_backend/app/examples/__pycache__/mcp_examples.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..41a72082a32c7dcd6099f21ab72c7a84b01d603a GIT binary patch literal 1896 zcmb^yO>Y}j@a?C)YsXFOC}drrnAfi!8Z7Bx|$#NH?)}w{O=W zj*1k)FW^u?PD#b394dtqJvK@YJv#Ei)`~+VPQBTRDulQ&&+*cLY9u69dh_P%&CHuO zGkeg559-&_;5q-%vaykphU8Ey|bVg@CW@cH!sz~QnS)GR^ta7WcUtd)s!@jpKW&=lXuhR`aG?C}1L}ONL{)s)J4J`^Wc) z?dIfXG!+^Xa+6LuOq|mW4Bih82ng2PNW|G(piv zv-=IK(=isIL8L;4SJ-7H62I7W=6ahu!CYyxtsVp?I_R^Jz9XzK%iIe~5vFr1LWi?_ zbhd+B_)E^|Vh&zfkB@URP#d?v&lYo+TM&{oGPHdDu5HIF+zQ{pt`yllcSp#Jirzsl z&57Ju|G#_C6XX0p@8F0Xa+mx+a`$;GdW#iN@6yrr_ABYBoX|0+;t-0Xg+o|Nu;ll+ zFBt8@Lf8#$0QKh^f$ci^O%f^X)^5MBd#&W#4!DdOQez3! zCkne=Vz1kdQHTUPDTwBLB&@rs2`_U@GGIXCLv9^|CtS24Ml6FoVy=R=zz+=o}(huusRRe-#?_8QMklp1$vtZR=*`d1f`o6NK9DGn!M(X{q?Mr*o!CTe-;kt6UDG8F?NTSR@ zqX#7}HjtDMe?yWW0tTQD^|M`exaVdw6E=H2Q$@du9m%ac)6yGpD5#% z_vfn0d`;0SpXiaZ@v1UhQ$`Qd4GHxQHIUE?hJ}>4d$W;3iA)q<|G&rgOIrE<&4Z!) zd^J7XOo$L`ipH90#VXTSWg065{V18_5F;E%`vknmo}{|rEbV;H8%@(lkxiI`U!;sBGrKiWXB zJsfOpkE|!7l_mYj*pbtsD~5HpyM873vQoZN3GSS@U$uA*gr?Y=>~ngYs9^q2u+p;W literal 0 HcmV?d00001 diff --git a/agent_framework_oci/templates/agent_template_backend/app/examples/__pycache__/noc_examples.cpython-313.pyc b/agent_framework_oci/templates/agent_template_backend/app/examples/__pycache__/noc_examples.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a8f3f88711923277c99fcb4759848611ad3eb33f GIT binary patch literal 1843 zcmdUv&5zqe6u`%^6e(I&;zOj;njj%X7}uVr-XwN* z#@RL!AOwFy4}02jV-HC57EW~4OD{-^_RugVBu>4h3KfDAZ=9H-iV6-~7|Czmn|Xfo z{NB$q$>$9OLvQ!ie^e0qSs2O4&6LSiP;MX#QDjM0>K*Cr6is1d$<36dH07q!Or1%k z!N*EB6-#ZVtqeSxrJu=JMhUGeRQ(&@EchmVhLwx`GA-TA_rHfw7q63UuM;xt5nR8t zS}_cen35hPj0BN`Bhn#V5>em5VUJM9^~1pFRPZHyEu`%$o$wm=LhynpPDJqfoi8!z z`k;wuOG~f5ECPbEjFY9a6?~CJgkh4L-3?hpoh~Mua3tj7cz%40&+tZ{U8?uUVUlh`mxLgYcTnjHVLN^KJX%<0hJmd6yyH7hjE9^eA zU5LjGk#^t?>@MRfB~hOSbypNQ8KQ4rz%$_>$_PV;8fZ;Qwja%w)R5NXM|PrFspXmX z1!-}%=sk@f(i8mU#QzEV%0KL<|J+YCIPKWm{xjK6k4AZ`d#*Wj$C(u7s4t*=;xF$Mm!v>dIBr?+! zeiuYVN2n@9MhFcA6Khxuej(wHRi{ZMwtd-g+a&O+POn!@POU<4J25J~0Y5Y&(H4aG z!KTykJ%^Scd{&&(25}#KhDOH0d&a^K#==O;|5Q4@ZEl%+C(rJe&fP1m4VS-L`F7=Y zbN~F>sCaC_%!4qMzmT;cR%56{Sp`$H2nwH1 z$e6cini}`)D?AL{oe4 t$uGitd@KuZo(9U{&1krKyD)t7)~B(#_x=adxwSr>L-tU((H9_rKLFfIuTlU2 literal 0 HcmV?d00001 diff --git a/agent_framework_oci/templates/agent_template_backend/app/examples/__pycache__/observer_examples.cpython-313.pyc b/agent_framework_oci/templates/agent_template_backend/app/examples/__pycache__/observer_examples.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3b7d6a833e47c463be3fb2fd1743e45642680257 GIT binary patch literal 1352 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 literal 0 HcmV?d00001 diff --git a/agent_framework_oci/templates/agent_template_backend/app/presentation/tool_renderers.py b/agent_framework_oci/templates/agent_template_backend/app/presentation/tool_renderers.py new file mode 100644 index 0000000..f77c47a --- /dev/null +++ b/agent_framework_oci/templates/agent_template_backend/app/presentation/tool_renderers.py @@ -0,0 +1,74 @@ +from __future__ import annotations + +from typing import Any + +from agent_framework.presentation import register_tool_response_renderer + + +def _money_brl(value: Any) -> str: + try: + return f"{float(value):.2f}".replace(".", ",") + except (TypeError, ValueError): + return str(value) + + +def render_telecom_invoice(*, tool_name: str, result: dict[str, Any], state: dict[str, Any], agent_label: str) -> str | 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: + plano = result.get("plano") + if plano is None: + return None + parts = [f"[{agent_label}] Seu plano é {plano}"] + internet_gb = result.get("internet_gb") + status = result.get("status") + if internet_gb is not None: + parts.append(f"com {internet_gb} GB") + if status is not None: + parts.append(f"status {status}") + return ", ".join(parts) + "." + + +def render_retail_order(*, tool_name: str, result: dict[str, Any], state: dict[str, Any], agent_label: str) -> str | None: + order_id = result.get("order_id") + status = result.get("status") + if order_id is None or status is None: + return None + lines = [f"[{agent_label}] Pedido {order_id}: status {status}."] + total = result.get("valor_total") + if total is not None: + lines.append(f"Valor total: R$ {_money_brl(total)}.") + items = result.get("itens") or [] + rendered_items: list[str] = [] + if isinstance(items, list): + for item in items: + if isinstance(item, dict): + value = item.get("descricao") or item.get("nome") or item.get("sku") + else: + value = item + if value not in (None, ""): + rendered_items.append(str(value)) + if rendered_items: + lines.append("Itens: " + "; ".join(rendered_items) + ".") + return " ".join(lines) + + +def render_retail_delivery(*, tool_name: str, result: dict[str, Any], state: dict[str, Any], agent_label: str) -> str | None: + order_id = result.get("order_id") + transportadora = result.get("transportadora") + codigo = result.get("codigo_rastreio") + previsao = result.get("previsao_entrega") + if any(v is None for v in (order_id, transportadora, codigo, previsao)): + return None + return ( + f"[{agent_label}] Entrega do pedido {order_id}: transportadora {transportadora}, " + f"rastreio {codigo}, previsão {previsao}." + ) + + +def register_tool_renderers() -> None: + register_tool_response_renderer("telecom.invoice", render_telecom_invoice) + register_tool_response_renderer("telecom.plan", render_telecom_plan) + register_tool_response_renderer("retail.order", render_retail_order) + register_tool_response_renderer("retail.delivery", render_retail_delivery) diff --git a/agent_framework_oci/templates/agent_template_backend/app/workflow_actions/__pycache__/__init__.cpython-313.pyc b/agent_framework_oci/templates/agent_template_backend/app/workflow_actions/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d217376044aa07f27746a8bbc8017869e7897083 GIT binary patch literal 199 zcmey&%ge<81i!iqveba|V-N=hn4pZ$0zk%8hG2$ZMsEf$#v(=qhIA%P=9i2>VNJ$c zoGGbg`8lP@iTQq-Ot%<{n1RA889oC^hFgv$sksF?i6yDU`ibeOc_r~Metc45a&~H7 zihg22fqr>@QFdBRetCRia!F=>Ua@|Bd}dx|NqoFsLFFwDo80`A(wtPgA`YO5AUlge Rj1SC=jEwgf#EaN~8~|9dGr<4= literal 0 HcmV?d00001 diff --git a/agent_framework_oci/templates/agent_template_backend/app/workflow_actions/__pycache__/devolucao.cpython-313.pyc b/agent_framework_oci/templates/agent_template_backend/app/workflow_actions/__pycache__/devolucao.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9ec9aa1b6daa7d9bda590c8289fbfd5b1b8db60c GIT binary patch literal 977 zcmZ`%%WKp?9G;nE)9q_ZX@$0GH?~sUg55sxpa_;Og4Kde*Mk;9noO6pNhZu>Thxo_ z(W^o|x!&wS=&|?y16%gwfFOA4ZA(siawfZ3so=o;9y8zX_07cn{XIae-|xbmD+qv} z(n(iW+lW13d;kWZz<>r?g%1%$I@m-Lz)+T83uUOAijfgp+f)`cqiYQ8s7vhxR86qi z|6sc>U^A7TLT~kf2)%DdE(w_KVBI19$=ARodWflS1=z;E9uVEC;2^?xbfVL05V=0q zF^f(<%d2f_`FNku-I+7lMFH{w>1}&t-?Wm%Jhx|gu47R%#E$C_u7#EeVm!klE5cl( zII7aX7PNGhCakw&$IC)Y0$tJqpSLLhpbXZP4z^<$C>=c2v+z2&t!%@Bvc@w>7d%U- zgQ@8{1;o`YLOiZiaCC@hM&zNgE|ZPuI$w^kA9|ugR!rtMQ{UXO>|GoR^xazoe)M72EI4llhu|d)W z&))TkQ}ysYIx5cOcVK}KO$9>u4Ltr1md-VR2J3^@8gQbCAY7;oH-S)JoJ1W(vGigE opvmO=Je$C$8t_IFA@~T^1W@Xu#g;x^i4$Lj+&oVpbVQW=16iEzC;$Ke literal 0 HcmV?d00001 diff --git a/agent_framework_oci/templates/agent_template_backend/app/workflows/__pycache__/agent_graph.cpython-313.pyc b/agent_framework_oci/templates/agent_template_backend/app/workflows/__pycache__/agent_graph.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c5a3581927113268636bb146f308f6553041f9df GIT binary patch literal 54222 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 RPjd6!8pB@~<+zQ8{}-oiu!#Tw literal 0 HcmV?d00001 diff --git a/agent_framework_oci/templates/agent_template_backend_day_zero/app/__pycache__/mcp_gateway_client_factory.cpython-313.pyc b/agent_framework_oci/templates/agent_template_backend_day_zero/app/__pycache__/mcp_gateway_client_factory.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a8f0280db78b0089151ee0234a0faefa1c84a8e4 GIT binary patch literal 1034 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 N!@|C22>v4n{{V^SoSpyx literal 0 HcmV?d00001 diff --git a/agent_framework_oci/templates/agent_template_backend_day_zero/app/agents/__pycache__/orders_agent.cpython-313.pyc b/agent_framework_oci/templates/agent_template_backend_day_zero/app/agents/__pycache__/orders_agent.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cbe2d5df6826d1114751028c10bea6eb013b306e GIT binary patch literal 2459 zcmb7G&2JM&6rZ(sosI1{Uv`{00TyV8+=3GX1{EPh3ONA9pe#nAMVfBxiP^9pW@eq@ zo)Ab?4mtD^wU<_+tyHLlRH^?!QBK?vrBzm|Rzm8DOXW0h;MO<0YZIzoI`%%lnfK<+ z+xLF&jdyx_;t0m~&u%O}>q6*HK4}jrWOhyfvx-zikt(Q>OTxtnjVPRtUW#56si>e~ zbO5Ph4yn>ju^0{ZQK=TocQw9)S^WI;4dtVm*(=Jmnafu{oW3@r98s>&Dxqw;Ml2^D zpJ8_z#2}8Xm}^fg-L#d(wTDW@HtU+R_GF0|oLA1-))MT|9No6mhG}ZFd6}3tZ5HBc zW1cy>)6f)KsZ-eJC`8c|N@`S7szk9!ZSCiZZi5|b!KNkwJw_Ue#?L2(_zUiIUhr~S zy>2wIzl_1qf^HE03kE^j@4GwOupHeam-V~4RS8};ppkI0a|W1IbQ4hlq83pF8dW1y z+>74+s4|b)qCh28${`w4V?evqE-Kfe`ED<zN)cIwew-H3J8?->A*V9b4C$Zfuc z9t$P#H)W0@I%a*+ z07C7>$uPx+=5RbJ@meFh{_n;7tvQP|HFF;w}0u(F> ztI?8_g#ECigNn93LS^CO4kpTiDilK>%8_!kEUJAmD--Fv4ZptylzQ_XV1y#f{^bjHLilf0t7 zYZwj-kPKbKA$J`w$zcs}*Q%PMQC=!uFEl&Mn;o7$ckROU87~_^7>9d0>UqhFX%_nw zP#?Fz7-kM&kB)L9QLsz*0S8J$bxP{+3SlXP2hB$#>B-mrMR3Ued44&?7nq61s;jjc=x=w&baGdFuIKc5Cp^#^510+5da) zxZ9U;`{s9~=xC}XqmglU_@Fy7-s(r`i5BWk$Cu^S5E>ra$`&@Vg-4B_%wOg4smo}IHmf(rY;RpsMWSY4i5)&clDIe84U7?DEXGnUSqbVIu<( z+{_fWdW-9Faih2Rn(=meKeJc(QWz7zlJ*Mu?x3amz1HuheqZ%_t>0#ObA8i<^KvO1 za0x*7vow=H_lsj}+SLYJpV&)c43%btl3t7#bjlnfxPg$1@t1lZ?)1Sr2c z184YOr8f?G^64N1XXq&q@Se+fQMaOkAZ$k@L41`$!s$QI)XUgO;l%pD!B+@=eFOgh DGN67X literal 0 HcmV?d00001 diff --git a/agent_framework_oci/templates/agent_template_backend_day_zero/app/agents/__pycache__/product_agent.cpython-313.pyc b/agent_framework_oci/templates/agent_template_backend_day_zero/app/agents/__pycache__/product_agent.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d394a5bffdf0cb7a16d3842fc00bdf991d7d38d0 GIT binary patch literal 2564 zcmb7GO>7%Q6rT0&IvdAvk~)s_*D~}kG6W}8n^sg+)lhP1OVg-ZqwpgQoAt!qvOi{K zH`JUekWddfaH-$|5(3l~2?+^t2l>RUQ9)U)K&r&47vvIp;KrNXwVNU?jJ?k@^WMC9 zJMVqpcxP}hhoF7=(`(meHH3Z_gKksP&dzb@+(J5HNSE}?1?hZ-Ww7YW7v%E_Q!pAw z`;o3pB3*q`S&)-;Ol@QEg;Oi&vKL3wVWj^}zHO8`Sl4 zxh4KiKyB)K*lB;`T8@XWwLizE=QIt!{mlloMIWE_+zraO;ai@o2aaQ~)mA`F^7U3rvWy^{$>Hd$=fC}lMZ%HL+2KH6EO*nEu%|J)-z1m zho1iEnmDv;5>s_`60xkF1=*+fF|8q2`lI~rBYKzzmr))f>7ClL87D8@Q|v8{ey0iI z7Fr#)Qw2h+*p|A3)p@%cC0adWr^y1F6G36?l?hl8h_4Na568X9KV&6NkYDg(wIyB*d@~BSP#Eq6mVE1H!!)(K+8~&e$2Z#noD3}5xk_Sd+57Y9y?XiRyN znwDW(+&3_F1S!-5-{Z3wGVFRB=pnAg_HB<>@zV9CZ2<+roP*a5NHO--DTAf34)|sR ze8f6>otlAfFl@AMx4)-6o)ny7F-J^&;Z<>sQ(QOdu*b!-EBKwjaO)nfTfFJHg3Byk zttinTZ*eHElv|2*KK3*Z2tjJg5)3NS`PK&V6zDp@>x<=m@F zQ8@t#N!RquD{7QAT>dWLD(8YT0*3)$oDxoC@XMZo9vF=^8EqPjreN#(i3)3hW!GVr zb3hAcqAa34P~98e+mry@NetwABsZvE>0_fpug051`566aL~I%~Y_CvjJ#QF>T+~a7 zP*xIpnFVe%{1k9t=8&-c3dBP|&4cp9&3rgEd2=8Xy-pSl6}JnOtwQC_q5FmTZEgOZ zHvgbl-Yy>ADjp8=Bfm}_3x`Xc3>rBr@2K)rp`)RRL*e*=aNQ=dWC-~O=;p+YJrR|YRH?t4Mro+kS!>O6D_)Iu6d%N{{>)w&`_h&9V8psak zIw;$pd$bqzA9*y1_N+*M^JgK__oo&Yq)(;ABg$tdp!Z`*T0E-!I5sW%MnqxF+TgAMj&%)(0>|bEaRAzIO_L~32*AxwHA92|EV*x6 zE_FRnD?-7>gxBYUsDg+}Bu0g062teIwFb8pC*&?-XW0p8_GHtHj!?wJtKC|o1e z_#Wa_AR73S0k>g_vRx{ufANQdi5ofzM*Jsx5@4jAN{-+(I|&Lw>|7wbBTJI>D5FZs Z;{uXS{f6fM%ASyp-zy$`jNmtR@DC@@r=I`- literal 0 HcmV?d00001 diff --git a/agent_framework_oci/templates/agent_template_backend_day_zero/app/agents/__pycache__/prompting.cpython-313.pyc b/agent_framework_oci/templates/agent_template_backend_day_zero/app/agents/__pycache__/prompting.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d96c6e4c1af487e002014819ffbfc640032fcfa0 GIT binary patch literal 1183 zcma)5%WD%s7@vJ4DVy%bN-0_>ETu@(ril*$--(-hbWN zek&vNLpUP?UzpUNhV>mPqq6h_J(j3sqOw|+r_r`b<(iUD{Ssk$DbC^`2s!3%7%)4@ z77$W~pVVKKM5PMag#E0QrRC)Ijx?Wu&P{~Oi{j;T;-RaFuK$1iBtDQU^0}Opi+co0 zML9P|y(p)g+7y#GW6Oyjs1^0EZs1js=1@g7P&r+Z40KDGL-|boCj_rKt_>r`W@tu~ zRNbA>bO;3^QF8dccH1Q{Qyz zk>}c&0ww$SljGKaH$a0bgqegzzzcisuE;2Au|6aY!m6%E;tWXRWQWINBVw`s53?BU z%9@s!W2HuToMN21Q9dOOAUifd7Os07WQakgN26M zL#dV+U^S$^720lTG*Fg+Bj0+7?N=mlEC)BNT|&bWj-q5%rD1b7s1>6|JPm-?u>O&m z(4!MTM1_wvVQHe%ag>`paQEF-u4Bx14g0Y2Ve4q?W23XQ)?HfvyxA>moD?>`Se?QP zK-<`EuJ>|N2YdT_t<_HMS~piXoNYer8B+(|zSp|fF&4YVjYHbiS5EYmj=tJ_@I5=x z%gwaMW_rft>*sHtwTkVl`F3`ptuFL|1A3ZI({b2i72Y4Gx;QE@Y6nvYze2|cUjkdw=K(c>81Wh9sB4|*sdaSukxa4m4c(;d%oj<~VVB=4* zv|X^#%1*e#);%tH#W1roZys#f?{~q?>-+uck^y{IVn2BGsg8<7o>AZ3bN>nXp@UzKG4=_^e;r_V>;rDUy5r|I^_=w&GKz9R literal 0 HcmV?d00001 diff --git a/agent_framework_oci/templates/agent_template_backend_day_zero/app/agents/__pycache__/support_agent.cpython-313.pyc b/agent_framework_oci/templates/agent_template_backend_day_zero/app/agents/__pycache__/support_agent.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9dee7059da020e37fd2a806601d770b8999a8d6d GIT binary patch literal 2461 zcmb7G&2JM&6rZ(sosHu-AGYJf4zLA6uxo1eC=nv{ciLGcg&TOo~#nX zj>o60I}Xu^ZA$w3Q$y8FX=(kTR5A6MVy{14CK}_V^QN&(sHNDdX~>SQE3|%@=q9Zf zMd za!ReH)v>>f!O)_r5%voPLE7iLJL?#>s*}s=UDc=rZyV4^IBA{*W)0m$l!LHEWR6DV z2<7*qy&qX*L0jUeAPYG}V{!~=hulHMYP8VlC3c7CMFLEE-Bu8_z`vP_k6w5vJDkP7 zSp%|$=6bbIfY6+zajnVRgw}Es&7IRiv_R*o#`PJxtbPhuiw)kOM)@?xhA&w zDtf}rfX7iy)4fg`fYgai>t2^_ni{62V-xCiQKgD4LYLJF@q~&}xkWtDBDSp>Rm&62 zc_stBnC?UBC9MEq9Lx)GkGF`nNW0)v%A!HL8A&qI!$>b9eT?)ok^*9}07>oPk#SqE zjcY)txilVvtSL6j2y9l=ahvEhm=h}$w&r+VsoW;U0$xz+_)|j7ambTE#~R-QO0ib= zM2uBKwK4WGyD==bmYKWO2_W}SV-TgYtD-w}a5d@XkNheQhBT8~jk|-=YIi^ehF81X z{bRq0`6lc`l{SVjVK_X1r}-CZyLZabve4=b|31%% zm18mwR`@bE+xcc!i<5S~QD!RxOI%b?{P`qwd*1wn5pGb}#mNYAR z00vqNVeGO($r7{%1=@j4&5AMxtIMY5tUp@+)`VVB1qqb3QY`RLW_1gY59{9R(knGg ziREav6{ImV5u4n#y#&i?$aQ5wu@%bd#Or}(hgq}3ljpBpygub+gZ#zep0;{H@M4N# zeF7;TH^3OSY)CwsXGWr6mmUBPlm=>)fZHUjgO(jHIq#_20<2mVB(g;rVqQNa-m-a{ zV5mgw*Vuv=trEM?LDNhw_=k82zc53O=rBm=J|-61)+Cr(49c*0Xokt7)G@r?Jvj|4 zBTV-jATJ=HpJ#_w67E25rORbpBZhiX+sVRavha9hD><<(PHc!1&r{j$)RE295jWBI zd+vnWn{j(TY6{VOvLT|O5qI#AJ2cYhL+Q~5>P*L1#Kr&`9Nx|rH?zgZ&JV^y0;1tTVo|4|N{f$)WzM+-vJC zaPxkCvc!GGO&;UFJ_X#f3^#e4e>O18_~RVVJ=MkH`T(BhIUqrG{oji6bCzfMN?AjK zizE#&Y8t87nB`UoL?PmXL`Ol#V#Os%LD(~G?cKO}2loK+pE~a`Qw(1Qjhh+T&J;H@ z5W=lYX}hPiA(l3KO0O-}P48#+b6;@7{FlOhuFx5DRKL~w&D3wJeyjDnEbFardT>FU z2?yK((EAKUC(!%i80+SO1NSHP5*Xic6fKnWV7#bO%hptb7$%5$CZGe%>f4MIfp{70 zmxNluifvPM9&Ql}<0ps?G8LAOe#QBOy@53WNF>u42-eLohih;4vZJf3OJO8_FnYw2dfy|{%}i$CALch$($gSd4cB62-H37=w-XUK{#6ojXZ}DFFJq^;lN+hSuMqtD G2L1svB7o}v literal 0 HcmV?d00001 diff --git a/agent_framework_oci/templates/agent_template_backend_day_zero/app/observability/__pycache__/__init__.cpython-313.pyc b/agent_framework_oci/templates/agent_template_backend_day_zero/app/observability/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..359dee6e45c3f33c435089d7c5c4141ca2ed9494 GIT binary patch literal 200 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 CR{LZC literal 0 HcmV?d00001 diff --git a/agent_framework_oci/templates/agent_template_backend_day_zero/app/workflows/__pycache__/agent_graph.cpython-313.pyc b/agent_framework_oci/templates/agent_template_backend_day_zero/app/workflows/__pycache__/agent_graph.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a39b5852a026f642b44beac29cda2ef94d232c11 GIT binary patch literal 44732 zcmeIb33yxAl_vNemWPGl2JSn!6BG%Ok|>EUH20`CC?A0%0ESLOSrp2UOu?sD$>?mg$+bI-k>o^Iyw%>3%v=NtYd$Ne3>$d4}O zxWAj{xbJczC-VJVA20DXa%=iEeOgJ|r;~JjdP&dxwEaS#K{7D6uHV>al1$94?>G0Q zNomY2^jrGUrF7;t^k?*CN}0@U?9b}Uma>`K)Nk#}k#d;Z+@IT*C*?7BT7Q0DfmFcU zmj1%NBB_YE)BB72N~99z&gd`gE0fBYJF~yMuR^L|?yP=WU!_#Z+}ZtAebrJmb6fjs z`f8#LXQnLD??q0cVanLDq)v2TsEhPm_moBEoiX67#Fcl5PLEjF%@tK!7M zVooe-*F;-QYGr=K@GDXL+NMhFWxu8fc0N)zF1cOvZs)YiJ2fS_=8ieXkGaQRn49%@ z=iQQB8`1U*?u_Wg{hcHGBW7_PaeFBml4kcVxTFcm<(VG#%(XC6VE&hdHAtXF;;ar+jg=kb=_w=gl~PDIc{8P7=`pL=9>fyw{`E6`;> zJuAI1IX(N*e)qI{#yu~cKoqM|m_*+UhCR_Ie*hI_HQ4EP&n1SWcTTyz^Fv2{C^*a2 z(&d>(t)`eivak$Gvl9#B^YVMzkTl_zeDbRWg`As}lwdOpU@b;f7;#OB)Fk87N=30& zch4MkPfQ>W=bSWq+yiu!Pb_fUg|5JRh1^B6h=&H5an87BW~CF(8JE{J<(9^yeI13$ z=du;=-{p>Q5-)O+M&u=}sF8G{R?>^QBf@%(s4wQ8*GUFZIARnHM@;K=qLKNSMU#{^ zWwxh9iU!-J9~WAVKxuhCMDO5`z3U;&E=i z&)q(oYZ@cKJ+W=SwBT;p<(l@n9k!uWNX_H35<0~-?>Rneo0nWiUDL;0w(;2+TYOB~ z8W^q?pUdl+_ndUMAUo+q%hBoC@fTW-xx5pzG#(u09^bs%=8D$W=05J3ccEZzA9@Gj zw)xqKS)UF6>4QM=rjV=6Z9^Z;U%xa%S=>Fw-3LnjQDF%)4jk-R+A7%J0sjuJIS# z-U;V~>xA>9TbgZg&CRt?-_Qpr$7U0UW9~%6=yZC}h)!puD&^R5$Z={>HlG3DOI*0n z_Ko!WaB>mTI9eQSH1CcW#%D1XygWZn)s`PxDZYZg`+tSHRdY5p#V9u-hbH`vB&Le_ zAGFG|;2x|V#}MN<|6T2%-oh;a+uZt5T@H6Z@6)t!K1~j{+sbjXqa*qRq%miE>~~nR zH<#nmPztZ$)hDGc;yAB{ z22o4J@EQ~F8AY9_m+@`m<@gi8h;>0fVv1#v@FSPoYZ^6)!WM+MFq+2L>Pyi^ED4cg z&Y{eN@Ql^rUh`PC>^o{oC5p6G4U#-|Z6funS92g$y>5d3k zuzj=Mg+@feGCDWw!$gG1>cs^&CMO$aJKL1JFk`;7`CQlkbi%c;mPN;M;gT?I#gh5l zQwttUa5k3@38%0B>AYtgP9>Eik~PiN04JMxv4H#Rg49gK6I^UTm)6mX5ojh{-f?#% zL!Lz^uvEP~A2DKqMzQ8y3lvc)Z!FeB3T&f{CuSXXJxo6lfOZ$4gQUmDWe;*Ug=X2j?|?wVepDe@uHtQ?2t1z#`E zalfXCwzBqO*@d!DWk;a0Bmq5z1Y^TouaM63E#S%-MEoXV~8CZ`&8N@B7Z-P+sjX^J;HC?Fv0T6?l5;)UI1O zW#PP{P+r~H{pSyzI}|P`yH!wrc46_Dzx7D4;F()Rw#B?9qkrvWuxKh=Q4=n1T6*4J z)Nwc6kehLbGo)wSv2vE|U|Lxe(V0W158W!L3>7p63L3)&1Bpq}1WF>LXMB>yWfh0B z^Uf5VE<&yLFKO>^_*tHKKtEAbgkT(h%0rVDJ@>x{ph9^Tf$r3c+Gdnp zraqtNB|#L5IZ&YnKqFD0l1VfHnng2UnwSP?5iNk}Vme@km;sn6W&&o3S%BGMHlS6s z0_KQ0fVpBWV4j!GpJ~r?l-f_>I zYnsuD6SE$l4LyZv1yiFmJMTvSdFP2*-OGG^3q<*2x}s@RLK^R+XKF!mUB7t!`?H(P zHroiOygh@x&b>oBd$vi8uYs@4=JA3kb|%bK&D((=lr%_vdA4ZjN#clXh|~rO6Gd>7 zJ4#w7U@<4>i1NkQvB%Ff&T~;7aSTqDG5HO~%HX3H)Y&&n#4W3{+1xW@bIlw@gWx}F zx+WXgmg_&ooYxX(FXq{2b=Nh;cT?o{c9G zH|gj;EseZ?z!+Rf86UJwqg$iT!PaS7W!ZD^scA~Vo>3uzXaQauH>O}8)rouuKgvxj zMBu^UX+chTaBiBuMD`r~(zH=_kLAd&gQBSE&>+1+VvT{=i#{NY6kpj71P#c>=rcy& zCwo9TYDJw)3bn^-lp-ehyX2Un(4j>c6yj~HLdHB+DZ5abQrR8p6+CN=h~ zC~X2kCu2xa+TX5TrVc&or4X27^>S%sLKmS5**CUEB~&5f##-diQLS8Nq%M?w$7tGT z&x-J3*>{Y{685YJSK4%psO{C^<+AVC4%s!TPsraU`;K+Xt`*@`vhNs8|Li$9JhD@E z$A5`5Wuu@*_8aS$T?h9eG>wJQqQah0Z9K6WY>DIle;ngyk>+e<4_I-TW5~X3wtpV(=hiS zrZXNxb|sAGR@rZgvu6xKK4gLzX!-<}d>_5c%R;e8anE39*FcYRxN`(_Y0p4{h+%&u zH!g2*?t;_-K-_QFN~6FY$;3Q-6jaHaO9F%92IV>lp@wtP<(rR`#pD&@=y1=-fj#2T zh;wh}K_}71dwRrQ)2wRONAyez62+D_<9gXiG8K>8CsAKW)KrjDSXYa`Bx+j(X{V=W zm^+d-KRY|^j4qjWBlBYtuSlBYnsSn`4kERPo(an$MxT40)=pnEXCW#m15>gvGvgwO z855k@+oYpZj41+?p+sXyqG^PslP1YEPT&{;nujBW(<#Jn5-kA{-BA=%qHjE6jxXmD zEeVX)ifAEFjTFX~>V(zQ?VSRRClQ?=5uPVus86B=4g7(!XiGG6N362g1)Nn(@F`_d zK#r1OLJ0VJbRC?CJi@&#Vag)Ef`^x@cNnbF(|E@t-Vg}aCPt2UX z<5o`7(*D<-mz>~}{MPLHP@_zrWN-yF-=0M_ zX}5}N{-}xayH&Mrc~7uvJ4L9tRo%Yq306NvFSc71%}btO#U^?wy;V(&VfD^vNM7Y) zLoja*(wlEpZMnQVSk)6vUsAhxEYy8C(0$lHIU6XMBj3VX`E`pgU)dALAEcbawT{1f z>B{_#XZ%N=3+{0FrQ;9K?tHiAZuI94_#w@R2A+eOgXBp+@SN0m$@7bvJz99u4?M9R z(Ocoa(4Ml~DyUxU4is!!+6sW2R6O!47pnvL83G zZB($iUps=gr00lNap?)N4{><0`P4*&v(Vrmf&6c@lX^M6K90k`F%- zofq;JyDp+9e$^e(OnTu3zKRJ?e89}vzVxLp#RMMCm$2zH2LVZK(icrg99to(#}2@D zhaByzNbTDN@E@7bqo5>I&=M$U2^Fjl6s%v~f4MzW(D|!^&X39}7WIF0=*%k*v|M2q z56>Vx3+j|t`1lJtf8!%6zTEh1}H!_)GhM*RG3-i@pN4^eTaW3BVfQx#ym< zMH@ixq>4szRBHdlq$IC2@E z{F@T5Aq8IYSD|=ieDZHfyv7uG$zS2wo}j#@6nM#>$epA|E~osPvb;p$t9=*bukeU* zh7$C%~JY0x$X7;`n5jTz~mDWjkb~z)SwLsw6!! zKKYm7CE0n>Ggc>ii2RDUB)m_0*c_+uo$)|1L)3_w4rObP<)xNhL-IAJTgwkm?BkJ5m%8N#Ye?ho9xC2T`Rlezw$~eT03}k+$?b-Uasx!i0#u9Q@sXx@Q6KZ z_dG_Zpux0*5Hc`+^!E|r5+BiG&kh0*-shvlF}lgPbsAFW3D@>WQxfTvz>CJ|M>+Nn zfPv9eU*cYKopGObpY2_A-pp@jG!=G0DNE_=1inGwn*_c^;57gg!V;HoLv^HB5-6+y zAYyb)OfXtb`YQQ-jljPm@KBV}X^Qd(1inq+I|RN<;121-4LB2?V(=`cI9cXB*+;fnq`AOMgX3jJ1mWV=R5)kxR4GUpSg?^;Qw?!LPIzb`D zsoRvQ<7)w~FLAf5rQbUov^JbFgpHXYV+HXprd z9RDm)&Q>hdyxw@JaoKrgBDCvZVAsK5F#Ou#rdfwkLaAP7gI1w0} z2s+$1jgtvj9vS6q!D7wD#tV&0PcKjWk^?I&*meho6HeiPrJGF*1L@s2JY2=)(@HcL| zY1|$!(khQ~zkTaX`d@!@;g?w;M7gy1|`bb0)JI| zqKCf-X?EWJ zhI_?#{e5_>VzSlejsKC-l57-Gw9?A+d(Q1y^n^-V1EsB}PWX*aEk6&ix;n(fdL$sz1DSG%(ZHiQn zU5^y$vs33PS{=F`g_TII`vS@~*E6cm;d=SqY1kMd_FF|0M zIa)>qHHLr1w2?E!i@7Q4{!cij#%ObaJ)?q{7vGRf*iu)mo7`I~(&xw1iv?cW3*Ckr1&VC_-YQ$QH_HlB8uB~?P zuVWgvnn`R|;C&;YX7H~V{5Bvz`0p9~iZi^mT(V^iZ|qTk?iE8f;V>4t~BZt!H0 zylv}9X1pRK|@zc~j#VLDTIFmv3xTJ|_9Ia9}oQcGC z#IzMX`xmoa8rDRuYBN7MH(j=g;iR`!1fiaN^>&3)_BX|Mb2N zL9doo@RtO&rjCkZGUNtCn=g3hA2t@43iE&U29vI$)Y3J8#DL7cI-1QiUqNqy2eDm96{ zc0sY`eR}zY>|@W4YPaZob1tv+N8~*U0L|_h9G{tzrll9?)kON~EMMtG_AV=RPei{D z(l?QwCqUUm^f-xxZ*()cwJz@osL{B+P@1Ws7+)q|enxtOeoacXqF;ka(Kd~aQX?Wk zJ(WFCtznW>MamyOO0OV}?>~cCWxK991!uOO-X6-S3*^*=E%o7oQtByx<+@co^XcZ0wIN__2xsNpuByLizhL(_ zZ4XxM2vr@v(*91z)s7oSg58J1m30@3E)*?o307_l+iEYGE|``YgSPf?S|FtS7jk*+g+Nx-9gUD}ja6~6C|Iy2 zRM560-OePd`BpMQy_oS<$^2rVE#ZTYrvm1fUq+&r)NU>O@aKTa9Lfb%z^)>dzO1{ z*R8qex#01)b_MIYLv_zyS$OBf)f4`G&jfp)4aai-La=sAxW;~Q&xJip&j)Kd!j%oT zYMYi0T^6qBg0(%js_U0bp@xn?Lr1WB^Q|iTl70E$<@sRM&byh$ynLwNS9J4t3b=yi zJDjD!`T*MaR=5C)xk4!7H{gGupdnmb9x7fNC|(;X-W(|2e0k%QJ;CC^Q0`zbckpf{ zs(7c0!;o>Dc7&{T0c%}2tLX{)@1xD#!OG}d*mR-kPaJR91C={jkKWfCsUMBhj|8lg z+iyQwZdFtTs&>9%M{@)#cHXK(>wMn}(G{wnMMEf$4WTs3I*qah_@t1_$_ZH4U$O_S z>qD9A1DWe@*SChto#7hyM?3ch*9>0UbNR*B2QCf#c<}0;z?wnyXt<&pNDHkGx;6MJ z*!OXleINTZTut*wPwffT_gynxZhPHw$@1fjtENCb9cF;8QEtWqQAzR%CHeH8nJXLR z?`bfk@8x2Y-OJ~)_u?I0cCVDn8{$8`m%&x_@b}WuPIs*+@u&ByxTYcgZa-oA^xgpt z*U-;Dcv`{B%5#U1|HiilQ}nBy`THFF)k1!_R=8TEC3k7wzFh6qwvyon;Tm)$@N#_v zKin)_-`KegFK?~qhg*fW+SkDSwv8WNXMDS|i(cNf@WUI7@22OFyQTv0JuN@nVSG>5 zNx|>86b)~+eqgk~{Xs6jj~713>oVZw7p43@o$!mYDst~A+9y~(EEM4Wu-t;;eAvkE zOA|g^qbGN(p8VU3_N5#B8RYioP#k{+zt1Z8Z34L)D6PMhC%BHm4GeZLxRpW!I&udD z!VpN~kt&eR+*an!751$$1d926WtKpRh1~T9#9491lhinvaBM%A`6vw%*U|u!Ni<5* zlX$3*35{soPkK~$rb#$rN{WbAXpf@<=}8c&$f7j0_;GDzs5z-(6h0$HgB(8vKBF8i znjB24Sye!%5z{sw#38}|ldCmDCLhy`j}>P)_>s76eO=qhbgt0roJuZm`b znBma2$NDZgZyN`Esc;cBl=P&GtCBC`7A7UfD|}V77O=~$7t=pmz0~nD9BMgaK@^ki z&^->zhyGB}fEZEEHpFW+%BSqr6#6;TzS7*0^A4RHxeiy3gMKsH-hr zAK5ihExY2sVor*$=E=Wn^{+ZtZqpR`0z3?$=V{uHkfGnm$ScFxcZ3n4lj?{Y_U?6_~n z9H|7%F8HFM(vKGYGMLgpoZX>hkql~*9;etd z(9^xYXJ=f1fecqlP2#AdMWf`>Ul0!6^Ej1l=cSMF0u=$q{IMebJ%tJrvokJ_H)5I@ zpL5cY2A_0`BIdI*1JM%)SgkneLjsH;q-MhjWzunAMUSb?vVHz|-T#i_D-FcDGnzN! zCk>3B^o%o}Q2IY8?ym{3y!CO$kd->3V=ZJn@_5PO!2+hoSioDE z`LE5N`MuM>x9D9y7R=mnN*8{7rto%QX}GZLyy=|DU$rh+xIR=k7-JdN1UC(aqpaQ1 zK(MLi z0c&H(+7hs~fEB#5`<=n7gZ}-8Zcfhly~k1H6MQF?yj#;tm6_sq)7yT{5vtUF%{bMU ze&FfTe1SZDnq8!hANx7N_iB+YXSWtX>AOi^A5dY(>jT#MaF*=}*tu|7?fGZVJsU2s zJ3o64&DI#IY7bPk-zvxHgJt98nqc`3FrnbJtX#=fvJkIDpp+}FI$wUS zJdB@~b1e#r%NwwL@2~2T{mW`YWi0{fwz^PxTcEs+9Wa03;^kKUgj)GtE?2nYo`$;k zUID$M)eASk1J%8&L4FTsr2l zi*Q}H4emF2zJI&$rlxZ%Uf$YnL8Q0M`~WY!ou(&uRyq9NcJKo_;q8`AD_(B!{D48Y zp#ky??R&-ifLVC2q%#dK@7GcC_t)|R7UBJM0=c*Fdxl`rZ*iO`gl^u#$Dm=8&{ zo&VUI?Wt+W$DvuVc4KY-?M_kHg~5~gicFj>mJazaR(!Q)D+DdSFrbmNuq?ngqJ?Nt zT7qkZp!N4DsAQ#-Z-vTXKf3zk$5noQp*-^6Zu=sMYtkrLATP^1+EDA7{u66v?V!kU!xLTqm zcX>ruk@o5~zAI0-x?KzRHQoaMYw3Jffp9HDAa@>5{sla_i-fLL!?g;&tIBfCW+8Wz z0sj9y?teGOy?pHOvBv#z3=s*77Porbe;vNb<9>y1t%z|iVTt3UPXPXTIQ(u5hrFa| zFm~?ru|~s7)S2p|fs}fam0J^4tBD`=Q6!Z~u==;21WV49oUb@nv6L4qY6<1E#HTxD z3QU+56Q;m_9+~J7h^|r!d;TdG=$I~k0z3VX1^Q)FBgN4CCW4YDsu=F5GCyt6rkJQm zddujwE8x#!^x7k|NfTtikUf)H9c0WJRSi@%#W3Up*`>CHXVOy@>Gg<;v>LK5HB~nC zm_&mnJt=UiNq|*wiaLkRt80PjKKzk-o+SxAUPm%l`-yr`pJ@B!M|_y{TP?mK{XW>H ziZ4<6ts$EpO!}R+^1SY-7Mcsc2L(d|WKt@*j4HW!jiW|d&h|oCjnpiA_=7Kr7Kf&X zhmk-dP7Rx6IUc0aD{_HV3%#10^x#Rg93eMW&eyQhQn6CmI4C6MB)1wqW3wujlnS3v zyj3vneI=?yC&GSI`~(qBEUzd(?EFBtBl;vLTV=Cd1AHs6x??4FLQE&`}=x<&tb!QLp$Jh{f{SPG0~Ic(izu+L3(U}mGBoiPUsuVfVu0cHtEj=GW0 zjN3Oei$F551v^qOQAnyBOf=R)b_kEVqm!S_H4htVlo-g((*K5DlKzeW@iowZqMxL5 zI|;JS1W_St!=%X?=V2JGza=EZSq;L6#C)(ykx&Nd0}6KlAead%$s>|RfF}h+Y^E7od1$Du!{2>U;)u=BI2*M)o3xNbj)F6w*N@#LP1L0qGkkx33aunF5k+Kf}_17t(16x$!Ig3P~W{g+*+8dV<9C{~}B@ARXW|!pgw^;zpT7(o%q@be^FyFb4@4{8YvLL!t7z;>B6%O!R+c#_NJvwfBmLY z!fi-NkDNOaDr*juHIv9R{!(f?-+!+E{Ls0f75-4F$TgobLQy6+{}fE96rM`^4AR|j zS@r8DE}ghs7;NbZSi6&?0r$;ZMeS>5lFc=pYg#-REMEJXA)HfuddEk(rQz~}i+TR? zgUiLgEI;^K+D8?2i(d#25g6JW*rV^ zm4vdYpsKUD;o{~Co0n#S)muZ=T~{=Jlhu7U6Zypn?N3TMOXjJUe}CKAPS}+U=arpx zogP~(4CFO_ZP)F*k~3qc#{#yIcMF5Ikzn4)sa?0ThQm2UuQlA!^4X<#v|M@))Rqd$ zAZvutm~e43nu=^m>P_am%_POh<%-uo$de@-2_(Gl2>STd?uOoS{(2+7YrAlLjh5Vw zmR_Cq%`(21Grn2gnTwaV)}|rgt!;d-M)%hCP987sa6AIu(J;48=q)k4W9EC)E$^gR z$X#GSoE3~Komc+~{_c~-4tcKm{N#6{wnL-3Gye!F-D;XsRjQ|NRgT)IhAVWJS0frm zHOW{-Bj!=lI<1!s3u{~X$7Bv%ShEdJy!)0mcrr^~Cmpf#xNL(7`$j)PPe^}HU=u*Z z0^M7jXpOFG3)CwIu)s_12@h69T0bQ$%Pt!&=HoC$9-ThPU>BB4WfjFFgOySu`{@qb zPOP6E5Cy&k92E6T%x<=w%#F^l@dUJTMtBFCkD#=uOp0vs#6(*|<@+*~Pl%R}#bon4 zO;*u~io}DFyiVH1dpc$*T(0annxDRd@Kv0%zrN#&`yJ0!kAL_`aMv^boVrlXv%k!F zHk@B_#&g=^x3vcI+d}ypmq$W*TLXDpFCV^Pg`u8M-f$pq*uT#i%zN(CE|@OOt_|0& zfi9iDrN>{h>xzrM$vu4Zqcn2(lqdZ;wGYy{TqlnVl>aw#p8bul2L*f8(bdW?^IcZq zCtA4vtkcq!uf4`W6v$t*@LjpWwRDIG`D?j6!F-{s*>J6t@2ap|E3=T>Zh-%a&&&#} z>@)ipU{<1^S$so#Op8$VfYqR7GU-WF?~w`IhFF{ls5+22fdre`>Ra_NHz1#=ka36x z2dogK*t%C(j8z|v$*W;!v51vSdT^W{ol8%0Ds~o2y=2OXu@oh-$T(Akr_139d4f~| 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 P-!t*~_c(%VTKWF~9eL!V literal 0 HcmV?d00001 diff --git a/agent_framework_oci/templates/agent_template_backend_day_zero/config/mcp_parameter_mapping.yaml b/agent_framework_oci/templates/agent_template_backend_day_zero/config/mcp_parameter_mapping.yaml index 5b29ccf..91d57af 100644 --- a/agent_framework_oci/templates/agent_template_backend_day_zero/config/mcp_parameter_mapping.yaml +++ b/agent_framework_oci/templates/agent_template_backend_day_zero/config/mcp_parameter_mapping.yaml @@ -60,6 +60,18 @@ mcp_parameter_mapping: mensagem. pattern: (?i)\\b(?:pedido|order)\\s*[:#-]?\\s*([A-Z0-9-]+)\\b group: 1 + cancelar_pedido: + map: + session_key: session_id + extract: + order_id: + from: message + type: string + strategy: hybrid + description: Extraia somente o identificador do pedido informado explicitamente pelo usuário. Retorne null quando não houver identificador de pedido na mensagem. + pattern: (?i)\\b(?:pedido|order)\\s*[:#-]?\\s*([A-Z0-9-]+)\\b + group: 1 + solicitar_troca: map: session_key: session_id diff --git a/agent_framework_oci/templates/agent_template_backend_day_zero/config/routing.yaml b/agent_framework_oci/templates/agent_template_backend_day_zero/config/routing.yaml index 34c9781..187a070 100644 --- a/agent_framework_oci/templates/agent_template_backend_day_zero/config/routing.yaml +++ b/agent_framework_oci/templates/agent_template_backend_day_zero/config/routing.yaml @@ -84,6 +84,25 @@ intents: - Quero saber sobre meu pacote de internet. - Tenho roaming internacional? + + - name: retail_order_cancel + domain: retail + agent: orders_agent + description: Cancelamento explícito de pedido ou compra. + priority: 20 + mcp_tools: + - consultar_pedido + - cancelar_pedido + keywords: + - cancelar pedido + - cancelamento do pedido + - cancelar a compra + - cancelar compra + examples: + - Quero cancelar meu pedido. + - Cancele o pedido. + - Quero cancelar a compra. + - name: retail_order_tracking domain: retail agent: orders_agent diff --git a/agent_framework_oci/templates/agent_template_backend_day_zero/config/tool_policies.yaml b/agent_framework_oci/templates/agent_template_backend_day_zero/config/tool_policies.yaml index 66c9854..48a83d5 100644 --- a/agent_framework_oci/templates/agent_template_backend_day_zero/config/tool_policies.yaml +++ b/agent_framework_oci/templates/agent_template_backend_day_zero/config/tool_policies.yaml @@ -7,6 +7,12 @@ defaults: require_confirmation: false tool_policies: + cancelar_pedido: + operation_type: transactional + require_confirmation: true + requires: [order_id] + + solicitar_troca: operation_type: transactional require_confirmation: true diff --git a/agent_framework_oci/templates/agent_template_backend_day_zero/config/tools.yaml b/agent_framework_oci/templates/agent_template_backend_day_zero/config/tools.yaml index d85fae1..2329dc7 100644 --- a/agent_framework_oci/templates/agent_template_backend_day_zero/config/tools.yaml +++ b/agent_framework_oci/templates/agent_template_backend_day_zero/config/tools.yaml @@ -61,6 +61,23 @@ tools: - rastreamento - transportadora - previsão + cancelar_pedido: + description: Simula o cancelamento de um pedido de varejo. + mcp_server: retail + enabled: true + tool_type: action + requires: + - order_id + confirmation_required: true + args_schema: + order_id: string + selection_keywords: + - cancelar pedido + - cancelamento do pedido + - cancelar compra + - cancelar a compra + + solicitar_troca: description: Simula abertura de solicitação de troca. mcp_server: retail diff --git a/agent_framework_oci/tests/__pycache__/conftest.cpython-313-pytest-9.0.2.pyc b/agent_framework_oci/tests/__pycache__/conftest.cpython-313-pytest-9.0.2.pyc index db53f3f8ef98d16bce001c8430beee43c5bfb92e..dff3d6833be99c0b51c704c4ecd31b8cc56cdc17 100644 GIT binary patch delta 68 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 literal 0 HcmV?d00001 diff --git a/agent_framework_oci/tests/__pycache__/test_mcp_parameter_extraction_runtime.cpython-313-pytest-9.0.2.pyc b/agent_framework_oci/tests/__pycache__/test_mcp_parameter_extraction_runtime.cpython-313-pytest-9.0.2.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2c07d300f2f2e537e24190299b5ddd1352f107e4 GIT binary patch literal 8824 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 aeQtKJx;KU02fx)l!uHYb>n}g! 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 cancelar pedido must not reuse tracking intent.""" + from agent_framework.routing.models import IntentDefinition + + class _Continuity: + async def evaluate(self, state, *, intents): + raise AssertionError("continuity must be preempted by explicit intent shift") + + router = object.__new__(EnterpriseRouter) + router.state_policies = [] + router.intents = [ + IntentDefinition( + name="retail_order_cancel", + domain="retail", + agent="orders_agent", + description="cancelamento", + priority=20, + mcp_tools=["consultar_pedido", "cancelar_pedido"], + keywords=["cancelar pedido"], + examples=[], + enabled=True, + ), + IntentDefinition( + name="retail_order_tracking", + domain="retail", + agent="orders_agent", + description="tracking", + priority=30, + mcp_tools=["consultar_pedido", "consultar_entrega"], + keywords=["pedido"], + examples=[], + enabled=True, + ), + ] + router.continuity = _Continuity() + router.enable_llm_router = False + router.llm = None + router.telemetry = None + router.fallback_agent = "billing_agent" + + decision = await router.route({ + "user_text": "quero cancelar pedido", + "sanitized_input": "quero cancelar pedido", + "active_agent": "orders_agent", + "intent": "retail_order_tracking", + "route_decision": { + "route": "orders_agent", + "agent": "orders_agent", + "intent": "retail_order_tracking", + "domain": "retail", + "mcp_tools": ["consultar_pedido", "consultar_entrega"], + }, + "context": {"session": {}}, + }) + + assert decision.agent == "orders_agent" + assert decision.intent == "retail_order_cancel" + assert decision.method == "keyword" + assert decision.mcp_tools == ["consultar_pedido", "cancelar_pedido"] + assert decision.metadata["route_stickiness_preempted"] is True + assert decision.metadata["previous_agent"] == "orders_agent" + assert decision.metadata["previous_intent"] == "retail_order_tracking" diff --git a/agent_framework_oci/tests/test_transactional_tool_flow.py b/agent_framework_oci/tests/test_transactional_tool_flow.py index f292bec..e2597ec 100644 --- a/agent_framework_oci/tests/test_transactional_tool_flow.py +++ b/agent_framework_oci/tests/test_transactional_tool_flow.py @@ -88,3 +88,202 @@ async def test_transaction_waits_then_executes_after_confirmation(): assert runtime.calls[-1][0] == "solicitar_devolucao" assert runtime.calls[-1][1]["confirmed"] is True assert second[-1]["ok"] is True + +class _ContestPolicyRouter: + def __init__(self): + from types import SimpleNamespace + self.registry = SimpleNamespace( + tools={"contestar_cobranca": object()}, + get_tool=lambda name: SimpleNamespace(selection_keywords=["contestar", "não contratei", "nao contratei"]), + ) + + def resolve_execution_policy(self, tool_name, arguments=None): + return { + "operation_type": "transactional", + "require_confirmation": True, + "requires": ["subject", "valor"], + "policy_source": "test", + } + + def validate_execution_policy(self, tool_name, arguments=None): + policy = self.resolve_execution_policy(tool_name, arguments) + return True, None, policy + + +class _ContestRuntime(AgentRuntimeMixin): + def __init__(self): + self.tool_router = _ContestPolicyRouter() + self.calls = [] + + async def _call_mcp_tool(self, tool_name, arguments, state): + self.calls.append((tool_name, dict(arguments))) + return {"ok": True, "tool_name": tool_name, "result": {"status": "OPENED"}} + + +@pytest.mark.asyncio +async def test_collecting_parameters_does_not_replace_collected_subject_with_stale_context(): + """A later value-only turn must not replace an already collected subject. + + Regression reproduced from Contas: subject was collected as TIM CTRL, while + context/tool_arguments still exposed TIM Fashion from another transaction. + When the user supplied only R$ 71,99, the stale context used to overwrite + the collected subject before confirmation. + """ + runtime = _ContestRuntime() + state = { + "user_text": "R$ 71,99", + "sanitized_input": "R$ 71,99", + "route": "contestacao_agent", + "intent": "state:COLLECTING_CONTESTACAO_PARAMETERS", + "transaction_status": "COLLECTING_PARAMETERS", + "selected_tool_call": { + "tool_name": "contestar_cobranca", + "arguments": { + "subject": "TIM CTRL Redes Sociais 8.0", + "motivo": "não contratei", + }, + }, + # Simulates stale contextual arguments left by another action/session turn. + "context": { + "tool_arguments": { + "subject": "TIM Fashion Mensal", + "valor": 71.99, + } + }, + } + + result = await runtime.execute_tools_for_intent(state, tools=[]) + + assert result[-1]["transaction_status"] == "AWAITING_CONFIRMATION" + assert state["pending_tool_call"]["arguments"]["subject"] == "TIM CTRL Redes Sociais 8.0" + assert state["pending_tool_call"]["arguments"]["valor"] == 71.99 + assert state["pending_tool_call"]["arguments"]["motivo"] == "não contratei" + assert state["pending_tool_call"]["arguments"]["query"] == "R$ 71,99" + assert runtime.calls == [] + +class _InitialContestLLM: + async def ainvoke(self, messages, **kwargs): + prompt = messages[0]["content"] + if "Campo: subject" in prompt: + return {"content": '{"subject": "TIM CTRL Redes Sociais 8.0"}'} + if "Campo: valor" in prompt: + return {"content": '{"valor": null}'} + if "Campo: motivo" in prompt: + return {"content": '{"motivo": "não contratei"}'} + return {"content": '{}'} + + +class _InitialContestRouter(_ContestPolicyRouter): + def resolve_execution_policy(self, tool_name, arguments=None): + return { + "operation_type": "transactional", + "require_confirmation": True, + "requires": ["subject"], + "policy_source": "test", + } + + def parameter_extract_rules(self, tool_name): + return { + "subject": {"from": "message", "strategy": "llm", "type": "string", "description": "item"}, + "valor": {"from": "message", "strategy": "llm", "type": "number", "description": "valor"}, + "motivo": {"from": "message", "strategy": "llm", "type": "string", "description": "motivo"}, + } + + +class _InitialContestRuntime(AgentRuntimeMixin): + def __init__(self): + self.tool_router = _InitialContestRouter() + self.llm = _InitialContestLLM() + self.calls = [] + + async def _call_mcp_tool(self, tool_name, arguments, state): + self.calls.append((tool_name, dict(arguments))) + return {"ok": True, "tool_name": tool_name, "result": {"status": "OPENED"}} + + +@pytest.mark.asyncio +async def test_new_contestation_does_not_inherit_subject_or_value_from_previous_transaction(): + runtime = _InitialContestRuntime() + state = { + "user_text": "nao contratei TIM CTRL Redes Sociais 8.0", + "sanitized_input": "nao contratei TIM CTRL Redes Sociais 8.0", + "mcp_tools": ["contestar_cobranca"], + "route": "contestacao_agent", + "intent": "contas_contestation", + "context": { + "tool_arguments": { + "subject": "TIM Fashion Mensal", + "valor": 10.0, + "motivo": "contestação antiga", + } + }, + } + + result = await runtime.execute_tools_for_intent(state) + pending = state["pending_tool_call"]["arguments"] + assert result[-1]["transaction_status"] == "AWAITING_CONFIRMATION" + assert pending["subject"] == "TIM CTRL Redes Sociais 8.0" + assert pending["motivo"] == "não contratei" + assert "valor" not in pending + assert runtime.calls == [] + +@pytest.mark.asyncio +async def test_closed_transaction_is_not_operational_context_for_next_turn(): + runtime = _InitialContestRuntime() + state = { + "user_text": "nao contratei TIM CTRL Redes Sociais 8.0", + "sanitized_input": "nao contratei TIM CTRL Redes Sociais 8.0", + "mcp_tools": ["contestar_cobranca"], + "route": "contestacao_agent", + "intent": "contas_contestation", + # Historical/closed transaction must never feed the new one. + "transaction_status": "COMPLETED", + "selected_tool_call": { + "tool_name": "cancelar_vas_avulso", + "arguments": {"subject": "TIM Fashion Mensal", "valor": 10.0}, + }, + "pending_tool_call": {}, + "context": { + "tool_arguments": { + "subject": "TIM Fashion Mensal", + "valor": 10.0, + } + }, + } + + result = await runtime.execute_tools_for_intent(state) + + assert result[-1]["transaction_status"] == "AWAITING_CONFIRMATION" + assert state["active_transaction"]["tool_name"] == "contestar_cobranca" + assert state["active_transaction"]["arguments"]["subject"] == "TIM CTRL Redes Sociais 8.0" + assert state["pending_tool_call"]["tool_name"] == "contestar_cobranca" + assert state["pending_tool_call"]["arguments"]["subject"] == "TIM CTRL Redes Sociais 8.0" + assert state["last_transaction"]["tool_name"] == "cancelar_vas_avulso" + assert state["last_transaction"]["arguments"]["subject"] == "TIM Fashion Mensal" + + +@pytest.mark.asyncio +async def test_terminal_confirmation_closes_active_transaction_and_clears_latches(): + runtime = _Runtime() + state = { + "user_text": "Quero devolver o pedido 123 porque me arrependi", + "sanitized_input": "Quero devolver o pedido 123 porque me arrependi", + "mcp_tools": ["consultar_pedido", "solicitar_devolucao"], + "route": "support_agent", + "intent": "retail_support_exchange_return", + } + await runtime.execute_tools_for_intent(state) + assert state["active_transaction"]["status"] == "AWAITING_CONFIRMATION" + + state["user_text"] = "sim" + state["sanitized_input"] = "sim" + await runtime.execute_tools_for_intent(state) + + assert state["transaction_status"] == "COMPLETED" + assert state["active_transaction"] is None + assert state["selected_tool_call"] == {} + assert state["pending_tool_call"] == {} + assert state["missing_parameters"] == [] + assert state["next_state"] is None + assert state["last_transaction"]["tool_name"] == "solicitar_devolucao" + assert state["last_transaction"]["status"] == "COMPLETED" diff --git a/agent_framework_oci/tests/unit/__pycache__/test_langgraph_checkpoint_saver.cpython-313-pytest-9.0.2.pyc b/agent_framework_oci/tests/unit/__pycache__/test_langgraph_checkpoint_saver.cpython-313-pytest-9.0.2.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3fdd4357c52cdfd5ad39f1e241ff579ec6e1e25c GIT binary patch literal 7140 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 X1LRQ+!wJQDjqF~QDt^f!OGo|>!Q{q1 literal 0 HcmV?d00001 diff --git a/agent_framework_oci/tests/unit/__pycache__/test_resilient_checkpointer.cpython-313-pytest-9.0.2.pyc b/agent_framework_oci/tests/unit/__pycache__/test_resilient_checkpointer.cpython-313-pytest-9.0.2.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8453472727f69487e5eedd894b908605e3f1723a GIT binary patch literal 5311 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 literal 0 HcmV?d00001 diff --git a/app/__pycache__/state.cpython-313.pyc b/app/__pycache__/state.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e4c9a18ce804a04fc3762a745306d02874436ac3 GIT binary patch literal 2723 zcmZ`*%TF6e7+>3qF%Ls* zaSy#9waU#LDlIp2a}WJv&`Q;6EG(8edY1%Ce%xXB9266W3I2&J*|TCLep=Y+&;tFp1sN|QX}%MNF?&D4vBCzvRjMn)+4kLp=*)d^$6XNXdEKn zjAWY<4V!yaY6OqZF0{E7#ra&Kfx5tNE7IPM&=&$}U($)%R~vWu`28BTUCq^9{9fD_ zKIURuw_QX`p3;R*pmBy7BaSWbCBw1zF=e_d1g~+EPaHV(^`7M%2z9#a)S%8Du`nO= z7^cX@Z(Tmkbep*3Cu|~OH$0b*P{(sIPZAq)x_n9=k%0xR)-a-&d6vugxD5;t6J_$G>C|;%^Rc?oK(6Ch zj86#Ix6SGM5KG^+F#2GTW!S=o3*3bVGIY!0nFh8^V%G*lv*$&YPRSlIWUF|guj}SV z{jTx3U5^nPIvj}@!f&ww%`th_rBJzU$Zm@QJjU}-`W~V6?g%J;;}Hs`ABzo4_GJXY zxZzmDX!eTa**bxN0`-PY^*VN8o-iM;f$2VB4n+-1w|RCz&~MJ9V6u;qoN|9;yUm8q z7^KRGnGo9}ZWA$5gRw!>-s%Vybu6Cl3!r)6Qh4drbsN3ZZPVG?1AcEj%tYa%yOv|T z7C{GSbo;<_1EQKoOx-r{Il8**;(Ej7vjc`Q1#B+l&>8Gk3APW`5Dl30t1S0a(PlBE zTi|9kk=|%n1XyJ)M@$~mI;!KkLkVWQ_>ruM`a8PtiROS3x4)l!{u4Fxc3;81$@?|; ziPmy-6Jbgn`n$5dG09U1*)T?g_&7p!$Mj%#5uZfpji*~Z%``%=Gt9MM)ocgU3FcA` zQr)&4*ekel45X?FKcf_WFcq#^aMifF3+uxZa7lR{$ty$*1pTFC7Zwy;=v^>AgFl6T zQ?1)>)vP|#9-|+qBPw83nN@Z|XQ)nUR5zV!_bnmXqq8dXv?}lBW}`{r9|T1{#OsKi z#T4aNC7jM4ZiiEu!)M{8+~N1(y1rRRlARf%$S+obN{n)T?1(&VSI(`Hzl%7FJ6uZLL#jzc`r+)Xi|A+^)1)d;J*b zTo22uZQ}$YTnmeHg5KO>pf2{F=VOY~@t7zmU-BzH^Vg3cLPcbL-j8@%yb-83!fq>O zWY5l1>Gm;K2-E@)>2?Q3P?!zW*|0PpsPjD@OBE4&vC@9n$#slQ@nrjSaVt=_!nNyy z_K>7kWVp&&C(+S5sgrwwdMjL(T`I5qsjkpR{Vn)*BgRKuSWs(wL*+@g*?`xU+)pYN yq`NL+1G_Gd0rAw`?j5*Czk?%ekiss*GwYjjW5Ii literal 0 HcmV?d00001 diff --git a/app/agents/__pycache__/contas_prompting.cpython-313.pyc b/app/agents/__pycache__/contas_prompting.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..61d44228017b724c2a3f9e62a626bc393e4d81e5 GIT binary patch literal 1076 zcmZ`&%TE(Q7@yhQw%bmiictw_ERP5cp~VM@_-I0+2dEm-6)!c}jNNHj(%o%lrlxS> z;K9cM50cB`VTnMb|ISh9lrT}&-orRoq>S_kQ5xfTH_Fa zpGpYH=mFSyB*8YYfCckl2~wC+Sj%fmI@P;a&l^h-8tGyqAEnXf`WUbxR&*X(rWG3j zYsOqZD~(l*bo^LJX($l({eWZc20oKwyh`hK371xh6pUreSDzf8>3POH++gkoDak5N zC@PT-0PIXj?KUW$*os={GuPJ@BBAE=3~MT=JpYgdRe+_FszjaFL%_OYpKAh^iII`Xpm<7I8OomY_TH$PnPfsiMzi7)0EroNZ z{vir`odD_hlVdd=5iJFN*{z6JjRszgvyDh*9edS{NS&8wZp#gr#4iPo>sLgStuszM z0n!Po<|0hnF1uA?+ag8@3#u=POoJ)$ITMD;BH|2}iCqn_BjS``$L6HLh0Zt?dWCQi zk;tv3bz%6}Bf_Z3Z41M}95cC6kV>V*)2!$7tdo6gE!xX8SR*CQvSpVtZp+f8qwTpB zik%>fEAr;PGK*`qo`PljZoLL&BbnN|7*aLaPT*nJw|f?PS>C7~0jo>4364``SMe9gBSZyGyhD>>RuPJS-5&{P{`WX2YnJuqfF@?wxS=&(HK zdC5eS5?-f%S4f*8Atzp!3ORGC1|;I;x?kc!P-Rs8R5gFTT6JG^7et3t9@W-YK(8o# zN%@%fyuhhfNsf+7QGE@jp5QMXLU;(q4#Cw!F#HXmA29L$MiXA>Xga*!(SdgHw?f@a Fe*j^!^2Y!G literal 0 HcmV?d00001 diff --git a/app/agents/__pycache__/contestacao_agent.cpython-313.pyc b/app/agents/__pycache__/contestacao_agent.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0cea8190da2e698a3b15120eb9af0157199a5eef GIT binary patch literal 5317 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 literal 0 HcmV?d00001 diff --git a/app/agents/__pycache__/faturas_agent.cpython-313.pyc b/app/agents/__pycache__/faturas_agent.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..aaaddde632112f23dd2493dbe96c1f3c40afc8ae GIT binary patch literal 5243 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 literal 0 HcmV?d00001 diff --git a/app/agents/__pycache__/prompting.cpython-313.pyc b/app/agents/__pycache__/prompting.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3e5a5bc4667bfc98c78eabde31aca739f6f3c752 GIT binary patch literal 1163 zcma)5%}X0W6ras*5=q=mEh4QTEF#5dO!|Q!(hsCiYpbQ0F4RL=hU_Ga>=!c=FnYH1GdUU6szR*cQS3>m4? zoxpSmsDT#>vl94KTB|ecKom2XglohXwjf^UVnIw!Tr#M4f?_7~5IZ=|ppF>^(8+x@&<=$dpOJ_UOc2UXv~WZ?72mAjq@PmVP6~{c`+DnQXaT~gu_tJbn2l? zE0_VK%JCD8e(S&hhe;z(r^&rkP}mp@)!^_Z ze46NV6y?Sb=ss=bI>v0*s2o}!wvM(wHaZI{-G$Z9o87|tNn!nq-6_0+Xd73WtG(RB z!QTE}Yq^uV(ajYOr<;#^#>9cU@3tOvjQOr{>yUNzr4xOrqc1lfeanvZa#QV*sh%#s48l@N!b>_2i@Z{AfW82j_IEZaC t`LqXAju5*l^((S!{*T9rNIG5c{RYg(0qUqnMtTI1H{{s|fB|`uJ literal 0 HcmV?d00001 diff --git a/app/agents/__pycache__/runtime.cpython-313.pyc b/app/agents/__pycache__/runtime.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8def84ef3edc9fd397adeb8c3324fb457a97d607 GIT binary patch literal 444 zcmXw0u}T9$5S`84c`=fxRj@LoyC&C|P6Q3HxDY{uR>HC*o8$Ddcg*f-EN%P)!C&xm z1gnD-YGo&+uyrmMrx@PMJl=cDF6;FgQ1$uK%?ktgDu(~6lz=Ty2|U9HMr;59L)I#A zWl#w$v;rILz(HrVvj!W1i*5_9-8OXBIxX;tea^5N+Me@WY(18538fMvOq3|?S^4g9 zD3!U$l!<0?7|kPV&wk|gFR74anMGjB7m zaX!sVhLUr%$TDw|lrnsZVkYksyzO9VhBjT%DcVNC+YxEnNl|KIui~LwtX)1g~t?2Xig>)qcMfiDLqZ{yDl&6e3C7h+Fv_&(ucfyI7=p3ERS%T mROtsm?^FA+7-I`)|5kxru{XF}z`+MJ-(l~w)_ZiZPMkkg$A9Gj literal 0 HcmV?d00001 diff --git a/app/agents/__pycache__/suporte_contas_agent.cpython-313.pyc b/app/agents/__pycache__/suporte_contas_agent.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7667f050ec5bf8cefb30f72835a141840fbcaa90 GIT binary patch literal 5913 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 F^9w(uN-6*V literal 0 HcmV?d00001 diff --git a/app/domain/contas/__pycache__/__init__.cpython-313.pyc b/app/domain/contas/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..381f89028ebfa9545701632205ccffe5ca9ab88d GIT binary patch literal 344 zcmYk2!Ab)$5QdZ8N=v1u-aN&dJ=nZ}h@c2nDnh&uaW`F4cavq3R`e$L2I52XZM?c5 z2zv1*>C-$s8e+TQkwu&UH7lj*fP%nR-|r#E5QrndCI3^0+(p# zD)ElbG&&E-8W9Sep-e58nKB!b2OQoa^R|rxXrn#AxV*1=2Zc=+xjMvVUk$ArhT|uu Vl)jPEce3}f&0hPvk6r8q{};QzX1M?W literal 0 HcmV?d00001 diff --git a/app/domain/contas/__pycache__/client.cpython-313.pyc b/app/domain/contas/__pycache__/client.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c4e531a59bface0790c44a822f0f2378bedc3cf3 GIT binary patch literal 43231 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 literal 0 HcmV?d00001 diff --git a/app/domain/contas/__pycache__/contestation_rules.cpython-313.pyc b/app/domain/contas/__pycache__/contestation_rules.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..79a4578e3dfb2d2a9ab77c8ff6d7f9d3db6dff11 GIT binary patch literal 13592 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 literal 0 HcmV?d00001 diff --git a/app/domain/contas/__pycache__/invoice_resolver.cpython-313.pyc b/app/domain/contas/__pycache__/invoice_resolver.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8ae4984bd7d378f7c5f3584011fd7cf492defeaa GIT binary patch literal 54205 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 K9N%+Gf%y+nP@|~; literal 0 HcmV?d00001 diff --git a/app/domain/contas/__pycache__/item_matcher.cpython-313.pyc b/app/domain/contas/__pycache__/item_matcher.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5cddda6ab890ccc77f0cbafa62146efac374c700 GIT binary patch literal 9932 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 WW07wvotuRln|+--&DJ0!cO= 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 C!cMUO literal 0 HcmV?d00001 diff --git a/app/domain/contas/__pycache__/protocol_triplets.cpython-313.pyc b/app/domain/contas/__pycache__/protocol_triplets.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..aef22d72623db0356715ec5ff68ec8a527a98be0 GIT binary patch literal 7752 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 literal 0 HcmV?d00001 diff --git a/app/domain/contas/__pycache__/rct_policy.cpython-313.pyc b/app/domain/contas/__pycache__/rct_policy.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..574bf5e6ed787477670c33b048288d532d263897 GIT binary patch literal 6345 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 J&+lSA{2xuH)K>ri literal 0 HcmV?d00001 diff --git a/app/domain/contas/__pycache__/string_metrics.cpython-313.pyc b/app/domain/contas/__pycache__/string_metrics.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..93334aef6c89b32c3584fc606cf5962bd796189b GIT binary patch literal 6318 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 literal 0 HcmV?d00001 diff --git a/app/domain/contas/__pycache__/vas_variation.cpython-313.pyc b/app/domain/contas/__pycache__/vas_variation.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cfd99cc736f69ddd933dcf9a6ed328100437ca60 GIT binary patch literal 42144 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

a-kFB#XPmO+U3=eK4>`xSji*w*% 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 literal 0 HcmV?d00001 diff --git a/app/domain/contas/__pycache__/workflow_actions.cpython-313.pyc b/app/domain/contas/__pycache__/workflow_actions.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2b73a3870313cf1cbe7b7618d02fa77eff9b853b GIT binary patch literal 129646 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 UmTlw$jMD&PJQgsqkd5d62l;qyw*UYD literal 0 HcmV?d00001 diff --git a/app/domain/contas/integrations/__pycache__/secure_pdf_crypto.cpython-313.pyc b/app/domain/contas/integrations/__pycache__/secure_pdf_crypto.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5aaabe11e3395521e77fd951b805f23a5b9193a5 GIT binary patch literal 2484 zcmai0&2JM&6yLRX*Rh@Tu1NxEXefywj#ID`8a@IgiU{GumJnKFsnrUtHuff2u-Dt! zHD4zmdg-ZD1vOH8$f2s>1S*w!?VrH12cuCam1qyWRZ4s5sc&{YHVu(7hnY9;H#2Yc z&HMfAEm2G`(5&A-zwwM?m^WlXTO>5ttu-(nG9{+O7MTKz*n`B56eB1CW3(78aEL4L zh!6Z+Q7FVvEU@`vUm=d-g#=0jbD@|l^rL>TV@NC|N_`{D4GyKiiU*do8p$UABw@2G zPU@D`aCO&gSk9Gf1SdXgHe5rqYfT6DH?7_b*7lvNHEyq%&Kj%}7EOE2K$x#Ls)hp~ zf3>(+I_dPmvDaqmi__M%*$PX7bQ%w1lwsJdU%~s3QM*`~Io`1qz_+&&OHqqe$r(XY z1!^fI;I>A0D9LRAOpkY5R-_zJ#CP#>Hy+^9yExr{6d)_Ars)bb*0uIfi{3*Wq#k82 zwR+=t_fE$yo=5Oh>rh(&jO*bvqxZ@)7be-r` zw2w>@m7vZEieuq1RfpW-VAyaaU$@*mTvN~MtA^!jm4@Z&js~`Y%!-B##|Ca0+O3n? z?FPD;*KIprZPX!TK3tk7!Be-Ma8n9QgA37uVP4 zeDUxj;feHE@+ap!ajtb?Q{MaF&i9hPZ~CXhKWBf;KKsy@=iBlnPrl^Kh1TVl>5+DN z%uA1LO!(>Sqs#3h^WKqp|Hy)uUT76IQ-kf)ffuO*>-YTBR68}}rDmRH{M6~z#m(f< z{nd?gUNZBX%WT1wnVm)A7m$RvMMCXLLr*TcMaZh;L4&4rg@Jk)2FjT&v8Bjd#EPh- z;DV-h#X;?-K6;{>q8>%2R&U&aume4mT3y0M%TZ;BdV6EJOCrEYscma?e;_oR+LZ(~ z_$eWal`e^UTj>`lqdgzB=!q6z=6AdiM|T6h+l_>>u%k3|We8+|yK;^EYCxfygvN+u zJS!uj;)qBT8ip?5XNQ-BSAiNJlCXf*h$tqG!-A03h@=`3K@GKo2r%wzTA^Yfl9Fr; z?I$=3u+j7eIx~)AL?>4$6Nw@`!ue;;1K%uHW#*|B**r0P0DD4?bxRO?pFElKa;$`pHAjxkG3iuA1e- zM37u#0U2%+SwZ5nGEQjPN)sH0rXj+u@GbhAs8%zVbGD8g0})mQuZ8nr_CciVwY#}B z{a#&nb0lAeZMwNoBAuLGTWuiIU8_5xq)+U$%SLA1bj@3aL-z%u9%}e*JIE`W)@u0l zL5&doL*#)TGr>29Z`t=T{4HtLjCnK-5NHYGkQ(?a%ChV$X8a8!zGi0rV9vj07G5!@ Ve%mwJlKvKA?BqX#G4^n9&VR4;^Em(j literal 0 HcmV?d00001 diff --git a/app/domain/contas/parsers/__pycache__/__init__.cpython-313.pyc b/app/domain/contas/parsers/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..84bb16ba90e4e457dd0c81a764766872286fca3c GIT binary patch literal 945 zcmZ8f&ubGw6rS1LY?575L#;jJP(oXkfObzsiXvJ|AqmvlHC~Dg+w7)nO=iQJjgp=s zc=IL{^Dp$~pJM5uWoSXD9(ogV@ami0t_2_Lyf@$5_q};PCZ&=^Q239Jd$SrL7wVFU zo*H!W8jSuT%A14#AcMsY72;Mqgzwh`_&kMPu z(t5&4lL&{gkcTm2OZ}moPTw4dJ+_1MN*;e3v#J-0RXj%ItUUe2`fQCK9hdKo>Sv|O zCpKC?waO<}<;bdxSB|YaqvvPkg|82e%1=l2Q+wvbo;$MV#^Tss_+~6jkcHHAP_#*- zlJ3+@xQT$wB^^jRV(dgwSDFyS1K|5pe%Ow;MGW_=xN2`|wzL@Q4A2)a25R>~O-q{b zu#bBNYJsGkR*~#sI+dvu$$FY3Pu?Q)jCoixJ0vix*k%+#;c+kW2i@QaRPm}-Of2H@ lOQ)2cllco$JSVe1$=!3}d|#{oAvwDEdy3d~`XQgN`~`Ai=b``r literal 0 HcmV?d00001 diff --git a/app/domain/contas/parsers/__pycache__/bill_parser.cpython-313.pyc b/app/domain/contas/parsers/__pycache__/bill_parser.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3bf1bd885ba430fcbf60284db5e9a66c81c767c2 GIT binary patch literal 23749 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 Hl<|K7_1yOC literal 0 HcmV?d00001 diff --git a/app/domain/contas/parsers/__pycache__/bill_processor.cpython-313.pyc b/app/domain/contas/parsers/__pycache__/bill_processor.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4aa36a9e104d2f5fb72553f07e46384d9dd82b25 GIT binary patch literal 36264 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 z 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 Any: return self.client.consultar_faturas(msisdn) + def consultar_plano(self, *, msisdn: str, **args: Any) -> dict[str, Any]: + """Retorna somente os planos presentes na evidência de billing analysis. + + A consulta é deliberadamente determinística: não usa VAS, RAG nem o + workflow de invoice_explanation para responder qual é o plano do cliente. + """ + billing = args.get("billing_analysis") + if not isinstance(billing, dict): + billing = self.client.billing_analysis( + msisdn, + invoice_id=args.get("invoice_id"), + customer_id=args.get("customer_id"), + ) + + plans: list[dict[str, Any]] = [] + for section in billing.get("currentInvoice") or [] if isinstance(billing, dict) else []: + if not isinstance(section, dict): + continue + section_type = str(section.get("type") or "").strip().casefold() + section_desc = str(section.get("desc") or "").strip().casefold() + if section_type not in {"plano", "planos"} and section_desc not in {"plano", "planos"}: + continue + for item in section.get("items") or []: + if not isinstance(item, dict): + continue + name = str(item.get("desc") or item.get("name") or "").strip() + if not name: + continue + plans.append({ + "name": name, + "value": item.get("value"), + "type": str(item.get("type") or section.get("type") or "plano"), + "contestable": item.get("contestable"), + }) + + return { + "plans": plans, + "count": len(plans), + "source": "billing_analysis.currentInvoice", + } + def invoice_explanation(self, *, msisdn: str, **args: Any) -> dict[str, Any]: # Reuse framework-prefetched evidence when available; the domain never owns # a second cache/session implementation. Explanation itself is produced by diff --git a/app/observability/__pycache__/__init__.cpython-313.pyc b/app/observability/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7f5ed4c43318abc74536e29160f88750887952de GIT binary patch literal 180 zcmey&%ge<81bI(dvOx4>5CH>>P{wB#AY&>+I)f&o-%5reCLr%KNa|Lwer{fgeu}PO4oIE6@&*8;U`UkIamWj77{q767+qFf9N8 literal 0 HcmV?d00001 diff --git a/app/observability/__pycache__/telemetry_observer.cpython-313.pyc b/app/observability/__pycache__/telemetry_observer.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..51057b8003d1f1be4885cdb99f83cc833867abbb GIT binary patch literal 4791 zcmdTITWl1`v3q9rz4jVEuuXh;j2*)oymojUM#pi+SR5D@h5`EwngwAP4=kdhz%OpG9h@{y{ZU4xAS_jgHK zQ(IkK)zw{HRbB1Xnwl_yX8z+BQ^Qe0{*Ik$lRSj3P62Y8C`6$n

F8Cfl(mj0mR$ zCY%zPC}Uq7kxu!T5AcX0Z6i|>^8@DNSO73T$AU^!32-dbLUs@(xQ!^G1A?cEg>&I} z%@gdzsT0!*Go{KV+#1Pj6BbD}HS4s(3~j2Sm*I#iq5qaa~u9G)$S%StBT}fzLh+ z;0AdVshxGoG5Kb3Dbi7n>|BiOT#CeR9A9o|zH{`}(NgEJa>LMK!_e&hl9XE5x8N*f z7uo<_1!?j>cUHpMS&2y&gcY&~0^Bd#0>CpnYXH=3c+EJbRk2PpjMT%oIso9E*131E z+|aYw(1XS~GT$}t%xC9o0A)=e{eNH_$P(YdI60R0TxT1wqk&ipf;aYvVaJ2@w}9Nn zKwAq}AXM6`FkK5Y;L5?lZOSda5thg;{TFWErriEqARbJ{1s<9VbEGR6Y3>=W2q(|b z46X>O)$w>#6|>agVH-8PKAEN)1@jOozM4 z2CA%o<}giWmgR&2N$WD4xI9s?4O6#mnXlJ|Ev8{!TZZdk@WgO(OdUFV=G^JwvEk!= zcrEnzA53iAWEk|@pi-B$v}0V=WqU?5`#cqx_d)L-*|v}a7Fy8*Nnh8PY?wBznhV1^ za(O+>^eYA3c4RJ}2)i-wuE;WNTEAwo%iza;+bXcMo~~TY1Wt$`&chYm_cpmumxo`k zU6Aw0!CQ{ZQ3xJ4w06ZXJmt9PO17TQvN&`&#m4xTW!VdnpsE_C;i#(n!?hFM#A6aw zwtf({F%Th!T6g@qc6n>tZz4P#P8o*Ybh9E&5?OaQi z91+_|mcB1$DHdR&qvhg0H^hTt4DvGfh)VxB1gAEXB}nR;W}{C-q~<*R*P~d=DiK15AFr2Nsvjsv z2mTrzfa`8Hx)K16f7>6!PCh^8AL^wKLfyv>kq3SB*g@$*zl8XH0qF-R;)iw(^@tB; zI@IZZ*x^IGTZGYvaf)~k;%jLD=HzMMSC|GaLB~r2n->Y=)#L#oTXpi3&`(n0Fjc4` z^i%lV#Ob-iOBFX{m@~)bsOM$^`vAJUvYwMX$G{qrVTH{(Z1giceDCZ7c(72AyIt=* ze&9L-vNnb`dcbm1>z#|YE`Htqqxr6-_V>SPE{&uYCIOT#d{VkJu{e^xd9l=#DaSIU zU}iCv`F0g^$md;=TJ1ep%NRQf5UMe5GhR-91cVJH3UU)carTbuqsn#; zrdWN$NPFk^FSQ@~YG>)RzVI1<(#1=qpJWzK>u98GIhHL2vx~9pw`>T+zfX7C4*J&{ z25W8h5r9n%gSG10?^SLXU{i3O69{mRV0OH`d18zEz5IsPkw>is%=I(fDKOKOlJF*H zkkLsz%<~+>VeZo}n=qS>!{c@j6ko+p<)6u%8FMZ}cjePvhi5OV4vhfyW$k(~NTNJU z*5>tO`7C@2@~oWs3*dzI&EbNdBmftdZnP{DdC+<`hp0)_f~32Phus|>}y&HlihvG?{z$_fzIQ`<`o|j{iJ?pb+}>IN(5<9 zvgHRW$OXdTmgh0Rp6{hToj&(dUyi=u@F_u@*Fk&@@Q;VrjK&Rw<^!q>Ki(0&qDIhI z*#ev=7>kL>ftkp=?ELVmfdZ0oQ{#UH7!OA7cpcc~8&4sIb%B?a0ILCEL*59ti@ssI20 literal 0 HcmV?d00001 diff --git a/app/presentation/__init__.py b/app/presentation/__init__.py new file mode 100644 index 0000000..c0eba0d --- /dev/null +++ b/app/presentation/__init__.py @@ -0,0 +1,3 @@ +from .tool_renderers import register_tool_renderers + +__all__ = ["register_tool_renderers"] diff --git a/app/presentation/__pycache__/__init__.cpython-313.pyc b/app/presentation/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..14330eb9442afb1ca9acfe6c4a253d49d56fa362 GIT binary patch literal 267 zcmZuru}T9$5Z$>8oJojSX=|ayHEx2fSXn9BTxl^Zx#3v7>@KsbVrkk4&y5CXQT+e^ZxvcZ;4YMAP?(?`n{k%GY}3l5R~h+H~X+F1<@8 zqHtonl-d})i-eDhIX-#5*CqrVM3%5g);o=8olS@*;W_V|t$h2?(>af&ee-GDld&!V S;8UG`O^-e%$1fFEBK`uVflC?y literal 0 HcmV?d00001 diff --git a/app/presentation/__pycache__/tool_renderers.cpython-313.pyc b/app/presentation/__pycache__/tool_renderers.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..aadb4a777754bc05a76998ed7f46366477a9e564 GIT binary patch literal 5440 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 MA224SkD+t@4<#@grT_o{ literal 0 HcmV?d00001 diff --git a/app/presentation/tool_renderers.py b/app/presentation/tool_renderers.py new file mode 100644 index 0000000..510b60a --- /dev/null +++ b/app/presentation/tool_renderers.py @@ -0,0 +1,108 @@ +from __future__ import annotations + +from typing import Any + +from agent_framework.presentation import register_tool_response_renderer + + +def _money_brl(value: Any) -> str: + try: + return f"{float(value):.2f}".replace(".", ",") + except (TypeError, ValueError): + return str(value) + + +def render_contas_plan( + *, tool_name: str, result: dict[str, Any], state: dict[str, Any], agent_label: str +) -> str | None: + plans = result.get("plans") + if not isinstance(plans, list) or not plans: + return None + + lines: list[str] = [] + for plan in plans: + if not isinstance(plan, dict): + continue + name = plan.get("name") + if not name: + continue + value = plan.get("value") + line = f"- {name}" + if value is not None: + line += f": R$ {_money_brl(value)}" + lines.append(line) + + if not lines: + return None + if len(lines) == 1: + return f"[{agent_label}] Seu plano é:\n{lines[0]}" + return f"[{agent_label}] Existem {len(lines)} planos associados à sua conta:\n" + "\n".join(lines) + + + +def _service_value(service: dict[str, Any]) -> Any: + details = service.get("details") if isinstance(service.get("details"), dict) else {} + for candidate in ( + details.get("valor"), + details.get("value"), + service.get("valor"), + service.get("value"), + service.get("price"), + ): + if candidate not in (None, ""): + return candidate + return None + + +def _money_brl_preserve(value: Any) -> str: + if value is None: + return "" + text = str(value).strip() + if not text: + return "" + # TIM APIs may already return BRL decimal strings such as "10,00". + # Normalize only when needed and never invent a value. + if "," in text and "." not in text: + try: + return f"{float(text.replace(',', '.')):.2f}".replace(".", ",") + except ValueError: + return text + return _money_brl(value) + + +def render_contas_vas( + *, tool_name: str, result: dict[str, Any], state: dict[str, Any], agent_label: str +) -> str | None: + services = result.get("products") or result.get("services") + if not isinstance(services, list) or not services: + return None + + lines: list[str] = [] + for service in services: + if not isinstance(service, dict): + continue + name = service.get("name") or service.get("description") or service.get("billDescription") + if not name: + continue + + details = service.get("details") if isinstance(service.get("details"), dict) else {} + can = service.get("can") if isinstance(service.get("can"), dict) else {} + details_can = details.get("can") if isinstance(details.get("can"), dict) else {} + cancelable = bool(can.get("cancel", details_can.get("cancel", False))) + category = service.get("classe") or details.get("classe") or ("avulso" if cancelable else None) + value = _service_value(service) + + line = f"- {name}" + if category: + line += f" ({category})" + if value not in (None, ""): + line += f": R$ {_money_brl_preserve(value)}" + lines.append(line) + + if not lines: + return None + return f"[{agent_label}] Você possui os seguintes serviços ativos:\n" + "\n".join(lines) + +def register_tool_renderers() -> None: + register_tool_response_renderer("contas.plan", render_contas_plan) + register_tool_response_renderer("contas.vas", render_contas_vas) diff --git a/app/workflows/__pycache__/agent_graph.cpython-313.pyc b/app/workflows/__pycache__/agent_graph.cpython-313.pyc index f04dab576b845bfcec2205877d6a77eef1b405fb..40457f09ea635b5998ab6ba5163ed03accb06f00 100644 GIT binary patch delta 69 zcmex)g89!0X710tyj%=G@YkkoBX<_7W{`evUWtB+zHhK+d_YltR%&udv3^=+QE^Fp Ya(-S(VsU(KW_nR#O8(~AtoQB#0Ad9ibN~PV delta 66 zcmex!g8AnOX710tyj%=GkoTlzBX<_7n!kQ-UWtB+zDrSlK~jE&zJHLTvyZF3Z)JFX VQMP_SQGQlxa!K*#d93&D0RRTr7)k&D diff --git a/config/mcp_parameter_mapping.yaml b/config/mcp_parameter_mapping.yaml index e3dff43..6f9322a 100644 --- a/config/mcp_parameter_mapping.yaml +++ b/config/mcp_parameter_mapping.yaml @@ -6,6 +6,10 @@ mcp_parameter_mapping: map: customer_key: msisdn session_key: session_id + consultar_plano: + map: + customer_key: msisdn + session_key: session_id invoice_explanation: map: customer_key: msisdn diff --git a/config/prompts/billing.yaml b/config/prompts/billing.yaml index 3a8914a..1f249ae 100644 --- a/config/prompts/billing.yaml +++ b/config/prompts/billing.yaml @@ -6,3 +6,15 @@ system: | Se houver resultado de invoice_explanation, preserve nomes, valores e conclusões vindas da tool. Não prometa nem estime valores de faturas futuras. Seja objetivo e mantenha o comportamento de negócio do Contas. + + Quando o cliente perguntar pelo plano contratado, use somente itens + classificados como plano na fatura/tool. Não liste VAS, streamings ou benefícios + como se fossem o plano principal. + + Se houver mais de um plano, diga que há mais de um plano associado à conta + e liste cada um com seu respectivo valor quando disponível. + + Não use informações de uma cobrança antiga para completar a pergunta atual. + + Quando houver resultado de tool, não extrapole procedimentos ou políticas + que não estejam nesse resultado. \ No newline at end of file diff --git a/config/prompts/contestation.yaml b/config/prompts/contestation.yaml index 3929aff..3d20fdb 100644 --- a/config/prompts/contestation.yaml +++ b/config/prompts/contestation.yaml @@ -1,7 +1,43 @@ system: | Você é o agente de Contestação e Ações do Contas TIM. - Trabalhe apenas com itens explicitamente identificados pelos dados da fatura/tool. - Cancelamento de VAS avulso, contestação e demais mutações são transações determinísticas: nunca execute ação em texto livre. - O agent_framework_oci coleta parâmetros, mantém stickiness e exige confirmação antes da tool transacional. - Não conceda ressarcimento em dobro quando a regra de negócio não permitir. - Comunique o resultado real da tool, sem inventar protocolo ou sucesso. + + Trabalhe somente com itens, valores, categorias e resultados explicitamente + presentes na mensagem atual, nas tools ou no contexto de fatura autorizado. + + A referência explícita mais recente do cliente ao item da cobrança prevalece + sobre itens mencionados anteriormente. Nunca reutilize um serviço antigo para + completar uma nova contestação quando o cliente identificou outro item. + + Diferencie: + - VAS avulso: serviço adicional classificado como avulso. + - VAS estratégico: serviço estratégico; não o transforme em avulso por inferência. + - Incluso no plano: benefício do plano; não o trate como VAS cancelável. + - Plano: item classificado como plano na fatura; não o trate como VAS. + - Juros, multas e demais categorias: preserve a classificação retornada pela fatura/tool. + + "Não conheço", "não sabia que tinha" ou dúvida sobre o que é um serviço não + significam automaticamente que o cliente deseja contestar ou cancelar. + "Não contratei", "não reconheço a contratação" ou pedido explícito de contestação + caracterizam intenção de contestação quando houver item identificável. + + Se a referência do cliente for ambígua e houver mais de um item possível, + não escolha um deles por inferência. Peça clarificação. + + Cancelamento, contestação e demais mutações são transações determinísticas. + Nunca execute nem simule uma ação em texto livre. + Confirmação, stickiness, coleta de parâmetros e execução pertencem ao + agent_framework_oci. + + Ao receber resultado de tool: + - preserve exatamente o item e o valor retornados; + - preserve a categoria retornada; + - não substitua o item por outro encontrado na fatura; + - não declare sucesso quando a tool falhou ou bloqueou; + - não invente protocolo. + + Se a tool retornar OUT_OF_SCOPE, bloqueio ou categoria não tratável, + explique somente o motivo efetivamente retornado. + Não invente canal alternativo, central de atendimento, gravações, histórico, + prazo, estorno, recurso ou procedimento que não esteja explícito em tool ou RAG. + + Seja objetivo e responda apenas sobre a solicitação atual. \ No newline at end of file diff --git a/config/prompts/vas.yaml b/config/prompts/vas.yaml index 88c0d71..9f04a04 100644 --- a/config/prompts/vas.yaml +++ b/config/prompts/vas.yaml @@ -12,3 +12,12 @@ system: | Quando a intent for consulta do plano principal, responda somente com os dados de consultar_plano; não substitua o plano por uma lista de VAS. Em consultas informativas, não termine com convite para outra ação ou outro canal. + Preserve a classificação original do serviço retornada pela tool/fatura: + avulso, estratégico ou incluso. + + Nunca trate plano como VAS. + Nunca trate benefício incluso como serviço avulso. + Nunca trate estratégico como avulso por similaridade de nome. + + "Não conheço este serviço" é inicialmente uma dúvida sobre o serviço; + não converta automaticamente em pedido de cancelamento ou contestação. \ No newline at end of file diff --git a/config/routing.yaml b/config/routing.yaml index 66c4a2f..6e1ba69 100644 --- a/config/routing.yaml +++ b/config/routing.yaml @@ -21,6 +21,30 @@ state_policies: - state: COLLECTING_SUPORTE_CONTAS_PARAMETERS agent: suporte_contas_agent intents: +- name: contas_plan_information + domain: telecom_contas + agent: faturas_agent + priority: 142 + description: Consulta do nome, identificação ou valor do plano principal ou dos planos contratados da linha. Não se aplica a VAS, serviços adicionais, aplicativos, assinaturas, parceiros ou benefícios incluídos. + mcp_tools: + - consultar_plano + keywords: + - qual é meu plano + - qual e meu plano + - qual é o meu plano + - qual e o meu plano + - meu plano contratado + - plano contratado + - nome do meu plano + - que plano eu tenho + - quais são meus planos + - quais sao meus planos + examples: + - Qual é meu plano? + - Qual é o meu plano contratado? + - Que plano eu tenho? + - Qual o nome do meu plano? + - Quais são os planos da minha linha? - name: contas_invoice_query domain: telecom_contas agent: faturas_agent @@ -110,6 +134,12 @@ intents: - ajuste na fatura - estorno - valor indevido + - não contratei + - nao contratei + - não reconheço a contratação + - nao reconheco a contratacao + - não contratei esse plano + - nao contratei esse plano examples: - Quero contestar essa cobrança - Esse valor é indevido @@ -118,7 +148,7 @@ intents: domain: telecom_contas agent: contestacao_agent priority: 145 - description: Cancelamento ou retirada de serviço/VAS e sua cobrança recorrente. + description: Cancelamento ou retirada explicitamente solicitada de serviço/VAS. Não use para simples alegação de contratação não reconhecida; nesses casos use contestação. mcp_tools: - consultar_vas - cancelar_vas_avulso @@ -130,12 +160,9 @@ intents: - retirar servico - desativar serviço - desativar servico - - não contratei esse serviço - - nao contratei esse servico - tirar esse vas examples: - Quero cancelar esse serviço - - Não contratei esse VAS - Quero retirar essa assinatura - name: contas_vas_strategic domain: telecom_contas @@ -169,7 +196,8 @@ intents: agent: vas_agent priority: 110 description: Consulta ou explicação de VAS, serviço adicional, assinatura, aplicativo, - parceiro, bundle ou benefício do plano. + parceiro, bundle ou benefício adicional. Não use esta intent para perguntas sobre + nome, identificação ou valor do plano principal/plano contratado da linha. mcp_tools: - consultar_vas - buscar_informacao diff --git a/config/tools.yaml b/config/tools.yaml index eda07b2..48c3e4b 100644 --- a/config/tools.yaml +++ b/config/tools.yaml @@ -1,7 +1,7 @@ tools: consultar_faturas: - description: Consulta faturas atuais/anteriores, status, vencimento, valor e existência - de fatura aberta sem iniciar o workflow de explicação. + description: Consulta faturas atuais/anteriores, status, vencimento, valor e existência de fatura aberta sem iniciar o + workflow de explicação. mcp_server: contas enabled: true args_schema: @@ -15,9 +15,26 @@ tools: - fatura atual - fatura em aberto - conta em aberto + consultar_plano: + description: Consulta exclusivamente o nome e valor do plano ou planos contratados a partir da evidência de billing analysis; + não retorna VAS como plano. + mcp_server: contas + enabled: true + args_schema: + msisdn: string + selection_keywords: + - qual é meu plano + - qual e meu plano + - plano contratado + - nome do meu plano + - que plano eu tenho + - quais são meus planos + response: + mode: renderer + renderer: contas.plan invoice_explanation: - description: Explica composição, diferença ou variação de valores de uma fatura; - não deve ser usada apenas para consultar/obter a fatura. + description: Explica composição, diferença ou variação de valores de uma fatura; não deve ser usada apenas para consultar/obter + a fatura. mcp_server: contas enabled: true args_schema: @@ -33,8 +50,7 @@ tools: - cobrança diferente - por que esse valor buscar_informacao: - description: Conhecimento do Contas é atendido pelo RagService do agent_framework_oci, - não pelo MCP. + description: Conhecimento do Contas é atendido pelo RagService do agent_framework_oci, não pelo MCP. mcp_server: contas enabled: false args_schema: @@ -52,6 +68,9 @@ tools: enabled: true args_schema: msisdn: string + response: + mode: renderer + renderer: contas.vas selection_keywords: - vas - serviço adicional @@ -74,8 +93,7 @@ tools: - serviços anteriores - servicos anteriores cancelar_vas_avulso: - description: Executa cancelamento de VAS avulso no novo domínio Contas; confirmação - e estado são do framework. + description: Executa cancelamento de VAS avulso no novo domínio Contas; confirmação e estado são do framework. mcp_server: contas enabled: true tool_type: action @@ -93,8 +111,7 @@ tools: - desativar serviço - desativar servico tratar_vas_estrategico: - description: Trata VAS estratégico/bundle no novo domínio Contas; diálogo e estado - são do framework. + description: Trata VAS estratégico/bundle no novo domínio Contas; diálogo e estado são do framework. mcp_server: contas enabled: true tool_type: conversational @@ -115,8 +132,7 @@ tools: - globoplay - amazon prime contestar_cobranca: - description: Executa contestação no novo domínio Contas após confirmação transacional - do framework. + description: Executa contestação no novo domínio Contas após confirmação transacional do framework. mcp_server: contas enabled: true tool_type: action @@ -138,8 +154,7 @@ tools: - ajuste na fatura - estorno finalizar_atendimento: - description: Executa apenas efeitos de domínio da finalização; encerramento, memória - e telemetria ficam no framework. + description: Executa apenas efeitos de domínio da finalização; encerramento, memória e telemetria ficam no framework. mcp_server: contas enabled: true tool_type: action @@ -160,8 +175,7 @@ tools: msisdn: string protocol: string enviar_sms: - description: Envia SMS via integração TIM; use apenas quando um fluxo de domínio - exigir. + description: Envia SMS via integração TIM; use apenas quando um fluxo de domínio exigir. mcp_server: contas enabled: true args_schema: diff --git a/contas_mcp/__pycache__/__init__.cpython-313.pyc b/contas_mcp/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3a7efe46ef6de2a7da46964f402337b80a3d7ff0 GIT binary patch literal 173 zcmey&%ge<80^eJ*K-6Op0RxOs#%C5FV=6;BgC?WjN`@jPAn!9s>XwgwZeEFgioS2K zXM8|WepYI7NwI!fW>IlTd~$wXNn&w)Zf1H>VoJV#VtQ&GOi&*tmt3G9AD@|*SrQ+w jS5SG2!zMRBr8Fniu80+AILPv15aS~=BO_xGGmr%U{r@ck literal 0 HcmV?d00001 diff --git a/contas_mcp/servers/__pycache__/__init__.cpython-313.pyc b/contas_mcp/servers/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ea8e9aceba7d33e3400d4ca26662e293dd4f51e4 GIT binary patch literal 181 zcmey&%ge<80^eJ*K-6Op0RxOs#%C5FV=6;BgC?WjN`@jPAn!9s>Q;z;ZeEFgioS2K zXM8|WepYI7NwI!fW>IlTd~$wXNn&w)Zf1H>VoJV#VtQ&GOi&*tmt3GQIlTd~$wXNn&w)Zf1H>VoJV#VtQ&GOi&*tmt3GBWmJaQMNZ?+fJHFJZbjWnU=lY&vM!`mJ@GW=%NiY!tHdj*<`%mY*y{=jO}c8 zv;Vn;Diq10q>eq`x3k}t#KNtr`#ksDbI&>V+;cxlPEOL{`k%*s>tfuubh`hA9^}g; z1@s>k#Orjg>B@ARj??$(y7j!?L19CWfj6+iEnvnOtI>MW^GE*xkbJR=V?9XEM)Z?KEWQx(?te`-~msWy|HAF$^@y zdBuMBp*C)VPS=~S(`m;T*b$2@hdABZymui7x*WRRLpq%Wzh^8cJCjRhwM*e_%?1XK z)SkTVd_JFr(|QWJxA0q7IK8K^yNEAh;fx+f_f~!@3upEecbD)b-KBgfd(P@9>n`WZ zSvb3=qPvo>WMO+xRd+RC&B8f7HQlv*Eeq%N)OFYM^(>s%)6m_>H==II#X2sZD`?j9 z+s>31>tv|&+s{;^*7dPB+!n;yab|1m4Zo8!T;9bMp4rV6RiMRq+QT{Uw3R*ix#B$C zMI+zD&2S|w)SRP3X{C8OuI!9$R~$hJeY3Yw$CYyxTqRf4sOPHd4I_H4hO1rkT*uX~ zd2Zku*F10Iwy$~K!R_R#@NXBlyFMHOs-s*td)K3+I>z;~H+{;Re(rcQ-3cY#0LMk&4a)EM zeVh}JJ;@*&;7&1k?&q#>Lo9TFyULwrp@ZBt?l~4Z#9ilxS?Dl#gFC}QE!+#-^DK0P zdyzZKLap4VxDgg=<37!uW1)8LCCKc#3@`iRBl_4;O9 zGZQ|qzYovGvMZ1Bk>&*o=NvlX)HuCTw@;Z%*X}aHRZYL<1dZ)MkgZ1$%*s+h;7}cNSvP^ z{YPUxvhG0MX5SSL&ri6i*e#>H$2H>_nRI!_#(3BC_{iwEXY|svZ^Ap{;SnJx8UfL# zrm1$L*GK#_KAsX=qu)kdNJP(Lo|zH9XJ%%?JLX5tvpXgxJ*QB&3zNR91D~#%wyy)ojc|DP|SW|cj1UCvaYb__p8JUpU$v}Zt0n7|WqY^qw_XPX^H}oG}MBp{u zu<~sbgkU&IK@l>_9|kDJx@$O5elg5A0eX^gU7oEjtMV?@-PiY3CGcAjkH=i7iX$)2oUFu6kwZ=$7vF3cPLrQw9V(~d5}M=Ic2boo@H50e>YW&!a7|9! za5>iDW`la*H$;c~JAdFsbcf$Jg?{unygtV?j{!Tu`y2tkuRbZM{mR6Q%i%iDPwJyQ;!<7kZRa71++e$S+56hqVHMqNCUK8Hd8YaQNqzT$ICd8Xd^ zI*&?E`bJ%o^+~`&Mm;)+lzKrd{nM^dPsGN1E(a!f&j?i%Bsh{NQy2ezeI#uoxidse zQL+QNr>2pKyaRycGw4R#CvT@)Hf|B?@qzyC_SV6Xf&TtMK9}B?(k-2C#8djgMCu%T z74DHt!dSTyBT>4*)6~^KF;C()tNS=bXU+|p9IFL8SFM?g<_BdT#u>IG3Fh376Lec@ zSFOcg-M?HDEIA-r53XizTTQhKHTw}ID+S;4_I%@-n0xp`OM;XlMQ7b27z;Myc9cNq zKiZ8#U(=n@@p?`N)?UxYf$2A#F>-OlTAYao)0e;*!Rnc~c)U$u42Ov~kD03yBj!Q$ zG)-|oZ9`;CLNk0Mk$QiGx&Z{!=Js501tu|x0kW7F{xQWpF*-Ahc(o49kIzREUHn*p zP|wd(&V7{W2unRO5=j~vnew>0-l)We_Eg>C7t z^u6aOTXqK>`(}^MeflTHeNqyN7)b;2`O!odk4DY_)%-UKTBENV(KimDvP3C8^^t@r z|AgP|jU)gHm_~uL7PrSg%1=zwgcPw(c&7uP{=mQ~SHu>}eHt^k??$(hx98gEWWYah z1rVWOh`~Y;X#BB&A9EfkGl;L-=f|M-_$iv-;dMo8RUgTasi)@}C1Dd{;2av&e$6u) zm~kOb8CxB0kAq@OjMDJMAjGrOIGS1=(=LqW29$xmlm_iO+Cvaf#&LZlIo2%9$Tu>T zMxAWo95mbd{PhugEYdh=i4RkTk0$T{%|S{E`b6Yll+_98(JpC*M~~2S@46D0^!oyw zs$J?eGXRq^gCZ?zypR&MO!NoE=H9m*EJ>H#q+M~RdIX=3c$=5IDgSIIunVX z00ZKWWV0TSD&j$hgA*G=RRjC9YJ>LDoad6u@v!Ek2jY2G(NcoeA9E?|A7r}=ljUPlS)Bc}5p1|FAJ22X;7nvwKzbPNkKc85o#NGjOT zsR@i`8V#tMFHnQ>I(+B^)N|A|?K(d(3C@mMGV{)T7MH?u^!h4;)CWmkOlDHcHggAW;FbgEaCfgZoiXo1*MUeMpnD%SW1$~(}X)>84Z8}OnG>~G?H~;!pqvtgP41~ZtyFF zE=1?$&Xqw<2qMRps!t3?!0+%}@IX`n7Xt+HO}+DPy%WCrsyHIb1acb3Q|SBa45M!3 z#%8Tph~}^7Bk_a%{l~abn&st-SZ)(B>A#P_YdWVsLwC~PH#F${q<#YN@;L_7@uTUS z28FlN6M0~&CvX%_!*N6J7D;vFjq@6uam1<8<-*$-(@(tT0O`TjUCuZ;UmCx1*rOjq zeH{4n8ZPLnjD7bFeGy%t6j6@5_;m%hkb>{kJaPEt~BWQVzUtN?A?G5poYb zEd74fcdH(Cibn>6xr1VgQ!qOp$LY+rU;ZpkXFKR8KHxJsEh)y=6L4G8Pv|3wzt4t> z4*b2+Co!0U4+l>#tELX3ozD#T{Xfaiu4Ea^B{ETT}3pZ?Q7|MNfJh$jiyaU*V^)DfWZ z>G7|F}aa)V$#pgBC4NyhXx%kY20OvjFOt<0$Rl;Dj(xL`OhMrhZ6j6 zxXtQTEh(S7IzJ<9saxVj+xC#HY5BZpX%1Nq1ucg}OUrEAYI5r5?F*R;*Ot=7wAxVG z_GN>Zyd#v{987K&llRSbtfpsuer&0M#hs$Ha<)C3k~-V@z9~6uw%tm(nX*u@cwuQ^iCet1_`G1>v0~o&zA0V)mbLK0 z!jxdIT`|{%P1c|(NB)qp;9TgO|I~`PENo5vAZRg(s%ZUYg}%SbeU6zeaU2t0{EXbv6_b6FPy z0%Df)9UywP?t%{8=+wtzbNYegby4uh#pki9NUo7wYvit|9R^Z2rbF%tTpaR`w(c3? zo7C~21QiT0bAb5fKH~C7XCcke!~sG71BQTiLAJn+*jW5Vr|@eupfGb2qsOLj3Vn9xY zmqJ(&uh#(rroWU8HsiQ;>X+`A_0*^wBr1P7t`Q8m2SSIc#)!4OZ{$QkR#0!`x`Yjsc_4}E^!+)?|iAJ-gpZK+(Vz>(F9bYys z6o0KJRNL}yZOg;rP;L92?YFmo+4xI8A<)Z3_4?mStk>U28b0f)yU|$J{Cv%gxHJBm zszgR^_?HnWVjhJu`hsuL9Wn79u;`;6{$J7iM5+(`nPX$-<0iDGgbwgO+O1QY#p1Hx7Mh=A@y|gKC~le@)k@n@Z=hxNK+oPCX5x zi{^{Qi+Zo#sng=(xC9wdyav@AYEWtLq6j7p?F+R>~ zROM_OCVrD$G6|4#W*j8)b{c`^A0g*>Rl4}iYsAv!vAJ1I6r-hZX1RqbQV30@gXVIr z_=$3SZ^9-ql9U)GRSiu~Y1t*z5K!v^+Ir2ZbmnJhnI1#h{N&nhXq|R^g|pctKZX0= z4P{Gf zN}HrsWO1ckG$Lbqh60S{X#VtGF6)W)PT=AzP?JqcR5-O!^qVv8Jm5UETUy~714PFl zV)rqTqROc1eDKFmhGH#?2i8jn!B11@cj-p&qS8BKry0W=Ny5r_bR~@UQw(z~!&o}V z2ePIi5_idSoyVjOE&K%^bpDKiX9B##F)PXNaW1zTVuGwBjV?UEx?u)t`>~j?fM~yk zjQl^s?H3U0Gwln;dr6Ci-{}u!Rs}Pw#LSwx#MKnXVy>7{GZ**1Ej?^a58EFIU#9jO=8R#B?N-yx zruk0MQm~jLTB?@<54y#Mj&Q-&dHc=Yur1@(wVT%#l0vqUpsnPO%&SGki%nnrRH$fs zuxPtjv~#X)J}+o3khAF(Eydv0mtF`Wi{iTZE$>>3pxUu`U3u%h(8( zuqLl#Y(wr!fx4N8uJWj4R1ryyg6Sl*9!%u{dFA@F2P=fM^mc*(ogzb0Qk_InAaMFU zl4%NZS|dx+klaB7{RjdoSrStYWXTws>W4v0rAr<@QE3rsGh)wF(jsKSqzULqL04d( z!nYzBWUG1nMD$nGf))R7=v~dzdtMO}?<0X9%3?`O+&A&=>2YDu`R(q9mw#9q+TSni z@5h^8GTrRUTZ;6NgyXc72>mVljaZ~b6sFUP#It3aj)T-N{@>BtEvp1gh>7?6vr%gd&KI;${Ve_khDzZD3TEonX9mnG}NfGrJimguY>+-q(p6T^w*TB{iLd`qhuh;kU1}x`93iJ#wAIXZt(wy2E5FnhGHrd=v~{)M z$lS58z39%1w_jX5Cfc{nb**M>Ss4GCF_cjk%&2=WHRmt#OXf|h_N|K*U)ve7HwNvE z?`0N*^Na88ySs1kikM#?%5Pt;c)RAUngbA7%9~bIU(r*pj91^n2#pDX;7y*j%FO`N&Memx5R=4eY(D9w_ zZ*~ivr^Nk3E6<$`Z5s)08=23(lXp8$D5zaYs}nqz<`PydS@RdZhr1s&ubg}?ba*&;cz7}KjpWypm!?)6`vsS0A)WwxbTP0rwjB6L&Vdi( zb=wX;PSEXadVB9%d;k6ZU}nSovBkQuy+o+kE86#dulmvRD`(Dyj<|wHT<_&L{=!kW zU|h{FTXcV|EtJ1a%-{B2LD8b|4fE^frEJmB7;>~Nx4qr>yzDWspVNlt z>E&sIi>3zp!MF1UA0;?#n5J&sa+$hyYyHP2-Oj`M57TtHg&!B{tf}+ycdWOqzmp4`>Y%DIkgA4@+bG^WiDiIVC$`9goX3ou zUd4bZ>{1F!-hst9EQZ9Xm|SIf4T1y+*jnaIlW9`e9+{z8!`gw!l3tP1JL9Diodzb_ z(EIJgv}iHaF*Xs3f%YgPu4sf~Y9uaU?+{os&|xrmCL+hBVBMHbmPgZ-wOd+ch#G%j z5n8e~q2*|B$FMgcwI8fbuuRC7JiwRB+%Z$uf)(#$uT<6)E|_q^4r~nBj{4X%4Wkh# zNx{kU4i{E9Tz<#7bN-2`bLZ+E{RmF^$Ry<4xrU^3=h%debqhR7RxQvIJ4hIqbU9#S z#w^tWcp;f=$ZNju+{datViDsGF#!U^1sJV)k|+h1^HG{)w}DI{2u!%Ku3qop-uXJK z;KY~*S+iy9@poPaC@=*`U_esRLBl%1`_4B=)0?EoCF>z3Tj1=IjMy%?Zfp=*_}@k! ztl={V-**tcUqs-bUd3sEOIC9lg9a_Ej%lqoF#ZarM){HIC_kbn?KSw0%P0_Q!jfXx zj|Z4=%;P7bzr^NVKZYS@I*AvRIFe>8=8lr(@rYz8G%+LDveJ?|&B{>_$2e1kKlvW= z@)O_x3#P}mAAh&0e|g)N;-VAEi7)nq3hI`&hjQwLoO*ndSd~{Acc7-Qr()Ot9S_T!@Mc*u4# zXgev|hGx6ow`72O4rkj}a;le_#GIXieb@2{A#=}cFIzWTO|4wY{7Gv4oN+a?d~xQD zYp-8hP7o{hh?z}uiGOLyoNHd#ws3l(XYsO-TebB3k8}5itr@raZuTwg{E5}^p-Gq4 z@UdB!w`Jkf7Ymls#N6t+J@eac?iGwXmyNhd)R^EYUnK4V4fG%Vu8A2sfKD-CkLadq zY1*mR!p)etC{sRJ@N-G&i6F6Slk|!(yaBfrnyMud?~3LM_59OHPz1z(VF^&=D{TUV zVhi6)WH-RLz(f=n3QUN~F_mR()Ow9h$CYDz_6{4a#D$!StxOiG5!Trw+HQTWCd`G;fg zl%CytHL9FA!KJKAXOi2(*_b*5s!tB;NvP$u@mW!+J53wflFnr~6EK5k?!Zc_X74HL zU0Q0wZXkQTsZ>`81&U_u9Jy{#RmNs^b8ID7mNsSBxUon$oEk-a-9Wk=iv12`#lmtZ zre=BOa-^}FE$1*mCeiCIXIz8cX_jl~O~hhA!MZ4Tlxyxf1pL>G!Q~QK4is)o>rHYd z!RX4O7+qn7+iMx#D#vsxeFf7hK!qf6uhnbe^03yOPo^ha0eZ^HZ6PC&;SwcX;y|e! zj{VAg!4*bFGbRMoSR&;nmGP`j zj^Xt6(K0 z4(#4oz5?}p)I}3pL+`W4G$Cp)Y!wbS})r4qXx6U(g+h zE7D!iM-BWeFz~Am{5>KLNJ{Pouu3kNB8&yd#+&i?#I*CoNPDhKxTCspx2$7#C|Yva zt`cm03piz%Z92eOtBff3Aq&`nsx<6i$q|!GX^|iPE0#wRZ%#Hy#6>5ykbUlev{|Zm z;u<#jI8I1Rw_-f+xcCm(Z&(LUj(Y-(q4!O*T%tQeurzQUJ4k%kbTZ?qPdW&I=y;B9 zeRLbZtuKZriZJAFaw)@vd9P2Y4aX|n?#*xWhR&;gvFFAo=IlQOY0U6ADQY( z@>wKLn_DNj4%~INqN-Zcl1PgD9;Wp?cJi6{Noo=7W=BV{rA~rj7_THC#bZAr*^hY!B%aGDDAqi|iGS)6;?*7gj z%rFQGHH1;vfl$HBmMa*}z(n5zZKUIhZ}go%faFHYMP#>f2#S1G%S5szLRCDd5hOrA zAwt9?8NvB^Qj|w5G%7}XGn|T~Vp}I|O9SKY#*QQGIaxwv zNKEu2Ar`}=6L<^^; zdvqh~M*cVGMx!c{%r*-t<0g>-ohjz6K5T;VUBEsV;A&Nhq);XSP0H*zr8di$8%c$9 zePsd_kp~{XNKu)_`41?n3E2TnJW@q}lRo~hbo+bU{3*CG`AxY=f?WCtvb``lF*c6< zIFf#V{|CgSCi-6nae>Tc)tRkA#&e?SIml+KCd*vgt*)D0LROtQHiHFu74o-VPOJO4@wsoyyyl3(aDBStz{*_LM2Lp_J{x zl{(io!+Zg0)~3+QP1T$L=13 zcCVl@RIqOu3f%p3N5h2`^SL+s!`Vf1onf2(){8e^T<8>SrAytSZTD(b?b6VjXYQYQ zP$AYG5vy9~jY3vgFtvQup106+Z~xu>OG#q>j!=H{G7lYN$bL9zKP=jh%yqqQvxjSU z3R#uG)T&k6R-t&iXxp)}=jfvtA)o+ZyJ}xvI63Y*V9hD)+j-}3UQN>c?BB_ISI7xe0c+&8}_T6t+zEvsg z8x*%Y!_^%h#>Z{V{?KO0Nq?-fq@_R3v&3hHbGO{fxtk*t?-X-)&84i`au@2qRvNN3 z1Z@qgTT1Vpy?ZvaWq)wXekeP)w9WOci4e}PucjA=(yN2%)k~dA&C6aGsLq+FhixHK z4*rMJb3^GR!Ss^FmSB2$D7`+IUO#7gZ{HCyz4cprmUpgXkN}=h|IIyfCLz7`gY24c zZgDuT>yiCYqHtnb$hjQ07k-!+pPKYo7oV8)F>MWJ(H%3Fl@cmf3ts~cd6;kL-!A@Soh&W$Wny= zs!ySsL%|w+JiKa2pKn??#q8mNmOarZP=z5g?Z}Rmi9mEtN|{ zp}N*!U8~SJB-RauD-O-I327xkYiT&YB$Qtl%&)^bUG~jmALKYfIn}|OYSi;y!`+5Z z-j1b{VS3pR%xU=0WGqa1tTS%0AvPBO2zvp`eEeVR43+N0{|~ZD!}bEKT`Zawt_zhf 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 S}c3`OEOZ1>(?`>6qePa<1yk#&#mM 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 KzUI|TPy9dbQYd}^ literal 0 HcmV?d00001 diff --git a/contas_mcp/servers/contas_mcp_server/main.py b/contas_mcp/servers/contas_mcp_server/main.py index bc51e36..25504e2 100644 --- a/contas_mcp/servers/contas_mcp_server/main.py +++ b/contas_mcp/servers/contas_mcp_server/main.py @@ -1,6 +1,8 @@ from __future__ import annotations import sys +import re +import unicodedata from pathlib import Path from typing import Any, Callable @@ -70,6 +72,7 @@ class ToolCall(BaseModel): TOOLS: dict[str, dict[str, Any]] = { "consultar_faturas": {"description": "Consulta faturas do cliente.", "input_schema": {"msisdn": "string"}}, + "consultar_plano": {"description": "Consulta exclusivamente o plano ou planos contratados presentes na fatura.", "input_schema": {"msisdn": "string"}}, "invoice_explanation": {"description": "Executa o workflow de explicação de fatura com pause/resume pelo WorkflowRuntime do framework.", "input_schema": {"msisdn": "string"}}, "consultar_vas": {"description": "Consulta VAS ativos.", "input_schema": {"msisdn": "string"}}, "consultar_historico_vas": {"description": "Consulta histórico de VAS.", "input_schema": {"msisdn": "string"}}, @@ -111,6 +114,97 @@ def _clarification_option(item: Any) -> dict[str, Any]: return {"label": label, "value": name, "msisdn": msisdn, "charge_date": charge_date} + +def _norm_invoice_name(value: Any) -> str: + """Normalização conservadora para comparação exata de nomes de itens.""" + text = str(value or "").strip().casefold().replace("+", " ") + text = unicodedata.normalize("NFKD", text) + text = "".join(ch for ch in text if not unicodedata.combining(ch)) + text = re.sub(r"[^a-z0-9]+", " ", text) + return re.sub(r"\s+", " ", text).strip() + + +def _invoice_subject_catalog(args: dict[str, Any]) -> list[dict[str, Any]]: + """Catálogo mínimo de itens reais da fatura, sem fuzzy matching. + + É usado como barreira de consistência antes do resolver especializado em VAS. + """ + found: dict[str, dict[str, Any]] = {} + + def add(name: Any, value: Any = None, category: Any = None, contestable: Any = None) -> None: + canonical = str(name or "").strip() + key = _norm_invoice_name(canonical) + if not key: + return + item = found.setdefault(key, {"name": canonical, "value": value, "category": str(category or "").strip(), "contestable": contestable}) + if item.get("value") in (None, "") and value not in (None, ""): + item["value"] = value + if not item.get("category") and category: + item["category"] = str(category).strip() + if item.get("contestable") is None and contestable is not None: + item["contestable"] = contestable + + analysis = args.get("billing_analysis") + if isinstance(analysis, dict): + for section_name in ("currentInvoice", "invoiceVariation"): + sections = analysis.get(section_name) + if not isinstance(sections, list): + continue + for section in sections: + if not isinstance(section, dict): + continue + category = section.get("type") or section.get("desc") + items = section.get("items") + if not isinstance(items, list): + continue + for item in items: + if isinstance(item, dict): + add(item.get("desc") or item.get("name"), item.get("value"), item.get("type") or category, item.get("contestable")) + + detail = args.get("invoice_detail") + if isinstance(detail, dict): + parsed = detail.get("parsed_content") if isinstance(detail.get("parsed_content"), dict) else detail + if isinstance(parsed, dict): + # parsed_content normalmente é agrupado por MSISDN. + roots = list(parsed.values()) if parsed and all(isinstance(v, dict) for v in parsed.values()) else [parsed] + for root in roots: + if not isinstance(root, dict): + continue + plans = root.get("Planos") or root.get("Plano") + if isinstance(plans, dict): + for plan_name, plan_data in plans.items(): + value = plan_data.get("valor_final") if isinstance(plan_data, dict) else None + add(plan_name, value, "plano", False) + for section_name, section_value in root.items(): + if section_name in {"Planos", "Plano"} or not isinstance(section_value, list): + continue + for item in section_value: + if isinstance(item, dict): + add(item.get("desc") or item.get("name"), item.get("value") or item.get("valor_final"), item.get("classe") or section_name, item.get("contestable")) + + return list(found.values()) + + +def _recover_explicit_contestation_subject(args: dict[str, Any]) -> dict[str, Any] | None: + """Recupera item explicitamente citado no texto original da contestação. + + Na confirmação a mensagem corrente pode ser apenas ``sim``. O ``motivo``/ + ``descricao`` preserva a fala que abriu a transação e é uma fonte mais forte + que um ``subject`` residual. Só corrige quando há exatamente um nome canônico + da fatura explicitamente presente; não faz fuzzy matching. + """ + original = " ".join(str(args.get(k) or "") for k in ("motivo", "descricao")).strip() + if not original: + return None + norm_original = f" {_norm_invoice_name(original)} " + matches = [] + for item in _invoice_subject_catalog(args): + name_norm = _norm_invoice_name(item.get("name")) + if name_norm and f" {name_norm} " in norm_original: + matches.append(item) + return matches[0] if len(matches) == 1 else None + + def _preflight_subject(name: str, args: dict[str, Any]) -> dict[str, Any] | None: """Resolve/desambigua o item contra a evidência da fatura antes do workflow. @@ -125,6 +219,42 @@ def _preflight_subject(name: str, args: dict[str, Any]) -> dict[str, Any] | None subject = str(args.get("subject") or "").strip() if not msisdn or not subject: return None + # Contestação pode referenciar qualquer categoria da fatura. Antes do + # resolver especializado em serviços/VAS, preserve um item explicitamente + # citado no texto que abriu a transação. Isso impede que um plano explícito + # seja reinterpretado como outro VAS durante a confirmação. + if name == "contestar_cobranca": + explicit = _recover_explicit_contestation_subject(args) + if explicit is not None: + previous_subject = subject + canonical = str(explicit.get("name") or subject) + args["subject"] = canonical + subject = canonical + if explicit.get("value") not in (None, ""): + args["resolved_value"] = str(explicit.get("value")) + category = str(explicit.get("category") or "").strip() + if category: + args["resolved_category"] = category + if _norm_invoice_name(previous_subject) != _norm_invoice_name(canonical): + args["_subject_corrected_from"] = previous_subject + + # O workflow/CVAL atual de contestar_cobranca trata VAS. Um plano + # existente deve ser rejeitado com o próprio nome/valor, nunca + # convertido em outro serviço. + if _norm_invoice_name(category) in {"plano", "planos"}: + return { + "status": "OUT_OF_SCOPE", + "success": False, + "subject": canonical, + "resolved_value": args.get("resolved_value"), + "category": category or "plano", + "error": f"O item '{canonical}' existe na fatura e é um plano, mas não pertence a uma categoria tratável por esta operação.", + "metadata": { + "subject_corrected_from": args.get("_subject_corrected_from"), + "subject_source": "explicit_contestation_text", + }, + } + try: invoice_detail = args.get("billing_analysis") if not isinstance(invoice_detail, dict): @@ -176,7 +306,7 @@ def _preflight_subject(name: str, args: dict[str, Any]) -> dict[str, Any] | None return None async def _enrich_invoice_context(name: str, args: dict[str, Any]) -> None: - if name not in {"invoice_explanation", "cancelar_vas_avulso", "tratar_vas_estrategico", "contestar_cobranca"}: + if name not in {"consultar_plano", "invoice_explanation", "cancelar_vas_avulso", "tratar_vas_estrategico", "contestar_cobranca"}: return msisdn = str(args.get("msisdn") or "").strip() if not msisdn: @@ -690,6 +820,7 @@ async def _run_cancelamento_com_contestacao(args: dict[str, Any]) -> dict[str, A async def _invoke(name: str, args: dict[str, Any]) -> Any: requirements = { "consultar_faturas": ("msisdn",), + "consultar_plano": ("msisdn",), "invoice_explanation": ("msisdn",), "consultar_vas": ("msisdn",), "consultar_historico_vas": ("msisdn",), diff --git a/data/agent_framework.db b/data/agent_framework.db new file mode 100644 index 0000000000000000000000000000000000000000..0d835a6af7f7fd3f2a38aa466b205ab8ea2cadbf GIT binary patch literal 20480 zcmeI((QDgA90zbIPMfwYbKmk%3P)CG%&bn5Wz{m6F6%r9b(}S`OG^vltozwjYe|`O z?h-~HQU-k*`y=*H_9yf;{U`cg>}fFew2Namu|cHtrKJ5H7Cz~YpMLkb!*D|W>252O z#QI4Zamgy$Wlh($ZyD1xt)Px`>X?=VRau;#sBis5J+E5OZv6h=a`9hn@r$S0@;Aj- z#e1rP0s#m>00Izz00bZa0SJ8R0{iQWODo-mzW+Ro1?`4n*XIL@W&am{n8X8LQX2UY zMM=8nXQSQ|3S?gUx!c>#^-hy*w7+lOXYUh=kWs-pZl=jM_ z9l<3DpUcv3*Yu^8Mnix3Q1af8@*?J4Uzp_GS^uup%*}_bU1BH7gd`NK)4bndKW=Yq zu5UkJcbX5%>|N$ZZSAcNYj<0%@=*I6S=?Iqpnz6hz{9=$g~K15Wp(IZ{-vo83Irek0SG_<0uX=z1Rwwb2teTD z3%uy)#qO2TS655H(te@4xp~X7gG$A9szyz?w&8eI)$r`TZCEuTw^FsdT5wZPpO1!8 z(vX5A^3}r!$urCHrseQSgbd~0PD*`BQ}vK1<`Laa!;BG&!uT;~!!RC<)IK_5g4j-) z3{oEPH?Q9OnW!_m_4lK-e-8e5G`UfI_D*$Pt8v#dZ6k0z$8dz@svL!9aO&T*-Cot} z3)}QWujh!s=#e19aZT5#^_;+{1g<3<;kw-G*{1CpX3em?j^)*>R=w)pa7@Rmm|vS_ z-84^Y|8PAOHafKmY;|fB*y_009U<;Ik5FERElaxcFhO yIvnl)Uu(tJpA{Mg3jqi~00Izz00bZa0SG_<0uVSG0zaHr+y2c{cm1dRG2nkJXW|S1 literal 0 HcmV?d00001 diff --git a/tests/migration/__pycache__/conftest.cpython-313-pytest-9.0.2.pyc b/tests/migration/__pycache__/conftest.cpython-313-pytest-9.0.2.pyc new file mode 100644 index 0000000000000000000000000000000000000000..857919f7071b0baf2af0430d9ba24c922b902246 GIT binary patch literal 854 zcmZuvO-~a+7=E|iGRwB5%SWOZ38j|?gETQV(cotgQ`#W9YvN^-$x;?vZFifQX-O}p z2^=IIz=M&Wfd9lJ8=}-nI2aFxn~{T8XSP6yIEUw*_w#w?%^auGI>_^9~566Pb9WzpN8I3$~sEJ6RM{ zPB!JZyA&O9wNHX?-ow*qshSF`}8TO#yGfw%) zkUeB;X7=Lb8KG!72Cy&&@c#-kf3eE~d#EV73!)7y4ux}TiT|!mD$YfC_BZk+Qe@J=^PPX3H}0DsNDDf literal 0 HcmV?d00001 diff --git a/tests/migration/__pycache__/test_backend_wrapper_contract_parity.cpython-313-pytest-9.0.2.pyc b/tests/migration/__pycache__/test_backend_wrapper_contract_parity.cpython-313-pytest-9.0.2.pyc new file mode 100644 index 0000000000000000000000000000000000000000..80a0749f0eb620007b410233e2b0e169a5270e10 GIT binary patch literal 37569 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 G5&wUFij3|6 literal 0 HcmV?d00001 diff --git a/tests/migration/__pycache__/test_business_events_and_guardrails.cpython-313-pytest-9.0.2.pyc b/tests/migration/__pycache__/test_business_events_and_guardrails.cpython-313-pytest-9.0.2.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a058388d715b8061e569d0d6d70023a52c82f381 GIT binary patch literal 4284 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 literal 0 HcmV?d00001 diff --git a/tests/migration/__pycache__/test_framework_native_structure.cpython-313-pytest-9.0.2.pyc b/tests/migration/__pycache__/test_framework_native_structure.cpython-313-pytest-9.0.2.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d11c3b16ae52c8017fa5a35c33df78ed6e5067dc GIT binary patch literal 18987 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

13At?JslwLs5}pca74=fJz$xTOUSlqBp zK#oJ++YWb;QroF)2ZE{O?H9KfB)PES>37d)i=u^2nS7nH7LZGl`MV{_Guv&S;kbh^ zbjeJim3_oN$;bzTOd|DuUwM`4GE=U`$DcsTm5M7zSThfL?V71}B?Qj<< zwVld#AjyLoA$VN;n6JO@_OCt|5^t^(57tRHd-pGbhfY-6(8=Z|7_&qI=c~>VXpPko zo#p~9fdpC*ToFa*#=3V`({XxKa3y=W_zHroN@E@PS#hW?T3;Cpp^^=vvaYh?ZjAU8 zoR5YVzzvV)dQ{;b?~nH}u?e}Rvo+$i!xus#+$K2R0_MpYBR%rQKR$qt64To>m zJG{_}jd_vB=7d?HP(dbQ2xDD?W)XAqC;C?hy@5f4IQ%;2BlTu-dO7m+RM|1i18pu7l|5s1-bT& zn45`txYB)D*am77CE_^c+g-A_CgRQmIZs(!gY=c$vr9zT4D3_tWh_( zYvUK8ThjQ5$clEgA-4(|B%QwT}E$hIHOsfp5XbGCl}BqXP2kf#)W&{BK`i ziu8tl^+Go32r+myw~+ABsbY5!e2SvB!!m|7bneZqvk5+|$)DwZntN9*?H$(k4i`3I zgpd8USU8z1ojj$TJXOd{Y9}XO7cYx%Zv9v#0`l@x{q^D>2VvcmYGCtwJG~i%p8sS* z)jfPm0KM}W*L@?nlQM({95)C(s7}xyOi;`}0>BO;J5ag(c-4G~fM*c8AIlPdl|e}{ zS{1C9EILpki`Z>)e}^pEag25wdxb0_Rk{b9H~K>bc*>E-A1%nGF0dgAm(C?JXN*Dh z_VcoJA9!H6eX4p*zs2m)J^YTWOT=kpZ%{^eB88_4gwGwIoNH)xQl&(b7)Rz|axH@u zsW$|&c;_&|u*vZJMNxEj5`UsWqWNY2lTz-2rF)GgIIuQdfEj^t-cOYP0|2#cOjvD* zXa9x!kljb&C-Gk$!r6q2-``0=$Y*~ZZ2Fz8uVzcZKE?c%oC-+&6%^ls>k-3}(MEPp%lW~3NQ6l)XHyY2--w?pTy zY?!WB6(()gJGt#|4>ul=EuD1u?7$^l+6$7j0I+nb> z=B+ie-h0i9uZ&zx{$%WjW2NSe#paEF(edtce|_NQfkHG^ioU2tUo34KE^ZqxoERyc z$Y>`rr4u>rM6RG-xO3vdT+5=@4_rQQb-_Sdq`Bn1?Qq)(C@@w|ug&*5lkr=0Bus3`kqP>972qY(p{o0>Ki^17LF4r&W{HDw3k{$_;nb*OudEQ|zQj_tsx_;zDu*iW9zw^aTN zM{mT7_HN@3W^~gAO{m6`ovug1?VR>I9zWGbn~vI}<}!Gh!*?ISNB*ZZ_?v3}d7Hhu6Mc>krZphi<{u`T=)s LtQU_Ptla+xY9D?O literal 0 HcmV?d00001 diff --git a/tests/migration/__pycache__/test_mcp_contestation_subject_guard.cpython-313-pytest-9.0.2.pyc b/tests/migration/__pycache__/test_mcp_contestation_subject_guard.cpython-313-pytest-9.0.2.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b0f5f4c8ab92df1cfc83e89e3621b80eff55fb1c GIT binary patch literal 9000 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 T0DJiJ<_J6RxFf($P%r-i#58Bv literal 0 HcmV?d00001 diff --git a/tests/migration/__pycache__/test_original_contestation_validation.cpython-313-pytest-9.0.2.pyc b/tests/migration/__pycache__/test_original_contestation_validation.cpython-313-pytest-9.0.2.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9b41048420ca97ef9dde58d702ab10f96bf09176 GIT binary patch literal 42861 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 literal 0 HcmV?d00001 diff --git a/tests/migration/__pycache__/test_original_vas_variation_adversarial.cpython-313-pytest-9.0.2.pyc b/tests/migration/__pycache__/test_original_vas_variation_adversarial.cpython-313-pytest-9.0.2.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0240ce5f53672d31a252756924edcfa6246a12ce GIT binary patch literal 43326 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 literal 0 HcmV?d00001 diff --git a/tests/migration/__pycache__/test_vas_response_renderer.cpython-313-pytest-9.0.2.pyc b/tests/migration/__pycache__/test_vas_response_renderer.cpython-313-pytest-9.0.2.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0fc052a8244e6a34447e07afafe1eb6380d3b760 GIT binary patch literal 4433 zcmeHLO-vg{6yCMRf2?i(NdiROP>}2zmmGJ23TsuVm8u?ksiM+TPJOd~*fgrtsEvAHw7i|~n>T-N z*ZaQVFp+3tpbV>De)cV5n4c-|O2DlgjzQ%yBQOGcl_9Ks56lL&0ME=K65?q~;A(g_ zLLyKPb~7X@Ah5AzHXZtv4l(J`;19CZFM4Chju{hsnYi3bV+1lL^TMW{?q@g_d!outKZax4^y) zjq0V8>r(idVHUm3GxHFZ2MqPrgtkBc2o_M1#MKCt&jqU9McQy2S@rwLj*IA)M=*$Ezf}etfF5%Py z#LY&b#b$5Dx*fK7+|eCY5%N~y-6eQkCfV}q!s(MZ(@6d2aXxbr=T{Qv?vpsbia0Mb z>7F?&S|)0tlGn9rTkgs=egkt3lN1fhRydE9yd>wW&R7K+##>cC%Iccqg2|r6m8HQ1+ z$s8^%sYG=r19}7;tpubots?7~&`f4UZ(?m~SyJ>ZWW{tU_xy<1+> zB~2GGv0BAEmSvGhWs+A*WlSV1CTjSeL>Vg%p5juaDCv)b6VlxnTDa zmt}PcyAe%J*&BqX|2`oqvD(FZDk))Ilvc|!R#?jhv&){c#sk)=3#+a8Qug*Tp1b^AFAX*mhM~2mWs>7 zUW|?DJ96ae2qB4N%4^nnJ4{Y9l}8|uib`It6eLZ=EAYnRB^d_Caz)a}c~}?K8rpB5 zBi5OpqHVR#^!8gjIb--e7rTZsGvB*DjhcxM2tG*VTOoAh!!XG8>Rj@1cnrH)^2C zoeq9KVoem$F4aleW&}5BE8)#@VXL3Ua$h~&akin%LxL;TI z9e~`-`N(WQKD~#AYFx%ZW83{EH+F#BYZr|fT*iU>b#>nX$nAa~nGMLN!RZhlJJTST zBS6@KIRN%CXmd|6gSZW4f?4*M>Hlqa3k&;&wGQPWKg9K)DuV7@=iJ`XFZ4w*R3R=d2s>@Z$# zCcU)B0GPULLf!yu)n^3vlV4Eba}NW+w||8ygi=w{ipsL{-6vV-)j>!41+%~#DHWG{LGe2;>$G_CPfl?dOCYL%u?zM|j2FE*azpm~(0J$;k zBeMbd^d3spxMl?QwD?w z!a5^5vLfT;b4c|WB0VHUkXA9DvLY@=&eA@w;c_`shBOUvwG(p2mS None: + items = [ + { + "item_name": "TIM Fashion Mensal", + "claimed_amount": "10", + "validated_amount": "10", + } + ] + invoice = { + "currentInvoice": [ + { + "type": "servicos_contratados_de_parceiros", + "desc": "Serviços de valor adicionado", + "value": "76.98", + "items": [ + { + "type": "servicos_contratados_de_parceiros", + "desc": "TIM Fashion Mensal", + "value": "10.0", + "contestable": True, + } + ], + } + ] + } + + validated, validation_log, error = validate_contestation_items(items, invoice) + + assert error is None + assert validation_log[-1]["status"] == "aprovado" + assert validation_log[-1]["secao_vas"] is True + assert validation_log[-1]["item_fatura_resolvido"] == "TIM Fashion Mensal" + assert validation_log[-1]["tipo_fatura"] == "servicos_contratados_de_parceiros" + assert validated[0]["validated_amount"] == "10" + + +def test_validate_contestation_items_prefere_evidencia_vas_quando_item_aparece_em_multiplas_visoes() -> None: + items = [ + { + "item_name": "TIM Fashion Mensal", + "claimed_amount": "10", + "validated_amount": "10", + } + ] + invoice = { + "invoiceVariation": [ + { + "desc": "TIM Fashion Mensal", + "value": "10.0", + } + ], + "currentInvoice": [ + { + "type": "servicos_contratados_de_parceiros", + "desc": "Serviços de valor adicionado", + "value": "76.98", + "items": [ + { + "type": "servicos_contratados_de_parceiros", + "desc": "TIM Fashion Mensal", + "value": "10.0", + "contestable": True, + } + ], + } + ], + } + + _, validation_log, error = validate_contestation_items(items, invoice) + + assert error is None + assert validation_log[-1]["status"] == "aprovado" + assert validation_log[-1]["secao_vas"] is True + assert validation_log[-1]["tipo_fatura"] == "servicos_contratados_de_parceiros" diff --git a/tests/migration/test_vas_response_renderer.py b/tests/migration/test_vas_response_renderer.py new file mode 100644 index 0000000..a03ff62 --- /dev/null +++ b/tests/migration/test_vas_response_renderer.py @@ -0,0 +1,24 @@ +from app.presentation.tool_renderers import render_contas_vas + + +def test_vas_renderer_includes_available_values(): + result = { + "products": [ + {"name": "TIM Fashion Mensal", "can": {"cancel": True}, "details": {"valor": "10,00"}}, + {"name": "Aya Audiobooks Premium", "can": {"cancel": True}, "details": {"valor": "9,99"}}, + {"name": "Neymar Jr", "can": {"cancel": True}, "details": {"valor": "12,00"}}, + {"name": "Tamboro Mensal", "can": {"cancel": True}, "details": {"valor": "14,99"}}, + ] + } + text = render_contas_vas(tool_name="consultar_vas", result=result, state={}, agent_label="VasAgent") + assert "TIM Fashion Mensal (avulso): R$ 10,00" in text + assert "Aya Audiobooks Premium (avulso): R$ 9,99" in text + assert "Neymar Jr (avulso): R$ 12,00" in text + assert "Tamboro Mensal (avulso): R$ 14,99" in text + + +def test_vas_renderer_does_not_invent_missing_value(): + result = {"products": [{"name": "Sem Preço", "can": {"cancel": True}, "details": {}}]} + text = render_contas_vas(tool_name="consultar_vas", result=result, state={}, agent_label="VasAgent") + assert "Sem Preço (avulso)" in text + assert "R$" not in text