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,24 @@
# Sample guideline, please follow similar structure for guideline with code samples
# 1. Suggest using streams instead of simple loops for better readability.
# <example>
# *Comment:
# Category: Minor
# Issue: Use streams instead of a loop for better readability.
# Code Block:
#
# ```java
# // Calculate squares of numbers
# List<Integer> squares = new ArrayList<>();
# for (int number : numbers) {
# squares.add(number * number);
# }
# ```
# Recommendation:
#
# ```java
# // Calculate squares of numbers
# List<Integer> squares = Arrays.stream(numbers)
# .map(n -> n * n) // Map each number to its square
# .toList();
# ```
# </example>

Binary file not shown.

View File

@@ -0,0 +1,68 @@
# Checkpoint Enterprise no Agent Framework OCI
Esta versão adiciona quatro capacidades ao checkpointer do LangGraph usado pelo framework:
1. **Checkpoint Integrity**: cada checkpoint é salvo dentro de um envelope com `schema_version`, `checkpoint_id`, `payload_hash` SHA-256 e `created_at`. Na leitura, o hash é recalculado. Se o payload foi truncado, alterado ou corrompido, o checkpoint é ignorado no recovery.
2. **Checkpoint Compaction**: checkpoints antigos são removidos automaticamente conforme a configuração `CHECKPOINT_COMPACT_EVERY` e `CHECKPOINT_KEEP_LAST`. Isso evita crescimento infinito da tabela `workflow_checkpoints`.
3. **Resilient Checkpointer**: gravações e leituras usam retry com backoff e jitter. A camada resiliente funciona sobre memory, SQLite e Oracle/Autonomous Database.
4. **Checkpoint Recovery**: ao recuperar o estado, o framework varre os últimos checkpoints e retorna o mais recente válido, pulando checkpoints corrompidos.
## Configuração
No `.env`:
```env
CHECKPOINT_REPOSITORY_PROVIDER=sqlite
ENABLE_RESILIENT_CHECKPOINTER=true
ENABLE_CHECKPOINT_INTEGRITY=true
ENABLE_CHECKPOINT_COMPACTION=true
CHECKPOINT_COMPACT_EVERY=50
CHECKPOINT_KEEP_LAST=20
CHECKPOINT_RECOVERY_SCAN_LIMIT=25
CHECKPOINT_RETRY_MAX_ATTEMPTS=3
CHECKPOINT_RETRY_BASE_DELAY_SECONDS=0.05
CHECKPOINT_RETRY_MAX_DELAY_SECONDS=1.0
CHECKPOINT_RETRY_JITTER_SECONDS=0.05
```
Para produção com múltiplos pods, prefira:
```env
CHECKPOINT_REPOSITORY_PROVIDER=autonomous
ADB_USER=...
ADB_PASSWORD=...
ADB_DSN=...
ADB_WALLET_LOCATION=...
ADB_TABLE_PREFIX=AGENTFW
```
## Uso no LangGraph
```python
from agent_framework.checkpoints import create_langgraph_checkpointer
checkpointer = create_langgraph_checkpointer(settings)
graph = builder.compile(checkpointer=checkpointer)
config = {"configurable": {"thread_id": session_id}}
result = graph.invoke(input_state, config=config)
```
O `thread_id` continua sendo a chave de recuperação da conversa. Em ambiente com Load Balancer, qualquer pod consegue retomar a execução se usar o mesmo repositório persistente.
## Arquivos alterados
- `agent_framework/src/agent_framework/checkpoints/checkpoint_repository.py`
- `agent_framework/src/agent_framework/checkpoints/langgraph_saver.py`
- `agent_framework/src/agent_framework/checkpoints/__init__.py`
- `agent_framework/src/agent_framework/config/settings.py`
- `tests/unit/test_resilient_checkpointer.py`
## Observação importante
O provider `memory` agora também usa o `RepositoryCheckpointSaver` quando `ENABLE_RESILIENT_CHECKPOINTER=true`. Para voltar ao `MemorySaver` puro do LangGraph em testes locais, configure:
```env
ENABLE_RESILIENT_CHECKPOINTER=false
CHECKPOINT_REPOSITORY_PROVIDER=memory
```

View File

@@ -0,0 +1,114 @@
# AI Agent Platform — Enterprise Routing Edition
Esta versão inclui o projeto completo com:
- `agent_framework`: framework reutilizável.
- `agent_template_backend`: backend FastAPI com LangGraph, OCI Generative AI, Langfuse, guardrails, judges, supervisor e roteamento enterprise.
- `agent_frontend`: frontend web independente.
- `templates/template_telecom_billing_product`: template de exemplo para telecom com agentes de Fatura e Produto.
- `templates/template_retail_orders_support`: template de exemplo para e-commerce com agentes de Pedido e Suporte.
## Roteamento enterprise
O roteamento fica em:
```text
agent_framework/src/agent_framework/routing/
```
Componentes principais:
- `models.py`: modelos `IntentDefinition`, `RouterStatePolicy`, `RouteDecision`.
- `config_loader.py`: carrega o YAML de intents e políticas.
- `enterprise_router.py`: decide o agente de destino por estado, keyword, LLM ou fallback.
O template usa:
```text
agent_template_backend/config/routing.yaml
```
## Ordem de decisão
1. Estado conversacional (`state_policies`).
2. Keywords/intents configuráveis.
3. LLM Router opcional (`ENABLE_LLM_ROUTER=true`).
4. Fallback (`router.fallback_agent`).
## Como testar roteamento sem chamar o agente final
```bash
curl -X POST http://localhost:8000/debug/route \
-H 'Content-Type: application/json' \
-d '{
"channel": "web",
"payload": {
"text": "Minha fatura veio alta",
"user_id": "u1",
"channel_id": "browser-1",
"context": {"msisdn": "5511999999999"}
}
}'
```
Resposta esperada:
```json
{
"route": "billing_agent",
"agent": "billing_agent",
"intent": "billing_invoice_explanation",
"method": "keyword"
}
```
## Como habilitar roteamento por LLM
No `.env` do backend:
```env
LLM_PROVIDER=oci_openai
OCI_GENAI_API_KEY=...
OCI_GENAI_BASE_URL=https://inference.generativeai.sa-saopaulo-1.oci.oraclecloud.com/openai/v1
OCI_GENAI_MODEL=openai.gpt-4.1
ENABLE_LLM_ROUTER=true
ROUTING_CONFIG_PATH=./config/routing.yaml
```
## Como adicionar novo agente
1. Criar classe do agente em `agent_template_backend/app/agents/`.
2. Instanciar o agente em `AgentWorkflow.__init__`.
3. Adicionar node no LangGraph.
4. Adicionar a rota no `add_conditional_edges`.
5. Criar intent no `config/routing.yaml` apontando `agent: nome_do_agente`.
## Templates incluídos
### Template 1 — Telecom
Diretório:
```text
templates/template_telecom_billing_product
```
Agentes:
- BillingAgent
- ProductAgent
### Template 2 — Retail/E-commerce
Diretório:
```text
templates/template_retail_orders_support
```
Agentes:
- OrdersAgent
- SupportAgent
Este segundo template mostra como reutilizar a mesma arquitetura para outro domínio de negócio.

View File

@@ -0,0 +1,23 @@
# Delta Implementado para Padrão FIRST
Esta versão corrige as prioridades levantadas na comparação com o FIRST:
1. Oracle Session Repository real
2. Oracle Message History real
3. Oracle LangGraph Checkpoint Repository real
4. LangGraph Deep Telemetry
5. Token Accounting
6. Cost Accounting
7. Session Lock SSE
8. Replay Buffer SSE
9. KeepAlive SSE
10. Recovery por Last-Event-ID
11. Redis Provider e Distributed Cache
12. Oracle Vector Provider
13. Oracle Graph Provider
14. RAG Telemetry
15. Langfuse Generation Tracking
16. OpenTelemetry/Event Bus compatível
17. OCI Streaming Exporter preservado
A lógica de domínio continua genérica; o framework não copia regras específicas de cobrança do FIRST.

View File

@@ -0,0 +1,45 @@
# Agent Framework FIRST Enterprise Plus
Esta versão evolui o framework nos quatro blocos solicitados:
1. **Langfuse Enterprise completo**
- `Telemetry.span()` com trace/session/user/metadata/tags.
- `Telemetry.generation()` com `usage`, token/cost metadata e compatibilidade Langfuse v2/v3.
- `Telemetry.score()` para judges/avaliações.
- Eventos arbitrários são registrados como spans seguros para evitar `Unknown observation type` no Langfuse.
2. **Token/Cost Accounting completo**
- `TokenUsageCollector` suporta `prompt_tokens`, `completion_tokens`, `cached_tokens`, `reasoning_tokens` e `total_tokens`.
- Tabela de preços por modelo via `MODEL_PRICES_JSON`.
- Conversão USD→BRL via `USD_BRL_RATE`.
- Persistência em `UsageRepository` e endpoint `/debug/usage`.
3. **Redis distribuído**
- `DistributedCache`: L1 memória + L2 Redis/SQLite/Oracle.
- `RedisCache` com `redis.asyncio` quando disponível e fallback sync.
- Namespace por `CACHE_KEY_PREFIX`.
- Telemetria de cache hit/miss/set/delete.
4. **Oracle Vector + PGQL reais**
- `OracleVectorStore` usa `VECTOR_DISTANCE(..., COSINE)` e `TO_VECTOR()` no Oracle 23ai.
- Tentativa automática de criar vector index quando suportado.
- `OracleGraphStore` usa tabelas `GRAPH_NODE` e `GRAPH_EDGE`.
- Suporte a criação de Property Graph e consulta por `GRAPH_TABLE`/PGQL, com fallback SQL.
Também foi corrigido o problema de duplicação SSE por replay + fila live usando controle de `max_replayed_id` no `SSEHub.subscribe()`.
## Testes
```bash
PYTHONPATH=agent_framework/src pytest -q tests/unit
```
Resultado validado nesta geração:
```text
17 passed
```
## Segurança
Os arquivos `.env` foram higienizados para não conter chaves reais. Configure suas credenciais localmente antes de usar OCI/Langfuse.

View File

@@ -0,0 +1,105 @@
# Ajustes operacionais finais — padrão FIRST
Esta versão corrige os gaps identificados na comparação contra o FIRST.
## Correções aplicadas
### 1. Checkpoint LangGraph operacional
O workflow não compila mais com `MemorySaver()` diretamente. Foi criado o adaptador:
```text
agent_framework/checkpoints/langgraph_saver.py
```
Ele conecta o LangGraph ao repository configurado do framework:
- `memory`
- `sqlite`
- `oracle` / `autonomous`
No workflow:
```python
builder.compile(checkpointer=create_langgraph_checkpointer(self.settings))
```
### 2. Telemetria LangGraph envolvendo a execução real
Foi adicionado wrapper de nó no workflow:
```python
self._node("billing_agent", self.billing_agent)
```
Assim o span/evento `langgraph.node.*` envolve a execução real do nó, não apenas um bloco vazio.
Eventos emitidos:
- `langgraph.node.started`
- `langgraph.node.completed`
- `langgraph.node.failed`
- `langgraph.edge.selected`
### 3. RAG integrado aos agentes
Os agentes agora recebem `RagService` e usam o contexto recuperado no prompt:
- BillingAgent
- ProductAgent
- OrdersAgent
- SupportAgent
O RAG usa:
- `VECTOR_STORE_PROVIDER=memory|sqlite|oracle|autonomous`
- `GRAPH_STORE_PROVIDER=memory|oracle|autonomous`
- `RAG_TOP_K`
### 4. Cache integrado ao runtime dos agentes
Criado mixin:
```text
agent_template_backend/app/agents/runtime.py
```
Ele adiciona:
- busca RAG padronizada;
- chave de cache para chamada LLM;
- hit/miss com telemetria;
- cache distribuído via `create_cache(settings)`.
### 5. Testes unitários
Criada pasta:
```text
tests/unit
```
Cobertura inicial:
- cache;
- SSE;
- RAG;
- checkpoint saver;
- telemetria LangGraph;
- runtime dos agentes;
- verificação estática do workflow;
- imports principais.
Validação local executada:
```text
12 passed
```
## Como testar
```bash
cd projeto_agent_framework_first_ready
pip install -r agent_template_backend/requirements.txt
pytest -q tests/unit
```

View File

@@ -0,0 +1,379 @@
# Projeto Agent Framework FIRST-ready
Esta versão mantém a arquitetura do `meu_projeto_agent_framework` e adiciona os padrões operacionais encontrados no projeto FIRST.
## Recursos adicionados
1. **SSE no padrão FIRST**
- `GET /gateway/events/{session_id}` para stream `text/event-stream`.
- `POST /gateway/message/sse` para processar mensagem emitindo eventos SSE.
- Eventos: `connected`, `flow.start`, `session.upserted`, `message.received`, `workflow.started`, `workflow.completed`, `message.responded`, `flow.end`.
- Keepalive configurável por `SSE_KEEPALIVE_SECONDS`.
- Lock por sessão para evitar concorrência dentro da mesma conversa.
- Replay de eventos via `Last-Event-ID` ou query param `last_event_id`.
2. **Persistência de sessão e mensagens**
- Implementado provider `sqlite`, executável localmente.
- `SESSION_REPOSITORY_PROVIDER=sqlite`.
- `MEMORY_REPOSITORY_PROVIDER=sqlite`.
- Tabelas locais: `agent_sessions`, `agent_messages`.
- Idempotência por `message_id`.
3. **Checkpoint persistente**
- Implementado provider `sqlite` para checkpoint final do workflow.
- `CHECKPOINT_REPOSITORY_PROVIDER=sqlite`.
- Endpoint de leitura: `GET /sessions/{session_id}/checkpoint`.
4. **Histórico de mensagens**
- Endpoint: `GET /sessions/{session_id}/messages`.
- Histórico usado como memória conversacional antes de chamar o LangGraph.
5. **Cache**
- Novo módulo `agent_framework.cache.cache`.
- Suporta cache local em memória e Redis se `ENABLE_REDIS_CACHE=true`.
6. **RAG / Vector Store**
- `agent_framework.rag.vector_store` agora possui `InMemoryVectorStore`, `SQLiteVectorStore` e contrato `AutonomousVectorStore`.
- A versão SQLite usa busca lexical local para desenvolvimento.
- O contrato permite trocar por Oracle Vector Search sem alterar a camada de aplicação.
7. **Observabilidade**
- Mantém Langfuse existente.
- Acrescenta eventos de gateway/SSE/workflow com `session_id`, `agent_id`, `tenant_id`, `message_id`, rota e intenção.
## Arquitetura resultante
```text
Browser
|-- POST /gateway/message/sse
|-- GET /gateway/events/{session_id}
|
FastAPI Template Backend
|
ChannelGateway
|
SessionRepository + MessageHistory + CheckpointRepository
|
LangGraph AgentWorkflow
|
Guardrails -> Router/Supervisor -> Agent -> Output Guardrails -> Judges
|
Telemetry / Langfuse / OCI Streaming
```
## Como rodar localmente
```bash
cd agent_template_backend
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
pip install -e ../agent_framework
uvicorn app.main:app --host 0.0.0.0 --port 8000
```
Frontend:
```bash
cd agent_frontend
python -m http.server 3000
```
Abra:
```text
http://localhost:3000
```
## Variáveis principais
```env
SESSION_REPOSITORY_PROVIDER=sqlite
MEMORY_REPOSITORY_PROVIDER=sqlite
CHECKPOINT_REPOSITORY_PROVIDER=sqlite
VECTOR_STORE_PROVIDER=sqlite
SQLITE_DB_PATH=./data/agent_framework.db
ENABLE_SSE=true
SSE_KEEPALIVE_SECONDS=15
ENABLE_MESSAGE_IDEMPOTENCY=true
```
## Teste via curl
Mensagem normal:
```bash
curl -X POST http://localhost:8000/gateway/message \
-H 'Content-Type: application/json' \
-d '{"channel":"web","payload":{"text":"teste","message":"teste","session_id":"s1","user_id":"u1","message_id":"m1"}}'
```
Mensagem com SSE:
```bash
curl -N http://localhost:8000/gateway/events/s1
```
Em outro terminal:
```bash
curl -X POST http://localhost:8000/gateway/message/sse \
-H 'Content-Type: application/json' \
-d '{"channel":"web","payload":{"text":"teste","message":"teste","session_id":"s1","user_id":"u1","message_id":"m2"}}'
```
Histórico:
```bash
curl http://localhost:8000/sessions/s1/messages
```
Checkpoint:
```bash
curl http://localhost:8000/sessions/s1/checkpoint
```
## Observação importante
A versão adicionada é executável localmente com SQLite. As classes `AutonomousSessionRepository`, `DatabaseMessageHistory`, `AutonomousCheckpointRepository` e `AutonomousVectorStore` mantêm o contrato para Oracle Autonomous Database, mas nesta entrega usam SQLite como backend local para permitir rodar e testar sem infraestrutura Oracle.
## Evolução de Observabilidade no padrão FIRST
Esta versão adiciona uma camada corporativa de observabilidade ao framework, mantendo os componentes reutilizáveis dentro de `agent_framework`.
### Componentes adicionados
```text
agent_framework/observability/
├── context.py # ContextVar: request_id, session_id, user_id, tenant_id, agent_id, channel, ura_call_id, workflow_id, message_id
├── telemetry.py # Facade central: span, event, generation, rag_event, cache_event, checkpoint_event
├── event_bus.py # Event bus interno para plugar logs, SSE, OCI Streaming, Elastic, Phoenix etc.
├── otel.py # OpenTelemetry opcional via OTLP
├── workflow_events.py # workflow.started, node.started, node.completed, edge.selected, workflow.failed
├── guardrail_events.py # guardrail.<CODE>.evaluated e guardrail.<CODE>.blocked
├── judge_events.py # judge.<NAME>.evaluated
├── streaming_events.py # sse.connected, sse.keepalive, sse.event.emitted
└── decorators.py # decorator @traced para classes do framework
```
### Correlação ponta-a-ponta
Cada chamada HTTP cria ou propaga `x-request-id` e o fluxo de mensagem vincula:
```text
request_id → tenant_id → agent_id → session_id → user_id → channel → message_id → workflow_id
```
O contexto usa `ContextVar`, portanto funciona em chamadas assíncronas, FastAPI, LangGraph e providers LLM.
### Langfuse
Ative no `.env`:
```env
ENABLE_LANGFUSE=true
LANGFUSE_PUBLIC_KEY=pk-lf-...
LANGFUSE_SECRET_KEY=sk-lf-...
LANGFUSE_HOST=http://localhost:3000
```
O framework registra:
```text
Trace de conversa
├── http.request
├── agent.gateway_message
├── workflow.langgraph.ainvoke
├── workflow.input_guardrails
│ └── guardrail.<CODE>.evaluated / blocked
├── workflow.routing_decision
├── workflow.agent.<agent>
│ └── generation.<model>
├── workflow.output_guardrails
├── workflow.judge
│ └── judge.<NAME>.evaluated
├── workflow.supervisor_review
├── workflow.persist
└── sse.event.emitted / sse.keepalive
```
### OpenTelemetry
Ative no `.env`:
```env
ENABLE_OTEL=true
OTEL_SERVICE_NAME=agent-framework-template
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318/v1/traces
```
Com isso, os mesmos spans são exportados via OTLP para Elastic, Grafana Tempo, Jaeger, Collector ou outro backend compatível.
### SSE observável
O `SSEHub` agora registra eventos de:
- conexão aberta;
- replay de eventos;
- evento emitido;
- keepalive;
- lock por sessão no processamento de mensagem.
### Guardrails e Judges
Além dos eventos agregados (`guardrails.input.completed`, `judges.completed`), cada decisão individual gera telemetria própria:
```text
guardrail.MSK.evaluated
guardrail.OOS.blocked
judge.response_quality.evaluated
judge.groundedness.evaluated
```
### Extensão para outros backends
A classe `Telemetry.event_bus` permite plugar novos handlers sem alterar o workflow. Exemplo:
```python
async def enviar_para_elastic(event):
...
telemetry.event_bus.subscribe(enviar_para_elastic)
```
---
## Evolução FIRST Enterprise Completa
Esta versão recebeu os componentes que faltavam para aproximar o framework do padrão operacional do projeto FIRST:
### Persistência Oracle Autonomous Database
Foram adicionados providers reais Oracle:
- `OracleSessionRepository`
- `OracleMessageHistory`
- `OracleCheckpointRepository`
- `OracleCache`
- `OracleVectorStore`
- `OracleGraphStore`
- `OracleStore`
Tabelas criadas automaticamente com prefixo configurável `ADB_TABLE_PREFIX`:
- `<PREFIX>_AGENT_SESSION`
- `<PREFIX>_AGENT_MESSAGE`
- `<PREFIX>_WORKFLOW_CHECKPOINT`
- `<PREFIX>_WORKFLOW_CHECKPOINT_WRITE`
- `<PREFIX>_WORKFLOW_CHECKPOINT_BLOB`
- `<PREFIX>_SSE_EVENT`
- `<PREFIX>_CACHE_ENTRY`
- `<PREFIX>_RAG_DOCUMENT`
- `<PREFIX>_GRAPH_EDGE`
### Configuração Oracle
```env
SESSION_REPOSITORY_PROVIDER=oracle
MEMORY_REPOSITORY_PROVIDER=oracle
CHECKPOINT_REPOSITORY_PROVIDER=oracle
CACHE_BACKEND_PROVIDER=oracle
VECTOR_STORE_PROVIDER=oracle
GRAPH_STORE_PROVIDER=oracle
SSE_STORE_PROVIDER=oracle
ADB_USER=ADMIN
ADB_PASSWORD=***
ADB_DSN=meu_adb_high
ADB_WALLET_LOCATION=/path/wallet
ADB_WALLET_PASSWORD=***
ADB_TABLE_PREFIX=AGENTFW
```
### SSE Enterprise
O SSE agora possui:
- lock por sessão (`SessionLockManager`)
- keepalive configurável
- replay por `Last-Event-ID`
- persistência de eventos em SQLite ou Oracle
- telemetria de conexão, replay, keepalive e desconexão
Endpoint:
```text
GET /gateway/events/{session_id}?last_event_id=123
```
### LangGraph Deep Telemetry
Foi adicionado `LangGraphDeepTelemetry` com eventos:
- `langgraph.node.started`
- `langgraph.node.completed`
- `langgraph.node.failed`
- `langgraph.edge.selected`
Esses eventos são enviados para o Event Bus, Langfuse e OpenTelemetry quando habilitados.
### Token e Cost Accounting
Foi adicionado:
- `TokenUsageCollector`
- `CostTracker`
- cálculo de `prompt_tokens`, `completion_tokens`, `cached_tokens`, `total_tokens`
- cálculo de `cost_usd` e `cost_brl`
Configuração opcional:
```env
USD_BRL_RATE=5.0
MODEL_PRICES_JSON={"openai.gpt-4.1":{"input_per_1m":"2.00","output_per_1m":"8.00"}}
```
### Cache Enterprise
O cache agora é em cascata:
```text
L1: InMemory
L2: Redis, SQLite ou Oracle
```
Configuração:
```env
ENABLE_REDIS_CACHE=true
REDIS_URL=redis://localhost:6379/0
```
ou:
```env
CACHE_BACKEND_PROVIDER=oracle
```
### RAG Oracle 23ai
Foi adicionado `OracleVectorStore`, com suporte a coluna `VECTOR` e `VECTOR_DISTANCE()` quando um embedding provider for conectado.
Sem embedding provider, mantém fallback lexical para desenvolvimento local.
Também foi adicionado `OracleGraphStore` com tabela de arestas, pronto para evoluir para PGQL/Property Graph.
### Langfuse
Cada chamada LLM agora gera `generation` com:
- input
- output
- model
- provider
- token usage
- cost metadata
Além disso, spans de workflow, guardrails, judges, RAG, cache, checkpoint, SSE e LangGraph são publicados pelo mesmo Event Bus.

View File

@@ -0,0 +1,62 @@
# Guardrails implementados no framework
Esta versão adiciona uma camada pragmática de guardrails ao `agent_framework`, inspirada na separação de rails por estágio: input, output, retrieval e execução/tool.
## Rails de input
- `MSIZE` — bloqueia mensagens excessivamente grandes.
- `MSK` — mascara CPF, CNPJ, telefone, e-mail, cartão, CEP, RG, tokens e chaves.
- `TOX` — detecta toxicidade e registra severidade sem bloquear por padrão.
- `PINJ` — detecta prompt injection e registra score.
- `JBRK` — detecta jailbreak/roleplay de burla e registra score.
- `VLOOP` — bloqueia loop conversacional repetitivo.
## Rails de output
- `PII_OUT` — mascara PII na resposta do agente.
- `CMP` — suaviza promessas absolutas e linguagem de garantia excessiva.
- `REVPREC` — bloqueia verbalização de ação operacional sem confirmação de tool.
- `GND` — sinaliza groundedness/risco quando há resposta específica sem evidência.
- `ALUC_RISK` — marca risco de alucinação para telemetria e judges.
## Rails opcionais
- `RET_REL` — valida relevância de chunks de retrieval por score mínimo.
- `TOOL_VAL` — valida ferramenta MCP/tool, argumentos obrigatórios, valores negativos e allowlist.
## Arquivos alterados
- `agent_framework/src/agent_framework/guardrails/rails.py`
- `agent_framework/src/agent_framework/guardrails/pipeline.py`
- `agent_framework/src/agent_framework/guardrails/__init__.py`
## Uso rápido
```python
from agent_framework.guardrails.pipeline import GuardrailPipeline
pipeline = GuardrailPipeline()
sanitized_input, input_decisions = await pipeline.run_input(
user_text,
{"history_texts": history_texts},
)
final_answer, output_decisions = await pipeline.run_output(
answer,
context,
)
```
Para tools/MCP:
```python
_, decisions = await pipeline.run_tool(
"cancelar_produto",
{"produto": "VAS", "valor": 0},
{
"required_args": ["produto"],
"allowed_tools": ["cancelar_produto", "consultar_fatura"],
},
)
```

View File

@@ -0,0 +1,139 @@
# Projeto Agent Framework — FIRST Operational Max
Esta versão adiciona os ajustes operacionais que faltavam para aproximar o framework do padrão FIRST em produção.
## Ajustes incluídos nesta versão
### 1. Langfuse Enterprise Adapter
Novo módulo:
```text
agent_framework/observability/langfuse_enterprise.py
```
Inclui adaptador compatível com SDKs Langfuse v2/v3 para:
- atualização de trace;
- score/avaliação de trace;
- prompt registry quando suportado pelo SDK;
- isolamento das diferenças de API do Langfuse.
### 2. Token e Cost Accounting persistente
Novo pacote:
```text
agent_framework/billing/
```
Inclui:
- `UsageRecord`
- `SQLiteUsageRepository`
- `OracleUsageRepository`
- `create_usage_repository(settings)`
O provider LLM agora registra automaticamente:
- `prompt_tokens`
- `completion_tokens`
- `cached_tokens`
- `total_tokens`
- `cost_usd`
- `cost_brl`
- `tenant_id`
- `agent_id`
- `session_id`
- `message_id`
Novo endpoint:
```http
GET /debug/usage
GET /debug/usage?tenant_id=default
GET /debug/usage?session_id=<id>
```
### 3. RAG Service operacional
Novo módulo:
```text
agent_framework/rag/rag_service.py
```
Inclui:
- `RagService.add_documents()`
- `RagService.retrieve()`
- `RagResult.as_prompt_context()`
- telemetria de latência, quantidade de documentos, top scores e grafo.
### 4. Configuração nova
Variável adicionada:
```env
USAGE_REPOSITORY_PROVIDER=sqlite
```
Valores:
```text
sqlite
oracle
autonomous
```
### 5. Compatibilidade operacional local
Por padrão, a contabilização de uso usa SQLite mesmo que o restante esteja em memória. Assim é possível testar localmente sem Oracle.
## Teste rápido
```bash
cd agent_template_backend
uvicorn app.main:app --host 0.0.0.0 --port 8000
```
Teste uma mensagem:
```bash
curl -X POST http://localhost:8000/gateway/message \
-H 'Content-Type: application/json' \
-d '{"channel":"web","payload":{"text":"teste","user_id":"u1","session_id":"s1"}}'
```
Verifique uso/custo:
```bash
curl http://localhost:8000/debug/usage
```
## Para rodar com padrão mais próximo de produção
```env
SESSION_REPOSITORY_PROVIDER=sqlite
MEMORY_REPOSITORY_PROVIDER=sqlite
CHECKPOINT_REPOSITORY_PROVIDER=sqlite
USAGE_REPOSITORY_PROVIDER=sqlite
CACHE_BACKEND_PROVIDER=sqlite
VECTOR_STORE_PROVIDER=sqlite
ENABLE_LANGFUSE=true
LANGFUSE_HOST=http://localhost:3000
LANGFUSE_PUBLIC_KEY=...
LANGFUSE_SECRET_KEY=...
```
Para Autonomous Database:
```env
SESSION_REPOSITORY_PROVIDER=oracle
MEMORY_REPOSITORY_PROVIDER=oracle
CHECKPOINT_REPOSITORY_PROVIDER=oracle
USAGE_REPOSITORY_PROVIDER=oracle
CACHE_BACKEND_PROVIDER=oracle
VECTOR_STORE_PROVIDER=oracle
GRAPH_STORE_PROVIDER=oracle
ADB_USER=...
ADB_PASSWORD=...
ADB_DSN=...
ADB_WALLET_LOCATION=...
ADB_TABLE_PREFIX=AGENTFW
```

View File

@@ -0,0 +1,75 @@
# AI Agent Platform com MCP Tools
Esta versão adiciona uma camada MCP ao framework:
- `agent_framework.mcp.MCPToolRouter`
- `agent_template_backend/config/mcp_servers.yaml`
- `agent_template_backend/config/tools.yaml`
- `mcp_servers/telecom_mcp_server`
- `mcp_servers/retail_mcp_server`
## Subir localmente
Terminal 1:
```bash
bash ./scripts/run_mcp_servers.sh
```
Terminal 2:
```bash
cd agent_template_backend
python -m venv .venv
source .venv/bin/activate
pip install -e ../agent_framework
pip install -r requirements.txt
uvicorn app.main:app --reload --reload-dir app --reload-dir config --port 8000
```
Terminal 3:
```bash
cd agent_frontend
python -m http.server 5173
```
## Testes rápidos
Listar tools MCP carregadas pelo backend:
```bash
curl http://localhost:8000/debug/mcp/tools
```
Chamar tool diretamente via backend:
```bash
curl -X POST http://localhost:8000/debug/mcp/call/consultar_fatura \
-H 'Content-Type: application/json' \
-d '{"msisdn":"11999999999","invoice_id":"INV-001"}'
```
Roteamento Telecom + MCP:
```bash
curl -X POST http://localhost:8000/gateway/message \
-H 'Content-Type: application/json' \
-d '{"channel":"web","payload":{"session_id":"sess-tel-1","message":"Minha fatura veio alta","context":{"msisdn":"11999999999","invoice_id":"INV-001"}}}'
```
Roteamento Retail + MCP:
```bash
curl -X POST http://localhost:8000/gateway/message \
-H 'Content-Type: application/json' \
-d '{"channel":"web","payload":{"session_id":"sess-ret-1","message":"Meu pedido não chegou","context":{"order_id":"PED-1001","customer_id":"C-001"}}}'
```
## Docker Compose
```bash
docker compose up --build
```
No compose, o backend usa `config/mcp_servers.docker.yaml` para apontar para `telecom-mcp` e `retail-mcp`.

View File

@@ -0,0 +1,108 @@
# Multi-agent isolation
Esta versão permite subir mais de um `agent_template` no mesmo backend e chavear por `agent_id` sem misturar estado.
## O que ficou isolado
A chave lógica usada pelo backend é:
```text
tenant_id:agent_id:session_id
```
Com isso ficam isolados:
- memória conversacional;
- checkpoints do LangGraph (`thread_id`);
- telemetria/tags;
- prompts por perfil de agente;
- configuração de guardrails por agente;
- configuração de judges por agente;
- metadados de sessão.
## Arquivo principal
```text
agent_template_backend/config/agents.yaml
```
Exemplo:
```yaml
default_agent_id: telecom_contas
agents:
- agent_id: telecom_contas
prompt_policy_path: ./config/agents/telecom_contas/prompt_policy.yaml
guardrails_config_path: ./config/agents/telecom_contas/guardrails.yaml
judges_config_path: ./config/agents/telecom_contas/judges.yaml
- agent_id: retail_orders
prompt_policy_path: ./config/agents/retail_orders/prompt_policy.yaml
guardrails_config_path: ./config/agents/retail_orders/guardrails.yaml
judges_config_path: ./config/agents/retail_orders/judges.yaml
```
## Como escolher o agente na chamada
### Telecom
```bash
curl -X POST http://localhost:8000/gateway/message \
-H 'Content-Type: application/json' \
-d '{
"channel": "web",
"agent_id": "telecom_contas",
"tenant_id": "tim",
"payload": {
"session_id": "sessao-123",
"user_id": "cliente-1",
"message": "Quero entender minha fatura",
"context": {"invoice_id": "FAT-001"}
}
}'
```
### Retail
```bash
curl -X POST http://localhost:8000/gateway/message \
-H 'Content-Type: application/json' \
-d '{
"channel": "web",
"agent_id": "retail_orders",
"tenant_id": "loja",
"payload": {
"session_id": "sessao-123",
"user_id": "cliente-1",
"message": "Onde está meu pedido?",
"context": {"order_id": "PED-001"}
}
}'
```
Mesmo usando o mesmo `session_id`, as conversas ficam separadas porque as chaves finais serão:
```text
tim:telecom_contas:sessao-123
loja:retail_orders:sessao-123
```
## Endpoints úteis
```text
GET /agents
GET /health
POST /debug/route
POST /gateway/message
```
## Como adicionar um novo agent_template
1. Crie uma pasta em `agent_template_backend/config/agents/<novo_agent_id>/`.
2. Adicione `prompt_policy.yaml`, `guardrails.yaml` e `judges.yaml`.
3. Registre o agente em `config/agents.yaml`.
4. Chame `/gateway/message` usando `agent_id=<novo_agent_id>`.
## Observação arquitetural
O backend continua usando um único processo FastAPI e um único framework instalado, mas o estado persistido não usa mais `session_id` sozinho. Isso evita que dois agentes compartilhem memória, checkpoints ou decisões de governança acidentalmente.

View File

@@ -0,0 +1,281 @@
# Modos de roteamento multi-agent: Enterprise Router e Supervisor
Este projeto suporta dois desenhos arquiteturais para roteamento entre agentes, sem precisar criar dois frameworks diferentes.
## Modos disponíveis
Configure por variável de ambiente:
```bash
ROUTING_MODE=router
```
ou:
```bash
ROUTING_MODE=supervisor
```
Também existe a chave documental em `agent_template_backend/config/routing.yaml`:
```yaml
router:
mode: router
```
A variável de ambiente `ROUTING_MODE` é a forma recomendada para ativar um modo em runtime, especialmente em Docker, Kubernetes ou OCI.
---
## Opção 1: Enterprise Router
Fluxo:
```text
Usuário
-> Input Guardrails
-> EnterpriseRouter
-> AgentRegistry
-> 1 agente especialista
-> Output Guardrails
-> Judges
-> Supervisor Review
-> Persistência/eventos
```
Uso recomendado quando cada mensagem deve ser atendida por um único agente especialista.
Exemplos:
- `Minha fatura veio alta` -> `billing_agent`
- `Onde está meu pedido?` -> `orders_agent`
- `Quero trocar um produto com defeito` -> `support_agent`
Vantagens:
- Menor latência.
- Menor custo de tokens.
- Debug mais simples.
- Mais fácil de operar em produção.
Limitação:
- Uma mensagem com múltiplos assuntos precisa ser roteada para um agente principal ou tratada por handoff.
---
## Opção 2: Supervisor
Fluxo:
```text
Usuário
-> Input Guardrails
-> Supervisor.route_plan
-> supervisor_agent
-> billing_agent opcional
-> orders_agent opcional
-> product_agent opcional
-> support_agent opcional
-> Consolidação
-> Output Guardrails
-> Judges
-> Supervisor Review
-> Persistência/eventos
```
Uso recomendado quando uma única mensagem pode envolver vários agentes.
Exemplo:
```text
Meu pedido não chegou e também fui cobrado duas vezes.
```
Neste caso, o supervisor pode acionar:
- `orders_agent`
- `billing_agent`
Vantagens:
- Suporta múltiplas intenções na mesma mensagem.
- Permite consolidação de respostas.
- Facilita cenários enterprise com vários domínios.
Custos:
- Maior latência.
- Maior consumo de tokens.
- Mais complexidade operacional.
---
## O que foi alterado no código
### 1. Configuração
Arquivo:
```text
agent_framework/src/agent_framework/config/settings.py
```
Foi adicionada a configuração:
```python
ROUTING_MODE: Literal['router','supervisor'] = 'router'
```
### 2. Workflow LangGraph
Arquivo:
```text
agent_template_backend/app/workflows/agent_graph.py
```
O nó `enterprise_route` foi substituído por um nó genérico:
```text
routing_decision
```
Esse nó decide o caminho com base em `ROUTING_MODE`:
- `router` usa `EnterpriseRouter`.
- `supervisor` usa `Supervisor.route_plan`.
Também foi adicionado o nó:
```text
supervisor_agent
```
Ele executa um ou mais agentes e consolida o resultado.
### 3. Supervisor
Arquivo:
```text
agent_framework/src/agent_framework/supervisor/supervisor.py
```
Foi adicionada a estrutura:
```python
SupervisorPlan
```
E o método:
```python
route_plan(state)
```
Esse método retorna uma lista de agentes a executar.
### 4. Debug
Endpoint:
```text
POST /debug/route
```
Agora respeita `ROUTING_MODE` e permite verificar rapidamente como uma mensagem será roteada.
---
## Como testar localmente
### Instalação
```bash
cd agent_template_backend
python -m venv .venv
source .venv/bin/activate
pip install -U pip setuptools wheel
pip install -e ../agent_framework
pip install -r requirements.txt
```
### Modo Router
```bash
export ROUTING_MODE=router
uvicorn app.main:app --reload --port 8000
```
Teste:
```bash
curl -X POST http://localhost:8000/debug/route \
-H 'Content-Type: application/json' \
-d '{"channel":"web","payload":{"text":"Onde está meu pedido?","session_id":"s1"}}'
```
Resultado esperado:
```json
{
"mode": "router",
"route": "orders_agent"
}
```
### Modo Supervisor
```bash
export ROUTING_MODE=supervisor
uvicorn app.main:app --reload --port 8000
```
Teste:
```bash
curl -X POST http://localhost:8000/debug/route \
-H 'Content-Type: application/json' \
-d '{"channel":"web","payload":{"text":"Meu pedido atrasou e minha fatura veio duplicada","session_id":"s2"}}'
```
Resultado esperado:
```json
{
"mode": "supervisor",
"route": "supervisor_agent",
"agents": ["billing_agent", "orders_agent"]
}
```
---
## Isolamento
A chave lógica de isolamento permanece:
```text
tenant_id:agent_id:session_id
```
Use essa chave para memória, sessão, checkpoint e telemetria. Em produção, recomenda-se padronizar `agent_id` por agente especialista ou por template, dependendo do nível de isolamento desejado.
---
## Recomendação
Comece em produção com:
```bash
ROUTING_MODE=router
```
Ative:
```bash
ROUTING_MODE=supervisor
```
quando houver necessidade real de múltiplos agentes na mesma mensagem.

View File

@@ -0,0 +1,86 @@
# Template Backend/Frontend alinhado ao BusinessContext v2
Este pacote atualiza o `agent_template_backend` e o `agent_frontend` para refletir o framework novo, onde as chaves vindas do canal/front-end são resolvidas uma vez como chaves canônicas e propagadas pelas camadas até o MCP Server.
## Fluxo implementado
1. O front-end envia `tenant_id`, `agent_id`, `session_id` e `business_context`.
2. O backend normaliza a mensagem via `ChannelGateway` preservando todo o payload no `context`.
3. O backend usa `IdentityResolver` com `config/identity.yaml` para gerar `BusinessContext`:
- `customer_key`
- `contract_key`
- `interaction_key`
- `account_key`
- `resource_key`
- `session_key`
4. O workflow recebe `context.business_context`.
5. Os agentes de exemplo não montam mais argumentos específicos como `msisdn`, `invoice_id` ou `order_id` diretamente.
6. O `MCPToolRouter` usa `config/mcp_parameter_mapping.yaml` para converter chaves canônicas em parâmetros reais de cada tool MCP.
## Arquivos principais ajustados
- `agent_template_backend/app/main.py`
- carrega `IdentityResolver`;
- resolve `BusinessContext` por mensagem;
- persiste as chaves na sessão/memória/metadata/SSE;
- adiciona `/debug/identity`.
- `agent_template_backend/app/agents/runtime.py`
- adiciona `_collect_mcp_context()` centralizado;
- repassa `business_context` e `original_context` para o MCP Router.
- `agent_template_backend/app/agents/*_agent.py`
- agentes passam a usar `_collect_mcp_context()` em vez de montar argumentos específicos.
- `agent_template_backend/config/identity.yaml`
- define como campos do canal/front-end alimentam as chaves canônicas.
- `agent_template_backend/config/mcp_parameter_mapping.yaml`
- define como chaves canônicas viram parâmetros reais por tool MCP.
- `agent_frontend/index.html` e `agent_frontend/app.js`
- adicionam campos de `tenant`, `agent` e chaves canônicas;
- enviam `business_context` no payload;
- mantêm aliases de domínio para compatibilidade (`msisdn`, `invoice_id`, `order_id`, etc.).
## Teste rápido
Suba backend, frontend e MCP servers. Depois teste:
```bash
curl -s http://localhost:8000/health | jq
curl -s -X POST http://localhost:8000/debug/identity \
-H 'Content-Type: application/json' \
-d '{
"channel":"web",
"tenant_id":"default",
"agent_id":"telecom_contas",
"payload":{
"message":"Minha fatura veio alta",
"session_id":"teste-001",
"msisdn":"11999999999",
"invoice_id":"3000131180",
"ura_call_id":"URA-123",
"business_context":{
"customer_key":"11999999999",
"contract_key":"3000131180",
"interaction_key":"URA-123",
"session_key":"teste-001"
}
}
}' | jq
curl -s -X POST http://localhost:8000/debug/mcp/call/consultar_fatura \
-H 'Content-Type: application/json' \
-d '{
"business_context": {
"customer_key":"11999999999",
"contract_key":"3000131180",
"interaction_key":"URA-123",
"session_key":"teste-001"
}
}' | jq
```
No log do backend, procure por `mcp.tool.mapped`. Ele deve indicar as chaves mapeadas e `has_msisdn=true`, `has_invoice_id=true` para o domínio telecom.

View File

@@ -0,0 +1,28 @@
# Testes unitários do framework
Esta versão inclui uma pasta `tests/unit` cobrindo os componentes principais:
- cache local e distribuído;
- SSE com encode, persistência e replay;
- RAG com busca vetorial em memória;
- checkpoint saver compatível com LangGraph;
- telemetria profunda de LangGraph;
- runtime dos agentes com cache/RAG;
- verificação estática do workflow para garantir que não usa mais `MemorySaver()` diretamente.
## Como executar
```bash
cd projeto_agent_framework_first_ready
python -m venv .venv
source .venv/bin/activate
pip install -r agent_template_backend/requirements.txt
pip install pytest pytest-asyncio
pytest -q
```
Para rodar apenas os testes unitários:
```bash
pytest -q tests/unit
```

113
Documentacao/README_old.md Normal file
View File

@@ -0,0 +1,113 @@
# AI Agent Platform — LangGraph + OCI
Monorepo com três projetos independentes:
- `agent_framework/`: biblioteca reutilizável para agentes escaláveis.
- `agent_template_backend/`: backend FastAPI usando o framework, com dois agentes, roteador, máquina de estados, sessão persistente e gateway de canais.
- `agent_frontend/`: frontend web simples e independente para conversar com o backend via gateway HTTP.
## Visão de arquitetura
```text
Frontend Web / WhatsApp / Voz / Texto
Channel Gateway + Adapters
SessionRepository persistente
Supervisor / Router Agent
LangGraph StateGraph
Agent A Agent B
↓ ↓
Guardrails → LLM OCI Generative AI → Output Guardrails → Judges
Memory / RAG / Vector / Graph / Telemetry / Streaming
```
![img_1.png](../img_1.png)
## Quickstart local
Suba a estrutura de Langfuse, MongoDB, REDIS para seu ambiente de desenvolvimento:
Vá até o folder ./agent_framework/Infrastructure_Langfuse/, onde existe o docker-compose.yml e execute:
```bash
docker compose up
```
O langfuse estará em:
```bash
http://localhost:3005
```
Crie sua Organização e seu projeto
![img.png](../img.png)
Será criado também um MongoDB e um REDIS, logo seu .env terá a configuração para apontar para estes recursos conteinerizados.
Você pode também apontar para um banco de dados Autonomous Oracle, basta configurar no arquivo .env.
Depois compile do Agent Framework dentro do agent_template_backend (agente template que se utiliza do Framework):
Obs: configure o arquivo .env.
Terminal 1:
```bash
cd agent_framework_oci
python -m venv .venv
source .venv/bin/activate
cd agent_template_backend
pip install -e ../agent_framework
pip install -r requirements.txt
uvicorn app.main:app --reload --reload-dir app --reload-dir config --port 8000
```
Terminal 2:
```bash
cd agent_framework_oci
bash ./scripts/run_mcp_servers.sh
```
Terminal 3:
```bash
cd agent_framework_oci
cd agent_frontend
python -m http.server 5173
```
Abra `http://localhost:5173`.
## OCI LLM
Configure no `.env`:
```env
LLM_PROVIDER=oci_openai
OCI_GENAI_BASE_URL=https://inference.generativeai.sa-saopaulo-1.oci.oraclecloud.com/openai/v1
OCI_GENAI_MODEL=openai.gpt-4.1
OCI_GENAI_API_KEY=...
```
Para rodar sem credenciais, use:
```env
LLM_PROVIDER=mock
```
## Estado do projeto
Este é um template de referência funcional/simulável. Conectores reais de Autonomous Database, MongoDB, Redis, Langfuse, OCI Streaming e OCI GenAI estão isolados por interfaces/adapters para facilitar evolução e deploy.
## Enterprise Routing Edition
Esta versão também possui `README_ENTERPRISE_ROUTING.md`, com detalhes sobre roteamento por estado, intents configuráveis, LLM Router opcional e dois templates de exemplo.
## Multi-agent isolation
Esta distribuição inclui suporte para múltiplos `agent_template` no mesmo backend.
Consulte `README_MULTI_AGENT_ISOLATION.md`.

1545
Documentacao/README_old2.md Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,38 @@
VALIDAÇÃO - GLOBAL SUPERVISOR
Alterações implementadas:
1. Framework
- agent_framework.global_supervisor.models
- agent_framework.global_supervisor.config
- agent_framework.global_supervisor.session_store
- agent_framework.global_supervisor.router
- agent_framework.global_supervisor.client
2. Novo serviço
- agent_gateway/app/main.py
- agent_gateway/app/settings.py
- agent_gateway/config/backends.yaml
- agent_gateway/README.md
- agent_gateway/Dockerfile
- agent_gateway/docs/ARQUITETURA_GLOBAL_SUPERVISOR.md
3. Docker Compose
- serviço agent-gateway adicionado na porta 8010.
Validações executadas:
- python3 -m compileall -q agent_framework/src/agent_framework/global_supervisor agent_gateway/app
Resultado: OK
- Smoke test do roteamento híbrido:
Entrada 1: "Minha fatura veio alta" -> contas
Entrada 2: "e esse valor?" na mesma session_id -> contas por active_backend
Resultado: OK
- Smoke test de import do app FastAPI:
from app.main import app, registry, router
Resultado: OK
Observação:
- O proxy SSE do gateway foi deixado como etapa futura. O endpoint /gateway/message/sse já roteia e encaminha como mensagem normal; para SSE fim-a-fim, pode-se implementar proxy de /gateway/events/{session_id} para o backend ativo.

View File

@@ -0,0 +1,5 @@
VALIDATION REPORT - guardrails parallel fail-fast + observer IC
Date: 2026-06-03
compileall: OK
smoke-tests: OK

BIN
Documentacao/img.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 186 KiB