atendentepro 0.6.1__py3-none-any.whl → 0.6.3__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/agents/answer.py +6 -0
- atendentepro/agents/confirmation.py +6 -0
- atendentepro/agents/escalation.py +6 -0
- atendentepro/agents/feedback.py +6 -0
- atendentepro/agents/flow.py +6 -0
- atendentepro/agents/interview.py +6 -0
- atendentepro/agents/knowledge.py +19 -0
- atendentepro/agents/onboarding.py +6 -0
- atendentepro/agents/usage.py +6 -0
- atendentepro/network.py +34 -0
- atendentepro/templates/__init__.py +4 -0
- atendentepro/templates/manager.py +54 -0
- {atendentepro-0.6.1.dist-info → atendentepro-0.6.3.dist-info}/METADATA +106 -23
- {atendentepro-0.6.1.dist-info → atendentepro-0.6.3.dist-info}/RECORD +18 -18
- {atendentepro-0.6.1.dist-info → atendentepro-0.6.3.dist-info}/WHEEL +0 -0
- {atendentepro-0.6.1.dist-info → atendentepro-0.6.3.dist-info}/entry_points.txt +0 -0
- {atendentepro-0.6.1.dist-info → atendentepro-0.6.3.dist-info}/licenses/LICENSE +0 -0
- {atendentepro-0.6.1.dist-info → atendentepro-0.6.3.dist-info}/top_level.txt +0 -0
atendentepro/agents/answer.py
CHANGED
|
@@ -26,6 +26,7 @@ def create_answer_agent(
|
|
|
26
26
|
name: str = "Answer Agent",
|
|
27
27
|
custom_instructions: Optional[str] = None,
|
|
28
28
|
style_instructions: str = "",
|
|
29
|
+
single_reply: bool = False,
|
|
29
30
|
) -> AnswerAgent:
|
|
30
31
|
"""
|
|
31
32
|
Create an Answer Agent instance.
|
|
@@ -40,6 +41,7 @@ def create_answer_agent(
|
|
|
40
41
|
name: Agent name.
|
|
41
42
|
custom_instructions: Optional custom instructions to override default.
|
|
42
43
|
style_instructions: Optional style/tone instructions to append.
|
|
44
|
+
single_reply: If True, agent responds once then transfers to triage.
|
|
43
45
|
|
|
44
46
|
Returns:
|
|
45
47
|
Configured Answer Agent instance.
|
|
@@ -54,6 +56,10 @@ def create_answer_agent(
|
|
|
54
56
|
if style_instructions:
|
|
55
57
|
instructions += style_instructions
|
|
56
58
|
|
|
59
|
+
# Single reply mode: respond once then return to triage
|
|
60
|
+
if single_reply:
|
|
61
|
+
instructions += "\n\nIMPORTANTE: Após fornecer sua resposta, transfira IMEDIATAMENTE para o triage_agent. Você só pode dar UMA resposta antes de transferir."
|
|
62
|
+
|
|
57
63
|
return Agent[ContextNote](
|
|
58
64
|
name=name,
|
|
59
65
|
handoff_description=(
|
|
@@ -28,6 +28,7 @@ def create_confirmation_agent(
|
|
|
28
28
|
name: str = "Confirmation Agent",
|
|
29
29
|
custom_instructions: Optional[str] = None,
|
|
30
30
|
style_instructions: str = "",
|
|
31
|
+
single_reply: bool = False,
|
|
31
32
|
) -> ConfirmationAgent:
|
|
32
33
|
"""
|
|
33
34
|
Create a Confirmation Agent instance.
|
|
@@ -44,6 +45,7 @@ def create_confirmation_agent(
|
|
|
44
45
|
name: Agent name.
|
|
45
46
|
custom_instructions: Optional custom instructions to override default.
|
|
46
47
|
style_instructions: Optional style/tone instructions to append.
|
|
48
|
+
single_reply: If True, agent responds once then transfers to triage.
|
|
47
49
|
|
|
48
50
|
Returns:
|
|
49
51
|
Configured Confirmation Agent instance.
|
|
@@ -62,6 +64,10 @@ def create_confirmation_agent(
|
|
|
62
64
|
if style_instructions:
|
|
63
65
|
instructions += style_instructions
|
|
64
66
|
|
|
67
|
+
# Single reply mode: respond once then return to triage
|
|
68
|
+
if single_reply:
|
|
69
|
+
instructions += "\n\nIMPORTANTE: Após fornecer sua resposta, transfira IMEDIATAMENTE para o triage_agent. Você só pode dar UMA resposta antes de transferir."
|
|
70
|
+
|
|
65
71
|
return Agent[ContextNote](
|
|
66
72
|
name=name,
|
|
67
73
|
handoff_description=(
|
|
@@ -455,6 +455,7 @@ def create_escalation_agent(
|
|
|
455
455
|
name: str = "Escalation Agent",
|
|
456
456
|
custom_instructions: Optional[str] = None,
|
|
457
457
|
style_instructions: str = "",
|
|
458
|
+
single_reply: bool = False,
|
|
458
459
|
) -> EscalationAgent:
|
|
459
460
|
"""
|
|
460
461
|
Create an Escalation Agent instance.
|
|
@@ -477,6 +478,7 @@ def create_escalation_agent(
|
|
|
477
478
|
name: Agent name.
|
|
478
479
|
custom_instructions: Optional custom instructions to override default.
|
|
479
480
|
style_instructions: Optional style/tone instructions to append.
|
|
481
|
+
single_reply: If True, agent responds once then transfers to triage.
|
|
480
482
|
|
|
481
483
|
Returns:
|
|
482
484
|
Configured Escalation Agent instance.
|
|
@@ -500,6 +502,10 @@ def create_escalation_agent(
|
|
|
500
502
|
if style_instructions:
|
|
501
503
|
instructions += style_instructions
|
|
502
504
|
|
|
505
|
+
# Single reply mode: respond once then return to triage
|
|
506
|
+
if single_reply:
|
|
507
|
+
instructions += "\n\nIMPORTANTE: Após fornecer sua resposta, transfira IMEDIATAMENTE para o triage_agent. Você só pode dar UMA resposta antes de transferir."
|
|
508
|
+
|
|
503
509
|
# Combinar tools padrão com customizadas
|
|
504
510
|
agent_tools = list(ESCALATION_TOOLS)
|
|
505
511
|
if tools:
|
atendentepro/agents/feedback.py
CHANGED
|
@@ -895,6 +895,7 @@ def create_feedback_agent(
|
|
|
895
895
|
name: str = "Feedback Agent",
|
|
896
896
|
custom_instructions: Optional[str] = None,
|
|
897
897
|
style_instructions: str = "",
|
|
898
|
+
single_reply: bool = False,
|
|
898
899
|
) -> FeedbackAgent:
|
|
899
900
|
"""
|
|
900
901
|
Create a Feedback Agent for collecting user feedback, questions, and complaints.
|
|
@@ -921,6 +922,7 @@ def create_feedback_agent(
|
|
|
921
922
|
name: Agent name.
|
|
922
923
|
custom_instructions: Override default instructions.
|
|
923
924
|
style_instructions: Optional style/tone instructions to append.
|
|
925
|
+
single_reply: If True, agent responds once then transfers to triage.
|
|
924
926
|
|
|
925
927
|
Returns:
|
|
926
928
|
Configured Feedback Agent instance.
|
|
@@ -951,6 +953,10 @@ def create_feedback_agent(
|
|
|
951
953
|
if style_instructions:
|
|
952
954
|
instructions += style_instructions
|
|
953
955
|
|
|
956
|
+
# Single reply mode: respond once then return to triage
|
|
957
|
+
if single_reply:
|
|
958
|
+
instructions += "\n\nIMPORTANTE: Após fornecer sua resposta, transfira IMEDIATAMENTE para o triage_agent. Você só pode dar UMA resposta antes de transferir."
|
|
959
|
+
|
|
954
960
|
# Combine tools
|
|
955
961
|
agent_tools = list(FEEDBACK_TOOLS)
|
|
956
962
|
if tools:
|
atendentepro/agents/flow.py
CHANGED
|
@@ -27,6 +27,7 @@ def create_flow_agent(
|
|
|
27
27
|
name: str = "Flow Agent",
|
|
28
28
|
custom_instructions: Optional[str] = None,
|
|
29
29
|
style_instructions: str = "",
|
|
30
|
+
single_reply: bool = False,
|
|
30
31
|
) -> FlowAgent:
|
|
31
32
|
"""
|
|
32
33
|
Create a Flow Agent instance.
|
|
@@ -41,6 +42,7 @@ def create_flow_agent(
|
|
|
41
42
|
name: Agent name.
|
|
42
43
|
custom_instructions: Optional custom instructions to override default.
|
|
43
44
|
style_instructions: Optional style/tone instructions to append.
|
|
45
|
+
single_reply: If True, agent responds once then transfers to triage.
|
|
44
46
|
|
|
45
47
|
Returns:
|
|
46
48
|
Configured Flow Agent instance.
|
|
@@ -55,6 +57,10 @@ def create_flow_agent(
|
|
|
55
57
|
if style_instructions:
|
|
56
58
|
instructions += style_instructions
|
|
57
59
|
|
|
60
|
+
# Single reply mode: respond once then return to triage
|
|
61
|
+
if single_reply:
|
|
62
|
+
instructions += "\n\nIMPORTANTE: Após fornecer sua resposta, transfira IMEDIATAMENTE para o triage_agent. Você só pode dar UMA resposta antes de transferir."
|
|
63
|
+
|
|
58
64
|
return Agent[ContextNote](
|
|
59
65
|
name=name,
|
|
60
66
|
handoff_description="""
|
atendentepro/agents/interview.py
CHANGED
|
@@ -28,6 +28,7 @@ def create_interview_agent(
|
|
|
28
28
|
name: str = "Interview Agent",
|
|
29
29
|
custom_instructions: Optional[str] = None,
|
|
30
30
|
style_instructions: str = "",
|
|
31
|
+
single_reply: bool = False,
|
|
31
32
|
) -> InterviewAgent:
|
|
32
33
|
"""
|
|
33
34
|
Create an Interview Agent instance.
|
|
@@ -44,6 +45,7 @@ def create_interview_agent(
|
|
|
44
45
|
name: Agent name.
|
|
45
46
|
custom_instructions: Optional custom instructions to override default.
|
|
46
47
|
style_instructions: Optional style/tone instructions to append.
|
|
48
|
+
single_reply: If True, agent responds once then transfers to triage.
|
|
47
49
|
|
|
48
50
|
Returns:
|
|
49
51
|
Configured Interview Agent instance.
|
|
@@ -61,6 +63,10 @@ def create_interview_agent(
|
|
|
61
63
|
if style_instructions:
|
|
62
64
|
instructions += style_instructions
|
|
63
65
|
|
|
66
|
+
# Single reply mode: respond once then return to triage
|
|
67
|
+
if single_reply:
|
|
68
|
+
instructions += "\n\nIMPORTANTE: Após fornecer sua resposta, transfira IMEDIATAMENTE para o triage_agent. Você só pode dar UMA resposta antes de transferir."
|
|
69
|
+
|
|
64
70
|
return Agent[ContextNote](
|
|
65
71
|
name=name,
|
|
66
72
|
handoff_description="""
|
atendentepro/agents/knowledge.py
CHANGED
|
@@ -58,9 +58,22 @@ def load_embeddings() -> List[dict]:
|
|
|
58
58
|
return []
|
|
59
59
|
|
|
60
60
|
|
|
61
|
+
def _check_rag_dependencies() -> None:
|
|
62
|
+
"""Check if RAG dependencies are installed."""
|
|
63
|
+
try:
|
|
64
|
+
import numpy # noqa: F401
|
|
65
|
+
import sklearn # noqa: F401
|
|
66
|
+
except ImportError as e:
|
|
67
|
+
raise ImportError(
|
|
68
|
+
"RAG dependencies not installed. "
|
|
69
|
+
"Install with: pip install atendentepro[rag]"
|
|
70
|
+
) from e
|
|
71
|
+
|
|
72
|
+
|
|
61
73
|
async def _find_relevant_chunks(query: str, top_k: int = 3) -> List[dict]:
|
|
62
74
|
"""Find most relevant chunks for a given query."""
|
|
63
75
|
try:
|
|
76
|
+
_check_rag_dependencies()
|
|
64
77
|
from sklearn.metrics.pairwise import cosine_similarity
|
|
65
78
|
import numpy as np
|
|
66
79
|
|
|
@@ -218,6 +231,7 @@ def create_knowledge_agent(
|
|
|
218
231
|
name: str = "Knowledge Agent",
|
|
219
232
|
custom_instructions: Optional[str] = None,
|
|
220
233
|
style_instructions: str = "",
|
|
234
|
+
single_reply: bool = False,
|
|
221
235
|
) -> KnowledgeAgent:
|
|
222
236
|
"""
|
|
223
237
|
Create a Knowledge Agent instance.
|
|
@@ -241,6 +255,7 @@ def create_knowledge_agent(
|
|
|
241
255
|
name: Agent name.
|
|
242
256
|
custom_instructions: Optional custom instructions to override default.
|
|
243
257
|
style_instructions: Optional style/tone instructions to append.
|
|
258
|
+
single_reply: If True, agent responds once then transfers to triage.
|
|
244
259
|
|
|
245
260
|
Returns:
|
|
246
261
|
Configured Knowledge Agent instance.
|
|
@@ -268,6 +283,10 @@ def create_knowledge_agent(
|
|
|
268
283
|
if style_instructions:
|
|
269
284
|
instructions += style_instructions
|
|
270
285
|
|
|
286
|
+
# Single reply mode: respond once then return to triage
|
|
287
|
+
if single_reply:
|
|
288
|
+
instructions += "\n\nIMPORTANTE: Após fornecer sua resposta, transfira IMEDIATAMENTE para o triage_agent. Você só pode dar UMA resposta antes de transferir."
|
|
289
|
+
|
|
271
290
|
# Build tools list
|
|
272
291
|
agent_tools: List = []
|
|
273
292
|
|
|
@@ -28,6 +28,7 @@ def create_onboarding_agent(
|
|
|
28
28
|
name: str = "Onboarding Agent",
|
|
29
29
|
custom_instructions: Optional[str] = None,
|
|
30
30
|
style_instructions: str = "",
|
|
31
|
+
single_reply: bool = False,
|
|
31
32
|
) -> OnboardingAgent:
|
|
32
33
|
"""
|
|
33
34
|
Create an Onboarding Agent instance.
|
|
@@ -43,6 +44,7 @@ def create_onboarding_agent(
|
|
|
43
44
|
name: Agent name.
|
|
44
45
|
custom_instructions: Optional custom instructions to override default.
|
|
45
46
|
style_instructions: Optional style/tone instructions to append.
|
|
47
|
+
single_reply: If True, agent responds once then transfers to triage.
|
|
46
48
|
|
|
47
49
|
Returns:
|
|
48
50
|
Configured Onboarding Agent instance.
|
|
@@ -57,6 +59,10 @@ def create_onboarding_agent(
|
|
|
57
59
|
if style_instructions:
|
|
58
60
|
instructions += style_instructions
|
|
59
61
|
|
|
62
|
+
# Single reply mode: respond once then return to triage
|
|
63
|
+
if single_reply:
|
|
64
|
+
instructions += "\n\nIMPORTANTE: Após fornecer sua resposta, transfira IMEDIATAMENTE para o triage_agent. Você só pode dar UMA resposta antes de transferir."
|
|
65
|
+
|
|
60
66
|
return Agent[ContextNote](
|
|
61
67
|
name=name,
|
|
62
68
|
handoff_description=(
|
atendentepro/agents/usage.py
CHANGED
|
@@ -30,6 +30,7 @@ def create_usage_agent(
|
|
|
30
30
|
name: str = "Usage Agent",
|
|
31
31
|
custom_instructions: Optional[str] = None,
|
|
32
32
|
style_instructions: str = "",
|
|
33
|
+
single_reply: bool = False,
|
|
33
34
|
) -> UsageAgent:
|
|
34
35
|
"""
|
|
35
36
|
Create a Usage Agent instance.
|
|
@@ -42,6 +43,7 @@ def create_usage_agent(
|
|
|
42
43
|
name: Agent name.
|
|
43
44
|
custom_instructions: Optional custom instructions to override default.
|
|
44
45
|
style_instructions: Optional style/tone instructions to append.
|
|
46
|
+
single_reply: If True, agent responds once then transfers to triage.
|
|
45
47
|
|
|
46
48
|
Returns:
|
|
47
49
|
Configured Usage Agent instance.
|
|
@@ -52,6 +54,10 @@ def create_usage_agent(
|
|
|
52
54
|
if style_instructions:
|
|
53
55
|
instructions += style_instructions
|
|
54
56
|
|
|
57
|
+
# Single reply mode: respond once then return to triage
|
|
58
|
+
if single_reply:
|
|
59
|
+
instructions += "\n\nIMPORTANTE: Após fornecer sua resposta, transfira IMEDIATAMENTE para o triage_agent. Você só pode dar UMA resposta antes de transferir."
|
|
60
|
+
|
|
55
61
|
return Agent[ContextNote](
|
|
56
62
|
name=name,
|
|
57
63
|
handoff_description="A usage agent that can answer questions about the usage of the system.",
|
atendentepro/network.py
CHANGED
|
@@ -199,6 +199,9 @@ def create_standard_network(
|
|
|
199
199
|
# Style configuration
|
|
200
200
|
global_style: Optional[AgentStyle] = None,
|
|
201
201
|
agent_styles: Optional[Dict[str, AgentStyle]] = None,
|
|
202
|
+
# Single reply mode (auto-return to triage after one response)
|
|
203
|
+
global_single_reply: bool = False,
|
|
204
|
+
single_reply_agents: Optional[Dict[str, bool]] = None,
|
|
202
205
|
) -> AgentNetwork:
|
|
203
206
|
"""
|
|
204
207
|
Create a standard agent network with proper handoff configuration.
|
|
@@ -236,6 +239,8 @@ def create_standard_network(
|
|
|
236
239
|
custom_tools: Optional dict of custom tools by agent name.
|
|
237
240
|
global_style: Style configuration applied to all agents (tone, language, etc.).
|
|
238
241
|
agent_styles: Dict mapping agent names to specific styles (overrides global).
|
|
242
|
+
global_single_reply: If True, all agents respond once then transfer to triage.
|
|
243
|
+
single_reply_agents: Dict mapping agent names to single_reply mode (overrides global).
|
|
239
244
|
|
|
240
245
|
Returns:
|
|
241
246
|
Configured AgentNetwork instance.
|
|
@@ -278,6 +283,17 @@ def create_standard_network(
|
|
|
278
283
|
),
|
|
279
284
|
},
|
|
280
285
|
)
|
|
286
|
+
|
|
287
|
+
# Create network with single reply mode for specific agents
|
|
288
|
+
network = create_standard_network(
|
|
289
|
+
templates_root=Path("templates"),
|
|
290
|
+
client="my_client",
|
|
291
|
+
global_single_reply=False, # Not all agents
|
|
292
|
+
single_reply_agents={
|
|
293
|
+
"knowledge": True, # Knowledge responds once
|
|
294
|
+
"confirmation": True, # Confirmation responds once
|
|
295
|
+
},
|
|
296
|
+
)
|
|
281
297
|
"""
|
|
282
298
|
# Verificar licença
|
|
283
299
|
require_activation()
|
|
@@ -356,6 +372,15 @@ def create_standard_network(
|
|
|
356
372
|
return global_style.build_style_prompt()
|
|
357
373
|
return ""
|
|
358
374
|
|
|
375
|
+
# Single reply helper function
|
|
376
|
+
def get_single_reply_for_agent(agent_name: str) -> bool:
|
|
377
|
+
"""Get single_reply setting for a specific agent."""
|
|
378
|
+
# Agent-specific setting takes precedence
|
|
379
|
+
if single_reply_agents and agent_name in single_reply_agents:
|
|
380
|
+
return single_reply_agents[agent_name]
|
|
381
|
+
# Fall back to global setting
|
|
382
|
+
return global_single_reply
|
|
383
|
+
|
|
359
384
|
# Create agents without handoffs first
|
|
360
385
|
# Triage is always created (entry point)
|
|
361
386
|
triage = create_triage_agent(
|
|
@@ -372,6 +397,7 @@ def create_standard_network(
|
|
|
372
397
|
flow_keywords=flow_keywords,
|
|
373
398
|
guardrails=get_guardrails_for_agent("Flow Agent", templates_root),
|
|
374
399
|
style_instructions=get_style_for_agent("flow"),
|
|
400
|
+
single_reply=get_single_reply_for_agent("flow"),
|
|
375
401
|
)
|
|
376
402
|
|
|
377
403
|
interview = None
|
|
@@ -382,6 +408,7 @@ def create_standard_network(
|
|
|
382
408
|
tools=tools.get("interview", []),
|
|
383
409
|
guardrails=get_guardrails_for_agent("Interview Agent", templates_root),
|
|
384
410
|
style_instructions=get_style_for_agent("interview"),
|
|
411
|
+
single_reply=get_single_reply_for_agent("interview"),
|
|
385
412
|
)
|
|
386
413
|
|
|
387
414
|
answer = None
|
|
@@ -390,6 +417,7 @@ def create_standard_network(
|
|
|
390
417
|
answer_template="",
|
|
391
418
|
guardrails=get_guardrails_for_agent("Answer Agent", templates_root),
|
|
392
419
|
style_instructions=get_style_for_agent("answer"),
|
|
420
|
+
single_reply=get_single_reply_for_agent("answer"),
|
|
393
421
|
)
|
|
394
422
|
|
|
395
423
|
knowledge = None
|
|
@@ -404,6 +432,7 @@ def create_standard_network(
|
|
|
404
432
|
tools=tools.get("knowledge", []),
|
|
405
433
|
guardrails=get_guardrails_for_agent("Knowledge Agent", templates_root),
|
|
406
434
|
style_instructions=get_style_for_agent("knowledge"),
|
|
435
|
+
single_reply=get_single_reply_for_agent("knowledge"),
|
|
407
436
|
)
|
|
408
437
|
|
|
409
438
|
confirmation = None
|
|
@@ -414,6 +443,7 @@ def create_standard_network(
|
|
|
414
443
|
confirmation_format=confirmation_format,
|
|
415
444
|
guardrails=get_guardrails_for_agent("Confirmation Agent", templates_root),
|
|
416
445
|
style_instructions=get_style_for_agent("confirmation"),
|
|
446
|
+
single_reply=get_single_reply_for_agent("confirmation"),
|
|
417
447
|
)
|
|
418
448
|
|
|
419
449
|
usage = None
|
|
@@ -421,6 +451,7 @@ def create_standard_network(
|
|
|
421
451
|
usage = create_usage_agent(
|
|
422
452
|
guardrails=get_guardrails_for_agent("Usage Agent", templates_root),
|
|
423
453
|
style_instructions=get_style_for_agent("usage"),
|
|
454
|
+
single_reply=get_single_reply_for_agent("usage"),
|
|
424
455
|
)
|
|
425
456
|
|
|
426
457
|
# Create escalation agent if requested
|
|
@@ -431,6 +462,7 @@ def create_standard_network(
|
|
|
431
462
|
tools=tools.get("escalation", []),
|
|
432
463
|
guardrails=get_guardrails_for_agent("Escalation Agent", templates_root),
|
|
433
464
|
style_instructions=get_style_for_agent("escalation"),
|
|
465
|
+
single_reply=get_single_reply_for_agent("escalation"),
|
|
434
466
|
)
|
|
435
467
|
|
|
436
468
|
# Create feedback agent if requested
|
|
@@ -443,6 +475,7 @@ def create_standard_network(
|
|
|
443
475
|
tools=tools.get("feedback", []),
|
|
444
476
|
guardrails=get_guardrails_for_agent("Feedback Agent", templates_root),
|
|
445
477
|
style_instructions=get_style_for_agent("feedback"),
|
|
478
|
+
single_reply=get_single_reply_for_agent("feedback"),
|
|
446
479
|
)
|
|
447
480
|
|
|
448
481
|
# Configure handoffs dynamically based on which agents are included
|
|
@@ -554,6 +587,7 @@ def create_standard_network(
|
|
|
554
587
|
tools=tools.get("onboarding", []),
|
|
555
588
|
guardrails=get_guardrails_for_agent("Onboarding Agent", templates_root),
|
|
556
589
|
style_instructions=get_style_for_agent("onboarding"),
|
|
590
|
+
single_reply=get_single_reply_for_agent("onboarding"),
|
|
557
591
|
)
|
|
558
592
|
|
|
559
593
|
network.onboarding = onboarding
|
|
@@ -15,6 +15,7 @@ from .manager import (
|
|
|
15
15
|
load_confirmation_config,
|
|
16
16
|
load_onboarding_config,
|
|
17
17
|
load_style_config,
|
|
18
|
+
load_single_reply_config,
|
|
18
19
|
FlowConfig,
|
|
19
20
|
InterviewConfig,
|
|
20
21
|
TriageConfig,
|
|
@@ -23,6 +24,7 @@ from .manager import (
|
|
|
23
24
|
OnboardingConfig,
|
|
24
25
|
StyleConfig,
|
|
25
26
|
AgentStyleConfig,
|
|
27
|
+
SingleReplyConfig,
|
|
26
28
|
DataSourceConfig,
|
|
27
29
|
DataSourceColumn,
|
|
28
30
|
DocumentConfig,
|
|
@@ -42,6 +44,7 @@ __all__ = [
|
|
|
42
44
|
"load_confirmation_config",
|
|
43
45
|
"load_onboarding_config",
|
|
44
46
|
"load_style_config",
|
|
47
|
+
"load_single_reply_config",
|
|
45
48
|
"FlowConfig",
|
|
46
49
|
"InterviewConfig",
|
|
47
50
|
"TriageConfig",
|
|
@@ -50,6 +53,7 @@ __all__ = [
|
|
|
50
53
|
"OnboardingConfig",
|
|
51
54
|
"StyleConfig",
|
|
52
55
|
"AgentStyleConfig",
|
|
56
|
+
"SingleReplyConfig",
|
|
53
57
|
"DataSourceConfig",
|
|
54
58
|
"DataSourceColumn",
|
|
55
59
|
"DocumentConfig",
|
|
@@ -391,6 +391,49 @@ class StyleConfig(BaseModel):
|
|
|
391
391
|
return self.global_style
|
|
392
392
|
|
|
393
393
|
|
|
394
|
+
class SingleReplyConfig(BaseModel):
|
|
395
|
+
"""Configuration model for single reply mode.
|
|
396
|
+
|
|
397
|
+
When single_reply is enabled for an agent, it will respond once
|
|
398
|
+
and automatically transfer back to the Triage agent. This prevents
|
|
399
|
+
conversations from getting stuck in a specific agent.
|
|
400
|
+
|
|
401
|
+
Example YAML:
|
|
402
|
+
global: false
|
|
403
|
+
|
|
404
|
+
agents:
|
|
405
|
+
knowledge: true
|
|
406
|
+
confirmation: true
|
|
407
|
+
answer: true
|
|
408
|
+
"""
|
|
409
|
+
|
|
410
|
+
global_enabled: bool = False
|
|
411
|
+
agents: Dict[str, bool] = Field(default_factory=dict)
|
|
412
|
+
|
|
413
|
+
@classmethod
|
|
414
|
+
@lru_cache(maxsize=4)
|
|
415
|
+
def load(cls, path: Path) -> "SingleReplyConfig":
|
|
416
|
+
"""Load single reply configuration from YAML file."""
|
|
417
|
+
if not path.exists():
|
|
418
|
+
raise FileNotFoundError(f"Single reply config not found at {path}")
|
|
419
|
+
|
|
420
|
+
with open(path, "r", encoding="utf-8") as f:
|
|
421
|
+
data = yaml.safe_load(f) or {}
|
|
422
|
+
|
|
423
|
+
return cls(
|
|
424
|
+
global_enabled=data.get("global", False),
|
|
425
|
+
agents=data.get("agents", {}),
|
|
426
|
+
)
|
|
427
|
+
|
|
428
|
+
def get_single_reply_for_agent(self, agent_name: str) -> bool:
|
|
429
|
+
"""Get single_reply setting for a specific agent."""
|
|
430
|
+
# Agent-specific setting takes precedence
|
|
431
|
+
if agent_name in self.agents:
|
|
432
|
+
return self.agents[agent_name]
|
|
433
|
+
# Fall back to global
|
|
434
|
+
return self.global_enabled
|
|
435
|
+
|
|
436
|
+
|
|
394
437
|
class OnboardingConfig(BaseModel):
|
|
395
438
|
"""Configuration model for Onboarding Agent."""
|
|
396
439
|
|
|
@@ -514,6 +557,11 @@ class TemplateManager:
|
|
|
514
557
|
folder = self.get_template_folder(client)
|
|
515
558
|
return StyleConfig.load(folder / "style_config.yaml")
|
|
516
559
|
|
|
560
|
+
def load_single_reply_config(self, client: Optional[str] = None) -> SingleReplyConfig:
|
|
561
|
+
"""Load single reply configuration for the specified client."""
|
|
562
|
+
folder = self.get_template_folder(client)
|
|
563
|
+
return SingleReplyConfig.load(folder / "single_reply_config.yaml")
|
|
564
|
+
|
|
517
565
|
def clear_caches(self) -> None:
|
|
518
566
|
"""Clear all configuration caches."""
|
|
519
567
|
FlowConfig.load.cache_clear()
|
|
@@ -523,6 +571,7 @@ class TemplateManager:
|
|
|
523
571
|
ConfirmationConfig.load.cache_clear()
|
|
524
572
|
OnboardingConfig.load.cache_clear()
|
|
525
573
|
StyleConfig.load.cache_clear()
|
|
574
|
+
SingleReplyConfig.load.cache_clear()
|
|
526
575
|
|
|
527
576
|
|
|
528
577
|
def get_template_manager() -> TemplateManager:
|
|
@@ -616,3 +665,8 @@ def load_style_config(client: Optional[str] = None) -> StyleConfig:
|
|
|
616
665
|
"""Load style configuration for the specified client."""
|
|
617
666
|
return get_template_manager().load_style_config(client)
|
|
618
667
|
|
|
668
|
+
|
|
669
|
+
def load_single_reply_config(client: Optional[str] = None) -> SingleReplyConfig:
|
|
670
|
+
"""Load single reply configuration for the specified client."""
|
|
671
|
+
return get_template_manager().load_single_reply_config(client)
|
|
672
|
+
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: atendentepro
|
|
3
|
-
Version: 0.6.
|
|
3
|
+
Version: 0.6.3
|
|
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
5
|
Author-email: BeMonkAI <contato@monkai.com.br>
|
|
6
6
|
Maintainer-email: BeMonkAI <contato@monkai.com.br>
|
|
@@ -25,33 +25,33 @@ Classifier: Operating System :: OS Independent
|
|
|
25
25
|
Requires-Python: >=3.9
|
|
26
26
|
Description-Content-Type: text/markdown
|
|
27
27
|
License-File: LICENSE
|
|
28
|
-
Requires-Dist: openai-agents
|
|
29
|
-
Requires-Dist: openai
|
|
30
|
-
Requires-Dist: pydantic
|
|
31
|
-
Requires-Dist: PyYAML
|
|
32
|
-
Requires-Dist: python-dotenv
|
|
33
|
-
Requires-Dist: httpx
|
|
34
|
-
Requires-Dist: numpy>=1.24.0
|
|
35
|
-
Requires-Dist: scikit-learn>=1.3.0
|
|
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
|
|
36
34
|
Provides-Extra: dev
|
|
37
|
-
Requires-Dist: pytest
|
|
38
|
-
Requires-Dist: pytest-asyncio
|
|
39
|
-
Requires-Dist: black
|
|
40
|
-
Requires-Dist: isort
|
|
41
|
-
Requires-Dist: mypy
|
|
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"
|
|
42
40
|
Provides-Extra: docs
|
|
43
|
-
Requires-Dist: mkdocs
|
|
44
|
-
Requires-Dist: mkdocs-material
|
|
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"
|
|
45
43
|
Provides-Extra: rag
|
|
46
|
-
Requires-Dist:
|
|
47
|
-
Requires-Dist:
|
|
48
|
-
Requires-Dist:
|
|
49
|
-
Requires-Dist:
|
|
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
50
|
Provides-Extra: tracing
|
|
51
|
-
Requires-Dist: monkai-trace
|
|
51
|
+
Requires-Dist: monkai-trace<1.0.0,>=0.2.9; extra == "tracing"
|
|
52
52
|
Provides-Extra: azure
|
|
53
|
-
Requires-Dist: opentelemetry-sdk
|
|
54
|
-
Requires-Dist: azure-monitor-opentelemetry-exporter
|
|
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
55
|
Provides-Extra: all
|
|
56
56
|
Requires-Dist: atendentepro[azure,dev,docs,rag,tracing]; extra == "all"
|
|
57
57
|
Dynamic: license-file
|
|
@@ -94,6 +94,7 @@ Plataforma que unifica múltiplos agentes especializados para resolver demandas
|
|
|
94
94
|
- [Feedback Agent](#-feedback-agent)
|
|
95
95
|
- [Fluxo de Handoffs](#-fluxo-de-handoffs)
|
|
96
96
|
- [Estilo de Comunicação](#-estilo-de-comunicação-agentstyle)
|
|
97
|
+
- [Single Reply Mode](#-single-reply-mode)
|
|
97
98
|
- [Tracing e Monitoramento](#-tracing-e-monitoramento)
|
|
98
99
|
- [Suporte](#-suporte)
|
|
99
100
|
|
|
@@ -707,6 +708,88 @@ agents:
|
|
|
707
708
|
|
|
708
709
|
---
|
|
709
710
|
|
|
711
|
+
## 🔁 Single Reply Mode
|
|
712
|
+
|
|
713
|
+
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.
|
|
714
|
+
|
|
715
|
+
### Quando Usar
|
|
716
|
+
|
|
717
|
+
- **Chatbots de alto volume**: Respostas rápidas e independentes
|
|
718
|
+
- **Consultas simples**: Uma pergunta = uma resposta
|
|
719
|
+
- **Evitar loops**: Impedir que usuários fiquem presos em um agente
|
|
720
|
+
|
|
721
|
+
### Via Código
|
|
722
|
+
|
|
723
|
+
```python
|
|
724
|
+
from pathlib import Path
|
|
725
|
+
from atendentepro import create_standard_network
|
|
726
|
+
|
|
727
|
+
# Ativar para TODOS os agentes
|
|
728
|
+
network = create_standard_network(
|
|
729
|
+
templates_root=Path("./meu_cliente"),
|
|
730
|
+
client="config",
|
|
731
|
+
global_single_reply=True, # Todos respondem uma vez
|
|
732
|
+
)
|
|
733
|
+
|
|
734
|
+
# Ativar apenas para agentes específicos
|
|
735
|
+
network = create_standard_network(
|
|
736
|
+
templates_root=Path("./meu_cliente"),
|
|
737
|
+
client="config",
|
|
738
|
+
global_single_reply=False,
|
|
739
|
+
single_reply_agents={
|
|
740
|
+
"knowledge": True, # Knowledge responde uma vez
|
|
741
|
+
"confirmation": True, # Confirmation responde uma vez
|
|
742
|
+
"answer": True, # Answer responde uma vez
|
|
743
|
+
# interview: False # Interview pode ter múltiplas interações
|
|
744
|
+
},
|
|
745
|
+
)
|
|
746
|
+
```
|
|
747
|
+
|
|
748
|
+
### Via YAML (single_reply_config.yaml)
|
|
749
|
+
|
|
750
|
+
Crie o arquivo `single_reply_config.yaml` na pasta do cliente:
|
|
751
|
+
|
|
752
|
+
```yaml
|
|
753
|
+
# Global: aplica a todos os agentes
|
|
754
|
+
global: false
|
|
755
|
+
|
|
756
|
+
# Configuração por agente
|
|
757
|
+
agents:
|
|
758
|
+
# Agentes que respondem uma vez
|
|
759
|
+
knowledge: true
|
|
760
|
+
confirmation: true
|
|
761
|
+
answer: true
|
|
762
|
+
|
|
763
|
+
# Agentes que precisam de múltiplas interações
|
|
764
|
+
interview: false
|
|
765
|
+
flow: false
|
|
766
|
+
onboarding: false
|
|
767
|
+
```
|
|
768
|
+
|
|
769
|
+
### Comportamento
|
|
770
|
+
|
|
771
|
+
Quando `single_reply=True`:
|
|
772
|
+
|
|
773
|
+
```
|
|
774
|
+
[Usuário] → [Triage] → [Knowledge]
|
|
775
|
+
↓
|
|
776
|
+
(responde uma vez)
|
|
777
|
+
↓
|
|
778
|
+
[Triage] ← (retorno automático)
|
|
779
|
+
```
|
|
780
|
+
|
|
781
|
+
Quando `single_reply=False` (padrão):
|
|
782
|
+
|
|
783
|
+
```
|
|
784
|
+
[Usuário] → [Triage] → [Knowledge]
|
|
785
|
+
↓
|
|
786
|
+
(pode continuar)
|
|
787
|
+
↕
|
|
788
|
+
[Usuário]
|
|
789
|
+
```
|
|
790
|
+
|
|
791
|
+
---
|
|
792
|
+
|
|
710
793
|
## 📊 Tracing e Monitoramento
|
|
711
794
|
|
|
712
795
|
### MonkAI Trace (Recomendado)
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
atendentepro/README.md,sha256=TAXl5GRjhSwz_I-Dx_eN5JOIcUxuE_dz31iMZ_-OnRY,45390
|
|
2
2
|
atendentepro/__init__.py,sha256=CDK61bxE18NYvLeswIoQWLarw2_xJAOEb2yONsQ2CqQ,5606
|
|
3
3
|
atendentepro/license.py,sha256=rlPtysXNqAzEQkP2VjUAVu_nMndhPgfKv1yN2ruUYVI,17570
|
|
4
|
-
atendentepro/network.py,sha256=
|
|
4
|
+
atendentepro/network.py,sha256=QEWgvNEWNkr1-xHd54dIdfFIgGJsRLBgQpuaDnQXknM,24124
|
|
5
5
|
atendentepro/agents/__init__.py,sha256=OcPhG1Dp6xe49B5YIti4HVmaZDoDIrFLfRa8GmI4jpQ,1638
|
|
6
|
-
atendentepro/agents/answer.py,sha256=
|
|
7
|
-
atendentepro/agents/confirmation.py,sha256=
|
|
8
|
-
atendentepro/agents/escalation.py,sha256=
|
|
9
|
-
atendentepro/agents/feedback.py,sha256=
|
|
10
|
-
atendentepro/agents/flow.py,sha256=
|
|
11
|
-
atendentepro/agents/interview.py,sha256=
|
|
12
|
-
atendentepro/agents/knowledge.py,sha256=
|
|
13
|
-
atendentepro/agents/onboarding.py,sha256=
|
|
6
|
+
atendentepro/agents/answer.py,sha256=S6wTchNSTMc0h6d89A4jAzoqecFPVqHUrr55-rCM-p4,2494
|
|
7
|
+
atendentepro/agents/confirmation.py,sha256=bQmIiDaxaCDIWJ3Fxz8h3AHW4kHhwbWSmyLX4y3dtls,2900
|
|
8
|
+
atendentepro/agents/escalation.py,sha256=tnFhHaV8VnrMMh_p8Xt9JTMe4bkWcGb6mChECm8aAvI,17779
|
|
9
|
+
atendentepro/agents/feedback.py,sha256=0cU6LVcIp_2ZBB-Cdprnwgw1C5IKYC_ydQ8HJnlheqo,33585
|
|
10
|
+
atendentepro/agents/flow.py,sha256=8SsAQ_f-daOM25EVBTMKGSUI9ywG3y4B0bFcCnrUfo0,2645
|
|
11
|
+
atendentepro/agents/interview.py,sha256=3eWHUw63OJuVpHH-QYtdL8SadRgevNLv2N8Esa4Za2c,2722
|
|
12
|
+
atendentepro/agents/knowledge.py,sha256=Xew_qhAdBrm3oVRvHhKh2oi6aURyeIKU5CtgfAHBYEI,11054
|
|
13
|
+
atendentepro/agents/onboarding.py,sha256=IId7N9VeTvHggjK_piDOAmwzBztj6oHqbZq7YOpVJIg,2687
|
|
14
14
|
atendentepro/agents/triage.py,sha256=pdYCA5AqbGMY0WoJXvdceAz_gnQ7D_fJp7dxxsD-GDg,1958
|
|
15
|
-
atendentepro/agents/usage.py,sha256=
|
|
15
|
+
atendentepro/agents/usage.py,sha256=tTfbqh3vRIDu0cnB65tv-Z3neEj90COp85nlIVpRLJ8,2183
|
|
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=
|
|
34
|
-
atendentepro/templates/manager.py,sha256=
|
|
33
|
+
atendentepro/templates/__init__.py,sha256=Xc3yTQcdUbzKphbOYEAefhV1v9FzLas_WzuphYVpk_0,1377
|
|
34
|
+
atendentepro/templates/manager.py,sha256=VHnu2dxWA6TR07QjJtsDZIRkwIjq-zGoIDysul7WMkE,23347
|
|
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.6.
|
|
39
|
-
atendentepro-0.6.
|
|
40
|
-
atendentepro-0.6.
|
|
41
|
-
atendentepro-0.6.
|
|
42
|
-
atendentepro-0.6.
|
|
43
|
-
atendentepro-0.6.
|
|
38
|
+
atendentepro-0.6.3.dist-info/licenses/LICENSE,sha256=TF6CdXxePoT9DXtPnCejiU5mUwWzrFzd1iyWJyoMauA,983
|
|
39
|
+
atendentepro-0.6.3.dist-info/METADATA,sha256=ijYMZnbksuX5O7ao9bA0deK6gI5eYM3jtE2S_hd2WOE,27835
|
|
40
|
+
atendentepro-0.6.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
41
|
+
atendentepro-0.6.3.dist-info/entry_points.txt,sha256=OP0upzqJF3MLS6VX-M-5BfUwx5YLJO2sJ3YBAp4e6yI,89
|
|
42
|
+
atendentepro-0.6.3.dist-info/top_level.txt,sha256=BFasD4SMmgDUmWKlTIZ1PeuukoRBhyiMIz8umKWVCcs,13
|
|
43
|
+
atendentepro-0.6.3.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|