atendentepro 0.6.2__tar.gz → 0.6.4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. {atendentepro-0.6.2 → atendentepro-0.6.4}/CHANGELOG.md +40 -0
  2. atendentepro-0.6.2/README.md → atendentepro-0.6.4/PKG-INFO +341 -34
  3. atendentepro-0.6.2/PKG-INFO → atendentepro-0.6.4/README.md +283 -92
  4. {atendentepro-0.6.2 → atendentepro-0.6.4}/atendentepro/__init__.py +10 -0
  5. {atendentepro-0.6.2 → atendentepro-0.6.4}/atendentepro/agents/knowledge.py +13 -0
  6. {atendentepro-0.6.2 → atendentepro-0.6.4}/atendentepro/models/__init__.py +14 -1
  7. atendentepro-0.6.4/atendentepro/models/context.py +182 -0
  8. {atendentepro-0.6.2 → atendentepro-0.6.4}/atendentepro/network.py +143 -50
  9. {atendentepro-0.6.2 → atendentepro-0.6.4}/atendentepro/templates/__init__.py +8 -0
  10. {atendentepro-0.6.2 → atendentepro-0.6.4}/atendentepro/templates/manager.py +138 -0
  11. {atendentepro-0.6.2 → atendentepro-0.6.4}/pyproject.toml +23 -23
  12. atendentepro-0.6.4/requirements.txt +57 -0
  13. atendentepro-0.6.2/atendentepro/models/context.py +0 -21
  14. atendentepro-0.6.2/requirements.txt +0 -46
  15. {atendentepro-0.6.2 → atendentepro-0.6.4}/LICENSE +0 -0
  16. {atendentepro-0.6.2 → atendentepro-0.6.4}/MANIFEST.in +0 -0
  17. {atendentepro-0.6.2 → atendentepro-0.6.4}/atendentepro/README.md +0 -0
  18. {atendentepro-0.6.2 → atendentepro-0.6.4}/atendentepro/agents/__init__.py +0 -0
  19. {atendentepro-0.6.2 → atendentepro-0.6.4}/atendentepro/agents/answer.py +0 -0
  20. {atendentepro-0.6.2 → atendentepro-0.6.4}/atendentepro/agents/confirmation.py +0 -0
  21. {atendentepro-0.6.2 → atendentepro-0.6.4}/atendentepro/agents/escalation.py +0 -0
  22. {atendentepro-0.6.2 → atendentepro-0.6.4}/atendentepro/agents/feedback.py +0 -0
  23. {atendentepro-0.6.2 → atendentepro-0.6.4}/atendentepro/agents/flow.py +0 -0
  24. {atendentepro-0.6.2 → atendentepro-0.6.4}/atendentepro/agents/interview.py +0 -0
  25. {atendentepro-0.6.2 → atendentepro-0.6.4}/atendentepro/agents/onboarding.py +0 -0
  26. {atendentepro-0.6.2 → atendentepro-0.6.4}/atendentepro/agents/triage.py +0 -0
  27. {atendentepro-0.6.2 → atendentepro-0.6.4}/atendentepro/agents/usage.py +0 -0
  28. {atendentepro-0.6.2 → atendentepro-0.6.4}/atendentepro/config/__init__.py +0 -0
  29. {atendentepro-0.6.2 → atendentepro-0.6.4}/atendentepro/config/settings.py +0 -0
  30. {atendentepro-0.6.2 → atendentepro-0.6.4}/atendentepro/guardrails/__init__.py +0 -0
  31. {atendentepro-0.6.2 → atendentepro-0.6.4}/atendentepro/guardrails/manager.py +0 -0
  32. {atendentepro-0.6.2 → atendentepro-0.6.4}/atendentepro/license.py +0 -0
  33. {atendentepro-0.6.2 → atendentepro-0.6.4}/atendentepro/models/outputs.py +0 -0
  34. {atendentepro-0.6.2 → atendentepro-0.6.4}/atendentepro/prompts/__init__.py +0 -0
  35. {atendentepro-0.6.2 → atendentepro-0.6.4}/atendentepro/prompts/answer.py +0 -0
  36. {atendentepro-0.6.2 → atendentepro-0.6.4}/atendentepro/prompts/confirmation.py +0 -0
  37. {atendentepro-0.6.2 → atendentepro-0.6.4}/atendentepro/prompts/escalation.py +0 -0
  38. {atendentepro-0.6.2 → atendentepro-0.6.4}/atendentepro/prompts/feedback.py +0 -0
  39. {atendentepro-0.6.2 → atendentepro-0.6.4}/atendentepro/prompts/flow.py +0 -0
  40. {atendentepro-0.6.2 → atendentepro-0.6.4}/atendentepro/prompts/interview.py +0 -0
  41. {atendentepro-0.6.2 → atendentepro-0.6.4}/atendentepro/prompts/knowledge.py +0 -0
  42. {atendentepro-0.6.2 → atendentepro-0.6.4}/atendentepro/prompts/onboarding.py +0 -0
  43. {atendentepro-0.6.2 → atendentepro-0.6.4}/atendentepro/prompts/triage.py +0 -0
  44. {atendentepro-0.6.2 → atendentepro-0.6.4}/atendentepro/utils/__init__.py +0 -0
  45. {atendentepro-0.6.2 → atendentepro-0.6.4}/atendentepro/utils/openai_client.py +0 -0
  46. {atendentepro-0.6.2 → atendentepro-0.6.4}/atendentepro/utils/tracing.py +0 -0
  47. {atendentepro-0.6.2 → atendentepro-0.6.4}/atendentepro.egg-info/SOURCES.txt +0 -0
  48. {atendentepro-0.6.2 → atendentepro-0.6.4}/setup.cfg +0 -0
  49. {atendentepro-0.6.2 → atendentepro-0.6.4}/setup.py +0 -0
@@ -5,6 +5,46 @@ All notable changes to AtendentePro will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.6.4] - 2025-01-14
9
+
10
+ ### Added
11
+ - **Filtros de Acesso (Role/User)**: Novo sistema de controle de acesso baseado em roles e usuários
12
+ - `UserContext`: Contexto do usuário com user_id, role e metadata
13
+ - `AccessFilter`: Filtros whitelist/blacklist para roles e users
14
+ - `FilteredPromptSection`: Seções de prompt condicionais por role/user
15
+ - `FilteredTool`: Tools com filtro de acesso
16
+ - **Novos parâmetros em `create_standard_network`**:
17
+ - `user_context`: Contexto do usuário para filtragem
18
+ - `agent_filters`: Filtros de agente por role/user
19
+ - `conditional_prompts`: Prompts condicionais por role/user
20
+ - `filtered_tools`: Tools filtradas por role/user
21
+ - **Configuração via YAML** (`access_config.yaml`): Suporte a configuração de filtros via arquivo
22
+ - **Exemplos completos**: Pasta `docs/examples/access_filters/` com casos de uso
23
+
24
+ ### Documentation
25
+ - README atualizado com seção completa de Filtros de Acesso
26
+ - Exemplos de código e YAML para diferentes cenários
27
+
28
+ ## [0.6.3] - 2025-01-12
29
+
30
+ ### Changed
31
+ - **Dependências otimizadas**: numpy e scikit-learn movidos para opcional `[rag]`
32
+ - **Versões com limites**: Todas as dependências agora têm limites máximos de versão
33
+ - **CI mais rápido**: Cache de pip adicionado e matriz reduzida para Python 3.9 e 3.12
34
+ - Instalação base reduzida de ~300MB para ~50MB
35
+
36
+ ### Added
37
+ - **Exemplos de Single Reply Mode**: Pasta `docs/examples/single_reply/` com exemplos completos
38
+ - Documentação expandida no README com casos de uso práticos (FAQ Bot, Bot de Leads)
39
+
40
+ ### Fixed
41
+ - Warnings de instalação eliminados com pinagem de versões
42
+ - Tempo de deploy reduzido de ~40min para ~8-10min
43
+ - Verificação clara quando RAG dependencies não estão instaladas
44
+
45
+ ### Migration
46
+ - Se você usa RAG/Knowledge Agent, agora precisa: `pip install atendentepro[rag]`
47
+
8
48
  ## [0.6.2] - 2025-01-12
9
49
 
10
50
  ### Added
@@ -1,3 +1,61 @@
1
+ Metadata-Version: 2.4
2
+ Name: atendentepro
3
+ Version: 0.6.4
4
+ Summary: Framework de orquestração de agentes IA com tom e estilo customizáveis. Integra documentos (RAG), APIs e bancos de dados em uma plataforma inteligente multi-agente.
5
+ Author-email: BeMonkAI <contato@monkai.com.br>
6
+ Maintainer-email: BeMonkAI <contato@monkai.com.br>
7
+ License: Proprietary
8
+ Project-URL: Homepage, https://github.com/BeMonkAI/atendentepro
9
+ Project-URL: Documentation, https://github.com/BeMonkAI/atendentepro#readme
10
+ Project-URL: Repository, https://github.com/BeMonkAI/atendentepro
11
+ Project-URL: Issues, https://github.com/BeMonkAI/atendentepro/issues
12
+ Project-URL: Changelog, https://github.com/BeMonkAI/atendentepro/blob/main/CHANGELOG.md
13
+ Keywords: ai,agents,customer-service,chatbot,openai,multi-agent,atendimento,openai-agents,conversational-ai,rag,triage,handoff,escalation,feedback,knowledge-base,interview
14
+ Classifier: Development Status :: 4 - Beta
15
+ Classifier: Intended Audience :: Developers
16
+ Classifier: License :: Other/Proprietary License
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Programming Language :: Python :: 3.9
19
+ Classifier: Programming Language :: Python :: 3.10
20
+ Classifier: Programming Language :: Python :: 3.11
21
+ Classifier: Programming Language :: Python :: 3.12
22
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
23
+ Classifier: Topic :: Communications :: Chat
24
+ Classifier: Operating System :: OS Independent
25
+ Requires-Python: >=3.9
26
+ Description-Content-Type: text/markdown
27
+ License-File: LICENSE
28
+ Requires-Dist: openai-agents<1.0.0,>=0.3.3
29
+ Requires-Dist: openai<2.0.0,>=1.107.1
30
+ Requires-Dist: pydantic<3.0.0,>=2.0.0
31
+ Requires-Dist: PyYAML<7.0,>=6.0
32
+ Requires-Dist: python-dotenv<2.0.0,>=1.0.0
33
+ Requires-Dist: httpx<1.0.0,>=0.27.0
34
+ Provides-Extra: dev
35
+ Requires-Dist: pytest<9.0.0,>=7.0.0; extra == "dev"
36
+ Requires-Dist: pytest-asyncio<1.0.0,>=0.21.0; extra == "dev"
37
+ Requires-Dist: black<25.0.0,>=23.0.0; extra == "dev"
38
+ Requires-Dist: isort<6.0.0,>=5.12.0; extra == "dev"
39
+ Requires-Dist: mypy<2.0.0,>=1.0.0; extra == "dev"
40
+ Provides-Extra: docs
41
+ Requires-Dist: mkdocs<2.0.0,>=1.5.0; extra == "docs"
42
+ Requires-Dist: mkdocs-material<10.0.0,>=9.0.0; extra == "docs"
43
+ Provides-Extra: rag
44
+ Requires-Dist: numpy<2.0.0,>=1.24.0; extra == "rag"
45
+ Requires-Dist: scikit-learn<2.0.0,>=1.3.0; extra == "rag"
46
+ Requires-Dist: PyPDF2<4.0.0,>=3.0.0; extra == "rag"
47
+ Requires-Dist: python-docx<2.0.0,>=0.8.11; extra == "rag"
48
+ Requires-Dist: python-pptx<1.0.0,>=0.6.21; extra == "rag"
49
+ Requires-Dist: PyMuPDF<2.0.0,>=1.23.0; extra == "rag"
50
+ Provides-Extra: tracing
51
+ Requires-Dist: monkai-trace<1.0.0,>=0.2.9; extra == "tracing"
52
+ Provides-Extra: azure
53
+ Requires-Dist: opentelemetry-sdk<2.0.0,>=1.20.0; extra == "azure"
54
+ Requires-Dist: azure-monitor-opentelemetry-exporter<2.0.0,>=1.0.0; extra == "azure"
55
+ Provides-Extra: all
56
+ Requires-Dist: atendentepro[azure,dev,docs,rag,tracing]; extra == "all"
57
+ Dynamic: license-file
58
+
1
59
  # AtendentePro
2
60
 
3
61
  [![Python 3.9+](https://img.shields.io/badge/python-3.9+-blue.svg)](https://www.python.org/downloads/)
@@ -37,6 +95,7 @@ Plataforma que unifica múltiplos agentes especializados para resolver demandas
37
95
  - [Fluxo de Handoffs](#-fluxo-de-handoffs)
38
96
  - [Estilo de Comunicação](#-estilo-de-comunicação-agentstyle)
39
97
  - [Single Reply Mode](#-single-reply-mode)
98
+ - [Filtros de Acesso](#-filtros-de-acesso-roleuser)
40
99
  - [Tracing e Monitoramento](#-tracing-e-monitoramento)
41
100
  - [Suporte](#-suporte)
42
101
 
@@ -654,80 +713,328 @@ agents:
654
713
 
655
714
  O **Single Reply Mode** permite configurar agentes para responderem apenas uma vez e automaticamente transferirem de volta para o Triage. Isso evita que a conversa fique "presa" em um agente específico.
656
715
 
716
+ 📂 **Exemplos completos**: [docs/examples/single_reply/](docs/examples/single_reply/)
717
+
657
718
  ### Quando Usar
658
719
 
659
- - **Chatbots de alto volume**: Respostas rápidas e independentes
660
- - **Consultas simples**: Uma pergunta = uma resposta
661
- - **Evitar loops**: Impedir que usuários fiquem presos em um agente
720
+ | Cenário | Recomendação |
721
+ |---------|--------------|
722
+ | **Chatbots de alto volume** | Ativar para respostas rápidas |
723
+ | **FAQ simples** | ✅ Knowledge com single_reply |
724
+ | **Coleta de dados** | ❌ Interview precisa múltiplas interações |
725
+ | **Onboarding** | ❌ Precisa guiar o usuário em etapas |
726
+ | **Confirmações** | ✅ Confirma e volta ao Triage |
662
727
 
663
- ### Via Código
728
+ ### Exemplo 1: FAQ Bot (Via Código)
729
+
730
+ Chatbot otimizado para perguntas frequentes:
664
731
 
665
732
  ```python
666
733
  from pathlib import Path
667
734
  from atendentepro import create_standard_network
668
735
 
669
- # Ativar para TODOS os agentes
736
+ # FAQ Bot: Knowledge e Answer respondem uma vez
670
737
  network = create_standard_network(
671
738
  templates_root=Path("./meu_cliente"),
672
739
  client="config",
673
- global_single_reply=True, # Todos respondem uma vez
740
+ global_single_reply=False,
741
+ single_reply_agents={
742
+ "knowledge": True, # FAQ: responde e volta
743
+ "answer": True, # Perguntas gerais: responde e volta
744
+ "flow": True, # Menu: apresenta e volta
745
+ },
674
746
  )
747
+ ```
675
748
 
676
- # Ativar apenas para agentes específicos
749
+ ### Exemplo 2: Bot de Leads (Via Código)
750
+
751
+ Bot que coleta dados mas responde dúvidas rapidamente:
752
+
753
+ ```python
677
754
  network = create_standard_network(
678
755
  templates_root=Path("./meu_cliente"),
679
756
  client="config",
680
757
  global_single_reply=False,
681
758
  single_reply_agents={
682
- "knowledge": True, # Knowledge responde uma vez
683
- "confirmation": True, # Confirmation responde uma vez
684
- "answer": True, # Answer responde uma vez
685
- # interview: False # Interview pode ter múltiplas interações
759
+ # Interview PRECISA de múltiplas interações para coletar dados
760
+ "interview": False,
761
+
762
+ # Outros agentes podem ser rápidos
763
+ "knowledge": True, # Tira dúvidas sobre produto
764
+ "answer": True, # Responde perguntas
765
+ "confirmation": True, # Confirma cadastro
686
766
  },
687
767
  )
688
768
  ```
689
769
 
770
+ ### Exemplo 3: Ativar para TODOS os agentes
771
+
772
+ ```python
773
+ network = create_standard_network(
774
+ templates_root=Path("./meu_cliente"),
775
+ client="config",
776
+ global_single_reply=True, # Todos respondem uma vez
777
+ )
778
+ ```
779
+
690
780
  ### Via YAML (single_reply_config.yaml)
691
781
 
692
782
  Crie o arquivo `single_reply_config.yaml` na pasta do cliente:
693
783
 
694
784
  ```yaml
695
- # Global: aplica a todos os agentes
785
+ # Global: se true, TODOS os agentes respondem apenas uma vez
696
786
  global: false
697
787
 
698
- # Configuração por agente
788
+ # Configuração por agente (sobrescreve global)
699
789
  agents:
700
- # Agentes que respondem uma vez
701
- knowledge: true
702
- confirmation: true
703
- answer: true
790
+ # Agentes de consulta: respondem uma vez
791
+ knowledge: true # FAQ: responde e volta
792
+ answer: true # Perguntas: responde e volta
793
+ confirmation: true # Confirma e volta
794
+ usage: true # Explica uso e volta
704
795
 
705
- # Agentes que precisam de múltiplas interações
706
- interview: false
707
- flow: false
708
- onboarding: false
796
+ # Agentes de coleta: múltiplas interações
797
+ interview: false # Precisa coletar dados
798
+ onboarding: false # Precisa guiar usuário
799
+
800
+ # Opcionais
801
+ flow: true # Menu: apresenta e volta
802
+ escalation: true # Registra e volta
803
+ feedback: true # Coleta feedback e volta
804
+ ```
805
+
806
+ ### Fluxo Visual
807
+
808
+ **Com single_reply=True:**
809
+
810
+ ```
811
+ [Usuário: "Qual o preço?"]
812
+
813
+ [Triage] → detecta consulta
814
+
815
+ [Knowledge] → responde: "R$ 99,90"
816
+
817
+ [Triage] ← retorno AUTOMÁTICO
818
+
819
+ [Usuário: "E a entrega?"]
820
+
821
+ [Triage] → nova análise (ciclo reinicia)
822
+ ```
823
+
824
+ **Com single_reply=False (padrão):**
825
+
826
+ ```
827
+ [Usuário: "Qual o preço?"]
828
+
829
+ [Triage] → detecta consulta
830
+
831
+ [Knowledge] → responde: "R$ 99,90"
832
+
833
+ [Usuário: "E a entrega?"]
834
+
835
+ [Knowledge] → continua no mesmo agente
836
+
837
+ [Usuário: "Quero falar com humano"]
838
+
839
+ [Knowledge] → handoff para Escalation
840
+ ```
841
+
842
+ ### Configuração Recomendada
843
+
844
+ Para a maioria dos casos de uso:
845
+
846
+ ```yaml
847
+ global: false
848
+
849
+ agents:
850
+ knowledge: true # FAQ
851
+ answer: true # Perguntas gerais
852
+ confirmation: true # Confirmações
853
+
854
+ interview: false # Coleta de dados
855
+ onboarding: false # Guia de usuário
856
+ ```
857
+
858
+ ---
859
+
860
+ ## 🔐 Filtros de Acesso (Role/User)
861
+
862
+ O sistema de **Filtros de Acesso** permite controlar quais agentes, prompts e tools estão disponíveis para cada usuário ou role (função).
863
+
864
+ 📂 **Exemplos completos**: [docs/examples/access_filters/](docs/examples/access_filters/)
865
+
866
+ ### Quando Usar
867
+
868
+ | Cenário | Solução |
869
+ |---------|---------|
870
+ | **Multi-tenant** | Diferentes clientes veem diferentes agentes |
871
+ | **Níveis de acesso** | Admin vê mais opções que cliente |
872
+ | **Segurança** | Dados sensíveis só para roles específicas |
873
+ | **Personalização** | Diferentes instruções por departamento |
874
+
875
+ ### Níveis de Filtragem
876
+
877
+ 1. **Agentes**: Habilitar/desabilitar agentes inteiros
878
+ 2. **Prompts**: Adicionar seções condicionais aos prompts
879
+ 3. **Tools**: Habilitar/desabilitar tools específicas
880
+
881
+ ### Exemplo 1: Filtros de Agente (Via Código)
882
+
883
+ ```python
884
+ from pathlib import Path
885
+ from atendentepro import (
886
+ create_standard_network,
887
+ UserContext,
888
+ AccessFilter,
889
+ )
890
+
891
+ # Usuário com role de vendedor
892
+ user = UserContext(user_id="vendedor_123", role="vendedor")
893
+
894
+ # Filtros de agente
895
+ agent_filters = {
896
+ # Feedback só para admin
897
+ "feedback": AccessFilter(allowed_roles=["admin"]),
898
+ # Escalation para todos exceto clientes
899
+ "escalation": AccessFilter(denied_roles=["cliente"]),
900
+ }
901
+
902
+ network = create_standard_network(
903
+ templates_root=Path("./meu_cliente"),
904
+ client="config",
905
+ user_context=user,
906
+ agent_filters=agent_filters,
907
+ )
709
908
  ```
710
909
 
711
- ### Comportamento
910
+ ### Exemplo 2: Prompts Condicionais
712
911
 
713
- Quando `single_reply=True`:
912
+ Adicione instruções específicas baseadas na role:
714
913
 
914
+ ```python
915
+ from atendentepro import FilteredPromptSection
916
+
917
+ conditional_prompts = {
918
+ "knowledge": [
919
+ # Seção para vendedores
920
+ FilteredPromptSection(
921
+ content="\\n## Descontos\\nVocê pode oferecer até 15% de desconto.",
922
+ filter=AccessFilter(allowed_roles=["vendedor"]),
923
+ ),
924
+ # Seção para admin
925
+ FilteredPromptSection(
926
+ content="\\n## Admin\\nVocê tem acesso total ao sistema.",
927
+ filter=AccessFilter(allowed_roles=["admin"]),
928
+ ),
929
+ ],
930
+ }
931
+
932
+ network = create_standard_network(
933
+ templates_root=Path("./meu_cliente"),
934
+ client="config",
935
+ user_context=user,
936
+ conditional_prompts=conditional_prompts,
937
+ )
715
938
  ```
716
- [Usuário] → [Triage] → [Knowledge]
717
-
718
- (responde uma vez)
719
-
720
- [Triage] (retorno automático)
939
+
940
+ ### Exemplo 3: Tools Filtradas
941
+
942
+ ```python
943
+ from atendentepro import FilteredTool
944
+ from agents import function_tool
945
+
946
+ @function_tool
947
+ def deletar_cliente(cliente_id: str) -> str:
948
+ """Remove um cliente do sistema."""
949
+ return f"Cliente {cliente_id} removido"
950
+
951
+ filtered_tools = {
952
+ "knowledge": [
953
+ FilteredTool(
954
+ tool=deletar_cliente,
955
+ filter=AccessFilter(allowed_roles=["admin"]), # Só admin
956
+ ),
957
+ ],
958
+ }
959
+
960
+ network = create_standard_network(
961
+ templates_root=Path("./meu_cliente"),
962
+ client="config",
963
+ user_context=user,
964
+ filtered_tools=filtered_tools,
965
+ )
721
966
  ```
722
967
 
723
- Quando `single_reply=False` (padrão):
968
+ ### Via YAML (access_config.yaml)
969
+
970
+ ```yaml
971
+ # Filtros de agente
972
+ agent_filters:
973
+ feedback:
974
+ allowed_roles: ["admin"]
975
+ escalation:
976
+ denied_roles: ["cliente"]
977
+
978
+ # Prompts condicionais
979
+ conditional_prompts:
980
+ knowledge:
981
+ - content: |
982
+ ## Capacidades de Vendedor
983
+ Você pode oferecer até 15% de desconto.
984
+ filter:
985
+ allowed_roles: ["vendedor"]
986
+
987
+ # Acesso a tools
988
+ tool_access:
989
+ deletar_cliente:
990
+ allowed_roles: ["admin"]
991
+ ```
992
+
993
+ ### Tipos de Filtro
994
+
995
+ | Tipo | Descrição | Exemplo |
996
+ |------|-----------|---------|
997
+ | `allowed_roles` | Whitelist de roles | `["admin", "gerente"]` |
998
+ | `denied_roles` | Blacklist de roles | `["cliente"]` |
999
+ | `allowed_users` | Whitelist de usuários | `["user_vip_1"]` |
1000
+ | `denied_users` | Blacklist de usuários | `["user_bloqueado"]` |
1001
+
1002
+ ### Prioridade de Avaliação
1003
+
1004
+ 1. `denied_users` - Se usuário está negado, **bloqueia**
1005
+ 2. `allowed_users` - Se lista existe e usuário está nela, **permite**
1006
+ 3. `denied_roles` - Se role está negada, **bloqueia**
1007
+ 4. `allowed_roles` - Se lista existe e role não está nela, **bloqueia**
1008
+ 5. **Permite por padrão** - Se nenhum filtro matched
1009
+
1010
+ ### Fluxo Visual
724
1011
 
725
1012
  ```
726
- [Usuário] → [Triage] → [Knowledge]
727
-
728
- (pode continuar)
729
-
730
- [Usuário]
1013
+ ┌────────────────────────────────────────────────┐
1014
+ │ Requisição: role="vendedor" │
1015
+ └────────────────────────────────────────────────┘
1016
+
1017
+
1018
+ ┌────────────────────────────────────────────────┐
1019
+ │ FILTRO DE AGENTES │
1020
+ │ Knowledge: ✅ (vendedor allowed) │
1021
+ │ Escalation: ✅ (vendedor not denied) │
1022
+ │ Feedback: ❌ (only admin) │
1023
+ └────────────────────────────────────────────────┘
1024
+
1025
+
1026
+ ┌────────────────────────────────────────────────┐
1027
+ │ FILTRO DE PROMPTS │
1028
+ │ Knowledge recebe: "## Descontos..." │
1029
+ │ (seção condicional para vendedor) │
1030
+ └────────────────────────────────────────────────┘
1031
+
1032
+
1033
+ ┌────────────────────────────────────────────────┐
1034
+ │ FILTRO DE TOOLS │
1035
+ │ consultar_comissao: ✅ │
1036
+ │ deletar_cliente: ❌ (only admin) │
1037
+ └────────────────────────────────────────────────┘
731
1038
  ```
732
1039
 
733
1040
  ---