From 0a72afb94e171ca769f5d3e3e67d7e14339ba193 Mon Sep 17 00:00:00 2001 From: "cristiano.hoshikawa" Date: Thu, 20 Aug 2026 22:58:25 -0300 Subject: [PATCH] bugfixes: router stickness vs transaction workflow parameters --- FIX_TRANSACTION_INTENT_LOOP.md | 30 +++ FIX_TRANSACTION_PARAMETER_PRECEDENCE.md | 32 +++ .../src/agent_framework.egg-info/SOURCES.txt | 2 + .../__pycache__/__init__.cpython-313.pyc | Bin 391 -> 427 bytes .../__pycache__/idempotency.cpython-313.pyc | Bin 5675 -> 5711 bytes .../__pycache__/observer.cpython-313.pyc | Bin 17571 -> 17571 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 563 -> 563 bytes .../composite_publisher.cpython-313.pyc | Bin 2518 -> 2518 bytes .../__pycache__/event_builder.cpython-313.pyc | Bin 1276 -> 1276 bytes .../__pycache__/factory.cpython-313.pyc | Bin 4012 -> 4012 bytes .../__pycache__/publisher.cpython-313.pyc | Bin 1888 -> 1888 bytes .../tim_payload_mapper.cpython-313.pyc | Bin 9302 -> 9302 bytes .../__pycache__/tim_sequence.cpython-313.pyc | Bin 17577 -> 17577 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 530 -> 530 bytes .../__pycache__/kafka.cpython-313.pyc | Bin 1828 -> 1828 bytes .../__pycache__/langfuse.cpython-313.pyc | Bin 22399 -> 22399 bytes .../__pycache__/oci_streaming.cpython-313.pyc | Bin 1837 -> 1837 bytes .../__pycache__/pubsub.cpython-313.pyc | Bin 7456 -> 7456 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 419 -> 419 bytes .../usage_repository.cpython-313.pyc | Bin 15702 -> 15702 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 193 -> 229 bytes .../cache/__pycache__/cache.cpython-313.pyc | Bin 16503 -> 16539 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 232 -> 232 bytes .../__pycache__/adapters.cpython-313.pyc | Bin 4188 -> 4188 bytes .../channels/__pycache__/base.cpython-313.pyc | Bin 1812 -> 1812 bytes .../__pycache__/gateway.cpython-313.pyc | Bin 5787 -> 5787 bytes .../__pycache__/interruption.cpython-313.pyc | Bin 6472 -> 6472 bytes .../__pycache__/transcription.cpython-313.pyc | Bin 1445 -> 1445 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 939 -> 939 bytes .../checkpoint_repository.cpython-313.pyc | Bin 27179 -> 27179 bytes .../langgraph_saver.cpython-313.pyc | Bin 11254 -> 11260 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 194 -> 230 bytes .../agent_registry.cpython-313.pyc | Bin 6963 -> 6963 bytes .../__pycache__/settings.cpython-313.pyc | Bin 12549 -> 12585 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 286 -> 322 bytes .../mcp_gateway_client.cpython-313.pyc | Bin 3312 -> 3348 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 1517 -> 1517 bytes .../__pycache__/base.cpython-313.pyc | Bin 1391 -> 1391 bytes .../__pycache__/config_loader.cpython-313.pyc | Bin 7265 -> 7265 bytes .../__pycache__/custom_rails.cpython-313.pyc | Bin 4412 -> 4412 bytes .../framework_llm_client.cpython-313.pyc | Bin 18079 -> 18079 bytes .../__pycache__/llm_rails.cpython-313.pyc | Bin 6658 -> 6658 bytes .../output_supervisor.cpython-313.pyc | Bin 16119 -> 16119 bytes .../parallel_executor.cpython-313.pyc | Bin 19927 -> 19927 bytes .../__pycache__/pipeline.cpython-313.pyc | Bin 10905 -> 10905 bytes .../__pycache__/rail_action.cpython-313.pyc | Bin 670 -> 670 bytes .../__pycache__/rail_decision.cpython-313.pyc | Bin 1621 -> 1621 bytes .../__pycache__/rail_result.cpython-313.pyc | Bin 1020 -> 1020 bytes .../__pycache__/rails.cpython-313.pyc | Bin 31612 -> 31612 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 2978 -> 2978 bytes .../__pycache__/_compat.cpython-313.pyc | Bin 2461 -> 2461 bytes .../contestation_validation.cpython-313.pyc | Bin 22870 -> 22886 bytes .../__pycache__/contracts.cpython-313.pyc | Bin 6905 -> 6905 bytes .../__pycache__/input_size.cpython-313.pyc | Bin 3562 -> 3562 bytes .../__pycache__/llm_adapter.cpython-313.pyc | Bin 3815 -> 3815 bytes .../__pycache__/llm_client.cpython-313.pyc | Bin 7349 -> 7349 bytes .../__pycache__/llm_rails.cpython-313.pyc | Bin 8897 -> 8897 bytes .../output_sanitization.cpython-313.pyc | Bin 13926 -> 13926 bytes .../__pycache__/pipeline.cpython-313.pyc | Bin 12667 -> 12667 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 489 -> 489 bytes .../__pycache__/_context.cpython-313.pyc | Bin 5391 -> 5391 bytes .../ausencia_oferta_proativa.cpython-313.pyc | Bin 9580 -> 9580 bytes .../__pycache__/coerencia.cpython-313.pyc | Bin 9496 -> 9496 bytes .../__pycache__/dlex_in.cpython-313.pyc | Bin 1320 -> 1320 bytes .../__pycache__/dlex_out.cpython-313.pyc | Bin 1607 -> 1607 bytes .../__pycache__/fallback.cpython-313.pyc | Bin 17205 -> 17205 bytes .../__pycache__/fraseologia.cpython-313.pyc | Bin 6068 -> 6068 bytes .../__pycache__/out_of_scope.cpython-313.pyc | Bin 17099 -> 17099 bytes .../prompts/__pycache__/pinj.cpython-313.pyc | Bin 8323 -> 8323 bytes .../__pycache__/ragsec.cpython-313.pyc | Bin 1121 -> 1121 bytes .../__pycache__/revprec.cpython-313.pyc | Bin 5422 -> 5422 bytes .../prompts/__pycache__/tox.cpython-313.pyc | Bin 645 -> 645 bytes .../toxicidade_output.cpython-313.pyc | Bin 939 -> 939 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 1683 -> 1683 bytes .../rails/__pycache__/alcada.cpython-313.pyc | Bin 5015 -> 5015 bytes .../rails/__pycache__/anatel.cpython-313.pyc | Bin 9164 -> 9164 bytes .../__pycache__/confirmation.cpython-313.pyc | Bin 11032 -> 11032 bytes .../rails/__pycache__/dlex_in.cpython-313.pyc | Bin 3295 -> 3295 bytes .../__pycache__/dlex_out.cpython-313.pyc | Bin 3347 -> 3347 bytes .../rails/__pycache__/ragsec.cpython-313.pyc | Bin 5429 -> 5429 bytes .../rails/__pycache__/revprec.cpython-313.pyc | Bin 5437 -> 5437 bytes .../rails/__pycache__/tox.cpython-313.pyc | Bin 8252 -> 8252 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 553 -> 553 bytes .../rules/__pycache__/alcada.cpython-313.pyc | Bin 1897 -> 1897 bytes .../__pycache__/pinj_patterns.cpython-313.pyc | Bin 3738 -> 3738 bytes .../__pycache__/tox_blocklist.cpython-313.pyc | Bin 1522 -> 1522 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 388 -> 424 bytes .../__pycache__/mcp_mapper.cpython-313.pyc | Bin 4672 -> 4708 bytes .../__pycache__/models.cpython-313.pyc | Bin 3124 -> 3160 bytes .../__pycache__/resolver.cpython-313.pyc | Bin 4693 -> 4729 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 634 -> 634 bytes .../judges/__pycache__/judge.cpython-313.pyc | Bin 36448 -> 36448 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 241 -> 241 bytes .../__pycache__/llm_client.cpython-313.pyc | Bin 6118 -> 6118 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 249 -> 249 bytes .../prompts/__pycache__/aluc.cpython-313.pyc | Bin 6464 -> 6464 bytes .../prompts/__pycache__/csi.cpython-313.pyc | Bin 1333 -> 1333 bytes .../__pycache__/fallback.cpython-313.pyc | Bin 8029 -> 8029 bytes .../prompts/__pycache__/rqlt.cpython-313.pyc | Bin 1171 -> 1171 bytes .../prompts/__pycache__/vctn.cpython-313.pyc | Bin 642 -> 642 bytes .../llm/__pycache__/__init__.cpython-313.pyc | Bin 227 -> 227 bytes .../llm/__pycache__/base.cpython-313.pyc | Bin 835 -> 835 bytes .../profile_resolver.cpython-313.pyc | Bin 9295 -> 9295 bytes .../llm/__pycache__/providers.cpython-313.pyc | Bin 35982 -> 35982 bytes .../mcp/__pycache__/__init__.cpython-313.pyc | Bin 453 -> 489 bytes .../mcp/__pycache__/client.cpython-313.pyc | Bin 18406 -> 18442 bytes .../mcp/__pycache__/models.cpython-313.pyc | Bin 2116 -> 2152 bytes .../mcp/__pycache__/registry.cpython-313.pyc | Bin 4720 -> 4756 bytes .../__pycache__/tool_policy.cpython-313.pyc | Bin 5647 -> 5701 bytes .../__pycache__/tool_router.cpython-313.pyc | Bin 14169 -> 14205 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 1115 -> 1151 bytes .../long_term_extractor.cpython-313.pyc | Bin 2529 -> 2529 bytes .../long_term_memory.cpython-313.pyc | Bin 6855 -> 6855 bytes .../long_term_models.cpython-313.pyc | Bin 1764 -> 1764 bytes .../long_term_store.cpython-313.pyc | Bin 29202 -> 29202 bytes .../message_history.cpython-313.pyc | Bin 8339 -> 8375 bytes .../summary_memory.cpython-313.pyc | Bin 12490 -> 12526 bytes .../__pycache__/summary_store.cpython-313.pyc | Bin 9500 -> 9536 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 194 -> 230 bytes .../__pycache__/identity.cpython-313.pyc | Bin 3481 -> 3481 bytes .../__pycache__/session.cpython-313.pyc | Bin 2688 -> 2724 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 1410 -> 1410 bytes .../__pycache__/context.cpython-313.pyc | Bin 7402 -> 7402 bytes .../__pycache__/event_bus.cpython-313.pyc | Bin 3648 -> 3648 bytes .../guardrail_events.cpython-313.pyc | Bin 2066 -> 2066 bytes .../__pycache__/ic_events.cpython-313.pyc | Bin 641 -> 641 bytes .../__pycache__/judge_events.cpython-313.pyc | Bin 1426 -> 1426 bytes .../langgraph_telemetry.cpython-313.pyc | Bin 4979 -> 4979 bytes .../__pycache__/llm_advisors.cpython-313.pyc | Bin 2953 -> 2953 bytes .../__pycache__/noc_contract.cpython-313.pyc | Bin 5090 -> 5090 bytes .../__pycache__/noc_otel.cpython-313.pyc | Bin 6337 -> 6337 bytes .../__pycache__/observer.cpython-313.pyc | Bin 4709 -> 4709 bytes .../__pycache__/otel.cpython-313.pyc | Bin 3427 -> 3427 bytes .../streaming_events.cpython-313.pyc | Bin 1850 -> 1850 bytes .../__pycache__/telemetry.cpython-313.pyc | Bin 51538 -> 51538 bytes .../__pycache__/token_cost.cpython-313.pyc | Bin 8612 -> 8612 bytes .../workflow_events.cpython-313.pyc | Bin 3345 -> 3345 bytes .../oci/__pycache__/__init__.cpython-313.pyc | Bin 227 -> 227 bytes .../oci/__pycache__/auth.cpython-313.pyc | Bin 3259 -> 3259 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 199 -> 235 bytes .../__pycache__/oracle_store.cpython-313.pyc | Bin 44971 -> 44971 bytes .../__pycache__/sqlite_store.cpython-313.pyc | Bin 14998 -> 15034 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 465 -> 470 bytes .../__pycache__/renderers.cpython-313.pyc | Bin 4328 -> 4333 bytes .../rag/__pycache__/__init__.cpython-313.pyc | Bin 725 -> 725 bytes .../embedding_provider.cpython-313.pyc | Bin 6542 -> 6542 bytes .../__pycache__/graph_store.cpython-313.pyc | Bin 5543 -> 5543 bytes .../rag/__pycache__/ingest.cpython-313.pyc | Bin 12596 -> 12596 bytes .../__pycache__/rag_service.cpython-313.pyc | Bin 10065 -> 10065 bytes .../__pycache__/vector_store.cpython-313.pyc | Bin 18671 -> 18671 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 236 -> 236 bytes .../session_repository.cpython-313.pyc | Bin 8605 -> 8605 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 405 -> 441 bytes .../__pycache__/config_loader.cpython-313.pyc | Bin 2276 -> 2312 bytes .../__pycache__/continuity.cpython-313.pyc | Bin 13218 -> 13254 bytes .../enterprise_router.cpython-313.pyc | Bin 18938 -> 26354 bytes .../__pycache__/models.cpython-313.pyc | Bin 2426 -> 2462 bytes .../routing/enterprise_router.py | 141 ++++++++++- .../__pycache__/__init__.cpython-313.pyc | Bin 328 -> 364 bytes .../__pycache__/agent_runtime.cpython-313.pyc | Bin 137406 -> 140322 bytes .../agent_framework/runtime/agent_runtime.py | 48 ++++ .../sse/__pycache__/__init__.cpython-313.pyc | Bin 227 -> 227 bytes .../sse/__pycache__/events.cpython-313.pyc | Bin 9603 -> 9603 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 234 -> 234 bytes .../__pycache__/supervisor.cpython-313.pyc | Bin 4704 -> 4704 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 858 -> 894 bytes .../__pycache__/graph.cpython-313.pyc | Bin 1395 -> 1431 bytes .../__pycache__/models.cpython-313.pyc | Bin 5212 -> 5248 bytes .../__pycache__/registry.cpython-313.pyc | Bin 2341 -> 2377 bytes .../__pycache__/repository.cpython-313.pyc | Bin 2694 -> 2730 bytes .../__pycache__/runtime.cpython-313.pyc | Bin 29107 -> 29143 bytes .../__pycache__/tool_executor.cpython-313.pyc | Bin 1946 -> 1982 bytes .../conftest.cpython-313-pytest-9.0.2.pyc | Bin 787 -> 807 bytes ..._interruption.cpython-313-pytest-9.0.2.pyc | Bin 0 -> 15037 bytes ...nal_tool_flow.cpython-313-pytest-9.0.2.pyc | Bin 53813 -> 68115 bytes ...t_transaction_state_router_interruption.py | 218 ++++++++++++++++++ tests/test_transactional_tool_flow.py | 66 ++++++ 177 files changed, 534 insertions(+), 3 deletions(-) create mode 100644 FIX_TRANSACTION_INTENT_LOOP.md create mode 100644 FIX_TRANSACTION_PARAMETER_PRECEDENCE.md create mode 100644 tests/__pycache__/test_transaction_state_router_interruption.cpython-313-pytest-9.0.2.pyc create mode 100644 tests/test_transaction_state_router_interruption.py diff --git a/FIX_TRANSACTION_INTENT_LOOP.md b/FIX_TRANSACTION_INTENT_LOOP.md new file mode 100644 index 0000000..aeb8345 --- /dev/null +++ b/FIX_TRANSACTION_INTENT_LOOP.md @@ -0,0 +1,30 @@ +# Correção: escape de estado transacional / mudança de intenção + +Correção aplicada em 2026-08-20 para impedir que uma sessão fique presa em `COLLECTING_PARAMETERS` ou `AWAITING_CONFIRMATION` quando o usuário muda explicitamente de assunto. + +## Comportamento corrigido + +Antes: + +1. uma transação entrava em `COLLECTING_PARAMETERS`; +2. `next_state` forçava o mesmo agente via `state_policies`; +3. toda mensagem seguinte era tratada como tentativa de preencher o parâmetro faltante; +4. uma nova intenção como `quais sao meus servicos` permanecia presa no fluxo anterior. + +Agora: + +- o `EnterpriseRouter` verifica mudança explícita de intenção antes de aplicar o lock de estado; +- keyword explícita tem prioridade; +- quando necessário, o LLM router pode detectar mudança com confiança >= `router.confidence_threshold`; +- a decisão recebe `metadata.transaction_interruption=intent_shift`; +- o runtime encerra a transação pendente como `CANCELLED`, limpa `next_state`, parâmetros e latches, e prossegue com a nova intent; +- cancelamentos explícitos como `cancele essa operação anterior` funcionam também durante `COLLECTING_PARAMETERS`. + +## Testes adicionados + +- mudança de intent durante `COLLECTING_PARAMETERS`; +- resposta curta/baixa confiança permanece na transação; +- cancelamento explícito durante coleta de parâmetros; +- limpeza do estado transacional antes de executar a nova intent. + +Testes focados: 19 passed. diff --git a/FIX_TRANSACTION_PARAMETER_PRECEDENCE.md b/FIX_TRANSACTION_PARAMETER_PRECEDENCE.md new file mode 100644 index 0000000..ccdaabe --- /dev/null +++ b/FIX_TRANSACTION_PARAMETER_PRECEDENCE.md @@ -0,0 +1,32 @@ +# Transaction parameter precedence fix + +Correção para a regressão em que uma resposta curta que preenchia um parâmetro pendente (ex.: `R$ 71,99` para `valor`) era classificada pelo LLM Router como uma nova intent e interrompia a transação. + +## Regra aplicada + +Durante `COLLECTING_PARAMETERS` a ordem passa a ser: + +1. resposta compatível com parâmetro pendente -> mantém a política de estado e continua a transação; +2. cancelamento explícito -> cancela a transação; +3. nova intenção clara/pergunta explícita -> interrompe a transação e volta ao roteamento normal; +4. caso ambíguo -> permanece em clarificação. + +Exemplo corrigido: + +```text +não fiz essa contratação TIM CTRL Redes Sociais 8.0 +-> informe valor +R$ 71,99 +-> valor=71.99; continua contestar_cobranca; executa pré-validação +``` + +A mensagem `R$ 71,99` não pode mais virar `contas_invoice_explanation` enquanto `valor` estiver pendente. + +## Testes + +Foram adicionados testes para: + +- valor monetário com LLM sugerindo outra intent; +- entidade curta como resposta de parâmetro; +- pergunta clara durante coleta ainda interrompendo a transação; +- regressões existentes de intent-shift e transactional tool flow. diff --git a/libs/agent_framework/src/agent_framework.egg-info/SOURCES.txt b/libs/agent_framework/src/agent_framework.egg-info/SOURCES.txt index a8fbb5a..723d0a0 100644 --- a/libs/agent_framework/src/agent_framework.egg-info/SOURCES.txt +++ b/libs/agent_framework/src/agent_framework.egg-info/SOURCES.txt @@ -179,6 +179,8 @@ src/agent_framework/persistence/__init__.py src/agent_framework/persistence/mongodb_store.py src/agent_framework/persistence/oracle_store.py src/agent_framework/persistence/sqlite_store.py +src/agent_framework/presentation/__init__.py +src/agent_framework/presentation/renderers.py src/agent_framework/rag/__init__.py src/agent_framework/rag/embedding_provider.py src/agent_framework/rag/graph_store.py diff --git a/libs/agent_framework/src/agent_framework/__pycache__/__init__.cpython-313.pyc b/libs/agent_framework/src/agent_framework/__pycache__/__init__.cpython-313.pyc index 3cfa30e4be70334240562717a89ef051441e20cc..4712f5d8fcfdaea384ab2a1595080cdf727a1dc5 100644 GIT binary patch delta 78 zcmZo?Ud_z?nU|M~0SK-+wol}KZ&s(Dn^&TrqVF5*86QxTpOuEwiY&BtAJm cuOzWJJ~uPHC^02pKQTQu4<@+zIg^Vp09?EsJOBUy delta 44 ycmX@Fvs#DyGcPX}0}%ZC*0PcN6q8V_er{fgeoA6VqJEj7Nm^-6&Sq|A7hwQTa}Iz2 diff --git a/libs/agent_framework/src/agent_framework/__pycache__/observer.cpython-313.pyc b/libs/agent_framework/src/agent_framework/__pycache__/observer.cpython-313.pyc index 7d09d8707cbdc33a7e9b6a796c4b7dd450346e7d..4430e9493b93734b95847525a791892098f07ce3 100644 GIT binary patch delta 22 ccmZ47$+)GcPX}0}xzyY~RSekRJd%`~}1S delta 20 acmZ1@zeb+>GcPX}0}%ZC*0Pa%AwK{@JO-Tr diff --git a/libs/agent_framework/src/agent_framework/analytics/__pycache__/publisher.cpython-313.pyc b/libs/agent_framework/src/agent_framework/analytics/__pycache__/publisher.cpython-313.pyc index 9d2f0df1359a391111730f96c25e61b341f80b27..acba0d979e800ee30a952c335c1c26bae3e784a6 100644 GIT binary patch delta 20 acmaFB_kfT4GcPX}0}xzyY~RQo$_@ZQum!dN delta 20 acmaFB_kfT4GcPX}0}%ZC*0Pa1lpO#@@CJ_n diff --git a/libs/agent_framework/src/agent_framework/analytics/__pycache__/tim_payload_mapper.cpython-313.pyc b/libs/agent_framework/src/agent_framework/analytics/__pycache__/tim_payload_mapper.cpython-313.pyc index 02c8aaed6e7264a116ff223eb8127e7211707c12..523b49d5ab2a02b73101b8730443f685edae834a 100644 GIT binary patch delta 20 acmccSam|DKGcPX}0}xzyY~RT3tpWf@WdzS0Ahv*r2qf` delta 22 ccmeyrj`9CGM()qNyj%=G@b6p8M(&bu0B6PsegFUf diff --git a/libs/agent_framework/src/agent_framework/analytics/providers/__pycache__/oci_streaming.cpython-313.pyc b/libs/agent_framework/src/agent_framework/analytics/providers/__pycache__/oci_streaming.cpython-313.pyc index 845679941d7318147b0afe7f1072a38098b365d5..c4c23442cfe0ef8c15efe694c467ef1372ae4ec9 100644 GIT binary patch delta 20 acmZ3>x0a9lGcPX}0}xzyY~RSO#0~&CxCI>m delta 20 acmZ3>x0a9lGcPX}0}%ZC*0PaXi5&nw_yzU= diff --git a/libs/agent_framework/src/agent_framework/analytics/providers/__pycache__/pubsub.cpython-313.pyc b/libs/agent_framework/src/agent_framework/analytics/providers/__pycache__/pubsub.cpython-313.pyc index b7d99e41bf2eca7ed441ae2bbef326d2bbd6e646..808c2d40df0d896392165f356ec175601828ee0d 100644 GIT binary patch delta 20 acmZ2rwZMw|GcPX}0}xzyY~RQ&DhmKT_61}B delta 20 acmZ2rwZMw|GcPX}0}%ZC*0PaXR2Be3HU>Qa diff --git a/libs/agent_framework/src/agent_framework/billing/__pycache__/__init__.cpython-313.pyc b/libs/agent_framework/src/agent_framework/billing/__pycache__/__init__.cpython-313.pyc index f4a8983e928abc9bfa99e8918c760487eaf3018f..9a35255f09b03903ff9f2fb29ffde0cbc48118f5 100644 GIT binary patch delta 20 acmZ3?yqKB$GcPX}0}xzuY~RQ|gAo8Xj|E}? delta 20 acmZ3?yqKB$GcPX}0}%ZC*0Pa%1|tAG)&@KP diff --git a/libs/agent_framework/src/agent_framework/billing/__pycache__/usage_repository.cpython-313.pyc b/libs/agent_framework/src/agent_framework/billing/__pycache__/usage_repository.cpython-313.pyc index 67c4c0c652ce177c8b73fff5f4f0ac0ae078173e..7fd6d10d69b29d3f606831714c360951e445e4bf 100644 GIT binary patch delta 20 acmcasb*+l~GcPX}0}xzuY~RT3Z3_TTe+H!h delta 20 acmcasb*+l~GcPX}0}%ZC*0Pb?+ZF&+#s_}@ diff --git a/libs/agent_framework/src/agent_framework/cache/__pycache__/__init__.cpython-313.pyc b/libs/agent_framework/src/agent_framework/cache/__pycache__/__init__.cpython-313.pyc index 6b482c02b1f657dfaf55c46d27d3467e6fd84801..13fc77ffed208e823b528b6d033a8d9bf41529ee 100644 GIT binary patch delta 77 zcmX@e_>__RGcPX}0}xzyY@f(&Y}TTmn^&TrqVF5*86QxTpOucSR9|5nO>BblCPhbo|*>}+-$()ZU+Ev5FEe& delta 46 zcmbQ;$oRd1k^3_*FBbz4{QK6jkz1HaC{{l=uS7p3u_RHy%+MsQG$&_s2$Q=V0AY9! A0ssI2 diff --git a/libs/agent_framework/src/agent_framework/channels/__pycache__/__init__.cpython-313.pyc b/libs/agent_framework/src/agent_framework/channels/__pycache__/__init__.cpython-313.pyc index 4e948c1afc6b849c683285102f4c01ee1c34b8b5..0976dfd5e7d50c345f8a072c978069773f9a6d2e 100644 GIT binary patch delta 19 ZcmaFC_=1u9GcPX}0}xzyY@f(|7XUkm1`PlJ delta 19 ZcmaFC_=1u9GcPX}0}%ZC)-sX%E&xC82Ic?& diff --git a/libs/agent_framework/src/agent_framework/channels/__pycache__/adapters.cpython-313.pyc b/libs/agent_framework/src/agent_framework/channels/__pycache__/adapters.cpython-313.pyc index df8eb6f901dee950808700d852a36ce3bb4ccbaa..5ae3b7175e1d75b8a8bfc63925b763e48e092138 100644 GIT binary patch delta 20 acmcbka7TgrGcPX}0}xzyY~RQoC;$LMp#|3f delta 20 acmcbka7TgrGcPX}0}%ZC*0Pa1Pyhf(;Rdh( diff --git a/libs/agent_framework/src/agent_framework/channels/__pycache__/base.cpython-313.pyc b/libs/agent_framework/src/agent_framework/channels/__pycache__/base.cpython-313.pyc index 337545bc9bad56af04b3b296c7c3d2ef77da118b..cfb37af7520e16e6a0f3748db022d33453f5ae75 100644 GIT binary patch delta 20 acmbQjH-(S;GcPX}0}xzyY~RSu$qoQD&;-%| delta 20 acmbQjH-(S;GcPX}0}%ZC*0PbClN|s%5Cy9M diff --git a/libs/agent_framework/src/agent_framework/channels/__pycache__/gateway.cpython-313.pyc b/libs/agent_framework/src/agent_framework/channels/__pycache__/gateway.cpython-313.pyc index 3871ce3533a72d6f597c784b09de06fc3c3a2e61..91f0fe45c8545b0c2d03ce81352f95f6d3cc7cce 100644 GIT binary patch delta 20 acmbQOJ6o6gGcPX}0}xzyY~RQ|K@0#qQw6jD delta 20 acmbQOJ6o6gGcPX}0}%ZC*0Pa%f*1fnlLn0d diff --git a/libs/agent_framework/src/agent_framework/channels/__pycache__/interruption.cpython-313.pyc b/libs/agent_framework/src/agent_framework/channels/__pycache__/interruption.cpython-313.pyc index 3e20c90c65eaa7813186958fc3cd52acec98a8dd..eb2b02cd5c39d6db27cd03e3a9efeebe7c4d5e41 100644 GIT binary patch delta 20 acmX?Mbi#=HGcPX}0}xzyY~RRjD+vHY5(UTr delta 20 acmX?Mbi#=HGcPX}0}%ZC*0Pb?RuTY6QU;*_ diff --git a/libs/agent_framework/src/agent_framework/channels/__pycache__/transcription.cpython-313.pyc b/libs/agent_framework/src/agent_framework/channels/__pycache__/transcription.cpython-313.pyc index ebad7aea0b867a8a77f695e372861465e7d5f8de..06ba8a40b0c68eb6517d4b9b50b69a954e40571a 100644 GIT binary patch delta 20 acmZ3=y_B2#GcPX}0}xzyY~RQ|ixmJl3I%-t delta 20 acmZ3=y_B2#GcPX}0}%ZC*0Pa%7ApWgN(NQ{ diff --git a/libs/agent_framework/src/agent_framework/checkpoints/__pycache__/__init__.cpython-313.pyc b/libs/agent_framework/src/agent_framework/checkpoints/__pycache__/__init__.cpython-313.pyc index c0e39fddda8471bb59580f24c1b4a390d1545b92..3aa66129c2539d8d9920ce0c299e58efc956ce64 100644 GIT binary patch delta 20 acmZ3@zM7r;GcPX}0}xzyY~RSefEfTeXa$7; delta 20 acmZ3@zM7r;GcPX}0}%ZC*0Pa%0W$zTs0LmD diff --git a/libs/agent_framework/src/agent_framework/checkpoints/__pycache__/checkpoint_repository.cpython-313.pyc b/libs/agent_framework/src/agent_framework/checkpoints/__pycache__/checkpoint_repository.cpython-313.pyc index 9111f5b4d3b526c5e5334b5a2c74fa854710a16d..999653a66c11c81a38fc4ddb20db41fa7a7bbfed 100644 GIT binary patch delta 22 ccmZ2|g>m&2M()qNyj%=GaNV(eBey~p09r=}2mk;8 delta 22 ccmZ2|g>m&2M()qNyj%=G@b6p8Ms9^H0AGg(;Q#;t diff --git a/libs/agent_framework/src/agent_framework/checkpoints/__pycache__/langgraph_saver.cpython-313.pyc b/libs/agent_framework/src/agent_framework/checkpoints/__pycache__/langgraph_saver.cpython-313.pyc index 3612f13c404d4871e1f5c1a85675c912cd390db2..32e257d5f9a616033ead573dcf0245528cc37cc6 100644 GIT binary patch delta 80 zcmews{wJLKGcPX}0}xzyY~RSeiqUMMer{fgeu}G#c0s2pPN^rpORRTsGpdgnpYB^oS#>cSR4;zrxs-< b#}}m*7v$#^r^c6A#Fyt6Wp94XD5wPh?_(Rr diff --git a/libs/agent_framework/src/agent_framework/config/__pycache__/__init__.cpython-313.pyc b/libs/agent_framework/src/agent_framework/config/__pycache__/__init__.cpython-313.pyc index b0c36ce82399b3e3b59b9ba7202c7a28ce6e46b0..881b18d68cad100bc8db3cad5062a756007f39f3 100644 GIT binary patch delta 77 zcmX@a_>7VJGcPX}0}xzyY@f(&Y}Trun^&TrqVF5*86QxTpOu=_?Wl%JKFTvDu`mRVF>5}%x( cSCUv9pPQLpl$esQpO~JS2NT?UT+NOP0B8ywS^xk5 delta 44 ycmZ3P)SATonU|M~0SNwmYuU)XN=+zHKR2&LKP9mwQNPU4B&{?jXY*?{J1ziN+Yg)o diff --git a/libs/agent_framework/src/agent_framework/gateways/__pycache__/__init__.cpython-313.pyc b/libs/agent_framework/src/agent_framework/gateways/__pycache__/__init__.cpython-313.pyc index 702723acdebf05b5496660fefa070628f7ede7fe..81ca480f23fb56b257b4521316ce626015cee809 100644 GIT binary patch delta 77 zcmbQobcl)jGcPX}0}xzyY@f*8WY(^qn^&TrqVF5*86QxTpOu?h#g diff --git a/libs/agent_framework/src/agent_framework/gateways/__pycache__/mcp_gateway_client.cpython-313.pyc b/libs/agent_framework/src/agent_framework/gateways/__pycache__/mcp_gateway_client.cpython-313.pyc index cfc5b653c2502992bd837bd70bac321674e430d8..a907c01a89852a6845c0d5974ed43d58a32964bb 100644 GIT binary patch delta 80 zcmew$IYo;5GcPX}0}xzyY~RRzg3)ZEer{fgeu}i_@% delta 44 ycmbOt^+A&RGcPX}0}%ZC*0PcN1fx){er{fgeoA6VqJEj7Nm^-6&Sp*~Zf*ceE)FgL diff --git a/libs/agent_framework/src/agent_framework/guardrails/__pycache__/__init__.cpython-313.pyc b/libs/agent_framework/src/agent_framework/guardrails/__pycache__/__init__.cpython-313.pyc index f275cd05fe4638d1c1bb8182e174595549c50593..021dd457d5f683050dad1057db5456f99573b307 100644 GIT binary patch delta 20 acmaFM{g#{iGcPX}0}xzyY~RTJh!p@tN(NN` delta 20 acmaFM{g#{iGcPX}0}%ZC*0PcN5i0;miU%$L diff --git a/libs/agent_framework/src/agent_framework/guardrails/__pycache__/base.cpython-313.pyc b/libs/agent_framework/src/agent_framework/guardrails/__pycache__/base.cpython-313.pyc index 8a466f4afb13e3adf086ca5a582581813087896c..4f3aafa75b1094ac80e3f6c77dc8fc28a759ef11 100644 GIT binary patch delta 20 acmaFQ^`49SGcPX}0}xzyY~RS8!U_OGb_Ll0 delta 20 acmaFQ^`49SGcPX}0}%ZC*0Pa1g%touwg$2Q diff --git a/libs/agent_framework/src/agent_framework/guardrails/__pycache__/config_loader.cpython-313.pyc b/libs/agent_framework/src/agent_framework/guardrails/__pycache__/config_loader.cpython-313.pyc index 26b9c5f88e8260f004563baa03e6bf762e30f6ac..2a53378b83a82823e6bae191a60390428c855dc9 100644 GIT binary patch delta 20 acmaE8@z8?%GcPX}0}xzyY~RQoCIbLR)dnH} delta 20 acmaE8@z8?%GcPX}0}%ZC*0Pa1Oa=f=6$bkN diff --git a/libs/agent_framework/src/agent_framework/guardrails/__pycache__/custom_rails.cpython-313.pyc b/libs/agent_framework/src/agent_framework/guardrails/__pycache__/custom_rails.cpython-313.pyc index 1edd310ea7f378ba0453ad437234d8b4179e5bed..dfaaa74bffe54012d051ceaa7bf1439dd223ed19 100644 GIT binary patch delta 20 acmdm^v`2~iGcPX}0}xzyY~RRjCIHlN delta 20 acmdm^v`2~iGcPX}0}%ZC*0Pb?P!Iq_Dh5>m diff --git a/libs/agent_framework/src/agent_framework/guardrails/__pycache__/framework_llm_client.cpython-313.pyc b/libs/agent_framework/src/agent_framework/guardrails/__pycache__/framework_llm_client.cpython-313.pyc index 3ac51858ed79bc5fdf56683fc432676c9802d92d..5cd9c995d7cf70157fee7b419f296da05c682321 100644 GIT binary patch delta 22 ccmbQ=%Q(N6k^3_*FBbz4Tz72W$UVgk08UN@vH$=8 delta 22 ccmbQ=%Q(N6k^3_*FBbz4{QK6jk$Z|808@?!ivR!s diff --git a/libs/agent_framework/src/agent_framework/guardrails/__pycache__/llm_rails.cpython-313.pyc b/libs/agent_framework/src/agent_framework/guardrails/__pycache__/llm_rails.cpython-313.pyc index f78d6e3e7b0de80c87056eba054b62d094a39e1c..8f332b011c7ebd9e582160793c95c306aeb14307 100644 GIT binary patch delta 20 acmZoNX)@vd%*)Hg00h?^+c$E5mjnPhY6bcL delta 20 acmZoNX)@vd%*)Hg00jTOwQS`6E(riXss_^l diff --git a/libs/agent_framework/src/agent_framework/guardrails/__pycache__/output_supervisor.cpython-313.pyc b/libs/agent_framework/src/agent_framework/guardrails/__pycache__/output_supervisor.cpython-313.pyc index 03df7c18c9f1a5a5b415d444b5200ad6879325ff..8d7b6d4a6b9a94b676b0650efb3f3dc8fefa523d 100644 GIT binary patch delta 20 acmexf`@NR?GcPX}0}xzyY~RTJ#tr~h8wZd8 delta 20 acmexf`@NR?GcPX}0}%ZC*0PcNjU516TL@_Y diff --git a/libs/agent_framework/src/agent_framework/guardrails/__pycache__/parallel_executor.cpython-313.pyc b/libs/agent_framework/src/agent_framework/guardrails/__pycache__/parallel_executor.cpython-313.pyc index 1105f132d9b9b87c540292746fe224fdbcdcb185..52cc5dac968229caae91d154e44577bd795eb8ce 100644 GIT binary patch delta 22 ccmcaUoALT=M()qNyj%=GaNV(eBlj6!09oG$eE_Xg_# diff --git a/libs/agent_framework/src/agent_framework/guardrails/__pycache__/rail_action.cpython-313.pyc b/libs/agent_framework/src/agent_framework/guardrails/__pycache__/rail_action.cpython-313.pyc index 083aa866cf066140f3aecb4e4a1847ad3ba117db..15c2696bb1c11294719b3e7c05f42396746fce47 100644 GIT binary patch delta 20 acmbQoI**n6GcPX}0}xzyY~RQ|nF#SR@QeNOvn?Rl80ak6XW7$F|_EQYRb4M@yTfL0%J{#PlzMLE4=W?~TP2=!e7jK&6X~8~ZB<7@IP(HlDE-O_L%M)E?0L_z7T! zuYK?;M|ce{ROMOVb^NQkik(JRjm!?Bzou*TB+tHRg5)AOgyXPiSUd%+Y>q@UJ2*vo z1_$WNX4)eOH5Q2KVK{~L4Nf+J_cshX#KmkP^~q-%N7=M7*63x0TP(!vB@oUSqDXKv zhGnbDq^m@HkFn;$x_vw}SH;z!q6fN_L@y|?pD0Hn(sP4(iu9tCC_031G<(<&_;>R| z(vOt-1;Z_~xj#|(Gr=na(^$7{W`j72Sc^3E>f>{Blfp(&Pe6{yN7*~V=I~>0g_Ils zE_+*88aB69Fot?-!tpX`Qx=k7nGF`xrnCmk5!jwSe)7H#%pRTFgo8NHq+AX0-F!5kK0hJ{lt$&yB0F?3!d`loA z8~v2TK`sFC&glsVH^FBVjT0>3V!J0q-T{r^QvxT!5&^v*d2RANrEF=E`H?)1i*xHyqeL=rk$(g5V0l9)d-J2`u(Cu{ zYn7M{Pj%#TJl9dOUYsJIP9Z@RDKqF;)fA;pnU9W6=Ncg;k`J&zNC|9scV}@>QXN-2daQ@x8zmu}jVNtMLlY&h1nmmR@Mze`%6elB9b nzmARI6aKr(g-gVrzOafg2st3>g*+;96qo!3ti<@!znlF7G0?|6 delta 1744 zcmZ`)Yitx%6y~zs>C&Z88Y_JTOKF7BzGw?6(HaZV+HUQyK1>WOsg%*@PKB0k>O!EygqPvuBOEN)eVHA}0|y7jmf3>k4tGlPQb6bS`M zH+zh@sRw(v1p5ryZ4Y?9TvK>vsVLznT5lq18jfE#Ez&H#I}$SJ0N+#Gpd1i+I>;{+ zUuJ{+#dTYhVFZTlZ`b|kVaM#*_4}AIg3xi^t~TWy15Fd)_@Y|8yDMSpbb{Mzo!=E9 zeS-g~RoP=T-={;ohYGH#;i*+l#CXim|Gl3lM8-iAHbz@Pc|06Z93aa|a7GI7>bVH+js5+mG@nm($ zrX+MPLE&@z%?N4na70{*ZW4+(S-n~m>xdB#>O=<7#Nis9UA4Pvp7)o%DI`y1lnnP--qwMa}sN19~ zwy!>yJum|ihDNU-&*bz~uj7kYdMp?rw#WI-ts{PUcQq(+ ziYwcaY|Q>1jco<)$9ej9`~$B}k(~2>Go@ z&+W)l&`bO62OH!U8|v8&zOwOgS`R!c?)z;-F9K!(9{{BM zeK5F_J`|uT*6JxRcgu#C2iN??mvA72!z8dQ80e z(xUo!{|mU z-vjypR{-O@qV*w`V_U7w3RC#mwj6Q{0JDC{zih569XFRt#|Syr4aQwWJ7& z0p=oy`H{j~+V2Xy*! zSbH3`a#2QhgYNz@*lHQ&bsdF4=^J;Apgd28YeN~8UX*M>DP6hHyS#K|(Vh%cl7mzD zRL1~&f#2U*rd&clbKK}$!;*Zs^S%=468Vo{6e(#CIKcHn4vHM*H#&3KT3dN^7yBC| CRMAfW diff --git a/libs/agent_framework/src/agent_framework/guardrails/calibrated/__pycache__/contracts.cpython-313.pyc b/libs/agent_framework/src/agent_framework/guardrails/calibrated/__pycache__/contracts.cpython-313.pyc index 2e8ea4348f99956453b4ee34384b06336ef3ea1f..71fe269d22af7937ed9e5c489b803d82333f4678 100644 GIT binary patch delta 20 acmexq`qPyAGcPX}0}xzyY~RTJP6_}_CkEmG delta 20 acmexq`qPyAGcPX}0}%ZC*0PcNofH63X9v3g diff --git a/libs/agent_framework/src/agent_framework/guardrails/calibrated/__pycache__/input_size.cpython-313.pyc b/libs/agent_framework/src/agent_framework/guardrails/calibrated/__pycache__/input_size.cpython-313.pyc index d149e1a8615d0ee908ab75bbb6c06aff1c62a9e5..8e036596c6ed782fcfaef5b1f0e50dd5ecb955ce 100644 GIT binary patch delta 20 acmaDQ{YskqGcPX}0}xzyY~RRzpBDf|8U}O# delta 20 acmaDQ{YskqGcPX}0}%ZC*0PcNJ}&@ES_e%4 diff --git a/libs/agent_framework/src/agent_framework/guardrails/calibrated/__pycache__/llm_adapter.cpython-313.pyc b/libs/agent_framework/src/agent_framework/guardrails/calibrated/__pycache__/llm_adapter.cpython-313.pyc index bfc04587ba695b335eca8deaa9e6f57132feabcb..99d7516e29fd8214761963aeedb9d96a041a3928 100644 GIT binary patch delta 20 acmaDZ`&^d$GcPX}0}xzyY~RRzhYtWn>jrQD delta 20 acmaDZ`&^d$GcPX}0}%ZC*0PcN4j%wZD+fsc diff --git a/libs/agent_framework/src/agent_framework/guardrails/calibrated/__pycache__/llm_client.cpython-313.pyc b/libs/agent_framework/src/agent_framework/guardrails/calibrated/__pycache__/llm_client.cpython-313.pyc index d75d2edf8066f03abceb45caed9eb8c2e5179f18..e0b005405a30636ab3cbe80b0b2f9644630461dd 100644 GIT binary patch delta 20 acmdmLxz&>UGcPX}0}xzyY~RSeN(KNz83rH# delta 20 acmdmLxz&>UGcPX}0}%ZC*0Pa%l?(t!SqAw4 diff --git a/libs/agent_framework/src/agent_framework/guardrails/calibrated/__pycache__/llm_rails.cpython-313.pyc b/libs/agent_framework/src/agent_framework/guardrails/calibrated/__pycache__/llm_rails.cpython-313.pyc index 13361936cb530e7898fd9d268c1123b208b79eaf..bfd8c5436cf03f7beb90d8a98786c6b65dd5266b 100644 GIT binary patch delta 20 acmX@;deD{oGcPX}0}xzyY~RSeO$h)+uLfcO delta 20 acmX@;deD{oGcPX}0}%ZC*0Pa%n-Ty@?*}^o diff --git a/libs/agent_framework/src/agent_framework/guardrails/calibrated/__pycache__/output_sanitization.cpython-313.pyc b/libs/agent_framework/src/agent_framework/guardrails/calibrated/__pycache__/output_sanitization.cpython-313.pyc index cff1ad31e6ef5c20edc5efb4d2cf90a5bc371b62..7a8d76336c0c3b03e14b306579983b520eb1ecb8 100644 GIT binary patch delta 20 acmaEs^DKw^GcPX}0}xzyY~RQoZ3X~P2L`hM delta 20 acmaEs^DKw^GcPX}0}%ZC*0Pa1+6(|yM+b}m diff --git a/libs/agent_framework/src/agent_framework/guardrails/calibrated/__pycache__/pipeline.cpython-313.pyc b/libs/agent_framework/src/agent_framework/guardrails/calibrated/__pycache__/pipeline.cpython-313.pyc index 6aef87ca030a9c9b3cc27c4f38ee18b1689ffa9f..a1f0e7fd6099217b241f4e9c83f53f3ca83c7398 100644 GIT binary patch delta 20 acmeyJ^gD_BGcPX}0}xzyY~RRTU}n diff --git a/libs/agent_framework/src/agent_framework/guardrails/calibrated/prompts/__pycache__/_context.cpython-313.pyc b/libs/agent_framework/src/agent_framework/guardrails/calibrated/prompts/__pycache__/_context.cpython-313.pyc index 3f7f8da5116d84a54fececd489f4dca5ed2de8de..768d0bcb40a6adce4b69d86669e9bdf89bba1f04 100644 GIT binary patch delta 20 acmeCz>eu4_%*)Hg00h?^+c$EvhynmP1_cQK delta 20 acmeCz>eu4_%*)Hg00jTOwQS^O5d{D~Mg`&k diff --git a/libs/agent_framework/src/agent_framework/guardrails/calibrated/prompts/__pycache__/ausencia_oferta_proativa.cpython-313.pyc b/libs/agent_framework/src/agent_framework/guardrails/calibrated/prompts/__pycache__/ausencia_oferta_proativa.cpython-313.pyc index 3c8735dd361d60cc5068bf28a84bc5573c0d7daf..ac166a0cec3e6572f6b65115d948f62f11058097 100644 GIT binary patch delta 20 acmaFk^~Q_)GcPX}0}xzyY~RS8s0si~9tLm# delta 20 acmaFk^~Q_)GcPX}0}%ZC*0Pa1Q567DUI$44 diff --git a/libs/agent_framework/src/agent_framework/guardrails/calibrated/prompts/__pycache__/coerencia.cpython-313.pyc b/libs/agent_framework/src/agent_framework/guardrails/calibrated/prompts/__pycache__/coerencia.cpython-313.pyc index bacf727e60531ddb97519401b20f1e308331be3b..760272aeb7bace78a73894481d9cf63bad666b2d 100644 GIT binary patch delta 20 acmbQ?HN%VhGcPX}0}xzyY~RSus|o-<{snXZ delta 20 acmbQ?HN%VhGcPX}0}%ZC*0PbCR}}z6J_bzy diff --git a/libs/agent_framework/src/agent_framework/guardrails/calibrated/prompts/__pycache__/dlex_in.cpython-313.pyc b/libs/agent_framework/src/agent_framework/guardrails/calibrated/prompts/__pycache__/dlex_in.cpython-313.pyc index d3762cc66454fc0696a619bebb371ecbd32388c2..ec6a935f1006fe88411206367b6bb838987517fa 100644 GIT binary patch delta 20 acmZ3%wStTLGcPX}0}xzyY~RQ&%L)KEUIhdI delta 20 acmZ3%wStTLGcPX}0}%ZC*0PaXmK6X!o(0_i diff --git a/libs/agent_framework/src/agent_framework/guardrails/calibrated/prompts/__pycache__/dlex_out.cpython-313.pyc b/libs/agent_framework/src/agent_framework/guardrails/calibrated/prompts/__pycache__/dlex_out.cpython-313.pyc index 2a3ee05f8dc50ab36d62d7490496cdd9c47f0b89..cec0449ca5d044c3c45861ee7ae889ca7da5abde 100644 GIT binary patch delta 20 acmX@kbDW3!GcPX}0}xzyY~RRj!v+97e+6a$ delta 20 acmX@kbDW3!GcPX}0}%ZC*0Pb?h7ABhzXm@5 diff --git a/libs/agent_framework/src/agent_framework/guardrails/calibrated/prompts/__pycache__/fallback.cpython-313.pyc b/libs/agent_framework/src/agent_framework/guardrails/calibrated/prompts/__pycache__/fallback.cpython-313.pyc index 7938ad52a75aaca620913c8454b8a9ee2522e591..a73de5dacbaa300f6f6d3605b61bd1bb176bac22 100644 GIT binary patch delta 22 ccmdnm#<;bOk^3_*FBbz4Tz72W$gSlJ08i`&V*mgE delta 22 ccmdnm#<;bOk^3_*FBbz4{QK6jkz30d097mpJOBUy diff --git a/libs/agent_framework/src/agent_framework/guardrails/calibrated/prompts/__pycache__/fraseologia.cpython-313.pyc b/libs/agent_framework/src/agent_framework/guardrails/calibrated/prompts/__pycache__/fraseologia.cpython-313.pyc index 384d9fa6d56f3be09bf24b37e7b93ac53a79a7d7..62078bd892b5ecd3124180bfa837712533d87fcd 100644 GIT binary patch delta 20 acmdm@zeS(>GcPX}0}xzyY~RSeQXBw4ga!lv delta 20 acmdm@zeS(>GcPX}0}%ZC*0Pa%r8odZ#0K2} diff --git a/libs/agent_framework/src/agent_framework/guardrails/calibrated/prompts/__pycache__/out_of_scope.cpython-313.pyc b/libs/agent_framework/src/agent_framework/guardrails/calibrated/prompts/__pycache__/out_of_scope.cpython-313.pyc index 27f4eadb3c08782fa51c38b59e3de09ca48822ab..6412537024a9cf95f768d40c50fc9bd564839178 100644 GIT binary patch delta 22 ccmX@z%6Ph!k^3_*FBbz4Tz72W$bG;G091AdA^-pY delta 22 ccmX@z%6Ph!k^3_*FBbz4{QK6jk^6uX09m#N`v3p{ diff --git a/libs/agent_framework/src/agent_framework/guardrails/calibrated/prompts/__pycache__/pinj.cpython-313.pyc b/libs/agent_framework/src/agent_framework/guardrails/calibrated/prompts/__pycache__/pinj.cpython-313.pyc index c73d15905d589bae080ed279799084899100553e..a767b8ccb19f0c4823f3a2463de8bbdd9285034c 100644 GIT binary patch delta 20 acmZp6Y}g9S_g delta 20 acmbQtJDHdJGcPX}0}%ZC*0PbigAD*X!v-Y) diff --git a/libs/agent_framework/src/agent_framework/guardrails/calibrated/rails/__pycache__/alcada.cpython-313.pyc b/libs/agent_framework/src/agent_framework/guardrails/calibrated/rails/__pycache__/alcada.cpython-313.pyc index d2b661521682a6acfc16a3b36bcc74a57157c802..2ab623549440ce003c0d0c0c5a44356270afd327 100644 GIT binary patch delta 20 acmbQPK3$#rGcPX}0}xzyY~RS;BMbmK*aevY delta 20 acmbQPK3$#rGcPX}0}%ZC*0PbiM;HJ=7zT0x diff --git a/libs/agent_framework/src/agent_framework/guardrails/calibrated/rails/__pycache__/anatel.cpython-313.pyc b/libs/agent_framework/src/agent_framework/guardrails/calibrated/rails/__pycache__/anatel.cpython-313.pyc index 6a18f89abc16a42ce2c9fd974a3fc381d4486241..677c5fd1fe955f6d3e2c04f0853e65ecd128a0f0 100644 GIT binary patch delta 20 acmX@(e#V{qGcPX}0}xzyY~RRzP#FM6um*?# delta 20 acmX@(e#V{qGcPX}0}%ZC*0PcNpfUhV@CRW4 diff --git a/libs/agent_framework/src/agent_framework/guardrails/calibrated/rails/__pycache__/confirmation.cpython-313.pyc b/libs/agent_framework/src/agent_framework/guardrails/calibrated/rails/__pycache__/confirmation.cpython-313.pyc index c26f95a4d602f9e08d9ed8f5517dcc5222c47f2a..bd586f3cdd25de09216c82bdee8bffc8f5dbd5f3 100644 GIT binary patch delta 20 acmbOcHY1GtGcPX}0}xzyY~RSus|^4^v;~p? delta 20 acmbOcHY1GtGcPX}0}%ZC*0PbCR~rCD^ag7H diff --git a/libs/agent_framework/src/agent_framework/guardrails/calibrated/rails/__pycache__/dlex_in.cpython-313.pyc b/libs/agent_framework/src/agent_framework/guardrails/calibrated/rails/__pycache__/dlex_in.cpython-313.pyc index 8039453c61cb1f262d72c8f0446fa4a4dce981d4..7f3a31cf57f639f61a679524d66231845cefa5be 100644 GIT binary patch delta 20 acmcaFd0&$IGcPX}0}xzyY~RRzg$Dpc83s-O delta 20 acmcaFd0&$IGcPX}0}%ZC*0PcN3J(BDSqCQo diff --git a/libs/agent_framework/src/agent_framework/guardrails/calibrated/rails/__pycache__/dlex_out.cpython-313.pyc b/libs/agent_framework/src/agent_framework/guardrails/calibrated/rails/__pycache__/dlex_out.cpython-313.pyc index 1694530201f3c8726ba8c385ea5a331807e4354f..3532b1559de5b94f1d07bdad32cb88cac7c44103 100644 GIT binary patch delta 20 acmbO%HCc-LGcPX}0}xzyY~RSu!3zL4UIgs` delta 20 acmbO%HCc-LGcPX}0}%ZC*0PbCgBJiio(0AL diff --git a/libs/agent_framework/src/agent_framework/guardrails/calibrated/rails/__pycache__/ragsec.cpython-313.pyc b/libs/agent_framework/src/agent_framework/guardrails/calibrated/rails/__pycache__/ragsec.cpython-313.pyc index 76358fb3768b7541b24bf87808c77ba23bcc8f75..e70216d7f9bb1cf798794d7cfe8f661f1103cc78 100644 GIT binary patch delta 20 acmdn0wN;DzGcPX}0}xzyY~RSOB?GcPX}0}xzyY~RRjr~m*%F$Ko} delta 20 acmdnvu*ZS>GcPX}0}%ZC*0Pb?Pyql)aR#6O diff --git a/libs/agent_framework/src/agent_framework/guardrails/calibrated/rules/__pycache__/__init__.cpython-313.pyc b/libs/agent_framework/src/agent_framework/guardrails/calibrated/rules/__pycache__/__init__.cpython-313.pyc index 3f3f905daa25b42028f47e0d9cfd7cdbabddcdd0..1dccf923f93ef2640e10c5b8750042a216b9b4c2 100644 GIT binary patch delta 20 acmZ3X3s|5G} delta 20 acmZ3jlvO diff --git a/libs/agent_framework/src/agent_framework/guardrails/calibrated/rules/__pycache__/alcada.cpython-313.pyc b/libs/agent_framework/src/agent_framework/guardrails/calibrated/rules/__pycache__/alcada.cpython-313.pyc index 63d722af5e1c90add9409b14a562b44f8e688cb7..f6900abf9968431c5661e409b0bb2a7498c6a366 100644 GIT binary patch delta 20 acmaFK_mYqMGcPX}0}xzyY~RQo#|{8P7zNP) delta 20 acmaFK_mYqMGcPX}0}%ZC*0Pa1jvW9=_?Wl%JKFTvDu`mRVF>5}%x( cSCUv9pPQLpl$esQpO~JS2NT>J&-{=N07X(9=>Px# delta 44 ycmaE&azKUqGcPX}0}%ZC*0Pb?iCHLBKR2&LKP9mwQNPU4B&{?jXLB?2Lp}gW_YW%o diff --git a/libs/agent_framework/src/agent_framework/identity/__pycache__/models.cpython-313.pyc b/libs/agent_framework/src/agent_framework/identity/__pycache__/models.cpython-313.pyc index 5ea4a982f37a1cfca2d44ca6cd67517c4e578c63..87109d3d5254f0c13a3bfd4eb20b6134286eb040 100644 GIT binary patch delta 80 zcmdlYaYKUpGcPX}0}xzyY~RRT&TQ7IpPN^rpQ7&@>=_?Wl%JKFTvDu`mRVF>5}%x( cSCUv9pPQLpl$esQpO~JS2NT>pg?Rx707B3l*Z=?k delta 44 ycmca1u|7NTGcPX}0}xzyY~RQo%xu=KpPN^rpQ7&@>=_?Wl%JKFTvDu`mRVF>5}%x( cSCUv9pPQLpl$esQpO~JS2NT>}!2FaC09HI5Hvj+t delta 44 ycmeyVa#e-t<8 delta 22 ccmaDbhv~r_ChpI?yj%=G@b6p8M()r)0AMc&HUIzs diff --git a/libs/agent_framework/src/agent_framework/judges/calibrated/__pycache__/__init__.cpython-313.pyc b/libs/agent_framework/src/agent_framework/judges/calibrated/__pycache__/__init__.cpython-313.pyc index 23d17df5df010f0702915172c3ad2619eea17b47..cad8920b20ab6488d6ab1e4da2372a0016f100ae 100644 GIT binary patch delta 19 Zcmey!_>qzOGcPX}0}xzyY@f*e3;;aU1}Fdk delta 19 Zcmey!_>qzOGcPX}0}%ZC)-sX%82~{%2LS*8 diff --git a/libs/agent_framework/src/agent_framework/judges/calibrated/__pycache__/llm_client.cpython-313.pyc b/libs/agent_framework/src/agent_framework/judges/calibrated/__pycache__/llm_client.cpython-313.pyc index b569f03928f9327be97d562e1240e1e80425b56f..03a186e52a37f53c64d78a971e7234db4fcc1d70 100644 GIT binary patch delta 20 acmaE+|4g6zGcPX}0}xzyY~RRzTO0sLR0f&= delta 20 acmaE+|4g6zGcPX}0}%ZC*0PcNwm1Mylm~MF diff --git a/libs/agent_framework/src/agent_framework/judges/calibrated/prompts/__pycache__/__init__.cpython-313.pyc b/libs/agent_framework/src/agent_framework/judges/calibrated/prompts/__pycache__/__init__.cpython-313.pyc index ceebfe041734e45dc07e0a67418be705d33e4efd..3f10bc32ddd822d8b8b1c634d0b03cb68cdd09a5 100644 GIT binary patch delta 19 Zcmey#_>++pAW(6w% delta 20 acmdnWwUvweGcPX}0}%ZC*0PaXixmJrrUnE6 diff --git a/libs/agent_framework/src/agent_framework/judges/calibrated/prompts/__pycache__/fallback.cpython-313.pyc b/libs/agent_framework/src/agent_framework/judges/calibrated/prompts/__pycache__/fallback.cpython-313.pyc index 9d4070db146bd8fe13600fd17b9124bb02dc5256..b1e254aaf928d19df646168f90463f177d500aae 100644 GIT binary patch delta 20 acmca>ch`>lGcPX}0}xzyY~RQoBo6>c5C$ax delta 20 acmca>ch`>lGcPX}0}%ZC*0Pa1NFD%9PzL@0 diff --git a/libs/agent_framework/src/agent_framework/judges/calibrated/prompts/__pycache__/rqlt.cpython-313.pyc b/libs/agent_framework/src/agent_framework/judges/calibrated/prompts/__pycache__/rqlt.cpython-313.pyc index 4bd6ec7572f7054871b94b1ed2b3982d50b0015a..df4b43cc382eb212fc3317bdd9a144cab0ea4d1b 100644 GIT binary patch delta 20 acmbQtIhm9DGcPX}0}xzyY~RS;!2$p^@dZKv delta 20 acmbQtIhm9DGcPX}0}%ZC*0Pbig9QLPF$Nm| diff --git a/libs/agent_framework/src/agent_framework/judges/calibrated/prompts/__pycache__/vctn.cpython-313.pyc b/libs/agent_framework/src/agent_framework/judges/calibrated/prompts/__pycache__/vctn.cpython-313.pyc index 86e84c3c4c7755f64a48fa1177e55d18439bd2c9..aabc742efdcd85e01559d2a490b0168c4c7a0bfa 100644 GIT binary patch delta 20 acmZo-ZDQsA%*)Hg00h?^+c$ETGXVfHw*>_N delta 20 acmZo-ZDQsA%*)Hg00jTOwQS@rX955>_XXYn diff --git a/libs/agent_framework/src/agent_framework/llm/__pycache__/__init__.cpython-313.pyc b/libs/agent_framework/src/agent_framework/llm/__pycache__/__init__.cpython-313.pyc index 0e67c293283afe19fbb2c0dd4b6bed3a47f73df6..fb39d5cc1905a498027c7eb250df571535952112 100644 GIT binary patch delta 19 ZcmaFN_?VIVGcPX}0}xzyY@f(|0{}YD1^xg4 delta 19 ZcmaFN_?VIVGcPX}0}%ZC)-sX%1^_=c2G;-p diff --git a/libs/agent_framework/src/agent_framework/llm/__pycache__/base.cpython-313.pyc b/libs/agent_framework/src/agent_framework/llm/__pycache__/base.cpython-313.pyc index 56dde3e283f5fc08f3395448ef36f771e55b1f75..6bde16ed1633a62006424a021ae279a7541760b9 100644 GIT binary patch delta 20 acmX@ic9@O(GcPX}0}xzyY~RRj!3+RA1O-a~ delta 20 acmX@ic9@O(GcPX}0}%ZC*0Pb?f*AloL=_?Wl%JKFTvDu`mRVF>5}%x( bSCUv9pPQLpl$esQpO~JS2NRs^&R7Qk4yGIB delta 43 xcmaFKe3Y5{GcPX}0}%ZC*0PaXi%}>}KR2&LKP9mwQNPU4B&{?jXL2@U9RMwj4krKr diff --git a/libs/agent_framework/src/agent_framework/mcp/__pycache__/client.cpython-313.pyc b/libs/agent_framework/src/agent_framework/mcp/__pycache__/client.cpython-313.pyc index fac6612968d482819d4a75212ad1a0412769d099..ec7374b81091ea177dad940346d8c5a5fff250a9 100644 GIT binary patch delta 82 zcmaFX&)7AAk^3_*FBbz4Tz72W$i0x+tU*6FuS7pZ-#6GZKAb>KSU)YZsJJ9P eIX|x?u{b_AGrcG=C0{==Jv9#|xOpG5h6@0Z86Cg? delta 46 zcmeC0!1%16k^3_*FBbz4{QK6jk$WMtP>g}ON6Z>70C5=* A0ssI2 diff --git a/libs/agent_framework/src/agent_framework/mcp/__pycache__/models.cpython-313.pyc b/libs/agent_framework/src/agent_framework/mcp/__pycache__/models.cpython-313.pyc index eef176c901221cb8208bac9cf4c95a491d7513dd..0a6bc11622348a409faa35332b6e315d4d237218 100644 GIT binary patch delta 80 zcmX>i@Irw5GcPX}0}xzyY~RT3!DQB;pPN^rpQ7&@>=_?Wl%JKFTvDu`mRVF>5}%x( cSCUv9pPQLpl$esQpO~JS2NT?!%5=_?Wl%JKFTvDu`mRVF>5}%x( cSCUv9pPQLpl$esQpO~JS2NT?E$Yd`704+ot#Q*>R delta 44 ycmbQD`ay;JGcPX}0}!}`v~A=TVG@ed&&?~*Pf09E)GsqMNh{6C*&NDbF8}}&mkg}{ diff --git a/libs/agent_framework/src/agent_framework/mcp/__pycache__/tool_policy.cpython-313.pyc b/libs/agent_framework/src/agent_framework/mcp/__pycache__/tool_policy.cpython-313.pyc index 50f832b7f88c2234f0433c81e82f95576d148368..61e7c5135ddc28615c3946d7a320f3ab7c2074a1 100644 GIT binary patch delta 80 zcmeCzIjY0;nU|M~0SK-;ZsaOvGH=z-%`4GQ(f1AZj1MTv&q_@$Db`QREGjOEPtMOP cNi2@f%}g&!Ov%?zOi#^&3F>dIW11)o05IwtPXGV_ delta 26 gcmX@A)33wznU|M~0SKmOZR9FuV)WmEwiY&BtAJm buOzWJJ~uPHC^02pKQTQu4<EwiY&BtAJm cuOzWJJ~uPHC^02pKQTQu4<@)-nyEq#0B0f`=l}o! delta 44 ycmdn)IN6c=GcPX}0}%ZC*0PcNAEQu)er{fgeoA6VqJEj7Nm^-6&Srb23ON8(vkxi& diff --git a/libs/agent_framework/src/agent_framework/memory/__pycache__/summary_memory.cpython-313.pyc b/libs/agent_framework/src/agent_framework/memory/__pycache__/summary_memory.cpython-313.pyc index 0b137229643cc140691b6aab7af4764368682f5f..fc17e6ed7a1aa5b9b97a2eb06dea84c2e779742e 100644 GIT binary patch delta 80 zcmX?=_%4zAGcPX}0}xzyY~RRzl-aCXKR2&LKSkd+*fTz$C_gJTxujS>EwiY&BtAJm cuOzWJJ~uPHC^02pKQTQu4<@+z5%UWj0Fx3PqyPW_ delta 44 ycmaEtcq)$yer{fgeoA6VqJEj7Nm^-6&So~27dilK4iD!5 diff --git a/libs/agent_framework/src/agent_framework/memory/__pycache__/summary_store.cpython-313.pyc b/libs/agent_framework/src/agent_framework/memory/__pycache__/summary_store.cpython-313.pyc index 1a22aabd823c8f24bc9cd6c913effb413e51a9bd..23d7c6b14db3bfed5d3d215d016435a7d37b7d61 100644 GIT binary patch delta 80 zcmbQ^b-;`JGcPX}0}xzyY~RQ&%VgH2pPN^rpQ7&@>=_?Wl%JKFTvDu`mRVF>5}%x( cSCUv9pPQLpl$esQpO~JS2NT?E#q>xC06fVYw*UYD delta 44 ycmX@$HOGtlGcPX}0}%ZC*0PaXmPsg0KR2&LKP9mwQNPU4B&{?jXLB6WBP9Sv5)SzQ diff --git a/libs/agent_framework/src/agent_framework/models/__pycache__/__init__.cpython-313.pyc b/libs/agent_framework/src/agent_framework/models/__pycache__/__init__.cpython-313.pyc index 539fe00487cc2191b9dbd2c532a0e388fdfa8eb5..30b57844cc18858073e341a545282e8f04715eb6 100644 GIT binary patch delta 77 zcmX@a_>7VJGcPX}0}xzyY@f(&Y}Trun^&TrqVF5*86QxTpOuCas`0^ delta 20 acmbO!JyV+dGcPX}0}%ZG*0Pbij~4(wxdvMR diff --git a/libs/agent_framework/src/agent_framework/models/__pycache__/session.cpython-313.pyc b/libs/agent_framework/src/agent_framework/models/__pycache__/session.cpython-313.pyc index 352c5f2beaf0b6d98965163dc57769b0482a883c..0ee244a364ea75abf30a4c0f325821eb834571be 100644 GIT binary patch delta 80 zcmZn=T_Vc;nU|M~0SK-;wr}KSW;Scl&&?~*Pto@c_KXiG%FjwoE-BVe%PcA`iBHbY cD@iPl&&^CPN=(VuPfSnEg9&a{U`}8M00KZ8KmY&$ delta 44 ycmZ1?+91mPnU|M~0SNwmYuU)n%q*0kpPN^rpORRTs9$Dil2)3Nv)P3?fgJ!Qtqp}GcPX}0}$MBY~RRzUj_h5Xa>Ll delta 20 acmaE5`O1>}GcPX}0}%ZG*0PcNz6=0Qs0Wz< diff --git a/libs/agent_framework/src/agent_framework/observability/__pycache__/event_bus.cpython-313.pyc b/libs/agent_framework/src/agent_framework/observability/__pycache__/event_bus.cpython-313.pyc index e1b3cb813888993af431b53ddacf4f3968631c67..1fb95390fd1257cf2df452f270e65cfaa3761a31 100644 GIT binary patch delta 20 acmX>gb3lgsGcPX}0}$MBY~RRj$_D^Gwgq|s delta 20 acmX>gb3lgsGcPX}0}%ZG*0Pb?ln($y_6Ab` diff --git a/libs/agent_framework/src/agent_framework/observability/__pycache__/guardrail_events.cpython-313.pyc b/libs/agent_framework/src/agent_framework/observability/__pycache__/guardrail_events.cpython-313.pyc index a550677f1880474d3f7785455b8f3335259a1cdf..778bed8487ea6d7344a166c3f758df2dbe6a9f1a 100644 GIT binary patch delta 20 acmbOvFiC*>GcPX}0}$MBY~RSu&H(^5&;-%| delta 20 acmbOvFiC*>GcPX}0}%ZG*0PbCodWGTUGcPX}0}$MBY~RQoB?JIPq6Pf` delta 20 acmaE=@>GTUGcPX}0}%ZG*0Pa1N(cZ-;s(|L diff --git a/libs/agent_framework/src/agent_framework/observability/__pycache__/otel.cpython-313.pyc b/libs/agent_framework/src/agent_framework/observability/__pycache__/otel.cpython-313.pyc index f9bc52abd74477f9442d81425c5fa19dd4d7f2e0..b1a5345006b06569dcf34d7c49d3fcca2152ad21 100644 GIT binary patch delta 20 acmaDX^;nAgGcPX}0}$MBY~RQo!3zLGJh diff --git a/libs/agent_framework/src/agent_framework/observability/__pycache__/telemetry.cpython-313.pyc b/libs/agent_framework/src/agent_framework/observability/__pycache__/telemetry.cpython-313.pyc index 5795c3fe7c4c9402379549586c78ae85d05b50f6..68d8edee7c5512af21ddbea07e618f73ccc15557 100644 GIT binary patch delta 22 ccmcaKiTTnbX710tyj%=GaKo{EBe(lW09SSgT>t<8 delta 22 ccmcaKiTTnbX710tyj%=G@c&!OMsD|$09>{RHUIzs diff --git a/libs/agent_framework/src/agent_framework/observability/__pycache__/token_cost.cpython-313.pyc b/libs/agent_framework/src/agent_framework/observability/__pycache__/token_cost.cpython-313.pyc index da822db243ca3d4472d447851ff657501e921c96..294851b4d132d14745872bc5625a1091e2157171 100644 GIT binary patch delta 20 acmZ4Dyu_LNGcPX}0}$MBY~RQ|QxO0_FSc?IGC delta 20 acmdljxm%L^GcPX}0}%ZG*0Pa%0}lX0zy`bk diff --git a/libs/agent_framework/src/agent_framework/persistence/__pycache__/__init__.cpython-313.pyc b/libs/agent_framework/src/agent_framework/persistence/__pycache__/__init__.cpython-313.pyc index da76b882469fe0e3522202c7c7aee5b76d5919d7..887100f75839ca43aaf830e3072cd50a1958381e 100644 GIT binary patch delta 77 zcmX@k_?nUXGcPX}0}xzyY@f(&Y}Tcpn^&TrqVF5*86QxTpOuHzW@LL diff --git a/libs/agent_framework/src/agent_framework/persistence/__pycache__/sqlite_store.cpython-313.pyc b/libs/agent_framework/src/agent_framework/persistence/__pycache__/sqlite_store.cpython-313.pyc index db4bea72769f5876b4f70116b011fb0d11c1f810..be530c3b64a81ea7c77584bb2a6be472619975c9 100644 GIT binary patch delta 80 zcmbPMx~r7?GcPX}0}xzuY~RS8!f4i~pPN^rpQ7&@>=_?Wl%JKFTvDu`mRVF>5}%x( cSCUv9pPQLpl$esQpO~JS2NT@f$S7(F0Azg}+5i9m delta 44 ycmdm0I<1uZGcPX}0}%ZC*0Pa1g;6L=KR2&LKP9mwQNPU4B&{?jXY*1IS(BG diff --git a/libs/agent_framework/src/agent_framework/presentation/__pycache__/__init__.cpython-313.pyc b/libs/agent_framework/src/agent_framework/presentation/__pycache__/__init__.cpython-313.pyc index c0db8033c914df779afabdd5b03df4e1a277161d..39de17f79ca3eb2782159c0d07d43a6017266ca7 100644 GIT binary patch delta 79 zcmcb}e2tm=GcPX}0}$MBY~RSu!)Vs6pPN^rpQ7&@>=_?Wl%JKFTvDu`mRVF>5}%x( bSCUv9pPQLpl$esQpO~JS2NRs^!Pp4^2iF_c delta 74 zcmcb{e36;^GcPX}0}!~xw{7I+VKi*h&&?~*Pf09E)K5%L%`1sd&d)1JERF}VQ;RZ_ bEwiY&BtAJm cuOzWJJ~uPHC^02pKQTQu4<@*opXnwa0CfQ!P5=M^ delta 75 zcmaE>_(GBUGcPX}0}!~xw{7IU%xKuIpPN^rpORRTsGpdgnpYB^oS#>cSR4;zrxs-< c#}}m*7v$#^r^c5V8pN097iDi2VYIKsP delta 20 acmZ3ky_F$S#w diff --git a/libs/agent_framework/src/agent_framework/rag/__pycache__/ingest.cpython-313.pyc b/libs/agent_framework/src/agent_framework/rag/__pycache__/ingest.cpython-313.pyc index c11503fca3d923bbc6b992eef99df71989a3548a..e33227c58fe1bf62e2594aff4a0a2c42ca580cb9 100644 GIT binary patch delta 20 acmdmzv?YoAGcPX}0}xzyY~RSOX$SyD$_4}g delta 20 acmdmzv?YoAGcPX}0}%ZG*0PaX(+~hm5eD7> diff --git a/libs/agent_framework/src/agent_framework/rag/__pycache__/rag_service.cpython-313.pyc b/libs/agent_framework/src/agent_framework/rag/__pycache__/rag_service.cpython-313.pyc index 66466a479e3d709b8e8b491c650defab380fcc83..0129c1ab9482cf2a6db530db648cfa072c2de0ec 100644 GIT binary patch delta 20 acmccUchQggGcPX}0}xzyY~RT3rVao|cm^o| delta 20 acmccUchQggGcPX}0}%ZG*0Pb?O&tJDzXt;V diff --git a/libs/agent_framework/src/agent_framework/rag/__pycache__/vector_store.cpython-313.pyc b/libs/agent_framework/src/agent_framework/rag/__pycache__/vector_store.cpython-313.pyc index bb0e6990c060ae27a6bf577227b9f66db14846ed..44bef70b919913169a26ae9616138eef9a6911a4 100644 GIT binary patch delta 22 ccmaDqk@5XRM()qNyj%=GaNV(eBli;z09;%LtN;K2 delta 22 ccmaDqk@5XRM()qNyj%=G@c&!OM(!sb0AZsDh5!Hn diff --git a/libs/agent_framework/src/agent_framework/repositories/__pycache__/__init__.cpython-313.pyc b/libs/agent_framework/src/agent_framework/repositories/__pycache__/__init__.cpython-313.pyc index 5fae24bcdca8351d30b6ce477d6a0cb2103a39de..3e3f1091370892ccd23dcfdcc982b72f313e40d1 100644 GIT binary patch delta 19 ZcmaFE_=b`DGcPX}0}xzyY@f*e5CA+J1{nYV delta 19 ZcmaFE_=b`DGcPX}0}%ZG)-sX%Apk&$2J-*_ diff --git a/libs/agent_framework/src/agent_framework/repositories/__pycache__/session_repository.cpython-313.pyc b/libs/agent_framework/src/agent_framework/repositories/__pycache__/session_repository.cpython-313.pyc index 4d042e31c102bbb5c33b75ca778315a67f888a2e..802cb4f5fe4fb4f2b25f32c9e0faaab28c40eede 100644 GIT binary patch delta 20 acmbR1JlC1~GcPX}0}xzyY~RQ|Nf7`)#s%>J delta 20 acmbR1JlC1~GcPX}0}%ZG*0Pa%k|F>_4F<~q diff --git a/libs/agent_framework/src/agent_framework/routing/__pycache__/__init__.cpython-313.pyc b/libs/agent_framework/src/agent_framework/routing/__pycache__/__init__.cpython-313.pyc index 2263e9bfe05475c3d2d5feb6a646e564ee8781c4..d5958ddc39c8a8fee9013ef7a4f031d0021755e0 100644 GIT binary patch delta 78 zcmbQrypx&xGcPX}0}xzyY@f*e)vQfFH?KrLMc+5rGd`dwKPxr4q*y;Kv#7WvJ~=yip$@hH diff --git a/libs/agent_framework/src/agent_framework/routing/__pycache__/continuity.cpython-313.pyc b/libs/agent_framework/src/agent_framework/routing/__pycache__/continuity.cpython-313.pyc index f614063e579d8fbb1d6d29f773038a68b2af0dac..e651f526e4bf4560d0c605d6b1e96becebe08e13 100644 GIT binary patch delta 80 zcmZ3Kek`5)GcPX}0}xzyY~RQo&Sci1pPN^rpQ7&@>=_?Wl%JKFTvDu`mRVF>5}%x( cSCUv9pPQLpl$esQpO~JS2NT>}!lY*i0AEfV$^ZZW delta 44 ycmX?>z9^mhGcPX}0}%ZC*0Pa1oJlA}KR2&LKP9mwQNPU4B&{?jXY&juJwpIi-wzA` diff --git a/libs/agent_framework/src/agent_framework/routing/__pycache__/enterprise_router.cpython-313.pyc b/libs/agent_framework/src/agent_framework/routing/__pycache__/enterprise_router.cpython-313.pyc index 67d963b16f5873f0d221fdc44d8c0583ad43e199..922735578512e10c025ab74541bb5ff3097263f7 100644 GIT binary patch delta 10486 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 delta 4000 zcmai0Yiu0V6`nggJNsV0cGq@dd)IM7Se*C~>^vPii62R@vnige0k6YmvODWcvYy@E zS;uw~SenuxH3+G_O^b?XQzVcgwLic@ji8huP=OGT_|aAj&q`Gvzfx#^xl+?}?l_K3 zP#I~yIdjgr=bn4-dEBqwCku=O{~ZW;1$e$(_r&pCJ6{YwN6MeT?*(B(phOXjh8*RWt-AcXU;!+PtS1IllQtyOM@hILlqO4YY zC^;@Jjr4=e53&pj178yclm;cp%?6c5rGirxN|RE_sY)fPRB@^bc-5S$R$@vGr)rdD zCB&(a5~krvM|{ov74b3=KM?0nNt;Mps?l~{5Ryc3C{nk>{_iICH!0*RZfT^NS({v2 zUA6STc9CLzN?1~ysW>aj>q(qFEyqa{+ucyZ{wT-X%e6#BX1|vs;^;kG{JI<#M>pIe z**&gMuv@Z?#)L^B?qU~R&Fl-;^Q4ZQbI-9R&jh>TirgEQEXmaJIT`|G8b*i!m^d~D zk9DGb$|$vG)sotNva>5UozJr?p2vxs4SGxLBkxPZn19ko30ci<`s>)w0xiVFz4##D zb;v0X`#2CK9`;7Cg;m2UE>3trKIN}v3xWE|4#9AzJTMb~l5SS;huLT_#QwX=%`W;w zK-aU6g1%cr>pe-=-HY044mMgonn4`(vNKmO%s+4NLnr*VNTy@A+bqjmNL>!PLR=I`5b$CC7_aeN<;Jv?D zNHs0)qTmwLm>?Lw6rlZ#wy^K|YdR~EzHZUx#Dpm9gW=olOHlipBROHGBP!$w*z4co z$dP!6ov(g?EmZ5Io@Hw;ku5A3iaA2Gfpvz$>z!$BN-tSeXrY3ZYL=@Z)AOo3)C zhgqVQ6F@K0E$rz~G}-~P(ini{)=sMVX|<%$dgMhB!t76>rgAfiJ=$zWE0*+vL47E~ zbc*}wdX#}h9M^_)ATv#=W|Y#LXGtY(wqynQPdck*bQ3ICRf`U#Gpdo*A>K8LMa6O# zsdiE?Oq+B&|K$Vr;0OmyZ~B3Wd2;Ka7#_3-RU?B27%5WS)JAdDw2d!*Gsw)>MRqwn z3+LP!3C*96{EawI5FyaT9<95t{4yw1_nDXFLD&B3=_XiUbB+lQ_!Wkq*bT%E(BoO zuz8rY&i`feCgMIN^W)mi>bAC*htYtGZ!+BpG~I&Gi_nL#3!xnV99V@k4zNQ6)h%CE zGcyox7&&nVj~6zO$dG9H{+^kz3oV$05w{b6fZJS(tIxBftG1!0D;;zVfv z%(mYVw)Y{2?A2H=LMcnkA#^%9F4v z>@;N;ds@XG3+(-#6dXu==M_;d!i==-o<^|E0A+b+RLGoc8vLY>ps0*+2H{bJ#}K}U za2DX3Q_yNkLv_(8n8_3j_UuqKdvvH%ye!PWICMy=Mt|Vwe~3oTBRt7!hxgYY`;q`V zOJ+?1G=u<~9qt$ZBe2(oqokF6I{exodJFNJgpU=uRW*1VLxG`CI40*VdA=n&JJ{zV z^<^DQ*rjbP8gnliGwJtH@C5Q?wOG`QES4d?K=slbPao*n1zK7b(vqQ0Y4idP`zb)& zYezNispVaYi|nm@GkMCe;(icINO->GfoH_-BcKCe#k%o`x&Tez~mT;_Z49j_$&*y`~v z2(s^tpNrpNi7)akFtKvSgAfkSyaMk5QJ zyl(O-55sYuUXt-5%(YD5Sq?~r6_ehUb5}kEC8!JK+iYA9wGg-hdJU8F&|jLIe)5gn z&us2(TigQLf+=qA!O9t+;T8;s7LTybY+pGJ%J${UkM{*VGo_V|6|!^)`MVLYZ&|)f zUNy}{*;1{g{iv`H;WEOj2(KVuNK!a)!3wAOB~s6%)e>A;kHWRiOsDBnsL(3FZPSk7 zApRp%!fP^sbHbOR*Xh1dSL^iN*wp8&`_~?k8QNoztJk%L5KkOezA!lnR|9$ihpQ}_ vYbP;wFxR@S85!K@Q%JQUVBxmhJyV73bYAPF*P-d=1}Y|0tp$hH0lL8iW6 diff --git a/libs/agent_framework/src/agent_framework/routing/__pycache__/models.cpython-313.pyc b/libs/agent_framework/src/agent_framework/routing/__pycache__/models.cpython-313.pyc index f4724fd9952a1f075dcda17da7cc53a49bc04ae8..bcf70e15958303a20a2f066ef9547be591760ca4 100644 GIT binary patch delta 80 zcmew*G*6iOGcPX}0}xzyY~RSO#%$K2pPN^rpQ7&@>=_?Wl%JKFTvDu`mRVF>5}%x( cSCUv9pPQLpl$esQpO~JS2NT@v%xumE04=y1%K!iX delta 44 ycmbOy{7Z=YGcPX}0}%ZC*0PaXjaeu`KR2&LKP9mwQNPU4B&{?jXLCBUIU4{xpAHQG diff --git a/libs/agent_framework/src/agent_framework/routing/enterprise_router.py b/libs/agent_framework/src/agent_framework/routing/enterprise_router.py index 73a9eb2..5ae99cc 100644 --- a/libs/agent_framework/src/agent_framework/routing/enterprise_router.py +++ b/libs/agent_framework/src/agent_framework/routing/enterprise_router.py @@ -35,6 +35,7 @@ class EnterpriseRouter: self.state_policies: list[RouterStatePolicy] = load_state_policies(self.config_path) self.defaults = load_router_defaults(self.config_path) self.fallback_agent = self.defaults.get("fallback_agent", "billing_agent") + self.intent_shift_threshold = float(self.defaults.get("confidence_threshold", 0.7)) self.enable_llm_router = bool(getattr(settings, "ENABLE_LLM_ROUTER", False)) self.continuity = SemanticRouteContinuity(settings, llm, telemetry) logger.info( @@ -56,11 +57,20 @@ class EnterpriseRouter: current_state = state.get("next_state") or session.get("metadata", {}).get("workflow_state") text = state.get("sanitized_input") or state.get("user_text") or "" - # Estados de coleta/confirmação têm precedência absoluta. Durante esses - # estados, palavras como "pedido" são respostas de preenchimento de - # parâmetros e não uma nova intenção de tracking. + # Estados transacionais preservam continuidade para respostas curtas + # (parâmetros, "sim", "não"), mas NÃO podem aprisionar a sessão. Antes + # de aplicar a política de estado, procuramos uma mudança explícita de + # intenção. Se houver uma intent diferente com confiança suficiente, ela + # vence o lock de estado e sinaliza ao runtime para encerrar a transação + # pendente antes de executar a nova intent. state_decision = self._route_by_state(current_state) if state_decision: + interruption = await self._transaction_state_interruption_candidate( + state, text=str(text), state_decision=state_decision + ) + if interruption is not None: + await self._emit(interruption, state) + return interruption await self._emit(state_decision, state) return state_decision @@ -116,6 +126,131 @@ class EnterpriseRouter: await self._emit(decision, state) return decision + + async def _transaction_state_interruption_candidate( + self, + state: dict[str, Any], + *, + text: str, + state_decision: RouteDecision, + ) -> RouteDecision | None: + """Detecta uma nova intenção durante coleta/confirmação transacional. + + A política de estado continua protegendo respostas curtas/ambíguas. Uma + interrupção só é aceita quando o roteador encontra uma intent diferente + da transação ativa. Keywords explícitas são preferidas; na ausência delas, + o LLM router pode decidir, desde que atinja o limiar configurado. + + O método não limpa o estado por conta própria. Ele marca a decisão com + ``transaction_interruption=intent_shift`` para que o runtime feche o latch + transacional de maneira centralizada e auditável. + """ + active_tx = state.get("active_transaction") if isinstance(state.get("active_transaction"), dict) else {} + started_intent = str(active_tx.get("started_from_intent") or "").strip() + previous = state.get("route_decision") or {} + previous_intent = str(previous.get("intent") or state.get("intent") or started_intent).strip() + + # Parameter answers have precedence over intent-shift detection. A reply + # such as ``R$ 71,99`` after the framework asked for ``valor`` is not a + # new billing-explanation intent; it is the missing transaction argument. + # Likewise, short entity-like replies (``TIM Music``) should remain in the + # pending transaction. Only clear question/action language is allowed to + # escape to the router. + missing = [str(x) for x in (state.get("missing_parameters") or []) if str(x).strip()] + if missing and self._looks_like_pending_parameter_answer(text, missing): + return None + + candidate = self._route_by_keyword(text) + if candidate is not None: + explicit = self._is_explicit_intent_shift(candidate) + different = ( + candidate.agent != state_decision.agent + or (started_intent and candidate.intent != started_intent) + or (previous_intent and not previous_intent.startswith("state:") and candidate.intent != previous_intent) + ) + if explicit and different: + candidate.metadata = { + **(candidate.metadata or {}), + "transaction_interruption": "intent_shift", + "interrupted_state": state_decision.next_state, + "interrupted_agent": state_decision.agent, + "interrupted_intent": started_intent or previous_intent, + } + return candidate + # Uma keyword reconhecida para a própria transação deve continuar + # protegida pelo estado; não há necessidade de chamar o LLM. + if not different: + return None + + if not (self.enable_llm_router and self.llm is not None): + return None + try: + candidate = await self._route_by_llm(text, state) + except Exception as exc: + logger.warning("Falha ao avaliar interrupção de estado transacional via LLM: %s", exc) + return None + + different = ( + candidate.agent != state_decision.agent + or (started_intent and candidate.intent != started_intent) + or (previous_intent and not previous_intent.startswith("state:") and candidate.intent != previous_intent) + ) + if not different or candidate.confidence < self.intent_shift_threshold: + return None + + candidate.metadata = { + **(candidate.metadata or {}), + "transaction_interruption": "intent_shift", + "interrupted_state": state_decision.next_state, + "interrupted_agent": state_decision.agent, + "interrupted_intent": started_intent or previous_intent, + } + return candidate + + @staticmethod + def _looks_like_pending_parameter_answer(text: str, missing_parameters: list[str]) -> bool: + """Return True when the current turn looks like an answer to a missing field. + + This is intentionally conservative: structured values are recognized by + parameter semantics, while a short entity-like phrase is accepted only if + it does not contain interrogative or explicit topic-shift language. + """ + raw = str(text or "").strip() + if not raw: + return False + normalized = unicodedata.normalize("NFKD", raw.lower()) + normalized = "".join(ch for ch in normalized if not unicodedata.combining(ch)) + normalized = re.sub(r"\s+", " ", normalized).strip() + names = {re.sub(r"[^a-z0-9_]+", "", str(x).lower()) for x in missing_parameters} + + # Explicit conversational shifts/questions must still escape the transaction. + shift_tokens = ( + "quero ", "gostaria ", "preciso ", "me diga", "me informe", "mostre", + "qual ", "quais ", "quando ", "onde ", "como ", "porque ", "por que ", + "esquece", "esqueca", "mudei de assunto", "outra coisa", "voltar para", + "cancelar ", "cancele ", "consultar ", "ver minha", "ver meu", + ) + if "?" in raw or any(tok in normalized for tok in shift_tokens): + return False + + # Common structured parameter families. + if names & {"valor", "value", "amount", "price", "preco", "preço"}: + if re.fullmatch(r"(?:r\$\s*)?[+-]?\d{1,3}(?:[.\s]\d{3})*(?:,\d{1,2})?|(?:r\$\s*)?[+-]?\d+(?:[.,]\d{1,2})?", normalized, flags=re.I): + return True + if names & {"order_id", "pedido", "pedido_id", "invoice_id", "fatura_id", "protocol", "protocolo", "protocolo_id"}: + if re.fullmatch(r"[a-z0-9._/-]{2,64}", normalized, flags=re.I): + return True + if names & {"data", "date", "due_date", "vencimento"}: + if re.fullmatch(r"\d{1,2}[/-]\d{1,2}(?:[/-]\d{2,4})?", normalized): + return True + + # A single short noun/entity phrase is usually the requested subject/reason. + # Keep it in the transaction unless it contains clear routing language. + words = re.findall(r"[a-z0-9$+.,/_-]+", normalized) + if len(missing_parameters) == 1 and 1 <= len(words) <= 5: + return True + return False + @staticmethod def _is_explicit_intent_shift(decision: RouteDecision) -> bool: """Retorna True para matches explícitos que devem vencer a stickiness. diff --git a/libs/agent_framework/src/agent_framework/runtime/__pycache__/__init__.cpython-313.pyc b/libs/agent_framework/src/agent_framework/runtime/__pycache__/__init__.cpython-313.pyc index eaad4f7b7e6cd1e3f605842bb6ef07c6f196f9b9..d69428ca3a71b23045f0f92ffef4bbfc566d85a9 100644 GIT binary patch delta 77 zcmX@X^oEK1GcPX}0}xzyY@f)z)~roGH?KrLMc+5rGd`dwKPxr4q*y;Kv#7WvJ~=X diff --git a/libs/agent_framework/src/agent_framework/runtime/__pycache__/agent_runtime.cpython-313.pyc b/libs/agent_framework/src/agent_framework/runtime/__pycache__/agent_runtime.cpython-313.pyc index 344e40b92f11d78bcb585093b56b46008b8f240d..f72ad72547a71436639cb6aa3b79d1a115f0e3d6 100644 GIT binary patch delta 13346 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 G1OE>f^DN5% delta 10781 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 Rl{~T-oZndp>isb>{u=`L6~X`j diff --git a/libs/agent_framework/src/agent_framework/runtime/agent_runtime.py b/libs/agent_framework/src/agent_framework/runtime/agent_runtime.py index 71326a7..6ba7c1d 100644 --- a/libs/agent_framework/src/agent_framework/runtime/agent_runtime.py +++ b/libs/agent_framework/src/agent_framework/runtime/agent_runtime.py @@ -1231,6 +1231,30 @@ class AgentRuntimeMixin: ) return result + @staticmethod + def _transaction_cancel_requested(text: str) -> bool: + """Reconhece cancelamento explícito de uma transação pendente. + + Mantém o conjunto deliberadamente pequeno para não confundir uma nova + ação de negócio (ex.: "cancelar meu serviço") com o cancelamento do + próprio fluxo pendente. + """ + normalized = " ".join(str(text or "").strip().casefold().split()) + exact = { + "cancelar", "cancele", "cancela", "desistir", "desisto", + "não quero continuar", "nao quero continuar", + "não quero mais", "nao quero mais", + "deixa pra lá", "deixa pra la", + } + if normalized in exact: + return True + contextual = ( + r"^(?:cancele|cancela|cancelar)\s+(?:essa|esta|a|o)?\s*(?:operação|operacao|solicitação|solicitacao|transação|transacao|pedido|processo)(?:\s+anterior)?$", + r"^(?:não|nao)\s+quero\s+mais\s+(?:contestar|continuar|prosseguir)(?:\s+.*)?$", + r"^(?:esqueça|esqueca)\s+(?:essa|esta|a)?\s*(?:solicitação|solicitacao|operação|operacao|transação|transacao)(?:\s+anterior)?$", + ) + return any(re.match(pattern, normalized) for pattern in contextual) + @staticmethod def _confirmation_decision(text: str) -> str | None: normalized = " ".join((text or "").strip().lower().split()) @@ -2033,6 +2057,30 @@ class AgentRuntimeMixin: text = state.get("sanitized_input") or state.get("user_text") or "" self._normalize_transaction_lifecycle(state) + # Uma transação em coleta/confirmação não pode aprisionar a sessão. O + # EnterpriseRouter sinaliza uma nova intent explícita em metadata; além + # disso, cancelamentos explícitos devem funcionar também durante coleta + # de parâmetros (antes, só funcionavam em AWAITING_CONFIRMATION). + active_before_interruption = self._active_transaction(state) + route_meta = (state.get("route_decision") or {}).get("metadata") or {} + interruption = str(route_meta.get("transaction_interruption") or "").strip().lower() + cancel_requested = self._transaction_cancel_requested(str(text)) + if active_before_interruption and (interruption == "intent_shift" or cancel_requested): + interrupted_tool = active_before_interruption.get("tool_name") + self._finish_active_transaction(state, "CANCELLED") + state["tool_policy_result"] = { + "action": "cancelled_by_intent_shift" if interruption == "intent_shift" else "cancelled_by_user", + "tool_name": interrupted_tool, + } + if cancel_requested and interruption != "intent_shift": + return [{ + "ok": True, + "tool_name": interrupted_tool, + "transaction_status": "CANCELLED", + "cancelled": True, + "reason": "user_cancelled_pending_transaction", + }] + # Clarificação de resultado de tool tem precedência: reutiliza a mesma tool # e argumentos, alterando apenas o parâmetro escolhido pelo usuário. if state.get("pending_tool_clarification"): diff --git a/libs/agent_framework/src/agent_framework/sse/__pycache__/__init__.cpython-313.pyc b/libs/agent_framework/src/agent_framework/sse/__pycache__/__init__.cpython-313.pyc index a9019c88e26379c2ff436c1605729a148374fa96..dd7a1875ed7493597eda414eeb29558501a936e2 100644 GIT binary patch delta 19 ZcmaFN_?VIVGcPX}0}xzyY@f(|0{}YD1^xg4 delta 19 ZcmaFN_?VIVGcPX}0}%ZG)-sX%1^_=i2G{@q diff --git a/libs/agent_framework/src/agent_framework/sse/__pycache__/events.cpython-313.pyc b/libs/agent_framework/src/agent_framework/sse/__pycache__/events.cpython-313.pyc index 3064cfd83e19a51bdb59e9f1f272a9ccf2402d50..876d1c1301061f2ab657adb72e98d4aca2bb404c 100644 GIT binary patch delta 20 acmZqnZuaK>%*)Hg00h?^+c$Dor~&{y+6A`& delta 20 acmZqnZuaK>%*)Hg00jTPwQS_BPz3-&AqJ5E diff --git a/libs/agent_framework/src/agent_framework/supervisor/__pycache__/__init__.cpython-313.pyc b/libs/agent_framework/src/agent_framework/supervisor/__pycache__/__init__.cpython-313.pyc index c26f2aff6be87f682d0bd0509119e261a230973d..87e1c2451c966ec3f549fc9a725b7c535da4b9ed 100644 GIT binary patch delta 19 ZcmaFG_==JHGcPX}0}xzuY@f(|9{@Yd1`+@O delta 19 ZcmaFG_==JHGcPX}0}%ZG)-sX%J^(;J2JHX< diff --git a/libs/agent_framework/src/agent_framework/supervisor/__pycache__/supervisor.cpython-313.pyc b/libs/agent_framework/src/agent_framework/supervisor/__pycache__/supervisor.cpython-313.pyc index 054da5c93ac9c4e4980b804581c0435623799a3d..55922ed3ef229bc4f58516291a142b33ce7e044c 100644 GIT binary patch delta 20 acmaE$@<4_AGcPX}0}xzuY~RQoDg*#T%mwTK delta 20 acmaE$@<4_AGcPX}0}%ZG*0Pa1R0se{8V1Jz diff --git a/libs/agent_framework/src/agent_framework/workflows/__pycache__/__init__.cpython-313.pyc b/libs/agent_framework/src/agent_framework/workflows/__pycache__/__init__.cpython-313.pyc index a3a6732540d64d9cf2eb7abd8a70eb2d505dd79e..c06dba486209e90f02b9c0036f3d495ff83c155f 100644 GIT binary patch delta 79 zcmcb`_K%JGGcPX}0}xzyY~RQ|pUJF4KR2&LKSkd+*fTz$C_gJTxujS>EwiY&BtAJm buOzWJJ~uPHC^02pKQTQu4<=_?Wl%JKFTvDu`mRVF>5}%x( cSCUv9pPQLpl$esQpO~JS2NT?!%q+kJ04%Q?!vFvP delta 44 ycmbQv{h5pVGcPX}0}%ZC*0Pb?jaevBKR2&LKP9mwQNPU4B&{?jXLCEV022T^Dh>qz diff --git a/libs/agent_framework/src/agent_framework/workflows/__pycache__/models.cpython-313.pyc b/libs/agent_framework/src/agent_framework/workflows/__pycache__/models.cpython-313.pyc index fa5b08cff973570fd9d6a6abc3d80633980484a0..954e555c7e71ef48a481a76a71db559e8f7bf1f8 100644 GIT binary patch delta 80 zcmcbk(V)rwnU|M~0SK-;wr}LV%4F82pPN^rpQ7&@>=_?Wl%JKFTvDu`mRVF>5}%x( cSCUv9pPQLpl$esQpO~JS2NT@GcPX}0}xzyY~RRziqWh?KR2&LKSkd+*fTz$C_gJTxujS>EwiY&BtAJm cuOzWJJ~uPHC^02pKQTQu4<@+zIinpr07|$V@Bjb+ delta 44 ycmX>pv{Z=uGcPX}0}%ZC*0PcN6r)gzer{fgeoA6VqJEj7Nm^-6&Sq{VJ9Yp?R1Px$ diff --git a/libs/agent_framework/src/agent_framework/workflows/__pycache__/repository.cpython-313.pyc b/libs/agent_framework/src/agent_framework/workflows/__pycache__/repository.cpython-313.pyc index 8dc468db78e7e525d2522b5b5b331c805c2fa424..fc2895d6c4f424be1eb9772edcdcca73520c2a12 100644 GIT binary patch delta 80 zcmZn@T_wu>nU|M~0SK-;wr}LV$!ON4pPN^rpQ7&@>=_?Wl%JKFTvDu`mRVF>5}%x( cSCUv9pPQLpl$esQpO~JS2NT@EwiY&BtAJm cuOzWJJ~uPHC^02pKQTQu4<@*I2je4F061wK9RL6T delta 44 ycmdnTKZ~FHGcPX}0}%ZC*0Pa%Hlt9cer{fgeoA6VqJEj7Nm^-6&gMIek5~af+7Dj< diff --git a/tests/__pycache__/conftest.cpython-313-pytest-9.0.2.pyc b/tests/__pycache__/conftest.cpython-313-pytest-9.0.2.pyc index ef585a773ee1b56a8f0e521fe8c7afddb9029159..36fcfaf382ea117d9d8ec5e5ba4eca6f3a212587 100644 GIT binary patch delta 63 zcmbQtww#UoGcPX}0}$MFY~RT3%B1G4pPN^rpORRTsGpWu5noc2m{**bT#}ie7oU@# RU!b3ypI4GtJUNMJBLHqG6}SKZ delta 43 xcmZ3^Hkpn4GcPX}0}vFI*Kg!@WfC&i&&?~*Pf09E)GsqMNh{6CnOw%S5dizV4BY?# diff --git a/tests/__pycache__/test_transaction_state_router_interruption.cpython-313-pytest-9.0.2.pyc b/tests/__pycache__/test_transaction_state_router_interruption.cpython-313-pytest-9.0.2.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d9b3acd30767a2fe80728caa80ae75a34352bb34 GIT binary patch literal 15037 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 literal 0 HcmV?d00001 diff --git a/tests/__pycache__/test_transactional_tool_flow.cpython-313-pytest-9.0.2.pyc b/tests/__pycache__/test_transactional_tool_flow.cpython-313-pytest-9.0.2.pyc index d6b76da4f7589d235d6526dfcab4dd1004a71a40..9f4d837968117aadd56a5ee30ec4ed2e9014dfac 100644 GIT binary patch delta 6076 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 delta 668 zcmZvZU1*X~7{`57Ud5bIWABz9=`QB7L9R9>YNWGtns!mVGH5k06jRgDtGK>KT@)F5 z6OXilAVwq0d9gUUZYrhA97MaQF^HlY=^`q+s9iKV$937ud4K%R^MB6soDVF@Yx6SA z&yEh2gnr!vH{<6|+}8Af^J)L6OdbVGKherxD7X8q$yCM~4rM~t>|WdSl$aoY)c3~m z+B-FtzwE?DI0!u9BRLJ|$b+<(;|w5?hz9(6afh5qG@j*&>C&VIdhlxQAlJ)m6KUj1 zQmFxOLp0&7d^haEx%@a-a6NB=LDUxFU?(>UEe`rHi8koPhv_zjIZIu}af(BfqL(f5;(EypUNk*!>f3=U%$i{cQr{vKC)=7Ro>(`V3TsMt zz&GY|1>DpPqOTl)Al@k-pnO~YOj%tx!U?RnfEx>D5J+FeuB7o()d_IWL+bTnnH6PQ z6+}Ig6^8o^C-HkV3x_aT8wLR#bu+%ICBcn@OP3)=DoY;~a0Ux6c3Ug{PgV(it)>g2xO+JXNpg32pG;~o&x#!U8sb@&j-mbP ucBV!cJPhsIY9BMkrU{1R?4kk;TP{#dha|lM&sG)i22?+!U9d;A(b!*?^T|j6 diff --git a/tests/test_transaction_state_router_interruption.py b/tests/test_transaction_state_router_interruption.py new file mode 100644 index 0000000..23f2e8c --- /dev/null +++ b/tests/test_transaction_state_router_interruption.py @@ -0,0 +1,218 @@ +from types import SimpleNamespace + +import pytest + +from agent_framework.routing.enterprise_router import EnterpriseRouter + + +class _LLM: + async def ainvoke(self, messages, **kwargs): + return '{"intent":"contas_vas_information","agent":"vas_agent","confidence":0.96,"reason":"nova consulta de serviços"}' + + +@pytest.mark.asyncio +async def test_state_policy_allows_high_confidence_new_intent(tmp_path): + routing = tmp_path / "routing.yaml" + routing.write_text( + """ +router: + fallback_agent: faturas_agent + confidence_threshold: 0.70 +state_policies: + - state: COLLECTING_CONTESTACAO_PARAMETERS + agent: contestacao_agent +intents: + - name: contas_contestation + agent: contestacao_agent + priority: 10 + keywords: [contestar] + - name: contas_vas_information + agent: vas_agent + priority: 20 + keywords: [serviços ativos] +""", + encoding="utf-8", + ) + settings = SimpleNamespace( + ROUTING_CONFIG_PATH=str(routing), + ENABLE_LLM_ROUTER=True, + ENABLE_ROUTE_STICKINESS=False, + ) + router = EnterpriseRouter(settings, llm=_LLM()) + state = { + "user_text": "quais são meus serviços?", + "sanitized_input": "quais são meus serviços?", + "next_state": "COLLECTING_CONTESTACAO_PARAMETERS", + "intent": "state:COLLECTING_CONTESTACAO_PARAMETERS", + "active_agent": "contestacao_agent", + "active_transaction": { + "tool_name": "contestar_cobranca", + "status": "COLLECTING_PARAMETERS", + "started_from_intent": "contas_contestation", + }, + } + + decision = await router.route(state) + + assert decision.intent == "contas_vas_information" + assert decision.agent == "vas_agent" + assert decision.metadata["transaction_interruption"] == "intent_shift" + assert decision.next_state is None + + +@pytest.mark.asyncio +async def test_state_policy_keeps_short_parameter_answer_in_transaction(tmp_path): + routing = tmp_path / "routing.yaml" + routing.write_text( + """ +router: + fallback_agent: faturas_agent + confidence_threshold: 0.70 +state_policies: + - state: COLLECTING_CONTESTACAO_PARAMETERS + agent: contestacao_agent +intents: + - name: contas_contestation + agent: contestacao_agent + priority: 10 + keywords: [contestar] + - name: contas_vas_information + agent: vas_agent + priority: 20 + keywords: [serviços ativos] +""", + encoding="utf-8", + ) + + class _LowConfidenceLLM: + async def ainvoke(self, messages, **kwargs): + return '{"intent":"contas_vas_information","agent":"vas_agent","confidence":0.30,"reason":"incerto"}' + + settings = SimpleNamespace( + ROUTING_CONFIG_PATH=str(routing), + ENABLE_LLM_ROUTER=True, + ENABLE_ROUTE_STICKINESS=False, + ) + router = EnterpriseRouter(settings, llm=_LowConfidenceLLM()) + state = { + "user_text": "TIM Music", + "sanitized_input": "TIM Music", + "next_state": "COLLECTING_CONTESTACAO_PARAMETERS", + "intent": "state:COLLECTING_CONTESTACAO_PARAMETERS", + "active_agent": "contestacao_agent", + "active_transaction": { + "tool_name": "contestar_cobranca", + "status": "COLLECTING_PARAMETERS", + "started_from_intent": "contas_contestation", + }, + } + + decision = await router.route(state) + + assert decision.method == "state" + assert decision.agent == "contestacao_agent" + assert decision.intent == "state:COLLECTING_CONTESTACAO_PARAMETERS" + +@pytest.mark.asyncio +async def test_state_policy_keeps_currency_value_as_pending_parameter_even_if_llm_wants_new_intent(tmp_path): + routing = tmp_path / "routing.yaml" + routing.write_text( + """ +router: + fallback_agent: faturas_agent + confidence_threshold: 0.70 +state_policies: + - state: COLLECTING_CONTESTACAO_PARAMETERS + agent: contestacao_agent +intents: + - name: contas_contestation + agent: contestacao_agent + priority: 10 + keywords: [contestar] + - name: contas_invoice_explanation + agent: faturas_agent + priority: 20 + keywords: [fatura] +""", + encoding="utf-8", + ) + + class _InvoiceLLM: + async def ainvoke(self, messages, **kwargs): + return '{"intent":"contas_invoice_explanation","agent":"faturas_agent","confidence":0.95,"reason":"valor isolado"}' + + settings = SimpleNamespace( + ROUTING_CONFIG_PATH=str(routing), + ENABLE_LLM_ROUTER=True, + ENABLE_ROUTE_STICKINESS=False, + ) + router = EnterpriseRouter(settings, llm=_InvoiceLLM()) + state = { + "user_text": "R$ 71,99", + "sanitized_input": "R$ 71,99", + "next_state": "COLLECTING_CONTESTACAO_PARAMETERS", + "intent": "state:COLLECTING_CONTESTACAO_PARAMETERS", + "active_agent": "contestacao_agent", + "missing_parameters": ["valor"], + "active_transaction": { + "tool_name": "contestar_cobranca", + "status": "COLLECTING_PARAMETERS", + "started_from_intent": "contas_contestation", + "arguments": {"subject": "TIM CTRL Redes Sociais 8.0"}, + }, + } + + decision = await router.route(state) + + assert decision.method == "state" + assert decision.agent == "contestacao_agent" + assert decision.intent == "state:COLLECTING_CONTESTACAO_PARAMETERS" + assert "transaction_interruption" not in (decision.metadata or {}) + + +@pytest.mark.asyncio +async def test_state_policy_still_allows_clear_question_to_interrupt_pending_value(tmp_path): + routing = tmp_path / "routing.yaml" + routing.write_text( + """ +router: + fallback_agent: faturas_agent + confidence_threshold: 0.70 +state_policies: + - state: COLLECTING_CONTESTACAO_PARAMETERS + agent: contestacao_agent +intents: + - name: contas_contestation + agent: contestacao_agent + priority: 10 + keywords: [contestar] + - name: contas_vas_information + agent: vas_agent + priority: 20 + keywords: [serviços] +""", + encoding="utf-8", + ) + settings = SimpleNamespace( + ROUTING_CONFIG_PATH=str(routing), + ENABLE_LLM_ROUTER=True, + ENABLE_ROUTE_STICKINESS=False, + ) + router = EnterpriseRouter(settings, llm=_LLM()) + state = { + "user_text": "quais são meus serviços?", + "sanitized_input": "quais são meus serviços?", + "next_state": "COLLECTING_CONTESTACAO_PARAMETERS", + "intent": "state:COLLECTING_CONTESTACAO_PARAMETERS", + "active_agent": "contestacao_agent", + "missing_parameters": ["valor"], + "active_transaction": { + "tool_name": "contestar_cobranca", + "status": "COLLECTING_PARAMETERS", + "started_from_intent": "contas_contestation", + }, + } + + decision = await router.route(state) + assert decision.intent == "contas_vas_information" + assert decision.metadata["transaction_interruption"] == "intent_shift" diff --git a/tests/test_transactional_tool_flow.py b/tests/test_transactional_tool_flow.py index 67c57b4..6a38d56 100644 --- a/tests/test_transactional_tool_flow.py +++ b/tests/test_transactional_tool_flow.py @@ -568,3 +568,69 @@ async def test_pre_validation_rejection_clears_collecting_latches_and_is_exposed patch = runtime.transaction_state_patch(state) assert patch["transaction_pre_validation"] == state["transaction_pre_validation"] assert patch["next_state"] is None +@pytest.mark.asyncio +async def test_collecting_parameters_can_be_cancelled_explicitly(): + runtime = _ContestRuntime() + state = { + "user_text": "cancele essa operação anterior", + "sanitized_input": "cancele essa operação anterior", + "route": "contestacao_agent", + "intent": "state:COLLECTING_CONTESTACAO_PARAMETERS", + "transaction_status": "COLLECTING_PARAMETERS", + "active_transaction": { + "transaction_id": "tx-1", + "tool_name": "contestar_cobranca", + "arguments": {}, + "status": "COLLECTING_PARAMETERS", + "started_from_intent": "contas_contestation", + }, + "selected_tool_call": {"tool_name": "contestar_cobranca", "arguments": {}}, + "missing_parameters": ["subject"], + "next_state": "COLLECTING_CONTESTACAO_PARAMETERS", + } + + result = await runtime.execute_tools_for_intent(state, tools=[]) + + assert result[-1]["transaction_status"] == "CANCELLED" + assert result[-1]["cancelled"] is True + assert state["transaction_status"] == "CANCELLED" + assert state["active_transaction"] is None + assert state["next_state"] is None + assert state["missing_parameters"] == [] + + +@pytest.mark.asyncio +async def test_route_intent_shift_clears_collecting_transaction_before_new_tools(): + runtime = _ContestRuntime() + state = { + "user_text": "quais são meus serviços?", + "sanitized_input": "quais são meus serviços?", + "route": "vas_agent", + "intent": "contas_vas_information", + "route_decision": { + "route": "vas_agent", + "agent": "vas_agent", + "intent": "contas_vas_information", + "metadata": {"transaction_interruption": "intent_shift"}, + }, + "transaction_status": "COLLECTING_PARAMETERS", + "active_transaction": { + "transaction_id": "tx-2", + "tool_name": "contestar_cobranca", + "arguments": {}, + "status": "COLLECTING_PARAMETERS", + "started_from_intent": "contas_contestation", + }, + "selected_tool_call": {"tool_name": "contestar_cobranca", "arguments": {}}, + "missing_parameters": ["subject"], + "next_state": "COLLECTING_CONTESTACAO_PARAMETERS", + } + + result = await runtime.execute_tools_for_intent(state, tools=[]) + + assert result == [] + assert state["transaction_status"] == "CANCELLED" + assert state["active_transaction"] is None + assert state["next_state"] is None + assert state["missing_parameters"] == [] + assert state["tool_policy_result"]["action"] == "cancelled_by_intent_shift"