From 76c8cdc738f1d60c7a405c16ff180027c4aa895b Mon Sep 17 00:00:00 2001 From: "cristiano.hoshikawa" Date: Wed, 2 Sep 2026 13:07:21 -0300 Subject: [PATCH] nova funcionalidade: reconciliacao temporal --- .../__pycache__/__init__.cpython-313.pyc | Bin 1502 -> 1501 bytes .../__pycache__/base.cpython-313.pyc | Bin 1376 -> 1375 bytes .../__pycache__/config_loader.cpython-313.pyc | Bin 9161 -> 9160 bytes .../__pycache__/custom_rails.cpython-313.pyc | Bin 4405 -> 4404 bytes .../framework_llm_client.cpython-313.pyc | Bin 19674 -> 19673 bytes .../__pycache__/llm_rails.cpython-313.pyc | Bin 5924 -> 5923 bytes .../output_supervisor.cpython-313.pyc | Bin 24307 -> 24306 bytes .../parallel_executor.cpython-313.pyc | Bin 21863 -> 21862 bytes .../__pycache__/pipeline.cpython-313.pyc | Bin 10890 -> 10889 bytes .../__pycache__/rail_action.cpython-313.pyc | Bin 655 -> 654 bytes .../__pycache__/rail_decision.cpython-313.pyc | Bin 1606 -> 1605 bytes .../__pycache__/rail_result.cpython-313.pyc | Bin 1005 -> 1004 bytes .../__pycache__/rails.cpython-313.pyc | Bin 42854 -> 43324 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 2995 -> 2994 bytes .../__pycache__/_compat.cpython-313.pyc | Bin 2446 -> 2445 bytes .../contestation_validation.cpython-313.pyc | Bin 2178 -> 2177 bytes .../__pycache__/contracts.cpython-313.pyc | Bin 6902 -> 6901 bytes .../__pycache__/input_size.cpython-313.pyc | Bin 3650 -> 3649 bytes .../__pycache__/llm_adapter.cpython-313.pyc | Bin 3800 -> 3799 bytes .../__pycache__/llm_client.cpython-313.pyc | Bin 7455 -> 7454 bytes .../__pycache__/llm_rails.cpython-313.pyc | Bin 8895 -> 8894 bytes .../output_sanitization.cpython-313.pyc | Bin 13911 -> 13910 bytes .../__pycache__/pipeline.cpython-313.pyc | Bin 12662 -> 12661 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 474 -> 473 bytes .../__pycache__/_context.cpython-313.pyc | Bin 5872 -> 5871 bytes .../ausencia_oferta_proativa.cpython-313.pyc | Bin 12206 -> 12205 bytes .../__pycache__/coerencia.cpython-313.pyc | Bin 4158 -> 4157 bytes .../__pycache__/dlex_in.cpython-313.pyc | Bin 1305 -> 1304 bytes .../__pycache__/dlex_out.cpython-313.pyc | Bin 1816 -> 1815 bytes .../__pycache__/fallback.cpython-313.pyc | Bin 17653 -> 17652 bytes .../__pycache__/fraseologia.cpython-313.pyc | Bin 7634 -> 7633 bytes .../__pycache__/out_of_scope.cpython-313.pyc | Bin 17494 -> 17493 bytes .../prompts/__pycache__/pinj.cpython-313.pyc | Bin 8425 -> 8424 bytes .../__pycache__/ragsec.cpython-313.pyc | Bin 1121 -> 1120 bytes .../__pycache__/revprec.cpython-313.pyc | Bin 3151 -> 3150 bytes .../prompts/__pycache__/tox.cpython-313.pyc | Bin 645 -> 644 bytes .../toxicidade_output.cpython-313.pyc | Bin 929 -> 928 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 1664 -> 1663 bytes .../rails/__pycache__/alcada.cpython-313.pyc | Bin 5000 -> 4999 bytes .../rails/__pycache__/anatel.cpython-313.pyc | Bin 9149 -> 9148 bytes .../__pycache__/confirmation.cpython-313.pyc | Bin 11043 -> 11042 bytes .../rails/__pycache__/dlex_in.cpython-313.pyc | Bin 3280 -> 3279 bytes .../__pycache__/dlex_out.cpython-313.pyc | Bin 3332 -> 3331 bytes .../rails/__pycache__/ragsec.cpython-313.pyc | Bin 5463 -> 5462 bytes .../rails/__pycache__/revprec.cpython-313.pyc | Bin 5471 -> 5470 bytes .../rails/__pycache__/tox.cpython-313.pyc | Bin 8294 -> 8293 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 534 -> 533 bytes .../rules/__pycache__/alcada.cpython-313.pyc | Bin 1882 -> 1881 bytes .../__pycache__/pinj_patterns.cpython-313.pyc | Bin 3731 -> 3730 bytes .../__pycache__/tox_blocklist.cpython-313.pyc | Bin 1507 -> 1506 bytes .../src/agent_framework/guardrails/rails.py | 26 +- .../__pycache__/__init__.cpython-313.pyc | Bin 349 -> 348 bytes .../__pycache__/agent_runtime.cpython-313.pyc | Bin 185641 -> 200597 bytes .../transaction_parameters.cpython-313.pyc | Bin 11118 -> 14476 bytes .../agent_framework/runtime/agent_runtime.py | 298 +++++++++++++++++- .../runtime/transaction_parameters.py | 182 +++++++---- app/__pycache__/__init__.cpython-313.pyc | Bin 151 -> 150 bytes app/__pycache__/main.cpython-313.pyc | Bin 37623 -> 37622 bytes app/__pycache__/state.cpython-313.pyc | Bin 3397 -> 3396 bytes .../contas_prompting.cpython-313.pyc | Bin 1061 -> 1060 bytes .../contestacao_agent.cpython-313.pyc | Bin 5302 -> 5301 bytes .../__pycache__/faturas_agent.cpython-313.pyc | Bin 10802 -> 10801 bytes .../__pycache__/prompting.cpython-313.pyc | Bin 1148 -> 1147 bytes .../__pycache__/runtime.cpython-313.pyc | Bin 435 -> 434 bytes .../suporte_contas_agent.cpython-313.pyc | Bin 5898 -> 6247 bytes .../__pycache__/vas_agent.cpython-313.pyc | Bin 5713 -> 5712 bytes app/agents/suporte_contas_agent.py | 13 + .../__pycache__/__init__.cpython-313.pyc | Bin 233 -> 232 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 329 -> 328 bytes .../contas/__pycache__/client.cpython-313.pyc | Bin 51886 -> 51885 bytes .../contestation_rules.cpython-313.pyc | Bin 13577 -> 13576 bytes .../contestation_validation.cpython-313.pyc | Bin 25402 -> 25401 bytes .../conversation_policy.cpython-313.pyc | Bin 17026 -> 17025 bytes .../__pycache__/ic_tags.cpython-313.pyc | Bin 17227 -> 17226 bytes .../informational_context.cpython-313.pyc | Bin 3496 -> 3495 bytes .../invoice_context.cpython-313.pyc | Bin 20358 -> 20357 bytes .../invoice_models.cpython-313.pyc | Bin 1804 -> 1803 bytes .../invoice_resolver.cpython-313.pyc | Bin 56049 -> 56048 bytes .../__pycache__/item_matcher.cpython-313.pyc | Bin 9917 -> 9916 bytes .../line_reference.cpython-313.pyc | Bin 3430 -> 3429 bytes .../pro_rata_rules.cpython-313.pyc | Bin 17674 -> 17673 bytes .../protocol_triplets.cpython-313.pyc | Bin 7737 -> 7736 bytes .../__pycache__/rct_policy.cpython-313.pyc | Bin 6330 -> 6329 bytes .../__pycache__/service.cpython-313.pyc | Bin 21633 -> 21632 bytes .../string_metrics.cpython-313.pyc | Bin 6303 -> 6302 bytes .../vas_cancellation_message.cpython-313.pyc | Bin 16324 -> 16323 bytes .../__pycache__/vas_variation.cpython-313.pyc | Bin 42129 -> 42128 bytes .../workflow_actions.cpython-313.pyc | Bin 150212 -> 150211 bytes .../secure_pdf_crypto.cpython-313.pyc | Bin 2475 -> 2474 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 936 -> 935 bytes .../__pycache__/bill_parser.cpython-313.pyc | Bin 23740 -> 23739 bytes .../bill_processor.cpython-313.pyc | Bin 36255 -> 36254 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 303 -> 302 bytes .../tim_guardrails.cpython-313.pyc | Bin 26114 -> 37474 bytes .../__pycache__/tim_judges.cpython-313.pyc | Bin 5862 -> 5861 bytes app/extensions/tim_guardrails.py | 226 +++++++++++++ .../__pycache__/__init__.cpython-313.pyc | Bin 174 -> 173 bytes .../__pycache__/aluc.cpython-313.pyc | Bin 6389 -> 6388 bytes .../ausencia_oferta_proativa.cpython-313.pyc | Bin 10751 -> 10750 bytes .../__pycache__/fraseologia.cpython-313.pyc | Bin 7528 -> 7527 bytes .../__pycache__/out_of_scope.cpython-313.pyc | Bin 17020 -> 17019 bytes .../__pycache__/revprec.cpython-313.pyc | Bin 3087 -> 3086 bytes .../__pycache__/rqlt.cpython-313.pyc | Bin 1096 -> 1095 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 165 -> 164 bytes .../telemetry_observer.cpython-313.pyc | Bin 4988 -> 4987 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 257 -> 256 bytes .../tool_renderers.cpython-313.pyc | Bin 5430 -> 5429 bytes .../__pycache__/agent_graph.cpython-313.pyc | Bin 73360 -> 73359 bytes config/judges.yaml | 2 +- .../conftest.cpython-313-pytest-9.0.2.pyc | Bin 829 -> 826 bytes ...sarial_parity.cpython-313-pytest-9.0.2.pyc | Bin 53228 -> 53225 bytes ...ntract_parity.cpython-313-pytest-9.0.2.pyc | Bin 37544 -> 37541 bytes ...nd_guardrails.cpython-313-pytest-9.0.2.pyc | Bin 4259 -> 4256 bytes ...rapper_parity.cpython-313-pytest-9.0.2.pyc | Bin 29071 -> 29068 bytes ...site_workflow.cpython-313-pytest-9.0.2.pyc | Bin 65485 -> 65482 bytes ...aining_parity.cpython-313-pytest-9.0.2.pyc | Bin 40363 -> 40360 bytes ...ompt_contract.cpython-313-pytest-9.0.2.pyc | Bin 6836 -> 6833 bytes ...icy_residuals.cpython-313-pytest-9.0.2.pyc | Bin 35554 -> 35551 bytes ...s_domain_mock.cpython-313-pytest-9.0.2.pyc | Bin 64307 -> 64304 bytes ...ation_routing.cpython-313-pytest-9.0.2.pyc | Bin 17213 -> 17210 bytes ...ss_rules_full.cpython-313-pytest-9.0.2.pyc | Bin 23187 -> 23184 bytes ...ilure_mapping.cpython-313-pytest-9.0.2.pyc | Bin 7664 -> 7661 bytes ..._out_of_scope.cpython-313-pytest-9.0.2.pyc | Bin 3507 -> 3504 bytes ...ck_regression.cpython-313-pytest-9.0.2.pyc | Bin 8377 -> 8374 bytes ...ty_resolution.cpython-313-pytest-9.0.2.pyc | Bin 10088 -> 10085 bytes ...y_mcp_service.cpython-313-pytest-9.0.2.pyc | Bin 20540 -> 20537 bytes ...aining_parity.cpython-313-pytest-9.0.2.pyc | Bin 17942 -> 17939 bytes ...ls_judges_spi.cpython-313-pytest-9.0.2.pyc | Bin 10125 -> 10122 bytes ...rity_extended.cpython-313-pytest-9.0.2.pyc | Bin 39468 -> 39465 bytes ...ent_gap_fixes.cpython-313-pytest-9.0.2.pyc | Bin 6816 -> 6813 bytes ...ion_directive.cpython-313-pytest-9.0.2.pyc | Bin 5874 -> 5871 bytes ...ive_structure.cpython-313-pytest-9.0.2.pyc | Bin 18962 -> 18959 bytes ...rag_directive.cpython-313-pytest-9.0.2.pyc | Bin 9450 -> 9447 bytes ...k_zero_legacy.cpython-313-pytest-9.0.2.pyc | Bin 1785 -> 1782 bytes ...binary_parity.cpython-313-pytest-9.0.2.pyc | Bin 12219 -> 12216 bytes ..._dict_history.cpython-313-pytest-9.0.2.pyc | Bin 1977 -> 1974 bytes ...ent_lifecycle.cpython-313-pytest-9.0.2.pyc | Bin 4906 -> 4903 bytes ...faults_parity.cpython-313-pytest-9.0.2.pyc | Bin 6441 -> 6438 bytes ...ime_stability.cpython-313-pytest-9.0.2.pyc | Bin 12468 -> 12463 bytes ...drail_context.cpython-313-pytest-9.0.2.pyc | Bin 8345 -> 8342 bytes ...cy_resilience.cpython-313-pytest-9.0.2.pyc | Bin 7342 -> 7339 bytes ...user_feedback.cpython-313-pytest-9.0.2.pyc | Bin 7683 -> 7680 bytes ...mework_native.cpython-313-pytest-9.0.2.pyc | Bin 43112 -> 43109 bytes ...inal_response.cpython-313-pytest-9.0.2.pyc | Bin 4548 -> 4545 bytes ...andoff_policy.cpython-313-pytest-9.0.2.pyc | Bin 10767 -> 10764 bytes ...ed_meaningful.cpython-313-pytest-9.0.2.pyc | Bin 4621 -> 4618 bytes ...xt_compaction.cpython-313-pytest-9.0.2.pyc | Bin 8381 -> 8378 bytes ..._alternatives.cpython-313-pytest-9.0.2.pyc | Bin 23144 -> 23141 bytes ...subject_guard.cpython-313-pytest-9.0.2.pyc | Bin 21826 -> 21823 bytes ...ct_resolution.cpython-313-pytest-9.0.2.pyc | Bin 5050 -> 5047 bytes ...cy_dependency.cpython-313-pytest-9.0.2.pyc | Bin 1895 -> 1892 bytes ...clarification.cpython-313-pytest-9.0.2.pyc | Bin 0 -> 2197 bytes ..._code_mapping.cpython-313-pytest-9.0.2.pyc | Bin 23698 -> 23695 bytes ...compatibility.cpython-313-pytest-9.0.2.pyc | Bin 20449 -> 20446 bytes ...ider_boundary.cpython-313-pytest-9.0.2.pyc | Bin 5714 -> 5711 bytes ...istry_actions.cpython-313-pytest-9.0.2.pyc | Bin 16944 -> 16941 bytes ...on_precedence.cpython-313-pytest-9.0.2.pyc | Bin 5393 -> 5390 bytes ...liance_anatel.cpython-313-pytest-9.0.2.pyc | Bin 17440 -> 17437 bytes ...on_validation.cpython-313-pytest-9.0.2.pyc | Bin 51108 -> 51105 bytes ...transcription.cpython-313-pytest-9.0.2.pyc | Bin 11604 -> 11601 bytes ...ation_message.cpython-313-pytest-9.0.2.pyc | Bin 23885 -> 23882 bytes ...vas_variation.cpython-313-pytest-9.0.2.pyc | Bin 142649 -> 142646 bytes ...n_adversarial.cpython-313-pytest-9.0.2.pyc | Bin 43301 -> 43298 bytes ...orkflow_cases.cpython-313-pytest-9.0.2.pyc | Bin 18727 -> 18724 bytes ...act_hardcodes.cpython-313-pytest-9.0.2.pyc | Bin 9971 -> 9968 bytes ...a_full_parity.cpython-313-pytest-9.0.2.pyc | Bin 18860 -> 18857 bytes ...ional_context.cpython-313-pytest-9.0.2.pyc | Bin 5900 -> 5897 bytes ...ration_compat.cpython-313-pytest-9.0.2.pyc | Bin 14142 -> 14139 bytes ..._29_stability.cpython-313-pytest-9.0.2.pyc | Bin 9282 -> 9279 bytes ...and_contracts.cpython-313-pytest-9.0.2.pyc | Bin 14543 -> 14540 bytes ...ty_pente_fino.cpython-313-pytest-9.0.2.pyc | Bin 30789 -> 30786 bytes ...c_uncertainty.cpython-313-pytest-9.0.2.pyc | Bin 8247 -> 25228 bytes ...ance_guidance.cpython-313-pytest-9.0.2.pyc | Bin 5889 -> 5886 bytes ...n_all_domains.cpython-313-pytest-9.0.2.pyc | Bin 31311 -> 31308 bytes ...nto_grounding.cpython-313-pytest-9.0.2.pyc | Bin 4955 -> 4952 bytes ..._continuation.cpython-313-pytest-9.0.2.pyc | Bin 24544 -> 24541 bytes ...ntract_parity.cpython-313-pytest-9.0.2.pyc | Bin 12420 -> 12417 bytes ...d_idempotency.cpython-313-pytest-9.0.2.pyc | Bin 14785 -> 14782 bytes ...tadata_parity.cpython-313-pytest-9.0.2.pyc | Bin 34887 -> 34884 bytes ...andoff_bypass.cpython-313-pytest-9.0.2.pyc | Bin 14380 -> 14377 bytes ...eration_types.cpython-313-pytest-9.0.2.pyc | Bin 6140 -> 6137 bytes ...dated_subject.cpython-313-pytest-9.0.2.pyc | Bin 8319 -> 8316 bytes ...ispute_parity.cpython-313-pytest-9.0.2.pyc | Bin 13783 -> 13780 bytes ...onse_renderer.cpython-313-pytest-9.0.2.pyc | Bin 4407 -> 4404 bytes ...mation_bypass.cpython-313-pytest-9.0.2.pyc | Bin 6241 -> 6238 bytes ...saction_scope.cpython-313-pytest-9.0.2.pyc | Bin 10406 -> 10403 bytes ...ecution_latch.cpython-313-pytest-9.0.2.pyc | Bin 7685 -> 7682 bytes ...ast_contracts.cpython-313-pytest-9.0.2.pyc | Bin 17446 -> 17443 bytes ...match_retry_deterministic_clarification.py | 24 ++ .../test_revprec_epistemic_uncertainty.py | 58 ++++ 190 files changed, 747 insertions(+), 82 deletions(-) create mode 100644 tests/migration/__pycache__/test_no_match_retry_deterministic_clarification.cpython-313-pytest-9.0.2.pyc create mode 100644 tests/migration/test_no_match_retry_deterministic_clarification.py diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/__pycache__/__init__.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/__pycache__/__init__.cpython-313.pyc index d0b2b90738a03416fa836880cb94d155e77983fe..bc07267eb827d1aee88907ef46a6e8f889f788d2 100644 GIT binary patch delta 36 qcmcb|eV3d2GcPX}0}w>I%-G2Nk%hZbKR2&LKSkd+*mE)m>oowzMhg7^ delta 37 rcmcc1eUF>_GcPX}0}zCtowkwtBMVQJer{fgezLw}acS{ncGhbE-I%-G1y%fwx(pPN^rpQ7&@?73Nm$%YvKz!M3# delta 38 scmcc5^?-}}GcPX}0}zCtowkvimx-rLKR2&LKUv?gxU_h)GLsE60NJ(*?*IS* diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/__pycache__/config_loader.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/__pycache__/config_loader.cpython-313.pyc index 750a7f1f5e827af5e957ed077ceffa4cd70512da..868b18d1c68ef28ae7b7788843ff58f67e7b3512 100644 GIT binary patch delta 37 rcmX@I%-G27z{FjrpPN^rpQ7&@?72CdsYnq3&-e<) delta 38 scmX@%e$t)$GcPX}0}zCtowkwNfr+PHKR2&LKUv?gxU_h47*mlV0O}(P{r~^~ diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/__pycache__/custom_rails.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/__pycache__/custom_rails.cpython-313.pyc index abe2d9d7931fd9faec209e02a7bc0e2959a47dea..5297e5ad4953625c7f5d11fa71b9483e3c353f83 100644 GIT binary patch delta 37 rcmdn0v_*;gGcPX}0}w>I%-G1C#=>2zpPN^rpQ7&@?76v?Wd{!c#5D@k delta 38 scmdm@v{i}wGcPX}0}zCtowkuXjfJO9KR2&LKUv?gxU_h44a*K50Nxc03;+NC 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 1c44d7be708b26345ab95b519bf56568302baeda..6a077d2e3b0467ea95eedd50ac46848b3dc5d928 100644 GIT binary patch delta 39 tcmcaLlkw(EM()qNyj%=G5a}{wBX=JscdLGGUWtB+zHhMS=B1pb&H(p%3?u*m delta 40 ucmcaPlkwI}M()qNyj%=G5Po*rM(#dNo;Lm5yb}FneaGU`;>}AqO`QP}*9}|% 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 3e23168589e04dd8d4421607ae797f85065730f9..70803d59f104dd23c8029ee18eda570ab42132de 100644 GIT binary patch delta 37 rcmZ3Yw^)z+GcPX}0}w>I%-G01nVGvvKR2&LKSkd+*mLtL<|<(T#s&)L delta 38 scmZ3iw?vQoGcPX}0}zCtowkvCGBZ!Ler{fgezLw}acS}9mCRMb0N@1-AOHXW 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 863d19cd864fc7ea77c66ed77dcb98566b17ec1d..c62f7b427e4f20701c0f23fb7bf4fe6c18a25b1c 100644 GIT binary patch delta 39 tcmeyom+{kHM()qNyj%=G5a}{wBlmYM?k4@*yb}Esecxcu&3xQXg8>ic4KM%z delta 40 vcmeygm+|vnM()qNyj%=G5Po*rM(*!iJk9#Kc_sSE`i{k=#hZD#p9TW}EEW!E diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/__pycache__/parallel_executor.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/__pycache__/parallel_executor.cpython-313.pyc index e4bd26ef64c4347c1838419e5787ea09aa1aee86..dd9c3d8e84ab119f8abf8d43b3830397bd3431fa 100644 GIT binary patch delta 39 tcmaF9it*VhM()qNyj%=G5a}{wBexqXcawf@UWtB+zHhMS=2%v)008*i3#R}8 delta 40 ucmaF1it+g>M()qNyj%=G5Po*rMs7D&o@V{ryb}FneaGU`;>|IvTmb+SCk)>J 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 063409316710bad40f31a1e3fff6ba1e1cfb7d1d..49c70be651ff6bd9e8d04c9676ae6ef38066c70e 100644 GIT binary patch delta 37 rcmeAQ?F{Aq%*)Hg00faPGd6NRX6CNc&&?~*Pto@c_T2o7d4d`M(7y}H delta 38 scmeAS?F!}o%*)Hg00iM@r)}hZ%*<1zpPN^rpRDg#Tw1*OC-Vd~0P80W0ssI2 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 3dc9f8ef64a804c207612a492fa40ba2b16434ad..93052a6e8103fc2547c304dcdfaf3d2198f8ddd3 100644 GIT binary patch delta 37 rcmeBY?PKNs%*)Hg00faPGd6PPGjiAH=jN5@r|A0zdv0!HI%-G0X&dgn>pPN^rpQ7&@?76v*c?S~!#BmDY delta 38 scmX@gbBu@kGcPX}0}zCtowkv?oSCOyKR2&LKUv?gxU_h4FY^v20Nz*(82|tP 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 4a31c5dc9ca03a0f9f006535d53c6db046e9321e..67dcd0c3d0071a67e1fdedad6ccec30942b24954 100644 GIT binary patch delta 37 rcmaFM{)V0VGcPX}0}w>I%-G1C%*0)zpPN^rpQ7&@?76v$shAM}%YO>9 delta 38 scmaFE{+6BlGcPX}0}zCtowkuXnTe-XKR2&LKUv?gxU_h4B~vjY0OgYl>i_@% diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/__pycache__/rails.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/__pycache__/rails.cpython-313.pyc index 8cb01ecc497c43b50d6f0d970b21568197e6da01..0dbd89ea93dcfd053c5674d3e89c87f550cb12b9 100644 GIT binary patch delta 2549 zcmZWrdsI~C5x;ZyA?${Q2q@wzmlX+1Q$Rry(5MK=LlE2rE77vK?p|nQB0Mj zP%E(~Q70;qR#20k;;F|b_oVGb@whmXz<*6;{TnR@UbZ-l=FZ%9e<;_JTkEV+eMVcBIgZN2Oa z04R+hG=ej|F~(_d+H!Qx*djxQ5ELc;_zf*WjIi#h#X_Y;)BnKoG=7x49n&S1hFgX}vVRtCZ6jzJv^|=Bair+iI zcgL=0wLBrK;}A6|ES?3JE7aAYL=6h#G8PtQz=OE9urehYTfW7ubcDPCe^gHt=H*Uy zGs+Jqim!rSTtkBmXg7q;YB%jJ}O-1ulVWaIRrrtWQ` zFuN6Qdq9_Hxt+t|?nI1`Fk@Uuh_y_Zgd{1FJmWyqo~B5OH8R~3Nt<&mePP6wdD)gZ z6g+CbWGi^zR&aTiG?X~7X2>%X>~FpuYe=1X+iXs<+!4%imU~~Ad8GS6n&Wp%9;#jh zZ`y5D>H6Qs#}hWrF3sS&(;`%5>QC!R4191VHnS>QIFk!iS^6`1dXfuD^10z$7VyEj zY*TfS?p#4}b%Aa)2e>?%OKzhD29k?()r;_rqB2lWU+j-_^UaMKR@c=f5xU1N{&pM2MY zKg0CpsrdKC^QL>mCb)y6t8H*k{dDyj5G|rwv1TX06@0JhCzd?!!q#w36gIQd>W;_% z2Egy)x-o!9v95VLY```(dHl+oBhF%)Si+$=@Pg5y3(N zZ5FjyH!#a=pfLeolfqC!)EDT&Qb`ft2S~?1#Pc7vLPf{Y2hx7!!IJhZO^iY~|e1J`dJ!%GfAI$AU z@DqHtHzda}F7f&p06GzUWX$56eklbfScH^@F;*zNVp)Kpx|8*F1? zZfLNJdItDfz7VA@A<2!`=cw*>ptH@e@{ zK^Z>XV>6a>bu=Hp-6P?-oUru0;)@aEDK^8(9{e#~_i7?Q*b9@kC=f zSRfQ|2YgXoo6^M&q1>Bf(mV-XRl9rdiN+R+^rHII_m{!sN%xRq6%Y3Hlm5fb#W04m z`@+^&Ipu3sa{4)kF+9;H!7uQ=zGT>nH~U%*zvkL^(DBR_xTfaqI%G)D>i2bWn7s7r z)!n}YaN>cz>);el>}{N<%`uVIvyfme0fk|Q38?=?jo}WD98%avd|-c&e@K$>Sxlb1 zLNDSlE;pVf?kT*3Zupbh^!#F-=_F|guHoSWl6Vp@zBmQP4mjf-yr`p79OVrzM|lm~ zgOBxB@V@!I{$g0I{-(ba%u#Z^NDx8G!Rg$Xc`(hWX)Ez?V+y(tO3;M82X|UO{XSa4D^hbD<9b}RDHASfx8ec?BXD5nz+CadWa(TVNCKDoj{&_7TJip&An&#v zgA39lv`Q1pqm5WV&_JNI*eJoNUpv6;^Re|KSs1&ToV*^&WcNdgQG=(wH zQjhpRe4yr|X;k_eHOD_x7?n%{G9Rm%rCCinji$|%*7TjrG*jJ~{c-Pkedm1N`3|QC zg!{dM=dUlms8jLBdU?y62e8vKOB_}gS>

7Dpz@E}2z`#&Me>h6-0T2yX}D^oU{X zoVi?$Sy5J8{gM;(=#%G0QPQ!+vQTWlck(u)aRd5+R zS`2Dm&qov0Ub^4qI3DqxqzH=%&YFxCgXWx<7cn>`l#9*_U9mJ$VuI;hAJJ6tZ8ESAfu?Lhp(|T{jsK=3(oMDCpi4G8=tT{a_7? zNDUC+YfPDSRBYyZEMLPTRy__+d#bxdK7=*sV==-loMNemJ?yCEI>6^_?VLpdoWY;d zUxF(boS}z{7?<(3*hw+Eu_k^pdyuhJn9$4pdG6^H>o_5kkVW{OFq*K2@C_cBmjMs4 zvmpreSru@OHD%?(h@ZI5?NMB5ljW)sXZe!F(!;@$?vWE=5BlY#!96PJP>v7WWv6nk zf%k8u{&)0_yav&&aW1Pa!7%G;_z@3VAL^cx72z)K$v47N)|Hw#s(y5Sw^Gi_?N}2e$bdGl>c_^Et?9TwEmqiDD%hxn%CGwU2XK)91 zm4!kYc9m@b6I)QO5qQkPH+T4Dk?|D5RDzOD8hTX(d8p`{z^jX?_yGhJAcTy@*s56| zv6WR_0^gGv)ysks$nY9%jGjYQa~KROr2vv7qPsc@>Ty`jfaoMU8Q-td<6kv;sAK+o zVW_3WbcLi-fG#;)C>&hs=cSYIJ9!i|us`H}@F*uEJK;yX>aq=~;;+0{5-_1Q5E8MV zb}BR>){ccGc%t?-V+~ikhnL$bD_zBQhs|kU;wY5ta)ngQ6*(q>=VGce3ogJTHO3KA zBbj@+9K|J)(`I)#mnpf%!D{TOyREC|T8Yqrol6Zu{XYrD!+JJ;89)0LWc3?iBTIeD z19WsVB*J=Ju-qUt|6@G~&n_PcTiNyHr2=fkgoaD7gL$kh1lGoA-Ph2|#Pz$h-b!bFN&yCMF#BZFNq`Kj z+FZa#!)KdwCn~x6Qi$ngC|oKRGeE|TDipLl=|`cju7|?1KVGPS-7Bmt$!ak&oDt*+je?xB=GK1 zB3#91?Isvddi*klBqZY8ongY|!KP^0nFQ(V@=lE!7U94ina|dl9nsund52zXBA2V! z-eKnAOC9<#Rua&GyS?m=T3e-kaiPOiRU+AorMslMkK*2B{vW}z_e0R#APFHI|J-MQ z8yLL5d(>m9X^50dHE9W{gva>%{!p=v9OkpJADo8dZW1daT^XD-^OR{YcuSS*pme#? pxXQ69=cH`8Qt1sGbFhGqMr=5E$15Lri(8(k=U diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/__pycache__/__init__.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/__pycache__/__init__.cpython-313.pyc index 57f8c4542d823419bc78cb51c051417de7b08ab0..715230e57f7d0b450a19bedc8256c74252cba0d3 100644 GIT binary patch delta 37 rcmdlizDb<>GcPX}0}w>I%-F~sz{%aBpPN^rpQ7&@?72Ce(}xKFzMu*z delta 38 scmdlazFD06GcPX}0}zCtowkuXfRm?HKR2&LKUv?gxU_h48mA8v0N7j$VE_OC 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 20682da7bb6f8e411924e7e17ad7331b6034f6c6..4d7ec5293811e4addbe3a4d1a072f1b14b42769c 100644 GIT binary patch delta 37 rcmeAZ?iJ?#%*)Hg00faPGd6P1VdHMr&&?~*Pto@c_T0Rg?KTqty2A?h delta 38 scmeAb?i1$z%*)Hg00iM@r)}h(!^YF1pPN^rpRDg#Tw1(&6WeVj0MvC1F8}}l diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/__pycache__/contestation_validation.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/__pycache__/contestation_validation.cpython-313.pyc index e88ed6e5bd2da5259d7b84913ba03e1d69d22ebd..ac2b9d0892605011c7935ffe13ab9719ff671ada 100644 GIT binary patch delta 37 rcmZn?Y!u}F%*)Hg00faPGd6Oov2st=&&?~*Pto@c_S|gC>dFiNtNjUR delta 38 scmZn^Y!c-D%*)Hg00iM@r)}g`W96BmpPN^rpRDg#Tw1)@hSilB0L3f{pa1{> 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 2e692edbd55785466e6c15d1c72d616381a30563..c5bcaafc4319105428670a5510c3000483d114ec 100644 GIT binary patch delta 37 rcmexn`qh;CGcPX}0}w>I%-G0%ijBKfKR2&LKSkd+*mLtkHc=4(kb5Mr+GcPX}0}w>I%-G2Nmxa4cKR2&LKSkd+*mJW8s~#r+&qfN3 delta 38 scmX>ob4Z5!GcPX}0}zCtowkwtFAGn*er{fgezLw}acS{pVOBj(0O`~V#Q*>R diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/__pycache__/llm_adapter.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/__pycache__/llm_adapter.cpython-313.pyc index 9772a2ded6f2e8ceba2122fc7f6a53225d75cfca..df23f355650fb7952bf91ec532fba9bf41687cf6 100644 GIT binary patch delta 37 rcmca1dtH|MGcPX}0}w>I%-G0Xz`@I%-F~s#lhXCpPN^rpQ7&@?76v+W1R>9#90c@ delta 38 scmbPdHQ$Q+GcPX}0}zCtowkuXii4+JKR2&LKUv?gxU_h40mnKK0Ny?f2LJ#7 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 fcdc277ac7b95a90672b7e4ad851d479d2cb1294..8b9f7599029680bc86942b628d4438211f0474dd 100644 GIT binary patch delta 37 rcmdn*y3dvSGcPX}0}w>I%-G0n$jsfUpPN^rpQ7&@?77*4xm+Fq%g_p( delta 38 scmdnzy5E)iGcPX}0}zCtowkwNkeR1VKR2&LKUv?gxU_h)J9D`_0Oi~Z)Bpeg 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 a36bce592cbe6c0296e9575facd16d35449f8e81..fb48f8ca3aeb0f4fff944978aafa48b6fcc70cee 100644 GIT binary patch delta 37 rcmcbfb1jGaGcPX}0}w>I%-F~s&&l1dpPN^rpQ7&@?76v&^Pvs^<68^^ delta 38 scmcbXb3KRqGcPX}0}zCtowkuXo|9*Ser{fgezLw}acS}9QqG4u0RAHlI{*Lx 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 daa206a97acdf592ee3d7a8fa1bf052e5395541c..1b50e7c17d260347ee59d8e7711dd5928d87d54b 100644 GIT binary patch delta 37 rcmeyC^fih5GcPX}0}w>I%-G1SD!|>MpPN^rpQ7&@?77)Sz)BGS;;Rb^ delta 38 scmeyG^eu_|GcPX}0}zCtowku%Re+~eKR2&LKUv?gxU_h)wSbi(0R3MKLI3~& 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 24c0300fb4635484c3c12be9d42734fc314a319d..a1c0ae305a27df0d2bc176fe80f54529231552cb 100644 GIT binary patch delta 36 qcmcb`e3O~`GcPX}0}w>I%-G1y&&b`QpPN^rpQ7&@>^WJDaSH&nL<$Q4 delta 37 rcmcb~e2ba;GcPX}0}zCtowkvipOL3mKR2&LKUv?gxU_h(D&rOa%&iMU 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 84a4672d73191518a3a87cdcee988b34cb326b0c..85e68340b1d72c1cd90dea97e82cc26e173bac58 100644 GIT binary patch delta 37 rcmeyM`(Bs(GcPX}0}w>I%-G1ig@wCEKR2&LKSkd+*mLt~7F8ht-k}SA delta 38 scmaE_`$3ocGcPX}0}zCtowkvC3ky%Ler{fgezLw}acS}9Q!J`N0QqVRwg3PC 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 d2948c87f21870463b042c70c4d2f9c96c5ef30c..014d27e96a36f95ec1c0fd0c4e9266dd33eab2a8 100644 GIT binary patch delta 37 rcmZ1%zc!xxGcPX}0}w>I%-G27tH(V@KR2&LKSkd+*mHA=o);qk)h7!G delta 38 scmZ1*zb>BpGcPX}0}zCtowkwNSC40|er{fgezLw}acS}9WIZoN0Pmv=KmY&$ diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/prompts/__pycache__/coerencia.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/prompts/__pycache__/coerencia.cpython-313.pyc index f78d1ba0acc9454e37fa4d15068e5014008b1e41..1adbe28eb841de9616eebac4d71ef9f39cefebd4 100644 GIT binary patch delta 37 rcmdm|uvdZmGcPX}0}w>I%-G0%nvc6zKR2&LKSkd+*mLtEz8FRT&{GR( delta 38 scmdn1uup;eGcPX}0}zCtowkwtG#^i&er{fgezLw}acS}9hkP-N0P4UDp#T5? diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/prompts/__pycache__/dlex_in.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/prompts/__pycache__/dlex_in.cpython-313.pyc index ce28e29f60ed86300bcf649969a149c91206e998..4c25391337980b36a9fe703021c28963b20fc7d5 100644 GIT binary patch delta 37 rcmbQqHG_-$GcPX}0}w>I%-G2Nmzld;KR2&LKSkd+*mJW83o9c4zOxDG delta 38 scmbQiHIs|`GcPX}0}zCtowkwtFEdY%er{fgezLw}acS{pVHQ?K0NBq9ApigX diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/prompts/__pycache__/dlex_out.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/prompts/__pycache__/dlex_out.cpython-313.pyc index d7b0e3d32902954deba9eba31579334ebd8549ae..4c834efd5965242d74ec0a4ffec468de942f8bec 100644 GIT binary patch delta 37 rcmbQiH=U3BGcPX}0}w>I%-G0%o|U^tKR2&LKSkd+*mLtURwG6Lzw!#i delta 38 scmbQvH-nG+GcPX}0}zCtowkwtJS$JHer{fgezLw}acS}9r>sVd0NLpa`~Uy| diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/prompts/__pycache__/fallback.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/prompts/__pycache__/fallback.cpython-313.pyc index f18b89eb7b5bdbf9ac3c4e0c90cc9f7be03e6a1c..ae92b20e17b3fe65ed64b052b5263daebf64da16 100644 GIT binary patch delta 39 tcmey`$@ry{k^3_*FBbz4M7qq_$XzAR-J_qISE8Sy?;Gs7d7^xZDggV13|0UD delta 40 ucmey;$@sOCk^3_*FBbz4grA+Zk-JKsr&m8WuS7pt-?6x~c=H7L6jcBh0S%4- diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/prompts/__pycache__/fraseologia.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/prompts/__pycache__/fraseologia.cpython-313.pyc index 87681d3431fd35e19b7ec29bcc3f19b5f35f0546..e757574e3fd728b50846b30f19e5361352d4ec2a 100644 GIT binary patch delta 37 rcmca)ebJixGcPX}0}w>I%-F~sEW_QepPN^rpQ7&@?72BhCW8?G)9VWX delta 38 scmca;eaV{pGcPX}0}zCtowkuXScYeUer{fgezLw}acS}9OqmQu0Pao};25*Yy*-wrtd 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 528d2668fa31b5b03e8f9cdf8c38d2f465f9639b..d785a3a97bbd4faf9de0b58fee6ae3858a830843 100644 GIT binary patch delta 37 rcmaFq_`;FI%-G0XCC}ZVpPN^rpQ7&@?74ZOd;}u^-!}_* delta 38 scmaFi_|lR4GcPX}0}zCtowkv?N}i`vKR2&LKUv?gxU_il1o;R?0QvU}umAu6 diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/prompts/__pycache__/ragsec.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/prompts/__pycache__/ragsec.cpython-313.pyc index 384cd688b7994f0acadc083fe5dcfcec89cec7f0..c586b640d91df9e5c49d5e988e69e9320d33275f 100644 GIT binary patch delta 37 rcmaFJ@qmN-GcPX}0}w>I%-F~+!_3{KpPN^rpQ7&@?77*PS&tC_!fy%M delta 38 scmaFB@sNZ2GcPX}0}zCtowku%hMA{ZKR2&LKUv?gxU_h)5wjj60NgbT5&!@I diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/prompts/__pycache__/revprec.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/prompts/__pycache__/revprec.cpython-313.pyc index dde7d4644fb02e949d73b3d6b564440b6123a745..6b2041d107c31b9079ddeab16eabbac66e8c7731 100644 GIT binary patch delta 37 rcmX>vaZZB!GcPX}0}w>I%-G0%n~S?!KR2&LKSkd+*mLtIu2@C@)9DM6 delta 38 scmX>nabAM^GcPX}0}zCtowkwtHWyEier{fgezLw}acS}9k6f{g0Pb=O$^ZZW 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 84f78f39621fe372343b03b9b3f0a6dce95186ba..50fcb15315db1bede1c74cb5e84546b43cf02b93 100644 GIT binary patch delta 36 qcmZo=ZDHm9%*)Hg00faPGd6M;GIF=;=jN5@r|A0zdrt0P{0ji3mI`eE delta 37 rcmZo+ZDr;D%*)Hg00iM@r)}geWaR14&&?~*Pu6!VE-jwi&iEGqy|xRb 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 9600db02d704117cf52dd9f357d843c4f6acbcff..ec8f20bfffdc05d4eb959676e0e5b4481cf8ffad 100644 GIT binary patch delta 37 rcmZ3;zJQ(kGcPX}0}w>I%-G1C$izKWKR2&LKSkd+*mH9QlO`how(SY# delta 38 scmZ3$zL1^!GcPX}0}zCtowkuXk%?!Ter{fgezLw}acS}9awbhi0MLL79smFU 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 679d83d10e29c60713d7d83b41dbf7039be865d1..8f3fac0e59edec9b26db2429aa7ccabf2a329098 100644 GIT binary patch delta 36 qcmZqR{m;YwnU|M~0SF>pW^CkM$jaTNpPN^rpQ7&@>^XS{>j?n6YYQj< delta 37 rcmey*)4!fKR2&LKUv?gxU_ikcGeRB)kO?o 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 5001ab461a8e646449038af40d777a3bbbaa09e6..e93d71eecabdb08a030bd5d6888654fc87e23c2c 100644 GIT binary patch delta 37 rcmeBBZ&&C3%*)Hg00faPGd6O+X5;SA&&?~*Pto@c_T0?G-o^s}!B+}w delta 38 scmZoy?@;Id%*)Hg00iM@r)}hZ&BoKIpPN^rpRDg#Tw1)Dk-d!v0NZ&BqyPW_ 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 93af9183a3a89a4dd1f21e88e95ec25e8f6823b0..659cca02653235768827f185384e795c29ffaf11 100644 GIT binary patch delta 37 rcmdn%zQ>*WGcPX}0}w>I%-G2Nm7BXmKR2&LKSkd+*mE-v&qi?o+OG?0 delta 38 scmdnvzSo`mGcPX}0}zCtowkwtD>qN4er{fgezLw}acS{pZk~I%-G0nEY97hpPN^rpQ7&@?77)X{H8Df%diU( delta 38 scmZ1!wm6LYGcPX}0}zCtowkwNSe&O{KR2&LKUv?gxU_h)r}#}_0OiFDNdN!< 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 2d893db11a0d4a7f7744c5eaae535ef28c406c98..f157348833b606390bde56eab02e3b9cc89f11d1 100644 GIT binary patch delta 37 rcmca0d0vwHGcPX}0}w>I%-G0%kd?brKR2&LKSkd+*mLs@)*oyD($fp} delta 38 scmX>vc|nr#RT60PQ~wE&u=k 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 7152ce1a948001f029cf67778af66eeb84ed61e2..e437bea977eb6981c862977590bbd233fde71cd5 100644 GIT binary patch delta 37 rcmZpXYL?>u%*)Hg00faPGd6M`Vdd`9&&?~*Pto@c_S}4%Rg)b6ym1Pd delta 38 scmZpcYLVjp%*)Hg00iM@r)}gu!phUFpPN^rpRDg#Tw1*O7ON&Z0M<(j(EtDd 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 26340d559a39bb93ce8dd1620f3a304b420c1776..b62a84fc863e7fdf412599be1a47d8ef8bef78f3 100644 GIT binary patch delta 37 rcmcbvbxn)=GcPX}0}w>I%-G0%jh(wgKR2&LKSkd+*mLt+_AFii+F1+C delta 38 scmcbnbzO`5GcPX}0}zCtowkwt8aq#?er{fgezLw}acS}9H|$xw0QCzE1ONa4 diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/rails/__pycache__/revprec.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/rails/__pycache__/revprec.cpython-313.pyc index 19b310af4e6cda8495aed73a38e00d177ae1cc97..aa2be86e684c2786e50c074b35df14c8e86ac486 100644 GIT binary patch delta 36 qcmcbwbx(`?GcPX}0}w>I%-G2NlAXI#KR2&LKSkd+*mDy{JTCyx!V35R delta 38 scmcbobzh77GcPX}0}zCtowkwtB|A@-er{fgezLw}acS}9|LpO+0QnvbFaQ7m diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/rails/__pycache__/tox.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/rails/__pycache__/tox.cpython-313.pyc index d82a04f723afe6eeaca9d3c9aded8def5539e6ce..15dcb19ffffced5f7b0297c4055f470672870e6a 100644 GIT binary patch delta 37 rcmaFn@YI3(GcPX}0}w>I%-G2NTY$S&KR2&LKSkd+*mJXxUI%-F~s!N}dEpPN^rpQ7&@>^V7~aXA2|!U_lg delta 37 rcmbQrGL41%GcPX}0}zCtowkuXf{~|NKR2&LKUv?gxU_h39^-NVzw8S@ diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/rules/__pycache__/alcada.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/rules/__pycache__/alcada.cpython-313.pyc index e72c6d270291065598c520a4157c26e6520e2b6e..86c6d7e1a5dfc97a944f3d63945d56ce79d1629c 100644 GIT binary patch delta 37 rcmcb`cax9%GcPX}0}w>I%-G1C#LC^FpPN^rpQ7&@?76v;^&ukw$<+%P delta 38 scmcb~cZ-kvGcPX}0}zCtowkuXiIt~QKR2&LKUv?gxU_h41?xjb0OQ{bQ2+n{ diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/rules/__pycache__/pinj_patterns.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/guardrails/calibrated/rules/__pycache__/pinj_patterns.cpython-313.pyc index 65efbd1a120ab8277effbfec8e31f1a8ae2c8f73..72d4bc1b534679d1811d220b0cdeab3dd64ef363 100644 GIT binary patch delta 37 rcmbO%J4u%NGcPX}0}w>I%-G1if{VLfKR2&LKSkd+*mLuKt}Dy{!2%0A delta 38 tcmbOvJ6V?dGcPX}0}zCtowkvC1sBf*{oK3~{bYT|;?m;H`?#(!0|46Y408Yg 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 32b0d827c0580565b245d1189928abefdba482d2..85ecb207a8e7a9a6ebfa42f633054a272febda51 100644 GIT binary patch delta 37 rcmaFN{fL|UGcPX}0}w>I%-F~+$HLvOpPN^rpQ7&@?77*LWgQ~`#bgR^ delta 38 scmaFF{g|8kGcPX}0}zCtowku%j)iA}er{fgezLw}acS{p6P9(10N*?drvLx| 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 fcfb31b..9a32e5b 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 @@ -323,10 +323,28 @@ class CoherenceRail(Guardrail): "data": out, }, ) - out = await classify_with_framework_llm( - _llm(ctx), "COER", {"text": text or "", "context": ctx}, - profile_name="guardrail", component_name="guardrail.coer", generation_name="guardrail.coer", - ) + try: + out = await classify_with_framework_llm( + _llm(ctx), "COER", {"text": text or "", "context": ctx}, + profile_name="guardrail", component_name="guardrail.coer", generation_name="guardrail.coer", + ) + except Exception as exc: + # COER is a conversational-coherence rail, not a security boundary. + # If its semantic classifier/provider is unavailable, the graph must + # continue and let the normal router/workflow clarification logic own + # the turn instead of surfacing an infrastructure exception. + return RailDecision( + code=self.code, + allowed=True, + reason="Classificador de coerência indisponível; continuidade delegada ao runtime", + sanitized_text=text, + metadata={ + "mechanism": "infrastructure_fail_open", + "calibrated": True, + "error_type": type(exc).__name__, + "error": str(exc)[:500], + }, + ) return RailDecision( code=self.code, allowed=bool(out.get("allowed", True)), reason=str(out.get("reason") or out.get("label") or "COER avaliado"), diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/runtime/__pycache__/__init__.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/runtime/__pycache__/__init__.cpython-313.pyc index da962e4492ef173d64d376c604a32f33860fecab..5312258964a239b5ffa243eb9639dbd4d27013db 100644 GIT binary patch delta 34 ocmcc1bcc!iGcPX}0}w>G%$Uf%mb*+pH?KrLMc+5rbK;Si0Im26^#A|> delta 35 pcmcb^beDqsEl;_AZeEFgvc6++Y4OCvGXcdU3@!iw 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 a519316898d1bbae99e8403724ebc4a22602130c..9603442b9cea1a901949c97fc5d7f07aa0c4d8e4 100644 GIT binary patch delta 40778 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 U1e#MlYIS7Ij9~a$0FZY74`4qFBLDyZ delta 30589 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 Vc0D}Rd1mSv<3z$I4nUUf{{djDU=9EP diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/runtime/__pycache__/transaction_parameters.cpython-313.pyc b/agent_framework_oci/libs/agent_framework/src/agent_framework/runtime/__pycache__/transaction_parameters.cpython-313.pyc index 48591afd12b0d3dd9bfeb1128e813e2ccdbc2a2c..b797d4f4500c47dbb651d181a8aca1e61c8e2d14 100644 GIT binary patch delta 7787 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 T%G{DDb3>wNyI<6SVgURPa9DUz delta 4645 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 str: + """Normalize bounded conversation text into newest->oldest message blocks. + + Role-labelled multi-line messages are kept intact. This avoids reversing + individual lines inside an assistant explanation while still honoring the + temporal search order required by parameter reconciliation. + """ + raw = str(context or "").strip() + if not raw: + return "" + blocks: list[str] = [] + current: list[str] = [] + for line in raw.splitlines(): + stripped = line.strip() + if not stripped: + continue + low = stripped.lower() + starts_role = low.startswith(("user:", "assistant:", "system:", "cliente:", "agente:")) + if starts_role and current: + blocks.append(" ".join(current)) + current = [stripped] + else: + current.append(stripped) + if current: + blocks.append(" ".join(current)) + if not blocks: + blocks = [line.strip() for line in raw.splitlines() if line.strip()] + newest = list(reversed(blocks)) + return "\n".join(f"history:{i+1}: {block}" for i, block in enumerate(newest)) + + async def _reconcile_transaction_parameters( + self, + state: dict[str, Any], + *, + tool_name: str, + parameter_names: list[str], + known_arguments: dict[str, Any] | None = None, + ) -> dict[str, Any]: + """Reconcile a coherent required-parameter set from text and tool schema.""" + # Compatibility/extensibility: if a domain/runtime subclass explicitly + # overrides the legacy extractor, honor that override and translate its + # candidates into reconciliation decisions. The base framework path below + # remains the coherent temporal reconciler. + override = getattr(type(self), "_extract_transaction_parameters", None) + if override is not None and override is not AgentRuntimeMixin._extract_transaction_parameters: + route_meta_compat = ((state.get("route_decision") or {}).get("metadata") or {}) if isinstance(state.get("route_decision"), dict) else {} + compat_fields = list(parameter_names) if route_meta_compat.get("transaction_parameter_values") else [ + name for name in parameter_names if (known_arguments or {}).get(name) in _EMPTY_VALUES + ] + extracted = await override( + self, state, tool_name=tool_name, missing_parameters=compat_fields, + known_arguments=dict(known_arguments or {}), + ) + values = dict(extracted or {}) + decisions = {name: ("resolved" if name in values else ("preserve" if (known_arguments or {}).get(name) not in _EMPTY_VALUES else "unresolved")) for name in parameter_names} + provenance = {name: ("current" if name in values else "state") for name in parameter_names if decisions[name] != "unresolved"} + return {"values": values, "decisions": decisions, "provenance": provenance, "clear_fields": []} + + active = self._active_transaction(state) or {} + schema = active.get("parameter_schema") if isinstance(active.get("parameter_schema"), dict) else None + if not schema: + policy = self._resolve_tool_execution_policy(tool_name, known_arguments or {}) + schema = self._transaction_parameter_schema(tool_name, policy) + description = str(active.get("tool_description") or self._transaction_tool_description(tool_name) or "") + route_meta = ((state.get("route_decision") or {}).get("metadata") or {}) if isinstance(state.get("route_decision"), dict) else {} + contextual_reentry = bool(route_meta.get("contextual_reentry")) + text = (route_meta.get("original_input") if contextual_reentry else None) or state.get("sanitized_input") or state.get("user_text") or "" + conversational_context = route_meta.get("relevant_conversation_context") if contextual_reentry else None + if not str(conversational_context or "").strip(): + conversational_context = active.get("parameter_conversational_context") + if contextual_reentry and not str(conversational_context or "").strip(): + effective = str(route_meta.get("contextual_reentry_input") or "") + prefix = "CONTEXTO DA SOLICITAÇÃO IMEDIATAMENTE ANTERIOR:\n" + suffix = "\n\nCONTINUAÇÃO ATUAL DO CLIENTE:\n" + if prefix in effective and suffix in effective: + conversational_context = effective.split(prefix, 1)[1].split(suffix, 1)[0].strip() + ordered_context = self._transaction_context_newest_first(conversational_context) + cached = route_meta.get("transaction_parameter_values") + effective_known = dict(known_arguments or {}) + if isinstance(cached, dict): + for key, value in cached.items(): + if str(key) in set(str(x) for x in parameter_names) and value not in _EMPTY_VALUES: + effective_known[str(key)] = value + return await reconcile_transaction_parameters( + getattr(self, "llm", None), + text=str(text), + tool_name=tool_name, + parameter_names=[str(x) for x in parameter_names], + known_arguments=effective_known, + parameter_schema=schema, + tool_description=description, + conversational_context=ordered_context, + ) + + async def _extract_transaction_parameters_current_only( + self, + state: dict[str, Any], + *, + tool_name: str, + missing_parameters: list[str], + known_arguments: dict[str, Any] | None = None, + ) -> dict[str, Any]: + """Collect pending parameters from the current utterance only. + + This is the normal COLLECTING_PARAMETERS path. Temporal conversation + history is deliberately excluded here; `_reconcile_transaction_parameters` + is the fallback when this direct collection cannot satisfy or validate the + declarative parameter contract. + """ + if not missing_parameters: + return {} + + # Preserve the framework extension contract: domain/test runtimes that + # explicitly override the legacy collector remain the authoritative + # implementation of the *traditional* first pass. The temporal fallback + # is still owned by the base runtime and is invoked only after failure. + override = getattr(type(self), "_extract_transaction_parameters", None) + if override is not None and override is not AgentRuntimeMixin._extract_transaction_parameters: + return await override( + self, + state, + tool_name=tool_name, + missing_parameters=list(missing_parameters), + known_arguments=dict(known_arguments or {}), + ) + + active = self._active_transaction(state) or {} + schema = active.get("parameter_schema") if isinstance(active.get("parameter_schema"), dict) else None + if not schema: + policy = self._resolve_tool_execution_policy(tool_name, known_arguments or {}) + schema = self._transaction_parameter_schema(tool_name, policy) + description = str(active.get("tool_description") or self._transaction_tool_description(tool_name) or "") + route_meta = ((state.get("route_decision") or {}).get("metadata") or {}) if isinstance(state.get("route_decision"), dict) else {} + text = route_meta.get("original_input") if route_meta.get("contextual_reentry") else None + text = text or state.get("sanitized_input") or state.get("user_text") or "" + return await extract_transaction_parameters( + getattr(self, "llm", None), + text=str(text), + tool_name=tool_name, + missing_parameters=[str(x) for x in missing_parameters], + known_arguments=dict(known_arguments or {}), + parameter_schema=schema, + tool_description=description, + conversational_context="", + ) + async def _extract_transaction_parameters( self, state: dict[str, Any], @@ -1535,6 +1682,7 @@ class AgentRuntimeMixin: suffix = "\n\nCONTINUAÇÃO ATUAL DO CLIENTE:\n" if prefix in effective and suffix in effective: conversational_context = effective.split(prefix, 1)[1].split(suffix, 1)[0].strip() + ordered_context = self._transaction_context_newest_first(conversational_context) extracted = await extract_transaction_parameters( getattr(self, "llm", None), text=str(text), @@ -1543,9 +1691,42 @@ class AgentRuntimeMixin: known_arguments={**dict(known_arguments or {}), **reused}, parameter_schema=schema, tool_description=description, - conversational_context=str(conversational_context or ""), + conversational_context=ordered_context, ) - return {**reused, **extracted} + + # Compatibility/resilience fallback: if a provider returns only a partial + # flat extraction, scan bounded prior text source-by-source from newest to + # oldest for still-unresolved fields. This preserves temporal order and + # remains schema-driven; the main COLLECTING_PARAMETERS path uses the + # coherent set reconciler above. + combined = {**reused, **extracted} + unresolved = [name for name in missing_parameters if name not in combined] + if unresolved and str(conversational_context or "").strip(): + source_lines = self._transaction_context_newest_first(conversational_context).splitlines() + for source_line in source_lines: + if not unresolved: + break + source_text = source_line.split(": ", 1)[1] if ": " in source_line else source_line + low_source = source_text.lower() + for role_prefix in ("user: ", "assistant: ", "cliente: ", "agente: ", "system: "): + if low_source.startswith(role_prefix): + source_text = source_text[len(role_prefix):] + break + recovered = await extract_transaction_parameters( + getattr(self, "llm", None), + text=source_text, + tool_name=tool_name, + missing_parameters=list(unresolved), + known_arguments={**dict(known_arguments or {}), **combined}, + parameter_schema=schema, + tool_description=description, + conversational_context="", + ) + for key, value in recovered.items(): + if key in unresolved and value not in _EMPTY_VALUES: + combined[key] = value + unresolved = [name for name in unresolved if name not in combined] + return combined def _transactional_action_match(self, text: str, tools: list[str] | None = None) -> str | None: """Detecta solicitação transacional usando metadados de tools.yaml. @@ -2827,23 +3008,48 @@ class AgentRuntimeMixin: policy = self._resolve_tool_execution_policy(tool_name, previous_args) missing_before = self._missing_required_arguments(policy, previous_args) - # Parâmetros TRANSACIONAIS são interpretados exclusivamente pelo - # extrator LLM genérico. Durante COLLECTING_PARAMETERS, a fala atual - # também pode CORRIGIR um required field já coletado em turno anterior - # (ex.: valor=19,99 e o cliente diz "desculpa, é 14,99" enquanto - # subject ainda está pendente). Por isso o contrato editável do turno - # é o conjunto completo de ``requires``; somente as chaves realmente - # extraídas pela LLM sobrescrevem ``previous_args``. Campos não citados - # permanecem intactos. Isso preserva parameter-before-intent-shift sem - # tornar valores antigos imutáveis por acidente. - editable_required = [str(name) for name in (policy.get("requires") or [])] - extracted = await self._extract_transaction_parameters( + # Primeira tentativa: coleta tradicional usando SOMENTE a fala + # atual. O histórico não deve participar enquanto a mensagem corrente + # conseguir preencher o contrato normalmente. + arguments = dict(previous_args) + extracted_current = await self._extract_transaction_parameters_current_only( state, tool_name=tool_name, - missing_parameters=editable_required, + missing_parameters=missing_before, known_arguments=previous_args, ) - arguments = {**previous_args, **extracted} + arguments.update(dict(extracted_current or {})) + state["transaction_parameter_collection"] = { + "tool_name": tool_name, + "mode": "current_turn", + "resolved_fields": sorted(str(k) for k in (extracted_current or {}).keys()), + } + + # Segunda opção: somente se a coleta tradicional ainda deixar + # required fields em aberto, reconcilie temporalmente usando o + # schema/descrições declarados em tools.yaml e o contexto bounded + # newest->oldest preservado na transação. + missing_after_current = self._missing_required_arguments(policy, arguments) + if missing_after_current: + required_fields = [str(name) for name in (policy.get("requires") or [])] + reconciliation = await self._reconcile_transaction_parameters( + state, + tool_name=tool_name, + parameter_names=required_fields, + known_arguments=arguments, + ) + for field in reconciliation.get("clear_fields") or []: + arguments.pop(str(field), None) + arguments.update(dict(reconciliation.get("values") or {})) + state["transaction_parameter_reconciliation"] = { + "tool_name": tool_name, + "trigger": "traditional_collection_unresolved", + "decisions": dict(reconciliation.get("decisions") or {}), + "provenance": dict(reconciliation.get("provenance") or {}), + "clear_fields": list(reconciliation.get("clear_fields") or []), + } + else: + state.pop("transaction_parameter_reconciliation", None) # Argumentos estruturados já presentes no contexto são aceitos de # forma genérica (não são parsing textual). Para required fields, @@ -2890,7 +3096,65 @@ class AgentRuntimeMixin: state, tool_name=tool_name, arguments=arguments, policy=policy, emit_events=emit_events ) if pre_validation_result is not None: - return [pre_validation_result] + # A pre-validation é a fronteira autoritativa da coleta + # tradicional. Se ela rejeitar um candidato de forma recuperável + # (NEEDS_PARAMETER), ainda não repromptamos o usuário: fazemos UMA + # tentativa de reconciliação temporal com o histórico bounded e + # com a semântica declarada em tools.yaml. Isso cobre referências + # como "é a de R$ 19,99" sem tornar o reconciliador o caminho + # primário de COLLECTING_PARAMETERS. + pre_meta = state.get("transaction_pre_validation") + pre_meta = pre_meta if isinstance(pre_meta, dict) else {} + retry_parameter = str(pre_meta.get("parameter") or "").strip() + recoverable = ( + str(pre_meta.get("status") or "").upper() == "NEEDS_PARAMETER" + and bool(retry_parameter) + and state.get("transaction_status") == "COLLECTING_PARAMETERS" + ) + if recoverable: + recovered_selected = dict(self._active_transaction(state) or state.get("selected_tool_call") or {}) + recovered_arguments = dict(recovered_selected.get("arguments") or {}) + required_fields = [str(name) for name in (policy.get("requires") or [])] + reconciliation = await self._reconcile_transaction_parameters( + state, + tool_name=tool_name, + parameter_names=required_fields, + known_arguments=recovered_arguments, + ) + for field in reconciliation.get("clear_fields") or []: + recovered_arguments.pop(str(field), None) + recovered_arguments.update(dict(reconciliation.get("values") or {})) + state["transaction_parameter_reconciliation"] = { + "tool_name": tool_name, + "trigger": "prevalidation_needs_parameter", + "rejected_parameter": retry_parameter, + "decisions": dict(reconciliation.get("decisions") or {}), + "provenance": dict(reconciliation.get("provenance") or {}), + "clear_fields": list(reconciliation.get("clear_fields") or []), + } + retry_policy = self._resolve_tool_execution_policy(tool_name, recovered_arguments) + retry_missing = self._missing_required_arguments(retry_policy, recovered_arguments) + if retry_parameter not in retry_missing: + state["selected_tool_call"] = {"tool_name": tool_name, "arguments": recovered_arguments} + self._set_active_transaction( + state, tool_name=tool_name, arguments=recovered_arguments, status="COLLECTING_PARAMETERS" + ) + state["missing_parameters"] = retry_missing + pre_validation_retry = await self._run_transaction_pre_validation( + state, + tool_name=tool_name, + arguments=recovered_arguments, + policy=retry_policy, + emit_events=emit_events, + ) + if pre_validation_retry is None: + arguments = recovered_arguments + policy = retry_policy + pre_validation_result = None + else: + return [pre_validation_retry] + if pre_validation_result is not None: + return [pre_validation_result] tool_name, policy, force_confirmation = self._apply_prevalidated_transaction_decision( state, tool_name=tool_name, arguments=arguments, policy=policy diff --git a/agent_framework_oci/libs/agent_framework/src/agent_framework/runtime/transaction_parameters.py b/agent_framework_oci/libs/agent_framework/src/agent_framework/runtime/transaction_parameters.py index 1a394f7..88cfbeb 100644 --- a/agent_framework_oci/libs/agent_framework/src/agent_framework/runtime/transaction_parameters.py +++ b/agent_framework_oci/libs/agent_framework/src/agent_framework/runtime/transaction_parameters.py @@ -69,69 +69,77 @@ def parse_transaction_confirmation(text: str) -> str | None: return None -async def extract_transaction_parameters( +async def reconcile_transaction_parameters( llm: Any, *, text: str, tool_name: str, - missing_parameters: list[str], + parameter_names: list[str], known_arguments: Mapping[str, Any] | None = None, parameter_schema: Mapping[str, Any] | None = None, tool_description: str | None = None, conversational_context: str | None = None, ) -> dict[str, Any]: - """Extract values for pending transactional parameters using the LLM only. + """Rebuild a coherent parameter set from text, newest to oldest. - This component intentionally contains no domain/entity regexes and no - knowledge of parameter names such as ``order_id`` or ``reason``. The - transaction runtime supplies the pending parameter names and optional schema; - the LLM only interprets the current user turn. State/control-flow decisions - remain deterministic outside this function. + The framework is intentionally field/domain neutral. Meaning comes from the + declarative tool schema (normally tools.yaml) plus the conversation text. + The LLM may resolve a field, preserve a previously known value, explicitly + clear a stale value whose context was superseded, or leave a field unresolved. + Returned provenance is interpretive metadata only; authoritative business + validation still belongs to the configured pre-validation/tool layer. """ - pending = [str(name) for name in (missing_parameters or []) if str(name).strip()] + names = [str(name) for name in (parameter_names or []) if str(name).strip()] message = str(text or "").strip() - if not pending or not message or llm is None: - return {} + if not names or not message or llm is None: + return {"values": {}, "decisions": {}, "provenance": {}, "clear_fields": []} schema = dict(parameter_schema or {}) known = { str(key): value for key, value in dict(known_arguments or {}).items() - if value not in _EMPTY_VALUES and str(key) not in pending + if value not in _EMPTY_VALUES } field_spec = { name: { "type": schema.get(name, "string") if not isinstance(schema.get(name), dict) else schema.get(name, {}).get("type", "string"), "description": None if not isinstance(schema.get(name), dict) else schema.get(name, {}).get("description"), } - for name in pending + for name in names + } + output_shape = { + "fields": { + name: {"decision": "resolved|preserve|clear|unresolved", "value": None, "source": "current|history:N|state"} + for name in names + } } - output_shape = {name: None for name in pending} prompt = ( - "Você extrai parâmetros PENDENTES de uma transação ativa. " - "Sua única tarefa é interpretar a mensagem atual e devolver valores para os parâmetros pendentes. " - "Não decida roteamento, intenção, confirmação ou execução da transação.\n\n" - "REGRAS OBRIGATÓRIAS:\n" - "1. Extraia SOMENTE parâmetros listados em pending_parameters.\n" - "2. Não invente valores e não transforme uma nova solicitação/intenção do usuário em valor de parâmetro.\n" - "3. Se nenhum parâmetro pendente foi realmente informado, devolva null para todos.\n" - "4. Se houver apenas um parâmetro pendente, uma resposta contendo apenas um valor pode ser associada a ele quando isso for semanticamente inequívoco.\n" - "5. Se houver vários parâmetros pendentes, extraia todos os que estiverem presentes no mesmo turno.\n" - "6. O nome do parâmetro não precisa aparecer literalmente na fala. Associe semanticamente o valor usando o nome da transação e os metadados disponíveis para cada campo.\n" - "7. Para cada parâmetro, considere o nome técnico, o tipo quando disponível e principalmente a descrição semântica quando disponível. A ausência de tipo ou descrição NÃO impede a extração.\n" - "8. Se a mensagem deixar clara a correspondência entre um trecho e um parâmetro, preencha-o mesmo que o usuário não cite o nome técnico do campo.\n" - "9. Não use conhecimento externo para completar valores ausentes e não transforme aproximações ou suposições em fatos.\n" - "10. conversational_context, quando presente, serve SOMENTE para resolver referências da mensagem atual (por exemplo: 'a de 14,99' apontando para um item citado imediatamente antes). Não trate texto do contexto como uma nova afirmação do cliente nem como evidência de negócio.\n" - "11. Quando a mensagem atual identifica um valor OU nome e o contexto imediatamente anterior contém uma única entidade compatível, você pode preencher essa entidade e os atributos pendentes inequivocamente associados a ela como CANDIDATOS. Exemplo genérico: se a fala identifica uma entidade e o contexto associa unicamente essa entidade a um valor requerido, o valor pode ser retornado como candidato. A validação autoritativa ocorrerá depois; não invente se houver ambiguidade.\n" - "12. Em caso de dúvida razoável sobre a correspondência ou o valor, prefira null.\n" - "13. Responda SOMENTE JSON válido, sem markdown, sem explicação e sem chaves extras.\n\n" + "Você é o conciliador temporal de parâmetros de uma transação ativa. " + "Reconstrua UM CONJUNTO COERENTE de parâmetros; não extraia cada campo de forma isolada. " + "Não decida roteamento, confirmação nem execução.\n\n" + "CONTRATO OBRIGATÓRIO:\n" + "1. O significado de cada campo vem EXCLUSIVAMENTE de parameter_schema e transaction_description, considerando principalmente a descrição semântica quando disponível. O framework não conhece conceitos de domínio por nome de campo.\n" + "2. A ausência de tipo ou descrição NÃO impede a extração quando o restante do contrato e o texto forem semanticamente suficientes.\n" + "3. A busca textual é temporal, em ordem decrescente: user_message é a fonte mais nova; depois conversational_context já vem do texto mais novo para o mais antigo.\n" + "3. Textos do usuário e textos explicativos do assistente podem ser usados para interpretar referências e relações entre campos. Não trate texto do contexto como uma nova afirmação do cliente; eles são contexto, não evidência autoritativa de negócio.\n" + "4. Para cada campo escolha: resolved = um texto determina novo valor; preserve = nenhum texto mais novo invalida o valor conhecido; clear = existe mudança textual mais nova que torna o valor conhecido incompatível/sem vínculo seguro com o novo contexto e ainda não há substituto; unresolved = não há valor conhecido nem candidato textual seguro.\n" + "5. Se uma fonte mais nova muda uma entidade, objeto, escopo ou outro contexto que dava sentido a campos extraídos anteriormente, REAVALIE os demais campos como conjunto. Não combine automaticamente um atributo antigo com um contexto novo só porque ambos existem.\n" + "6. Um valor de texto anterior pode continuar válido após uma mudança somente quando os textos, considerados em conjunto, sustentarem de forma inequívoca que ele ainda pertence ao contexto mais recente. Caso contrário use clear para o campo dependente.\n" + "7. Se a nova menção é inválida no mundo real, NÃO volte silenciosamente ao valor antigo. Ainda assim devolva o candidato textual mais recente como resolved; a pre-validation autoritativa é responsável por rejeitá-lo.\n" + "8. known_arguments é fallback de estado. Use preserve somente quando nenhum texto mais novo o contradiz ou rompe sua associação contextual.\n" + "9. Uma expressão só pode preencher um campo se satisfizer semanticamente type/description desse campo. Não transfira um trecho para outro campo apenas por proximidade lexical.\n" + "10. Se um texto recente corrige explicitamente informação anterior, a correção prevalece para os campos que o schema permite inferir; os demais devem ser reavaliados quanto à coerência com a correção.\n" + "11. Em ambiguidade razoável, prefira clear/unresolved a inventar uma associação. Em caso de dúvida razoável sobre a correspondência ou o valor, prefira null.\n" + "12. Responda SOMENTE JSON válido no formato pedido, sem markdown e sem chaves extras.\n\n" f"transaction_tool: {tool_name}\n" f"transaction_description: {tool_description or ''}\n" - f"pending_parameters: {json.dumps(pending, ensure_ascii=False)}\n" + f"parameter_names: {json.dumps(names, ensure_ascii=False)}\n" + f"pending_parameters: {json.dumps(names, ensure_ascii=False)}\n" f"parameter_schema: {json.dumps(field_spec, ensure_ascii=False, default=str)}\n" f"known_arguments: {json.dumps(known, ensure_ascii=False, default=str)}\n" - f"conversational_context: {str(conversational_context or '').strip()}\n" + "conversation_sources_newest_to_oldest:\n" f"user_message: {message}\n" + f"conversational_context: {str(conversational_context or '').strip()}\n" f"Formato obrigatório: {json.dumps(output_shape, ensure_ascii=False)}" ) @@ -144,44 +152,98 @@ async def extract_transaction_parameters( temperature=0.0, ) except TypeError: - # Compatibilidade com doubles/testes e providers mínimos que aceitam - # apenas messages. response = await llm.ainvoke([{"role": "user", "content": prompt}]) except Exception as exc: - logger.warning( - "transaction.parameter.llm_extract_failed tool=%s pending=%s error=%s", - tool_name, - pending, - exc, - ) - return {} + logger.warning("transaction.parameter.reconcile_failed tool=%s fields=%s error=%s", tool_name, names, exc) + return {"values": {}, "decisions": {}, "provenance": {}, "clear_fields": []} raw = _response_text(response).strip() try: payload = parse_json_object(raw) except (TypeError, ValueError): - logger.warning( - "transaction.parameter.llm_invalid_structured_output tool=%s pending=%s raw=%r", - tool_name, - pending, - raw[:240], - ) - return {} + logger.warning("transaction.parameter.reconcile_invalid_output tool=%s raw=%r", tool_name, raw[:240]) + return {"values": {}, "decisions": {}, "provenance": {}, "clear_fields": []} if not isinstance(payload, dict): - return {} + return {"values": {}, "decisions": {}, "provenance": {}, "clear_fields": []} - extracted: dict[str, Any] = {} - for name in pending: - value = payload.get(name) + # Backward compatibility with existing providers/test doubles that return a + # flat {field: value} object. Non-null flat values mean ``resolved``. + fields = payload.get("fields") if isinstance(payload.get("fields"), dict) else None + if fields is None: + fields = {} + for name in names: + flat_value = payload.get(name) + if flat_value in _EMPTY_VALUES: + decision = "preserve" if name in known else "unresolved" + source = "state" if decision == "preserve" else "" + else: + decision = "resolved" + source = "current" + fields[name] = {"decision": decision, "value": flat_value, "source": source} + + values: dict[str, Any] = {} + decisions: dict[str, str] = {} + provenance: dict[str, str] = {} + clear_fields: list[str] = [] + for name in names: + item = fields.get(name) if isinstance(fields, dict) else None + if not isinstance(item, dict): + item = {"decision": "unresolved", "value": None, "source": ""} + decision = str(item.get("decision") or "unresolved").strip().lower() + if decision not in {"resolved", "preserve", "clear", "unresolved"}: + decision = "unresolved" + decisions[name] = decision + source = str(item.get("source") or "").strip() + if source: + provenance[name] = source + if decision == "clear": + clear_fields.append(name) + continue + if decision == "preserve": + if name in known: + values[name] = known[name] + continue + if decision != "resolved": + continue declared = field_spec.get(name, {}).get("type", "string") - coerced = _coerce(value, declared) + coerced = _coerce(item.get("value"), declared) if coerced not in _EMPTY_VALUES: - extracted[name] = coerced + values[name] = coerced + else: + decisions[name] = "unresolved" logger.info( - "transaction.parameter.llm_extracted tool=%s pending=%s consumed=%s", - tool_name, - pending, - sorted(extracted), + "transaction.parameter.reconciled tool=%s decisions=%s resolved=%s clear=%s provenance=%s", + tool_name, decisions, sorted(values), clear_fields, provenance, ) - return extracted + return {"values": values, "decisions": decisions, "provenance": provenance, "clear_fields": clear_fields} + + +async def extract_transaction_parameters( + llm: Any, + *, + text: str, + tool_name: str, + missing_parameters: list[str], + known_arguments: Mapping[str, Any] | None = None, + parameter_schema: Mapping[str, Any] | None = None, + tool_description: str | None = None, + conversational_context: str | None = None, +) -> dict[str, Any]: + """Compatibility facade returning only resolved candidates. + + New runtime code should use :func:`reconcile_transaction_parameters` when it + needs preserve/clear/provenance decisions. Keeping this facade avoids + breaking routers and existing extensions that only need candidate extraction. + """ + result = await reconcile_transaction_parameters( + llm, + text=text, + tool_name=tool_name, + parameter_names=missing_parameters, + known_arguments=known_arguments, + parameter_schema=parameter_schema, + tool_description=tool_description, + conversational_context=conversational_context, + ) + return dict(result.get("values") or {}) diff --git a/app/__pycache__/__init__.cpython-313.pyc b/app/__pycache__/__init__.cpython-313.pyc index 40046a35c7be04b618f4f1307d1c71ec7ab118fd..ea9389d42f8f08d2184f0c19b23339b7e1f0bc59 100644 GIT binary patch delta 34 ocmbQvIE|6}GcPX}0}zxj%$Ue+%x$Wln^&TrqVF5*Inm1(0E{{az5oCK delta 35 pcmbQnIGvIEGcPX}0}uq9oi>r%n8!>%H?KrLS>Lg^w0NSYF94*63K#$Y diff --git a/app/__pycache__/main.cpython-313.pyc b/app/__pycache__/main.cpython-313.pyc index 75df421d60112dfdc750301e43643de8b2c78600..e291349c9548eb2918361ffbfba0a2d3f7940159 100644 GIT binary patch delta 39 tcmeyqlqbwrB$GcPX}0}zxj%-G2Njg#9*KR2&LKSkd+*mE;4mjyEb#*_*Y delta 38 scmX>ibySM`GcPX}0}uq9owkwt8z+yker{fgezLw}acS{p9xe-J0OPX@YybcN diff --git a/app/agents/__pycache__/contas_prompting.cpython-313.pyc b/app/agents/__pycache__/contas_prompting.cpython-313.pyc index 52278b7a99b1c7d4d11c3938d4fb49f5ef4c6668..16fc0c5a454a6a299849b9fa36f3c9a1290080ab 100644 GIT binary patch delta 37 rcmZ3=v4n&BGcPX}0}zxj%-G01nTgv)KR2&LKSkd+*mLtLrfNn2w9yJI delta 38 scmZ3&v6O@RGcPX}0}uq9owkvCG82!her{fgezLw}acS}9l}y!)0MRrHh5!Hn diff --git a/app/agents/__pycache__/contestacao_agent.cpython-313.pyc b/app/agents/__pycache__/contestacao_agent.cpython-313.pyc index 66aa0dd6ff56bc0a22e484afd196b6889b4b8e3a..2bf53faa513f5994d23d1b8bd0d0161c024b80c2 100644 GIT binary patch delta 37 rcmdm{xmA<^a$uF&6-%$q76F delta 37 rcmdnQyqTH%GcPX}0}uq9owku%pOME#KR2&LKUv?gxU_h(D`PGIzIF7%Q6rR~Xd%gDBNxZS0*ktopC$zDnLXwgah5T3{B8`J5ON#|vp^yWrB_wWKkdOiuCnRP!-TVj==J4&C z`QE(my*F>Kq<-y|{|E$ph%O6VeJdGRlfPu7=hMZKl`f>uk#YEuxyO9wftm0V@CAFf zWyWLs+DpSZao0MC#0TGqu`a0x@17EW{{@8fG(seB#0}ZLAq6#tgi@@AauTHZxRAkZ zNJH=g7lu`?k*}eI3_4%e6FMljYs-k#YOIW&;*OQ5J1oIuF#OC%X?O`H_|U$@*ijPP zaT0FDhecpj?@tD@1ro9!8D@3WM8W9pDG18D?Nn?t0 zyXM{PS}tO@5dLCAzC{M1g(c0K6XCKaKD{S$5uurwo6vzrrH=0D{+A@&;s&rAp>P@@ z)foc#+Y=8TAR6|Fgf|WwVohLg8tkfIfS!KpsliT0uns$5t<>wo;8~`Z zgRS7Z&42olKlt9_2g{e2uSU0nEk6Z2ZoIxNbw21C-IhjwX&~@UsE=uGzw=V4i>;Yu zdC|8cqv+rc#|Pw{0(?~0vYM^M*YM;3cRfn2J2;EDyCvp)r{Je4^yaiz*?{lehVx3V_=j^cpO%ge&J<@hp&`^ nU}C=h(HykZU&piXZG9Ba!NdBd+9?M2K8QW}2-$|&Nd5l-mEbIE delta 1419 zcmah{&u<$=6yDjH-L==*b)06sUScOs94ECCJ8AQi6hvLus#3aksj5cEKgeG*9Rfxm!CRdVPFS|L?xN~9toQTb4g+z?IG9uNm+>^h?0v?I-@_vX!e z-+SN8@6(sE`XfzK1-4dpzJB+M{_FY;v1fVe{kk``K9y^H*npqKAH~0AxM2*!7TzLM zC@YthD9lPBOJ$Ca=RUj2D#T@DC_u3;%n*vo+Ou))IX!TXSOJZSj-JJ=PVlmlKp|fF z$%`r<3Q+RA%5$jA_wU++#kxeLQGqcX_TDj+hcl95Z262S8G%ESufRfZ{vKu-F4-Is<-|QYy?je-0)nu8T?LO;Q5Qt=uNQvZ+ef2zhU^L_aeR@ zAKlyxWpHR2OMZ1%7b36i5=ql{Pr}3gkx%Vc&=q8lldBPCZ6Z5OwkDW$YY5pHaw~p( zggLiGWKWaZI6uamJ1Jz(kUMF9f13s7$u`aj%(;t^y-4noV^QYp#F4#3c7_#hrxC|Y z3#VH+)53XVYb>zXa+Vmvx5j6EB{oQdf8TiAjqst4!l7^meFc^91#}#K4KK-WwvSEo nZMlY|@Z%zUZeB%Ih(#jkEX+rS`tl;0zh|W%3*2xA*!_P1py2Zg diff --git a/app/agents/__pycache__/vas_agent.cpython-313.pyc b/app/agents/__pycache__/vas_agent.cpython-313.pyc index 0447c9eb0eb261b4866e0ca5adb08f88c47a3446..b2cf3cfc8b502497cb911cb7c118bcebf8c5e3ff 100644 GIT binary patch delta 37 rcmcbpb3upuGcPX}0}zxj%-G1ijEUP;KR2&LKSkd+*mLtz(PGcPX}0}uq9oi>rXn#Wc@H?KrLS>Lg^w0PpgZ~(v>3ta#J diff --git a/app/domain/contas/__pycache__/__init__.cpython-313.pyc b/app/domain/contas/__pycache__/__init__.cpython-313.pyc index ddb1b8e0edee8eb54365b63e88f6591082e7a625..9ebe6d4b77a7c09489495336a7f57e51af6fbc76 100644 GIT binary patch delta 34 ocmX@fbb^WdGcPX}0}zxj%$Uf1lG|B7H?KrLMc+5rbK-+c0Hn$adH?_b delta 35 pcmX@XbdrhtGcPX}0}uq9oi>sCB#(=JZeEFgvc6++Y4ODSnE<{a3)BDr diff --git a/app/domain/contas/__pycache__/client.cpython-313.pyc b/app/domain/contas/__pycache__/client.cpython-313.pyc index 6c06776a86323b93b0b9de4721f8c1236cb89568..3549f927c41f26a1331701a5de233f7ca3c986f0 100644 GIT binary patch delta 39 ucmZ2Cm3i${X710tyj%=GP{J@{Bll4zZb$vxyb}Esecxcu&3BkC9R~pDNDSNn delta 40 vcmZ2Gm3iG%X710tyj%=G5O8+dM((3bJWl$#c_sSE`i{k=#hY(4T{;c`1{w}F diff --git a/app/domain/contas/__pycache__/contestation_rules.cpython-313.pyc b/app/domain/contas/__pycache__/contestation_rules.cpython-313.pyc index 74643a29d56dff9c0bbde0c1d4bd396adc9ddc5e..3234a4e35610ef52bd16e443c895dee82f02e32b 100644 GIT binary patch delta 37 rcmeCo>d4~$%*)Hg00borGd6OwvT*zA=jN5@r|A0zdv2Ctd20XwyvPbl delta 38 scmeCk>dfN)%*)Hg00aSNr)}hBW#RGD&&?~*Pu6!VE-l_H&GOa&0NFGPqyPW_ diff --git a/app/domain/contas/__pycache__/contestation_validation.cpython-313.pyc b/app/domain/contas/__pycache__/contestation_validation.cpython-313.pyc index 61cefc447b92caeb3f5e50b43349de1cbab1b92a..8e6f974dc99816f7307d71570a4eb9ed4a5ce551 100644 GIT binary patch delta 39 tcmdmWjB)2NM()qNyj%=GP{J@{BexSXcaVN=UWtB+zHhMS=1As;@c`~k3{7v590w0Bn@By diff --git a/app/domain/contas/__pycache__/conversation_policy.cpython-313.pyc b/app/domain/contas/__pycache__/conversation_policy.cpython-313.pyc index 07cf4d7a75e5b1ca4ca5ab93b8e0c9b67aa640b6..3f0630560617afc8f725a81bdf7eaafbb7d746e9 100644 GIT binary patch delta 39 tcmZo_Wo&F^5$X delta 40 ucmX@r#(27ok^3_*FBbz41e~3=k^4LokF$PmUWtCPzGHD|@#d#YsSW@Md<|~^ diff --git a/app/domain/contas/__pycache__/informational_context.cpython-313.pyc b/app/domain/contas/__pycache__/informational_context.cpython-313.pyc index 0ab42f797b9950f9725c2c0a14f1f5a53052ec38..1e721723813c34d45189a2696bc2f9578e7f31fc 100644 GIT binary patch delta 37 rcmZ1>y*nMB%*)Hg00borGd6NpF>`zB=jN5@r|A0zdv2b{T+Ivst(6Jg delta 38 scmeC?>*3@6%*)Hg00aSNr)}h}V&?JE&&?~*Pu6!VE-l_Xfw`I)0Li}#Hvj+t diff --git a/app/domain/contas/__pycache__/invoice_resolver.cpython-313.pyc b/app/domain/contas/__pycache__/invoice_resolver.cpython-313.pyc index 238637387cffa76657c0d07d81e6b889b7b6272e..3b17448a4944d72bf329cfe9e0bf17a5bac1b69a 100644 GIT binary patch delta 39 ucmeykmHER~X710tyj%=GP{J@{BlitKZg2hEyb}Esecxcu&F=-7P67Z23JoFv delta 40 vcmeycmHFdVX710tyj%=G5O8+dM(!JeJU;rlc_sSE`i{k=#hc#=GMxkfCBF`Q diff --git a/app/domain/contas/__pycache__/item_matcher.cpython-313.pyc b/app/domain/contas/__pycache__/item_matcher.cpython-313.pyc index fe04912ceb6ff420f89679c4d8a044b9639ddd19..9c842b8f13563cc6bfc627ee009dd31caef75f35 100644 GIT binary patch delta 37 rcmdn%yT_ONGcPX}0}zxj%-G1?!@}*ZpPN^rpQ7&@?74X{iTf delta 38 scmdmCv(twAGcPX}0}uq9owkvC2@8*}er{fgezLw}acS}9T`YBy0O$q`UjP6A diff --git a/app/domain/contas/__pycache__/rct_policy.cpython-313.pyc b/app/domain/contas/__pycache__/rct_policy.cpython-313.pyc index 7c019eb79c4f3d7a545ef9ac16a23f5fbff857b0..d34ef17886fbeacdf3a96af533659b908613020c 100644 GIT binary patch delta 37 rcmdmGxYLmPGcPX}0}zxj%-G1C&&lnopPN^rpQ7&@?76v((}W)Y!qy5l delta 38 scmdmKxXY0HGcPX}0}uq9owkuXpOeQ;KR2&LKUv?gxU_h4E2jxR0N+?Q-Fgc) delta 38 scmX?Hf25xKGcPX}0}uq9owkv?fs-dhKR2&LKUv?gxU_ilG)`SJ0Q(FKkN^Mx diff --git a/app/domain/contas/__pycache__/vas_variation.cpython-313.pyc b/app/domain/contas/__pycache__/vas_variation.cpython-313.pyc index 1e1cf5575ea4961853e7bbf776acc0dd82ee6901..589b865356cbc8117d93fcb6bae40fccd5a39ba4 100644 GIT binary patch delta 39 tcmbPul4-(8ChpI?yj%=GP{J@{Be$+3w}*aiUWtB+zHhMSW*14{ZUEuC3rqk2 delta 40 ucmbPml4;^eChpI?yj%=G5O8+dMs8h69#8$;yb}FneaGU`;?2&IzTE)-Fbt*u diff --git a/app/domain/contas/__pycache__/workflow_actions.cpython-313.pyc b/app/domain/contas/__pycache__/workflow_actions.cpython-313.pyc index 8741f775586add57860f15e765779ebd989a8db3..f2c3ff7b7c814bb2c87ff11aec38419e03cd2dbd 100644 GIT binary patch delta 47 zcmX>ymGkgaPVUdVyj%=GP{J@{BX=J=x3_+7UWtB+zHhK+^HTQqrR+mGj6{PVUdVyj%=G5O8+dM(#d#9v}VOyb}FneaGU`;^rmn?Mv7hw=ZF5l6M9G De8mq$ 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 index 3764097f50cbdc3e42484ed5bd7128a7bcfd4680..17a8d7006096ded52d7ec9a074b336613b4842df 100644 GIT binary patch delta 37 rcmZ22yh@n+GcPX}0}zxj%-G0%iJ3c6KR2&LKSkd+*mLts=0mIi!6OSU delta 38 scmZ1_yjqz1GcPX}0}uq9owkwt5;ISfer{fgezLw}acS}97tDuP0p0x!hyVZp diff --git a/app/domain/contas/parsers/__pycache__/__init__.cpython-313.pyc b/app/domain/contas/parsers/__pycache__/__init__.cpython-313.pyc index b208cb5fd5aeef708af9eacb43b82665bc3dac6e..f61e15c77bcb3fec7cd0997ca2b63897753d84b8 100644 GIT binary patch delta 37 rcmZ3%zMP%=GcPX}0}zxj%-G2NkCEG3KR2&LKSkd+*mJWe(_}^fyN(JZ delta 38 scmZ3^zJi_mGcPX}0}uq9owkwtA0v;Cer{fgezLw}acS{p5vIwE0N7>=egFUf diff --git a/app/domain/contas/parsers/__pycache__/bill_parser.cpython-313.pyc b/app/domain/contas/parsers/__pycache__/bill_parser.cpython-313.pyc index 4280f885244a4891c88dd8822f15f2caa787b85f..252f8ee41906671468fc39d86e0d9f841911c2f4 100644 GIT binary patch delta 39 tcmdn9lX3S>M()qNyj%=GP{J@{BlkacZa@9pyb}Esecxcu&7vI3Ljd=x3@88q delta 40 vcmdnJlX1^ZM()qNyj%=G5O8+dM(%&?JpTH*c_sSE`i{k=#hXPqmWKcU7AFmY diff --git a/app/domain/contas/parsers/__pycache__/bill_processor.cpython-313.pyc b/app/domain/contas/parsers/__pycache__/bill_processor.cpython-313.pyc index 6f5fa988b3c948c5a4fccafce07991f9c0800ffe..3434ae1d1edc0daf38eba25d1825a1d12cc5a4a8 100644 GIT binary patch delta 39 tcmbO~n`z!`ChpI?yj%=GP{J@{Bliam?m+$Ayb}Esecxcu&Fq{rS^(ww3%&pV delta 40 vcmbO?n`!=RChpI?yj%=G5O8+dM(z(BJVE-oc_sSE`i{k=#hckUXS4tS1NaRX diff --git a/app/extensions/__pycache__/__init__.cpython-313.pyc b/app/extensions/__pycache__/__init__.cpython-313.pyc index ed789e3363d5ecbde2826a13b903672c9e49aca6..31a04df9653436e9d32697103217e49d84857ec6 100644 GIT binary patch delta 34 ocmZ3_w2q1UGcPX}0}zxj%$Uf%o7+J@H?KrLMc+5rbK<2~0G#9s8vpqsH;iI93v~bh diff --git a/app/extensions/__pycache__/tim_guardrails.cpython-313.pyc b/app/extensions/__pycache__/tim_guardrails.cpython-313.pyc index b0ae05ddb9ddfce3914f44a9ca434f73c2372147..99c6d05533f065668f24688f3bce1dad0029ab7e 100644 GIT binary patch delta 12516 zcmbVy3sfA}m0(r>KR`Fo%^y@kAZS2HLLdo!kPzrE1fpme3q-5vE}*6UpjX{UB4k@0 z=WNJ)5-F9eNbHHR<2{z*c&xE9C!UFu$dVH$Gg+H=-%${bgd)5X+k+r_H z9sK@l|Db8AEY_%9;vW;aAwi08qe5ha8wwLH z8VdTQh;T|642WFM{tgc6Mg)oTg@b}W#D$}g(P*UJV(A(2OPqK%B8DV?IK%~obKI#= z_zV{rS=MYU>=g#10fC&`ibXMQSPY58@8yPw5ERdZ$tj>LN|sPKQqS#+28Ga?2oXZk zkVv?I5E_mO!y*Sg`9siC1bPwzfpgHWHxTuSK28dABSOd*9vb3=Xk;Wz{NpgGaL7VL z94?L!YDzFoXeC8REb5I!i4dsgT7!fB;b=ITp4lh~OCr?q2LjwM42g?`asHmpPM$k- zsH5KUdu_i|tFRoYfJNWqGAR}@E0)w0{7{h2LxDLaz%+a?6HzgY zijou-6vGJ4I;>=f(x~Y53jthyZ;~z|M5WyD%T0+Px1_WQSj}Y+3&1Zbr2WI_{6VHm?XhiTSX5a}g>=I-RVra}ye}n!A zRKlW2*c*nG_;a?Z@>A>;xguZZ@?zhHIer)Cxwx#>#wP}**$YKq?0jP2L-Gu+(Vx@# zr|KJfM6Qs3!e!AhJdYR`j)hW{$kWhNG63K(?W7E= zlz%d>k{?5xDQx`L06sX+EMze`j!Su8&YLn!YoFvVJDx4Nn)6N1Y~_}C<(5R{w%N*E z@ycC^%JxL|Zr}L>cdX7in`2(5%{QFyTre>v>n%&;~=23v1^<~AgP^cKxl~r^;AtGGS69uXMRGzG_VHNpWeYy26BIrK7D&MUyE}-4w zE|Dw%AfgCtMTEQ}=dRtxzI?4~?dMtchCH{j&7^Wm`iP`+Ip)!^un|l+)Ck)1;BR8k%ZNZWgqwmNx@5@%nlVZ>ZPt#%6s5 z(}#zgrXH=EIqsCN0v(Gy*HFg(Mt;AcJoXbPyrLsGQ}W*cDCVH(1?KWgLGs@b`C9X6B)Mt~ z_>8_>1Bi?6n^^ zck7D&9b5ed!T&~pn?wE&g5SywE$t7?VitFae1xDK0dCSB@^j3-jsVw&Dp&Fg%-u$? z8o|FJxP#!A2!4v75y7wJ|I)I>McLW`GawE`ovlK|$t^j!qp|vJ zEP4e&7XZl&0Hq5}s!GIVQ_AEoHs{IT-(k|MVz0ft!>WnRV;cd%K>)DN^vtBO;}%dh z+yr+x47Lv4AKM?^AEcngf$I<;!>a?g<0o<#Xh+B36IcBHEr>+SqVMjYP;={JJ3@+Fz_GXJ!BXlEcUWig8dN-mp(3o3MN{f@TC;u+Zd> zh{3~PViGit6jMrFlU1-jib)De9tq4a@_i_kU)aC;Kn3D6v6a-Fv~x%$#i5Zp6bPU3 zgpgbdlCvdk7SZRSEyxbQlAQ=vvvS6PqP{9RP-#Qeul$!J3WdO{#TszqD6}_H327{A-)xC;sl@0t+c9(pdUx^LR z^Q+i{K)qCsxl83cd=~qH{0{#nRG97Ax*`YXMY-LJv;8^(5y1g0I4G}opJK0E`&;*4 zvM%f(X)EiEQ~`5SWA1Lr|w#2?t-3g7939+wu)-hYD3SDC(anVVU3 zczoczaSYFTcVzzclujV;6>|ywi;dTeVta{0rlMH8EoygNGjNxP=xG?egL*VOy+l7WYWqApl#qQllySjI`0UDT}dR9^-Jj#J=gQnmY3K32K-x3rj zZNdowA_~59;M(L?l@5QvJ>TCjD%c>|Xb2P8$k zBb=ai1YP*JU{s2rv&s2HI7&VaTvsp#NO({H>eS=m2GuEm&xh@#nB*Vwd+E69EiU8u z?*75*ln>Dt7LH3hCe%;SpUl81mXg_UG>rpk6Xxn`;An%J;fijD)kaE5U#NP=7U~W` z^{@-7?Er)-D`McbObCM_iA<<%C%gna5tl3KQ%R(qo8)Lz_XS3i^kZ-|Y8FP5@@-Nh zr=#if-+bn{FNuQ1P<v zeqmN&*N)`;)JYA)ru!z+lW@7l4?}|;TZY2^2?$6Cv7n2C&(xCRB2e#fNt+3EY!f0K z70{yNfnPcj*LVjdct(&W&Vb~d7=ducpeTlx&<%*b&DsV_kN|}QuCLaryiI-`JM9bR{VX%Z0@F++)X#mekh?Bd3eJ{76je{&{Fm6 zQX;$)M`ucoPEx%!YyhT|YE>$=9@s&jA5W*}lLo8o`qcCKB~Ahjgb&U$^L8e$aMtOH zJ6)G663(@gmU)fIVVN|6OJ>i#mDBa&*+foP!qzoo>iW2tMC*@=$sd659MBEu2Mhy7 z!+>ePJYbQ3(2*y<$CepG8n?z<#K=GFaLVPHvaDr-QzKtLT$CpO5w~XTa+#`;Uu~~? z05sZK2D}|@qqYKaK|QYxf=&t=)-$~B6dN?buO5Dl@N0lyGoQuV+&Z`3ZEzdiCb!vb zX*5!!&2&?OZJ(#|3t=!t~tTm-1JFh*&2r!uru%s44f=eYm);F6| z^>O$Hp(sU&HOmhb6zJD6o$NaKT{aJ#uZIc>wbmw9o+vGM@EKcr8A_ke4C;C;<;nhA z%x=)Pu$Yiilp!z$h86~I#UN!Y2#@0*&<+ zf=8S51K87oJf!H*NK*{n0K^j^aD-p*YXoIEBKX27^EBj#Sf3AKTcEr!2f@Mggkp*r z6qi>NA;hWDGh4ixz-bQy>(YGC9d+C~HA4 zoU}uZ>_&iE1Y>9t#&HQsF=c~2`RM`2gRTx)33%^Ps{-X7cpdD$2w+=`UzPj!R_h=D z;FhPIr8;2C7v#JnTV1*yD;nUG4Z)Xl>v)#34T!ux90*OoFs%GhNjXN;ck!AuU%|<6 z>w3(T091Cv$x%5P&I|;!KZ#UHk0sT2vVm?Z%vi`~m>#3Na+|YGx5%J98Rbmxdbh5T zg`qJi1_s9cK~gx&JNM;l`t0&EdyBU^VK592hgFABSStv6J#BwvNxRIHP=}fZ+HY~P zUkATr>ghAGIFw-s-@1&4$wn9m8G#Y^w17-u2&fr`pd&?{oi`gG=hCQltII4~`NEhQ zcpJnjXi}2@h*dJFfvV^*#7~YO`Y?h=5Kz+{yHND>RDldn9wj9+mGhhu&q<0c{fUPt zDk(bYlz)^Qgtih)6(v3Agix}YREHD`mAxR#YiiUJ?h(NNHRiY z5aPd)KjdAp{GutJ{FyfjxH-s;$gyv4xP1EQjn8hovhC@X+1efP+8v47*6V$V+OD~Z z>M1kU3MTSvud-Kro-@y_s+uzW$%dXpZ4a$AZ(s_FXUba>`K@yWrH^HNEn}L$Rp5%f z;V78Oo^G4o__dDL9X0QjGNm;OWlT=V)b1zSzg;=KeKvc2JbV3I$;#Z+c);O)aVX)Ak@1+T}mRbLgThb6oR9D5MZd|>g(%|t6_)^C~_I)w|jsG zsF(E@(7_T)(oXK4^ldNNO7B(Q(*w^( zUt81uhP~jnE$2Hm&-eVW_aA$&k0iEt-a6u*Z8#clIC`PyQt!pysgXp?SvBiibGhMz znf`&i532#nKdoMx%`(y<3;6B4mNIN?%S2RFJ01lFdP8J2MxFhYTpi zof=*vw{CUDKsu|vrG7(3-pXq+CKNI)hH1NT$oD0E-g;A66oIcftF2P7%v&xA6{#-+pwgL1A-g5e3GeBLk?wvacMcl zhO#JO+ToHme~hkiNgYZzc0XNP@0~T!y7wc5YhdUhdtbgfU051>s{abuBo6*V=An=0 ztV0mW7P_EuYXBl{9JuBJ5k^Od0H##R-~+h>CSeRNbkB@{?U)owV7uY19Trj(4MG6v zYigeu@Ph*lCKEKm>t-4oP_L`Q;Q)t$Jqc~b2uH-zQ9qcU&~@4zvwWbPM7kvs^74AV<>v>eY_f-nGZ-J!o|5Qf7AL6*XJVP=Ep=)HN`Ljw8` zn}DcDK*Y;=r~{SZW+OB_6b)D~m=x^dwjfuUtA8=n69_% zp@FTBIj_`+yTi(Fvqcy<13}_k&GMSm(F%dX;%2BFb%Mdutmcowo}!EZIgr{}`Yr#v z(_-236|k~aK@Aj3POEN_8h&SMdEFxQ&PufwV3+jSnWJKBmenm=YBQz{Ck*8AdYiod zh*Q2@YLWj(i33NGSHY}g`qKPtWCXCkI7a?{H5cQJyvEI>PP3$0!Bj9q%y#VxW{7o} z4yzGBs*~9|g{>dg)^8kA*mb|x^tZcAs*!aRm{ie|A%Dn64gi}g1_C{_uc}tffK3NQsvGjlo4ORkG9xpp?EGM-a8?Y-QP$f=)fn}aB$_pinwc*s9;axORT zQuD>;DPC@wZhLC~YqhjhQT=Su#(2@jtJ3priK3ks+wLwa zgzvn(`QtH2+Nc6#skI8%mmb`y2?R8_M6V03Lpk`(aKhlxkD?8TAvNs&ImBxv zF+%#V!9nkBH6P_c3SYJc8~lu7THr0 zJB5aepL7rlu7!N)1wkNN$x83Oip^P+)*c8Kkbp2s{st&gKIXW+-13wRk<~8=k@?|% z>Jub@vino>Qynr7-tmHiHIKotSzAlo*77`9uI+JKJJ`~5mDRJA2ji6of3i1G*%LRF zPwJsKkKNDJE|``5{`PXz6*+H3+mzpaGt@Qj`dy@pY|jQwohg* z=rYaq;3{ou{_e@=PR_Ir&iI12Hii-<;ny~Xu4Yg5UtakQPkdu&##A^{629HE>AT0C zJ2taZnDLI@YC4@LCa*P}zRFG=x}5!u&Un-5crlqV6}(ZkIZ@pATGi(1l`pitq&YD+pM)M zZfyhPf`KV6dvx%zlV3kM8-Br*{+^=S5KnUohUpynKf6oCSKO~d|ABtaJ;mqbH-G3+m<`ySPeHeGp4E! z-&@6$jUA$^4FH!}{aH})VT`JLT`RBe zeKl6XO3mB z$?0VIQgz~P6AZOX2LT#>Mc;}v^|YzNbMjlqirJO2v9A_hlWgeQ6q|)wiw_hOoB9S0 zBI#v zb+fkJaog_uUeat{@{(rTTvh$MW_?l4yH=|sYo4)YX3du~8TMIgOWca0(Ap8VcHBo` z=Mn;k?bm=5dtL*%`LptuPSgxS0L74VPovY9 zU{Ma3oca>PW#7|e>yNO>`k0+xO|cvGHAy7o=0{nIT(7TAA|dzw5PO2vThsvE3i^6R zzH`D`dIMNavEf_bJ>9MR?#@GV?FgO`H z*L{c`MXdh*GeIM|EY23i8ghNoXnaTh`5>qHkw$)h@F6dKMwI!f_XQ((>b|6wnjv}| zjR8A?|I}-*?;#Sw4UPN@@A`e11#czIc4>A+f&v1{U?te>AF-}#(k)>|WL8&+-090_ zugk-}*Y^AvTfK?^?g!MTWyFN->0Z+T;2ULi-BBwjrftEnFB%YA$iF~6_+zBc%j076 z(RNsB!@?d`&yKPSc023UUU+bU!QX||tJ$WhtOW*s7P?p;%UY%mF8~*@mW4ywem#5+ WEHL=HFk#7L^QOvv$G{Km^#1`DhA+zi delta 2998 zcma)8dr(|w6~Euz2ke{WwaYG$l~9RV^U&DVNvmz`)kd^`sI8+Yo5`qc^_*`Dc{q-} zFu(77zwdd^Irn$=_fN`?yv*#gHk(<(r~Q@j!Q9Urw7Z%0U}b!Jkz)2pgL>{%Jc>nF zxoBC1m8W>@Z0?*+W>NiuT@>`@sn_8eHpt1ZS@O` z&my6QL9K5CeM8B1xzWnb8CauPf6iz?n}2~8{FD}3`OnCHiQr{|R|v?1ct$cj5Y?>M zBx8}`XmV?!kDF*%c!kd9Kc|VdP$)7KR@F#!Xebmq!T4LqstjSJh^K{Lp}7Rlz_%NG zIeCV_H3@+iWO(7k*@oThGCXw8PvqC7RO5;?>qh`k*f*FbIRh4dj#dcmJ%tNn)tE4vrE|@OP)F0|_Kv1i{FAt|rW@cxD@4{! zru6H-X2`jN&RaxKO)v>lo4jTJB=c?pT9k<(U5+m!ps2#kru+rG9xW{!zxQM!k{IIu zqONJKn}8)96;O$XzC=-Bn+bt(X*sf96H9VyV-YOI_xDm?xN-5 zQLJ@3MN({fDQ*Z#9ZqO}Bp=2@PNzL+2*{Z^abr;5kq75C=M^}V9L0(I<_3+_R?E01 zpGFLMN}iGrj-~?UfK5$#Sy@U!5K9`oTI{me1NcVtbQHn;B_4Qkw~H0R3%l#HTn1zn zH+;CeW{rI#Q;LFgb6qeS@8r=-ib3&qdBswMpl)s-rFfB1$*MC5=>}EyNva$-^-Ds; zOJLicJ5j`^_S7`psz90}8Rf&Vcz7rjjwEAP!p`Eh|D{GQBx6rwetx7&aPrYs_8hRi z?A`9UvFkCM%Bv`7q;Qɡf`NsPvmemgIx0V7QjYGsG__qzLT6R9U?cqc8^ z4MpRq`k9hJtk4@9?LpzvY|#f|ebIO%8luw7FVYlozW5sD$W|=3v4L1p#R?nW=P^~cgO2oH^hlhFy>O#KFfXZN+HwmlYPb*s!xmF&EgHTm@CZ2`0|$fl+;{RM}S zu%OY3)WtFbqR^qXc@+ffS1N8OGb6*IxH}BWck=)MB!q3Q&I447t8B3KtK|vMxp)jDo3rsJ*$(9&KVi4nIt^+ zc$MwC^&W#cQ}eE8emLAU7Acv=MVfyHRMBrX$DmXmUNNnmv7X#`AE~^FoB3@8Z8_Wd8eNrqN3>c zYUWU=e>6GDqoEKdvEuaU@(DO~;5E;2GN%Zx5KI$@@YKLl2TRN?cs%|~>JIqD!Mcqr zWdj>w>6{!E(H;0~TB0^xQOE*^>}d&`^x{6o%!k_261C~|x`d3~p0q@5`tt@GD?C(s JO~OV*^*^#b;?e*B diff --git a/app/extensions/__pycache__/tim_judges.cpython-313.pyc b/app/extensions/__pycache__/tim_judges.cpython-313.pyc index 2c8ef81b054e3835c5d738468d785c128deb8b13..c13caca339ea6d7e4f147364e0815b913a432d93 100644 GIT binary patch delta 37 rcmaE+`&5_vGcPX}0}zxj%-G1y$IR`dpPN^rpQ7&@?73N$`JgZW#n%c( delta 38 scmaE=`%IVnGcPX}0}uq9owkvikD13=KR2&LKUv?gxU_h)3iCl>0OEiPpa1{> diff --git a/app/extensions/tim_guardrails.py b/app/extensions/tim_guardrails.py index ee520be..0542491 100644 --- a/app/extensions/tim_guardrails.py +++ b/app/extensions/tim_guardrails.py @@ -147,6 +147,43 @@ def _authorized_human_handoff(context: dict[str, Any]) -> bool: return any(terminal_workflow_handoff(root) for root in roots) + + +def _deterministic_tim_domain_response(text: str, context: dict[str, Any]) -> bool: + """Conservative fast path for unmistakable TIM Contas domain output. + + This extension may know the TIM Contas vocabulary; the generic framework does + not. Human-transfer language is intentionally excluded so handoff authorization + remains exclusively structural. Ambiguous domain prose still goes to TIM_OOS LLM. + """ + normalized = re.sub(r'\s+', ' ', str(text or '').strip().lower()) + if not normalized: + return False + + handoff_markers = ( + 'encaminhar', 'encaminhado', 'transferir', 'transferido', + 'atendente', 'pessoa', 'humano', 'especialista', + ) + if any(m in normalized for m in handoff_markers): + return False + + domain_markers = ( + 'contestação', 'contestacao', 'fatura', 'cobrança', 'cobranca', + 'plano', 'serviço', 'servico', 'vas', 'boleto', 'desconto', + ) + completion_markers = ( + 'registrad', 'cancelad', 'concluíd', 'concluid', 'executad', + 'processad', 'enviad', 'emitid', 'protocolo', + ) + + # Keep the bypass intentionally narrow: an unmistakable domain noun plus an + # operational/result marker. Ordinary explanations and ambiguous responses are + # still semantically audited by TIM_OOS. + return ( + any(m in normalized for m in domain_markers) + and any(m in normalized for m in completion_markers) + ) + def _parse_json(raw: Any) -> dict[str, Any]: text = str(getattr(raw, 'content', raw) or '').strip() m = re.search(r'\{[\s\S]*\}', text) @@ -196,6 +233,22 @@ class TimOutOfScopeRail(_TimPromptRail): }, }, ) + if _deterministic_tim_domain_response(text, context): + return RailDecision( + code=self.code, + allowed=True, + reason='resposta suportada pelo contexto do domínio TIM Contas', + sanitized_text=text, + metadata={ + 'external': True, + 'domain': 'TIM_CONTAS', + 'mechanism': 'deterministic_domain_bypass', + 'data': { + 'allowed': True, + 'reason': 'resposta suportada pelo contexto do domínio TIM Contas', + }, + }, + ) return await super().evaluate(text, context) class TimProactiveOfferRail(_TimPromptRail): @@ -347,6 +400,8 @@ class TimPrematureActionRail(_TimPromptRail): 'final_answer', 'customer_message', 'customer_response', 'answer', 'text', 'epistemic_status', 'output', 'result', 'items', 'results', 'errors', 'cancelados', 'nao_cancelados', 'nao_encontrados', 'terminal_status', + 'contestation_registered', 'contested_invoice_amount', 'contested_invoice_amount_open', + 'sms_sent', 'barcode', 'itemName', 'itemsResponse', 'contested_items', 'sr', } out = {} for k, v in value.items(): @@ -414,6 +469,142 @@ class TimPrematureActionRail(_TimPromptRail): return False return candidate in cls._authoritative_output_messages(context) + @staticmethod + def _normalized_text(value: Any) -> str: + text = str(value or '').lower() + text = text.replace('r$', ' ') + text = re.sub(r'\s+', ' ', text) + return text.strip() + + @classmethod + def _candidate_has_operational_completion_claim(cls, text: str) -> bool: + """Detect completion/effect claims, not ordinary explanations. + + REVPREC exists to stop claims that an operation already happened. A + billing explanation containing values/dates is not such a claim and must + not depend on a probabilistic binary LLM classification. + """ + normalized = cls._normalized_text(text) + patterns = ( + r'\b(cancelad[oa]s?|cancelei|cancelamos|cancelou|cancelamento .*conclu)', + r'\b(contesta(?:ção|cao) .*?(?:registrad|abert|conclu|criad))', + r'\b(registrad[oa]s?|executei|executamos|executou|executad[oa]s?|conclu[ií]d[oa]s?|processad[oa]s?)\b', + r'\b(enviad[oa]s?|emitid[oa]s?|retirad[oa]s?|removid[oa]s?)\b', + r'\b(protocol(?:o)? .*?(?:abert|gerad|registrad))', + r'\b(?:foi|foram) (?:cancelad|contestad|registrad|enviad|emitid|retirad|removid)', + r'\b(?:was|were|has been) (?:cancelled|canceled|registered|sent|issued|removed)', + ) + return any(re.search(pattern, normalized, re.I) for pattern in patterns) + + @classmethod + def _current_execution_scalar_evidence(cls, context: dict[str, Any]) -> tuple[list[str], bool, bool]: + """Flatten scalar facts from current successful result/output only. + + Returns (facts, completed, positive_effect). Inputs, conversation state, + history and metadata are excluded so user claims can never prove an action. + """ + roots = (context or {}).get('mcp_results') + if roots is None: + roots = (context or {}).get('tool_result') + if isinstance(roots, dict): + roots = [roots] + if not isinstance(roots, (list, tuple)): + return [], False, False + + facts: list[str] = [] + completed = False + positive = False + positive_status = {'completed', 'opened', 'open', 'iniciada', 'iniciado', 'success', 'succeeded', 'closed', 'fechado'} + positive_keys = { + 'success', 'executed', 'contestation_registered', 'sms_sent', + 'cancelled', 'canceled', 'registered', 'created', 'updated', + } + skip = {'state', 'input', 'metadata', 'conversation_history', 'history', 'session', 'session_metadata'} + + def walk(value: Any, path: tuple[str, ...] = ()) -> None: + nonlocal completed, positive + if isinstance(value, dict): + for k, v in value.items(): + key = str(k).lower() + if key in skip: + continue + if key == 'status' and str(v).strip().lower() == 'completed': + completed = True + if key in positive_keys and v is True: + positive = True + if key == 'status' and str(v).strip().lower() in positive_status: + positive = True + # Keys such as sms_sent/barcode are themselves meaningful + # evidence and can support paraphrased customer-facing text. + if key not in {'output', 'result', 'results'}: + facts.append(key) + walk(v, path + (key,)) + elif isinstance(value, (list, tuple)): + for item in value[:50]: + walk(item, path) + elif value not in (None, ''): + facts.append(str(value)) + + for item in roots: + if not isinstance(item, dict) or item.get('ok') is False: + continue + if str(((item.get('result') or {}) if isinstance(item.get('result'), dict) else {}).get('status') or '').upper() == 'COMPLETED': + completed = True + walk(item.get('result', item)) + return facts, completed, positive + + @classmethod + def _candidate_is_structurally_grounded_completion(cls, text: str, context: dict[str, Any]) -> bool: + """Allow a paraphrased completion only when current execution proves it. + + This deliberately does not know tool names. It requires a completed + current execution, a positive side-effect marker, grounding for every + material number mentioned by the candidate, and at least one meaningful + textual fact/entity shared with the execution result. + """ + if not cls._candidate_has_operational_completion_claim(text): + return False + facts, completed, positive = cls._current_execution_scalar_evidence(context) + if not (completed and positive and facts): + return False + + candidate = cls._normalized_text(text) + evidence_text = cls._normalized_text(' '.join(facts)) + + def canon_number(raw: str) -> str: + raw = raw.strip().replace(' ', '') + if ',' in raw and '.' in raw: + if raw.rfind(',') > raw.rfind('.'): + raw = raw.replace('.', '').replace(',', '.') + else: + raw = raw.replace(',', '') + else: + raw = raw.replace(',', '.') + try: + num = float(raw) + return (f'{num:.6f}').rstrip('0').rstrip('.') + except ValueError: + return re.sub(r'\D', '', raw) + + candidate_numbers = [canon_number(x) for x in re.findall(r'(?= 2] + if not material_numbers: + return False + if any(n not in evidence_numbers for n in material_numbers): + return False + + # Require an entity/message overlap beyond generic success vocabulary. + candidate_words = set(re.findall(r'[a-zà-ÿ0-9+_-]{4,}', candidate, re.I)) + stop = { + 'sucesso', 'registrada', 'registrado', 'concluido', 'concluida', + 'cliente', 'valor', 'protocolo', 'cobranca', 'contestacao', 'servico', + 'mensal', 'novo', 'boleto', 'recebeu', 'detalhes', + } + evidence_words = set(re.findall(r'[a-zà-ÿ0-9+_-]{4,}', evidence_text, re.I)) + meaningful_overlap = (candidate_words - stop) & (evidence_words - stop) + return bool(meaningful_overlap) + async def evaluate(self, text: str, context: dict[str, Any]) -> RailDecision: # Strongest possible proof: the exact customer-facing candidate was emitted by # the successful current-turn tool/workflow itself. REVPREC is about premature @@ -433,6 +624,41 @@ class TimPrematureActionRail(_TimPromptRail): }, ) + # REVPREC is not a general factuality rail. Ordinary descriptions and + # explanations contain no claim that an operation has already completed, + # so they are deterministically outside this rail's blocking scope. + if not self._candidate_has_operational_completion_claim(text): + return RailDecision( + code=self.code, + allowed=True, + reason='no_operational_completion_claim', + sanitized_text=text, + metadata={ + 'external': True, + 'domain': 'TIM_CONTAS', + 'mechanism': 'deterministic_claim_scope', + 'terminal_action': 'retry', + }, + ) + + # A composed/paraphrased response can still be proven by structured + # current-turn execution evidence even when it is not byte-for-byte equal + # to a workflow message. This removes nondeterministic false positives + # while keeping unsupported or contradictory claims on the semantic path. + if self._candidate_is_structurally_grounded_completion(text, context): + return RailDecision( + code=self.code, + allowed=True, + reason='current_execution_structurally_grounded', + sanitized_text=text, + metadata={ + 'external': True, + 'domain': 'TIM_CONTAS', + 'mechanism': 'deterministic_structured_execution_evidence', + 'terminal_action': 'retry', + }, + ) + evidence = self._current_execution_evidence(context) llm = _llm(context) if llm is None: diff --git a/app/extensions/tim_prompts/__pycache__/__init__.cpython-313.pyc b/app/extensions/tim_prompts/__pycache__/__init__.cpython-313.pyc index cb352ae4f468c4b288f2078ac481be9c7990be0d..d60c9769e1bd560f8f8fa349378ce91819ba3cbe 100644 GIT binary patch delta 34 ocmZ3-xR#OoGcPX}0}zxj%$Ue+%xQ>zgGcPX}0}uq9oi>r%n8#N?H?KrLS>Lg^w0NRt3IMDV3UmMf diff --git a/app/extensions/tim_prompts/__pycache__/aluc.cpython-313.pyc b/app/extensions/tim_prompts/__pycache__/aluc.cpython-313.pyc index e461acbb91d90d9ec11a35ba9f6863811cdf5249..51b29b943ff3a82db455f4de93559f0b3cc31814 100644 GIT binary patch delta 36 qcmexr_{EU>GcPX}0}zxj%-G1yE5YrdpPN^rpQ7&@>^WIQ;vxXT9}0H> delta 37 rcmexj_|=g6GcPX}0}uq9owkviSAxe=KR2&LKUv?gxU_h(vcyFI-L4DK diff --git a/app/extensions/tim_prompts/__pycache__/ausencia_oferta_proativa.cpython-313.pyc b/app/extensions/tim_prompts/__pycache__/ausencia_oferta_proativa.cpython-313.pyc index ec52917fdb8deff7b4be24a4d42cf1e367bb00cd..b40ec02f91300db88503b1be1ddf5f6e027855c3 100644 GIT binary patch delta 37 rcmew#{4bdMGcPX}0}zxj%-G0%PlG!~KR2&LKSkd+*mLt&4K79i?HmjL delta 38 scmewt{6CocGcPX}0}uq9owkwto(4~>er{fgezLw}acS}9FB)8o01IIaSpWb4 diff --git a/app/extensions/tim_prompts/__pycache__/fraseologia.cpython-313.pyc b/app/extensions/tim_prompts/__pycache__/fraseologia.cpython-313.pyc index 7e2bf2c7e8a9ed4aa4d8b87dac12890780cf8413..487c5c8624c6bd43d17d65365a4da30a15279aab 100644 GIT binary patch delta 37 rcmaE1_1ud4GcPX}0}zxj%-G1SDZ}lrpPN^rpQ7&@?77)NMuQOm&HD;2 delta 38 scmaEE^}>q#GcPX}0}uq9owku%Q-&u%KR2&LKUv?gxU_h)y^IDU0P6z_hyVZp diff --git a/app/extensions/tim_prompts/__pycache__/out_of_scope.cpython-313.pyc b/app/extensions/tim_prompts/__pycache__/out_of_scope.cpython-313.pyc index 2c2ad19df12ae9e7c42e6006c11e7879c499eef4..b8c4c566f492f6a0be5d02de392566575359b70a 100644 GIT binary patch delta 39 tcmey&G!vFvP diff --git a/app/extensions/tim_prompts/__pycache__/rqlt.cpython-313.pyc b/app/extensions/tim_prompts/__pycache__/rqlt.cpython-313.pyc index 3f69ac305a75c3962dea2f6e96d40aca6d38bb5b..df2f5a357241442fea92c3e23655d859bdd60ef4 100644 GIT binary patch delta 36 qcmX@Xah!wuGcPX}0}zxj%-G1C#?0-ZpPN^rpQ7&@>^ZrX`7{8qr3y^| delta 37 rcmX@kae{;UGcPX}0}uq9owkuXjhV+&KR2&LKUv?gxU_h34fAOL%ghU> diff --git a/app/observability/__pycache__/__init__.cpython-313.pyc b/app/observability/__pycache__/__init__.cpython-313.pyc index 0e2017dc924fde6f1fbbdbc38a93de944e7765dc..4195e82a5217dd5228b7c8dd9f71e5e46310eea5 100644 GIT binary patch delta 34 ocmZ3=xP+1WGcPX}0}zxj%$Ue+%r%n8!swH?KrLS>Lg^w0NRtGytg|3Qzz5 diff --git a/app/observability/__pycache__/telemetry_observer.cpython-313.pyc b/app/observability/__pycache__/telemetry_observer.cpython-313.pyc index decbfe3630686e106074c4dd1456484aa420c46e..af53bdbdfb8bb14e6b2f4201992f58f7ab9e5488 100644 GIT binary patch delta 37 rcmeyP_FIknGcPX}0}zxj%-G1il9Ah2KR2&LKSkd+*mLs%#yx@n*n|t3 delta 38 scmeyZ_D7BTGcPX}0}uq9owkvCB_ofYer{fgezLw}acS}9{fv7A0rl?;^Z)<= diff --git a/app/presentation/__pycache__/__init__.cpython-313.pyc b/app/presentation/__pycache__/__init__.cpython-313.pyc index 5783322361c59c205306da30d3a0e17bc4c4e3eb..f9fe47780828d96cbffa4dd7e9636c991800250c 100644 GIT binary patch delta 34 ocmZot<8 delta 35 pcmZo*YGmU6%*)Hg00aSNr%mK;<#E=}%`4GQ)^{u}EuJ_#6#%8;3bz0N diff --git a/app/presentation/__pycache__/tool_renderers.cpython-313.pyc b/app/presentation/__pycache__/tool_renderers.cpython-313.pyc index 1031a41d67728ab17d5aa77f1786497f7ac2a29b..8e103a45c4e739043c93cefdca422c26d850b57b 100644 GIT binary patch delta 37 rcmdm{wN;DzGcPX}0}zxj%-G0%k&)X&KR2&LKSkd+*mLs>Mn7Qy$XW{Z delta 38 scmdn0wM~orGcPX}0}uq9owkwtA|sEder{fgezLw}acS}9=Zt>B0Oe#1PXGV_ diff --git a/app/workflows/__pycache__/agent_graph.cpython-313.pyc b/app/workflows/__pycache__/agent_graph.cpython-313.pyc index 0ff8cec14aa09ea43f7c629b253ed946a2c4c5a1..9f99f5607ac2d9618d7dfe54e1a246a472dd4123 100644 GIT binary patch delta 43 xcmbQRm!*F%3-@PUUM>b8C}Ehfk-LeN+etq+uS7pZ-#6H^c_!=jnXHW8B>)yT4G#bS delta 44 zcmeC*%Q9gv3-@PUUM>b82sk@!BX<)kkF$PmUWtCPzGHD|aq|q;?K4;zze@lBIW!Jv diff --git a/config/judges.yaml b/config/judges.yaml index 158aa15..26faf83 100644 --- a/config/judges.yaml +++ b/config/judges.yaml @@ -4,5 +4,5 @@ profile: judge judges: - {name: tim_response_quality, type: external, class: app.extensions.tim_judges:TimResponseQualityJudge, enabled: true, threshold: 0.70} - {name: tim_groundedness, type: external, class: app.extensions.tim_judges:TimGroundednessJudge, enabled: true, threshold: 0.60} -sample_rate: 0.1 +sample_rate: 1.0 always_run_for_transactional: true 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 index 51d5c72a5d21b3e183febbb97966897ba9e53532..d3444cebf21d965c4a611a5982355783eab7c1da 100644 GIT binary patch delta 44 ycmdnXwu_DHGcPX}0}%L~-N=>9B%-gMn^&Trl30?cpO#q>pO~JSS2DSUX(s?0iVh$E delta 47 zcmdnRwwI0TGcPX}0}woq*vOU4ByOain^&Trl30?cUsRe`l9`(tpO#r+G`W#!Cjd>9 B4{iVe diff --git a/tests/migration/__pycache__/test_adversarial_parity.cpython-313-pytest-9.0.2.pyc b/tests/migration/__pycache__/test_adversarial_parity.cpython-313-pytest-9.0.2.pyc index 8a21abb8cc364b10f88bc4e43bacb00d15196125..73e4fbb324f39cb1ffd8b260bf5ada11f1df7b2e 100644 GIT binary patch delta 47 zcmaDepZVo{X0Fe?yj%=G;CFT-*8^q|JN?|e68)6Kl0^Nq%!>HL^whkP&5SIsPXhpe CBA%nGB;|CnE& F1^~Z&6Dt4! 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 index 27e9ab2e1ccb9db163358a42bda67b1b7ce0f80c..4158e8a9a15717066fc6312a82cb1cebb0f14525 100644 GIT binary patch delta 47 zcmZ3nlxgWwCa%xCyj%=G;CFT-*I_0RZ~ff768)6Kl0^Nq%!>HL^whkP%}BA%nGB;51Eei F0|2C75*q*j 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 index b7661046505619b85cf33a7e5acfd3490ef943a9..7ba6df00f39ce0ac2d8e4e4a611ec0739637448e 100644 GIT binary patch delta 45 zcmZ3ixImHXGcPX}0}%L~-N?0vQN&9>H?KrLC9xz?KP|H&J~2HtuVnLG#$$W{H#rX| delta 48 zcmZ3WxLA?vGcPX}0}woq*vPeqQQTKQH?KrLC9xz?zo;~?Br`WPJ}tAtX!9+`V|)N? C@DO$Y diff --git a/tests/migration/__pycache__/test_cancel_backend_wrapper_parity.cpython-313-pytest-9.0.2.pyc b/tests/migration/__pycache__/test_cancel_backend_wrapper_parity.cpython-313-pytest-9.0.2.pyc index e79b2cb93249d8653ab49d77968dbff76219dc0f..528abd785659fe8625c47eac383bc7591b1eba6a 100644 GIT binary patch delta 47 zcmeBw%-Hjok?S)rFBbz4_?_LzWx_1tsh^uyqMwpjlBl1SSrMO@o|;#(Ih5Hd4*+DG B4^037 delta 50 zcmeBq%-H{!k?S)rFBbz4JdfDOWx_1(qo12sqMwpjlBi!)npcvUn;M^%Sz)v}h}kL+ E0G!njn*aa+ diff --git a/tests/migration/__pycache__/test_cancel_composite_workflow.cpython-313-pytest-9.0.2.pyc b/tests/migration/__pycache__/test_cancel_composite_workflow.cpython-313-pytest-9.0.2.pyc index 8c67b7c8f4f7bbc7d69fa84b8838317ad08a112f..53cb8aa3eb448a6b45da86b004b55d53167b0c05 100644 GIT binary patch delta 47 zcmX^6pZU~(X0Fe?yj%=G;CFT-mm7CH?KrLC9xz?zo;~?Br`WPJ}tAtX!CK-R{{Wd C`w-6n diff --git a/tests/migration/__pycache__/test_contas_conversation_policy_residuals.cpython-313-pytest-9.0.2.pyc b/tests/migration/__pycache__/test_contas_conversation_policy_residuals.cpython-313-pytest-9.0.2.pyc index 6e47fb8f0f0fa08dae43e29e07650ef1f444a0fe..3766976d8c58db0cbf4958f3402bc26e17db8ae6 100644 GIT binary patch delta 47 zcmaDfmFfOeCa%xCyj%=G;CFT-*J%-v0R7y&68)6Kl0^Nq%!>HL^whkP&2L1$l>z{M CVi9uy delta 50 zcmcaVmFdw`Ca%xCyj%=Gz`toD*J%;)VEx>@68)6Kl0^NY(!7$)+|>BA%nGB;FGaqU F0syBt5<>t0 diff --git a/tests/migration/__pycache__/test_contas_domain_mock.cpython-313-pytest-9.0.2.pyc b/tests/migration/__pycache__/test_contas_domain_mock.cpython-313-pytest-9.0.2.pyc index 22dbfe844f1e2954124ba36ac1f8e4d06607ec7a..7190ad03a23f81c2b675f739b774cd2203ab9bdb 100644 GIT binary patch delta 47 zcmdn|jd{a2X0Fe?yj%=G;CFT-mlltRoqld!iGE6ANuqvQW<`8rdTL(DW^bMs?*Ms7 B5a0j+ delta 50 zcmdn+jd}AoX0Fe?yj%=G@GN2@mllt>qke8)iGE6ANuqvHX14$ delta 50 zcmdnh#<;hQk?S)rFBbz4JdfDO^^s9LP(L@XL_a05BvHSpG_NExH#I&jv%+XIKa;j2 E0HK)>eEHL^whkP&G(qLh64a- CHV|+C delta 50 zcmbQRm2vV`My}7iyj%=G@GN2@*Ip)ZfBoFN68)6Kl0^NY(!7$)+|>BA%nGB;x0$wv F0|21$5xoEa diff --git a/tests/migration/__pycache__/test_contestation_failure_mapping.cpython-313-pytest-9.0.2.pyc b/tests/migration/__pycache__/test_contestation_failure_mapping.cpython-313-pytest-9.0.2.pyc index bf297577fda3425b4d1b1294979f90228cf7261a..8e6f510cdc05b568095386a3c0059a400e4e6f8a 100644 GIT binary patch delta 45 zcmexh{nnc6GcPX}0}%L~-N?0+QN%+(H?KrLC9xz?KP|H&J~2HtuVnKvMlBftRxuAa delta 48 zcmaEB{lS{+GcPX}0}wom*vPe%QQTWUH?KrLC9xz?zo;~?Br`WPJ}tAtX!Bu4Eg1lf CpO~JSSF*W^%aR!YFHsHq delta 48 zcmdlWy;+*;GcPX}0}wom*vJ*hB_5%ln^&Trl30?cUsRe`l9`(tpO#r+w7Hzik{JMG CG!IAs diff --git a/tests/migration/__pycache__/test_contestation_single_item_mock_regression.cpython-313-pytest-9.0.2.pyc b/tests/migration/__pycache__/test_contestation_single_item_mock_regression.cpython-313-pytest-9.0.2.pyc index ded15b239dcec26c3dd47e4b13e9f767f7c3b73d..63febc4426de2b769090f34db9cbd9482cd69708 100644 GIT binary patch delta 45 zcmdn#xXqF4GcPX}0}%L~-N;qTEfS)in^&Trl30?cpO#q>pO~JSSF(8?x3nk#LVymC delta 48 zcmdnyxYLpAGcPX}0}woq*vM7OEgr6)n^&Trl30?cUsRe`l9`(tpO#r+w0SnSv?u_0 C`VZa! diff --git a/tests/migration/__pycache__/test_contestation_subject_entity_resolution.cpython-313-pytest-9.0.2.pyc b/tests/migration/__pycache__/test_contestation_subject_entity_resolution.cpython-313-pytest-9.0.2.pyc index c88fc030460e82e1c4b6c71abea93e764c1c1374..425be7af9f0830eafed62f13f75586030c2f0b7a 100644 GIT binary patch delta 45 zcmaFi_tcN;GcPX}0}%L~-N^NXQzS?~H?KrLC9xz?KP|H&J~2HtuVgbTSF$VsU=t4^ delta 48 zcmaFr_rj0sGcPX}0}woq*vR#SQ#@2ZH?KrLC9xz?zo;~?Br`WPJ}tAtXfqR6vMd0Z C9uRK; diff --git a/tests/migration/__pycache__/test_discount_history_mcp_service.cpython-313-pytest-9.0.2.pyc b/tests/migration/__pycache__/test_discount_history_mcp_service.cpython-313-pytest-9.0.2.pyc index 0aa7add3e1625b09c534c4d14cfd14ad0f045992..90c2b85f9d41435a3c459b8f3caa6d1a3c28ba35 100644 GIT binary patch delta 47 zcmdn9fN|#nMy}7iyj%=G;CFT-mkpU%*)Hg00hq>Hgd7@iTmp3=9TEDB$g!V7nSCfWag&Er)5?cZC2(>mjnP^ CHV*v& diff --git a/tests/migration/__pycache__/test_finalization_parity_extended.cpython-313-pytest-9.0.2.pyc b/tests/migration/__pycache__/test_finalization_parity_extended.cpython-313-pytest-9.0.2.pyc index 4f7f1b0f1377dde23f89bdf007a38172d317d56d..c15b13e9de0d72178987adedf19a1eaed886d6e1 100644 GIT binary patch delta 47 zcmZ3pg=ys$Ca%xCyj%=G;CFT-R|S)ZhkkBeiGE6ANuqvQW<`8rdTL(D=9x^Brvm_J C4-hf{ delta 50 zcmZ3vg=x(eCa%xCyj%=G@GN2@R|S)}w|;J3iGE6ANuqvHXpO~JSSF(9FJF74NGh+@B delta 48 zcmbPhy1b8@H@MaD}q(TO+PoUL_a05BvC&tvm!n*JvFanb0zCc7XVK? B4>JG& delta 50 zcmeC5!Z>LPBiCnMUM>b8cpkBlD}q(rQ$IJaL_a05BvHSpG_NExH#I&jv%+X|8S6|J E0EQJ1fdBvi diff --git a/tests/migration/__pycache__/test_framework_rag_directive.cpython-313-pytest-9.0.2.pyc b/tests/migration/__pycache__/test_framework_rag_directive.cpython-313-pytest-9.0.2.pyc index 532dbed3f868b26c638f412749c988663ca1711d..85534536783e6f9ebf1458e9c126f1717faa67cd 100644 GIT binary patch delta 45 zcmaFm`P`H1GcPX}0}uq9-N?nvB;u@}n^&Trl30?cpO#q>pO~JSSF%}!>6j7#MYIm3 delta 48 zcmaFv`O1^)GcPX}0}wom*vQ4qB<`l4n^&Trl30?cUsRe`l9`(tpO#r+v{{kqm=XYc CWe@NG diff --git a/tests/migration/__pycache__/test_framework_zero_legacy.cpython-313-pytest-9.0.2.pyc b/tests/migration/__pycache__/test_framework_zero_legacy.cpython-313-pytest-9.0.2.pyc index 93482bec0a28073e711810749eb6b120bf1d20b2..ac07629413cb7378a5de2d0227f415dcc62fb0de 100644 GIT binary patch delta 45 zcmey#`;C|DGcPX}0}%L~-N^NbMZ{4*H?KrLC9xz?KP|H&J~2HtuVgbb>o-OKPM{AN delta 47 zcmeyy`;(XJGcPX}0}woq*vR#WMchR{H?KrLC9xz?zo;~?Br`WPJ}tAtXcOx4B;u@}n^&Trl30?cpO#q>pO~JSSF*XENkkGcPX}0}uq9-N=>3D&nP|n^&Trl30?cpO#q>pO~JSSF*XC)rbiIErAX0 delta 48 zcmdnSzmuQqGcPX}0}woq*vOT}D(H?KrLC9xz?KP|H&J~2HtuVnLX#(Y5lHe?Q{ delta 48 zcmZ3kwn~lbGcPX}0}wom*vK`DQQTKQH?KrLC9xz?zo;~?Br`WPJ}tAtX!8!nd_e$f C+7I;r diff --git a/tests/migration/__pycache__/test_guardrail_original_defaults_parity.cpython-313-pytest-9.0.2.pyc b/tests/migration/__pycache__/test_guardrail_original_defaults_parity.cpython-313-pytest-9.0.2.pyc index 984cc30e2d94c9ba6e54adf5f7b57a6ba785b3be..518bd3bb53428601316897829dad04e592b5d4f2 100644 GIT binary patch delta 45 zcmZ2!w9JU>GcPX}0}%L~-N^NjN5oG*H?KrLC9xz?KP|H&J~2HtuVgb5uR0F^KoAZZ delta 48 zcmZ2xw9<&{GcPX}0}wom*vR#eM?6qJH?KrLC9xz?zo;~?Br`WPJ}tAtX!Cy_bshkE C#}H-! diff --git a/tests/migration/__pycache__/test_guardrail_runtime_stability.cpython-313-pytest-9.0.2.pyc b/tests/migration/__pycache__/test_guardrail_runtime_stability.cpython-313-pytest-9.0.2.pyc index 13b89e4c655db807d86725b34679bfddf007deb7..00a53d4371dc57569495d0c07402332eef75bc8e 100644 GIT binary patch delta 45 zcmdmzxIU5VGcPX}0}%XLy^$-FQN&$8H?KrLC9xz?KP|H&J~2HtuVixtqm4cQRfi86 delta 50 zcmZ3VxFwP6GcPX}0}!lUxsfZBQPM|0H?KrLC9xz?KQphmAT_xpJ~= E0H8?__5c6? diff --git a/tests/migration/__pycache__/test_human_handoff_guardrail_context.cpython-313-pytest-9.0.2.pyc b/tests/migration/__pycache__/test_human_handoff_guardrail_context.cpython-313-pytest-9.0.2.pyc index 7a5ea6351a0159690f339a2a6af5f87a27414103..1f8f69c8665a7b65465e5da9a761975ec5d58baf 100644 GIT binary patch delta 45 zcmbQ~IL(pkGcPX}0}%L~-N^NvQ^Z?8H?KrLC9xz?KP|H&J~2HtuVga^*F-S@K$8xS delta 48 zcmbQ{IMb2qGcPX}0}woq*vR#qQ`}EKH?KrLC9xz?zo;~?Br`WPJ}tAtXfrFn^&Trl30?cpO#q>pO~JSSF$;VDM$(cF>4L} delta 48 zcmZ2&xz3X7GcPX}0}woq*vMtgB<`x8n^&Trl30?cUsRe`l9`(tpO#r+v^kO~ND2UE CTn|hD diff --git a/tests/migration/__pycache__/test_input_guardrail_user_feedback.cpython-313-pytest-9.0.2.pyc b/tests/migration/__pycache__/test_input_guardrail_user_feedback.cpython-313-pytest-9.0.2.pyc index 0afa28be8c7b13ec7a1046b50b119b8a22ab1a08..244a39d3f64d93a6d585641ffe443afe90ae2a99 100644 GIT binary patch delta 45 zcmZp+X|Un?%*)Hg00aSNH*zsEig@bh=9TEDB$g!Vr)5^eC#I+7m26gFye|U)9+C~z delta 48 zcmZp$X}00|%*)Hg00hq?HgYjDiu>s2=9TEDB$g!V7nSCfWag&Er)5?cZB}HwF9QHk Cy$>J& diff --git a/tests/migration/__pycache__/test_invoice_context_framework_native.cpython-313-pytest-9.0.2.pyc b/tests/migration/__pycache__/test_invoice_context_framework_native.cpython-313-pytest-9.0.2.pyc index 2ddb92c17463b35db18462163d3ff9b3de88816c..6b4a63a8665cdb455440001a407f069bd135d5f5 100644 GIT binary patch delta 47 zcmaEHf$8Z5Ca%xCyj%=G;CFT-S0{^zkA7}miGE6ANuqvQW<`8rdTL(D=2a~F76Sl^ CK@md$ delta 50 zcmaEQf$7BsCa%xCyj%=G@GN2@S0{_OzkY6BiGE6ANuqvHXpO~JSSF$;QHH8NNGqVmH delta 48 zcmX@8d_p Cgb$Sf diff --git a/tests/migration/__pycache__/test_judge_context_compaction.cpython-313-pytest-9.0.2.pyc b/tests/migration/__pycache__/test_judge_context_compaction.cpython-313-pytest-9.0.2.pyc index 0c20b92a19ebd19383efc22085a93bdd9e172b1a..7ff40e9943241f4a53b88ab21d75b13a7c2e5aa8 100644 GIT binary patch delta 45 zcmdn%xXY32GcPX}0}%L~-N?nsC*q=?n^&Trl30?cpO#q>pO~JSSF%})Z?X^oH5U#W delta 48 zcmdnxxYv>EGcPX}0}woq*vQ4nC+@DFn^&Trl30?cUsRe`l9`(tpO#r+v{{{RvJe1j CCJ$)< diff --git a/tests/migration/__pycache__/test_line_policy_alternatives.cpython-313-pytest-9.0.2.pyc b/tests/migration/__pycache__/test_line_policy_alternatives.cpython-313-pytest-9.0.2.pyc index c3dab9350ce7267bef5a218a58c83b3a0f13c171..b1cbdb1a34e88cefd4430d8a6aa8d93bd6406b4a 100644 GIT binary patch delta 47 zcmaE{h4JYYMy}7iyj%=G;CFT-mlL~)i+*liiGE6ANuqvQW<`8rdTL(D=45u(U;uR< B4{!hg delta 50 zcmaF5h4IA}My}7iyj%=G@GN2@mlM0VyMAt7iGE6ANuqvHX6EaI)7n^&Trl30?cpO#q>pO~JSSF*W_*+2jQHSi8C delta 48 zcmdn4zDu3!GcPX}0}woq*vOU1EbgbDn^&Trl30?cUsRe`l9`(tpO#r+w7H$xKmY)1 CWepO~JSSF+iGRhT1{FiO|)NP(>6%1TOuh8w|8fgNq6U7 zXYNg!f*4y-=!*)L3i?uf>Z3mSo_`>R{jbnjb&0FU!VViGmJTEO5jXR>y z-YJSA?AYgf#!I5)qTOg8@^b^o&yQG{Pf@;HoZOx9-E?xGTgrIf89*a#wW!QkUg43J zJgmwA=TQK`@iDuB zJ!>L82X;Intsn_!iJ*yCbmx}uy36<6It`gz{w4y(4dLM;YEqZFJX6h6S5n~$%6LLW z3@3wn1ff<=O3>@b&k7L<&sI4}n+=r<#EewV)dl^P`kAils!KyHo($E4Bp7P2Yb4N_ z8A_;3MfJ3)`CdZaOM_;6 zXB#06CS=lNoWd)KsDKOAPl(hV5RxEC1iO+#RIv99?5)E;5`CID9ij^pQK}YF4K$H8hS}96;gQzCDBvL%Ub=9M{lfzGM6JTifW5 za{#1S@HUTc+Y|X-#I2g;=k*b8`%ZMamV50jgreHP_ThSj(6kQ5tVtcnmIXj7)bhjF zFHQ{)TO(}8 z1-BMDzB*qDcpSyt9>wuHGpL9rZW;XaYH*j6C~6WBL4}3t*GLKEmUc}K!5vp%BDnR4 zNjGi=Jd$qOa%syASxc*3I4>eM7J(Zs-vy*Q8dyA0Jt^RcB=lOMw#k6Agk7g~!g!p* zUMq}=zFw+=zE~SM0hbF@q{raOGgO9YGp2_!)Pg(8>#XX&9o4B|0iZXg2@@LO`uf0a zM4}bE?%}_!(NPay-*Mnzym-Wu?&zqi*F--!Ywv#YuLbhlu!l)Gof~p=Og9ge5p67!0L&}%wT2Gd?q<;`$V zd5tQn96@E;OjH?slk63TyMSZfa%k zR7UTYryl0oe?Ne}JeY|;cJU94{f5~F12$_ms=V|>>cMnl=+qeg7N0ti`|ea3SZ|vi zdyN!Ahp{L0bWz1CDQhN-OVz7Wzai}*S&^$*F(BxwpbLUQt$H?8s?gSn1KO999Z`FO zIIf!V%BswMDM=egM%&d;xmF;q!g!a9JYb8@H@MaYa+9Vn|^LyiGE6ANuqvQW<`8rdTL(D=1t5GA^>Ba B5Jmt1 delta 50 zcmeC*$v9~zBiCnMUM>b8cpkBlYa+9_r+#i;iGE6ANuqvHXHL^whkP%{Q1heF1wr B5Geov delta 50 zcmcaNpYh>*My}7iyj%=G@H}E8*LEiHDE-{L68)6Kl0^NY(!7$)+|>BA%nGB;SD83{ E0kwD$cK`qY diff --git a/tests/migration/__pycache__/test_observability_mapping_provider_boundary.cpython-313-pytest-9.0.2.pyc b/tests/migration/__pycache__/test_observability_mapping_provider_boundary.cpython-313-pytest-9.0.2.pyc index 7ad7e92a94ff447c582fc4e07cd96ae44836ca7b..60bbef801de4b849c264c048d461e728ba3c27ab 100644 GIT binary patch delta 45 zcmcblb6$t*GcPX}0}%L~-N-eENhDZ5H?KrLC9xz?KP|H&J~2HtuVnLHrm4aJN3{<- delta 48 zcmX@Fb4iEmGcPX}0}woq*vK`9NjywHH?KrLC9xz?zo;~?Br`WPJ}tAtX!9pO~JSSF(8zTPPm@F-#7A delta 48 zcmeCvnyAI~nU|M~0SKN)Y~-5FCLX7sn^&Trl30?cUsRe`l9`(tpO#r+w0S36C?5c3 CtPjip diff --git a/tests/migration/__pycache__/test_original_compliance_anatel.cpython-313-pytest-9.0.2.pyc b/tests/migration/__pycache__/test_original_compliance_anatel.cpython-313-pytest-9.0.2.pyc index 6d132626ec3b879c7fcbf13075fb7015d08fd9e3..2cb1695e8eeffd8361c3cb6b2c1edcd226b64b90 100644 GIT binary patch delta 47 zcmZ3`!8o^rk?S)rFBbz4_?_LzWy&Msrk|TvqMwpjlBl1SSrMO@o|;#(IgIC&IRH%1 B4tzFBbz4_?_LzrO71Xqo12sqMwpjlBl1SSrMO@o|;#(*^4RaC;(3J B4>bS) delta 50 zcmZ43&%C6cnd>tzFBbz4JdfDOrO71jub-P&qMwpjlBi!)npcvUn;M^%Sz)xk diff --git a/tests/migration/__pycache__/test_original_item_matcher_transcription.cpython-313-pytest-9.0.2.pyc b/tests/migration/__pycache__/test_original_item_matcher_transcription.cpython-313-pytest-9.0.2.pyc index 57bc99b911a83a21bc5523a2881c057703640a45..505c1f362340bed744922ee137272ba747f43143 100644 GIT binary patch delta 45 zcmcZ-buo(TGcPX}0}%L~-N-dlRK#CDH?KrLC9xz?KP|H&J~2HtuVnKs(OKdESzQmn delta 48 zcmcZ@btQ`HGcPX}0}wom*vK_gR6IyOH?KrLC9xz?zo;~?Br`WPJ}tAtX!CZ_S>gbZ CPZ13O diff --git a/tests/migration/__pycache__/test_original_vas_cancellation_message.cpython-313-pytest-9.0.2.pyc b/tests/migration/__pycache__/test_original_vas_cancellation_message.cpython-313-pytest-9.0.2.pyc index 67a604b521a671883a480a62ac6245c5d58f1bcb..cec548a43c515e602d82462aaefecf974f3f567c 100644 GIT binary patch delta 47 zcmX@Ri}BPhMy}7iyj%=G;CFT-*FiQBU;W&?68)6Kl0^Nq%!>HL^whkP&5zi!!vKE` B5VQaQ delta 50 zcmX@Li}CC(My}7iyj%=G@H}E8*FiS%0R7y&68)6Kl0^NY(!7$)+|>BA%nGB;_t~<; E0J(q?0ssI2 diff --git a/tests/migration/__pycache__/test_original_vas_variation.cpython-313-pytest-9.0.2.pyc b/tests/migration/__pycache__/test_original_vas_variation.cpython-313-pytest-9.0.2.pyc index 0170f18f7e892ee4520e721051dc61cace311e7e..9e1294e4f0821692785020719705150df9f2fe07 100644 GIT binary patch delta 55 zcmdmai(}g@4zACHL^whkPW?rs#UM|M% Jyj)B=$^Z#15cvQA delta 58 zcmdmXi(}_44zACBA%nGAsF0OVi MF2?O#TueI308W+?KmY&$ 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 index 585f22cfc220708ad1f7d2e6a766e7905c24369d..a3b93be0d9737f96d804b95b4bf639e3aec46fff 100644 GIT binary patch delta 47 zcmZ2_iD}U#Ca%xCyj%=G;CFT-*IY3XKmFXi68)6Kl0^Nq%!>HL^whkP&HKdCCjkI= CF%YK! delta 50 zcmZ2ggj68)6Kl0^NY(!7$)+|>BA%nGB;yT#Hc F0RXV>5%d56 diff --git a/tests/migration/__pycache__/test_original_workflow_cases.cpython-313-pytest-9.0.2.pyc b/tests/migration/__pycache__/test_original_workflow_cases.cpython-313-pytest-9.0.2.pyc index 2f30065cc4207db96dea43107e3610ac07e5f4bb..262b0d45765fbdcda81fe98165effc9381675b4d 100644 GIT binary patch delta 47 zcmZ2JiE+s!My}7iyj%=G;CFT-R~xg4vwm(~iGE6ANuqvQW<`8rdTL(D=H<){t^ivI B50(G` delta 50 zcmZ27iE;TPMy}7iyj%=G@H}E8R~xgqn|^LyiGE6ANuqvHXpO~JSSF(92lb;FzTBZ+K delta 48 zcmez1``MT4GcPX}0}woq*vQqwBp#-pn^&Trl30?cUsRe`l9`(tpO#r+w0RMep9%ny CyAY=U diff --git a/tests/migration/__pycache__/test_pro_rata_full_parity.cpython-313-pytest-9.0.2.pyc b/tests/migration/__pycache__/test_pro_rata_full_parity.cpython-313-pytest-9.0.2.pyc index 23596ce460898dc56ecf8871a2a04d48c81f39e2..10311ffdb4f6a0975f8e865152de38eae0d0929b 100644 GIT binary patch delta 47 zcmZ28nQ`T0My}7iyj%=G;CFT-R~D0qgMMyaiGE6ANuqvQW<`8rdTL(D=58iMcK}#} B4+sDN delta 50 zcmZ2EnQ_fzMy}7iyj%=G@GN2@R~D1Fvwm(~iGE6ANuqvHX(t}=%*)Hg00e$#H*&GDiG=9q=9TEDB$g!Vr)5^eC#I+7m26gLdny0`9={FU delta 48 zcmeCw>(S%-%*)Hg00hq>Hgd7CiHGaw=9TEDB$g!V7nSCfWag&Er)5?cZB}7>DgXdd CA`dD6 diff --git a/tests/migration/__pycache__/test_real_legacy_integration_compat.cpython-313-pytest-9.0.2.pyc b/tests/migration/__pycache__/test_real_legacy_integration_compat.cpython-313-pytest-9.0.2.pyc index 4494940b4406e0cca816a7449fb7d40a650026a4..3023a8c050af1ac171247bdad0b9b18d7578da3b 100644 GIT binary patch delta 45 zcmdm&w>yvPGcPX}0}uq9-N@C)DB`7`n^&Trl30?cpO#q>pO~JSSF(9MW4|c?RG1Hr delta 48 zcmdm;w=a+DGcPX}0}wom*vQq#DDJDDn^&Trl30?cUsRe`l9`(tpO#r+w0R9@Pa_X- delta 48 zcmdn*ama(~GcPX}0}veEwvlTmlX!%FZeEFgN@7W(eo<*&NoHMo diff --git a/tests/migration/__pycache__/test_remaining_command_contracts.cpython-313-pytest-9.0.2.pyc b/tests/migration/__pycache__/test_remaining_command_contracts.cpython-313-pytest-9.0.2.pyc index 2e6e762efa444b5d2f476a8360732199ea3fa6a5..11c65b98740c126002b7a6912a3b1d0d663290d8 100644 GIT binary patch delta 45 zcmX?Kc&3o+GcPX}0}%L~-N>cRDB`Z4n^&Trl30?cpO#q>pO~JSSF+iIvE3X1P5BPp delta 48 zcmX?8c)pP9GcPX}0}woq*vO^MDDI`7n^&Trl30?cUsRe`l9`(tpO#r+wAq!h-5daf C&=4yC diff --git a/tests/migration/__pycache__/test_requested_tools_parity_pente_fino.cpython-313-pytest-9.0.2.pyc b/tests/migration/__pycache__/test_requested_tools_parity_pente_fino.cpython-313-pytest-9.0.2.pyc index b03c9c9155ce7c60689f9cb9801bbe6e626bf468..61fa5a4282a390a1a02afdc9d68a55566ba50725 100644 GIT binary patch delta 47 zcmX^5f$`7>My}7iyj%=G;CFT-S0IOouYPV`iGE6ANuqvQW<`8rdTL(D<|2;E`2d0- B5VZgR delta 50 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 F{|&F*$$kI; delta 937 zcmb8tO=uHA6bJCUO(<=W-G*vxi)jMY+HMO?wAe~*7r$Cfja8^0Y1JfaGNxNhQYI6L zQZ0B=)Pp?mB8XlD@n#O5Jru!Hs}x}oPZh6fZl0W%mbBIF}dUj48}8FXe@mW67&ld0%D5Ior5R z2U|N_EHW;vLVk?%0@rcX^TJnj$s_N0HQ)gmCUv~;orW&_>Metg3H1r=!e-UqmdqFO zNppSwb@mc|DWju0-0a7v>P{TfLZM)W3C43)-YN-X&jaJJX`f2eI62LjtFKKP_Xq-B@;!D<0#MYvcOhGVTu7N9$o# z&JEP(RyIfUU}N#e+DY|A^&sc**-*UF(DF`M49h}zH=#>(h4)hKBO;PiB95-L~pVq?xNtOv?y_w;ZyYBEKz&aIZEe= z3q+il#s$9#>B<-X4(DQuW=!JWO5LooR`h?B+VFQxOyohB^Gv z(Hg3?k^0IF;s|k+7$=TncQ683j0b!AX61zK%rdd1cYid?&9k&?7GDK-`)4TD+H#T7 zCE_x!1*1@^^oM+)=q+fb0uaO7sR5Y4*QsL%60|5yFrq}z=g)nFDzO_!a)nIk8Z-E! j9D@88Z#gh#?)65Y>U1dn?@9ooc+VVlSA8BZYFmE;N_68R diff --git a/tests/migration/__pycache__/test_scenario_23_live_internet_balance_guidance.cpython-313-pytest-9.0.2.pyc b/tests/migration/__pycache__/test_scenario_23_live_internet_balance_guidance.cpython-313-pytest-9.0.2.pyc index 78cd7a132f0606e4c944ce0f885cdbfa62badf13..35e1b2d39c33625232659f4c09e9081a14af94a4 100644 GIT binary patch delta 45 zcmZqF`=`tGnU|M~0SE%lZsc0YArhvan^&Trl30?cpO#q>pO~JSSF-sOhdCbrL;Viq delta 48 zcmeyT+o;F&nU|M~0SKN)Y~)(WAs(rpn^&Trl30?cUsRe`l9`(tpO#r+wD~xPIUfLf CaS$*7 diff --git a/tests/migration/__pycache__/test_subject_entity_resolution_all_domains.cpython-313-pytest-9.0.2.pyc b/tests/migration/__pycache__/test_subject_entity_resolution_all_domains.cpython-313-pytest-9.0.2.pyc index 7441458d1bb01217bef26eaf414c747cc7bc462b..9181903d5f6f27e353c8eb269f8e5d50734b648c 100644 GIT binary patch delta 47 zcmX^Ah4IW6My}7iyj%=G;CFT-*IqV}K>ggj68)6Kl0^Nq%!>HL^whkP&G*;}ivg4R B5la97 delta 50 zcmX@}h4K6sMy}7iyj%=G@H}E8*IqX95dGY|68)6Kl0^NY(!7$)+|>BA%nGB;x7iAd E0ngPEnE(I) diff --git a/tests/migration/__pycache__/test_termino_desconto_grounding.cpython-313-pytest-9.0.2.pyc b/tests/migration/__pycache__/test_termino_desconto_grounding.cpython-313-pytest-9.0.2.pyc index fda062208d94e4bd530d85998b7215b45c0d7915..a499a4a6a73cfcdcd9e7d9fa1dc36cee72f7753a 100644 GIT binary patch delta 45 zcmcbuc0-NpGcPX}0}uq9-N@y^DB`A{n^&Trl30?cpO#q>pO~JSSF$;i@sl6`J>CxI delta 48 zcmcbic3X|>GcPX}0}wom*vRFHL^whkP&C)DKqXCOp B5VHUP delta 50 zcmcb+pYg$dMy}7iyj%=G@H}E8*Dq%AVEx>@68)6Kl0^NY(!7$)+|>BA%nGB;5-dlf E0mlXs0RR91 diff --git a/tests/migration/__pycache__/test_tim_contract_parity.cpython-313-pytest-9.0.2.pyc b/tests/migration/__pycache__/test_tim_contract_parity.cpython-313-pytest-9.0.2.pyc index fd354924136f99835afd49ab1e10584d37058193..8a1e5da68ae80a3f11c81484590997e0f4bce19c 100644 GIT binary patch delta 45 zcmZokY)s_(%*)Hg00e$#H*&S}irDMt=9TEDB$g!Vr)5^eC#I+7m26(Ydq)WXJO&Rp delta 48 zcmZonY)Rz$%*)Hg00hq?HgdJ|iaY7&=9TEDB$g!V7nSCfWag&Er)5?cZC=WIM+pFN C=MaSe diff --git a/tests/migration/__pycache__/test_tim_contracts_and_idempotency.cpython-313-pytest-9.0.2.pyc b/tests/migration/__pycache__/test_tim_contracts_and_idempotency.cpython-313-pytest-9.0.2.pyc index b8f80891aa0a7d3f30fc314e894eee929e63ba73..b91757b8de8ee4d611bbe2e5b1d4362333f95b79 100644 GIT binary patch delta 45 zcmX?Dyswz+GcPX}0}%L~-N+TdB;u)`n^&Trl30?cpO#q>pO~JSSF*W~DZm^6PS+0P delta 48 zcmdm2e6X17GcPX}0}woq*vJ*YB<`c1n^&Trl30?cUsRe`l9`(tpO#r+v^kF{z#IUD C>JTyj diff --git a/tests/migration/__pycache__/test_tim_event_metadata_parity.cpython-313-pytest-9.0.2.pyc b/tests/migration/__pycache__/test_tim_event_metadata_parity.cpython-313-pytest-9.0.2.pyc index 6e42081c74d86acd4667413a8b14da10f27b98a0..6ac10d02c8c905461771ebacf20824a64f8ed9e2 100644 GIT binary patch delta 47 zcmX>;f$7KuCa%xCyj%=G;CFT-7cY~DtA1`?iGE6ANuqvQW<`8rdTL(DW<4g!HUL(1 B4!i&W delta 50 zcmX>yf$8`JCa%xCyj%=G@GN2@7cY~zhkkBeiGE6ANuqvHX<{9 diff --git a/tests/migration/__pycache__/test_tim_oos_handoff_bypass.cpython-313-pytest-9.0.2.pyc b/tests/migration/__pycache__/test_tim_oos_handoff_bypass.cpython-313-pytest-9.0.2.pyc index 46a9b842b1c8dd12c97e572eb9455196389d018b..5247e6c805a81f9d8350c1ffee7de22ef1ac63f2 100644 GIT binary patch delta 45 zcmZ2eu(E*bGcPX}0}uq9-N?nrEaIe}n^&Trl30?cpO#q>pO~JSSF%}&nadOaJKhb; delta 48 zcmZ2ku%>|PGcPX}0}woq*vQ4mEbgkGn^&Trl30?cUsRe`l9`(tpO#r+v{{~+%M<`{ CA`ce; diff --git a/tests/migration/__pycache__/test_tool_policy_operation_types.cpython-313-pytest-9.0.2.pyc b/tests/migration/__pycache__/test_tool_policy_operation_types.cpython-313-pytest-9.0.2.pyc index d4852eb2f0dce131a69605fb9b724cce37dc51c0..ebd7a8c74465908432cce8d85b275765e7d05fcc 100644 GIT binary patch delta 45 zcmeyP|5KmqGcPX}0}%L~-N=pO~JSSF*WVsE`!^QAH0E delta 48 zcmeyV|3{zeGcPX}0}woq*vOS7B<`i3n^&Trl30?cUsRe`l9`(tpO#r+w7Em5kQD%k Cnh;?C diff --git a/tests/migration/__pycache__/test_transaction_state_and_vas_prevalidated_subject.cpython-313-pytest-9.0.2.pyc b/tests/migration/__pycache__/test_transaction_state_and_vas_prevalidated_subject.cpython-313-pytest-9.0.2.pyc index 419576459a9ff063fc16b5d1d2cd36d77035578b..8e11d85b92431b78adcde0653afb4e73a677f0e7 100644 GIT binary patch delta 44 ycmezG@W+AcGcPX}0}%L~-N+TkC=#Wgn^&Trl30?cpO#q>pO~JSSF*UCQ62zBx(=-X delta 47 zcmez4@ZW*!GcPX}0}woq*vJ*fC?2byn^&Trl30?cUsRe`l9`(tpO#r+w77;*9sqqC B5BmTB diff --git a/tests/migration/__pycache__/test_vaa_dispute_parity.cpython-313-pytest-9.0.2.pyc b/tests/migration/__pycache__/test_vaa_dispute_parity.cpython-313-pytest-9.0.2.pyc index 2a75bdb055330da0281acd083743639ecd83ba07..394640296970f8091eaec0c41f67bca676e4abd2 100644 GIT binary patch delta 45 zcmcbfeI=XgGcPX}0}%L~-N-eOQN&I^H?KrLC9xz?KP|H&J~2HtuVnKkMpY94T1^i} delta 48 zcmcbTeLb7&GcPX}0}woq*vK`JQQT2KH?KrLC9xz?zo;~?Br`WPJ}tAtX!CkTRTBV` CQxKH^ 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 index eb822d7efef9a620fbe7ee718ebf212aa3263745..f98b08f23423ef0589bda905904389c1bcd01d6a 100644 GIT binary patch delta 45 zcmdn4v_*;QGcPX}0}%L~-N+@*DdMP~n^&Trl30?cpO#q>pO~JSSF+iH^FKQPDoGAO delta 48 zcmdm@v|WkoGcPX}0}woq*vKW$Dej`5n^&Trl30?cUsRe`l9`(tpO#r+wAqyNKRWpO~JSSF(9J6Tcb&KZ*`; delta 48 zcmZ1+xGa$CGcPX}0}woq*vM7JBp#-pn^&Trl30?cUsRe`l9`(tpO#r+w0Q~>zZw8_ Ce-FF> diff --git a/tests/migration/__pycache__/test_workflow_execution_latch.cpython-313-pytest-9.0.2.pyc b/tests/migration/__pycache__/test_workflow_execution_latch.cpython-313-pytest-9.0.2.pyc index e131f1afb061e51bd994304c8557b9793b77d423..c75fdfff59ed8f11e9b8c8b2c99caf74e349254a 100644 GIT binary patch delta 45 zcmZp*X|mz^%*)Hg00e$#H*y6sin!?K=9TEDB$g!Vr)5^eC#I+7m256zoGb$XC#?=4 delta 48 zcmZp&X|>_{%*)Hg00hq>HgW|rio5IQ=9TEDB$g!V7nSCfWag&Er)5?cZO&($ECT>r C+z)O5 diff --git a/tests/migration/__pycache__/test_wrapper_last_contracts.cpython-313-pytest-9.0.2.pyc b/tests/migration/__pycache__/test_wrapper_last_contracts.cpython-313-pytest-9.0.2.pyc index a0abce737e7d3df9d4e48fae21036c4fe11c3fe8..65705074504e9e2c2bfc8d2a2eb57d37db9b6ef8 100644 GIT binary patch delta 47 zcmZ41!MM1Ck?S)rFBbz4_?_LzCBP)&q@SBtqMwpjlBl1SSrMO@o|;#(*^ue0BLGPv B4*~!H delta 50 zcmZ47!MLo0k?S)rFBbz4JdfDOCBP)^s-K%zqMwpjlBi!)npcvUn;M^%Sz)wUkLjx; E0DnIaPyhe` diff --git a/tests/migration/test_no_match_retry_deterministic_clarification.py b/tests/migration/test_no_match_retry_deterministic_clarification.py new file mode 100644 index 0000000..9a76391 --- /dev/null +++ b/tests/migration/test_no_match_retry_deterministic_clarification.py @@ -0,0 +1,24 @@ +from __future__ import annotations + +import pytest + +from app.agents.suporte_contas_agent import SuporteContasAgent + + +class MustNotRunLLM: + async def ainvoke(self, *args, **kwargs): + raise AssertionError("no_match_retry já é decisão de controle e não deve ser reinterpretado") + + +@pytest.mark.asyncio +async def test_no_match_retry_returns_safe_clarification_without_generative_reinterpretation(): + agent = SuporteContasAgent(MustNotRunLLM(), tool_router=None) + state = { + "intent": "contas_no_match_retry", + "user_text": "bota dois planos um em cima do outro pra cá", + "sanitized_input": "bota dois planos um em cima do outro pra cá", + "mcp_tools": [], + "context": {}, + } + result = await agent.run(state) + assert result["answer"] == "Desculpe, não entendi. Poderia repetir de outra forma?" diff --git a/tests/migration/test_revprec_epistemic_uncertainty.py b/tests/migration/test_revprec_epistemic_uncertainty.py index 794ad40..9e8d052 100644 --- a/tests/migration/test_revprec_epistemic_uncertainty.py +++ b/tests/migration/test_revprec_epistemic_uncertainty.py @@ -177,3 +177,61 @@ async def test_revprec_does_not_use_state_or_history_as_authoritative_exact_mess } out = await TimPrematureActionRail().evaluate(text, ctx) assert out.allowed is False + +@pytest.mark.asyncio +async def test_revprec_allows_plain_invoice_explanation_without_llm(): + text = "[FaturasAgent] Analisando a sua fatura atual, a variação foi de R$ 46,99 com Tamboro Mensal de R$ 14,99." + + class MustNotRunLLM: + async def ainvoke(self, *args, **kwargs): + raise AssertionError("explicação informacional não deve ser julgada como execução prematura") + + out = await TimPrematureActionRail().evaluate( + text, + {"guardrail_llm": MustNotRunLLM(), "mcp_results": []}, + ) + assert out.allowed is True + assert out.reason == "no_operational_completion_claim" + assert out.metadata["mechanism"] == "deterministic_claim_scope" + + +@pytest.mark.asyncio +async def test_revprec_allows_composed_contestation_when_current_execution_structurally_proves_claims(): + text = ( + "Sua contestação do valor R$ 14,99 referente ao Tamboro Mensal foi registrada com sucesso. " + "O protocolo aberto é 1234567890. Um novo boleto será emitido e você recebeu um SMS." + ) + + class MustNotRunLLM: + async def ainvoke(self, *args, **kwargs): + raise AssertionError("evidência estrutural suficiente não deve ser re-julgada probabilisticamente") + + ctx = { + "guardrail_llm": MustNotRunLLM(), + "mcp_results": [ + { + "tool_name": "qualquer_tool_transacional", + "ok": True, + "result": { + "status": "COMPLETED", + "output": { + "registrar": { + "success": True, + "contestation_registered": True, + "contested_invoice_amount": "14.99", + "sr": "1234567890", + "sms_sent": True, + "barcode": "34191.79001 01043.510047", + "items": [ + {"itemName": "Tamboro Mensal", "message": "Contestação criada com sucesso"} + ], + } + }, + }, + } + ], + } + out = await TimPrematureActionRail().evaluate(text, ctx) + assert out.allowed is True + assert out.reason == "current_execution_structurally_grounded" + assert out.metadata["mechanism"] == "deterministic_structured_execution_evidence"