ask
Envoyez une requête et recevez du texte, de la parole et des éléments d’affichage normalisés.
Installez le SDK Rust de Thalovant pour des clients stricts, du travail embarqué et des services fiables.
Utilisez le SDK Rust quand votre client a besoin de types forts, d’une faible surcharge ou d’un contrôle précis du runtime.
Le nom de la crate est thalovant.
Ajoutez la crate avec cargo add thalovant :
cargo add thalovantAjoutez @<version> quand vous avez besoin d’un build reproductible; la version courante
figure dans Versions prises en charge.
La connexion par appareil avec login_with_browser est disponible. MQTT sur TLS utilise le
magasin de confiance natif du système d’exploitation, tandis que HTTPS et WSS utilisent le
transport Rustls propre au SDK.
use thalovant::{ BootstrapIdentityOptions, Client, ControlPlane, HubProtocol, RequestOptions,};
#[tokio::main]async fn main() -> thalovant::Result<()> { let mut control = ControlPlane::default();
let result = control .create_client_identity_for_hub_id( "hub-id", BootstrapIdentityOptions { name: "rust-demo-client".into(), preferred_protocols: vec![HubProtocol::Wss, HubProtocol::Https, HubProtocol::Mqtt], ..Default::default() }, ) .await?;
let client = Client::with_protocol(result.identity.clone(), HubProtocol::Wss)?; let reply = client .ask("Tell me a short clean joke.", RequestOptions::default()) .await; let closed = client.close().await; let reply = reply?; closed?; println!("{}", reply.text);
Ok(())}ControlPlane::default() utilise https://api.thalovant.com.
Les comptes où l’authentification multifacteur (AMF) est activée doivent fournir un code TOTP ou un code de récupération à usage unique avec la connexion. Un simple appel à login est refusé avec le code HTTP 401 et le code mfa_required. Utilisez login_with_options; les champs ne sont envoyés que s’ils sont définis. La prise en charge de l’AMF exige le SDK v0.2.19 ou plus récent.
use thalovant::LoginOptions;
control .login_with_options( "password", LoginOptions { otp_code: Some("123456".into()), ..Default::default() }, ) .await?;Utilisez recovery_code: Some(...) au lieu de otp_code quand l’appareil d’authentification n’est pas disponible.
La connexion par appareil demande à votre navigateur d’approuver la connexion : les CLI, les services et les agents ne manipulent donc jamais votre mot de passe. Le SDK affiche un code court et l’adresse https://dash.thalovant.com/activate, ouvre cette page quand il le peut, puis attend que vous approuviez la demande dans le tableau de bord avec votre connexion habituelle, y compris la connexion Google ou l’AMF. Une fois la demande approuvée, le SDK détient un jeton d’API révocable et limité à des portées précises.
La connexion par appareil exige le SDK v0.2.20 ou plus récent. Approuver la demande exige un forfait payant pour l’espace de travail; un forfait gratuit reçoit le code HTTP 402.
use thalovant::DeviceLoginOptions;
let token = control .login_with_browser(DeviceLoginOptions { scopes: vec!["hubs:read".into(), "clients:write".into()], client_name: Some("my-tool".into()), ..Default::default() }) .await?;println!("signed in, token scopes: {}", token["scopes"]);Gérez le jeton obtenu sur la page API Tokens du tableau de bord.
Passez un jeton d’API enregistré quand le processus doit démarrer déjà authentifié, par exemple pour des tâches de CI et des services. Créez-en un sur la page API Tokens ou avec login_with_browser; la page affiche les portées, l’expiration et la dernière utilisation, et permet de révoquer le jeton en tout temps.
use thalovant::ControlPlane;
let token = std::env::var("THALOVANT_API_TOKEN").expect("THALOVANT_API_TOKEN is set");let control = ControlPlane::with_access_token(token);// Ready for authenticated calls, no login step needed.let hubs = control.list_hubs(Some(50), None, None).await?;use thalovant::{Client, RequestOptions};
let client = Client::from_config(Some("prod"))?;let reply = client .ask("What can this hub do?", RequestOptions::default()) .await;let closed = client.close().await;let reply = reply?;closed?;println!("{}", reply.text);Les fichiers d’identité bruts fonctionnent aussi :
use thalovant::{Client, RequestOptions};
let client = Client::from_file("_identity.json")?;let reply = client .ask("What can this hub do?", RequestOptions::default()) .await;let closed = client.close().await;let reply = reply?;closed?;println!("{}", reply.text);Les variables d’environnement fonctionnent aussi :
use thalovant::Client;
let client = Client::from_env()?;Le SDK exige Rust 1.88 ou plus récent et se connecte par WSS, HTTPS ou MQTT sur TLS. Chaque connexion est chiffrée et authentifiée avant l’envoi de quoi que ce soit.
Les transports exposent set_noise_state_dir pour le répertoire privé et persistant où le SDK garde ses clés et les identités de hub qu’il a enregistrées, ainsi que remote_static_key pour la clé du hub authentifié. Conservez ce répertoire quand vous redémarrez ou changez de transport pour la même identité. Utilisez des identités distinctes pour des clients simultanés; une connexion qui échoue ne supprime jamais une identité de hub enregistrée.
Les trois transports partagent un seul identifiant en cache par hub : changer uniquement le mot de passe de l’identité ne remplace donc pas un cache que le hub accepte encore. Une connexion refusée ou abandonnée l’élimine, si bien que la tentative suivante utilise le mot de passe actuel.
Pour vider ce cache à la main, appelez thalovant::forget_cached_psk(Some(state_dir.as_path()), &node_id)?, ou passez None pour le répertoire par défaut. La clé du client et l’identité de hub enregistrée restent intactes.
Définissez le répertoire avant de vous connecter. Par exemple, avec WSS :
use std::path::PathBuf;use thalovant::{Client, RuntimeTransport, WssTransport};
let transport = WssTransport::new(identity.clone());transport .set_noise_state_dir(Some(PathBuf::from("/path/to/private/persistent/sdk-state"))) .await;let client = Client { identity, transport: RuntimeTransport::Wss(transport) };HTTPS conserve les témoins (cookies) et refuse les redirections. with_options_and_http_client_builder permet à une application d’ajouter des autorités de certification privées de confiance tout en préservant ces exigences. MQTT exige TLS; utilisez set_tls_configuration pour une confiance personnalisée. Reconnectez-vous explicitement après la perte de la connexion au courtier (broker) et attendez que le client soit authentifié avant d’envoyer quoi que ce soit.
Utilisez de nouveaux identifiants de requête (request ID) pour Ask et de nouveaux identifiants d’interrogation (query ID) pour Query; les identifiants générés sont la valeur par défaut. Un collecteur concurrent qui porte le même identifiant est refusé sur le même client. Les espaces de noms sont indépendants. Les clients qui partagent un transport cloné partagent cette protection. Ne réutilisez pas un identifiant pour une opération logique ultérieure, même après une annulation : une réponse en retard peut encore le porter. Réutilisez un identifiant de session pour le contexte de conversation.
let identity = result.identity.clone();
println!("{:?}", identity.enabled_protocols());println!("{:?}", identity.endpoint_for(HubProtocol::Wss));println!("{:?}", identity.endpoint_for(HubProtocol::Https));println!("{:?}", identity.endpoint_for(HubProtocol::Mqtt));
for protocol in [HubProtocol::Wss, HubProtocol::Https, HubProtocol::Mqtt] { if !identity.supports_protocol(protocol) { continue; } if protocol == HubProtocol::Mqtt && identity.mqtt.is_none() { continue; }
let client = Client::with_protocol(identity.clone(), protocol)?; let reply = client .ask(&format!("Reply over {protocol:?}."), RequestOptions::default()) .await; let closed = client.close().await; let reply = reply?; closed?; println!("{protocol:?}: {}", reply.text);}MQTT exige les identifiants de courtier identity.mqtt retournés pour ce client.
Client::auto et les fonctions utilitaires de fichier, de configuration et d’environnement choisissent WSS, puis HTTPS, puis MQTT. L’ancien constructeur Client::new(identity) choisit HTTPS; utilisez Client::auto ou Client::with_protocol pour choisir un autre transport.
Pour les détails sur le courtier, consultez MQTT.
use thalovant::{build_client_context, ClientContextOptions, RequestOptions};
let context = build_client_context(None, ClientContextOptions { user_id: Some("user-42".into()), user_name: Some("Ada".into()), auth_provider: Some("oidc".into()), source: Some("checkout-kiosk".into()), platform: Some("kiosk".into()), locale: Some("en-US".into()), channel: Some("chat".into()), ..Default::default()});
let reply = client .ask( "Show the next instruction.", RequestOptions { context: Some(context), ..Default::default() }, ) .await?;use std::time::Duration;use thalovant::RequestOptions;use tokio::time::timeout;
let mut events = client.transport.subscribe();client .send_utterance("Say the current status.", RequestOptions::default()) .await?;
if let Ok(Ok(event)) = timeout(Duration::from_secs(12), events.recv()).await { println!("{} {}", event.name, event.text());}Un client connecté peut lister chaque intention à laquelle son hub répond, par langue, avec les phrases qu’une personne prononce pour atteindre chacune, dans sa propre session et sans jeton du plan de contrôle. Consultez Que peut-on demander à mon hub? pour savoir ce que le hub retourne, quels types de messages la connexion doit être autorisée à publier, et à quoi ressemblent un refus ou une liste en échec.
Depuis le SDK 0.3.0, les appels sont client.intents(languages, options).await, qui retourne l’inventaire regroupé par compétence, client.list_intents(lang, options).await, qui retourne les lignes d’enregistrement, et client.describe_intent(skill_id, intent_name, lang, options).await, qui retourne les définitions derrière une intention.
use thalovant::{Client, IntentInventoryOptions, ThalovantError};
let client = Client::from_file("_identity.json")?;let result = client .intents(["en-us", "fr-fr"], IntentInventoryOptions::default()) .await;let closed = client.close().await;match result { Ok(inventory) => { println!("{:?} {:?}", inventory.source, inventory.languages); for skill in &inventory.skills { for intent in &skill.intents { println!("{} {:?}", intent.id(), intent.examples(Some("fr-fr"), 2)); } } } Err(ThalovantError::PolicyDenied { denied_type, allowed, .. }) => { eprintln!("refused {denied_type}; allowed {allowed:?}"); } Err(error) => return Err(error),}closed?;intents interroge ovos.intent.list une fois par langue, puis complète les phrases que la liste ne contenait pas, par lots de DESCRIBE_BATCH requêtes, pour qu’un hub qui compte des centaines d’intentions ne reçoive jamais toute la rafale d’un coup. IntentInventoryOptions porte l’échéance et les options : describe: false s’arrête aux noms, aux moteurs et à l’état d’activation. examples(lang, limit) préfère les phrases complètes à celles qui contiennent un {slot}, puis les formulations plus complètes jusqu’à huit mots; phrases_for(lang) les retourne toutes, et l’inventaire se sérialise dans le même JSON que celui qu’affichent les autres SDK. Les étiquettes de langue se comparent sans tenir compte de la casse ni de _ et - : fr-fr et fr_FR forment donc une seule requête.
Un hub qui refuse une requête retourne immédiatement ThalovantError::PolicyDenied avec denied_type, code, reason et allowed. Avec la valeur par défaut fallback: true, un ovos.intent.list refusé ou silencieux retourne plutôt les noms seulement : source vaut IntentInventorySource::EngineManifests, denied nomme la requête indisponible sans prouver un refus de politique, et has_phrases() est faux. Un hub qui accepte la liste et y répond avec ok: false est un cas différent : depuis la 0.3.1, cela retourne ThalovantError::Runtime avec le texte d’erreur du hub, parce qu’une liste en échec n’est pas un hub vide. describe_intent continue de retourner une liste vide pour la même réponse, qui est une vraie réponse : le hub ne connaît pas cet enregistrement.
ask
Envoyez une requête et recevez du texte, de la parole et des éléments d’affichage normalisés.
conversation
Gardez les tours de parole liés dans une même session.
send_action
Envoyez une action structurée à partir d’un appareil, d’une interface ou d’une commande de service.
send_code
Envoyez une valeur numérisée, un numéro de série, une valeur de code QR ou un code saisi.
Pour la liste complète des méthodes, consultez Fonctions des SDK.
Utilisez control.get_operation(operation_id) pour suivre une commande acceptée; consultez Opérations.
Depuis le SDK v0.2.22, le plan de contrôle peut créer des hubs, des groupes de runtime et des installations de compétences. Parcourir le catalogue avec list_marketplace_skills exige hubs:read et fonctionne avec tous les forfaits. create_hub, create_runtime_group, install_runtime_group_skill, release_hub et release_runtime_group exigent hubs:write et un forfait payant.
let group = api.create_runtime_group(json!({"name": "kiosks"})).await?;let hub = api .create_hub(json!({"name": "joke-garden", "runtime_group_id": group["id"], "spec": {}}), None) .await?;
let hub = api.get_hub(hub["id"].as_str().unwrap_or_default()).await?;let etag = hub["etag"].as_str().unwrap_or_default();api.update_hub(hub["id"].as_str().unwrap_or_default(), json!({"active": false}), etag).await?;update_hub et delete_hub prennent l’etag actuel du hub comme argument obligatoire. Consultez Provisionner des hubs pour le flux complet, les champs immuables et le tableau des erreurs.
| Symptôme | Vérification |
|---|---|
| Jeton d’accès manquant | Appelez control.login(...) ou control.login_with_browser(...) avant les actions privées de l’API, ou utilisez ControlPlane::with_access_token(...). |
HTTP 401 avec le code mfa_required | Utilisez control.login_with_options(...) avec un otp_code ou un recovery_code. |
| L’accès à l’API exige un forfait payant | Passez l’espace de travail à un forfait supérieur avant de provisionner des ressources privées par l’API. |
| Protocole non pris en charge | Activez ce protocole sur le hub et créez une nouvelle identité. |
| MQTT échoue immédiatement | Vérifiez que l’identité possède les identifiants de courtier identity.mqtt. |
Le résultat de intents reste compatible. Utilisez intents_with_capabilities pour les gestionnaires de repli et une vérification prudente de la langue :
use thalovant::IntentInventoryOptions;
let result = client.intents_with_capabilities(["en-us"], IntentInventoryOptions::default()).await;let closed = client.close().await;let capabilities = result?;closed?;println!("{:?}", capabilities.inventory.source);println!("{}", capabilities.may_answer("en-us"));Les fenêtres de description d’intentions partagent un seul délai d’attente pour l’envoi et la collecte des réponses. Quand ce budget expire, les définitions déjà obtenues restent disponibles et aucune fenêtre suivante n’est envoyée. La connexion initiale, les listes par langue et la sonde de repli facultative ont des budgets distincts.
fallbacks_known distingue une découverte inconnue d’une liste vide confirmée. list_fallbacks(timeout) expose directement la requête facultative. Son plafond de 1,5 seconde inclut la connexion, l’envoi et l’attente de la réponse. Consultez la découverte des gestionnaires de repli.
ask_with_options(text, AskOptions) ajoute reply_settle (250 ms par défaut) et empty_reply_wait (cinq secondes) tout en préservant les littéraux RequestOptions existants. Ask et Query utilisent une seule échéance pour la connexion, l’envoi et la collecte des réponses. Un échec d’intention non bloquant peut se rattraper avec de la parole; un refus de politique reste un échec, et toute parole partielle est conservée.
Les clés enregistrées utilisent des verrous de processus bornés et une publication atomique sur un système de fichiers qui prend en charge les liens physiques et le renommage atomique. Conservez les clés enregistrées après une erreur. L’annulation et le nettoyage d’une connexion gardent la propriété de la génération qui se retire jusqu’à ce que son travail soit arrêté.
Les redirections du plan de contrôle sont refusées. Les appels authentifiés à l’API et les corps de requête exigent HTTPS, sauf pour les points de terminaison de développement en boucle locale (loopback) explicites. Consultez Sécurité des identifiants d’API.
wait_for_event(name, ListenOptions) attend un événement, avec une échéance totale par défaut de douze secondes. listen(name, ListenOptions) retourne un EventStream; appelez recv().await pour obtenir un Result<Option<Event>>. Définissez au besoin timeout, max_events, session_id, request_id et un predicate rapide et non bloquant. Un identifiant de requête correspondant a priorité sur une session de hub réécrite.
Chaque flux possède un abonnement borné. Un débordement ou une perte d’authentification retourne une erreur. Abandonnez le flux (drop) ou appelez close() pour vous désabonner sans fermer le client partagé. Annuler un futur recv laisse le flux utilisable; abandonner un futur wait_for_event libère son abonnement.
Le SDK peut lister, installer, mettre à jour et retirer les compétences du groupe de runtime d’un hub, et en consulter l’historique. Chaque hub qui partage ce groupe de runtime est touché. L’UUID d’un hub sélectionne le groupe; il ne crée pas d’installation isolée pour ce hub. Un jeton restreint doit couvrir tous les hubs servis par le groupe.
Les lectures exigent hubs:inspect (hubs:read l’inclut). Les écritures exigent hubs:write,
un forfait payant admissible et la propriété. Utilisez latest ou une version publiée précise
pour l’installation et les mises à jour. Une écriture acceptée retourne un operation_id;
l’acceptation ne signifie pas que le runtime a fini d’installer la compétence.
| Action | Méthode |
|---|---|
| Lister | list_hub_skills |
| Historique | list_hub_skill_history |
| Installer | install_hub_skill |
| Mettre à jour | update_hub_skill |
| Retirer | remove_hub_skill |
L’historique retourne l’enveloppe JSON de l’API avec des entrées event et operation
de la plus récente à la plus ancienne, en préservant les champs acteur/version qui peuvent être nuls. La limite va de 1 à 200.
Utilisez HubSkillWaitOptions pour choisir d’attendre la fin de l’opération (120 secondes, avec une interrogation toutes
les deux secondes par défaut). Pour les appels sensibles à l’annulation, soumettez d’abord sans
attendre, conservez la réponse acceptée, puis appelez wait_for_hub_skill_operation.
Annuler l’attente n’annule pas l’opération acceptée par le serveur. En cas d’échec de l’interrogation,
l’erreur conserve l’identifiant de l’opération; examinez cette opération au lieu de répéter
l’écriture. L’échéance d’attente annule aussi une requête d’état en cours.
Les indications de requête transmettent une langue reconnue, un pipeline d’intentions ordonné et l’emplacement de l’appelant sans modifier le contexte de l’appelant. Les indications vides sont omises. La fonction d’emplacement exige une ville et omet les coordonnées invalides ou nulles (zéro/zéro). Le hub valide les indications de langue en fonction des langues configurées.
Les réponses exposent la langue déclarée, les événements de parole et d’audio ordonnés et le
nombre de médias abandonnés. Les extraits audio intégrés des compétences sont limités à 4 Mio chacun et à
16 Mio par réponse, vérifiés avant la conservation et le décodage. L’audio ne prolonge pas
la fenêtre de stabilisation de la réponse. Le décodage accepte des octets hexadécimaux séparés par des
espaces blancs ASCII; il ne récupère jamais une URL ou un chemin de fichier fourni par une compétence.
La lecture relève de l’application. Toute fonction play ou Play ci-dessous appartient à votre application.
let location = thalovant::build_location(&thalovant::LocationOptions { city: "Montréal".into(), country: "CA".into(), ..Default::default()});let reply = client.ask_with_hints("Quel temps fait-il ?", Default::default(), thalovant::RequestContextOptions { stt_lang: Some("fr-ca".into()), location, ..Default::default()}).await?;for event in reply.media_events() { if event.is_audio() { let bytes = event.audio_bytes()?; /* play bytes */ } }let examples = intent.examples_with_options(Some("en-us"), 2, true, &Default::default());api.update_runtime_group_config(group_id, delta, None).await?;// Explicit full replacement:api.replace_runtime_group_config(group_id, full_config, None).await?;La fusion protégée exige les portées hubs:read et hubs:write et un forfait payant.
La fusion sûre exige une API dont le GET de configuration retourne une revision valide
et dont le PUT de configuration vérifie expected_revision. Le SDK relit et
réapplique le delta d’origine seulement après un HTTP 412, avec au plus trois tentatives.
Les tableaux et les valeurs scalaires remplacent; les objets fusionnent récursivement. Les personas ne sont remplacés
que s’ils sont fournis explicitement. Les échecs de connexion, les redirections, les autres statuts
et les résultats d’écriture ambigus ne font jamais l’objet d’une nouvelle tentative. Aucun repli PATCH non sûr n’est utilisé.
Les remplacements inconditionnels doivent tout de même être coordonnés avec les autres rédacteurs.
Utilisez l’opération de remplacement explicite montrée ci-dessus quand un remplacement complet est voulu, y compris avec une API plus ancienne. Le code existant qui compte sur le remplacement doit l’activer explicitement lors de la mise à jour. Les motifs d’intention bruts restent la valeur par défaut; les exemples prononçables retirent les parties facultatives, choisissent des variantes et substituent les emplacements (slots) fournis par l’appelant tout en conservant la priorité des phrases complètes.
Les limites audio utilisent des bornes supérieures basées sur la longueur encodée avant le décodage : les
espaces blancs de mise en forme consomment donc aussi le budget. Comme avec bytes.fromhex de Python, des espaces blancs ASCII
seuls se décodent en zéro octet. Les extraits malformés bornés restent disponibles comme métadonnées
d’événement et échouent au décodage; ils ne sont jamais récupérés ni lus automatiquement.
Des événements audio distincts peuvent répéter volontairement un contenu sonore identique. Seule
la livraison répétée du même objet d’événement est supprimée, là où l’identité des objets
est disponible, sans la compter comme un extrait abandonné. Le classement des exemples rendus
utilise la présence d’emplacements dans le motif d’origine, même quand des valeurs d’exemple sont fournies.
Les fusions protégées préservent les entiers natifs signés et non signés de 64 bits. Les valeurs à virgule flottante dans la configuration, les personas ou la configuration stockée doivent être finies et se situer dans l’intervalle ±9 007 199 254 740 991. Les valeurs plus grandes échouent avant l’écriture, car le décodage pourrait avoir arrondi un entier au-delà du stockage natif. Utilisez des identifiants sous forme de chaîne pour les entiers qui dépassent le stockage natif.
Disponible depuis la 0.8.1.
Les listes de phrases utilisent les données intégrées de thalovant-languages 0.2.1 et correspondent à Python
0.6.8 avec son extra de liste. Le choix de la langue suit les distances régionales d’OVOS :
une requête pour fr-CA peut donc utiliser des paramètres régionaux fr-FR enregistrés.
use thalovant::{as_sentence, IntentExampleOptions};let options = IntentExampleOptions { sentence: true, ..Default::default() };let examples = intent.examples_with_listing(Some("fr-CA"), 2, &options);let text = as_sentence("what time is it", Some("en-US"));Le rendu en phrase implique le rendu prononçable. Les valeurs d’emplacement explicites remplacent les exemples régionaux. Les phrases complètes passent avant les préfixes et les motifs à emplacements; les exemples rendus vides ou en double ne comptent pas dans la limite. Les exemples bruts sans limite gardent l’ordre d’enregistrement. Les paramètres régionaux inconnus conservent le texte brut et les noms d’emplacements.
Les méthodes d’exemples existantes restent disponibles. Utilisez ListingRules pour fournir un
instantané complet de données personnalisées ou pour choisir un rendu brut sans données régionales.
Aucune requête réseau n’est nécessaire pour charger les règles intégrées. Consultez le README du dépôt
pour la construction de règles personnalisées et la gestion des erreurs d’expressions régulières.
Les données de liste décrivent maintenant 270 langues, y compris les variantes régionales.
En espagnol, qué hora es devient Qué hora es?, et en français, coupe le son
devient Coupe le son.. Les langues sans règles, comme tlh, restent brutes.
HubSession possède une connexion de hub réutilisable. Fournissez une fabrique qui retourne un
client connecté et qui nettoie une tentative de connexion échouée ou annulée. Les abonnements
aux événements survivent au remplacement du client. Go et Rust exposent un flux d’événements
persistant; les autres SDK gérés exposent des descripteurs d’abonnement. Fermez la session
quand son propriétaire s’arrête; la fermeture attend les opérations acceptées et est définitive.
Les tentatives de connexion en arrière-plan attendent 10, 20, 40, 80, puis 120 secondes entre elles. Les appels au premier plan peuvent tenter immédiatement. Votre application gère la planification des sondes : utilisez le délai de sonde indiqué (60 secondes quand la connexion est retenue, 5 secondes quand elle est coupée). Le SDK ne rejoue jamais un Ask ou un Emit accepté après la perte d’une réponse, parce qu’un Ask peut déclencher une action. Le délai d’attente d’une requête s’applique à l’opération sous-jacente; l’attente de la session et votre fabrique de connexion ont des budgets distincts.
use thalovant::{HubSession, HubSessionPolicy, AskOptions};let session = HubSession::new(connect_client, HubSessionPolicy::default())?;let result = session.ask("What is the weather?", AskOptions::default()).await;session.close().await?;let reply = result?;Inventory, Skill et Intent offrent une vue présentable distincte de
l’inventaire d’intentions natif du runtime. Les paramètres régionaux inconnus du catalogue restent inconnus;
des phrases observées pour une langue ne prouvent pas que le catalogue la prend en charge. Les exemples choisissent
les paramètres régionaux pris en charge les plus proches. Une limite non positive retourne l’ensemble brut des phrases
(Rust utilise zéro pour sa limite non signée). Le JSON du cache inclut l’ordre explicite des langues
des intentions, pour que la sérialisation ne puisse pas changer la langue par défaut des exemples.
InventoryCache est facultatif, utilise par défaut une durée de vie (TTL) d’une heure et signale une absence dans le cache pour
les données invalides, expirées ou illisibles. Les écritures utilisent des fichiers temporaires privés et uniques
et un remplacement atomique. Sous POSIX, les fichiers de cache sont lisibles et modifiables par leur propriétaire seulement; Windows
utilise les ACL du répertoire de l’utilisateur. Les clés de cache séparent le mode, le chemin de l’identité et le nom d’hôte complet et normalisé du hub.
N’utilisez jamais les caches d’inventaire pour stocker des identifiants.
OriginPreference donne à une adresse privilégiée son propre budget de connexion court et
la met en pause après un échec. Dans les SDK autres que Python, la fabrique doit implémenter la
liaison à l’adresse sur son propre transport, conserver l’hôte public pour TLS/SNI et
terminer le nettoyage des tentatives échouées avant de retourner. Les restrictions du transport et de la plateforme
s’appliquent toujours. Cette fonction ne modifie pas le DNS global et ne désactive pas la validation TLS.
Une réponse expose reply.pipeline_ids(), reply.skill_ids() et reply.claimed().
Les identifiants de pipeline et de compétence sont des chaînes non vides, dans l’ordre de première apparition, sans doublons. Une réponse réussie dont les identifiants de pipeline contiennent tous le texte fallback (sensible à la casse) est signalée comme non revendiquée. Toute étape autre qu’un repli rend une réponse réussie revendiquée. Les réponses réussies de hubs plus anciens, sans marques d’étape, restent revendiquées. Les réponses en échec ou non traitées ne sont jamais revendiquées. Les marques malformées qui ne sont pas des chaînes sont ignorées.
Utilisez cette information comme indice pour décider de poursuivre ou non une conversation. Le texte de repli et le statut de réussite existant sont conservés. Ces marques ne constituent pas une identité de pair vérifiée et ne doivent pas autoriser d’actions.