# 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..evaluated e guardrail..blocked ├── judge_events.py # judge..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..evaluated / blocked ├── workflow.routing_decision ├── workflow.agent. │ └── generation. ├── workflow.output_guardrails ├── workflow.judge │ └── judge..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`: - `_AGENT_SESSION` - `_AGENT_MESSAGE` - `_WORKFLOW_CHECKPOINT` - `_WORKFLOW_CHECKPOINT_WRITE` - `_WORKFLOW_CHECKPOINT_BLOB` - `_SSE_EVENT` - `_CACHE_ENTRY` - `_RAG_DOCUMENT` - `_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.