Aller au contenu
ColliePWA

21/Documentation

Saisie vocale et Web Push

Le microphone dans le compositeur, et notifications lorsqu'un agent vous attend

Ces deux fonctionnalités sont désactivées par défaut. Vous pouvez activer un bouton de microphone dans le champ de saisie, ainsi que des notifications de navigateur qui se déclenchent lorsqu'un agent attend une saisie.

Saisie vocale (facultatif)

Un bouton de microphone dans le champ de saisie et un interrupteur mains libres dans Paramètres → Voix. Appuyez sur le bouton, parlez, et la transcription arrive dans la zone de message pour que vous puissiez la relire et l'envoyer. Si le mode mains libres est activé, elle est envoyée à votre place, via le même chemin de réponse sécurisé qu'un message saisi au clavier, sans jamais le contourner. Le microphone est le bouton rond à la fin de la ligne tant que la zone reste vide ; le premier caractère que vous saisissez le retransforme en Envoyer. Vous dictez un message ou vous le saisissez : il n'y a donc qu'une seule action principale au lieu de deux se disputant la largeur du champ.

Pendant que vous parlez, un enregistreur recouvre l'ensemble de la zone de composition, barre et champ inclus, sans ajouter de hauteur, afin que l'écran du dessus ne bouge jamais. OK se trouve là où était le micro et termine l'enregistrement. La corbeille à l'autre extrémité le supprime, et annule toujours pendant que l'enregistrement est en cours de transcription. Une fois que vous avez parlé, deux secondes de silence terminent l'enregistrement pour vous ; un cercle se referme autour de OK pour l'indiquer, et reprendre la parole réinitialise le décompte. Avant le premier mot, rien ne l'arrête tout seul.

Il n'existe pas tant que vous n'avez pas configuré de fournisseur. Exécutez collie stt setup, ou configurez Whistle (ci-dessous). Aucun bouton n'est affiché, aucun flux audio ne quitte le téléphone, aucun identifiant n'est conservé, aucun processus enfant ne s'exécute. Absent, pas désactivé. Quatre fournisseurs :

fournisseurce que c'est
openai-compatibleTout endpoint compatible POST /audio/transcriptions : l'API publique d'OpenAI, un clone cloud de Whisper ou un moteur local sur la même machine, qui constitue le choix zéro trafic sortant (ci-dessous).
codexEmprunte le binaire codex auquel vous faites déjà confiance pour obtenir un jeton éphémère. Pas de nouveau compte ni de nouvelle clé, mais un point de terminaison privé, non pris en charge nécessitant une étape de consentement : vous saisissez yes dans le terminal, ou appuyez sur J'accepte dans les Paramètres (ci-dessous).
local-cliExécute une commande de transcription déjà présente sur l'hôte, comme whisper-cli ou muesli-cli, une fois par enregistrement, et lit la transcription depuis son stdout. Aucun serveur HTTP requis (ci-dessous).
whistleLe moteur propre à Collie, Whistle. Aucune clé ni commande à configurer. Un enregistrement pouvant durer jusqu'à 4 minutes lui est envoyé sous forme de fichier WAV, et l'audio reste sur l'hôte. Un téléphone peut également exécuter Whistle directement, sans aucun téléversement.

La configuration s'effectue via le CLI pour la même raison que association : cette interface recevant un identifiant, elle a sa place sur le clavier de l'hôte. Il n'y a pas de formulaire web pour une clé, un point de terminaison ou une commande. Deux exceptions ne requièrent aucun des deux. Whistle ne conserve aucun identifiant, n'exécute aucune commande choisie par vous et n'envoie aucun flux audio hors de l'hôte ; un appareil disposant d'un accès en écriture peut donc le configurer depuis les Paramètres (pourquoi). Et dans Paramètres → Voix → Reconnaissance vocale sur l'hôte, un appareil disposant d'un accès en écriture peut basculer l'hôte entre Whistle, l'abonnement ChatGPT (le fournisseur codex) et Désactivé. ChatGPT n'est activé qu'après le même consentement que celui affiché par le terminal et un appui sur J'accepte (ci-dessous). Un fournisseur configuré dans le terminal avec une clé ou une commande, ou spécifié par votre environnement, y est affiché et n'est jamais modifié depuis l'application. Pour ces deux cas, la page affiche les commandes à exécuter sur l'hôte, avec Copier et Vérifier à nouveau, sans aucun formulaire.

$ 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.
  local-cli          run a transcription command already on this machine, such as
                     whisper-cli or muesli-cli. Its stdout is the transcript.
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`.

Chaque question ci-dessus possède un flag (--provider · --url · --model · --key · --lang), si bien qu'une exécution de provisionnement ne requiert aucun terminal. Laisser la clé vide est un mode pris en charge : un endpoint sans clé est contacté sans aucun en-tête Authorization, plutôt qu'avec un en-tête vide.

La langue parlée ne mérite d'être définie que pour un seul cas d'échec. Laissé vide (valeur par défaut), le modèle détecte la langue de lui-même, ce qui convient à une personne mélangeant deux langues dans une même phrase. Définissez-la si des enregistrements court reviennent régulièrement dans une langue que vous n'avez pas parlée : quelques secondes de signal audio avec accent ne suffisent pas pour une bonne détection, et le modèle devine. Un code à deux lettres, ou une étiquette régionale que Collie restreint pour vous (en-GB → en). Cela ne concerne que le fournisseur openai-compatible ; l'endpoint codex ne prend pas de paramètre de langue, et collie stt status vous l'indique plutôt que de vous laisser croire l'inverse.

Un enregistrement long bénéficie d'un délai long. Le délai alloué par le navigateur pour un extrait audio dépend de sa taille et non d'une valeur fixe : il suppose un débit montant soutenu de 256 kb/s et y ajoute le délai d'expiration propre au fournisseur via la passerelle, ce qui laisse un peu moins de six minutes pour la taille maximale de 8 MiB. Un enregistrement que Collie a accepté d'effectuer est un enregistrement qu'il accepte d'attendre. Pendant l'envoi, Collie arrête le polling et n'affiche pas d'alerte de connexion : saturer la bande passante montante d'un téléphone avec votre propre audio n'est pas une panne de service et ne doit pas être signalé comme telle.

Un enregistrement s'arrête au bout de cinq minutes. Un hôte exécutant Whistle prend en charge quatre minutes, car le téléphone lui envoie un fichier WAV, dont la taille est environ quatre fois supérieure à celle de l'enregistrement compressé. L'enregistreur affiche la limite applicable.

Est-ce que cela a fonctionné ? stt test envoie un cinquième de seconde de silence généré au fournisseur réel, une fois pour chaque format de conteneur qu'un téléphone peut enregistrer :

$ 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

Avec Whistle sur l'hôte, stt test envoie un seul extrait, un fichier WAV 16 kHz, et indique que webm et mp4 sont ignorés, car le téléphone convertit son enregistrement en WAV 16 kHz avant de l'envoyer à ce fournisseur.

Une transcription vide vaut succès : le silence n'est transcrit en rien, et c'est l'aller-retour qui était validé. En cas d'échec, l'erreur précise sa nature (authentification, endpoint, format de réponse). Rechargez ensuite Collie sur le téléphone : un microphone apparaît à côté du champ de saisie. collie stt status affiche ce qui est configuré et la provenance de chaque paramètre (le fichier, ou une variable d'environnement prioritaire) ; collie stt off supprime stt.json et le bouton disparaît à nouveau, sans redémarrage dans un cas comme dans l'autre.

Whistle : reconnaissance vocale sur votre téléphone ou sur votre hôte

Whistle est un modèle vocal compact développé par Cactus Compute. Le fichier pèse 16,9 Mo et la licence est Apache-2.0. Il prend en charge l'anglais, l'allemand, le français, l'espagnol, l'italien, le néerlandais et le polonais, et détecte la langue automatiquement. Il ne nécessite aucun compte, aucune clé et aucun programme supplémentaire. Collie intègre le moteur qui l'exécute ; il fonctionne ainsi sous Linux, macOS, Windows et NixOS.

Whistle peut s'exécuter à deux endroits. Choisissez pour chaque téléphone.

MoteurOù les mots sont générésÀ choisir lorsque
HôteSur l'ordinateur qui exécute Collie, dans un processus enfant éphémère issu du propre binaire de Collie.Le téléphone est peu puissant ou ancien. Un enregistrement est téléversé sous forme de fichier WAV, et un extrait prend une seconde ou deux.
Ce téléphoneDans le navigateur du téléphone, dans un worker.Le téléphone est récent. Il n'y a aucun téléversement, donc l'audio ne quitte jamais le téléphone, et cela fonctionne hors ligne une fois le modèle présent sur le téléphone.

Les deux moteurs lisent le même modèle. L'hôte en conserve une copie. Un téléphone qui souhaite exécuter Whistle lui-même le copie depuis l'hôte, jamais depuis Internet. Un extrait prend environ une seconde sur un téléphone récent.

Configurez-le depuis Paramètres. Vous devez disposer d'un appareil avec un accès en écriture (un appareil disposant de associé). Un appareil en lecture seule affiche "Un appareil avec accès en écriture peut configurer ceci." et ne peut pas lancer le téléchargement.

Paramètres → Voix est une page comportant deux pages secondaires :

  • Voice place ce qui est utilisé en premier. La carte supérieure a pour titre ce qui est configuré : la commande exécutée par votre hôte, comme whisper-cli avec Modèle ggml-base.bin et Votre propre commande sur votre hôte dessous ; le modèle d'un service vocal, comme whisper-large-v3 avec Un service vocal sur api.groq.com ; Whistle par Cactus Compute avec Modèle ca52876 et Sur ce téléphone ou Sur votre hôte ; ou Abonnement ChatGPT (OpenAI) avec Via Codex sur votre hôte. Si la commande est l'ancien wrapper whistle-stt, la carte l'indique et propose Passer à Whistle intégré, ce qui ouvre Speech de l'hôte. Ensuite vient le statut, qui indique sur quoi il repose, par exemple "Prêt. Whistle ca52876 est sur ce téléphone." ou "Pas prêt. Codex est déconnecté sur votre hôte.", la destination de Audio, et la façon dont il a été Configurer (depuis Paramètres par quel appareil et quand, ou dans un terminal sur l'hôte). Sous la carte se trouve l'interrupteur mains libres. Tout le reste se trouve derrière une seule ligne, Modifier le fonctionnement vocal. Tant que la reconnaissance vocale fonctionne, cette ligne reste fermée à chaque visite. Tant qu'elle ne fonctionne pas (rien de configuré, un téléphone en pause, une option d'hôte sans réponse), elle reste ouverte, et la carte supérieure affiche l'unique action : Configurer la voix sur ce téléphone, Restaurer ou Corriger. Dépliée, elle montre le choix propre à ce téléphone, Sur ce téléphone (marqué Recommandé) ou Sur votre hôte (l'ordinateur exécutant vos agents), qui est conservé par appareil. Le choix utilisé possède une bordure épaisse, une teinte et un badge Utilisé, et passer de l'un à l'autre ne déplace rien sur la page. Vient ensuite une ligne pour ce que l'hôte utilise, une ligne qui ouvre les cinq options, et une ligne pour le modèle. Chaque choix possède un bouton d'info qui liste cinq éléments : où va l'audio, s'il fonctionne hors ligne, ce qu'il coûte, la configuration requise et sa rapidité. Appuyer sur le bouton d'info ne sélectionne rien.
  • Synthèse vocale de l'hôte liste les cinq options de l'hôte. Whistle et votre propre commande conservent l'audio sur vos machines. Un service vocal et l'abonnement ChatGPT l'envoient hors de votre hôte. Off est isolé sous ces options. Une modification ici s'applique à chaque appareil associé à l'hôte. Un choix envoyant l'audio plus loin que celui qu'il remplace demande confirmation ; revenir en arrière s'applique dès l'appui. Chaque option comprend Comment configurer : des étapes numérotées, les commandes à copier, et les propres boutons de l'application là où elle peut agir. La prochaine étape à réaliser est marquée Suivant. Elle ne s'affiche ouverte d'elle-même que pour l'option utilisée lorsqu'elle ne fonctionne pas. L'option utilisée indique également ce qui est configuré, par exemple "Configuré : whisper-cli, modèle ggml-base.bin".
  • Modèle Whistle indique le créateur, Cactus Compute, la licence, et contient un lien vers la page du modèle sur Hugging Face. Il affiche la copie sur l'hôte et la copie sur ce téléphone, chacune avec son propre état.

Pour configurer Whistle :

  1. Sur un téléphone où la voix ne fonctionne pas encore, appuyez sur Configurer la voix sur ce téléphone dans la carte du haut sur Voice. Un seul appui effectue tout le parcours : l'hôte télécharge le modèle s'il ne l'a pas, ce téléphone le copie depuis l'hôte, et Sur ce téléphone est sélectionné. Une barre affiche la progression et indique l'étape en cours, « Téléchargement vers votre hôte… » ou « Copie vers ce téléphone… ». Si une étape échoue, le processus s'arrête là, indique la raison et propose Réessayer. Un appareil en lecture seule peut copier, car la copie est une lecture, mais il ne peut pas demander le téléchargement à l'hôte. Les deux mêmes étapes se trouvent aussi sous Modifier le fonctionnement vocal : Configurer (16,9 Mo) sur un téléphone sans copie, ou Copier sur ce téléphone quand l'hôte a déjà le modèle.
  2. Ou ouvrez Modèle Whistle et appuyez sur Télécharger sur l'hôte (16,9 Mo). Une barre affiche la progression. En cas d'échec, la page en indique la raison. Appuyez sur Réessayer. Quand le modèle est présent, la page affiche sa version (les sept premiers caractères de la révision Hugging Face, un lien vers cette révision) et sa taille. Détails affiche une courte somme de contrôle et la date à laquelle l'hôte l'a téléchargé.
  3. Pour la dictée via l'hôte, ouvrez Synthèse vocale de l'hôte et choisissez Whistle sur votre hôte, puis Modifier pour chaque appareil. Ou ouvrez Comment configurer en dessous et appuyez sur Utiliser sur l'hôte. Si vous configurez un autre fournisseur dans le terminal, avec une clé ou une commande, la page l'affiche et ne propose aucun choix. Les étapes de Whistle commencent alors par collie stt off sur l'hôte, puis collie stt whistle --host.
  4. Sur la copie de ce téléphone, Modèle Whistle indique la version et propose Supprimer de ce téléphone. Il indique aussi si le navigateur a accepté de conserver la copie (« Conservé ») ou s'il risque de la supprimer en cas de manque d'espace. Si l'hôte obtient plus tard un modèle plus récent, la copie le signale et propose Update.
  5. Sur Voice, ouvrez Modifier le fonctionnement vocal et choisissez Sur ce téléphone ou Sur votre hôte. Sur ce téléphone est désactivé tant que le téléphone n'a pas de copie. Sur votre hôte est désactivé tant que l'hôte n'a pas d'option vocale. La ligne sous le choix indique ce que l'hôte utilise.
  6. Pour supprimer le modèle de l'hôte, appuyez sur Supprimer de l'hôte sur Modèle Whistle et confirmez. Si Whistle était le moteur de l'hôte, la voix sur l'hôte s'arrête jusqu'à ce que vous le téléchargiez à nouveau.

Auteur de la modification. Quand un appareil associé modifie l'option de l'hôte depuis Paramètres, l'hôte enregistre le nom de cet appareil et l'heure. Voice et Synthèse vocale de l'hôte affichent alors « Dernière modification par Pixel 8 », avec l'heure. Une modification dans le terminal l'efface.

Ou configurez-le dans le terminal.

$ bin/collie stt whistle                 # fetch the model once
$ bin/collie stt whistle --host          # also make Whistle this host's engine
$ bin/collie stt whistle --from <path>   # use a copy you already have, same hash check
$ bin/collie stt whistle --remove        # remove the model, and the host engine if it is Whistle
$ bin/collie stt status                  # shows the model line

--host demande confirmation avant de remplacer un fournisseur que vous avez configuré intentionnellement. --yes répond à cette question pour une exécution sans terminal. La question précède le téléchargement, de sorte qu'une exécution refusée ne récupère rien. --remove ne touche pas à un fournisseur d'un autre type. collie stt off supprime le fournisseur et indique que le modèle reste. collie doctor avertit lorsque le modèle sur l'hôte n'est pas celui accepté par cette version. Le moteur est actif immédiatement, sans redémarrage. Vérifiez-le avec collie stt test.

Ce qui est téléchargé, et d'où. L'hôte récupère whistle.cact depuis une adresse Hugging Face figée, suit la redirection vers son CDN (au maximum cinq, en HTTPS uniquement, et jamais vers une adresse locale ou privée), et ne conserve le fichier que si son sha256 correspond au hachage inclus dans cette version. Une non-concordance supprime le fichier et signale les deux hachages. Le téléchargement est plafonné à 32 Mio avec un délai maximal de 10 minutes. Le fichier se trouve dans le dossier whistle du dossier d'état. Le code du moteur (environ 1 Mo) fait partie de chaque version de Collie et provient des propres fichiers de Collie.

Rien ne se télécharge tout seul. Pas à l'installation, pas lors d'une mise à jour, pas lorsque vous choisissez un moteur. Le modèle arrive lorsqu'une personne appuie sur Télécharger sur l'hôte, Configurer ou exécute collie stt whistle. Un téléphone le copie depuis l'hôte lorsque son propriétaire appuie sur Configurer, Copier sur ce téléphone ou Restaurer, et depuis nulle part ailleurs. L'hôte envoie le modèle à deux téléphones au maximum en même temps. Un troisième reçoit le message « réessayez dans un instant ».

Limites. Le moteur hôte prend un enregistrement de 4 minutes maximum, car un WAV fait environ quatre fois la taille de l'extrait compressé et la limite d'envoi reste fixée à 8 Mio. L'enregistreur affiche cette limite. Le moteur du téléphone prend jusqu'à 5 minutes. Le processus enfant de l'hôte a un délai fixé à la moitié de la durée de l'extrait, au moins 60 secondes et au plus 3 minutes, et au maximum deux extraits s'exécutent en même temps sur l'hôte. Un téléphone a besoin d'espace libre pour le modèle (il demande deux fois la taille du fichier) et d'une connexion sécurisée (HTTPS, comme le fournit tailscale serve).

Quand le téléphone ne peut pas le faire. Si Sur ce téléphone échoue sur un extrait, l'écran vocal en indique la raison et propose Envoyer à l'hôte, uniquement tant que l'hôte dispose d'un fournisseur vocal fonctionnel. L'extrait reste en mémoire, dans l'état d'échec, jusqu'à ce que vous appuyiez sur Envoyer à l'hôte ou que vous le rejetiez. Collie ne l'envoie jamais de lui-même, car vous avez choisi un moteur dont le principe est que l'audio reste sur place. Deux plantages du moteur au cours d'une même session désactivent Sur ce téléphone jusqu'au rechargement de l'application.

Lorsque la copie du téléphone a disparu. Un navigateur peut supprimer la copie pour libérer de l'espace. Le choix reste sur ce téléphone, et la dictée est mise en pause : Voice indique « Dictée en pause » et propose Restaurer, qui copie à nouveau le modèle depuis l'hôte. Le micro enregistre toujours, et l'extrait reste sur le téléphone avec Envoyer à l'hôte comme ci-dessus. Collie ne bascule pas vers l'hôte de lui-même. Pour utiliser l'hôte, choisissez Sur votre hôte.

Navigateurs. Ce téléphone nécessite un navigateur qui attribue au worker vocal sa propre politique de sécurité. Chrome sur Android est testé. WebKit est testé dans un build WebKit. Safari sur un iPhone n'est pas encore vérifié sur un appareil. Un navigateur incapable de l'exécuter affiche Sur ce téléphone comme désactivé avec la raison, et Sur votre hôte reste disponible.

Si vous utilisiez l'ancien wrapper. Les versions antérieures de cette page présentaient un wrapper local-cli autour d'un exécuteur natif, ffmpeg et jq. Cette configuration est abandonnée, mais rien ne modifie celle que vous possédez déjà, et elle continue de fonctionner. Pour passer au moteur intégré, exécutez bin/collie stt whistle --host --yes, ou exécutez collie stt off d'abord, puis bin/collie stt whistle --host. Vous pouvez aussi conserver le wrapper. Son fichier de modèle n'est pas réutilisé automatiquement. Passez-le avec --from <path> pour ignorer le téléchargement.

L'aspect sécurité de ce moteur, et la raison pour laquelle la configuration depuis Réglages est autorisée, se trouvent dans Sécurité et ADR 0096.

La prise en charge des conteneurs dépend du fournisseur

Le téléphone n'enregistre jamais en WAV. Il enregistre en Opus dans un conteneur WebM sur Chrome, Android et Firefox, ou en AAC dans un conteneur MP4 sur Safari et iOS, et envoie ces octets tels quels. Un fournisseur capable de transcrire le WAV peut quand même renvoyer une erreur 400 pour ces deux formats, et chaque dictée échoue alors avec la mention « refused » alors que stt test semble opérationnel. C'est pourquoi stt test envoie les trois extraits : le refus est détecté lors de la configuration, pas sur le téléphone.

Un cas concret, vérifié le 01/09/2026 avec POST /v1/audio/transcriptions d'OpenRouter :

formatmistralai/voxtral-small-24b-2507-sttopenai/whisper-large-v3-turbo
wavouioui
ogg/opusouioui
webm/opusnon, 400oui
mp4/m4a AACnon, 400oui

La solution de contournement réside dans le modèle, pas dans la clé : faites pointer la même clé OpenRouter vers openai/whisper-large-v3-turbo, qui accepte les quatre formats.

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

Une transcription refusée indique désormais le statut amont ainsi que le conteneur sous lequel elle a été envoyée, afin que l'erreur sur le téléphone précise le format rejeté par le fournisseur. (#148, merci @drewbitt)

Zéro sortie réseau : pointez vers votre propre moteur

La raison pour laquelle openai-compatible est le fournisseur à privilégier : indiquez-lui une URL de base locale et aucun enregistrement audio de la pièce ne quitte l'hôte. Deux moteurs fournissent un endpoint de transcription compatible OpenAI : le server intégré de whisper.cpp, et mudler/parakeet.cpp (MIT). Compilez ou installez l'un ou l'autre selon ses propres instructions, lancez-le sur la boucle locale (loopback) et faites pointer --url dessus :

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

C'est là toute l'intégration : Collie n'impose aucun choix de moteur.

Voxtral de Mistral ne nécessite aucun support dédié, et rien d'autre qui respecte ce contrat n'en a non plus : c'est le principe même de ce point de jonction. vLLM sert les modèles Voxtral aux poids ouverts sur /v1/audio/transcriptions, donc une instance locale se configure avec le même --url que n'importe quel autre moteur. Les modèles hébergés utilisent la même requête sur la base 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 prend en charge 13 langues et accepte le même champ ISO-639-1 language que Collie envoie déjà. Vérifiez-le avec collie stt test avant de vous y fier : la mention « compatible OpenAI » est une affirmation que chaque endpoint fait pour lui-même, et ce verbe existe pour la contrôler.

Le fournisseur codex : ce que vous acceptez

collie stt setup --provider codex affiche un bloc de consentement et s'arrête jusqu'à ce que vous saisissiez yes, car la réalité est la suivante : les enregistrements vont vers un endpoint ChatGPT non documenté et non pris en charge autorisé par la connexion votre, de sorte que votre compte ChatGPT supporte les limites de débit et le risque de bannissement, et cela peut cesser de fonctionner sans préavis.

Collie interroge cet endpoint d'abord sous son propre nom. C'est seulement si l'identité directe est refusée qu'il bascule sur les en-têtes de la CLI Codex ; ce mécanisme de secours est alors inscrit dans la configuration, sous un terme que collie stt status vous relit. Collie ne lit ni ne stocke jamais ~/.codex/auth.json ; le binaire auquel vous faites déjà confiance reste le seul à le manipuler.

Vous pouvez aussi le choisir dans Réglages. Ouvrez Paramètres → Voix → Reconnaissance vocale sur l'hôte sur un appareil disposant d'un accès en écriture. La page affiche ce que l'hôte utilise actuellement. Pour l'abonnement ChatGPT, elle affiche aussi l'identité enregistrée : honest, ou codex-cli lorsque le recours au repli a été nécessaire. La ligne Abonnement ChatGPT est accessible uniquement lorsque codex est installé sur l'hôte et connecté avec ChatGPT. Collie interroge codex login status pour le savoir. Sinon, la ligne en indique la raison en une phrase, et son Comment configurer signale l'étape suivante : installez Codex sur l'hôte, connectez-vous avec codex login, puis touchez Utiliser l'abonnement ChatGPT. Touchez la ligne, et un volet affiche le même consentement, mot pour mot, sous une ligne précisant que la modification s'applique à chaque appareil jumelé à l'hôte. Rien n'est envoyé à l'hôte tant que vous ne touchez pas J'accepte. L'hôte exécute ensuite la même vérification que collie stt setup, l'identité exacte d'abord, et écrit la même configuration. Si la vérification échoue, rien n'est écrit et le volet en explique la raison. Désactivé sur la même page supprime le fournisseur. Le terminal continue de fonctionner de la même manière.

Exécutez votre propre commande : le fournisseur local-cli

local-cli exécute une commande de transcription déjà installée, une fois par enregistrement, sans serveur HTTP intermédiaire :

bin/collie stt setup --provider local-cli \
  --command /Applications/Muesli.app/Contents/MacOS/muesli-cli --args transcribe
bin/collie stt test

Collie écrit l'enregistrement dans un fichier temporaire privé et exécute <command> [args…] <file>. Le chemin du fichier constitue toujours le dernier argument. Le stdout de la commande, nettoyé des espaces, correspond à la transcription.

paramètreoptionvariable d'environnementce que c'est
command--commandCOLLIE_STT_COMMANDUn chemin absolu, ou un nom présent dans PATH.
args--argsaucunLes arguments placés avant le chemin du fichier.

Un simple nom est résolu lorsque vous exécutez setup, et le chemin complet est enregistré. Le service s'exécute avec un PATH restreint, donc un nom trouvé par votre shell peut ne pas s'y résoudre. Un chemin relatif tel que ./whisper-cli est refusé.

--args prend des mots séparés par des espaces. Aucun shell ne les lit, les guillemets sont donc conservés tels quels. Un argument contenant un espace nécessite la forme JSON :

bin/collie stt setup --provider local-cli --command whisper-cli \
  --args '["-m", "/srv/my models/ggml-base.bin", "-nt"]'

Ce que la commande doit faire :

  • Être un fichier ordinaire que votre utilisateur peut exécuter. Un lien symbolique vers un tel fichier convient, car Collie le résout. collie stt setup refuse tout le reste, et collie stt status indique l'erreur.
  • Quitter avec le code de retour 0 et écrire la transcription sur stdout. Tout autre résultat fait échouer la dictée.
  • Se terminer en moins de 60 secondes. Collie interrompt alors la commande, ainsi que chaque processus qu'elle a lancé, avec SIGKILL.
  • Écrire au maximum 256 Kio sur stdout. Collie interrompt la commande dès qu'elle écrit davantage.
  • Ne rien laisser en cours d'exécution. Lorsque la commande se termine, Collie interrompt tout processus encore présent qu'elle a démarré. Un programme auxiliaire devant rester actif doit démarrer sa propre session, par exemple avec setsid.

Sous Windows, Collie arrête l'arbre complet des processus de la commande aux mêmes moments et, après une sortie normale, arrête tout processus démarré par la commande encore en cours d'exécution. Il reste un cas : un processus lancé par un auxiliaire ayant déjà quitté peut survivre à la commande.

Deux dictées au maximum exécutent la commande en même temps. Une troisième reçoit la réponse « occupé » déjà connue du téléphone, et Collie ne lance rien pour elle.

Un stdout vide est considéré comme un échec sur le téléphone, car rien ne peut être inséré dans le champ. collie stt test considère cela comme un succès, puisque ses extraits ne contiennent que du silence.

Remarque. La commande s'exécute avec le compte utilisateur du bridge, avec ses droits, une fois par dictée. Elle ne reçoit aucun shell, aucun stdin et aucune variable d'environnement COLLIE_*. Son stderr n'est jamais lu, et le téléphone ne voit jamais la ligne de commande ni aucun chemin, seulement l'échec de la commande et son code de retour.

Le fichier temporaire réside dans un dossier que seul votre utilisateur peut ouvrir, et Collie le supprime après chaque exécution. Si le bridge a été arrêté pendant un traitement, son prochain démarrage supprime ces dossiers lorsqu'ils ont plus d'une heure. L'acheminement ultérieur de l'audio dépend de la commande : un moteur local le conserve sur l'hôte.

Les explications détaillées de tout ce qui précède (pourquoi cela a été refusé deux fois, ce qui a changé et la raison de cette structure) se trouvent dans l'ADR 0029.

Web Push (facultatif)

Désactivé par défaut. La configuration nécessite trois étapes. La bibliothèque d'envoi (web-push) est incluse comme dépendance facultative lors de la compilation :

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

La commande push-keys génère la paire de clés et écrit COLLIE_VAPID_PUBLIC et COLLIE_VAPID_PRIVATE avec les permissions 600 dans le .env actif, à savoir ~/.config/collie/.env sur une installation binaire ou celui situé dans le dossier de configuration des plugins de Herdr sur une installation Herdr.

Passez une URI de contact en argument pour définir la revendication subject selon la RFC 8292 :

collie push-keys mailto:you@example.com

Sur les installations gérées par Herdr, ces deux étapes sont disponibles sous forme d'actions (herdr plugin action invoke push-keys --plugin herdr.collie et restart). Les actions Herdr n'acceptent pas d'arguments positionnels, donc la définition d'un subject nécessite d'exécuter la commande directement dans le shell.

Détails sur la gestion des clés :

La commande refuse d'écraser les clés existantes sauf si vous passez --force. Remplacer les clés invalide tous les abonnements actuels, obligeant chaque appareil à se réabonner avant de pouvoir recevoir à nouveau des notifications. Fournir un argument de subject sur une configuration existante met à jour uniquement l'adresse de contact et conserve les clés actuelles.

Remarque. Sur les versions de Herdr antérieures à 0.8.0, les actions restent figées à l'ensemble mis en cache lors de l'installation initiale du plugin (ADR 0006). Les actions push-keys et push-test n'apparaîtront pas tant que vous n'exécutez pas herdr plugin install. Exécutez plutôt bash scripts/collie-ctl.sh push-keys directement. Le script wrapper transmet la commande directement au binaire.

Testez le chemin de distribution sur tous les appareils abonnés :

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

La distribution prend une à deux secondes. Si la commande indique que le push est désactivé, redémarrez le service pour qu'il charge les clés générées. Si elle indique qu'aucun appareil n'est abonné, effectuez l'étape 3 dans le navigateur du téléphone.

Web Push nécessite un contexte sécurisé (HTTPS). Celui-ci est fourni par tailscale serve (certificats MagicDNS) ou par un reverse proxy externe terminant TLS (Variante C). Les configurations en HTTP brut (COLLIE_SERVE_MODE=http) n'ont pas de contexte sécurisé, et le navigateur désactive les contrôles d'abonnement dans Settings.

Collie envoie des notifications lorsqu'un agent entre dans l'état bloqué ou terminé, en plaçant le message de l'agent dans le corps. Sélectionner la notification mène directement à cet agent dans l'interface web.

Quelles alertes Collie envoie

Cinq types, chacun avec son propre commutateur sous Paramètres → Alertes → Notifier quand.

AlerteSe déclenche quandValeur par défaut
Action requiseun agent attend votre interventionactivé
Terminéun agent termine sa tâchedésactivé
Mises à jour de l'applicationune version plus récente de Collie est disponibleactivé
La charge de la machine reste élevéele CPU, la mémoire ou le disque le plus plein d'une machine reste au-dessus d'une règle définie pour celle-ciactivé
Cache sur le point d'expirerle cache de prompt d'un panneau expire dans environ cinq minutesdésactivé

Finished se déclenche lorsqu'un agent passe de l'état actif à l'état inactif ; un agent que vous interrompez est donc aussi considéré comme terminé.

La charge machine n'envoie rien tant que vous ne définissez pas de règle sur la page d'une machine. Le commutateur désactive toutes les règles en même temps. Une alerte est envoyée chaque fois qu'une valeur monte et reste élevée, et appuyer dessus ouvre la vue État de cette machine. Voir Machines.

Chaque appareil affiche le titre d'une alerte dans sa propre langue, et en anglais sur un appareil qui n'a pas ouvert Collie depuis sa mise à jour. Le corps reste tel que le pont l'a écrit.

Chaque interrupteur s'applique à tout le bridge. Un push est diffusé à chaque appareil abonné ; il n'y a donc rien à configurer par appareil.

L'avertissement de cache peut aussi être activé pour un panneau à la fois, depuis les paramètres propres à ce panneau : ouvrez le panneau, touchez le ⋮, puis Paramètres du panneau. Ces panneaux sont listés sous l'interrupteur global dans Paramètres, chacun avec un bouton Supprimer.

Les deux états se cumulent au lieu de s'écraser. Un panneau reçoit un avertissement lorsque l'interrupteur global est actif ou si le panneau figure sur cette liste. Désactiver l'interrupteur global ne réduit donc pas au silence un panneau surveillé manuellement.

Un panneau surveillé est averti une fois par cycle chaud. La requête suivante de l'agent décale l'échéance, et ce n'est qu'alors que le même panneau peut avertir à nouveau. Les heures calmes s'appliquent : un pont suspendu n'envoie rien, et une suspension qui s'achève à l'intérieur de la fenêtre prévient tout de même. Un panneau déjà froid n'est jamais averti, y compris un panneau qu'un basculement /model a refroidi alors qu'il restait du temps.

COLLIE_CACHE_WARN_SECONDS déplace la fenêtre, par défaut 300 secondes (configure.md).

Remarque. Cette alerte nécessite la lecture du cache de prompt. Elle ne couvre donc que les panneaux affichant un compte à rebours de cache, et aucun autre : le harness doit conserver une transcription lisible par Collie, et l'agent doit avoir effectué au moins un tour. La fenêtre à laquelle un panneau avertit réellement correspond au nombre de secondes configuré, ou à la moitié de la durée de vie du cache de ce panneau, selon la durée la plus courte. Un cache Claude d'une heure conserve la fenêtre complète de 300 secondes. Un cache de cinq minutes (Codex, OpenCode, pi et omp) avertit plutôt environ deux minutes et demie avant d'expirer.

Des abonnements obsolètes peuvent s'accumuler au fil du temps car les réinstallations sur l'écran d'accueil et les réinitialisations du service worker créent de nouveaux endpoints sans toujours renvoyer de code HTTP 410. Collie met à jour l'enregistrement lorsqu'un appareil se réenregistre. Vous pouvez afficher et supprimer directement les endpoints stockés :

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

Pushs émis par un agent durable

La fiche de question d'un agent durable peut envoyer une notification push à votre téléphone, et Collie limite le nombre de pushs émis par un même agent durable.

Le push indique "Permission needed in" suivi du nom attribué au panneau. Il ne reprend jamais le titre attribué par l'agent durable à la question. Un agent durable peut choisir ses termes : son titre (60 caractères au maximum) suit le nom de votre panneau après deux-points, et sa ligne (120 au maximum) constitue le corps. Ces termes modifient le contenu du push, mais jamais sa fréquence d'envoi.

PlafondLimiteAu-delà
Un volet3 pushs par minuteLa question s'affiche sur le téléphone et n'envoie aucun push
Un agent durable sur une machine10 pushs par minuteÀ l'identique
Un agent durable sur une machine30 pushs par heureUn push de synthèse, puis aucun push venant de cet agent durable pendant une heure

Le résumé indique "A durable agent on {host} is raising many asks", avec le nom de la machine pour host. Dans un équipage, il indique le membre. Le commutateur Needs input et la mise en veille bloquent aussi le résumé. Un plafond ne masque jamais une question : chaque question ouverte reste affichée sur le téléphone.

Collie envoie un push par question. Il mémorise chacune par machine, agent durable et appel d'outil ; ainsi, un agent durable qui redémarre et pose à nouveau la même question l'affiche sur le téléphone sans renvoyer de second push. Une question est oubliée une heure après sa clôture. La mémoire est stockée dans durable-asks.json dans le dossier d'état. Dans un équipage, le lead applique ces règles et conserve ce fichier, et le membre n'envoie aucun push pour ses propres questions (ADR 0100).

Modifier cette page sur GitHub

The rest of the documentation