atendentepro 0.5.7__py3-none-any.whl → 0.6.0__py3-none-any.whl

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.
atendentepro/README.md CHANGED
@@ -1191,7 +1191,81 @@ flowchart LR
1191
1191
  FEED --> |Protocolo TKT| EMAIL[Email + Ticket]
1192
1192
  ```
1193
1193
 
1194
- ### Passo 11: Criar Rede Específica (Opcional)
1194
+ ### Passo 11: Configurar Estilo de Comunicação (Opcional - style_config.yaml)
1195
+
1196
+ O **AgentStyle** permite personalizar o tom e estilo de comunicação dos agentes.
1197
+
1198
+ #### Configuração YAML
1199
+
1200
+ ```yaml
1201
+ # style_config.yaml
1202
+
1203
+ # Estilo Global (aplicado a todos os agentes por padrão)
1204
+ global:
1205
+ tone: "profissional e cordial"
1206
+ language_style: "formal" # formal, informal, neutro
1207
+ response_length: "moderado" # conciso, moderado, detalhado
1208
+ custom_rules: |
1209
+ - Seja objetivo e claro nas respostas
1210
+ - Use linguagem inclusiva
1211
+
1212
+ # Estilos específicos por agente (sobrescrevem o global)
1213
+ agents:
1214
+ escalation:
1215
+ tone: "empático e tranquilizador"
1216
+ custom_rules: |
1217
+ - Demonstre compreensão pela situação do usuário
1218
+ - Assegure que o problema será resolvido
1219
+
1220
+ knowledge:
1221
+ tone: "didático e paciente"
1222
+ response_length: "detalhado"
1223
+ custom_rules: |
1224
+ - Explique conceitos de forma acessível
1225
+ - Cite as fontes das informações
1226
+ ```
1227
+
1228
+ #### Uso Programático com AgentStyle
1229
+
1230
+ ```python
1231
+ from pathlib import Path
1232
+ from atendentepro import create_standard_network, AgentStyle
1233
+
1234
+ # Estilo global formal
1235
+ global_style = AgentStyle(
1236
+ tone="profissional e consultivo",
1237
+ language_style="formal",
1238
+ response_length="moderado",
1239
+ custom_rules="Sempre se apresente como assistente da empresa.",
1240
+ )
1241
+
1242
+ # Estilo específico para escalation (mais empático)
1243
+ escalation_style = AgentStyle(
1244
+ tone="empático e acolhedor",
1245
+ custom_rules="Demonstre compreensão e assegure resolução.",
1246
+ )
1247
+
1248
+ network = create_standard_network(
1249
+ templates_root=Path("./client_templates"),
1250
+ client="meu_cliente",
1251
+ global_style=global_style,
1252
+ agent_styles={
1253
+ "escalation": escalation_style,
1254
+ "feedback": AgentStyle(tone="solícito", custom_rules="Agradeça o feedback."),
1255
+ },
1256
+ )
1257
+ ```
1258
+
1259
+ #### Opções Disponíveis
1260
+
1261
+ | Parâmetro | Valores | Descrição |
1262
+ |-----------|---------|-----------|
1263
+ | `tone` | Texto livre | Tom da conversa (ex: "profissional", "empático") |
1264
+ | `language_style` | `formal`, `informal`, `neutro` | Nível de formalidade |
1265
+ | `response_length` | `conciso`, `moderado`, `detalhado` | Tamanho das respostas |
1266
+ | `custom_rules` | Texto livre | Regras adicionais personalizadas |
1267
+
1268
+ ### Passo 12: Criar Rede Específica (Opcional)
1195
1269
 
1196
1270
  Se precisar de lógica customizada:
1197
1271
 
@@ -1285,6 +1359,7 @@ client_templates/meu_cliente/
1285
1359
  ├── escalation_config.yaml # ✅ Recomendado - Transferência humana
1286
1360
  ├── feedback_config.yaml # ✅ Recomendado - Tickets/SAC
1287
1361
  ├── guardrails_config.yaml # ✅ Recomendado - Políticas de segurança
1362
+ ├── style_config.yaml # Opcional - Tom e estilo de comunicação
1288
1363
 
1289
1364
  │ # Dados (opcionais)
1290
1365
  ├── data/ # Dados estruturados
@@ -1310,6 +1385,7 @@ client_templates/meu_cliente/
1310
1385
  | `escalation_config.yaml` | Escalation | Recomendado | Canais e triggers |
1311
1386
  | `feedback_config.yaml` | Feedback | Recomendado | Tipos ticket e email |
1312
1387
  | `guardrails_config.yaml` | Todos | Recomendado | Escopo e restrições |
1388
+ | `style_config.yaml` | Todos | Opcional | Tom e estilo de comunicação |
1313
1389
 
1314
1390
  ---
1315
1391
 
atendentepro/__init__.py CHANGED
@@ -113,6 +113,7 @@ from atendentepro.agents import (
113
113
  # Network
114
114
  from atendentepro.network import (
115
115
  AgentNetwork,
116
+ AgentStyle,
116
117
  create_standard_network,
117
118
  create_custom_network,
118
119
  )
@@ -211,6 +212,7 @@ __all__ = [
211
212
  "configure_feedback_storage",
212
213
  # Network
213
214
  "AgentNetwork",
215
+ "AgentStyle",
214
216
  "create_standard_network",
215
217
  "create_custom_network",
216
218
  # Templates
@@ -25,6 +25,7 @@ def create_answer_agent(
25
25
  guardrails: Optional[List["GuardrailCallable"]] = None,
26
26
  name: str = "Answer Agent",
27
27
  custom_instructions: Optional[str] = None,
28
+ style_instructions: str = "",
28
29
  ) -> AnswerAgent:
29
30
  """
30
31
  Create an Answer Agent instance.
@@ -38,6 +39,7 @@ def create_answer_agent(
38
39
  guardrails: List of input guardrails.
39
40
  name: Agent name.
40
41
  custom_instructions: Optional custom instructions to override default.
42
+ style_instructions: Optional style/tone instructions to append.
41
43
 
42
44
  Returns:
43
45
  Configured Answer Agent instance.
@@ -48,6 +50,10 @@ def create_answer_agent(
48
50
  prompt = get_answer_prompt(answer_template=answer_template)
49
51
  instructions = f"{RECOMMENDED_PROMPT_PREFIX} {prompt}"
50
52
 
53
+ # Append style instructions if provided
54
+ if style_instructions:
55
+ instructions += style_instructions
56
+
51
57
  return Agent[ContextNote](
52
58
  name=name,
53
59
  handoff_description=(
@@ -27,6 +27,7 @@ def create_confirmation_agent(
27
27
  guardrails: Optional[List["GuardrailCallable"]] = None,
28
28
  name: str = "Confirmation Agent",
29
29
  custom_instructions: Optional[str] = None,
30
+ style_instructions: str = "",
30
31
  ) -> ConfirmationAgent:
31
32
  """
32
33
  Create a Confirmation Agent instance.
@@ -42,6 +43,7 @@ def create_confirmation_agent(
42
43
  guardrails: List of input guardrails.
43
44
  name: Agent name.
44
45
  custom_instructions: Optional custom instructions to override default.
46
+ style_instructions: Optional style/tone instructions to append.
45
47
 
46
48
  Returns:
47
49
  Configured Confirmation Agent instance.
@@ -56,6 +58,10 @@ def create_confirmation_agent(
56
58
  )
57
59
  instructions = f"{RECOMMENDED_PROMPT_PREFIX} {prompt}"
58
60
 
61
+ # Append style instructions if provided
62
+ if style_instructions:
63
+ instructions += style_instructions
64
+
59
65
  return Agent[ContextNote](
60
66
  name=name,
61
67
  handoff_description=(
@@ -454,6 +454,7 @@ def create_escalation_agent(
454
454
  guardrails: Optional[List["GuardrailCallable"]] = None,
455
455
  name: str = "Escalation Agent",
456
456
  custom_instructions: Optional[str] = None,
457
+ style_instructions: str = "",
457
458
  ) -> EscalationAgent:
458
459
  """
459
460
  Create an Escalation Agent instance.
@@ -475,6 +476,7 @@ def create_escalation_agent(
475
476
  guardrails: List of input guardrails.
476
477
  name: Agent name.
477
478
  custom_instructions: Optional custom instructions to override default.
479
+ style_instructions: Optional style/tone instructions to append.
478
480
 
479
481
  Returns:
480
482
  Configured Escalation Agent instance.
@@ -494,6 +496,10 @@ def create_escalation_agent(
494
496
  # Usar o prompt builder do módulo prompts
495
497
  instructions = f"{RECOMMENDED_PROMPT_PREFIX}\n{get_escalation_prompt(escalation_triggers=escalation_triggers, escalation_channels=escalation_channels)}"
496
498
 
499
+ # Append style instructions if provided
500
+ if style_instructions:
501
+ instructions += style_instructions
502
+
497
503
  # Combinar tools padrão com customizadas
498
504
  agent_tools = list(ESCALATION_TOOLS)
499
505
  if tools:
@@ -894,6 +894,7 @@ def create_feedback_agent(
894
894
  guardrails: Optional[List["GuardrailCallable"]] = None,
895
895
  name: str = "Feedback Agent",
896
896
  custom_instructions: Optional[str] = None,
897
+ style_instructions: str = "",
897
898
  ) -> FeedbackAgent:
898
899
  """
899
900
  Create a Feedback Agent for collecting user feedback, questions, and complaints.
@@ -919,6 +920,7 @@ def create_feedback_agent(
919
920
  guardrails: List of input guardrails.
920
921
  name: Agent name.
921
922
  custom_instructions: Override default instructions.
923
+ style_instructions: Optional style/tone instructions to append.
922
924
 
923
925
  Returns:
924
926
  Configured Feedback Agent instance.
@@ -945,6 +947,10 @@ def create_feedback_agent(
945
947
  # Usar o prompt builder do módulo prompts
946
948
  instructions = f"{RECOMMENDED_PROMPT_PREFIX}\n{get_feedback_prompt(ticket_types=ticket_types, protocol_prefix=protocol_prefix, brand_name=email_brand_name, sla_message=email_sla_message)}"
947
949
 
950
+ # Append style instructions if provided
951
+ if style_instructions:
952
+ instructions += style_instructions
953
+
948
954
  # Combine tools
949
955
  agent_tools = list(FEEDBACK_TOOLS)
950
956
  if tools:
@@ -26,6 +26,7 @@ def create_flow_agent(
26
26
  guardrails: Optional[List["GuardrailCallable"]] = None,
27
27
  name: str = "Flow Agent",
28
28
  custom_instructions: Optional[str] = None,
29
+ style_instructions: str = "",
29
30
  ) -> FlowAgent:
30
31
  """
31
32
  Create a Flow Agent instance.
@@ -39,6 +40,7 @@ def create_flow_agent(
39
40
  guardrails: List of input guardrails.
40
41
  name: Agent name.
41
42
  custom_instructions: Optional custom instructions to override default.
43
+ style_instructions: Optional style/tone instructions to append.
42
44
 
43
45
  Returns:
44
46
  Configured Flow Agent instance.
@@ -49,6 +51,10 @@ def create_flow_agent(
49
51
  prompt = get_flow_prompt(flow_template=flow_template, flow_keywords=flow_keywords)
50
52
  instructions = f"{RECOMMENDED_PROMPT_PREFIX} {prompt}"
51
53
 
54
+ # Append style instructions if provided
55
+ if style_instructions:
56
+ instructions += style_instructions
57
+
52
58
  return Agent[ContextNote](
53
59
  name=name,
54
60
  handoff_description="""
@@ -27,6 +27,7 @@ def create_interview_agent(
27
27
  guardrails: Optional[List["GuardrailCallable"]] = None,
28
28
  name: str = "Interview Agent",
29
29
  custom_instructions: Optional[str] = None,
30
+ style_instructions: str = "",
30
31
  ) -> InterviewAgent:
31
32
  """
32
33
  Create an Interview Agent instance.
@@ -42,6 +43,7 @@ def create_interview_agent(
42
43
  guardrails: List of input guardrails.
43
44
  name: Agent name.
44
45
  custom_instructions: Optional custom instructions to override default.
46
+ style_instructions: Optional style/tone instructions to append.
45
47
 
46
48
  Returns:
47
49
  Configured Interview Agent instance.
@@ -55,6 +57,10 @@ def create_interview_agent(
55
57
  )
56
58
  instructions = f"{RECOMMENDED_PROMPT_PREFIX} {prompt}"
57
59
 
60
+ # Append style instructions if provided
61
+ if style_instructions:
62
+ instructions += style_instructions
63
+
58
64
  return Agent[ContextNote](
59
65
  name=name,
60
66
  handoff_description="""
@@ -217,6 +217,7 @@ def create_knowledge_agent(
217
217
  guardrails: Optional[List["GuardrailCallable"]] = None,
218
218
  name: str = "Knowledge Agent",
219
219
  custom_instructions: Optional[str] = None,
220
+ style_instructions: str = "",
220
221
  ) -> KnowledgeAgent:
221
222
  """
222
223
  Create a Knowledge Agent instance.
@@ -239,6 +240,7 @@ def create_knowledge_agent(
239
240
  guardrails: List of input guardrails.
240
241
  name: Agent name.
241
242
  custom_instructions: Optional custom instructions to override default.
243
+ style_instructions: Optional style/tone instructions to append.
242
244
 
243
245
  Returns:
244
246
  Configured Knowledge Agent instance.
@@ -262,6 +264,10 @@ def create_knowledge_agent(
262
264
  )
263
265
  instructions = f"{RECOMMENDED_PROMPT_PREFIX} {prompt}"
264
266
 
267
+ # Append style instructions if provided
268
+ if style_instructions:
269
+ instructions += style_instructions
270
+
265
271
  # Build tools list
266
272
  agent_tools: List = []
267
273
 
@@ -27,6 +27,7 @@ def create_onboarding_agent(
27
27
  guardrails: Optional[List["GuardrailCallable"]] = None,
28
28
  name: str = "Onboarding Agent",
29
29
  custom_instructions: Optional[str] = None,
30
+ style_instructions: str = "",
30
31
  ) -> OnboardingAgent:
31
32
  """
32
33
  Create an Onboarding Agent instance.
@@ -41,6 +42,7 @@ def create_onboarding_agent(
41
42
  guardrails: List of input guardrails.
42
43
  name: Agent name.
43
44
  custom_instructions: Optional custom instructions to override default.
45
+ style_instructions: Optional style/tone instructions to append.
44
46
 
45
47
  Returns:
46
48
  Configured Onboarding Agent instance.
@@ -51,6 +53,10 @@ def create_onboarding_agent(
51
53
  prompt = get_onboarding_prompt(required_fields=required_fields)
52
54
  instructions = f"{RECOMMENDED_PROMPT_PREFIX} {prompt}"
53
55
 
56
+ # Append style instructions if provided
57
+ if style_instructions:
58
+ instructions += style_instructions
59
+
54
60
  return Agent[ContextNote](
55
61
  name=name,
56
62
  handoff_description=(
@@ -25,6 +25,7 @@ def create_triage_agent(
25
25
  guardrails: Optional[List["GuardrailCallable"]] = None,
26
26
  name: str = "Triage Agent",
27
27
  custom_instructions: Optional[str] = None,
28
+ style_instructions: str = "",
28
29
  ) -> TriageAgent:
29
30
  """
30
31
  Create a Triage Agent instance.
@@ -38,6 +39,7 @@ def create_triage_agent(
38
39
  guardrails: List of input guardrails.
39
40
  name: Agent name.
40
41
  custom_instructions: Optional custom instructions to override default.
42
+ style_instructions: Optional style/tone instructions to append.
41
43
 
42
44
  Returns:
43
45
  Configured Triage Agent instance.
@@ -47,6 +49,10 @@ def create_triage_agent(
47
49
  else:
48
50
  instructions = f"{RECOMMENDED_PROMPT_PREFIX} {get_triage_prompt(keywords_text)}"
49
51
 
52
+ # Append style instructions if provided
53
+ if style_instructions:
54
+ instructions += style_instructions
55
+
50
56
  return Agent[ContextNote](
51
57
  name=name,
52
58
  handoff_description="A triage agent that can delegate a customer's request to the appropriate agent.",
@@ -29,6 +29,7 @@ def create_usage_agent(
29
29
  guardrails: Optional[List["GuardrailCallable"]] = None,
30
30
  name: str = "Usage Agent",
31
31
  custom_instructions: Optional[str] = None,
32
+ style_instructions: str = "",
32
33
  ) -> UsageAgent:
33
34
  """
34
35
  Create a Usage Agent instance.
@@ -40,12 +41,17 @@ def create_usage_agent(
40
41
  guardrails: List of input guardrails.
41
42
  name: Agent name.
42
43
  custom_instructions: Optional custom instructions to override default.
44
+ style_instructions: Optional style/tone instructions to append.
43
45
 
44
46
  Returns:
45
47
  Configured Usage Agent instance.
46
48
  """
47
49
  instructions = custom_instructions or DEFAULT_USAGE_INSTRUCTIONS
48
50
 
51
+ # Append style instructions if provided
52
+ if style_instructions:
53
+ instructions += style_instructions
54
+
49
55
  return Agent[ContextNote](
50
56
  name=name,
51
57
  handoff_description="A usage agent that can answer questions about the usage of the system.",
atendentepro/network.py CHANGED
@@ -11,6 +11,84 @@ from dataclasses import dataclass, field
11
11
  from pathlib import Path
12
12
  from typing import Any, Callable, Dict, List, Literal, Optional
13
13
 
14
+
15
+ # =============================================================================
16
+ # Agent Style Configuration
17
+ # =============================================================================
18
+
19
+ @dataclass
20
+ class AgentStyle:
21
+ """
22
+ Configuration for agent conversation style and tone.
23
+
24
+ Allows customizing how agents communicate with users,
25
+ including tone, language style, response length, and custom rules.
26
+
27
+ Attributes:
28
+ tone: Conversation tone (e.g., "profissional", "empático", "consultivo")
29
+ language_style: Language formality ("formal", "informal", "neutro")
30
+ response_length: Response verbosity ("conciso", "moderado", "detalhado")
31
+ custom_rules: Additional custom rules as text
32
+
33
+ Example:
34
+ >>> style = AgentStyle(
35
+ ... tone="empático e acolhedor",
36
+ ... language_style="formal",
37
+ ... response_length="moderado",
38
+ ... custom_rules="Sempre se apresente como assistente da empresa."
39
+ ... )
40
+ >>> print(style.build_style_prompt())
41
+ """
42
+
43
+ tone: str = ""
44
+ language_style: str = "" # formal, informal, neutro
45
+ response_length: str = "" # conciso, moderado, detalhado
46
+ custom_rules: str = ""
47
+
48
+ def build_style_prompt(self) -> str:
49
+ """
50
+ Build style instructions to append to agent prompts.
51
+
52
+ Returns:
53
+ Formatted style instructions as a string.
54
+ """
55
+ parts = []
56
+
57
+ if self.tone:
58
+ parts.append(f"**Tom de conversa:** {self.tone}.")
59
+
60
+ if self.language_style:
61
+ style_map = {
62
+ "formal": "Use linguagem formal e respeitosa, evitando gírias e expressões coloquiais.",
63
+ "informal": "Use linguagem informal e descontraída, aproximando-se do usuário.",
64
+ "neutro": "Use linguagem neutra e objetiva, focando na clareza.",
65
+ }
66
+ instruction = style_map.get(
67
+ self.language_style.lower(),
68
+ f"Estilo de linguagem: {self.language_style}"
69
+ )
70
+ parts.append(f"**Linguagem:** {instruction}")
71
+
72
+ if self.response_length:
73
+ length_map = {
74
+ "conciso": "Seja conciso e direto nas respostas, evitando informações desnecessárias.",
75
+ "moderado": "Forneça respostas com nível médio de detalhe, equilibrando clareza e completude.",
76
+ "detalhado": "Forneça respostas detalhadas e completas, explicando cada ponto relevante.",
77
+ }
78
+ instruction = length_map.get(
79
+ self.response_length.lower(),
80
+ f"Tamanho das respostas: {self.response_length}"
81
+ )
82
+ parts.append(f"**Respostas:** {instruction}")
83
+
84
+ if self.custom_rules:
85
+ parts.append(f"**Regras adicionais:**\n{self.custom_rules}")
86
+
87
+ if not parts:
88
+ return ""
89
+
90
+ return "\n\n## Estilo de Comunicação\n" + "\n\n".join(parts)
91
+
14
92
  from atendentepro.agents import (
15
93
  create_triage_agent,
16
94
  create_flow_agent,
@@ -118,6 +196,9 @@ def create_standard_network(
118
196
  feedback_brand_color: str = "#4A90D9",
119
197
  feedback_brand_name: str = "Atendimento",
120
198
  custom_tools: Optional[Dict[str, List]] = None,
199
+ # Style configuration
200
+ global_style: Optional[AgentStyle] = None,
201
+ agent_styles: Optional[Dict[str, AgentStyle]] = None,
121
202
  ) -> AgentNetwork:
122
203
  """
123
204
  Create a standard agent network with proper handoff configuration.
@@ -153,6 +234,8 @@ def create_standard_network(
153
234
  feedback_brand_color: Brand color for feedback emails.
154
235
  feedback_brand_name: Brand name for feedback emails.
155
236
  custom_tools: Optional dict of custom tools by agent name.
237
+ global_style: Style configuration applied to all agents (tone, language, etc.).
238
+ agent_styles: Dict mapping agent names to specific styles (overrides global).
156
239
 
157
240
  Returns:
158
241
  Configured AgentNetwork instance.
@@ -178,6 +261,23 @@ def create_standard_network(
178
261
  include_escalation=False,
179
262
  include_feedback=False,
180
263
  )
264
+
265
+ # Create network with custom communication style
266
+ network = create_standard_network(
267
+ templates_root=Path("templates"),
268
+ client="my_client",
269
+ global_style=AgentStyle(
270
+ tone="profissional e consultivo",
271
+ language_style="formal",
272
+ response_length="moderado",
273
+ ),
274
+ agent_styles={
275
+ "escalation": AgentStyle(
276
+ tone="empático e acolhedor",
277
+ custom_rules="Demonstre compreensão pela situação.",
278
+ ),
279
+ },
280
+ )
181
281
  """
182
282
  # Verificar licença
183
283
  require_activation()
@@ -245,11 +345,23 @@ def create_standard_network(
245
345
  # Get custom tools
246
346
  tools = custom_tools or {}
247
347
 
348
+ # Style helper function
349
+ def get_style_for_agent(agent_name: str) -> str:
350
+ """Get style instructions for a specific agent."""
351
+ # Agent-specific style takes precedence
352
+ if agent_styles and agent_name in agent_styles:
353
+ return agent_styles[agent_name].build_style_prompt()
354
+ # Fall back to global style
355
+ if global_style:
356
+ return global_style.build_style_prompt()
357
+ return ""
358
+
248
359
  # Create agents without handoffs first
249
360
  # Triage is always created (entry point)
250
361
  triage = create_triage_agent(
251
362
  keywords_text=triage_keywords,
252
363
  guardrails=get_guardrails_for_agent("Triage Agent", templates_root),
364
+ style_instructions=get_style_for_agent("triage"),
253
365
  )
254
366
 
255
367
  # Create optional agents based on include flags
@@ -259,6 +371,7 @@ def create_standard_network(
259
371
  flow_template=flow_template,
260
372
  flow_keywords=flow_keywords,
261
373
  guardrails=get_guardrails_for_agent("Flow Agent", templates_root),
374
+ style_instructions=get_style_for_agent("flow"),
262
375
  )
263
376
 
264
377
  interview = None
@@ -268,6 +381,7 @@ def create_standard_network(
268
381
  interview_questions=interview_questions,
269
382
  tools=tools.get("interview", []),
270
383
  guardrails=get_guardrails_for_agent("Interview Agent", templates_root),
384
+ style_instructions=get_style_for_agent("interview"),
271
385
  )
272
386
 
273
387
  answer = None
@@ -275,6 +389,7 @@ def create_standard_network(
275
389
  answer = create_answer_agent(
276
390
  answer_template="",
277
391
  guardrails=get_guardrails_for_agent("Answer Agent", templates_root),
392
+ style_instructions=get_style_for_agent("answer"),
278
393
  )
279
394
 
280
395
  knowledge = None
@@ -288,6 +403,7 @@ def create_standard_network(
288
403
  include_rag_tool=has_embeddings,
289
404
  tools=tools.get("knowledge", []),
290
405
  guardrails=get_guardrails_for_agent("Knowledge Agent", templates_root),
406
+ style_instructions=get_style_for_agent("knowledge"),
291
407
  )
292
408
 
293
409
  confirmation = None
@@ -297,12 +413,14 @@ def create_standard_network(
297
413
  confirmation_template=confirmation_template,
298
414
  confirmation_format=confirmation_format,
299
415
  guardrails=get_guardrails_for_agent("Confirmation Agent", templates_root),
416
+ style_instructions=get_style_for_agent("confirmation"),
300
417
  )
301
418
 
302
419
  usage = None
303
420
  if include_usage:
304
421
  usage = create_usage_agent(
305
422
  guardrails=get_guardrails_for_agent("Usage Agent", templates_root),
423
+ style_instructions=get_style_for_agent("usage"),
306
424
  )
307
425
 
308
426
  # Create escalation agent if requested
@@ -312,6 +430,7 @@ def create_standard_network(
312
430
  escalation_channels=escalation_channels,
313
431
  tools=tools.get("escalation", []),
314
432
  guardrails=get_guardrails_for_agent("Escalation Agent", templates_root),
433
+ style_instructions=get_style_for_agent("escalation"),
315
434
  )
316
435
 
317
436
  # Create feedback agent if requested
@@ -323,6 +442,7 @@ def create_standard_network(
323
442
  email_brand_name=feedback_brand_name,
324
443
  tools=tools.get("feedback", []),
325
444
  guardrails=get_guardrails_for_agent("Feedback Agent", templates_root),
445
+ style_instructions=get_style_for_agent("feedback"),
326
446
  )
327
447
 
328
448
  # Configure handoffs dynamically based on which agents are included
@@ -433,6 +553,7 @@ def create_standard_network(
433
553
  required_fields=fields,
434
554
  tools=tools.get("onboarding", []),
435
555
  guardrails=get_guardrails_for_agent("Onboarding Agent", templates_root),
556
+ style_instructions=get_style_for_agent("onboarding"),
436
557
  )
437
558
 
438
559
  network.onboarding = onboarding
@@ -14,12 +14,15 @@ from .manager import (
14
14
  load_knowledge_config,
15
15
  load_confirmation_config,
16
16
  load_onboarding_config,
17
+ load_style_config,
17
18
  FlowConfig,
18
19
  InterviewConfig,
19
20
  TriageConfig,
20
21
  KnowledgeConfig,
21
22
  ConfirmationConfig,
22
23
  OnboardingConfig,
24
+ StyleConfig,
25
+ AgentStyleConfig,
23
26
  DataSourceConfig,
24
27
  DataSourceColumn,
25
28
  DocumentConfig,
@@ -38,12 +41,15 @@ __all__ = [
38
41
  "load_knowledge_config",
39
42
  "load_confirmation_config",
40
43
  "load_onboarding_config",
44
+ "load_style_config",
41
45
  "FlowConfig",
42
46
  "InterviewConfig",
43
47
  "TriageConfig",
44
48
  "KnowledgeConfig",
45
49
  "ConfirmationConfig",
46
50
  "OnboardingConfig",
51
+ "StyleConfig",
52
+ "AgentStyleConfig",
47
53
  "DataSourceConfig",
48
54
  "DataSourceColumn",
49
55
  "DocumentConfig",
@@ -314,6 +314,83 @@ class OnboardingField(BaseModel):
314
314
  priority: int = 0
315
315
 
316
316
 
317
+ class AgentStyleConfig(BaseModel):
318
+ """Configuration for individual agent style."""
319
+
320
+ tone: str = ""
321
+ language_style: str = "" # formal, informal, neutro
322
+ response_length: str = "" # conciso, moderado, detalhado
323
+ custom_rules: str = ""
324
+
325
+
326
+ class StyleConfig(BaseModel):
327
+ """Configuration model for agent communication styles.
328
+
329
+ Allows customizing tone, language, and response style globally
330
+ or per-agent through YAML configuration.
331
+
332
+ Example YAML:
333
+ global:
334
+ tone: "profissional e cordial"
335
+ language_style: "formal"
336
+ response_length: "moderado"
337
+
338
+ agents:
339
+ escalation:
340
+ tone: "empático e acolhedor"
341
+ custom_rules: "Demonstre compreensão"
342
+ """
343
+
344
+ global_style: AgentStyleConfig = Field(default_factory=AgentStyleConfig)
345
+ agents: Dict[str, AgentStyleConfig] = Field(default_factory=dict)
346
+
347
+ @classmethod
348
+ @lru_cache(maxsize=4)
349
+ def load(cls, path: Path) -> "StyleConfig":
350
+ """Load style configuration from YAML file."""
351
+ if not path.exists():
352
+ raise FileNotFoundError(f"Style config not found at {path}")
353
+
354
+ with open(path, "r", encoding="utf-8") as f:
355
+ data = yaml.safe_load(f) or {}
356
+
357
+ # Parse global style
358
+ global_data = data.get("global", {})
359
+ global_style = AgentStyleConfig(
360
+ tone=global_data.get("tone", ""),
361
+ language_style=global_data.get("language_style", ""),
362
+ response_length=global_data.get("response_length", ""),
363
+ custom_rules=global_data.get("custom_rules", ""),
364
+ )
365
+
366
+ # Parse agent-specific styles
367
+ agents = {}
368
+ for agent_name, agent_data in data.get("agents", {}).items():
369
+ agents[agent_name] = AgentStyleConfig(
370
+ tone=agent_data.get("tone", ""),
371
+ language_style=agent_data.get("language_style", ""),
372
+ response_length=agent_data.get("response_length", ""),
373
+ custom_rules=agent_data.get("custom_rules", ""),
374
+ )
375
+
376
+ return cls(global_style=global_style, agents=agents)
377
+
378
+ def get_style_for_agent(self, agent_name: str) -> AgentStyleConfig:
379
+ """Get style configuration for a specific agent."""
380
+ # Agent-specific style takes precedence
381
+ if agent_name in self.agents:
382
+ agent_style = self.agents[agent_name]
383
+ # Merge with global (agent-specific overrides global)
384
+ return AgentStyleConfig(
385
+ tone=agent_style.tone or self.global_style.tone,
386
+ language_style=agent_style.language_style or self.global_style.language_style,
387
+ response_length=agent_style.response_length or self.global_style.response_length,
388
+ custom_rules=agent_style.custom_rules or self.global_style.custom_rules,
389
+ )
390
+ # Fall back to global
391
+ return self.global_style
392
+
393
+
317
394
  class OnboardingConfig(BaseModel):
318
395
  """Configuration model for Onboarding Agent."""
319
396
 
@@ -432,6 +509,11 @@ class TemplateManager:
432
509
  folder = self.get_template_folder(client)
433
510
  return OnboardingConfig.load(folder / "onboarding_config.yaml")
434
511
 
512
+ def load_style_config(self, client: Optional[str] = None) -> StyleConfig:
513
+ """Load style configuration for the specified client."""
514
+ folder = self.get_template_folder(client)
515
+ return StyleConfig.load(folder / "style_config.yaml")
516
+
435
517
  def clear_caches(self) -> None:
436
518
  """Clear all configuration caches."""
437
519
  FlowConfig.load.cache_clear()
@@ -440,6 +522,7 @@ class TemplateManager:
440
522
  KnowledgeConfig.load.cache_clear()
441
523
  ConfirmationConfig.load.cache_clear()
442
524
  OnboardingConfig.load.cache_clear()
525
+ StyleConfig.load.cache_clear()
443
526
 
444
527
 
445
528
  def get_template_manager() -> TemplateManager:
@@ -528,3 +611,8 @@ def load_onboarding_config(client: Optional[str] = None) -> OnboardingConfig:
528
611
  """Load onboarding configuration for the specified client."""
529
612
  return get_template_manager().load_onboarding_config(client)
530
613
 
614
+
615
+ def load_style_config(client: Optional[str] = None) -> StyleConfig:
616
+ """Load style configuration for the specified client."""
617
+ return get_template_manager().load_style_config(client)
618
+
@@ -1,7 +1,7 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: atendentepro
3
- Version: 0.5.7
4
- Summary: Sistema de Atendimento Inteligente com Múltiplos Agentes IA - Biblioteca independente e modular baseada no OpenAI Agents SDK
3
+ Version: 0.6.0
4
+ Summary: Framework de orquestração de agentes IA para resolver interações complexas integrando múltiplas fontes de dados (documentos, APIs, bancos) em uma única plataforma inteligente.
5
5
  Author-email: BeMonkAI <contato@monkai.com.br>
6
6
  Maintainer-email: BeMonkAI <contato@monkai.com.br>
7
7
  License: Proprietary
@@ -10,7 +10,7 @@ Project-URL: Documentation, https://github.com/BeMonkAI/atendentepro#readme
10
10
  Project-URL: Repository, https://github.com/BeMonkAI/atendentepro
11
11
  Project-URL: Issues, https://github.com/BeMonkAI/atendentepro/issues
12
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
13
+ Keywords: ai,agents,customer-service,chatbot,openai,multi-agent,atendimento,openai-agents,conversational-ai,rag,triage,handoff,escalation,feedback,knowledge-base,interview
14
14
  Classifier: Development Status :: 4 - Beta
15
15
  Classifier: Intended Audience :: Developers
16
16
  Classifier: License :: Other/Proprietary License
@@ -48,21 +48,34 @@ Requires-Dist: python-docx>=0.8.11; extra == "rag"
48
48
  Requires-Dist: python-pptx>=0.6.21; extra == "rag"
49
49
  Requires-Dist: PyMuPDF>=1.23.0; extra == "rag"
50
50
  Provides-Extra: tracing
51
- Requires-Dist: opentelemetry-sdk>=1.20.0; extra == "tracing"
52
- Requires-Dist: azure-monitor-opentelemetry-exporter>=1.0.0; extra == "tracing"
51
+ Requires-Dist: monkai-trace>=0.2.9; extra == "tracing"
52
+ Provides-Extra: azure
53
+ Requires-Dist: opentelemetry-sdk>=1.20.0; extra == "azure"
54
+ Requires-Dist: azure-monitor-opentelemetry-exporter>=1.0.0; extra == "azure"
53
55
  Provides-Extra: all
54
- Requires-Dist: atendentepro[dev,docs,rag,tracing]; extra == "all"
56
+ Requires-Dist: atendentepro[azure,dev,docs,rag,tracing]; extra == "all"
55
57
  Dynamic: license-file
56
58
 
57
- # AtendentePro 🤖
59
+ # AtendentePro
58
60
 
59
61
  [![Python 3.9+](https://img.shields.io/badge/python-3.9+-blue.svg)](https://www.python.org/downloads/)
60
62
  [![PyPI version](https://badge.fury.io/py/atendentepro.svg)](https://pypi.org/project/atendentepro/)
61
63
  [![License: Proprietary](https://img.shields.io/badge/License-Proprietary-red.svg)](LICENSE)
62
64
 
63
- **Sistema de Atendimento Inteligente com Múltiplos Agentes IA**
65
+ **Framework de orquestração de agentes IA para interações complexas**
64
66
 
65
- Uma biblioteca Python modular para criar sistemas de atendimento automatizado usando múltiplos agentes de IA especializados baseados no [OpenAI Agents SDK](https://github.com/openai/openai-agents-python).
67
+ Plataforma que unifica múltiplos agentes especializados para resolver demandas que envolvem diferentes fontes de dados, sistemas e fluxos de decisão tudo orquestrado em um único lugar. Baseado no [OpenAI Agents SDK](https://github.com/openai/openai-agents-python).
68
+
69
+ ### Principais Capacidades
70
+
71
+ | Capacidade | Descrição |
72
+ |------------|-----------|
73
+ | **Classificação Inteligente** | Identifica a intenção e direciona para o agente especializado |
74
+ | **Integração de Dados** | Conecta documentos (RAG), CSVs, bancos de dados SQL e APIs externas |
75
+ | **Orquestração de Fluxos** | Handoffs automáticos entre agentes conforme a complexidade da demanda |
76
+ | **Escalonamento Controlado** | Transferência para atendimento humano com contexto preservado |
77
+ | **Gestão de Feedbacks** | Sistema de tickets para reclamações, sugestões e acompanhamento |
78
+ | **Configuração Declarativa** | Personalização completa via arquivos YAML |
66
79
 
67
80
  ---
68
81
 
@@ -90,8 +103,8 @@ Uma biblioteca Python modular para criar sistemas de atendimento automatizado us
90
103
  # Via PyPI
91
104
  pip install atendentepro
92
105
 
93
- # Ou via pip com versão específica
94
- pip install atendentepro==0.5.3
106
+ # Com monitoramento (recomendado)
107
+ pip install atendentepro[tracing]
95
108
  ```
96
109
 
97
110
  ---
@@ -696,26 +709,56 @@ configure_application_insights(
696
709
 
697
710
  ## 📝 Changelog
698
711
 
712
+ ### v0.5.9 (Atual)
713
+ - Descrição PyPI formal: "Framework de orquestração de agentes IA"
714
+ - README profissional com foco em capacidades corporativas
715
+
716
+ ### v0.5.8
717
+ - Novos keywords: triage, handoff, escalation, feedback, knowledge-base
718
+ - Dependência `tracing` agora usa `monkai-trace`
719
+
720
+ ### v0.5.7
721
+ - **MonkAI Trace**: Integração completa para monitoramento de agentes
722
+ - Novas funções: `configure_monkai_trace`, `run_with_monkai_tracking`
723
+ - Suporte multi-usuário para WhatsApp/chat
724
+
725
+ ### v0.5.6
726
+ - **Agentes configuráveis**: `include_knowledge=False`, `include_flow=False`, etc.
727
+ - Permite criar redes sem agentes específicos
728
+
729
+ ### v0.5.5
730
+ - Workflow PyPI apenas com tags de versão
731
+
732
+ ### v0.5.4
733
+ - Documentação completa standalone no PyPI
734
+
699
735
  ### v0.5.3
700
- - Documentação completa no README para PyPI
736
+ - Links de documentação corrigidos para PyPI
701
737
 
702
738
  ### v0.5.2
703
- - Atualização de contatos (monkai.com.br)
739
+ - Contatos atualizados (monkai.com.br)
704
740
 
705
741
  ### v0.5.1
706
742
  - Prompts modulares para Escalation e Feedback
707
743
  - Remoção de handoff circular Answer→Interview
708
744
 
709
745
  ### v0.5.0
710
- - Novo: Feedback Agent (tickets/SAC)
746
+ - **Novo**: Feedback Agent (tickets/SAC)
747
+ - Ferramentas: criar_ticket, consultar_ticket, listar_meus_tickets
711
748
 
712
749
  ### v0.4.0
713
- - Novo: Escalation Agent (transferência humana)
750
+ - **Novo**: Escalation Agent (transferência humana)
751
+ - Verificação de horário, prioridade automática, webhooks
714
752
 
715
753
  ### v0.3.0
716
- - Sistema de licenciamento
754
+ - Sistema de licenciamento com tokens
717
755
  - Publicação inicial no PyPI
718
756
 
757
+ ### v0.2.0
758
+ - Arquitetura modular completa
759
+ - 8 agentes especializados
760
+ - Sistema de templates YAML
761
+
719
762
  ---
720
763
 
721
- **Made with ❤️ by MonkAI**
764
+ **Made with ❤️ by [MonkAI](https://www.monkai.com.br)**
@@ -1,18 +1,18 @@
1
- atendentepro/README.md,sha256=AMVMJlVOlXcwU_kRGBiIoSn8hASLHrhZwxV1jr1LJsU,43012
2
- atendentepro/__init__.py,sha256=A7ANs1G18HZEhl-C_OVVdOzM0KCRDo-sX1Veq4IYwDo,5572
1
+ atendentepro/README.md,sha256=TAXl5GRjhSwz_I-Dx_eN5JOIcUxuE_dz31iMZ_-OnRY,45390
2
+ atendentepro/__init__.py,sha256=CDK61bxE18NYvLeswIoQWLarw2_xJAOEb2yONsQ2CqQ,5606
3
3
  atendentepro/license.py,sha256=rlPtysXNqAzEQkP2VjUAVu_nMndhPgfKv1yN2ruUYVI,17570
4
- atendentepro/network.py,sha256=s7h9if2oS_15BL8VoONjMlihEFCkJqdHxR5WFL81gl4,17310
4
+ atendentepro/network.py,sha256=1grEjYDZQ7K6r-eQ1tMV3g1vBAdkiNn0v1EeraqTK18,22341
5
5
  atendentepro/agents/__init__.py,sha256=OcPhG1Dp6xe49B5YIti4HVmaZDoDIrFLfRa8GmI4jpQ,1638
6
- atendentepro/agents/answer.py,sha256=dIZzGL_ddjC96JIiWSwDg33phwca8NpWFxO16FFYVoA,1905
7
- atendentepro/agents/confirmation.py,sha256=5Zg4z9A90CydYiEk8CEAKnnza71algFKF-N1WLwGDQI,2311
8
- atendentepro/agents/escalation.py,sha256=YNA2e1Si30FJoIJkpos3B9imaR_Q6uv9K2o-F-Ht8rQ,17190
9
- atendentepro/agents/feedback.py,sha256=xTFANEkFQaYIYQxlD6_hxTGAxfGUVwTM-rnfN0gT78Y,32996
10
- atendentepro/agents/flow.py,sha256=qWuPcjfm2peWjpHFUiq0P1blRk500LUUucb2Z9kT95Q,2056
11
- atendentepro/agents/interview.py,sha256=Tegfh3ZTr7__b_a0elyfn57u56yuS2pN_RB-8vOt-Os,2133
12
- atendentepro/agents/knowledge.py,sha256=M8XOJ_yxYRyuCaBxn-xFCCWE-MTx5bjyUi4-E2tSPL8,10080
13
- atendentepro/agents/onboarding.py,sha256=bDdwEE33Hcnv8UW3qsHhLcloaEL5xfh3BBeoWTgb8s0,2098
14
- atendentepro/agents/triage.py,sha256=VUHOwbQq0jt8pDfNy0FWznicqXDgMfXW0JwAsuGcAzg,1733
15
- atendentepro/agents/usage.py,sha256=hmckYQ4kOfYqu15xsxg_r2VoRozCwtw-RxxteUtbsI0,1594
6
+ atendentepro/agents/answer.py,sha256=Bwxhpeqp7bbiqHN3hfLwuF7wCekd0H2CI4H0UKMTDAY,2130
7
+ atendentepro/agents/confirmation.py,sha256=EB1vb_qBeZu9r0WKTe98kBHfdiuBzVaRUZmDpUIc7sc,2536
8
+ atendentepro/agents/escalation.py,sha256=ukFRNs0ISUug29IN2_wzIKUF_YKw5CCyGzkITtfdLx0,17415
9
+ atendentepro/agents/feedback.py,sha256=7afcdXmW6NfVKJcmZPWbRwD5yPOVOWbvVdqh0LaYfyE,33221
10
+ atendentepro/agents/flow.py,sha256=MLcumyoFFXqhkwu9lIURLJx_sSz-MZvwUdXRGW_PyXo,2281
11
+ atendentepro/agents/interview.py,sha256=vFYCEvtCoCwX7vMVaN5acXO6xKzuBA12jxrqA1SE6n8,2358
12
+ atendentepro/agents/knowledge.py,sha256=Lui1ZVC4AYOvzfm4G4vJZtaRNsXBTVlgfOSchBXryVE,10305
13
+ atendentepro/agents/onboarding.py,sha256=f7ezfZdL3o0o4mLoTpDLFoxUNeEcCKl80qQsxL7t7JI,2323
14
+ atendentepro/agents/triage.py,sha256=pdYCA5AqbGMY0WoJXvdceAz_gnQ7D_fJp7dxxsD-GDg,1958
15
+ atendentepro/agents/usage.py,sha256=wdxX7ZJVO6RGkuAY7JIgTfUQHid-q9U5ohLmvIg399c,1819
16
16
  atendentepro/config/__init__.py,sha256=LQZbEz9AVGnO8xCG_rI9GmyFQun5HQqo8hJkkm-d_e4,338
17
17
  atendentepro/config/settings.py,sha256=Z1texEtO76Rrt-wPyEXM3FyujDE75r8HbEEJClzFOvk,4762
18
18
  atendentepro/guardrails/__init__.py,sha256=lCSI4RbQeIOya8k1wIADoxz9gYySDtUtOv-JiXisvyQ,454
@@ -30,14 +30,14 @@ atendentepro/prompts/interview.py,sha256=9zVGA8zSmm6pBx2i1LPGNJIPuLlz7PZKRJE_PC6
30
30
  atendentepro/prompts/knowledge.py,sha256=B3BOyAvzQlwAkR51gc-B6XbQLtwIZlwGP1ofhZ4cFbk,4644
31
31
  atendentepro/prompts/onboarding.py,sha256=78fSIh2ifsGeoav8DV41_jnyU157c0dtggJujcDvW4U,6093
32
32
  atendentepro/prompts/triage.py,sha256=bSdEVheGy03r5P6MQuv7NwhN2_wrt0mK80F9f_LskRU,1283
33
- atendentepro/templates/__init__.py,sha256=kSXiDXVIZKKsSn2GuHBcHsnXqVRcNWyBzRlKl9HYoCI,1137
34
- atendentepro/templates/manager.py,sha256=KdE4khWDMD2S607TDTMkvJ8lZzQ9D_TD_lBaXYSTBzI,17932
33
+ atendentepro/templates/__init__.py,sha256=GbtNnhf2Zz-JiNReq-bBLzTdMZ-JFItmPU0OjnlU640,1267
34
+ atendentepro/templates/manager.py,sha256=kEeVRc1GHW5W8Q3GHgn6iBEvyzyO-GcEIKTBorYaHXw,21405
35
35
  atendentepro/utils/__init__.py,sha256=WCJ6_btsLaI6xxHXvNHNue-nKrXWTKscNZGTToQiJ8A,833
36
36
  atendentepro/utils/openai_client.py,sha256=R0ns7SU36vTgploq14-QJMTke1pPxcAXlENDeoHU0L4,4552
37
37
  atendentepro/utils/tracing.py,sha256=kpTPw1PF4rR1qq1RyBnAaPIQIJRka4RF8MfG_JrRJ7U,8486
38
- atendentepro-0.5.7.dist-info/licenses/LICENSE,sha256=TF6CdXxePoT9DXtPnCejiU5mUwWzrFzd1iyWJyoMauA,983
39
- atendentepro-0.5.7.dist-info/METADATA,sha256=sNb7PC8RcGrtRtciak-J_yiJedDxquF7N2mtl_4QwFo,20757
40
- atendentepro-0.5.7.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
41
- atendentepro-0.5.7.dist-info/entry_points.txt,sha256=OP0upzqJF3MLS6VX-M-5BfUwx5YLJO2sJ3YBAp4e6yI,89
42
- atendentepro-0.5.7.dist-info/top_level.txt,sha256=BFasD4SMmgDUmWKlTIZ1PeuukoRBhyiMIz8umKWVCcs,13
43
- atendentepro-0.5.7.dist-info/RECORD,,
38
+ atendentepro-0.6.0.dist-info/licenses/LICENSE,sha256=TF6CdXxePoT9DXtPnCejiU5mUwWzrFzd1iyWJyoMauA,983
39
+ atendentepro-0.6.0.dist-info/METADATA,sha256=HmvbabP9S-qrSMMZ3p_Yf2RGw07XKpJMHhrb4rNBnMk,22701
40
+ atendentepro-0.6.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
41
+ atendentepro-0.6.0.dist-info/entry_points.txt,sha256=OP0upzqJF3MLS6VX-M-5BfUwx5YLJO2sJ3YBAp4e6yI,89
42
+ atendentepro-0.6.0.dist-info/top_level.txt,sha256=BFasD4SMmgDUmWKlTIZ1PeuukoRBhyiMIz8umKWVCcs,13
43
+ atendentepro-0.6.0.dist-info/RECORD,,