Saltar al contenido
ColliePWA

08/Documentation

Entrada de voz y Web Push

El micrófono en el editor y notificaciones cuando un agente está esperando una respuesta

Ambas funciones están desactivadas de forma predeterminada. Se puede habilitar un botón de micrófono en el compositor y notificaciones del navegador que se activan cuando un agente está esperando una entrada.

Entrada de voz (opcional)

Un botón de micrófono en el editor y un interruptor de manos libres en Settings. Se pulsa el botón, se habla y la transcripción aparece en el cuadro de mensaje para revisarla y enviarla. Con el modo manos libres activado se envía automáticamente, siguiendo la misma ruta protegida de respuesta que un mensaje escrito, nunca una alternativa.

El micrófono es el botón redondo al final de la fila mientras el cuadro esté vacío; el primer carácter escrito lo convierte de nuevo en Send. Se dicta un mensaje o se escribe, manteniendo una única acción principal en lugar de dos compitiendo por el ancho del campo.

No existe hasta que se ejecuta collie stt setup. No se dibuja ningún botón, ningún audio sale del teléfono, no se guarda ninguna credencial, no se ejecuta ningún proceso secundario. Ausente, no deshabilitado. Dos proveedores:

proveedorqué es
openai-compatibleCualquier endpoint compatible con POST /audio/transcriptions: la API pública de OpenAI, un clon de Whisper en la nube o un motor local en la misma máquina, que es la opción sin salida de datos (abajo).
codexUtiliza el binario de codex en el que ya se confía para obtener un token de corta duración. Sin cuentas nuevas, sin claves nuevas, y un endpoint privado, no soportado que incluye un paso de consentimiento donde se debe escribir yes (abajo).

La configuración se realiza mediante CLI por la misma razón que emparejamiento: esta superficie acepta una credencial, por lo que corresponde al teclado del host. No hay formulario de configuración web.

$ bin/collie stt setup
Which speech-to-text provider?
  openai-compatible  any endpoint that speaks POST /audio/transcriptions —
                     the public OpenAI API, or a local whisper.cpp / parakeet.cpp
                     server, which is the zero-egress choice and the one to prefer.
  codex              borrow your own `codex` sign-in. No new key, no new account —
                     and a private endpoint that may break without notice.
provider [openai-compatible]:
The API base, INCLUDING its version prefix — the provider appends /audio/transcriptions.
  local  http://127.0.0.1:8080/v1     (whisper.cpp / parakeet.cpp — nothing leaves the host)
  cloud  https://api.openai.com/v1    (room audio leaves this machine)
base URL: http://127.0.0.1:8080/v1
The model the endpoint understands. Empty takes Collie's default, gpt-transcribe.
model [gpt-transcribe]: whisper-1
API key [none]:
The language you speak, as a two-letter ISO-639-1 code — en, de, tr, ja.
LEAVE IT EMPTY to let the model detect it, which is what you want if you mix languages in one
sentence. Name one only if short clips keep coming back in a language you did not speak: a few
seconds of accented audio is too little for the model to detect from, and it guesses.
spoken language [auto-detect]: en
✓ speech-to-text configured — /home/you/.local/state/collie/stt.json (owner-only)
  Live immediately — no restart needed. The bridge re-reads this file per request.
  Check it end to end with `collie stt test`.

Cada pregunta anterior tiene un flag (--provider · --url · --model · --key · --lang), por lo que una ejecución de aprovisionamiento no necesita terminal. Dejar la clave vacía es un modo soportado: un endpoint sin clave se conecta sin ningún encabezado Authorization, en lugar de uno vacío.

Solo vale la pena configurar el idioma hablado ante un error concreto. Si se deja en blanco (el valor predeterminado), el modelo detecta el idioma automáticamente, lo cual es adecuado si se mezclan dos idiomas en una frase. Se debe configurar si los fragmentos cortos se transcriben repetidamente en un idioma no hablado: unos pocos segundos de audio con acento son insuficientes para detectarlo y el modelo hace una suposición. Un código de dos letras o una etiqueta regional que Collie simplifica (en-GBen). Solo se aplica al proveedor openai-compatible; el endpoint codex no acepta idioma, y collie stt status lo indica explícitamente en lugar de omitirlo.

Una grabación larga obtiene un límite de tiempo largo. El tiempo asignado por el navegador para un fragmento depende de su tamaño, no es un número fijo: asume una subida constante de 256 kb/s y añade el límite de tiempo del propio proveedor del puente, permitiendo un poco menos de seis minutos para el máximo de 8 MiB. Un fragmento que Collie aceptó grabar es un fragmento que está dispuesto a esperar. Mientras la subida está en curso, Collie detiene el sondeo y no escala el aviso de conexión: el propio audio saturando la subida de un teléfono no es una caída del servicio y no debe reportarse como tal.

¿Funcionó? stt test envía un quinto de segundo de silencio generado a través del proveedor real, una vez por cada contenedor que un teléfono puede grabar:

$ bin/collie stt test
provider: openai-compatible (http://127.0.0.1:8080/v1, model whisper-1, language en)
sending:  0.2 s of generated silence as audio/wav (the setup probe) … ✓ 214 ms
  transcript: (empty) — expected from silence, and the empty answer still proves the pipeline.
sending:  0.2 s of generated silence as audio/webm;codecs=opus (Chrome, Android, Firefox) … ✓ 198 ms
sending:  0.2 s of generated silence as audio/mp4 (Safari, iOS) … ✓ 190 ms

Una transcripción vacía se considera aprobada: el silencio se transcribe en nada y se valida el trayecto de ida y vuelta. Si falla, el error especifica el tipo (autenticación, endpoint, formato de respuesta). Luego se recarga Collie en el teléfono: aparecerá un micrófono junto al cuadro de mensaje. collie stt status indica qué está configurado y el origen de cada ajuste (el archivo o una variable de entorno con mayor prioridad); collie stt off elimina stt.json y el botón desaparece de nuevo, sin requerir reinicio en ningún caso.

El soporte de contenedores depende del proveedor

El teléfono nunca graba WAV. Graba Opus en un contenedor WebM en Chrome, Android y Firefox, o AAC en un contenedor MP4 en Safari e iOS, y envía esos bytes tal cual. Un proveedor que transcribe WAV aún puede responder 400 a ambos, y cada dictado falla entonces con "refused" mientras stt test parece correcto. Por eso stt test envía los tres clips: el rechazo se detecta durante la configuración, no en el teléfono.

Un caso, verificado el 2026-09-01 con POST /v1/audio/transcriptions de OpenRouter:

formatomistralai/voxtral-small-24b-2507-sttopenai/whisper-large-v3-turbo
wav
ogg/opus
webm/opusno, 400
mp4/m4a AACno, 400

La solución alternativa es el modelo, no la clave: apunte la misma clave de OpenRouter a openai/whisper-large-v3-turbo, que acepta los cuatro.

bin/collie stt setup --provider openai-compatible \
  --url https://openrouter.ai/api/v1 --model openai/whisper-large-v3-turbo --key <key>

Una transcripción rechazada ahora indica el estado del upstream y el contenedor con el que se envió, de modo que el error en el teléfono muestra qué formato rechazó el proveedor. (#148, gracias @drewbitt)

Sin salida de datos: apunte a su propio motor

La razón por la que openai-compatible es el proveedor a elegir: asígnele una URL base local y ningún audio de la sala sale del host. Dos motores ofrecen un endpoint de transcripción compatible con OpenAI: el server integrado de whisper.cpp y mudler/parakeet.cpp (MIT). Compile o instale cualquiera de ellos según sus propias instrucciones, ejecútelo en loopback y apunte --url hacia él:

bin/collie stt setup --provider openai-compatible --url http://127.0.0.1:8080/v1

Esa es toda la integración: Collie no tiene preferencia sobre qué motor responde.

Voxtral de Mistral no necesita soporte propio, y tampoco nada más que use este contrato; ese es el propósito de la unión. vLLM sirve los modelos abiertos Voxtral en /v1/audio/transcriptions, por lo que uno local es el mismo --url que cualquier otro motor. Los modelos alojados son la misma solicitud en la base propia de Mistral:

bin/collie stt setup --provider openai-compatible \
  --url https://api.mistral.ai/v1 --model voxtral-mini-latest --key <key> --lang en

Voxtral Mini Transcribe cubre 13 idiomas y acepta el mismo campo ISO-639-1 language que Collie ya envía. Pruébelo con collie stt test antes de confiar en él: "compatible con OpenAI" es una afirmación que cada endpoint hace por sí mismo, y ese verbo existe para verificarlo.

El proveedor codex: lo que se acepta

collie stt setup --provider codex imprime un bloque de consentimiento y se detiene hasta que se escribe yes, porque la realidad es esta: las grabaciones van a un endpoint de ChatGPT no documentado y sin soporte autorizado mediante el inicio de sesión de a su, por lo que la cuenta de ChatGPT asume el límite de velocidad y el riesgo de suspensión, y puede dejar de funcionar sin previo aviso.

Collie consulta a ese endpoint primero bajo su propio nombre. Solo si se rechaza la identidad real, recurre a las cabeceras de Codex CLI; y ese mecanismo de reserva queda registrado en la configuración, en un término que collie stt status le muestra. Collie nunca lee ni almacena ~/.codex/auth.json; el binario en el que ya confía sigue siendo lo único que interactúa con él.

El razonamiento detrás de todo lo anterior (por qué se rechazó dos veces, qué cambió y por qué la unión tiene esta forma) está en ADR 0029.

Web Push (opcional)

Desactivado por defecto. La configuración requiere tres pasos. La biblioteca del remitente (web-push) se incluye como dependencia opcional durante la compilación:

collie push-keys     # 1. generate + write the VAPID keys
collie restart       # 2. Collie reads them at start
#                      3. on your phone: Settings → notifications

El comando push-keys genera el par de claves y escribe COLLIE_VAPID_PUBLIC y COLLIE_VAPID_PRIVATE con permisos de archivo 600 en el .env activo, que es ~/.config/collie/.env en una instalación binaria o el ubicado en el directorio de configuración de plugins de Herdr en una instalación de Herdr.

Pase un URI de contacto como argumento para definir la notificación de asunto de RFC 8292:

collie push-keys mailto:you@example.com

En instalaciones gestionadas por Herdr, ambos pasos están disponibles como acciones (herdr plugin action invoke push-keys --plugin herdr.collie y restart). Las acciones de Herdr no aceptan argumentos posicionales, por lo que definir un asunto requiere ejecutar el comando directamente en la shell.

Detalles del manejo de claves:

El comando no sobrescribe las claves existentes a menos que se pase --force. Reemplazar las claves invalida todas las suscripciones actuales, lo que exige que cada dispositivo se vuelva a suscribir antes de poder recibir notificaciones de nuevo. Proporcionar un argumento de asunto en una configuración existente solo actualiza la dirección de contacto y conserva las claves actuales.

Nota. En versiones de Herdr anteriores a 0.8.0, las acciones permanecen fijadas al conjunto almacenado en caché durante la instalación inicial del plugin (ADR 0006). Las acciones push-keys y push-test no aparecerán hasta que se ejecute herdr plugin install. Ejecute bash scripts/collie-ctl.sh push-keys directamente en su lugar. El script contenedor pasa el comando directamente al binario.

Pruebe la ruta de entrega en todos los dispositivos suscritos:

collie push-test                     # or: push-test "Title" "Body"

La entrega tarda entre uno y dos segundos. Si el comando indica que push está desactivado, reinicie el servicio para que cargue las claves generadas. Si indica que no hay dispositivos suscritos, complete el paso 3 en el navegador del teléfono.

Web Push requiere un contexto seguro (HTTPS). Esto lo proporciona tailscale serve (certificados de MagicDNS) o un proxy inverso externo que termine TLS (Variante C). Las configuraciones HTTP simples (COLLIE_SERVE_MODE=http) carecen de un contexto seguro y el navegador desactiva los controles de suscripción en Settings.

Collie envía notificaciones cuando un agente entra en el estado blocked o done, colocando el mensaje del agente en el cuerpo. Al seleccionar la notificación se navega directamente a ese agente en la interfaz web.

Las suscripciones obsoletas pueden acumularse con el tiempo, ya que las reinstalaciones en la pantalla de inicio y los reinicios del service worker crean nuevos endpoints sin devolver siempre un HTTP 410. Collie actualiza el registro cuando un dispositivo se vuelve a registrar. Puede ver y eliminar endpoints almacenados directamente:

# one line per device: service, since, user agent, endpoint tail
bin/collie push list
bin/collie push forget <substring>   # or: push forget --all

Editar esta página en GitHub