Muninn
Haz que tu agente inicie el dictado
Documentación
muninn
Dictado nativo de IA en la barra de menús de macOS para texto de desarrollador.
Muninn graba el habla, la transcribe, procesa la transcripción mediante un pipeline de texto configurable e inyecta el texto final en la aplicación activa. El pipeline predeterminado está diseñado para dictado cercano al código: comandos, flags, nombres de paquetes, rutas de archivos, variables de entorno, acrónimos y otros tokens que el dictado de propósito general suele modificar.
Contenido
- Qué hace Muninn
- Inicio rápido
- Instalación y ejecución
- Configurar Muninn
- Proveedores de transcripción
- Modelo de pipeline
- Transcripción en streaming
- Perfiles contextuales y voces
- Control externo
- Privacidad, reproducción y depuración
- Desarrollo
- Limitaciones actuales
- Mapa de fuentes
Qué hace Muninn
Flujo predeterminado en modo grabado:
hotkey or tray click
-> record temporary WAV
-> resolve transcription provider route
-> transcribe with the first usable provider
-> run the refine step
-> run optional external filters
-> inject final text into the active app
Muninn incluye:
- una aplicación de barra de menús de macOS con un indicador de bandeja en vivo
- teclas de acceso rápido globales para pulsar-para-hablar, alternar modo hecho y cancelar
- captura de micrófono a un WAV temporal, con valor predeterminado de 16 kHz mono
- una ruta de transcripción local-primero a través de Apple Speech, whisper.cpp, Deepgram, OpenAI, Google y SpaceXAI (xAI) para transcripción grabada
- un modo de streaming opcional para proveedores que admiten transcripción en vivo en este código base
- un paso
refineintegrado que aplica un prompt conservador de dictado para desarrolladores (OpenAI o SpaceXAI / xAI) - soporte de filtros Unix externos para pasos de pipeline personalizados
- inyección de texto mediante eventos de teclado en la aplicación actual
- control externo opcional mediante URLs
muninn://y un servidor MCP en localhost - artefactos de reproducción opcionales para depurar expresiones
Controles predeterminados:
| Acción | Predeterminado |
|---|---|
| Pulsar-para-hablar | ctrl con disparador double_tap y una ventana de doble toque de 300 ms |
| Alternar modo hecho | ctrl + shift + d |
| Cancelar captura activa | ctrl + shift + x |
| Clic izquierdo en bandeja | Alternar: iniciar cuando está inactivo, detener cuando graba |
Los cambios de teclas de acceso rápido se leen de la configuración, pero la recarga en vivo de la configuración no reemplaza los enlaces de teclas activos. Reinicia Muninn después de cambiar las teclas de acceso rápido.
Inicio rápido
Usa esta ruta cuando quieras ejecutar Muninn desde este repositorio.
Requisitos previos
- macOS
- Rust 1.88.0 o más reciente
- Herramientas de línea de comandos de Xcode para compilaciones locales
- Permisos de macOS para Micrófono, Accesibilidad y Monitoreo de Entrada
- Claves opcionales de proveedores en la nube cuando uses Deepgram, OpenAI, Google, SpaceXAI (xAI) o un paso
refinerespaldado por la nube
1. Compilar el binario
cargo build --release --bin muninn
2. Crear un archivo de configuración
Muninn lee la configuración en este orden:
MUNINN_CONFIG$XDG_CONFIG_HOME/muninn/config.toml~/.config/muninn/config.toml
Si el archivo de configuración resuelto no existe, Muninn crea una configuración predeterminada ejecutable. Para comenzar desde la configuración de ejemplo en su lugar:
CONFIG_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/muninn"
mkdir -p "$CONFIG_DIR"
cp configs/config.sample.toml "$CONFIG_DIR/config.toml"
3. Establecer credenciales cuando sea necesario
Muninn carga ./.env desde el directorio de trabajo actual de forma predeterminada. Las variables de entorno existentes del shell anulan .env y los valores de configuración.
Crea .env solo con las claves que uses:
OPENAI_API_KEY=<OPENAI_API_KEY>
DEEPGRAM_API_KEY=<DEEPGRAM_API_KEY>
GOOGLE_API_KEY=<GOOGLE_API_KEY>
GOOGLE_STT_TOKEN=<GOOGLE_STT_TOKEN>
XAI_API_KEY=<XAI_API_KEY>
Establece MUNINN_LOAD_DOTENV=0, false o no para deshabilitar la carga de .env.
4. Ejecutar la aplicación de bandeja
cargo run --release --bin muninn
Resultado esperado: Muninn aparece en la barra de menús de macOS con un indicador de bandeja M.
5. Otorgar permisos y verificar
Otorga estos permisos al propio Muninn:
| Permiso | Por qué Muninn lo necesita | Ruta en Configuración del Sistema |
|---|---|---|
| Micrófono | Grabar tu habla | Privacidad y seguridad > Micrófono |
| Accesibilidad | Inyectar el texto final en la aplicación activa | Privacidad y seguridad > Accesibilidad |
| Monitoreo de Entrada | Escuchar teclas de acceso rápido globales mientras otra aplicación está activa | Privacidad y seguridad > Monitoreo de Entrada |
Para verificar la aplicación:
- Enfoca un campo de texto en otra aplicación.
- Haz clic en el ícono de bandeja de Muninn para comenzar a grabar.
- Di una frase corta.
- Haz clic nuevamente en el ícono de bandeja para detener la grabación.
Resultado esperado: Muninn transcribe la expresión, ejecuta el pipeline y escribe el texto final en la aplicación enfocada.
Si macOS deja de mostrar el aviso de permiso, restablece el servicio TCC afectado y reinicia Muninn:
tccutil reset ListenEvent
tccutil reset Accessibility
tccutil reset Microphone
Instalación y ejecución
Instalar desde crates.io
cargo install muninn-speech-to-text
muninn
El nombre del paquete es muninn-speech-to-text; el nombre del binario es muninn.
Ejecutar desde la configuración de ejemplo
MUNINN_CONFIG="$PWD/configs/config.sample.toml" cargo run --release --bin muninn
Esto es útil para el desarrollo local porque evita cambiar tu configuración de usuario.
Instalar un binario de versión
El flujo de trabajo de versiones compila archivos tar para:
aarch64-apple-darwinx86_64-apple-darwin
Después de extraer un archivo de versión, mantén el binario en una ruta estable antes de otorgar permisos de macOS:
mkdir -p "$HOME/.local/bin"
mv muninn "$HOME/.local/bin/muninn"
chmod +x "$HOME/.local/bin/muninn"
"$HOME/.local/bin/muninn"
Los permisos de macOS se adjuntan a la identidad exacta de la aplicación o binario. Mover o reemplazar un binario sin empaquetar puede requerir otorgar permisos nuevamente.
Compilar un paquete .app local
Usa el paquete de aplicación cuando quieras una identidad de aplicación estable, manejo de URLs muninn:// y comportamiento normal de Elementos de Inicio de Sesión.
cargo build --release --bin muninn
bash scripts/package-macos-app.sh
open dist/Muninn.app
El script de empaquetado crea dist/Muninn.app, lo firma ad hoc de forma predeterminada y crea dist/Muninn.app.zip cuando ditto está disponible. Establece CODESIGN_IDENTITY para usar un certificado de Developer ID, o establece CODESIGN_APP=0 para omitir la firma.
Configuración recomendada del paquete de aplicación:
- Mueve
dist/Muninn.appa/Applications/Muninn.app. - Ejecútalo una vez y otorga permisos a
Muninn. - Agrégalo en Configuración del Sistema > General > Elementos de Inicio de Sesión.
- Mantén
[app].autostart = falsecuando uses Elementos de Inicio de Sesión.
Finder y Elementos de Inicio de Sesión no heredan el entorno de tu shell. Guarda las credenciales en la configuración o asegúrate de que el directorio de trabajo de Muninn contenga el archivo .env que esperas que lea.
Habilitar inicio automático de binario sin empaquetar
Establece [app].autostart = true para permitir que Muninn escriba un LaunchAgent para la ruta del ejecutable actual.
Comportamiento:
- Muninn escribe
~/Library/LaunchAgents/com.bnomei.muninn.plistcuando inicia o recarga la configuración. - Los cambios surten efecto en el próximo inicio de sesión de macOS.
- El LaunchAgent incluye
MUNINN_CONFIG. - El LaunchAgent no hereda las exportaciones interactivas del shell.
- Cuando uses
Muninn.app, prefiere los Elementos de Inicio de Sesión de macOS sobre esta ruta de LaunchAgent para binario sin empaquetar.
Configurar Muninn
El ejemplo canónico es configs/config.sample.toml. El esquema raíz se encuentra en src/config.rs.
Secciones importantes de configuración
| Sección | Propósito |
|---|---|
[app] | Perfil predeterminado, contrato estricto de pasos, inicio automático de binario sin empaquetar |
[hotkeys.*] | Enlaces de pulsar-para-hablar, alternar modo hecho y cancelar |
[indicator] | Visibilidad y colores del indicador de bandeja |
[recording] | Formato de captura WAV y post-procesamiento opcional de tempo con FFmpeg; valores predeterminados: mono, 16 kHz y postprocess_speed = 1.0 |
[transcription] | Modo grabado versus streaming y ruta ordenada de proveedores |
[pipeline] | Plazo del pipeline, formato de payload y pasos posteriores a la transcripción |
[transcript] | Prompt base y texto de anexo al prompt para el paso de refinamiento integrado |
[refine] | Proveedor de refinamiento (openai o xai), endpoint, modelo, temperatura y salvaguardas |
[voices.*] | Comportamiento de refinamiento con nombre y glifo opcional de una letra en la bandeja |
[profiles.*] | Anulaciones específicas de contexto para grabación, ruta, pipeline, transcripción o refinamiento |
[[profile_rules]] | Coincidencias ordenadas para la aplicación frontal y el título de la ventana |
[external_control] | Esquema de URL y ajustes de control de grabación MCP |
[logging] | Artefactos de reproducción, retención y detalle de depuración |
[providers.*] | Credenciales de proveedores, endpoints, modelos y ajustes de streaming |
Post-procesamiento de tempo en WAV grabado
Establece una velocidad superior a 1.0 para post-procesar cada captura completada con FFmpeg antes de que un proveedor de grabación la lea. El filtro preserva el tono:
[recording]
postprocess_speed = 2.0
El valor predeterminado, 1.0, deja el WAV finalizado sin cambios. Se aceptan valores desde 1.0 hasta 16.0; los valores superiores a 2× se expresan como múltiples etapas atempo de FFmpeg para evitar el comportamiento de omisión de muestras del filtro con un solo factor alto. Muninn necesita ffmpeg en PATH cuando el valor configurado es superior a 1.0 (por ejemplo, brew install ffmpeg); si no está disponible, la bandeja muestra un estado de error rojo y la captura se descarta. Los proveedores de streaming aún reciben fotogramas de captura en vivo a velocidad normal; el WAV post-procesado se usa para transcripción grabada, respaldo y reproducción después de que la captura finaliza.
Ruta de proveedores
La ruta de proveedores predeterminada es local-primero:
[transcription]
providers = ["apple_speech", "whisper_cpp", "deepgram", "openai", "google", "xai"]
Los perfiles pueden anular solo la ruta:
[profiles.mail.transcription]
providers = ["deepgram", "openai", "google", "xai"]
Si aún tienes pasos stt_* explícitos en pipeline.steps, Muninn los acepta e infiere la ruta a partir de ese orden. Las configuraciones nuevas deberían preferir [transcription].providers.
Pasos del pipeline
Cada paso del pipeline tiene:
idcmdargsopcionalio_modeopcionaltimeout_mson_error
Valores admitidos de io_mode:
| Valor | Comportamiento |
|---|---|
auto | Los integrados usan JSON de sobre; los comandos externos usan filtrado de texto de forma predeterminada |
envelope_json | El paso lee y escribe el sobre JSON completo |
text_filter | El paso lee el texto de la transcripción y escribe texto de reemplazo |
Valores admitidos de on_error:
| Valor | Comportamiento |
|---|---|
continue | Conservar el sobre anterior y ejecutar pasos posteriores |
fallback_raw | Sustituir transcript.raw_text y continuar |
abort | Detener el pipeline y mostrar el error |
Ejemplo:
[transcription]
providers = ["apple_speech", "whisper_cpp", "deepgram", "openai", "google", "xai"]
[[pipeline.steps]]
id = "refine"
cmd = "refine"
timeout_ms = 2500
on_error = "continue"
[[pipeline.steps]]
id = "uppercase"
cmd = "/usr/bin/tr"
args = ["[:lower:]", "[:upper:]"]
timeout_ms = 250
on_error = "continue"
Sugerencias de prompt de refinamiento
transcript.system_prompt y transcript.system_prompt_append guían el paso refine integrado. No cambian el proveedor de voz a texto, y Muninn no analiza el JSON anexado en APIs de adaptación nativas del proveedor.
[transcript]
system_prompt = "Prefer minimal corrections. Focus on technical terms, developer tools, package names, commands, flags, file names, paths, env vars, acronyms, and obvious dictation errors. If uncertain, keep the original wording."
system_prompt_append = """
Vocabulary JSON:
{"terms":["Muninn","whisper.cpp","Deepgram","Cargo.toml"],"commands":["cargo test --all-targets","rg --files"],"paths":["src/config.rs",".env"]}
"""
Proveedores de transcripción
| Proveedor | Modo grabado | Modo streaming | Credenciales | Notas |
|---|---|---|---|---|
| Apple Speech | Sí | No | Ninguna | Proveedor local de macOS 26+. Utiliza los recursos de Speech gestionados por Apple para la configuración regional seleccionada. |
| whisper.cpp | Sí | No | Ninguna | Proveedor local. Por defecto usa tiny.en, almacenado en ~/.local/share/muninn/models, con device = "auto". |
| Deepgram | Sí | Sí | DEEPGRAM_API_KEY o providers.deepgram.api_key | Las subidas grabadas usan /v1/listen; el streaming usa la API WebSocket en vivo. |
| OpenAI | Sí | Sí | OPENAI_API_KEY o providers.openai.api_key | Las subidas grabadas se verifican contra el límite de audio de 25 MB de OpenAI; el streaming usa transcripción en tiempo real. |
| Sí | No invocable actualmente | GOOGLE_API_KEY, GOOGLE_STT_TOKEN o valores de configuración | La transcripción REST grabada funciona a través del endpoint configurado. El adaptador de streaming de Google construye solicitudes de Speech-to-Text v2, pero la dependencia fijada google-cloud-speech-v2 1.12.0 no expone un RPC de streaming invocable, por lo que Muninn informa google_official_client_streaming_rpc_unavailable. | |
| SpaceXAI (xAI) | Sí | Sí | XAI_API_KEY o providers.xai.api_key | Id de configuración xai, paso stt_xai. Las subidas grabadas usan POST https://api.x.ai/v1/stt (multipart; sin campo STT model). El streaming usa wss://api.x.ai/v1/stt con autenticación Bearer, PCM mono de 16 kHz y un handshake transcript.created. Opcionales language, format, keyterm, diarize, filler_words y vad_threshold bajo [providers.xai]. Anulaciones de entorno: XAI_STT_ENDPOINT, XAI_STT_STREAMING_ENDPOINT, XAI_STT_LANGUAGE. |
El paso refine no es un proveedor de STT. Usa la configuración [refine] y HTTP compatible con chat-completions por defecto (provider = "openai"). Establece provider = "xai" para refinar con SpaceXAI / xAI (https://api.x.ai/v1/chat/completions, modelo grok-4.5 por defecto). Establecer solo el proveedor cambia el endpoint y el modelo a los valores predeterminados de ese proveedor, de modo que una clave de xAI nunca se envía a una URL de OpenAI.
Variables de entorno
| Aspecto | Variables |
|---|---|
| Ruta de configuración | MUNINN_CONFIG |
Carga de .env | MUNINN_LOAD_DOTENV |
| Deepgram | DEEPGRAM_API_KEY, DEEPGRAM_STT_ENDPOINT, DEEPGRAM_STT_MODEL, DEEPGRAM_STT_LANGUAGE, MUNINN_DEEPGRAM_STUB_TEXT |
| Transcripción y refinamiento de OpenAI | OPENAI_API_KEY, MUNINN_OPENAI_STUB_TEXT, MUNINN_REFINE_STUB_TEXT |
| Transcripción grabada de Google | GOOGLE_API_KEY, GOOGLE_STT_TOKEN, GOOGLE_STT_ENDPOINT, GOOGLE_STT_MODEL, MUNINN_GOOGLE_STUB_TEXT |
| Transcripción y refinamiento de SpaceXAI (xAI) | XAI_API_KEY, XAI_STT_ENDPOINT, XAI_STT_STREAMING_ENDPOINT, XAI_STT_LANGUAGE, MUNINN_XAI_STT_STUB_TEXT, MUNINN_REFINE_STUB_TEXT |
Las variables simuladas están pensadas para comprobaciones locales y pruebas. Omiten las llamadas en vivo al proveedor para el paso correspondiente.
Ciclo de vida del modelo whisper.cpp
Comportamiento predeterminado:
providers.whisper_cpp.modelsin establecer se resuelve atiny.entiny.ense resuelve aggml-tiny.en.bin- el directorio de modelos predeterminado es
~/.local/share/muninn/models - Muninn descarga automáticamente modelos canónicos conocidos en el primer uso
- las rutas de modelos personalizados explícitos deben existir previamente
device = "auto"usa Metal en builds compatibles de Apple Silicon y CPU en caso contrario
Precalienta la caché de modelos predeterminada:
mkdir -p "$HOME/.local/share/muninn/models"
curl -L \
-o "$HOME/.local/share/muninn/models/ggml-tiny.en.bin" \
"https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-tiny.en.bin"
Si una ruta solo local apunta a un modelo personalizado inexistente, Muninn registra un diagnóstico missing_whisper_cpp_model y no inyecta nada a menos que otro proveedor produzca transcript.raw_text más adelante.
Modelo de pipeline
Muninn pasa un sobre a través de cada paso integrado y externo. Los pasos STT integrados completan transcript.raw_text; los pasos de transformación como refine escriben output.final_text. La inyección prefiere output.final_text y puede recurrir a transcript.raw_text.
Comandos de pasos integrados:
| Comando | Propósito |
|---|---|
stt_apple_speech | Transcripción de Apple Speech para grabaciones completadas |
stt_whisper_cpp | Transcripción local de whisper.cpp para grabaciones completadas |
stt_deepgram | Transcripción de Deepgram para grabaciones completadas |
stt_openai | Transcripción de OpenAI para grabaciones completadas |
stt_google | Transcripción REST de Google para grabaciones completadas |
stt_xai | Transcripción de SpaceXAI / xAI para grabaciones completadas |
refine | Limpieza de dictado de desarrollador con chat-completions (openai o xai) |
Ejecuta un paso integrado directamente para comprobaciones rápidas:
cargo run -q -- __internal_step <stt_apple_speech|stt_whisper_cpp|stt_deepgram|stt_openai|stt_google|stt_xai|refine>
Usa los fixtures JSON en tests/fixtures para ejemplos de sobres de entrada.
Transcripción en streaming
El modo grabado es el predeterminado. Habilita el streaming explícitamente:
[transcription]
mode = "streaming"
providers = ["deepgram", "openai", "xai"]
[transcription.streaming]
frame_ms = 100
finish_timeout_ms = 10000
fallback_to_recorded_on_error = true
Comportamiento del streaming:
- El streaming de Deepgram envía audio LINEAR16 mono a través de WebSocket.
- El streaming de OpenAI usa transcripción en tiempo real y fuerza captura mono de 24 kHz para esa emisión.
- El streaming de SpaceXAI / xAI usa
wss://api.x.ai/v1/sttcon BearerXAI_API_KEY, esperatranscript.created, envía tramas PCM mono de 16 kHz y finaliza conaudio.done. Cuando xAI es el proveedor de streaming activo, Muninn fuerza captura mono de 16 kHz para esa emisión. - El streaming de Google no es invocable actualmente porque la dependencia fijada
google-cloud-speech-v21.12.0 expone tipos de solicitud y respuesta pero ningún método de streaming invocable. - Muninn aún escribe el WAV completado durante el streaming.
- Cuando el streaming falla y
fallback_to_recorded_on_error = true, Muninn puede ejecutar la ruta de WAV completado. - Una transcripción de streaming exitosa siembra
transcript.raw_text;refine, la puntuación, la reproducción y la inyección usan el mismo pipeline descendente que el modo grabado. - Los resultados intermedios de streaming son transitorios. Muninn no muestra una interfaz de transcripción parcial ni persiste el historial de transcripción parcial.
Perfiles contextuales y voces
Muninn puede cambiar el comportamiento de refinamiento según la aplicación en primer plano. Captura el id del bundle, el nombre de la aplicación y un título de ventana de mejor esfuerzo, luego aplica la primera entrada profile_rules que coincida. Si ninguna regla coincide, el comportamiento recurre a [app].profile; el glifo de la bandeja inactiva recurre a M.
Orden de resolución:
- Comienza desde la configuración base.
- Aplica la voz coincidente, si el perfil coincidente nombra una.
- Aplica las anulaciones del perfil al final.
Voz significa comportamiento de modelado de texto más un glifo opcional de bandeja, no una voz de audio.
[app]
profile = "default"
[voices.codex]
indicator_glyph = "C"
system_prompt = "Prefer terse developer dictation. Keep commands, flags, file names, and code tokens intact."
system_prompt_append = """
Vocabulary JSON:
{"terms":["Codex","Muninn","Cargo.toml"],"commands":["cargo test --all-targets","cargo clippy --all-targets -- -D warnings"]}
"""
[voices.terminal]
indicator_glyph = "T"
system_prompt = "Preserve shell commands exactly. Prefer minimal punctuation changes."
[profiles.codex]
voice = "codex"
[profiles.terminal]
voice = "terminal"
[[profile_rules]]
id = "codex-app"
profile = "codex"
app_name = "Codex"
[[profile_rules]]
id = "terminal-app"
profile = "terminal"
bundle_id = "com.apple.Terminal"
Comportamiento de la bandeja:
- la vista previa inactiva muestra el glifo de la voz coincidente, o
M - la grabación y el procesamiento congelan el glifo resuelto para esa emisión
?está reservado para comentarios de credenciales faltantes
Control externo
Muninn puede ser controlado por agentes y scripts a través de dos transportes:
- Esquema de URL
muninn://, disponible para el.appempaquetado de macOS - Servidor MCP HTTP streamable en localhost, deshabilitado por defecto
Ambos transportes usan el mismo vocabulario de control de grabación que los eventos de bandeja y atajos de teclado.
[external_control]
url_scheme_enabled = true
mcp_enabled = false
start_recording_enabled = false
mcp_bind_address = "127.0.0.1:2769"
Semántica de acciones:
| Acción | Comportamiento |
|---|---|
start | Inicia la grabación solo cuando está inactivo y start_recording_enabled = true |
stop | Detiene una grabación activa y ejecuta el pipeline; no-op cuando está inactivo |
toggle | Inicia cuando está inactivo y permitido; de lo contrario detiene una grabación activa |
cancel | Descarta una grabación activa sin transcripción ni inyección |
El inicio externo está deshabilitado por defecto porque inicia la captura del micrófono. Habilitar start_recording_enabled = true es la decisión de confianza local para agentes y scripts configurados.
Esquema de URL
El .app empaquetado registra muninn:// a través de CFBundleURLTypes.
| URL | Acción |
|---|---|
muninn://record, muninn://start | iniciar |
muninn://stop, muninn://done | detener |
muninn://toggle | alternar |
muninn://cancel, muninn://abort | cancelar |
open "muninn://record"
Un binario lanzado con cargo run no recibe estos enlaces de LaunchServices.
Servidor MCP
Cuando mcp_enabled = true, Muninn sirve MCP en:
http://127.0.0.1:2769/mcp
Herramientas:
get_statusstart_recordingstop_recordingcancel_recording
Ejemplo de registro con un cliente compatible con MCP:
auggie mcp add muninn --transport http --url http://127.0.0.1:2769/mcp
get_status es de solo lectura y devuelve JSON como:
{
"state": "idle",
"recording_active": false,
"busy": false,
"permissions": {
"microphone": "granted",
"accessibility": "granted",
"input_monitoring": "granted"
}
}
state es uno de idle, recording_active, permission_blocked, already_running o failed.
Restricciones de seguridad:
- El servidor MCP no tiene autenticación.
mcp_bind_addressdebe ser una dirección de socket de loopback explícita como127.0.0.1:2769o[::1]:2769.- Muninn rechaza wildcard, LAN, nombres de host y otros enlaces que no sean loopback.
- El servidor MCP se inicia solo al lanzar la aplicación. Cambiar
mcp_enabledmás tarde requiere reiniciar Muninn.
Privacidad, reproducción y depuración
Los registros de trazado van a stderr y se controlan con RUST_LOG.
RUST_LOG=recording=debug cargo run --release --bin muninn
El registro de reproducción está deshabilitado por defecto. Cuando está habilitado:
replay_detail = "minimal"almacena solo metadatos dispersos de emisionesreplay_detail = "full_debug"almacena configuración redactada, contexto objetivo, sobres finales, resultado del pipeline, contexto de refinamiento y ruta de inyecciónreplay_retain_audio = trueconserva audio solo cuandoreplay_detail = "full_debug"- el audio retenido usa un enlace duro cuando es posible y recurre a una copia
- las instantáneas de depuración completa redactan secretos de proveedores y campos de prompts
- los artefactos de reproducción son para inspección, no para re-ejecución
[logging]
replay_enabled = true
replay_detail = "minimal"
replay_retain_audio = false
replay_dir = "~/.local/state/muninn/replay"
replay_retention_days = 7
replay_max_bytes = 52428800
Comprobaciones comunes de recuperación:
| Síntoma | Comprobación |
|---|---|
| El atajo de teclado no inicia la grabación | Otorga Monitoreo de Entrada a Muninn y reinicia después de cambiar la configuración del atajo |
| El clic en la bandeja graba pero el atajo no | Falta Monitoreo de Entrada o el listener del atajo necesita reinicio |
| El texto no se inyecta | Otorga Accesibilidad a Muninn |
| No se inyecta texto después de una ruta solo local de Whisper | Verifica missing_whisper_cpp_model y confirma la ruta del modelo configurado |
| El inicio MCP externo es rechazado | Establece external_control.start_recording_enabled = true y reinicia si el servidor MCP no estaba habilitado al lanzar |
| El streaming de Google falla o informa no disponible | Usa transcripción grabada de Google, streaming de Deepgram, streaming de OpenAI o streaming de xAI |
| Faltan credenciales de SpaceXAI / xAI | Establece XAI_API_KEY o providers.xai.api_key; para refinamiento también establece [refine] provider = "xai" |
Desarrollo
Ejecuta las comprobaciones principales:
cargo fmt --all -- --check
cargo clippy --all-targets --all-features -- -D warnings
cargo test --all-targets
El repositorio también incluye hooks prek:
prek validate-config
prek run --all-files
prek install
Ejecuta la suite de benchmarks:
cargo bench --bench runtime_bottlenecks
Filtra a un grupo de benchmarks:
cargo bench --bench runtime_bottlenecks pipeline_runner
cargo bench --bench runtime_bottlenecks replay_persist
El objetivo del benchmark se centra en rutas de latencia por emisión que no requieren llamadas de red:
- transformación y remuestreo de salida de audio
- viajes de ida y vuelta JSON de sobres
- construcción del cuerpo de solicitud de Google
- resolución de perfiles y voces
- puntuación de reemplazo
- sobrecarga del runner de pipeline en proceso
- persistencia de reproducción con y sin artefactos de audio retenidos
Límites actuales
- El runtime compatible de Muninn es macOS.
- Apple Speech requiere macOS 26+ y recursos de Speech gestionados por Apple.
- whisper.cpp y Apple Speech son solo proveedores de grabación completada.
- La construcción de solicitudes de streaming de Google existe, pero el streaming en vivo de Google no es invocable hasta que el cliente oficial fijado exponga un RPC de streaming.
- El modo streaming usa solo el texto final del proveedor. No hay interfaz de transcripción parcial.
- Los artefactos de reproducción son para inspección, no para reproducción determinista.
- La transcripción respaldada por proveedores necesita presupuestos de tiempo de espera realistas.
- El servidor MCP de control externo no tiene autenticación, está deshabilitado por defecto, se enlaza solo a loopback y se inicia solo al lanzar la aplicación.
- El flujo de trabajo de lanzamiento del repositorio empaqueta binarios crudos; usa el script de empaquetado local cuando necesites un bundle
.app.
Mapa de fuentes
Usa estos archivos al verificar las afirmaciones del README contra el código fuente:
