PC Agent es una plataforma multiagente operada desde Discord para investigar, crear, publicar, recordar y aprobar acciones sensibles con compuertas humanas. Combina un runtime de agentes con LangGraph, una API de control, memoria vectorial, memoria operativa, UI administrativa, observabilidad y workers de ingesta.
El objetivo del proyecto es simple: convertir Discord en una consola de operaciones para subagentes especializados sin perder trazabilidad, configuracion ni control humano sobre decisiones de alto impacto.
- Capacidades
- Arquitectura
- Servicios
- Inicio Rapido
- Configuracion
- Comandos De Discord
- Memoria E Ingesta
- Seguridad Y Aprobaciones
- Observabilidad
- Validacion
- Roadmap
- Bot de Discord con comandos, hilos por subagente, embeds, botones y flujos de aprobacion.
- Runtime de IA en FastAPI con acciones
chat,research,trade_decision,marketing,writer,picture,coder-webyemail. - Grafo de marketing con LangGraph: contexto, vision, deteccion de intencion, critica, refinamiento de voz y aprobacion humana.
- Subagente Writer con contrato estructurado, validacion de prompts, salida a Obsidian para blogs/storytelling y errores seguros de persistencia.
- Subagente Picture con memoria visual y soporte de imagenes adjuntas.
- Subagente Coder Web para crear o ajustar e-commerce y experiencias React/TS.
- Subagente Email para proveedores Google, Outlook, IMAP/SMTP, clientes locales y respuestas bulk aprobadas.
- Control API para estado del sistema, configuracion runtime, fuentes de conocimiento, ingestas y memoria diaria.
- Ingestion worker con scheduler, embeddings locales via Ollama y persistencia en Supabase/pgvector.
- Memoria proactiva por contexto: general, marketing, picture, coder-web y email.
- Observabilidad opcional con Langfuse.
- Stack local completo con Docker Compose.
PC Agent sigue un estilo Clean/Hexagonal: los casos de uso hablan con puertos de dominio y las integraciones externas viven como adaptadores. Esto permite cambiar LLMs, stores, APIs de marketing o conectores de trading sin reescribir los flujos.
flowchart TD
Discord["Discord Bot"] --> Runtime["Assistant Runtime<br/>FastAPI + LangGraph"]
UI["Admin UI<br/>React + Nginx"] --> Control["Control API<br/>FastAPI"]
Discord --> Control
Control --> Worker["Ingestion Worker<br/>Scheduler + API"]
Control --> Supabase["Supabase / pgvector"]
Runtime --> LLM["Gemini / OpenAI / Ollama<br/>via Open Claw + LiteLLM"]
Runtime --> Mentis["MentisDB<br/>operational memory"]
Runtime --> Zernio["Zernio Adapter<br/>marketing data"]
Runtime --> Pilot["Pilot Web Adapter<br/>coder-web"]
Runtime --> Kalshi["Kalshi Adapter<br/>trading research"]
Runtime --> Obsidian["Obsidian Vault<br/>writer output"]
Worker --> Ollama["Ollama<br/>mxbai-embed-large"]
Worker --> Supabase
Worker --> Mentis
Runtime -. traces .-> Langfuse["Langfuse Stack"]
Control -. health/config .-> Langfuse
| Capa | Responsabilidad | Modulos principales |
|---|---|---|
| Entrada | Discord, UI admin y endpoints HTTP | services/discord-bot, ui, control-api/app/api |
| Aplicacion | Casos de uso, grafos y orquestacion | assistant-runtime/app/use_cases, control-api/app/application |
| Dominio | Modelos, puertos y politicas | assistant-runtime/app/domain, control-api/app/domain |
| Adaptadores | LLMs, memoria, Supabase, Zernio, Kalshi, Pilot Web | assistant-runtime/app/adapters, control-api/app/adapters |
| Datos | Vector store, runtime config, Obsidian, memoria diaria | Supabase, pgvector, Docker volumes |
| Observabilidad | Trazas, errores y costos de LLM | Langfuse, LiteLLM callbacks |
| Servicio | Puerto | Descripcion |
|---|---|---|
control-api |
8000 |
Plano de control: health checks, configuracion, fuentes, ingestas y memoria. |
assistant-runtime |
8100 |
Cerebro multiagente: trading, marketing, writer, picture, coder-web y email. |
discord-bot |
- |
Interfaz principal de operaciones, aprobaciones y conversaciones en hilos. |
ingestion-worker |
interno 8000 |
Scheduler y ejecuciones manuales de ingesta, tendencias y consolidacion. |
ui |
8080 |
Consola administrativa React servida por Nginx. |
supabase-vector-db |
54322 |
Postgres local con pgvector para desarrollo. |
ollama |
11434 |
Embeddings locales bajo perfil embeddings. |
mentisdb |
9471 |
Memoria operativa opcional. En compose actual usa traefik/whoami como placeholder local. |
obsidian |
3010, 3011 |
Vault visual para artefactos del Writer. |
langfuse-* |
3000, 9001 |
Observabilidad self-hosted bajo perfil observability. |
cp .env.example .envConfigura como minimo:
ADMIN_API_TOKEN=
DISCORD_BOT_TOKEN=
DISCORD_REQUESTS_CHANNEL_ID=
DISCORD_NOTIFICATIONS_CHANNEL_ID=
DISCORD_STATUS_CHANNEL_ID=
DISCORD_APPROVER_USER_IDS=
SUPABASE_URL=
SUPABASE_PUBLISHABLE_KEY=
SUPABASE_SERVICE_ROLE_KEY=
OPENAI_API_KEY= # o GEMINI_API_KEY
docker compose up --buildAbre:
http://localhost:8080
docker compose --profile embeddings up --build
docker compose exec ollama ollama pull mxbai-embed-largedocker compose --profile observability up --builddocker compose --profile embeddings --profile observability up --buildLa configuracion puede venir de .env o del store runtime compartido en
/config/runtime-config.json. El Control API expone una vista publica que oculta
secretos y solo indica si las claves existen.
| Grupo | Variables |
|---|---|
| Runtime | ENVIRONMENT, ADMIN_API_TOKEN, RUNTIME_CONFIG_PATH, CORS_ALLOW_ORIGINS |
| Discord | DISCORD_BOT_TOKEN, DISCORD_REQUESTS_CHANNEL_ID, DISCORD_NOTIFICATIONS_CHANNEL_ID, DISCORD_STATUS_CHANNEL_ID, DISCORD_APPROVER_USER_IDS |
| LLM | DEFAULT_LLM_PROVIDER, OPENAI_API_KEY, OPENAI_ADMIN_API_KEY, GEMINI_API_KEY, MINIMAX_API_KEY, TOGETHER_API_KEY |
| Imagenes | OPENAI_IMAGE_EDIT_MODEL, PICTURE_IMAGE_GENERATION_PROVIDER, PICTURE_IMAGE_EDIT_PROVIDER, TOGETHER_API_KEY, TOGETHER_IMAGE_MODEL, OLLAMA_IMAGE_BASE_URL, OLLAMA_IMAGE_MODEL |
| Supabase | SUPABASE_URL, SUPABASE_PUBLISHABLE_KEY, SUPABASE_SERVICE_ROLE_KEY, VECTOR_DATABASE_URL |
| Zernio | ZERNIO_API_KEY |
| Embeddings | EMBEDDING_PROVIDER, EMBEDDING_MODEL, EMBEDDING_DIMENSIONS, OLLAMA_BASE_URL |
| Memoria | MENTIS_BASE_URL, MENTIS_ENABLED, MENTIS_API_KEY |
| Observabilidad | LANGFUSE_HOST, LANGFUSE_ENABLED, LANGFUSE_PUBLIC_KEY, LANGFUSE_SECRET_KEY |
| Trading | KALSHI_ENV, KALSHI_API_KEY_ID, KALSHI_PRIVATE_KEY_PATH |
| Schedules | MARKET_INGESTION_CRON, TRENDS_INGESTION_CRON, MENTIS_SYNC_CRON |
| Endpoint | Servicio | Uso |
|---|---|---|
GET /health |
Control API | Health check del plano de control. |
GET /status |
Control API | Estado agregado de servicios. |
GET /config |
Control API | Configuracion publica efectiva. |
GET /config/runtime |
Control API | Vista segura de runtime config. |
PUT /config/runtime |
Control API | Actualizar config con x-admin-token. |
GET /knowledge-sources |
Control API | Listar fuentes de conocimiento. |
POST /knowledge-sources |
Control API | Registrar fuentes con x-admin-token. |
POST /ingestion/runs |
Control API | Disparar markets, trends, mentis, consolidation o all. |
GET /intelligence/memory/today |
Control API | Leer memoria reciente por contexto. |
POST /assistant/request |
Assistant Runtime | Ejecutar acciones multiagente. |
El bot escucha comandos en DISCORD_REQUESTS_CHANNEL_ID. Cuando crea un hilo de
subagente, los mensajes posteriores pueden continuar sin repetir el prefijo: el
bot infiere el agente desde el nombre del hilo.
| Comando | Uso |
|---|---|
!help |
Muestra la guia operativa del bot. |
!help marketer |
Muestra solo comandos de !marketer, incluyendo --source zernio y --account. |
!help email |
Muestra comandos y reglas de seguridad de !email. |
!status |
Estado de servicios desde Control API. |
!ask <duda> |
Pregunta rapida al asistente. |
!research <tema> |
Investigacion profunda. |
!claw <pregunta> |
Hilo de analisis profundo usando memoria diaria. |
!run <target> |
Ejecuta trabajos de ingesta: markets, trends, mentis, consolidation, all. |
!memory |
Reporte de memoria/inteligencia reciente. |
!memory --clean |
Solicita confirmacion para borrar memoria general del dia. |
!approve_trade <id o instruccion> |
Abre confirmacion de operacion con botones. |
!claw --model-status |
Muestra proveedor/modelo de chat e investigacion del asistente general. |
| Comando | Uso |
|---|---|
!marketer-status |
Estado del Marketer Agent. |
!marketer dashboard |
Dashboard visual de Zernio. |
!marketer report [tipo] |
Reporte general, diario, semanal, mensual, crecimiento o engagement. |
!marketer top-content |
Mejores contenidos. |
!marketer audience |
Insights de audiencia y segmentos. |
!marketer alerts |
Alertas de crecimiento. |
!marketer comments |
Comentarios recientes. |
!marketer negative-comments |
Comentarios negativos o de riesgo. |
!marketer --source zernio comments --account <id> |
Lee comentarios recientes directamente desde Zernio Comments API para una cuenta concreta. |
!marketer --source zernio negative-comments --account <id> |
Filtra comentarios de riesgo usando comentarios reales de Zernio. |
!marketer leads |
Leads detectados. |
!marketer whatsapp |
Contactos opt-in y campanas WhatsApp creadas para OpenWA. |
!marketer best-hours |
Mejores horarios para publicar. |
!marketer memory |
Memoria de marketing. |
!marketer memory --clean |
Confirmacion para borrar memoria de marketing. |
!marketer --model-status |
Muestra modelos conectados para estrategia, copys, visuales y edicion. |
| Comando | Uso |
|---|---|
!marketer |
Centro de control con botones rapidos. |
!marketer campaign <objetivo> |
Crea una campana asistida. |
!marketer approve-campaign [texto] |
Ejecuta una campana ya aprobada. |
!marketer posts <tema> |
Genera cola de posts. |
!marketer approve-posts [texto] |
Ejecuta posts aprobados. |
!marketer post <texto> --platform <instagram|tiktok> --account <id> --schedule "fecha" |
Publica o programa contenido. |
!marketer whatsapp send <campaign_id> |
Solicita aprobacion humana por botones para poner una campana WhatsApp en cola. |
!marketer whatsapp approve <campaign_id> / deny <campaign_id> |
Fallback textual para aprobar o denegar si Discord bloquea componentes. |
!marketer reply-drafts |
Prepara borradores de respuestas. |
!marketer respond |
Responde comentarios. |
!marketer qualify |
Cualifica leads calientes. |
!marketer magnet |
Procesa lead magnets via DM. |
!marketer --source zernio qualify --account <id> |
Cualifica leads desde comentarios reales de Zernio y conserva trazabilidad de comentario, post y cuenta. |
!marketer --source zernio magnet --account <id> |
Detecta triggers de lead magnet desde Zernio antes de preparar DMs para aprobacion. |
!marketer --source zernio sentiment --account <id> |
Analiza sentimiento usando comentarios actuales de Zernio. |
!marketer trends |
Busca tendencias virales. |
!marketer sentiment |
Analiza sentimiento y crisis. |
!marketer funnel <tema> |
Disena un embudo. |
!marketer research <tema> |
Investiga mercado o competidores. |
!marketer competitors [marca] |
Analisis competitivo. |
!marketer collab <tema> |
Encuentra colaboraciones. |
!marketer content-plan [rango] |
Calendario de contenido, por defecto 7 dias. |
!marketer repurpose |
Reutiliza contenido ganador. |
!marketer --free-model <peticion visual> |
Genera una imagen de prueba usando el proveedor gratuito configurado, por defecto Together. |
Las acciones sensibles de marketing pueden devolver requires_approval. En ese
caso el bot muestra botones para aprobar, denegar, guardar draft o personalizar el
texto antes de ejecutar.
--source zernio fuerza al Marketer a leer comentarios desde Zernio en lugar de
la memoria operativa local. Para entornos con varias cuentas conectadas, usa
--account <id> para evitar ambiguedad y mantener trazabilidad empresarial.
El runtime productivo instancia MarketingGraph con ZernioAdapter. El contrato
MarketingPort incluye cuentas conectadas, comentarios, dashboard, reportes,
drafts, publicaciones, leads, DMs, respuestas, idempotencia y auditoria de runs.
El workflow legacy no debe usarse como ruta demo en produccion.
| Comando | Uso |
|---|---|
!writer blog <es|en> <tema> |
Crea un blog y lo guarda en Obsidian. |
!writer story <es|en> <tema> |
Crea storytelling y lo guarda en Obsidian. |
!writer storytelling <es|en> <tema> |
Alias de story. |
!writer <mensaje> |
Chat directo con el redactor. |
!writer --model-status |
Muestra modelos conectados para redaccion y keywords visuales. |
Writer devuelve status, message, command, content, artifact y
metadata. Si Obsidian no esta disponible, devuelve writer.persistence_failed
en lugar de reportar exito parcial. Las imagenes no se insertan desde fuentes
externas no licenciadas; el agente sugiere keywords para buscar o generar assets
aprobados antes de publicar.
| Comando | Uso |
|---|---|
!picture <descripcion> |
Genera una imagen con memoria proactiva. |
!picture --free-model <descripcion> |
Genera una imagen de prueba usando el proveedor gratuito configurado. |
!picture <edicion> con imagen adjunta |
Edita una pieza existente, por ejemplo cambiar texto conservando composicion y estilo. |
!picture memory |
Muestra aprendizajes visuales. |
!picture memory --clean |
Solicita confirmacion para limpiar memoria visual. |
!picture --model-status |
Muestra modelos conectados para plan creativo, generacion y edicion. |
El comando acepta imagenes adjuntas como referencia o como pieza a editar. Para
pruebas sin consumir Gemini/OpenAI, --free-model usa Together con
TOGETHER_IMAGE_MODEL=black-forest-labs/FLUX.1-schnell-Free cuando
TOGETHER_API_KEY esta configurado. Ollama queda como fallback configurable para
imagenes, pero el servicio Docker de Ollama se mantiene versionado para proteger
los embeddings locales.
Ejemplos rapidos:
!marketer --free-model poster cuadrado para Instagram de cafe artesanal, texto "Sabor de Origen"
!picture --free-model portada editorial futurista para una marca de skincare
| Comando | Uso |
|---|---|
!coder-web <descripcion> |
Crea o ajusta una experiencia web/e-commerce. |
!coder-web memory |
Muestra aprendizajes del desarrollador web. |
!coder-web memory --clean |
Solicita confirmacion para borrar memoria coder-web. |
!coder-web --model-status |
Muestra modelos conectados para analisis UI/UX, plan tecnico y Pilot. |
El comando acepta mockups o referencias visuales adjuntas.
| Comando | Uso |
|---|---|
!email / !email status |
Estado del proveedor, lectura, envio y templates configurados. |
!email sent-today |
Lista emails enviados el mismo dia desde el proveedor configurado. |
!email categorize <categoria> |
Prepara categorizacion por filtros/categoria. |
!email --template-<nombre> <categoria> |
Prepara respuestas bulk usando un template del administrador y solicita aprobacion. |
!email process-queued |
Procesa jobs bulk aprobados en cola. |
!email --model-status |
Muestra modelos conectados para clasificacion, resumen y templates. |
El sub-agente !email usa arquitectura hexagonal: el nucleo solo conoce
casos de uso y puertos; Google, Outlook, IMAP/SMTP, cliente local de PC u otros
proveedores viven como adaptadores. Los envios bulk requieren configuracion en
Admin UI, permiso explicito de envio, limites por minuto, auditoria e
idempotencia. Por defecto se genera un job_id aprobable; despues de la
aprobacion humana queda en cola y !email process-queued ejecuta el envio real
con actualizacion por destinatario.
La pantalla Email Agent del administrador permite revisar estado y editar
proveedor, credenciales, permisos, categorias y templates desde la misma vista
operativa del sub-agente.
Los comandos --model-status no llaman a los proveedores externos ni consumen
cuota. Solo leen la configuracion efectiva del runtime para mostrar que modelo
usaria cada subagente y si falta alguna variable requerida.
Ejemplos:
!marketer --model-status
!picture --model-status
!claw --model-status
!writer --model-status
!coder-web --model-status
!email --model-status
Si ves un error 422 Unprocessable Entity al ejecutar uno de estos comandos,
normalmente significa que discord-bot ya cargo el comando nuevo pero
assistant-runtime sigue corriendo una version anterior que no reconoce
action_type=model_status. Recarga ambos servicios:
docker compose up -d --build assistant-runtime discord-botPara una recarga rapida si la imagen ya esta construida:
docker compose restart assistant-runtime discord-botEl conocimiento de largo plazo vive en Supabase con embeddings:
knowledge_sources: fuentes habilitadas para ingesta.knowledge_documents: chunks vectorizados concontent_hashpara evitar duplicados.mentis_memory: memoria consolidada por contexto.marketing_leads: leads detectados por los flujos de marketing.
Funcion de busqueda:
public.match_knowledge_documents(query_embedding, match_count, filter)Migraciones principales:
supabase/migrations/20260508000100_vector_knowledge.sql
supabase/migrations/20260508000200_ollama_mxbai_embeddings.sql
supabase/migrations/20260508000300_knowledge_document_hash.sql
supabase/migrations/20260511000100_system_config.sql
supabase/migrations/20260512000400_marketing_leads.sql
Aplicar migraciones contra Supabase linked:
npm_config_cache=/private/tmp/pc-agent-npm-cache npx --yes supabase@latest db push --linked --workdir . --yesEl worker puede correr por cron o bajo demanda:
markets: lee fuentes habilitadas, extrae texto, chunking, embeddings y upsert.trends: recoleccion de tendencias.mentis: sincronizacion MentisDB pendiente.consolidation: consolidacion diaria de memoria.all: ingesta de fuentes y tendencias.
Configuracion de embeddings por defecto:
EMBEDDING_PROVIDER=ollama
EMBEDDING_MODEL=mxbai-embed-large
EMBEDDING_DIMENSIONS=1024
OLLAMA_BASE_URL=http://ollama:11434
Las acciones de trading (trade_decision y open_position) estan bloqueadas si
no cumplen todas estas condiciones:
source.platformdebe serdiscord.source.channel_iddebe coincidir conDISCORD_REQUESTS_CHANNEL_ID, si esta configurado.approval.statusdebe serapproved.approval.channel_iddebe coincidir con el canal autorizado.approval.approver_user_iddebe existir enDISCORD_APPROVER_USER_IDS, si la lista esta configurada.
El bot implementa esta experiencia con un embed de confirmacion y botones de continuar/cancelar. El runtime vuelve a validar la compuerta, por lo que la UI o un cliente HTTP no pueden saltarse la politica.
Langfuse es opcional y se activa con:
LANGFUSE_ENABLED=true
LANGFUSE_HOST=http://langfuse-web:3000
LANGFUSE_PUBLIC_KEY=
LANGFUSE_SECRET_KEY=
Cuando las claves existen, el adapter Open Claw registra callbacks de LiteLLM para trazas exitosas y fallidas. El worker tambien marca ejecuciones observables en jobs de ingesta.
.
+-- services/
| +-- assistant-runtime/ # Runtime multiagente, grafos y adaptadores
| +-- control-api/ # API de configuracion, estado, ingesta y memoria
| +-- discord-bot/ # Bot operacional de Discord
| +-- ingestion-worker/ # Scheduler, embeddings, tendencias y consolidacion
+-- ui/ # Admin dashboard React/Vite
+-- docs/ # Documentacion tecnica y propuestas por subagente
+-- supabase/migrations/ # Schema Supabase remoto
+-- infra/postgres/ # Init SQL para pgvector local
+-- tests/ # Pruebas de casos de uso e integracion ligera
+-- docker-compose.yml # Orquestacion local
Pruebas y checks utiles:
python3 tests/test_use_cases.py
python3 tests/test_assistant_runtime_gate.py
python3 tests/test_ingestion_worker.py
python3 tests/test_marketing_v04.py
docker compose --profile observability --profile embeddings configTambien hay pruebas especificas por servicio, por ejemplo:
services/assistant-runtime/venv/bin/python -m unittest services/assistant-runtime/test_marketing_graph_regression.py
services/assistant-runtime/venv/bin/python -m unittest services/assistant-runtime/test_marketing_automation.py
services/assistant-runtime/venv/bin/python -m unittest services/assistant-runtime/test_writer_workflow.py
services/assistant-runtime/venv/bin/python tests/test_assistant_runtime_dispatch.py
python3 services/discord-bot/test_marketer_approval.py- Arquitectura del sistema
- MarketingGraph en produccion
- Observabilidad
- Marketer memory
- Marketer lead qualification
- Marketer trend discovery
- Marketer WhatsApp OpenWA
- Picture subagent
- Writer subagent
- Coder web subagent
- Email subagent
- Docker commands
- Runtime multiagente con FastAPI.
- Marketing graph con LangGraph y aprobacion humana.
- Tool calling compatible con Gemini/OpenAI via adaptador.
- Memoria proactiva por contexto.
- UI administrativa para configuracion y estado.
- Worker de ingesta con pgvector y Ollama.
- Adapter MentisDB/Supabase Memory para read/write estable, healthcheck real y RLS service-role.
- Historial visual de consolidaciones en UI con contrato normalizado.
- Base Kalshi con limites de riesgo, auditoria durable y fail-closed para ordenes bloqueadas.
- Base WhatsApp/OpenWA para contactos opt-in, campanas draft, UI y acceso desde
!marketer whatsapp. - Writer endurecido con contrato estructurado, validacion, auditoria ligera y errores de persistencia.
- Marketer con contrato
MarketingPortalineado a Zernio y ruta productiva sin fallback demo en runtime. - Envio WhatsApp/OpenWA con aprobacion humana, rate limits, opt-out y webhooks de entrega.
- Adapter Kalshi live con autenticacion RSA-PSS, submit real de ordenes e idempotencia end-to-end.
- Reconciliacion Kalshi de ordenes, fills, cancelaciones y drift de posicion.
- Dashboard operativo de auditoria trading, rechazos de riesgo y exposicion diaria.
- Tests de contrato Supabase/PostgREST para Mentis Memory y trading audit.
- Observabilidad productiva: metricas, trazas y alertas para Mentis, consolidaciones y Kalshi.
- Politicas multi-tenant para memoria, trading y runtime config.
- Rotacion y validacion de secretos para Supabase, Kalshi, Discord y proveedores LLM.
- Backups, retencion y redaccion selectiva de memoria sensible.
- Runbooks de incidentes para trading live, perdida de auditoria y fallos de consolidacion.
- E2E UI/API para flujos criticos: consolidaciones, memoria, config y trading preview.
- CI completa por servicio.
PC Agent esta en desarrollo activo. La arquitectura ya separa dominio, aplicacion y adaptadores; algunas integraciones externas siguen siendo placeholders o dependen de claves privadas. Para operar en produccion, revisa aprobadores, secretos, permisos del bot, limites de LLM y persistencia de Supabase antes de activar flujos con impacto real.
