Saltar al contenido
Kira LOCAL-FIRST
Guía técnica verificada

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.

Verificado

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.

Corregido

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.

Verificado

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.

Verificado

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.

Corregido

Sin promesa falsa de waitlist o instalador

La FAQ renderizada ya no afirma que exista un instalador público o una lista por email como si estuvieran disponibles. El acceso sigue en desarrollo activo hasta documentar un flujo real de release.

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
Un bug real de agenda vino de chequear current_speech_source.startsWith("kira-agenda") para inferir estado del controlador. El controlador puede emitir acciones con source="chat"; confiá en el estado del controlador, no en etiquetas pegadas a un evento.
Los widgets Tk son single-threaded
Cualquier mutación de widget debe ocurrir en el main loop. El hilo de dispatch de UIState es separado, así que los callbacks deben usar schedule_ui_update() / after_idle antes de tocar widgets Tk.
Reasoning token budget
Modelos como qwen3 y gemma pueden gastar parte del token budget en razonamiento interno. Un cap duro de num_predict puede devolver respuestas vacías o truncadas; el motor remueve ese cap para esas familias.
Los storage paths se resuelven al importar
STORAGE_PATHS se resuelve cuando se importa config/storage.py. apply_storage_environment() corre antes de inicializar librerías; cambiar storage.yaml en runtime no mueve rutas ya resueltas.
Los gates de privacidad van antes que los fallbacks cómodos
El switch local-only debe evaluarse antes del fallback ligero/offline de Edge-TTS. Reordenar esas ramas puede enviar texto a Microsoft aunque el usuario haya pedido síntesis solo local.
La configuración persistida puede contaminar tests
Cualquier test de comandos del motor que escriba preferencias como tts_local_only o tts_speed debe parchear save/load a una ruta temporal; si no, puede mutar la configuración real del usuario.
Validá namespaces de topics al leer, no solo al rutear
Filas hostiles o legacy pueden existir ya en SQLite. El topic inbox aísla IDs ajenos al leer para que el render y el dismiss de la UI coincidan sobre qué le pertenece.
app_shell.py tiene presupuesto duro de líneas
El guard de integración mantiene app_shell.py por debajo de 3100 líneas. El comportamiento nuevo de UI casi siempre debe vivir en un módulo pequeño inyectado, dejando app_shell solo para cableado.

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.