PTENES
Asistente personal · Telegram · local

Un bot que trabaja sin exceder la memoria de la máquina

Cola durable en SQLite, gestor de Ollama con preflight de RAM, costo por llamada con presupuesto y un cerebro que recuerda en PT-BR. Funciona junto a v2 hasta alcanzar la paridad.

Ilustración de openpcbot v3: asistente personal ejecutándose localmente
Qué es

Sucesor de openpcbot v2, diseñado a partir de problemas reales

v2 funciona, pero es un monolito sin cola, sin costo por llamada y sin gestión de Ollama, con dos bloqueos por falta de RAM en agosto. v3 toma lo que ya estaba listo y probado en otros repos locales y lo organiza por capas.

🧱 Cola real

Claim atómico, lease con heartbeat, backoff, idempotencia y drain gradual, portados de inemaccbot con las 107 pruebas originales. Lanes por tipo de trabajo, un claude -p a la vez.

🧠 Cerebro en PT-BR

Memorias con salience y decaimiento, búsqueda por FTS5 más vector bge-m3, consolidación nocturna que detecta contradicciones y un vault curado que solo guarda con tu aprobación.

💸 Costo y RAM bajo control

Todas las llamadas de LLM pasan por un único gateway: tier local → barato → premium, presupuesto mensual con bloqueo y preflight que rechaza cargar un modelo grande si no hay 40 GB libres.

Cómo funciona

El recorrido de un mensaje

Los canales solo traducen a un bus de eventos. El orquestador clasifica con un modelo local pequeño antes de gastar cualquier token en la nube.

Telegram / CLI / HTTP→ Bus→ Enrutador (llama3.2)→ Memoria (3 capas)→ Respuesta directa (qwen3.8) o job de agente (claude -p)→ Protección de secretos→ Chat
1

Enrutador

Devuelve JSON con ruta, agente y tier. "directo" para conversar; "agente" cuando necesita archivo, shell, repo, web o skill.

2

Gateway de LLM

Presupuesto → proveedor → preflight de RAM → llamada → costo en chamadas_llm. Ollama cuesta cero, pero cuenta tokens y tiempo.

3

Cola

El job de agente se ejecuta claude -p --output-format json en la lane agente. El resultado y el costo real vuelven al chat de origen.

4

Aprendizaje

Cada turno se convierte en memoria. Un hecho duradero genera una propuesta para MEMORY.md / USER.md; lo apruebas con un comando.

Requisitos previos

Lo que debe estar en producción

Todo local. Las API keys compartidas se leen en runtime desde .env del v2; el v3 solo necesita su propio token de bot.

Ollama como servicio

Solo HTTP en 11434. Nunca un ollama serve en paralelo.

# modelos usados (las mismas tags de v2)
ollama pull qwen3.8:27b
ollama pull llama3.2
ollama pull bge-m3

Node 20+ y Claude Code

El agente se ejecuta mediante un subproceso de la CLI, no con el SDK.

node -v          # v20+
claude --version # CLI en el PATH del usuario

Bot propio en Telegram

Créalo en BotFather. El token de v2 se rechaza al iniciar (dos getUpdates = 409 y bot sordo).

# ~/projetos/openpcbotv3/.env
TELEGRAM_BOT_TOKEN_V3=123456:AAH...
PORT_V3=3142
PISO_RAM_GB=40
Guía de uso · paso a paso

Del clone al bot respondiendo

Cinco comandos. Sin token de Telegram, el servicio igual se inicia, con HTTP y CLI.

1

Instalar y configurar

Copia el ejemplo de .env y completa solo lo que corresponde al v3.

git clone git@github.com:inematds/openpcbotv3.git && cd openpcbotv3
npm install
cp .env.exemplo .env   # TELEGRAM_BOT_TOKEN_V3, PORT_V3, PISO_RAM_GB, ORCAMENTO_MENSAL_USD
2

Ejecutar el doctor

Verifica env, Ollama y modelos, RAM, CLIs, v2 activo, unit y límite de memoria. No cambia nada.

npm run doctor
✅ mismo modelo general que el v2   v2=qwen3.8:27b v3=qwen3.8:27b
✅ RAM                          63.8 GB disponibles · mínimo para cargar un modelo grande: 40 GB
⚠️  TELEGRAM_BOT_TOKEN_V3        ausente — canal de Telegram desactivado
3

Importar las memorias de v2

Snapshot con VACUUM INTO: la base de datos de v2 nunca se abre para escritura. Idempotente.

npx tsx src/cli/importar.ts
memorias del v2: leídas 308 · insertadas 291 · ya existían 17
4

Instalar el servicio

Unit de usuario con Restart=on-failure, MemoryHigh=1.5G e MemoryMax=2G. El mismo script sirve para reiniciar después de cambiarlo src/ o .env.

bash scripts/instalar-servico.sh
# build + daemon-reload + enable + restart; sin sudo
journalctl --user -u openpcbotv3 -f -o cat
5

Conversar

En Telegram, o por HTTP y CLI mientras no haya token.

npm run cli -- "/health"
npm run cli -- "lembra que eu prefiro respostas curtas"
npm run cli -- "no projeto X, conta as linhas de src/app.ts"   # se convierte en job de agente
6

Operar por el chat

Cola, costo, memoria, tareas y cron sin salir de Telegram. El dashboard está en http://127.0.0.1:3142/.

/status [id]        # cola por lane o detalle de un job
/usage              # costo hoy/semana/mes, por tier y agente, presupuesto
/health             # Ollama, RAM, RSS, cola, heartbeat, canales
/memoria lista|buscar|salvar|propostas|aprovar <id>
/tarefa add amanhã 9h revisar PR   # recordatorio + resumen en /daily
/cron lista · /ollama status · /consolidar · /novo
Ejemplos

Lo que pasó en las primeras pruebas en producción

Interacciones reales del día en que se inició v3, con v2 activo en la misma máquina.

Memoria entre turnos

tú> qual a capital do RS? e lembra que eu prefiro respostas curtas
bot>  Porto Alegre.
bot>  📝 Guardar no vault? "…prefiro respostas curtas" → /memoria aprovar 1
tú> o que eu te disse que prefiro?
bot>  Respostas curtas.

Job de agente con costo real

tú> no projeto openpcbotv3, conta as linhas de src/fila/worker.ts
bot>  🧠 lead — job #7. /status 7 acompanha.
bot>  419
# llamadas_llm: claude-cli · sonnet · premium · US$ 0,1465 · 7,8 s
# pico de memoria de la unidad: 636 MB (límite 2 G)

Preflight de RAM que rechaza

/ollama preflight qwen3.6:35b-a3b
⛔ ya hay un modelo grande residente (qwen3.8:27b) — política de 1 residente

/ollama descarregar qwen3.8:27b
⛔ este proceso no lo cargó (puede ser del v2) — rechazado

Health que consume el hub

GET /health
{ "ok": true, "rss_mb": 82, "canais": ["telegram","http"],
  "ram": { "disponivelGb": 35.3, "swapUsadoGb": 8.5 },
  "ollama": { "online": true, "carregados": ["qwen3.8:27b"] },
  "orcamento": { "pct": 0, "limite_usd": 50, "travado": false } }
Roadmap

Estrangulamiento, no corte abrupto

v3 se inicia con su propio bot junto a v2. No se elimina nada hasta alcanzar la paridad: todos los comandos de v2 responden en v3, 7 días sin jobs perdidos, costo semanal medido.

0–2 ✓
Esqueleto, cola, Ollama, costo, telemetríaBus, config YAML, unit con límite de memoria; cola portada; gestor de Ollama con preflight; gateway de LLM con presupuesto; /status, /usage, /health, alertas.
3–5 ✓
Canales, orquestador, cerebro, tareasTelegram/CLI/HTTP; enrutador local; agente por CLI con sesión y costo real; memoria PT-BR importada de v2, embeddings, consolidación nocturna, vault curado; cron como jobs, heartbeat, /tarefa, /daily.
6–7 ✓
Slack, WhatsApp, dashboard, doctor, backupSlack mediante Web API (desactivado hasta el corte); WhatsApp con una protección que lo rechaza mientras v2 sea dueño de la sesión; dashboard en una página; doctor; backup nocturno cifrado.
8
CorteCambiar el token de producción, dejar v2 en solo lectura durante 30 días y archivarlo. Solo por orden explícita. Después: WhatsApp real en un daemon separado, Slack activado, retención de la tabla de jobs.