Transcribe tus reuniones en vivo en la GPU y te sugiere qué responder — todo local, en una ventanita flotante que vive encima de cualquier app.
Demo · Cómo funciona · Motores ASR · Inicio rápido · Configuración · Privacidad
🎬 Video demo en camino
En el demo se ve: transcripción bilingüe en vivo, el panel 🧠 con resumen/ideas/alerta del copiloto, la detección de "¿me preguntan a mí?" con respuesta sugerida al instante, y el panel lateral de respuestas a pedido.
Es un copiloto de reuniones que corre 100% en tu máquina. Captura el audio del sistema (lo que suena en una llamada de Meet, Zoom, WhatsApp, etc.), lo transcribe en vivo en la GPU, y usa Claude (vía tu suscripción, sin API key) para:
- 🧠 Entender el hilo — cada pocos segundos arma un resumen + ideas para aportar + una alerta si te asignan una tarea.
- 🙋 Responder por ti — detecta cuándo te hacen una pregunta a ti (por tu nombre o en segunda persona) y te prepara una respuesta con el contexto de la reunión.
- 💬 Responder a pedido — botones para pedir ideas, resumen, qué preguntar o cómo responder, o una caja para preguntarle lo que sea sobre la reunión.
Todo en una ventana flotante, sin marco y siempre encima, que arrastras donde quieras.
Pensado para Fedora + Wayland + NVIDIA. El audio nunca sale de tu equipo: solo el texto de la transcripción viaja a Claude.
Una sola ventana flotante reúne todo. Así se reparte:
┌──────────────────────────────────────────────────────────────────┐
│ capturando ⏸ pausar · tema · limpiar · – · ⤢ · ✕ │ barra superior
├──────────────────────────────────────┬───────────────────────────┤
│ PANEL DEL COPILOTO 🧠 │ PESTAÑAS 💡 📝 ❓ 🙋 💬 📋 │ panel lateral
│ resumen · ideas · alerta │ │ (respuestas
│ │ Respuestas a pedido │ a pedido)
│ TRANSCRIPCIÓN EN VIVO │ con historial + hora │
│ (negrita = frase confirmada) │ │
│ ...parcial en cursiva mientras hablas│ 🔄 actualizar · 💾 ctx │
│ ┌──────────────────────────────────┐ │ 🧹 limpiar · copiar · ✕ │
│ │ 💡 Respuesta sugerida │ │ │
│ └──────────────────────────────────┘ │ │
├──────────────────────────────────────┴───────────────────────────┤
│ [ 💡 Ideas ] [ 📝 Resumen ] [ ❓ ¿Qué pregunto? ] [ 🙋 Responder ] │ acciones rápidas
├──────────────────────────────────────────────────────────────────┤
│ [ Pregúntale a Claude sobre la reunión… ] [ Preguntar ]│ caja de preguntas
└──────────────────────────────────────────────────────────────────┘
- Barra superior — el estado (capturando · pensando · pausado · error) y los controles: ⏸ pausar la captura (descarta el audio sin cerrar nada), tema (cicla oscuro · claro · vidrio · vidrio legible), limpiar la transcripción, – minimizar, ⤢ expandir, ✕ cerrar (mata el proceso).
- Panel del copiloto 🧠 — cada
interval_ssegundos: una línea de resumen de lo que se habla, ideas para aportar, y una alerta si te asignan una tarea o se toma una decisión. - Transcripción en vivo — las frases confirmadas (con auto-scroll); el parcial va en cursiva mientras alguien habla.
- 💡 Respuesta sugerida — aparece sola cuando detecta que te preguntan a ti (por tu nombre o en segunda persona).
- Panel lateral de respuestas a pedido — pestañas 💡 Ideas · 📝 Resumen · ❓ Preguntas · 🙋 Responder · 💬 Pregunta libre · 📋 Contexto (esta última es editable: escribes el briefing de la sesión). Las respuestas se acumulan con su hora (historial, no se pisan). Acciones: 🔄 actualizar, 💾 guardar contexto, 🧹 limpiar, copiar, ✕ cerrar el panel.
- Acciones rápidas — un toque pide ideas / resumen / qué preguntar / cómo responder al instante.
- Caja de preguntas — escríbele lo que sea; Claude responde con el contexto de la reunión.
Verdad técnica: en Linux/Wayland no existe una forma fiable de excluir una ventana de la captura de pantalla — el compositor ya la pintó en el frame que se comparte, y ningún protocolo (xdg-desktop-portal, wlr-screencopy) ofrece un "no me captures" por ventana. Ni Cluely ni sus clones lo resuelven en Wayland (dependen de APIs de Windows/macOS). Pero sí puedes mantenerla fuera de vista de tres formas reales:
- 🪟 Comparte una ventana, no la pantalla. En Meet/Zoom/Teams elige compartir una ventana o pestaña concreta; el overlay es otra ventana y no aparece en lo que ven los demás.
- 📱 Segunda pantalla / celular. Corre con
--no-windowy abre la URL en el celular o un monitor que no compartas — la UI completa vive ahí. - 👻 Modo fantasma (click-through). El botón 👻 vuelve la ventana atravesable y semitransparente: la sigues viendo, pero los clics pasan a lo que tengas detrás y no estorba. Registra el atajo ANTES de usarlo (en ese modo no puedes clicar la ventana):
Salidas del modo fantasma: el atajo Super+G, tu atajo de mostrar/ocultar, o el
bash scripts/set_hotkey.sh "<Super>g" ghost # alterna el modo fantasma
curlque se imprime en la terminal al entrar (por si no tienes atajos).
El stealth real (invisible incluso en la grabación) llegará con el port a Windows vía
SetWindowDisplayAffinity(WDA_EXCLUDEFROMCAPTURE), que el SO sí soporta de forma nativa.
Pipeline de 5 piezas desacopladas; run.py es el ensamblador que las cablea:
PipeWire (monitor del sink)
│ PCM s16 mono 16k
▼
Transcriptor ASR (GPU) ──parciales/finales──► Orquestador (FastAPI + WebSocket)
Nemotron / Parakeet / Whisper │ ▲
▼ │ eventos JSON
Cerebro Claude (claude -p caliente)
│
▼
UI flotante (PySide6 nativa / web)
- Captura ·
pw-recordentrega chunks PCM del monitor del sink. - Transcripción · streaming cache-aware en la GPU (mismo interfaz para los 3 motores).
- Orquestador · sirve la UI, expone
/ws(token), difunde eventos y mantiene el contexto de sesión en 3 capas (briefing durable + resumen acumulativo + ventana rodante). - Cerebro · un proceso
claude -ppersistente y precalentado (TTFT ~2-3 s). - UI · widget nativo PySide6 (estable en Wayland vía XWayland), con temas, panel lateral y caja de preguntas.
Tres motores ASR, cada uno en su propio venv (sus dependencias de torch/NeMo chocan). Se elige con engine en config.toml o con --engine:
| Motor | Modelo | VRAM | Latencia | Idiomas | Estado |
|---|---|---|---|---|---|
nemotron ⭐ |
Nemotron 3.5 ASR streaming 0.6B | ~2.7 GB | Baja (streaming cache-aware nativo) | es/en + 17 (detección por frase) | Recomendado |
parakeet |
Parakeet TDT 0.6B v3 | ~1.3 GB | Media | es/en + 23 | Respaldo liviano |
whisper |
faster-whisper turbo |
~2.9 GB | Media | es/en | Alternativa |
¿Por qué Nemotron? Es un RNN-T FastConformer cache-aware: hace streaming de verdad (no re-transcribe el buffer), con baja latencia y muy buen español (WER 4.11% en FLEURS). Detecta español ↔ inglés automáticamente por frase — ideal para reuniones donde se mezclan idiomas y términos técnicos.
Nemotron y Parakeet necesitan GPU NVIDIA (streaming en tiempo real no es viable en CPU). Pero el motor
whispersí corre en CPU: enconfig.tomlpon[whisper] device = "cpu"(elcompute_typepasa aint8solo) y usarealtime_model = "tiny"o"base"para que vaya en tiempo real. Es más lento que en GPU, pero funciona sin tarjeta..venv/bin/python run.py --native --engine whisper
- 🌗 Bilingüe automático —
target_lang = "auto"detecta es/en sin que hagas nada. - 📋 Contexto que no se pierde — un briefing de sesión (escribes de qué va la reunión, o cargas un archivo/proyecto), un resumen acumulativo que mantiene el hilo entre temas, y la ventana de lo más reciente. El copiloto no pierde el foco aunque la llamada salte de tema.
- 📚 Glosario — corrige nombres propios y términos técnicos del proyecto (
Proxmox,Cloudflare,pfSense…) que el ASR oye raro. - 🧠 Cerebro intercambiable — Claude (
claude -p, suscripción) o un LLM local vía Ollama ([brain] backend), sin nube ni API key. Mide la latencia local conscripts/derisk_ollama.py. - 👻 Modo fantasma — vuelve la ventana atravesable (click-through) para que no estorbe; parte de la discreción.
- 🎨 Temas legibles — oscuro, claro y dos modos vidrio; la ventana se mantiene legible aunque esté semitransparente.
- ⏸️ Pausar captura · 🧹 limpiar · arrastrar · minimizar · expandir.
- 🔒 Atajos globales (GNOME) para mostrar/ocultar o entrar en modo fantasma al vuelo.
Requisitos: Fedora con PipeWire, GPU NVIDIA (o CPU con el motor
whisper, ver ¿No tienes GPU?), Python 3.12,uvy el CLIclaudeautenticado.
1) Motor recomendado — Nemotron (.venv-nemotron):
uv venv .venv-nemotron
uv pip install --python .venv-nemotron "nemo_toolkit[asr] @ git+https://github.com/NVIDIA/NeMo.git@main"
uv pip install --python .venv-nemotron "fastapi>=0.115" "uvicorn[standard]" websockets \
"pydantic>=2.7" pywebview PySide6 qtpy
uv pip install --python .venv-nemotron -e . --no-deps2) Configura:
cp config.example.toml config.toml # edítalo (token, idioma, glosario…)
.venv-nemotron/bin/python scripts/derisk_audio.py --list # encuentra el monitor del sink
# pon ese node-id en [audio] target de config.toml3) Corre:
.venv-nemotron/bin/python run.py --nativeLa primera vez descarga el modelo (~2.4 GB). Cambiar de motor es solo el comando:
.venv-parakeet/bin/python run.py --native --engine parakeet
.venv/bin/python run.py --native --engine whisperInstalar los motores de respaldo (Parakeet / Whisper)
# Whisper (.venv)
python3.12 -m venv .venv && source .venv/bin/activate && pip install -e ".[dev]"
# Parakeet (.venv-parakeet, NeMo 2.7.x)
uv venv .venv-parakeet --python 3.12
uv pip install --python .venv-parakeet "nemo_toolkit[asr]" fastapi "uvicorn[standard]" \
websockets "pydantic>=2.7" pywebview PySide6 qtpy setuptools
uv pip install --python .venv-parakeet -e . --no-depsTodo vive en config.toml (copia de config.example.toml, gitignorado). Las perillas principales:
| Sección | Clave | Qué hace |
|---|---|---|
| raíz | engine |
"nemotron" · "parakeet" · "whisper" |
[user] |
names, role |
tus nombres (para detectar preguntas) y tu rol (personaliza la IA) |
[nemotron] |
target_lang |
"auto" (es/en) o "es" para forzar español |
[nemotron] |
att_context_size |
[56,13]=1120 ms (más preciso) … [56,3]=320 ms (más rápido) |
[asr] |
glossary |
términos/nombres del proyecto para corregir la transcripción |
[context] |
briefing, briefing_file |
contexto durable: texto fijo o un archivo/carpeta que se resume al arrancar |
[copilot] |
interval_s |
cada cuántos segundos el copiloto analiza el contexto |
[audio] |
target |
node-id del monitor del sink (de derisk_audio.py --list) |
[parakeet] |
silence_rms |
umbral de voz; 0 = autocalibra el piso de ruido |
[server] |
token |
token de acceso a la UI (cámbialo) |
- El audio nunca sale de tu equipo. La captura y la transcripción ocurren localmente en tu GPU.
- A Claude solo viaja el texto de la transcripción reciente, para las sugerencias.
- La UI está protegida por token y escucha solo en
127.0.0.1. - Tu
config.toml(token, glosario, rutas) está gitignorado — nunca se sube.
La categoría existe — sobre todo el género de copilots en vivo estilo Cluely, que explotó en 2025 — pero casi todos comparten el mismo molde: Whisper + Ollama/BYOK, macOS/Windows, en inglés. Este proyecto se sale de ahí:
| Notetakers cloud (Otter, Fireflies, Fathom) |
Copilots en vivo (Cluely, Final Round AI) |
Open source (Natively, Pluely, Meetily) |
Este proyecto | |
|---|---|---|---|---|
| Procesamiento | ☁️ nube | ☁️ nube | 💻 local | 💻 local |
| Sugerencia en vivo | ❌ (post-reunión) | ✅ | ✅ | ✅ |
| ASR | propietario | propietario | Whisper | Nemotron streaming (NeMo) |
| LLM | propietario | propietario | Ollama / BYOK | Claude (suscripción) o Ollama local |
| Sistema operativo | web | macOS / Win | macOS / Win | Linux / Wayland |
| Idioma | EN+ | EN | EN | es/en bilingüe |
| Precio | 💲 suscripción | 💲 suscripción | gratis | gratis |
En resumen: como idea no es nueva (hay un topic entero cluely-alternative en GitHub). Lo distintivo aquí es el stack: ASR Nemotron streaming en la GPU (no Whisper), cerebro Claude por suscripción o LLM local (Ollama), y Linux/Wayland + español de primera — una combinación que no se ve en los demás.
Referencias · Open source: Natively · Pluely · Meetily. De pago: Otter.ai, Fireflies, Cluely, Final Round AI.
⚖️ Úsalo con consentimiento: grabar a terceros sin avisar es problemático (a Otter le cayó una demanda colectiva en 2025 por eso). El procesamiento local es para tu privacidad, no para grabar a otros a escondidas.
Algunas decisiones de diseño que costaron y quedaron documentadas:
claude -pen frío tarda 5-9 s → se usa caliente (proceso persistente + prewarm) y stripped; TTFT baja a ~2-3 s.- Nemotron es "con prompt" → hay que fijar el idioma con
set_inference_prompt(...)o decodifica vacío. - Streaming sin comerse palabras → usar
CacheAwareStreamingAudioBufferde NeMo (preprocesa una vez) en vez de re-preprocesar ventanas, y consumir solo chunks completos. - Sesiones largas → el RNN-T acumula la hipótesis sin límite; se reinicia por frase/longitud (manteniendo el cache acústico) para no ralentizarse.
- Wayland → la ventana nativa fuerza XWayland (
QT_QPA_PLATFORM=xcb) para que frameless/always-on-top/arrastre sean fiables.
- Cerebro intercambiable (Claude / Ollama local).
- Modo fantasma (click-through) para discreción en Linux.
- Port a Windows con stealth real (
WDA_EXCLUDEFROMCAPTURE) + captura WASAPI loopback. - Phrase boosting nativo de NeMo (sesgar el decoder con el glosario, no solo corrección por similitud).
- Modo fp16 para Nemotron (bajar VRAM a ~1.4 GB).
- Reciclaje del buffer de audio en maratones de varias horas.
Hecho con ☕ en 🇵🇦 · Procesamiento local · Tu audio es tuyo