Arquitectura verificada, implementación actual y límites en desarrollo.
Esta sección se actualizó contra la memoria del proyecto en Engram y la copia actual de la web. Separa comportamiento ya implementado, mensajes corregidos y trabajo futuro, porque una documentación para desarrolladores sirve solo si no promete de más.
Resumen de auditoría
Los puntos verdes ya estaban alineados con la memoria del proyecto. Los puntos ámbar se corrigieron en este pase. Los puntos azules son límites de desarrollo activo y no deben tratarse como garantías de release.
OpenCohost es el chasis de orquestación
Correcto: el valor del producto está en coordinar Ollama, TTS, contexto de LiveAudio, Agenda Mode, reacción al chat, perfiles, presencia de avatar/música y resiliencia; no es solo un wrapper.
La historia de voz no es solo Qwen-TTS
Actualizado: la implementación verificada incluye síntesis local con Piper, síntesis ligera opcional con Edge-TTS cuando la privacidad lo permite, y trabajo activo de voz personalizada/Qwen. La documentación ya no promete un stack garantizado solo con Qwen.
Local-first no significa cómputo gratis
Correcto: el modo local evita billing cloud/API por defecto, pero el desarrollador igual debe presupuestar GPU/VRAM, RAM, electricidad, elección de modelo, carga del juego y tiempo de setup.
LiveAudio sigue siendo un puente separado
Correcto: escucha de voz, Silero VAD, transcripción Whisper, subtítulos, transcripciones y contexto limpio pertenecen al puente LiveAudio, no a un micrófono siempre activo en OpenCohost.
Ruta de instalador real y documentada
El sitio ahora enlaza el instalador alpha para Windows generado por CI en GitHub Releases y lo etiqueta como alpha; el copy de "no hay instalador" se retiró cuando el flujo de release se volvió real.
Raíz de composición
app_shell.py cablea el hilo motor, health monitor, cliente OBS, SmartAggregator, Stream Admin, topic inbox bridge, controles de TTS y paneles de UI mediante protocolos tipados. Debe orquestar; la lógica va en módulos testeables.
Observer UIState
Contenedor de estado thread-safe y agnóstico al framework, con propiedades tipadas. Los observers despachan en un hilo daemon; los callbacks de UI deben volver al main loop de Tk antes de tocar widgets.
Cola de prioridad + acumulación
El hilo motor prioriza entradas en tiempo real como PTT, chat y agenda, mientras compacta overflow en consultas acotadas para no enterrar a los modelos locales bajo ruido crudo del stream.
Cambio de tiers LLM
Los slots manuales Quality / Balanced / Fast mapean a tags de modelos Ollama. El cambio preserva conversación/perfil y hace rollback al último modelo bueno conocido ante fallos.
Ruta de voz con privacidad explícita
La ruta de TTS soporta síntesis local con Piper, presets persistidos de velocidad y un switch tts_local_only que bloquea Edge-TTS antes de que el texto pueda salir de la máquina.
Entrada de temas con aprobación humana
El topic inbox permite que agentes propongan ideas, pero approve sigue siendo solo humano. Validación de namespace al leer, timeouts cortos de SQLite y rollback protegen la UI bajo carga.
Avatar state bridge
Un puente pub/sub permite que módulos core señalen estados del avatar sin acoplarse a UI ni OBS. OBSClient puede suscribirse y actualizar fuentes de imagen cuando cambia el estado.
Escalera de degradación
La recuperación de agenda y el cambio de modelo priorizan degradación segura: reintentos, descarte de prefetch obsoleto, estados de pausa explícitos y rollback en vez de deadlocks silenciosos en vivo.
Notas verificadas de implementación reciente
Switch TTS local-only
tts_local_only.json persiste la preferencia en config. Cuando está ON, el motor enruta la síntesis ligera a Piper y server_qwen.py devuelve HTTP 400 antes de cualquier llamada a Edge-TTS.
Presets de velocidad Piper
La UI expone Rápida, Media, Calma y Lenta con valores length_scale. El motor persiste cambios en tts_speed.json y reconstruye la configuración de síntesis Piper bajo lock.
Fix de doble cierre de agenda
El controlador ya no hace prefetch de un segundo kira-agenda-stop cuando un tema está CLOSING, y las acciones prefetched obsoletas se descartan en vez de reproducirse después.
Topic inbox
Los agentes pueden proponer candidatos con namespace ti_. El polling de UI es fail-open, la aprobación es solo humana y los fallos al encolar hacen rollback de filas aprobadas.
Gotchas para contribuidores
Nunca uses metadata externa como proxy del estado interno
Los widgets Tk son single-threaded
Reasoning token budget
Los storage paths se resuelven al importar
Los gates de privacidad van antes que los fallbacks cómodos
La configuración persistida puede contaminar tests
Validá namespaces de topics al leer, no solo al rutear
app_shell.py tiene presupuesto duro de líneas
Puntos de extensión
OpenCohost todavía no tiene un sistema formal de plugins, pero los desarrolladores pueden extender estas superficies de forma deliberada:
- Perfiles (perfiles.json): texto del system prompt y flag use_system. Los defaults viven en config/default_profiles.json.
- Slots de tiers LLM (llm_tiers.json): quality, balanced y fast validados contra modelos Ollama instalados al iniciar.
- Archivos de privacidad y velocidad TTS: tts_local_only.json y tts_speed.json persisten política de voz y choices de length_scale de Piper.
- YAMLs de configuración: storage.yaml, smart_aggregator.yaml, avatar.yaml y stream_admin.yaml configuran rutas, shaping de chat, OBS/avatar, OAuth y moderación.
- Catálogo de modelos (config/settings.py): MODELS_CATALOG necesita display, desc, size_gb y family antes de aparecer de forma segura en la UI.
- Sistema de protocolos (ui/protocols.py): MotorEventCallback, SmartAggregatorCallbacks y StreamAdminCallbacks definen contratos tipados de callback.
- Topic inbox (opencohost/core/topic_inbox.py + ui/topic_inbox_bridge.py): permite propuestas de agentes sin saltarse aprobación humana.
- Crash reporting (ui/crash_reporting.py): excepthook de Python, excepthook de threading, hook de callbacks Tk y faulthandler cubren distintas clases de falla.
Problemas difíciles de stream que ya tuvimos que resolver
Kira se fue formando con problemas reales de directo: chats ruidosos, voz con retraso, límites de hardware local, sesiones largas y la necesidad de ser útil sin quitarle el control al host.
Varias cargas de IA en una PC de streamer
Desafío
Correr un co-host local no es apretar un botón y magia. El stream puede necesitar LLM local, voz personalizada y escucha/transcripción mientras OBS, el juego y los overlays también están activos.
Ejemplo en vivo
Juego + OBS + voz de Kira + escucha de LiveAudio en la misma máquina.
Resultado
OpenCohost coordina las piezas y deja visible el tradeoff: calidad, velocidad, VRAM y carga del stream siguen bajo control del host.
Agenda Mode con contexto del directo
Desafío
Un co-host necesita ritmo. Si Kira solo lee un guion fijo, se siente muerta. Si reacciona a todo, se vuelve ruido. El desafío fue mantenerla enfocada sin apagar lo que pasa en el chat.
Ejemplo en vivo
Kira puede continuar un tema planeado, notar que el ambiente cambió y ajustar el ángulo sin robarle el control al streamer.
Resultado
Agenda Mode se pensó alrededor de un loop de eventos: el host marca dirección, Kira sostiene el flujo y el contexto del chat puede moldear la conversación sin tomar el mando.
Recuperación cuando el co-host se quedaba callado
Desafío
En versiones anteriores, ciertas combinaciones de co-host y chat en vivo podían dejar a Kira en silencio. Para un asistente de stream eso es grave: el momento muere, el host no recibe ayuda y la audiencia no ve nada.
Ejemplo en vivo
Un directo con chat activo y agenda corriendo no debería hacer que Kira se pause para siempre.
Resultado
Corregimos el flujo del producto para que co-host, reacción al chat y control del streamer convivan sin bloquearse.
Contexto de chat sin saturar el modelo
Desafío
Inyectar chat crudo a un LLM local es matar la experiencia. Un stream mezcla spam, bromas, mensajes repetidos, olas de reacción, frases cortas y picos repentinos de actividad.
Ejemplo en vivo
En vez de repetir el chat palabra por palabra, Kira entiende la presión del ambiente y responde como co-host.
Resultado
OpenCohost transforma el chat en contexto útil para que Kira reaccione al stream sin espejar la sala ni saturarse cuando el chat se pone caótico.
Push-to-talk para control real por voz
Desafío
Al conectar LiveAudio por WebSocket, Kira podía reaccionar a demasiado. Sin audífonos, incluso podía escucharse a sí misma por el micrófono y responder en bucle. Además, la transcripción de voz puede llegar con un pequeño retraso.
Ejemplo en vivo
Mantenés una tecla, hablás natural — incluso una idea larga — soltás y Kira recibe el contexto completo.
Resultado
PTT vuelve la escucha intencional: recoge voz mientras está activo, envía el contexto al soltar y acepta un pequeño margen de transcripción tardía para que la interacción se sienta más real.
Robustez bajo presión de directo
Desafío
Los directos no son demos limpias. Puede haber cortes, componentes ocupados, ventanas abiertas durante horas o entradas inesperadas. Una herramienta para streamers tiene que doblarse antes de romperse.
Ejemplo en vivo
Si una parte se retrasa o no está disponible, el show entero no debería caerse por eso.
Resultado
OpenCohost fue reforzado para degradar mejor ante problemas: Kira debería seguir siendo útil incluso cuando el entorno del stream se pone desordenado.
Memoria ordenada para sesiones largas
Desafío
Un stream puede durar horas. Si cada mensaje, broma, transcripción y respuesta vale lo mismo para siempre, el modelo local se ahoga y Kira pierde foco.
Ejemplo en vivo
Kira debería recordar la dirección útil del show, no arrastrar cada línea vieja del chat para siempre.
Resultado
OpenCohost mantiene continuidad con contexto compacto en vez de memoria infinita, ayudando a que Kira siga coherente en sesiones largas.
Presencia de Avatar y OBS
Desafío
Kira necesitaba sentirse presente en pantalla, no escondida en una caja de texto. La audiencia debería entender cuándo escucha, piensa o habla sin que el host lo explique todo el tiempo.
Ejemplo en vivo
Un viewer puede mirar el stream y entender rápido la presencia actual de Kira.
Resultado
Conectamos presencia visual con comportamiento amigable para OBS para que Kira se sienta parte del show, no una herramienta de fondo.
Una UI para streamers, no para técnicos
Desafío
La primera UI era demasiado densa. Mostraba demasiados controles juntos y se sentía más como una cabina técnica que como un producto de stream. Eso hace que la gente dude, aunque las funciones sean útiles.
Ejemplo en vivo
Un host debería encontrar voz, stream, co-host, música y avatar sin leer un manual antes.
Resultado
Remodelamos la interfaz con tabs más claras, secciones más tranquilas, explicaciones y una disposición más centrada en Kira para usuarios no técnicos.
Música que acompaña a Kira
Desafío
La música de fondo puede hacer que el stream se sienta vivo, pero también puede pelearse con el co-host. Si pisa a Kira, la audiencia tiene que esforzarse más para entender el momento.
Ejemplo en vivo
Kira habla, el stream sigue claro y la música acompaña el ambiente en vez de competir.
Resultado
OpenCohost ahora maneja mejor el flujo musical para que el show se sienta más suave cuando Kira entra en la conversación.
LiveAudio como puente de escucha separado
Desafío
La escucha por voz es suficientemente importante como para vivir en una pieza conectada propia. LiveAudio detecta cuándo alguien realmente habla, transcribe la voz localmente y pasa contexto limpio a OpenCohost.
Ejemplo en vivo
La voz puede convertirse en subtítulos, transcripciones y contexto útil sin hacer que OpenCohost escuche permanentemente por defecto.
Resultado
LiveAudio usa Silero VAD y OpenAI Whisper open-source como puente separado para contexto de voz, subtítulos y transcripciones.