| title | AETHERIS |
|---|---|
| emoji | 🧠 |
| colorFrom | indigo |
| colorTo | purple |
| sdk | docker |
| app_port | 7860 |
| pinned | false |
| license | mit |
| short_description | Agente Cognitivo Autonomo - RAG + Google Workspace + HITL |
Agente Cognitivo Autónomo — Trabajo Fin de Máster (TFM, Máster en Soluciones IAG)
AETHERIS evoluciona el concepto de chatbot hacia un agente que piensa, recupera, busca y actúa. Combina una base de conocimiento RAG, búsqueda web en tiempo real (Tavily MCP, 5 herramientas), automatización de Google Workspace (Calendar, Gmail y Drive) con confirmación Human-in-the-Loop, memoria persistente con mem0.ai y observabilidad completa con LangSmith — todo ello tras una interfaz Streamlit limpia y con seguridad mediante Guardrails bilingües (EN/ES).
Streamlit (puerto 8501) ──SSE──► FastAPI (puerto 8000) ──► Grafo LangGraph
│
┌───────────────────────────────┤
│ │ │
RAG (Chroma) Herramientas MCP Memoria
(Tavily 5 tools / (mem0 + SQLite + Chroma)
Google Calendar
+ Gmail Python stdio (gmail_mcp_server.py)
+ Google Drive)
Documentación completa de arquitectura: docs/architecture.md
| Característica | Tecnología |
|---|---|
| RAG (documentos privados) | LangChain + Chroma, recuperación MMR, >85% tasa de acierto |
| Búsqueda web — 5 herramientas | tavily-mcp: search, research, extract, crawl, map |
| Google Workspace | Calendar (stdio), Gmail (stdio, Python nativo) y Drive (stdio) mediante MCP OAuth2 |
| Human-in-the-Loop | HITL uno a uno: aprobación/rechazo por acción; cola de acciones pendientes; rechazo continúa con la siguiente acción; lecturas auto-ejecutadas |
| Guardrails de seguridad | Filtrado entrada/salida bilingüe (EN+ES), detección de inyección de prompts, redacción de PII |
| Fallback LLM | OpenAI → AWS Bedrock (Anthropic Claude) automático |
| Memoria a corto plazo | mem0.ai (cloud o local con Chroma) |
| Memoria a largo plazo | SQLite (clave-valor) + Chroma (búsqueda semántica) |
| Observabilidad | LangSmith — trazas, costes, latencia |
| Streaming | FastAPI SSE → Streamlit renderizado token a token |
| Transcripción de audio | faster-whisper (STT local) vía /api/v1/speech/transcribe |
- Python 3.12+
- Node.js 18+ (necesario para servidores MCP vía
npx) - Claves API: OpenAI, LangSmith, Tavily
- Google OAuth:
client_secret_aetheris.json+GOOGLE_REFRESH_TOKEN(Calendar, Gmail y Drive) - (Opcional) Credenciales AWS para fallback Bedrock
- (Opcional) Clave API de mem0.ai para modo cloud
pip install -r requirements.txtcp .env.example .env
# Edita .env y rellena todas las claves APICopia el fichero client_secret_*.json de Google Cloud Console en data/google/ y ejecuta:
# Calendar — obtiene data/google/.calendar-token.json
# Windows PowerShell:
$env:GOOGLE_OAUTH_CREDENTIALS="data/google/client_secret_aetheris.json"
$env:GOOGLE_CALENDAR_MCP_TOKEN_PATH="data/google/.calendar-token.json"
npx -y @cocal/google-calendar-mcp auth
# Linux / macOS:
GOOGLE_OAUTH_CREDENTIALS=data/google/client_secret_aetheris.json \
GOOGLE_CALENDAR_MCP_TOKEN_PATH=data/google/.calendar-token.json \
npx -y @cocal/google-calendar-mcp auth# Drive — obtiene data/google/.drive-token.json
# Windows PowerShell:
$env:GOOGLE_OAUTH_CREDENTIALS="data/google/client_secret_aetheris.json"
npx @modelcontextprotocol/server-gdrive auth
# Linux / macOS:
GOOGLE_OAUTH_CREDENTIALS=data/google/client_secret_aetheris.json \
npx @modelcontextprotocol/server-gdrive authCopia el refresh_token del fichero generado en GOOGLE_REFRESH_TOKEN de tu .env.
Gmail usa el servidor Python nativo
aetheris/mcp_tools/gmail_mcp_server.pycon transporte stdio — se lanza automáticamente al arrancar AETHERIS, sin dependencia npm ni proceso HTTP externo. No requierenpx authadicional: usa el mismoGOOGLE_REFRESH_TOKENque Calendar y Drive.
uvicorn aetheris.api.main:app --reload --host 0.0.0.0 --port 8000streamlit run aetheris/ui/app.py --server.port 8501Abre http://localhost:8501 en tu navegador.
AETHERIS incluye configuración lista para desplegar en Hugging Face Spaces con el runtime Docker.
HF Spaces (puerto publico 7860)
│
▼
[supervisord]
├── Streamlit :7860 (publico)
└── FastAPI :8000 (interno — Streamlit lo llama via localhost)
-
Crear un Space en huggingface.co/new-space:
- SDK: Docker
- Hardware: CPU Basic (gratuito) o superior
-
Subir el repositorio (o conectar tu repo de GitHub):
git remote add hf https://huggingface.co/spaces/<tu-usuario>/aetheris git push hf main
-
Configurar secretos en Settings → Repository secrets:
Secreto Descripción OPENAI_API_KEYClave OpenAI LANGSMITH_API_KEYClave LangSmith TAVILY_API_KEYClave Tavily (opcional) GOOGLE_REFRESH_TOKENRefresh token OAuth2 Google GOOGLE_CLIENT_SECRET_JSONContenido base64 del client_secret JSON Obtener
GOOGLE_CLIENT_SECRET_JSON:# Linux / Mac base64 -w 0 data/google/client_secret_aetheris.json # Windows PowerShell [Convert]::ToBase64String([IO.File]::ReadAllBytes('data\google\client_secret_aetheris.json'))
-
HF Spaces construirá la imagen automáticamente al detectar el
Dockerfile. El entrypoint (scripts/entrypoint.sh) decodifica los secretos y arranca supervisord.
# Construir la imagen
docker build -t aetheris .
# Ejecutar localmente (equivalente a HF Spaces)
docker run -p 7860:7860 \
-e OPENAI_API_KEY=sk-... \
-e GOOGLE_REFRESH_TOKEN=1//... \
-e GOOGLE_CLIENT_SECRET_JSON=$(base64 -w 0 data/google/client_secret_aetheris.json) \
aetherisAbre http://localhost:7860 en tu navegador.
# Ingestar un solo fichero
python scripts/ingest_documents.py --file ./mi_informe.pdf
# Ingestar una carpeta completa
python scripts/ingest_documents.py --dir ./docs/| Variable | Obligatoria | Descripción |
|---|---|---|
OPENAI_API_KEY |
Sí | Clave API de OpenAI (LLM + embeddings) |
AWS_ACCESS_KEY_ID |
No | Credenciales AWS para Bedrock (fallback) |
AWS_SECRET_ACCESS_KEY |
No | Credenciales AWS para Bedrock (fallback) |
AWS_REGION |
No | Región AWS (por defecto: eu-west-1) |
BEDROCK_MODEL_ID |
No | ID del modelo en Bedrock |
LANGSMITH_API_KEY |
Sí | Observabilidad LangSmith |
LANGSMITH_PROJECT |
No | Nombre del proyecto (por defecto: aetheris) |
LANGCHAIN_TRACING_V2 |
No | Activar trazado LangSmith (true) |
TAVILY_API_KEY |
No | Búsqueda web MCP Tavily (5 herramientas) |
MEM0_API_KEY |
No | mem0.ai cloud (dejar vacío para modo local) |
GOOGLE_CLIENT_SECRET_FILE |
No | Ruta a client_secret_aetheris.json |
GOOGLE_REFRESH_TOKEN |
No | Refresh token OAuth2 de Google (Calendar, Gmail y Drive) |
WHISPER_MODEL_SIZE |
No | Tamaño del modelo Whisper (small por defecto) |
GUARDRAILS_ENABLED |
No | Activar guardrails de seguridad (true) |
LLM_MODEL |
No | Nombre del modelo (por defecto: gpt-4o-mini) |
Consulta .env.example para la lista completa.
START → Guardrail entrada → [bloqueado → rechazo | OK → cargar memoria → manager]
intent → {RAG | web_search (Tavily) | google_action → google_planner_node | LLM directo}
HITL uno a uno:
google_planner_nodeplanifica las acciones y aplica correcciones deterministas (búsqueda previa a borrado, fix de ordenación, etc.)- Acciones de lectura — auto-ejecutadas sin modal.
- Acciones destructivas — el agente procesa una acción por turno. Si hay varias, el modal se muestra acción a acción. Si el usuario rechaza una, el flujo continúa con la siguiente.
- La reanudación se hace vía
POST /api/v1/chat/{thread_id}/resume.
→ generar respuesta → Guardrail salida → guardar memoria → END
El nodo web_search_node usa un selector LLM (WEB_TOOL_SELECTOR_PROMPT) para elegir
automáticamente la herramienta Tavily más adecuada según el tipo de consulta:
| Herramienta | Cuándo se usa |
|---|---|
tavily_search |
Búsqueda general (noticias, hechos, precios, eventos actuales) |
tavily_research |
Análisis exhaustivo de temas complejos con múltiples fuentes |
tavily_extract |
Leer el contenido completo de una URL concreta |
tavily_crawl |
Rastrear un sitio web completo desde su URL raíz |
tavily_map |
Mapear la estructura (listado de URLs) de un sitio web |
| Servicio | Transporte | Paquete / Servidor | Autenticación |
|---|---|---|---|
| Calendar | stdio | @cocal/google-calendar-mcp (npx) |
GOOGLE_OAUTH_CREDENTIALS + .calendar-token.json |
| Gmail | stdio | gmail_mcp_server.py (Python nativo) |
GMAIL_TOKEN_PATH + GOOGLE_REFRESH_TOKEN |
| Drive | stdio | @piotr-agier/google-drive-mcp (npx) |
GOOGLE_DRIVE_OAUTH_CREDENTIALS + .drive-token.json |
Los ficheros de token en data/google/ se generan automáticamente al arrancar AETHERIS a partir de GOOGLE_REFRESH_TOKEN. Solo es necesario ejecutar npx ... auth una vez para obtener el refresh token inicial (Calendar y Drive). Gmail usa el mismo refresh token directamente desde google-auth.
AETHERIS implementa un sistema de fallback automático:
- OpenAI (primario) —
gpt-4o-minipor defecto - AWS Bedrock (fallback) — Anthropic Claude vía
ChatBedrockConverse
Si OpenAI devuelve un error (timeout, cuota, fallo de API), el sistema redirige automáticamente la solicitud a Bedrock sin intervención del usuario. El proveedor utilizado se registra en LangSmith para trazabilidad.
| Capa | Almacén | Alcance | Tecnología |
|---|---|---|---|
| Corto plazo (sesión) | SQLite checkpoints | Por thread_id |
LangGraph AsyncSqliteSaver |
| Corto plazo (conversacional) | mem0.ai | Por user_id + session_id |
mem0 cloud o local |
| Largo plazo (preferencias) | SQLite user_memory |
Por user_id entre sesiones |
Tabla clave-valor |
| Largo plazo (hechos semánticos) | Chroma | Por user_id, búsqueda semántica |
Colección aetheris_long_term_facts |
PII: Los mensajes originales (con datos reales) se persisten siempre en el checkpoint de LangGraph. La versión PII-redactada (
sanitized_user_input) se usa exclusivamente para las llamadas al LLM y nunca se almacena en el historial.
# Todos los tests
pytest
# Solo tests unitarios (rápidos, sin E/S externa)
pytest tests/unit -v
# Tests de integración (Chroma/SQLite reales en /tmp)
pytest tests/integration -v
# Tests E2E (pila completa, APIs simuladas)
pytest tests/e2e -v
# Con cobertura
pytest --cov=aetheris --cov-report=term-missingConsulta docs/test_documentation.md para la documentación completa de tests.
aetheris/
├── agent/ # StateGraph LangGraph, nodos, aristas, prompts
├── guardrails/ # Filtrado de seguridad entrada/salida (EN+ES)
├── rag/ # Ingesta, recuperación, cadena RAG
├── mcp_tools/ # Cliente MCP (Tavily + Calendar/Gmail/Drive) + auth Google OAuth2
├── memory/ # mem0 (corto plazo) + SQLite/Chroma (largo plazo)
├── observability/ # Helpers de trazado LangSmith
├── api/ # Backend FastAPI (routers, schemas, middleware)
├── ui/ # Frontend Streamlit (páginas, componentes)
└── llm.py # Factoría LLM con fallback OpenAI → Bedrock
| Método | Endpoint | Descripción |
|---|---|---|
| POST | /api/v1/chat |
Iniciar/continuar chat (stream SSE) |
| POST | /api/v1/chat/{id}/resume |
Reanudar tras aprobación HITL |
| GET | /api/v1/chat/{id}/history |
Obtener historial de conversación |
| DELETE | /api/v1/chat/{id} |
Eliminar conversación e historial |
| GET | /api/v1/chat/threads/{user_id} |
Listar conversaciones del usuario |
| POST | /api/v1/documents/upload |
Subir + ingestar documento |
| GET | /api/v1/documents |
Listar documentos indexados |
| DELETE | /api/v1/documents/{id} |
Eliminar documento |
| GET | /api/v1/memory/{user_id} |
Obtener memoria del usuario |
| PUT | /api/v1/memory/{user_id} |
Actualizar memoria del usuario |
| POST | /api/v1/speech/transcribe |
Transcribir audio (faster-whisper) |
| GET | /api/v1/health |
Estado del sistema |
| GET | /api/v1/health/langsmith |
Conectividad con LangSmith |
| GET | /api/v1/health/google |
Estado de credenciales y tools Google MCP |
Documentación interactiva disponible en http://localhost:8000/docs.
Proyecto académico — Máster en Soluciones de Inteligencia Artificial Generativa (EBIS Business Techschool).