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,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.