Playbooks
Un playbook est un ensemble de tâches qui mène à un résultat : les tâches qu'une sélection doit couvrir avant d'être soumise, l'ordre dans lequel elles s'ouvrent, les choix entre plusieurs façons de faire une tâche, et les tâches qui ne valent que pour certaines sélections.
playbooks:
- name: open-company
goal: "ouvrir une société : la structure, puis (option) la comptabilité"
tasks:
formation: {skill: formation, label: "Votre société"}
accounting: {skill: accounting, required: false, label: "Votre comptabilité", after: [formation]}
- name: take-meal-order
goal: "commander un repas : les plats, puis le retrait ou la livraison"
tasks:
plats: {skill: takeMealSelection, label: "Vos plats"}
remise:
label: "Retrait ou livraison"
after: [plats]
one_of: # deux méthodes, une skill : chacune est un de ses kinds
retrait: {skill: takeDeliveryOption, kind: pickup}
livraison: {skill: takeDeliveryOption, kind: delivery}
choose: customer # la personne choisit (le défaut)
Le but et les tâches
goalest le résultat auquel mène le playbook, en une phrase. C'est ce que l'agent voit pour le proposer (start_playbook, son brief). Absent, c'est le nom du playbook qui s'affiche.taskssont rangées par nom : le nom que citentafter,all_ofet$submitted[<tâche>.<appel>], jamais celui de la skill.
Une tâche s'écrit sous une seule de ces trois formes :
| forme | sens |
|---|---|
{skill: x}, ou {skill: x, kind: k} | l'action d'une skill ; avec kind, d'un seul kind de cette skill |
{one_of: {méthode: {skill, kind, when, params}}, choose: …} | plusieurs méthodes ; une seule fait la tâche |
{all_of: [a, b]} | faite quand a et b sont faites ; un point de rendez-vous pour after |
Et sur la tâche :
| clé | sens |
|---|---|
when | la tâche ne vaut que si cette condition tient (Les conditions) — sur toutes les formes |
required | le playbook ne peut pas être soumis sans elle — vrai par défaut. Pas sur un all_of |
label | le titre de la tâche tel que la personne le lit, dans sa langue : dans le stepper et en tête de ses lignes dans la sélection. Absent, c'est le nom de la skill rendu lisible, en anglais. Pas sur un all_of |
after | les tâches qui doivent être faites avant que celle-ci s'ouvre. Pas sur un all_of |
params | lie des paramètres de sa skill à ce qu'une autre tâche a déposé (Les params d'une tâche). Sur la forme {skill} et sur chaque méthode d'un one_of ; jamais sur le one_of lui-même ni sur un all_of |
Un all_of n'est pas une étape : il n'a ni titre, ni place dans le stepper, ni ligne à lui, et
il ne bloque jamais le submit. Chaque tâche qu'il nomme dit elle-même si elle est requise.
Une skill est l'action d'une seule tâche d'un playbook : c'est par sa skill qu'une carte
retrouve sa tâche. Deux méthodes d'un même one_of peuvent partager une skill, à condition que
chacune nomme son propre kind. Deux playbooks peuvent donner le même nom de tâche ; seul un
$submitted[…] écrit sur l'appel d'une skill, qui vaut pour toute la station, refuse un nom qui
désigne deux appels différents (Le submit).
Choisir une méthode — choose
Un one_of a au moins deux méthodes. Chacune est l'action d'une skill (skill), ou d'un seul
de ses kinds (kind), et peut porter un when. Une seule méthode fait la tâche.
| valeur | qui choisit |
|---|---|
customer (défaut) | la personne, parmi les méthodes dont le when tient. L'étape les présente, chacune avec l'outil qui la montre ; l'agent est invité à appeler l'un ou l'autre, selon ce que la personne demande |
rule | la première méthode dont le when tient. Les lignes des autres sont refusées. Si la skill de cette méthode est retirée de la station, la tâche n'a pas de méthode : elle est sautée, la méthode suivante n'est pas prise à sa place |
Une méthode sans when est obligatoire : elle vaut toujours, donc la tâche a toujours une
méthode. Sous rule, c'est la dernière.
Les conditions — when
Un when, sur une tâche ou sur une méthode, lit une seule chose : $selection.kinds, les kinds
des lignes encore dans la sélection et de ce que ce parcours a déjà déposé. Il s'y lit comme une
liste, à droite de in ou not in :
emballage:
skill: gift-wrap
required: false
when: "'gift' in $selection.kinds"
- Une tâche dont le
whenest faux est sautée : elle n'est pas une étape, ne bloque jamais le submit, et ses lignes sont refusées. Les tâches placéesafterelle ne l'attendent pas. Si la condition ne peut pas être évaluée, la tâche vaut. - Une méthode ne vaut que si son
whenest vrai. - Un
whenne regarde pas les kinds de sa propre tâche : la ligne d'une tâche n'est pas encore choisie quand on l'ajoute, la condition la fermerait pour toujours. On conditionne une tâche sur ce qui vient avant elle.
Les params d'une tâche
Une skill lit ses paramètres ($params.<nom>) dans les args de ses appels de submit. Une tâche
lie un paramètre de sa skill à ce qu'une autre tâche du même playbook a déposé :
$submitted[<tâche>.<appel>].<sortie>.
skills:
- name: repondre
params:
refund_id: {} # pas de default : seule une tâche le fixe
invoke: {method: draftReply}
kinds: {reply: {}}
submit:
- {name: send, tool: sendReply, args: {body.draft: "$item.ref", body.refund_id: "$params.refund_id"}}
playbooks:
- name: ticket
tasks:
geste:
label: "Geste"
one_of: # chaque méthode a un appel `pay` qui garde `id`
remboursement: {skill: rembourser}
avoir: {skill: avoir}
reponse:
skill: repondre
label: "Réponse"
params: {refund_id: "$submitted[geste.pay].id"}
- La référence fait l'ordre.
reponseattendgeste, comme siafter: [geste]était écrit : une ligne dereponseest refusée tant quegesten'est pas faite (« Réponse : il faut d'abord terminer Geste »). - Une liaison se lit dans son propre playbook. Deux playbooks peuvent donner le même nom à des tâches différentes : chacun lit les siennes.
- Un choix est une seule référence. Les deux méthodes de
gesteont chacune un appelpay:$submitted[geste.pay]lit celle qui a été déposée. - Au submit, l'appel de
reponsepart après celui degeste, dans le même submit, avec sa réponse. Hors de ce playbook, le paramètre vaut sondefault; ce que fait le submit quand rien ne le fixe est dans Le submit.
Comment il s'ouvre
auto_triggersur une skill : s'en servir ouvre le playbook.start_playbook: l'agent l'ouvre lui-même, quand il juge que c'est le bon parcours.
C'est l'agent qui choisit. Un playbook sans auto_trigger est signalé au chargement (« seulement
joignable par start_playbook »).
Ce qu'il garantit
-
Une tâche est faite quand la sélection contient un item d'un kind de ses méthodes qui valent (le
kindd'une méthode, sinon tous les kinds de sa skill). C'est lu dans la sélection, jamais dans la conversation : la personne peut s'interrompre et revenir. Une tâche sautée compte comme faite pour celles qui l'attendent ; unall_ofest fait quand chaque tâche qu'il nomme l'est. Un choix qui contient deux méthodes, ou une méthode écartée, n'est pas fait : le parcours reste sur lui. -
L'ordre et les choix, à chaque choix (
step_open). Tant que le playbook est actif, une ligne est refusée, avec la raison, dans la langue de la station, et rien n'est écrit, quand :- une tâche de son
aftern'est pas faite : « Votre comptabilité : il faut d'abord terminer Votre société » ; - sa tâche ne vaut pas pour cette sélection : « emballage ne s'applique pas à cette sélection » ;
- elle est d'un kind de la skill que sa tâche ne prend pas (
kind) : « Retrait ne prend pas ce choix » ; - sa méthode ne vaut pas : « livraison n'est pas possible pour Retrait ou livraison avec cette sélection » ;
- sous
choose: rule, une autre méthode est retenue : « Retrait ou livraison se fait par retrait avec cette sélection » ; - une autre méthode de la tâche est déjà dans la sélection : « Retrait ou livraison : retrait est
déjà dans votre sélection — retirez cette ligne pour prendre livraison ». Un ajout qui remplace
l'autre méthode dans sa part (
max_items: 1) passe : l'ordre se vérifie sur la sélection telle que l'ajout la laisse.
Ce que ce parcours a déjà déposé compte comme choisi. Dans le stepper, une tâche qui attend est indiquée non disponible, avec les kinds qui manquent. Une tâche attend aussi les tâches que lisent ses
params. Sansafterniparams, les tâches se font dans n'importe quel ordre. - une tâche de son
-
Le submit est bloqué, avec la raison :
-
tant qu'une tâche
requiredqui vaut n'est pas faite : « Retrait ou livraison : étape requise de cette commande — ajoutez d'abord pickup ou delivery » ; -
tant que la sélection garde une ligne que le submit ne doit pas déposer — choisie avant l'ouverture du parcours, ou rendue fausse par un choix suivant :
- une ligne d'une tâche qui ne vaut plus (son
whenest devenu faux après le choix : le retrait a remplacé la livraison pour laquelle on avait écrit un message au livreur) : « Message au livreur ne s'applique pas à cette sélection » ; - une ligne d'un kind que sa tâche ne prend pas : « Retrait ne prend pas ce choix » ;
- une méthode écartée par la règle ou par son
when: « Retrait ou livraison se fait par retrait avec cette sélection », « livraison n'est pas possible pour Retrait ou livraison avec cette sélection » ; - deux méthodes d'un même choix : « Retrait ou livraison : gardez un seul choix parmi retrait, livraison ».
L'agent le lit aussi : tant que c'est le cas, il dit ce qui bloque et laisse la personne retirer la ligne, au lieu de proposer de confirmer.
- une ligne d'une tâche qui ne vaut plus (son
Une tâche déjà déposée par un submit partiel de ce parcours reste faite — pour un choix, la méthode déposée reste la sienne, quoi que dise ensuite la règle ou un
when, et la ligne d'une autre méthode est refusée : on peut réessayer le reste. -
-
Si l'état du parcours ne peut pas être lu, le choix d'une ligne liée à une règle du playbook et le submit sont bloqués aussi, avec une phrase qui le dit (« l'ordre de ce parcours ne peut pas être vérifié pour l'instant — réessayez dans un moment ») : jamais de commande hors de l'ordre ni sans ses tâches requises.
Ces phrases viennent du catalogue de Convoy, en français ou en anglais selon global.language ; les
widget.labels du tenant ne les changent pas.
Ce que le chargement refuse
| écrit | refusé parce que |
|---|---|
| une tâche qui n'a aucune des trois formes, ou plusieurs | on ne saurait pas ce qu'elle fait |
kind sans skill, choose sans one_of | ils ne s'appliquent à rien |
| une skill ou un kind non déclarés | la tâche n'aurait rien pour la montrer faite |
| une skill dans deux tâches du même playbook | une carte ne saurait pas de quelle tâche elle est |
| deux méthodes qui prennent le même kind | une ligne ne saurait pas de quelle méthode elle est |
un one_of de moins de deux méthodes, ou dont chaque méthode a un when | ce n'est pas un choix ; ou une sélection pourrait ne laisser aucune méthode |
sous choose: rule, la méthode sans when avant une autre | les méthodes après elle ne seraient jamais retenues |
| une méthode dont la skill ne produit aucun kind | rien ne pourrait la montrer choisie |
| une tâche requise dont rien ne produit de kind | rien ne pourrait la montrer faite |
un when qui lit autre chose que $selection.kinds ($memory, $submitted[…], $read[…], $result[…], $item…), ou qui ne le lit pas comme une liste | la raison est donnée : ce n'est pas lisible ici |
un when qui cherche un kind que la station n'a pas | la condition ne tiendrait jamais (ou toujours, avec not in) |
un when de tâche ou de méthode qui cherche un kind de sa propre tâche (pour un all_of, des tâches qu'il joint) | la ligne n'est pas encore choisie quand on l'ajoute : la tâche resterait fermée, ou changerait entre le choix et le submit |
un all_of de moins de deux tâches, qui se nomme lui-même ou nomme une tâche absente | le rendez-vous ne serait jamais fait |
required, label ou after sur un all_of | il n'est pas une étape |
un all_of sur des tâches ordonnées entre elles | elles ne peuvent pas se faire ensemble |
un after qui nomme une tâche absente, ou une tâche que rien ne peut montrer faite | la tâche ne s'ouvrirait jamais |
un after ou un all_of qui boucle | aucune tâche de la boucle ne s'ouvrirait |
une tâche requise placée after une tâche facultative, directement ou par un all_of | elle rendrait la facultative requise en fait |
des params sur un one_of (on les écrit sur chaque méthode) ou sur un all_of | ils ne lancent pas de skill à eux |
une liaison à $read[…] | une lecture ne laisse pas encore de trace qu'une tâche puisse lire |
une liaison à $result[…] | les sous-playbooks n'existent pas encore |
une liaison à une valeur fixe, ou à une autre référence $… | une valeur fixe est le default de la skill ; une tâche ne lie qu'à $submitted[<tâche>.<appel>].<sortie> |
une liaison à un paramètre que la skill ne déclare pas, ou que son invoke.args lit | elle ne fixerait rien ; ou l'invoke lirait le default pendant que le submit lit la liaison |
une liaison à une tâche absente du playbook, à la tâche elle-même, à un appel que la tâche ne fait pas, à une sortie que l'appel ne garde pas, à un appel qui n'est pas un request | la référence se résoudrait à vide |
une liaison à une tâche qui a un when | elle peut être sautée : sa réponse n'existerait jamais |
une liaison à un one_of dont une méthode ne fait pas l'appel | choisie, cette méthode ne laisserait rien à lire |
un after contraire à une liaison (geste placée after reponse, qui la lit) | l'ordre écrit contredit la donnée |
une tâche requise dont les params lisent une tâche facultative | elle rendrait la facultative requise en fait |
un paramètre de skill sans default qu'aucune tâche ne lie | rien ne le fixerait : chaque appel qui le lit serait mis en attente |
Ce qu'il ne garantit pas encore
- Les conditions sur autre chose que les kinds choisis. Un
whenne lit ni un fait de la room, ni un total, ni ce qu'une tâche a lu ou déposé. Pour une vraie dépendance de données, utilisezdepends_onsur la skill : elle tient même hors du parcours. - Le choix par le modèle. Ni
choose: clm, nifallback. - Ce qu'une tâche fixe ou déclenche. Ni
paramsliés à$read[…]ou$result[…], nidepends_on, nion_open, niguardssur une tâche ; niresult, nisubmit_guardpropre au playbook, niactivation, ni sous-playbooks. Tous les outils restent présentés au modèle, quelle que soit la tâche ouverte. - Les lectures (les skills qui ne font que répondre) ne peuvent pas être des tâches requises,
ni être citées par un
after: elles ne produisent pas de kind, rien ne les montre faites.
Voir Limites actuelles.