First commit

This commit is contained in:
2026-06-19 22:17:09 -03:00
commit 239203ee2a
533 changed files with 75195 additions and 0 deletions

View File

@@ -0,0 +1,12 @@
# Desenvolvimento de agentes
Os arquivos `billing_agent.py`, `product_agent.py`, `orders_agent.py` e `support_agent.py` foram mantidos com os mesmos nomes do template completo para o workflow continuar compatível.
A implementação de negócio original está comentada no final de cada arquivo.
Para criar seu agente:
1. Edite o método `run()` da classe desejada.
2. Use o bloco comentado como referência.
3. Depois, ajuste o roteamento em `config/routing.yaml`.
4. Se quiser renomear classes/arquivos, atualize também os imports em `app/workflows/agent_graph.py`.

View File

@@ -0,0 +1,67 @@
"""
DAY ZERO TEMPLATE - BillingAgent
Esqueleto mínimo já compatível com ConversationSummaryMemory.
Substitua o prompt e a regra de negócio conforme o seu agente.
"""
from app.agents.prompting import apply_agent_profile_prompt
from app.agents.runtime import AgentRuntimeMixin
class BillingAgent(AgentRuntimeMixin):
name = "billingAgent"
def __init__(
self,
llm,
telemetry=None,
tool_router=None,
rag_service=None,
cache=None,
settings=None,
observer=None,
memory=None,
summary_memory=None,
):
self.llm = llm
self.telemetry = telemetry
self.tool_router = tool_router
self.rag_service = rag_service
self.cache = cache
self.settings = settings
self.observer = observer
self.memory = memory
self.summary_memory = summary_memory
async def run(self, state):
# OPCIONAL: habilite quando seu agente precisar de MCP/RAG.
tool_context = []
rag_context = None
rag_metadata = {}
# Prepara a memória resumida antes do prompt.
await self.prepare_memory_context(state)
messages = self.build_messages(
state,
system_prompt=apply_agent_profile_prompt(
state,
"Você é um agente especialista em faturas. Responda com clareza, objetividade e sem sugerir ações não solicitadas. Use dados MCP quando disponíveis.",
),
mcp_results=tool_context,
rag_context=rag_context,
rag_metadata=rag_metadata,
)
answer = await self._invoke_llm_cached(state, "BillingAgent", messages)
return {
"answer": answer,
"next_state": "DAY_ZERO_ACTIVE",
"mcp_results": tool_context,
"rag": rag_metadata,
"memory_context_metadata": state.get("memory_context_metadata"),
}
async def _collect_tool_context(self, state):
return await self._collect_mcp_context(state)

View File

@@ -0,0 +1,67 @@
"""
DAY ZERO TEMPLATE - OrdersAgent
Esqueleto mínimo já compatível com ConversationSummaryMemory.
Substitua o prompt e a regra de negócio conforme o seu agente.
"""
from app.agents.prompting import apply_agent_profile_prompt
from app.agents.runtime import AgentRuntimeMixin
class OrdersAgent(AgentRuntimeMixin):
name = "orders_agent"
def __init__(
self,
llm,
telemetry=None,
tool_router=None,
rag_service=None,
cache=None,
settings=None,
observer=None,
memory=None,
summary_memory=None,
):
self.llm = llm
self.telemetry = telemetry
self.tool_router = tool_router
self.rag_service = rag_service
self.cache = cache
self.settings = settings
self.observer = observer
self.memory = memory
self.summary_memory = summary_memory
async def run(self, state):
# OPCIONAL: habilite quando seu agente precisar de MCP/RAG.
tool_context = []
rag_context = None
rag_metadata = {}
# Prepara a memória resumida antes do prompt.
await self.prepare_memory_context(state)
messages = self.build_messages(
state,
system_prompt=apply_agent_profile_prompt(
state,
"Você é um agente de pedidos de varejo. Use dados de tools quando disponíveis.",
),
mcp_results=tool_context,
rag_context=rag_context,
rag_metadata=rag_metadata,
)
answer = await self._invoke_llm_cached(state, "OrdersAgent", messages)
return {
"answer": answer,
"next_state": "DAY_ZERO_ACTIVE",
"mcp_results": tool_context,
"rag": rag_metadata,
"memory_context_metadata": state.get("memory_context_metadata"),
}
async def _collect_tool_context(self, state):
return await self._collect_mcp_context(state)

View File

@@ -0,0 +1,67 @@
"""
DAY ZERO TEMPLATE - ProductAgent
Esqueleto mínimo já compatível com ConversationSummaryMemory.
Substitua o prompt e a regra de negócio conforme o seu agente.
"""
from app.agents.prompting import apply_agent_profile_prompt
from app.agents.runtime import AgentRuntimeMixin
class ProductAgent(AgentRuntimeMixin):
name = "productAgent"
def __init__(
self,
llm,
telemetry=None,
tool_router=None,
rag_service=None,
cache=None,
settings=None,
observer=None,
memory=None,
summary_memory=None,
):
self.llm = llm
self.telemetry = telemetry
self.tool_router = tool_router
self.rag_service = rag_service
self.cache = cache
self.settings = settings
self.observer = observer
self.memory = memory
self.summary_memory = summary_memory
async def run(self, state):
# OPCIONAL: habilite quando seu agente precisar de MCP/RAG.
tool_context = []
rag_context = None
rag_metadata = {}
# Prepara a memória resumida antes do prompt.
await self.prepare_memory_context(state)
messages = self.build_messages(
state,
system_prompt=apply_agent_profile_prompt(
state,
"Você é um agente especialista em produtos, planos e serviços. Explique sem fazer oferta proativa e sem executar ações sem confirmação. Use dados MCP quando disponíveis.",
),
mcp_results=tool_context,
rag_context=rag_context,
rag_metadata=rag_metadata,
)
answer = await self._invoke_llm_cached(state, "ProductAgent", messages)
return {
"answer": answer,
"next_state": "DAY_ZERO_ACTIVE",
"mcp_results": tool_context,
"rag": rag_metadata,
"memory_context_metadata": state.get("memory_context_metadata"),
}
async def _collect_tool_context(self, state):
return await self._collect_mcp_context(state)

View File

@@ -0,0 +1,15 @@
from __future__ import annotations
def apply_agent_profile_prompt(state: dict, default_prompt: str) -> str:
"""Adiciona o prefixo de prompt configurado para o agent_template selecionado.
Cada agent_id pode definir metadata.system_prefix em config/agents.yaml. Isso
mantém prompts isolados sem duplicar o código dos agentes especializados.
"""
profile = state.get("agent_profile") or (state.get("context") or {}).get("agent_profile") or {}
metadata = profile.get("metadata") or {}
prefix = (metadata.get("system_prefix") or "").strip()
if not prefix:
return default_prompt
return f"{prefix}\n\n{default_prompt}"

View File

@@ -0,0 +1,7 @@
from __future__ import annotations
# Compatibilidade local do template/backend.
# A implementação oficial agora fica no framework para evitar duplicação entre agentes.
from agent_framework.runtime import AgentRuntimeMixin, MessageBuilder, RuntimeContext
__all__ = ["AgentRuntimeMixin", "MessageBuilder", "RuntimeContext"]

View File

@@ -0,0 +1,67 @@
"""
DAY ZERO TEMPLATE - SupportAgent
Esqueleto mínimo já compatível com ConversationSummaryMemory.
Substitua o prompt e a regra de negócio conforme o seu agente.
"""
from app.agents.prompting import apply_agent_profile_prompt
from app.agents.runtime import AgentRuntimeMixin
class SupportAgent(AgentRuntimeMixin):
name = "support_agent"
def __init__(
self,
llm,
telemetry=None,
tool_router=None,
rag_service=None,
cache=None,
settings=None,
observer=None,
memory=None,
summary_memory=None,
):
self.llm = llm
self.telemetry = telemetry
self.tool_router = tool_router
self.rag_service = rag_service
self.cache = cache
self.settings = settings
self.observer = observer
self.memory = memory
self.summary_memory = summary_memory
async def run(self, state):
# OPCIONAL: habilite quando seu agente precisar de MCP/RAG.
tool_context = []
rag_context = None
rag_metadata = {}
# Prepara a memória resumida antes do prompt.
await self.prepare_memory_context(state)
messages = self.build_messages(
state,
system_prompt=apply_agent_profile_prompt(
state,
"Você é um agente de suporte de varejo para troca, devolução e garantia.",
),
mcp_results=tool_context,
rag_context=rag_context,
rag_metadata=rag_metadata,
)
answer = await self._invoke_llm_cached(state, "SupportAgent", messages)
return {
"answer": answer,
"next_state": "DAY_ZERO_ACTIVE",
"mcp_results": tool_context,
"rag": rag_metadata,
"memory_context_metadata": state.get("memory_context_metadata"),
}
async def _collect_tool_context(self, state):
return await self._collect_mcp_context(state)