Clients vocaux et bornes
Affichez un écran « que puis-je dire » dans la langue de la personne, construit à partir du hub plutôt que tapé à la main.
Liste des intentions auxquelles un hub répond et des phrases qui les déclenchent, depuis un client connecté, sans jeton d'API.
Un client connecté peut demander à son hub ce qu’on peut lui demander. Le hub répond avec toutes les intentions que ses compétences ont enregistrées, par langue, ainsi que les phrases qu’une personne prononce pour atteindre chacune d’elles.
La réponse passe par la session du client lui-même. Aucun jeton d’API, aucune connexion à un compte et aucun rôle dans l’espace de travail n’entrent en jeu. Un client vocal, une borne, un installateur ou un agent peut montrer à une personne quoi dire, ou confirmer qu’une nouvelle compétence répond, avec rien de plus que sa connexion.
Une intention est une chose qu’une compétence sait faire, par exemple current.weather. Interrogez un hub et il renvoie toutes ses intentions, regroupées par compétence, avec les phrases qui atteignent chacune d’elles, dans chaque langue. Tout client connecté peut poser la question, pourvu que sa connexion ait le droit de publier ovos.intent.list (et ovos.intent.describe, quand les phrases doivent être obtenues à part). Cela ne coûte rien de plus que la connexion elle-même. Un refus est une erreur de politique qui nomme le type de message; elle revient aussitôt, pas sous forme de délai dépassé. La solution se trouve dans les types de message de la connexion, dans le tableau de bord.
L’inventaire regroupe les intentions par compétence. Chaque intention comporte :
| Champ | Signification |
|---|---|
skill_id | La compétence qui a enregistré l’intention, par exemple thalovant-skill-weather.thalovant. |
name | Le nom de l’intention, par exemple current.weather. L’identifiant complet est skill_id:name. |
engine | La façon dont le hub la reconnaît. padatious reconnaît des phrases entières; adapt reconnaît des ensembles de mots-clés. |
enabled | Si le hub y répond en ce moment. |
phrases | Les phrases qui l’atteignent, classées par langue. |
Les phrases apparaissent telles que la compétence les a écrites. Un mot entre accolades est un emplacement que la personne remplit : what is the weather in {location} correspond à « what is the weather in Montréal ». Les intentions à mots-clés portent des ensembles de mots-clés plutôt que des phrases; elles sont donc listées sans phrases.
Voici une compétence météo qui parle anglais et français, sous la forme JSON qu’affichent les SDK et la commande thalovant intents --json :
{ "languages": ["en-us", "fr-fr"], "source": "intent-manifest", "denied": [], "skills": [ { "skill_id": "thalovant-skill-weather.thalovant", "languages": ["en-us", "fr-fr"], "intents": [ { "id": "thalovant-skill-weather.thalovant:current.weather", "skill_id": "thalovant-skill-weather.thalovant", "name": "current.weather", "engine": "padatious", "enabled": true, "phrases": { "en-us": ["what is the weather", "what is the weather in {location}", "how is it outside"], "fr-fr": ["quel temps fait-il", "quelle est la météo à {location}", "quelle est la météo"] } } ] } ]}source indique comment l’inventaire a été lu. intent-manifest porte des phrases par langue. engine-manifests est la solution de repli qui ne donne que les noms, décrite plus bas, et denied nomme la requête qui a déclenché ce repli.
Demandez chaque langue que vous voulez afficher. Les étiquettes de langue se comparent sans égard à la casse, et _ et - comptent comme le même caractère : fr-fr, fr_FR et fr-FR désignent une seule langue. Le hub répond avec l’étiquette qu’il a en mémoire; une demande pour fr-fr peut donc revenir étiquetée fr-FR.
Une compétence n’est listée que dans les langues qu’elle fournit. Une compétence qui a des phrases en anglais et aucune en français apparaît dans la liste anglaise et n’a pas de phrases françaises. Le hub n’enregistre que les langues que son runtime charge. S’il manque une langue entière, vérifiez les langues principale et secondaires dans Runtime.
Le hub répond à deux requêtes, et la connexion n’a besoin que de celles que son client envoie :
| Type de message | Ce qu’il fait | Quand le client l’envoie |
|---|---|---|
ovos.intent.list | Liste toutes les intentions enregistrées pour une langue. | Toujours. |
ovos.intent.describe | Renvoie l’enregistrement d’une intention, y compris ses phrases. | Seulement quand le client doit demander les phrases à part. |
Un client qui veut seulement savoir quelles intentions un hub a enregistrées n’a besoin que de ovos.intent.list : il obtient les noms, les moteurs et l’état d’activation, sans les phrases. Chaque SDK demande les phrases à moins que vous désactiviez cette option; en Python, le réglage est client.intents(["en-us"], describe=False).
Demander les phrases ne veut pas toujours dire envoyer ovos.intent.describe. Les SDK demandent au hub de joindre la définition de chaque intention à la liste elle-même, avec include_definitions. Un hub dont le runtime respecte cette option renvoie une liste qui contient déjà les phrases; aucune requête de description n’est alors envoyée, et la connexion n’a jamais besoin de ce second type. Le SDK ne se replie sur une description intention par intention que si la liste est revenue sans définitions, et c’est seulement dans ce cas que la connexion a aussi besoin de ovos.intent.describe.
Lequel des deux cas se produit dépend du runtime, et aujourd’hui aucun runtime livré ne joint les définitions. OpenVoiceOS garde volontairement sa liste sans définitions, et les hubs Thalovant utilisent un runtime construit à partir de ces mêmes sources. Un runtime qui ne reconnaît pas include_definitions l’ignore et renvoie la liste simple; le SDK décrit alors les intentions une par une. En pratique, la connexion a donc besoin des deux types. Autorisez les deux, à moins d’avoir mesuré le contraire; c’est ce que font les connexions de Thalovant elles-mêmes.
Les deux sont en lecture seule. Ils ne révèlent que des intentions que la connexion peut déjà déclencher; les autoriser n’ajoute donc aucun privilège. Les connexions que Thalovant crée pour les clients SDK et pour Thalovant Voice incluent les deux par défaut.
Pour les vérifier ou les modifier, ouvrez Connections dans le tableau de bord, sélectionnez la connexion et ouvrez ses paramètres d’accès. La liste des types de message que la connexion peut publier (allowedTypes dans la spécification du client) doit contenir chaque type que le client envoie. Ajoutez-les si la connexion a été créée avant l’arrivée de cette fonction, ou si son accès a été restreint à la main, puis reconnectez le client.
Une connexion qui n’a pas le droit de publier l’un des types ne reçoit pas de réponse. Le hub répond plutôt aussitôt hive.policy.denied, en nommant le type de message et les types que la connexion peut publier :
{ "denied_type": "ovos.intent.list", "code": "acl_disallowed_type", "reason": "ovos.intent.list not in allowed_types", "data": { "msg_type": "ovos.intent.list", "allowed": ["recognizer_loop:utterance", "speak"] }}Les SDK transforment cette réponse en erreur de politique typée dès qu’elle arrive, au lieu d’attendre un délai dépassé. L’erreur nomme le type refusé et porte code, reason et la liste allowed. En Python, c’est ThalovantPolicyDeniedError, et son message vous indique où corriger le problème :
The hub refused 'ovos.intent.list': ovos.intent.list not in allowed_types.Allow this connection to publish 'ovos.intent.list' in the dashboard's connection settings.Un refus n’est pas la seule réponse décevante. Le hub peut aussi répondre à une requête qu’il a acceptée avec ok: false et une erreur qui lui est propre, et les deux requêtes ne l’entendent pas de la même façon.
Quand ovos.intent.list répond par une erreur, c’est la liste qui a échoué. Le hub n’a pas dit ce qu’il a enregistré; les SDK lèvent donc leur erreur de runtime, qui porte le texte d’erreur du hub. Une liste qui a échoué n’est pas un hub vide, et la présenter comme une absence d’intentions montrerait à une personne un appareil qui ne peut rien faire. En Python, cela donne :
ovos.intent.list failed: intent manifest unavailableRedemandez une fois le hub en bonne santé. Si l’échec persiste, vérifiez l’état en direct du hub et son runtime dans Hubs.
Quand ovos.intent.describe répond par une erreur, c’est une réponse normale et vide : le hub ne connaît pas cet enregistrement. L’intention reste dans l’inventaire avec son nom, son moteur et son état d’activation, sans phrases. Aucune erreur n’est levée, et le reste de l’inventaire n’est pas touché.
Quand le hub refuse ovos.intent.list ou ne répond pas avant son délai, les SDK se replient par défaut sur deux requêtes plus anciennes, intent.service.adapt.manifest.get et intent.service.padatious.manifest.get. Celles-ci ne renvoient que les noms des intentions, sous la forme skill_id:intent_name, sans langue ni phrases.
Un résultat limité aux noms le signale. source vaut engine-manifests, denied liste ovos.intent.list, et aucune intention ne porte de phrases. C’est suffisant pour confirmer qu’une compétence s’est enregistrée; ce n’est pas suffisant pour montrer aux gens quoi dire. Quand les requêtes de repli sont refusées elles aussi, l’erreur de politique est levée.
Les SDK de haut niveau actuels utilisent tous ce repli quand la liste reste sans réponse. L’ancien champ denied nomme la requête non disponible; il ne prouve pas un refus de politique. Si les requêtes des moteurs dépassent aussi leur délai, l’opération lève l’erreur de délai du SDK. Les réponses et les refus qui portent un autre identifiant de requête ne peuvent pas compléter cette requête.
Désactivez le repli quand votre client doit échouer plutôt que fonctionner en mode dégradé. En Python, c’est client.intents(fallback=False).
Les phrases des intentions ne décrivent pas toutes les façons dont un hub peut répondre. Les SDK peuvent ajouter une sonde facultative de l’inventaire qui utilise ovos.skills.fallback.list pour les gestionnaires de repli et lit ovos.skills.fallback.list.response. Autorisez cette requête sur la connexion si vous voulez cette information. La sonde prend au plus 1,5 seconde, en tout, pour la connexion, l’envoi et l’attente de la réponse; une annulation par l’appelant arrête quand même l’opération.
fallbacks_known (ou son nom propre au langage) distingue une liste vide confirmée d’une prise en charge inconnue. Un refus, un silence, une enveloppe de réponse mal formée et une réponse d’échec explicite laissent la prise en charge inconnue. Un tableau de replis accepté produit une liste connue de gestionnaires utilisables; les lignes invalides sont ignorées. may_answer(lang) est prudent : il ne renvoie faux que si la découverte des replis a réussi sans aucun gestionnaire et qu’aucune intention activée n’a de phrases pour cette langue. Une prise en charge inconnue n’est pas une preuve que le hub ne peut pas répondre.
Python, Node, Kotlin, Swift et .NET ajoutent cette information à leur inventaire. Go et Rust gardent leur type d’inventaire existant et exposent une enveloppe de capacités additionnelle au moyen de IntentsWithCapabilities et intents_with_capabilities. La bibliothèque C embarquée fournit les trames de requête de repli et la classification des réponses; l’appelant implémente la sonde, la collecte des résultats et la décision de disponibilité.
Clients vocaux et bornes
Affichez un écran « que puis-je dire » dans la langue de la personne, construit à partir du hub plutôt que tapé à la main.
Installateurs
Confirmez qu’une compétence fraîchement installée répond, dans chaque langue que le runtime charge, avant de remettre le hub.
Agents
Laissez un agent lire ce que le hub sait faire avant qu’il choisisse une phrase, au lieu de deviner.
Tests
Vérifiez que le hub a enregistré les intentions que votre compétence fournit. Consultez Ajouter votre propre compétence.
Le SDK Python 0.4.36 et plus récent lit l’inventaire avec client.intents([...]), et la commande thalovant intents l’affiche :
thalovant --identity _identity.json intents --lang en-us --lang fr-frConsultez Lister ce qu’on peut demander au hub dans le guide du SDK Python. Les SDK Node.js, Go, Rust, Kotlin, Swift et .NET offrent les trois mêmes appels sous leur propre graphie, et la bibliothèque C embarquée construit et lit les deux trames. Chaque page de SDK les nomme et donne un exemple fonctionnel.
Les SDK gérés actuels et MCP peuvent rendre les motifs bruts des intentions sous forme de phrases. Activez l’option de phrases de l’outil d’exemples pour retirer les mots facultatifs, choisir parmi les variantes, insérer des valeurs d’exemple propres à la langue dans les emplacements, et ajouter les majuscules et la ponctuation. Les valeurs d’emplacement que vous fournissez remplacent les exemples. Les motifs d’intention d’origine restent disponibles.
Les exemples préfèrent les phrases complètes aux préfixes et aux motifs à emplacements. Les limites de rendu comptent les résultats uniques non vides. La correspondance régionale peut utiliser une langue régionale voisine enregistrée; elle ne traduit pas une compétence dans une langue qu’elle ne prend pas en charge. Les langues inconnues gardent le texte brut. Consultez les guides des SDK pour les versions et les exemples; en Python, il faut installer l’extra facultatif de listage.
| Symptôme | À vérifier d’abord |
|---|---|
Une erreur de politique nomme ovos.intent.list ou ovos.intent.describe | Ajoutez ce type de message aux types de message de la connexion dans le tableau de bord, puis reconnectez le client. |
Des noms mais aucune phrase, et source vaut engine-manifests | La connexion n’autorise peut-être que les requêtes de repli, ou la liste n’a reçu aucune réponse. Vérifiez que le runtime implémente la liste et autorise ovos.intent.list; autorisez ovos.intent.describe quand les phrases ne sont pas jointes. |
| La liste a échoué avec une erreur du hub | Le hub n’a pas pu lire son manifeste d’intentions. Ce n’est pas un hub vide. Vérifiez son état en direct dans Hubs, puis redemandez. |
| Une intention n’a pas de phrases | C’est une intention à mots-clés, le hub ne connaît pas cet enregistrement, ou sa description n’est pas arrivée à temps. Augmentez le délai ou demandez la description de cette intention seule. |
| Une langue entière manque | Vérifiez la configuration des langues du runtime et la découverte des replis. L’absence de phrases, à elle seule, n’exclut pas une réponse. |
| Une compétence manque | Vérifiez son état d’installation et son état en direct dans Skills. |
| L’appel dépasse son délai sans erreur de politique | Vérifiez que la connexion authentifiée est prête, que le runtime implémente la requête, et son budget de réponse. Consultez Connexions. |
L’inventaire est prêt à être montré quand :
skill_id attendu;source vaut intent-manifest et denied est vide;