Aller au contenu principal
Version: Cible · roadmap

De l'actuelle à la cible

Ce qui change dans le fichier​

actuelleciblepourquoi
tenant_id, store_name, domainstation: {id, kind, name}une organisation possède plusieurs stations
global: {language, currency, locale}global.timezone en plusles horaires d'une sous-identité, les échéances des boîtes
agent: {name, persona, tone, rules, emoji, model}agent.mode en plus ; les rules qui valent pour tout agent deviennent des politiquesagent.rules atteignent encore les deux portes ; seule la façon de parler de notre agent doit y rester
agent.portals.web.widget: {origins, theme}la même forme ; identity.auth en plusle site du tenant est un portail de l'agent, pas la station
—agent.portals: {web, teams, slack, whatsapp} avec identity.authde nouveaux portails, et la preuve de qui parle
—station.identity.providers (otp, oidc, assertion, chacun avec verifies:) et identifies: true sur un champ de formulaireune room identifiée (déclarée), puis authentifiée (vérifiée). identifies: true existe déjà dans l'actuelle
apis[].operations: [{id, access, reversible, exposed}]risk et audience en plusle risque, ce qui sort. access, reversible et exposed existent déjà dans l'actuelle
skills[].invoke: {method, args} ou {native}, params: {x: {default}} (default facultatif)invoke.guards ; set_by et type sur un paramètrequi peut fixer un paramètre, de quel type est sa valeur, et une lecture a ses gardes. La déclaration unique (invoke, kinds, present, select, submit, render), invoke.native, invoke.args, $params lu par invoke.args et par les appels du submit, un paramètre qui vaut son default ou la liaison d'une tâche existent déjà dans l'actuelle
catalog: {from_skill, mode, query_arg} au niveau de la station— : la config n'a pas de catalogue ; un item se résout par ce qu'un invoke a montré dans la room, et se lit par le present de la skill qui l'a montrél'invoke dit déjà ce que la station propose ; une seconde déclaration pourrait le contredire, et une copie indexée vieillirait
present.fields d'une skill : {from, type, role, template}le même bloc ; le rôle headline et la class en plusles champs typés, leurs rôles (title, billed, link) et la table des types, commune aux formulaires, existent déjà dans l'actuelle ; un item se lit par le present de la skill qui l'a montré
kinds: {x: {when, select, submit}}kinds.<x>.present en plus (une permission sur ce qu'un profil voit) ; kinds.<x>.fields, les champs de ligne que la personne remplit ligne par ligneun kind se reconnaît par une condition sur un champ présenté ; cela existe déjà dans l'actuelle. Un choix qui appartient à une ligne (l'accompagnement d'un plat) n'avait nulle part où s'écrire
select: {max_items, guards: [form, require, check, update]}, chaque garde avec whenpermission, policy, approval en plus dans guards ; name, effect, mode, reason sur toute garde ; unique, valid_for ; quantity: {min, max, step}, le plus souvent par kindune liste ordonnée, ouverte à d'autres gardes. La liste, require, when et le langage des conditions existent déjà dans l'actuelle
submit: [{name, mode, tool, args, output, line_fields, line_shape}], un seul appel par skill ou par kindplusieurs appels, exécutés dans l'ordre ; chaque sortie typée : output: {x: {from, type}} ; line: remplace line_fields et line_shape ($line.ref, $line.quantity, $line.price, $line.fields.<champ>) ; extra_linesenchaîner des écritures dans une même skill ; une seule table de types pour tout ce qui porte une valeur. Les appels nommés, leurs sorties et $action.key existent déjà dans l'actuelle
$submitted[tache.appel].sortie : la tâche d'un playbook$result[tache], $read[tache] en plusce qu'une tâche a lu ou rendu. $submitted[tache.appel] existe déjà dans l'actuelle
playbooks[]: {name, goal, tasks: {nom: {skill, kind, one_of, choose, all_of, when, required, label, after, params}}}one_of: {choose, fallback, methods: {nom: {skill, kind, when, label, params}}} : choose dans le one_of, un label par méthode ; plus d'all_of, after: [a, b] attend les deux ; when sur $read (pas sur $memory ni $submitted) ; choose: clm ; params liés à $read ou $result ; depends_on, on_open, guards sur une tâchela condition sur les données, la donnée, le nom d'une méthode tel que la personne le lit. Les tâches nommées, goal, label, after, le choix (one_of, choose: customer|rule, écrit à côté de one_of), when sur $selection.kinds, les params d'une tâche (et de chaque méthode) liés à $submitted[tache.appel] avec l'after qu'ils impliquent, et l'ordre appliqué au choix existent déjà dans l'actuelle
— (l'agent ouvre le playbook : auto_trigger, start_playbook)activation: {when, intent, exclusive_skills}un playbook qui s'ouvre et fait loi
submit_guard de la stationsubmit_guard par playbook, avec submitted_byqui soumet, et sous quelle règle
une commande déclarée sur chaque skill dont elle envoie les lignes, regroupée par opération au submitsubmit sur le playbook : l'appel qui envoie les lignes de plusieurs tâches, déclaré une fois, ses lignes prises par $selection[task=…] ; cité $submitted[<appel>]deux copies d'un même appel pouvaient diverger, et le corps dépendait alors de l'ordre des lignes
—profiles avec grantsobligatoire dès qu'il y a une skill : la migration écrit un profil anonyme qui reçoit les opérations qu'appellent les skills existantes, une par une
agent.portals.web.widget.labels, qui ne touche pas les refustexts: {fr: {<clé>: "…"}} au niveau de la station, pour les phrases de refus et de retenuele modèle lit aussi ces phrases : elles valent sur toutes les portes
—policies, inboxes, events, automations, tests, evalsnouveaux, tous facultatifs

La forme précédente des playbooks n'est pas lue : l'outil la réécrit (python -m convoy_core.config.migrate). Chaque élément de steps devient une tâche nommée d'après sa skill, sans after : l'ordre d'une liste ne dit pas une dépendance, l'auteur l'écrit s'il la veut. description devient goal ; trigger disparaît, et son intent devient le goal d'un playbook qui n'avait pas de description. $submitted[<skill>.<appel>] devient $submitted[<tâche>.<appel>] quand la skill est l'action — ou celle d'une méthode d'un one_of — de tâches d'un seul nom. Un all_of disparaît : chaque tâche dont l'after le nomme attend directement ses membres. choose et fallback entrent dans le one_of, et ses méthodes passent sous methods.

Le catalogue. L'outil retire catalog. Rien ne le remplace : la recherche passe par une skill dont l'invoke est l'opération de recherche du tenant (la question sous un paramètre, à la place de query_arg), et une référence se résout par ce que la room a déjà vu. mode: indexed n'a pas d'équivalent : Convoy n'indexe pas le catalogue d'un tenant (le cas d'un tenant sans opération de recherche reste ouvert).

Le submit aussi. line_fields: {ref: a, quantity: b} devient line: {a: "$line.ref", b: "$line.quantity"} (une clé absente garde slug ou qty) ; line_shape: ref devient line: "$line.ref" ; sans l'un ni l'autre, rien n'est écrit : la forme par défaut est la même. Les appels d'une même opération portés par les skills de plusieurs tâches d'un playbook deviennent un seul appel dans le submit de ce playbook, quand leurs args et leur forme de ligne sont les mêmes : $selection[kind=k] y devient $selection[task=…], et les références $submitted[<tâche>.<appel>] vers lui deviennent $submitted[<appel>]. Des args différents, ou une skill aussi utilisée hors de tout playbook, sont laissés à l'auteur, avec la raison. Une config migrée doit envoyer au tenant les mêmes requêtes, octet pour octet.

L'ordre de construction​

Une étape n'est livrée que quand ses exemples de cette version passent dans la version actuelle.

  1. Les états d'action (en attente, lue) et les traces de lecture, dans la room et le reçu.
  2. L'ordre appliqué au choix ; les tâches (after, one_of, when) ; le planificateur (les tâches nommées, goal, label, after, one_of avec choose: customer ou rule, when sur les kinds choisis et l'ordre appliqué au choix, step_open, sont construits ; choose écrit dans le one_of, le label d'une méthode, le retrait d'all_of, when sur $read, choose: clm et le guidage du modèle vers les tâches ouvertes suivent).
  3. La nouvelle forme des skills, l'ancienne lue pendant une version ; les six configs migrées (la liste ordonnée des gardes de select, require, when et le langage des conditions sont construits ; la déclaration unique de la skill est construite, avec params et leur default, invoke.args, invoke.native et kinds.<k> (when, select, submit), et les params d'une tâche liés à $submitted[…]).
  4. Le submit guard par playbook, avec l'appel de commande du playbook (submit, line:, extra_lines) et les champs de ligne ; puis le graphe d'états de chaque playbook, compilé au chargement, avant le guidage ; les sous-playbooks ; puis result et $result, qui lisent un sous-playbook.
  5. Le parcours attaché à la room ; les approbations liées à une version de l'action ; valid_for.
  6. Les profils, per_profile, les permissions ; l'identité par personne (le plane d'identité, identifies et le fournisseur otp via le tenant sont construits ; via: convoy, oidc, assertion, le choix par portail, les demandes d'authentification et submitted_by: owner suivent).
  7. approval, quand une room accueille plusieurs personnes avec des rôles.
  8. submitted_by, quand les acteurs sont authentifiés ; puis les sous-identités déléguées.
  9. set_by, les classes de données, les audiences ; les gardes de lecture.
  10. L'activation déterministe, seek_guidance sans modèle, la règle de la première écriture.
  11. L'idempotence par action, unique, reversible, budget, inboxes ($action.key est construite ; reversible est déclaré et rend le submit MCP destructif ; l'écran d'approbation et l'ordre au submit suivent).
  12. Les automatisations, avec leur profil et la vérification des boucles ; la section agent et ses portails (la section agent et agent.portals.web.widget: {origins, theme} sont construits ; Teams, Slack, WhatsApp à côté du widget et de la PWA suivent).
  13. Les versions de station, le staging, les tests de contrat, le rejeu ; les evals de l'agent.
  14. Le modèle de classement en ombre, puis en SUGGEST, puis en ENFORCE, station par station.

D'où viennent ces décisions​

  • ADR-028 §6 — un playbook comme ensemble de tâches et quatre relations.
  • ADR-029 — tout est une station ; l'action ; la sélection comme ordre d'actions ; les sous-playbooks ; qui soumet.
  • ADR-030 — le point de décision, le planificateur, le modèle de classement ; les profils ; seek_guidance ; la provenance, les classes de données, le temps, l'exécution, le Human In The Loop, les automatisations.
Les noms ne sont pas tous fixés

Certaines clés de ce guide sont des propositions que les ADR n'ont pas encore figées : le bloc station, global.timezone, auth.on_behalf_of, station.delegation, agent.portals et identity.auth, la syntaxe des tests et des evals. Elles pourront changer à l'implémentation ; le sens, non.