Aller au contenu

Tâches programmées

Une tâche est un prompt réutilisable que vous configurez une fois, puis qui s’exécute à la demande, selon un planning, sur appel d’API, ou sur un événement d’une base de connaissance (un document ajouté, modifié ou supprimé). À chaque exécution, la tâche mobilise les ressources que vous lui avez données (bases de connaissance, connecteurs, recherche web, exécution de code) et livre son résultat par email, message Slack ou webhook, en texte ou en JSON.

Une tâche reste une requête différée : un déclenchement = un appel au modèle + une livraison. Il n’y a pas de chaînage entre tâches ni de processus permanent.

Les tâches se créent et se configurent dans le portail (/portal/taches) : prompt, variables, ressources, modèle, fréquence, sorties et format. La création demande une session (elle identifie le créateur, dont le périmètre est réutilisé à chaque exécution), elle n’est donc pas exposée par l’API.

Vous pouvez aussi composer une tâche depuis une conversation de l’assistant : décrivez ce que vous voulez automatiser, et l’assistant peut proposer une tâche (nom, prompt, planification, ressources, destinataires) sous la forme d’une carte « Tâche proposée », avec une estimation du coût par exécution. Rien n’est créé tant que vous n’avez pas cliqué sur Créer la tâche ; vous pouvez aussi Modifier dans le portail avant de valider, ou Écarter la proposition. Cette voie est réservée aux rôles qui ont accès au portail (propriétaire, administrateur, membre) : un rôle consommateur, cantonné à l’assistant, ne la voit pas.

L’API (/v1/tasks) sert ensuite à lister, lire, modifier, supprimer, déclencher une tâche et à consulter son historique, typiquement depuis une automatisation (Make, n8n, un cron, un script).

Les tâches sont propres à une organisation. L’API exige donc une clé d’organisation portant le scope tasks ; une clé personnelle est refusée.

Le champ Prompt du portail est un éditeur visuel : la mise en forme (titres, listes, gras, tableaux) s’applique directement et le prompt est enregistré en markdown. Une bascule Markdown donne accès à la source brute. Les variables ${nom} et les citations de document (@) s’écrivent normalement dans les deux modes.

Le prompt d’une tâche peut contenir des variables ${nom}. À chaque déclenchement, vous fournissez leurs valeurs dans un objet inputs. Les variables système ${date}, ${now} et ${task_name} sont toujours disponibles.

{ "inputs": { "dossier_id": "D-123", "priorite": "haute" } }

Une clé d’inputs commençant par un underscore (_context, _document_id…) est réservée : ces clés sont posées par Miraca lui-même (contexte du déclencheur, relance) et toute valeur que vous fourniriez sous un tel nom est ignorée.

Toutes les routes exigent l’en-tête Authorization: Bearer sk-… (clé d’organisation, scope tasks).

RouteVerbeRôle
/v1/tasksGETListe les tâches de l’organisation.
/v1/tasks/{slug}GETDétail d’une tâche.
/v1/tasks/{slug}PATCHMet à jour partiellement une tâche.
/v1/tasks/{slug}DELETESupprime une tâche (et son historique).
/v1/tasks/{slug}/runPOSTDéclenche un run (trigger = api).
/v1/tasks/{slug}/runsGETHistorique des runs (statuts, dates, livraisons).
/v1/tasks/{slug}/runs/{run_id}GETExport complet d’un run (config, métriques, résultat, feedback, déroulé).

POST /v1/tasks/{slug}/run accepte { "inputs": {…}, "context": "…", "wait": false }.

Le champ context (optionnel, texte libre jusqu’à 32 000 caractères) est ajouté au prompt pour ce run précis — utile pour passer le contenu de l’enregistrement qui a déclenché votre scénario (Make, n8n…). Il est traité comme des données, pas des consignes : une instruction qui s’y trouverait n’est pas exécutée.

{ "inputs": { "client": "ACME" }, "context": "Extrait du dossier : …" }

Les valeurs de inputs et le context sont enregistrés avec l’exécution, chiffrés au repos comme son résultat : ils servent à la relancer à l’identique et se relisent dans son export.

Pour une tâche qui relit son dernier résultat, ce sont les valeurs de inputs qui désignent l’exécution précédente, pas le context : deux appels aux mêmes inputs se relisent, quel que soit le context joint (voir Mémoire d’exécution).

Le champ instruction (optionnel, texte jusqu’à 4 000 caractères) ajoute une consigne pour cette exécution seulement, sans modifier le prompt enregistré de la tâche : utile pour infléchir un run sans changer la configuration pour les suivants (« pour cette fois, se concentrer sur les impayés »).

{ "instruction": "Se concentrer sur les factures en retard de plus de 30 jours." }

Pour poser une consigne qui s’appliquera à la prochaine exécution, quel que soit son déclencheur (planning, bouton « Exécuter », API), utilisez PATCH /v1/tasks/{slug} avec next_run_instruction :

{ "next_run_instruction": "Vérifie aussi les nouveaux clients de la semaine." }

Elle est consommée par le run qui démarre puis effacée : une file d’un seul message, pas un réglage permanent. next_run_instruction: null (ou une chaîne vide) la retire avant qu’elle ne serve.

Par défaut (wait absent ou false), l’appel est asynchrone : il répond 202 avec un run_id, et le résultat est livré par les sorties configurées.

Fenêtre de terminal
curl -X POST https://api.miraca.fr/v1/tasks/brief-quotidien/run \
-H "Authorization: Bearer sk-…" \
-H "Content-Type: application/json" \
-d '{"inputs":{"dossier_id":"D-123"}}'
{ "run_id": "…", "status": "pending" }

Avec "wait": true, l’appel attend le résultat (borné par un délai côté serveur). Au-delà de ce délai, il répond 202 avec le run_id, à interroger via /runs.

{
"run_id": "…",
"status": "done",
"output": "…",
"error": null,
"delivered": [{ "type": "email", "ok": true, "detail": "vous@org.fr" }]
}

En format JSON (réglage de la tâche), output est l’objet déjà parsé, directement exploitable dans l’étape suivante d’un scénario no-code.

Le même endpoint relance une exécution passée avec exactement son contexte : { "replay_of": "<run_id>" } recopie les variables, le contexte d’appelant et le document déclencheur de cette exécution (les champs inputs et context sont alors ignorés). Deux options, combinables, valables aussi sans replay_of :

  • "deliver": false : rien n’est envoyé (ni e-mail, ni Slack, ni webhook). Le livrable est enregistré dans l’exécution et se lit au tableau de bord ou dans l’export. Utile pour régler un prompt sans écrire aux destinataires à chaque essai.
  • "model": "gemma" : l’exécution tourne sur un autre modèle du catalogue, pour comparer deux livrables à consigne strictement égale. Le modèle de la tâche n’est pas modifié ; un identifiant inconnu est refusé (400).
{ "replay_of": "…", "deliver": false, "model": "qwen-small" }

Une exécution encore en cours ne se relance pas (409) ; un replay_of qui n’appartient pas à la tâche répond 404. Dans l’historique, la nouvelle exécution porte replay_of et overrides ({} pour une relance à l’exact). Une relance avec option est une expérience : elle n’est jamais relue comme « dernier résultat » par les exécutions suivantes (voir Mémoire d’exécution), alors qu’une relance à l’exact compte comme une exécution ordinaire.

GET /v1/tasks/{slug}/runs renvoie les métadonnées d’exécution : statut, dates, état des livraisons, et les métriques du run — model (modèle effectif), duration_ms, cost_eur (coût en euros, remise de cache incluse) et co2_g (empreinte carbone en grammes de CO₂eq). Ces champs sont null pour les exécutions antérieures à leur capture. Une relance porte en plus replay_of (l’exécution source) et overrides (ses options). Le contenu du résultat n’est pas exposé par cette route ; utilisez wait:true sur /run pour récupérer le résultat d’une exécution.

La route accepte deux paramètres de requête : ?limit= (défaut 30, plafond 100) et ?before=, un curseur opaque pour continuer une page précédente. La réponse porte next_cursor : reprenez sa valeur telle quelle dans ?before= pour obtenir la page suivante (plus ancienne) ; null signifie qu’il n’y a plus rien à récupérer.

{ "data": [ /* … */ ], "next_cursor": "eyJjcmVhdGVkQXQiOiIyMDI2LTA5LTAxIiwiaWQiOiIu4iJ9" }

L’état des livraisons (delivered) nomme chaque destination : l’adresse e-mail, le canal Slack, et pour un webhook son hôte seulement (hook.eu1.make.com : 200), jamais son adresse complète.

GET /v1/tasks/{slug}/runs/{run_id} renvoie l’export complet d’une exécution, en un seul document autoportant : la configuration de la tâche (consigne, ressources, format de sortie, budget), les métriques et les entrées du déclenchement, le résultat, le feedback posé et le déroulé (tours de modèle, outils appelés, sources).

C’est le même document que le bouton Exporter en JSON du tableau de bord : un diagnostic se scripte comme il se clique. Utile pour joindre une exécution à un ticket, la relire hors ligne ou la faire analyser ailleurs.

{
"format": "astrolabe.task-run/v1",
"exported_at": "2026-07-23T10:00:00.000Z",
"task": { "slug": "veille-hebdo", "prompt": "…", "kb_slugs": ["docs"] },
"run": { "id": "…", "status": "done", "cost_eur": 0.0421, "usage": { } },
"result": "…",
"feedback": "…",
"trace": { "steps": [], "sources": [], "rounds": [] }
}

result, feedback, trace et run.inputs (les entrées du déclenchement) sont chiffrés au repos et déchiffrés pour cette réponse. Les trois premiers valent null quand l’exécution n’en a pas produit ; run.inputs vaut {} pour un déclenchement sans entrée, et null seulement si elles n’ont pas pu être déchiffrées. Les étapes publiées pendant l’exécution (run.progress_steps) sont chiffrées de la même façon, sous la clé de la tâche.

L’export porte tout ce qui est connu du run, pas seulement son résultat :

  • run : statut, déclencheur, entrées du déclenchement, dates, durée, coût en euros, carbone, modèle effectif, usage (tokens, part de cache) et l’état de chaque livraison ;
  • trace.steps : chaque appel d’outil — outil, base visée, requête et filtres, paramètres bruts, nombre de résultats, sortie, tour qui l’a demandé, et l’indicateur d’échec le cas échéant ;
  • trace.rounds : chaque tour de modèle avec ses tokens d’entrée/sortie, la part servie par le cache, son coût, sa durée et son carbone ;
  • trace.sources : les extraits cités (document, score, facettes, lien) ;
  • run.progress_rounds et run.progress_steps : les tours mesurés et les étapes relevées pendant l’exécution (outil, paramètres, réflexion du tour, aperçu du résultat, 60 étapes au plus). C’est ce qu’on sait d’un run encore en cours, dont le déroulé n’est pas encore écrit. progress_steps est vide dès que le run est terminé : son déroulé se lit alors dans trace.

Un run échoué a lui aussi une trace : sa réponse n’est jamais revenue, donc trace.steps porte les étapes relevées pendant l’exécution, avec un aperçu de chaque sortie d’outil au lieu de la sortie complète, et trace.sources est vide.

L’export porte aussi efficiency et tool_usage, qui répondent à « pourquoi ce run a-t-il coûté ce qu’il a coûté » plutôt qu’à « combien » :

{
"efficiency": {
"rounds": [
{ "n": 1, "prompt_tokens": 900, "cached_tokens": 400, "reusable_tokens": 0, "completion_tokens": 50 },
{ "n": 2, "prompt_tokens": 1200, "cached_tokens": 800, "reusable_tokens": 896, "completion_tokens": 30 }
],
"anatomy": {
"tour": 1,
"postes": [{ "name": "kb_bases", "chars": 800 }, { "name": "outil:kb_search", "chars": 1200 }],
"chars_total": 2000,
"tokens_estimes": 571
}
},
"tool_usage": { "used": { "kb_search": 3 }, "missing": ["kb_write_document"] }
}
  • efficiency.anatomy : à quoi ressemblait le premier tour : la taille (en caractères) de chaque fragment de consigne système et de chaque outil proposé, triés du plus gros au plus petit. Sert à voir CE qui pèse, avant d’y toucher.
  • efficiency.rounds[].reusable_tokens : ce que le tour précédent avait de prompt, arrondi au bloc de cache (128), soit la part que le préfixe commun pouvait servir depuis le cache si rien n’a changé en tête. Comparé à cached_tokens du même tour, cela dit si le fournisseur a effectivement servi ce qu’il pouvait servir.
  • tool_usage : les outils réellement appelés pendant ce run (used, par nombre d’appels) et ceux que le modèle a demandés mais qui n’étaient pas proposés (missing) : un signal pour ajuster les outils actifs de la tâche.

GET /v1/tasks/{slug} porte le même tool_usage, agrégé sur les 30 derniers runs terminés de la tâche qui ont relevé leur usage d’outils (un run arrêté avant la fin de sa boucle n’en a pas, et n’est pas compté) : { "runs_analyzed": 12, "used": {…}, "unused": ["create_file"], "missing": ["kb_write_document"] }. unused liste les outils actifs sur la tâche mais jamais appelés sur cette fenêtre, visible aussi sur le tableau de bord (carte « Efficience »), avec un bouton pour les désactiver.

efficiency.anatomy.postes peut porter deux lignes d’AGRÉGAT, jamais du contenu : autre (au-delà des 40 postes les plus gros, le reste regroupé) et autre_systeme (la part de la consigne système de tête qui n’appartient à aucun fragment nommé connu, comme la personnalité de la tâche, la notice de date ou la notice de pseudonymisation, calculée par différence pour que rien ne disparaisse silencieusement même si un futur fragment oublie de s’enregistrer). Les deux sont optionnelles (absentes si rien à agréger).

Chaque tâche a sa page dédiée au portail (cliquez sur sa carte dans Tâches) : la configuration en un coup d’œil, des totaux sur 30 jours (nombre d’exécutions, coût, carbone) et l’historique complet — chaque exécution avec sa durée, son coût en euros et son empreinte carbone. Cliquez sur une exécution réussie pour lire son résultat. La page s’actualise toute seule tant qu’une exécution est en cours ; les liens des emails de résultat mènent directement à ce tableau de bord.

La carte Efficience résume le socle du dernier run terminé (tokens estimés, postes les plus lourds), la part du cache réellement servie tour par tour et les suggestions de tool_usage (outils actifs jamais appelés, avec un bouton Désactiver ; rien n’est retiré automatiquement).

Ouvrez une exécution terminée et cliquez sur Relancer… : la fenêtre se ferme et une nouvelle ligne apparaît en tête de l’historique, lancée avec exactement le contexte de l’exécution d’origine (mêmes variables, même contexte d’appelant, même document déclencheur). C’est la façon de rejouer une exécution déclenchée par un document ou par l’API, que le bouton Exécuter ne sait pas reproduire.

Deux options, combinables :

  • Ne rien envoyer : ni e-mail, ni Slack, ni webhook. Le livrable est enregistré et se lit dans le détail de l’exécution, comme si la tâche l’avait envoyé, sans écrire aux destinataires à chaque essai de prompt.
  • Modèle : relancer sur un autre modèle du catalogue pour comparer deux livrables à consigne égale. Le modèle de la tâche n’est pas modifié.

Sans option, l’exécution est relancée à l’exact et compte comme une exécution ordinaire. Avec une option, c’est une expérience : elle apparaît comme telle dans l’historique (« Relance », « sans envoi », « modèle : … ») et n’est pas relue comme « dernier résultat » par les exécutions suivantes. Ce qui change malgré tout entre l’original et sa relance : la date (${date}, ${now}), l’état des sources consultées, et le dernier résultat relu par une tâche qui accède à son historique.

Pendant qu’une exécution est en cours, l’historique affiche sa progression — le tour atteint, le temps déjà passé et le dernier outil lancé — au lieu d’un simple « En cours ». Sur une tâche longue, on voit ainsi qu’elle avance, à quel rythme, et à quoi elle travaille en ce moment.

Ouvrez l’exécution pendant qu’elle tourne : le déroulé se construit sous vos yeux, tour après tour, avec pour chacun l’outil appelé, ses paramètres et la phrase par laquelle le modèle explique ce qu’il cherche. C’est aussi ce qui reste visible quand une exécution échoue : on voit alors où elle en était.

Sous le résultat, une exécution en mode agent affiche son déroulé : la chronologie complète de ce qu’elle a fait, dans l’ordre. Les outils appelés (recherches, lectures de page, écritures dans une base…) avec leurs paramètres et leur nombre de résultats, et entre eux les tours de modèle avec la taille du contexte, la part servie par le cache, les tokens produits, la durée et le coût.

Les deux sont côte à côte pour une raison : le contexte est réinjecté à chaque tour, donc il grossit avec les résultats accumulés juste au-dessus de lui. On voit ainsi quelle recherche a fait gonfler le contexte, et on distingue une boucle trop large (tour long avec un gros contexte) d’un appel qui traîne côté modèle (tour long avec un petit contexte).

Ce qui n’a pas abouti y figure aussi, signalé en rouge et compté dès l’en-tête : un tour en délai dépassé (avec le temps qu’il a coûté), un outil en échec — une écriture refusée, une recherche dont les moteurs n’ont pas répondu. C’est souvent ce qui explique qu’une exécution se soit déclarée terminée sans avoir produit l’effet attendu.

Le déroulé indique aussi les sources citées. Vous voyez ainsi ce que la tâche a fait pour arriver à son résultat, ce qui aide à écrire un feedback précis. Il est chiffré au repos comme le résultat et n’est pas relu par le modèle (affichage seul).

Une exécution en attente ou en cours peut être annulée depuis le tableau de bord : bouton Annuler sur sa ligne, confirmation demandée. Une fois annulée, elle s’arrête au plus tôt (au prochain point de contrôle si elle est en cours) et n’est plus reprise. Cette action n’est disponible qu’au portail, elle n’est pas exposée par l’API.

Au-delà de 180 jours, le résultat, le livrable, la trace et les éventuels fichiers produits d’une exécution sont effacés automatiquement. La ligne elle-même reste dans l’historique (date, durée, coût en euros, empreinte carbone, statut), avec la mention « Contenu effacé après 180 jours » à la place du résultat. Cela n’affecte ni les totaux du tableau de bord (30 jours) ni le budget consommé de la tâche, qui restent exacts. Une exécution dont le contenu a été effacé ne peut plus être relancée (ses paramètres d’origine ne sont plus disponibles), ni faire l’objet d’un avis du modèle (il n’y a plus rien à analyser).

Une tâche qui a une base en Écriture peut changer les facettes d’un document — typiquement faire passer une fiche de « à faire » à « fait » une fois le travail livré. Pour une facette à énumération, la valeur doit être l’une de celles du schéma ; sinon l’appel échoue avec la liste des valeurs acceptées, et le modèle peut se corriger. La clé de la facette, elle, est rapprochée de celles du schéma (casse, accents, apostrophes, espaces) : une clé qui ne correspond à aucune facette déclarée n’échoue pas, elle crée une facette libre, et le résultat de l’outil le signale en nommant les facettes déclarées, pour que le modèle refasse l’appel si une autre était visée.

Pour chaque base de connaissance, chaque connecteur et chaque boîte mail, une tâche a un niveau d’accès : Aucun (non utilisé), Lecture (le cas courant) ou Écriture. En écriture, la tâche peut modifier la ressource : ajouter, modifier ou supprimer des documents d’une base, appeler les opérations d’écriture d’un connecteur, ou envoyer, répondre, ranger et supprimer dans une boîte mail.

Le niveau est plafonné par les droits de la personne qui a créé la tâche : une tâche ne peut jamais écrire une ressource que son créateur ne peut pas écrire lui-même (le sélecteur « Écriture » est alors désactivé). Ce plafond est re-vérifié à chaque exécution — si l’accès du créateur est retiré entre-temps, la tâche retombe automatiquement en lecture seule. L’écriture n’est jamais accordée par défaut.

Les notes personnelles (« Mes notes ») ne peuvent pas être confiées à une tâche, ni surveillées par un déclencheur : une tâche tourne au nom de son créateur mais peut être modifiée par un administrateur, qui lirait alors des notes qui ne sont pas les siennes. Les tâches qui les déclaraient avant cette règle les ont perdues de leurs ressources ; le reste de la tâche est inchangé.

Les serveurs MCP ne peuvent pas non plus être confiés à une tâche : leurs outils sont des écritures par défaut, et une tâche n’est soumise à aucune confirmation, donc personne ne relirait une action chez un tiers.

Dans une conversation, une écriture qui sort du compte vous est soumise : l’assistant propose, vous cliquez. Une tâche, elle, se déclenche quand personne ne regarde — une carte à valider y resterait en attente pour toujours.

Sur une boîte mail, le cran « Écriture » d’une tâche est donc l’accord lui-même : vous autorisez cette tâche à envoyer sans vous demander, à chaque exécution. En Lecture, la tâche dépouille la boîte (chercher, lire, lister les dossiers) et n’y touche pas — c’est le réglage à préférer pour une veille ou un tri.

Le plafond du créateur s’applique ici comme ailleurs : une boîte qui vous est partagée en lecture seule ne peut pas devenir écrivable par votre tâche.

L’accord « Écriture » n’ouvre pas l’envoi vers n’importe qui. Pour l’envoi d’un message et son transfert, les deux outils dont le destinataire est choisi par le modèle (jamais la réponse, qui répond toujours à l’expéditeur d’origine), l’envoi n’a lieu que si tous les destinataires (à, copie, copie cachée) sont membres de votre organisation. Dès qu’un seul ne l’est pas, rien ne part : la tâche n’a personne devant un écran pour relire un envoi avant qu’il parte, contrairement à l’assistant ou à Slack. Déposer un brouillon reste toujours possible : rien n’est envoyé, une personne le relira dans son client mail.

Une tâche peut se déclencher automatiquement quand un document bouge dans une base de connaissance : dans la fenêtre d’édition, activez « Déclencher sur un événement d’une base de connaissance », choisissez la base surveillée, les événements (ajout / modification / suppression) et, en option, une condition sur les facettes (ne déclenche que si le document porte, par exemple, type=facture).

Le document déclencheur est fourni à la tâche : sa référence, et — pour un ajout ou une modification — son contenu (si la base est aussi déclarée en Lecture dans les ressources de la tâche). Cas d’usage : « à chaque nouvelle facture, vérifie sa conformité », « à chaque compte-rendu ajouté, mets à jour le suivi ».

Comptent comme une modification : une édition du contenu, une mise à jour par synchronisation d’un connecteur, et un changement de facette — typiquement déplacer une fiche d’une colonne à l’autre dans la vue kanban. C’est ce qui permet le schéma « liste de tâches à faire » : on dépose une fiche, on la passe en à faire, et ce passage déclenche le traitement.

Plusieurs mouvements rapprochés sur le même document ne déclenchent qu’une seule exécution, sur l’état final. Déplacer une fiche puis la ramener aussitôt, ou enchaîner deux corrections, ne lance donc pas deux traitements redondants : c’est l’état du document au moment du traitement qui compte, et il est le même dans les deux cas. Deux documents distincts déclenchent bien, eux, deux exécutions.

Supprimer une base entière déclenche l’événement suppression pour chacun de ses documents, comme les supprimer un par un.

Par l’API (PATCH /v1/tasks/{slug}), le déclencheur s’écrit "trigger_kb": { "kb_slug": "factures", "events": ["created"], "facets": { "type": "facture" } } et se retire par "trigger_kb": null. Le serveur retrouve lui-même l’identifiant de la base depuis kb_slug : collection_id est facultatif. Un déclencheur incomplet (sans base ou sans événement) est refusé en 400 avec la raison, il n’efface jamais celui qui existe.

Quand une tâche a un déclencheur KB, vous pouvez référencer les métadonnées du document qui l’a déclenchée, dans le prompt comme dans les champs de livraison (destinataires email, sujet, destinataire Slack) :

VariableContenu
${document.titre}Titre du document
${document.reference}Identifiant externe (external_id)
${document.date}Date métier (AAAA-MM-JJ)
${document.url}Lien source
${document.evenement}ajout, modification ou suppression
${document.base}Slug de la base surveillée
${document.facette.<clé>}Valeur(s) d’une facette, ex. ${document.facette.dossier}

Exemples : un sujet d’email Nouveau transcript : ${document.titre}, ou un destinataire Slack ${document.facette.responsable} (si la facette porte un email). Un destinataire templaté est re-vérifié membre de l’organisation au moment de l’envoi (même garde que les destinataires fixes) ; une variable absente se résout en vide.

La clé d’une facette se retrouve sans tenir compte de la casse, de la forme Unicode des accents ni des espaces insécables : ${document.facette.Statut} lit la facette statut. Ce n’est pas une recherche approximative, proprietaire ne lit pas propriétaire.

À l’enregistrement de la tâche, une clé qui correspond à une facette du schéma de la base surveillée est récrite avec la clé du schéma, dans le prompt, l’objet, les destinataires et la condition du déclencheur : ${document.facette.Statut} est enregistrée ${document.facette.statut}. Une clé qui ne correspond à aucune facette déclarée n’est pas refusée : un document peut porter des facettes libres, absentes du schéma, et la tâche est enregistrée telle quelle. Elle ne se déclenche alors que sur les documents qui portent cette facette.

Une variable qui reste sans valeur sur un document (facette absente ou vide) n’est pas silencieuse. Pour une exécution déclenchée par un document, l’historique indique la variable concernée et les facettes que le document porte : pour un destinataire, par une ligne en échec dans les envois ; pour le prompt, dans le journal du serveur. Lancée à la main, planifiée ou appelée par l’API, une exécution n’a pas de document : ces variables sont vides par construction et rien n’est signalé.

Une tâche peut surveiller une base dans laquelle elle écrit. C’est même le schéma le plus courant : une base recense des demandes à traiter, la tâche se déclenche à chaque nouvelle fiche, fait le travail, puis reclasse la fiche (avancement, compte rendu).

Elle ne se re-déclenche pas pour autant : Miraca retient quelle tâche est à l’origine de chaque écriture, et n’envoie jamais un événement à la tâche qui vient elle-même d’écrire le document. Les autres tâches qui surveillent la même base, elles, sont bien déclenchées comme d’habitude ; et si quelqu’un d’autre (une personne, une synchronisation) modifie ensuite ce document, la tâche repart normalement.

Une modification que vous faites ensuite (reclasser la fiche, éditer son contenu, la supprimer) réveille normalement la tâche : la trace d’auteur ne vaut que pour l’écriture de la tâche elle-même.

Ce mécanisme couvre l’auto-déclenchement d’une tâche par elle-même. Pour les cas indirects (deux tâches qui s’écrivent mutuellement), posez un budget (ci-dessous).

Pendant qu’une tâche travaille sur une fiche, celle-ci porte un indicateur « n tâches en cours » dans la liste des documents de la base (Connaissances), avec le nom des tâches concernées au survol. Il se met à jour tout seul et disparaît une fois les exécutions terminées : on voit d’un coup d’œil qu’un document est en train d’être traité, et par combien de tâches à la fois. Vous n’y voyez que les tâches que vous avez le droit de consulter (les vôtres, ou toutes si vous administrez l’organisation).

Une tâche peut livrer son résultat de trois façons, cumulables :

DestinationCe que vous saisissez
EmailUne ou plusieurs adresses, séparées par des virgules. Réservées aux membres de l’organisation.
SlackUn ou plusieurs destinataires, séparés par des virgules : un canal (#direction, C01234ABCDE — invitez d’abord le bot dans le canal) ou l’email d’un membre (message privé).
WebhookUne URL appelée en POST (JSON), avec signature HMAC optionnelle. L’adresse et le secret sont chiffrés une fois enregistrés.

Chaque destinataire Slack est traité séparément : un canal reçoit le message dans le canal, un email reçoit un message privé du bot Miraca. Une adresse email qui n’est pas membre de l’organisation est refusée (même garde que la sortie email). Chaque envoi est consigné individuellement dans l’historique de l’exécution, avec sa cause en cas d’échec (channel_not_found = le bot n’est pas dans le canal, ou le nom est inexact).

Ces champs acceptent aussi les variables du document déclencheur : une valeur qui se résout en plusieurs adresses (une facette « participants » qui en porte deux) donne bien deux envois distincts. Une facette de type personne (Prénom Nom <adresse>) est lue comme une personne : l’adresse entre chevrons est le destinataire.

Pour le destinataire Slack, cette souplesse a une limite : une valeur qui provient d’une variable (${document.facette.*}) ne peut se résoudre qu’en email d’un membre de l’organisation ; un canal ou un identifiant Slack doit être écrit en dur dans le champ. Sans quoi le contenu d’un document synchronisé pourrait rediriger une livraison vers un canal que personne n’a choisi dans le formulaire. Une cible qui ne respecte pas cette règle n’est pas postée ; l’échec se lit dans l’historique de l’exécution.

Si vous renseignez un secret, chaque livraison porte quatre en-têtes :

En-têteContenu
X-Miraca-SignatureHMAC-SHA256(secret, corps), en hexadécimal
X-Astrolabe-Signaturela même valeur, sous l’ancien nom (conservée : ne cassez pas ce que vous avez déjà écrit)
X-Miraca-Timestampl’instant de l’envoi, en secondes depuis epoch
X-Miraca-Signature-V2v0= suivi de HMAC-SHA256(secret, "v0:" + timestamp + ":" + corps)

Vérifiez la paire V2, pas la première signature. Celle-ci ne couvre que le corps : qui met la main sur une livraison — dans un journal, chez un proxy — peut la rejouer à l’identique, indéfiniment, et rien ne vous permet de faire la différence avec l’originale. La V2 couvre l’instant d’envoi, donc un rejeu se reconnaît à son âge.

La première signature reste émise, et le restera : elle est vérifiée par des récepteurs déjà en production, et la changer les casserait tous d’un coup. C’est à vous de passer à la seconde.

import { createHmac, timingSafeEqual } from "node:crypto";
function livraisonValide(req, corpsBrut, secret) {
const ts = req.headers["x-miraca-timestamp"];
const recue = req.headers["x-miraca-signature-v2"];
if (!ts || !recue) return false;
// 1. La fraîcheur D'ABORD : sans elle, la signature v2 ne vaut pas mieux que la v1.
// Cinq minutes, la même fenêtre que celle recommandée par Slack.
if (Math.abs(Date.now() / 1000 - Number(ts)) > 300) return false;
// 2. Puis la signature, en comparaison à temps constant.
const attendue = "v0=" + createHmac("sha256", secret).update(`v0:${ts}:${corpsBrut}`).digest("hex");
const a = Buffer.from(recue), b = Buffer.from(attendue);
return a.length === b.length && timingSafeEqual(a, b);
}

L’adresse d’un webhook et son secret de signature sont chiffrés avant d’être enregistrés, sous la clé propre à la tâche. Seul l’hôte de l’adresse (hook.eu1.make.com) reste lisible : c’est lui que nomme le journal des envois d’une exécution, jamais l’adresse complète.

Le secret n’est jamais réaffiché, ni dans le portail ni par l’API. Dans la tâche, le champ « Secret de signature » part vide :

  • laissé vide, le secret enregistré est conservé ;
  • une saisie le remplace ;
  • « Retirer le secret » le supprime, et les appels ne sont plus signés.

Un secret est attaché à son adresse. Si vous changez l’adresse du webhook, le secret enregistré n’est pas repris : saisissez celui du nouveau récepteur.

Le champ deliveries de PATCH /v1/tasks/{slug} remplace la liste des sorties :

{
"deliveries": [
{ "type": "email", "to": ["vous@org.fr"], "subject": "Bilan du ${date}" },
{ "type": "slack", "channel": "#direction" },
{ "type": "webhook", "url": "https://hook.exemple.org/abc", "secret": "votre-secret" }
]
}

En lecture (GET /v1/tasks, GET /v1/tasks/{slug}, réponse d’un PATCH), un webhook est rendu avec son adresse et l’indicateur has_secret, sans son secret :

{ "type": "webhook", "url": "https://hook.exemple.org/abc", "has_secret": true }

Ce que vaut le champ secret d’un webhook, en écriture :

Vous envoyezEffet
"secret": "valeur"Le secret est remplacé.
aucun champ secret, même urlLe secret enregistré est conservé.
"secret": null ou ""Le secret est retiré.
une autre url, sans secretAucun secret : celui de l’ancienne adresse n’est pas repris.

Vous pouvez donc relire une tâche, modifier sa liste de sorties et la renvoyer telle quelle sans perdre la signature. has_secret est ignoré en écriture.

Par défaut, une tâche envoie sa réponse finale aux destinations configurées. C’est simple, mais ça impose au livrable de tenir dans une seule réponse, donc sous le plafond de tokens.

Dès qu’une tâche a au moins une destination (email ou Slack), l’agent dispose en plus d’un outil deliver : il peut envoyer un contenu pendant son exécution, autant de fois qu’il le souhaite. Un rapport en cinq parties peut ainsi partir en cinq messages, sans être contraint par le plafond d’une génération unique.

Deux règles à connaître :

  • L’agent choisit le contenu, jamais le destinataire. Les adresses et canaux restent ceux que vous avez configurés dans la tâche, avec leurs variables (${document.titre}, ${date}…) rendues exactement comme pour un envoi automatique. C’est délibéré : un destinataire choisi par le modèle serait choisi par ce qu’il lit, donc détournable par une page web ou un document piégé.
  • Un livrable volumineux se livre en plusieurs appels avec suite. Passez suite: true sur toutes les parties sauf la dernière. Une fois la dernière partie livrée (toutes ses destinations atteintes, et aucune étape de la checklist encore ouverte si vous utilisez le mode planification), l’exécution s’arrête automatiquement, sans rappeler l’agent : le résumé affiché (« Livrable enregistré et transmis (N partie(s), M mots). ») est composé par la plateforme, pas rédigé par l’agent. Inutile de lui demander de résumer ce qu’il a envoyé en fin de réponse.
  • Une livraison qui atteste de sources jamais ouvertes est refusée. Sur une tâche de veille, si l’exécution n’a ouvert aucune page (aucune lecture d’URL réussie) et que le rapport présente malgré tout des sources comme « consultées », « vérifiées » ou « rien à signaler », l’envoi est bloqué et l’agent reçoit l’explication : il doit ouvrir les pages, ou signaler ces sources comme non consultées. Vous voyez l’étape en échec dans le déroulé de l’exécution, avec son motif. Signaler une source comme non consultée est une information utile, pas un aveu : c’est une veille courte et juste plutôt qu’une veille étoffée et fausse. Dès qu’au moins une page a été ouverte, la livraison passe.

Le résultat que l’agent reçoit de deliver dit ce qui s’est passé, pour qu’il n’annonce jamais un envoi qui n’a pas eu lieu : le détail par destination (delivered, avec le motif de chaque échec), les compteurs ok_count et failed_count, et attached, la liste des fichiers réellement joints. Un identifiant de fichier qui n’existe pas pour cette exécution n’est ni ignoré ni joint : il figure dans missing_files, avec une note qui précise que le fichier n’est pas parti. Quand rien n’est envoyé (tâche sans destination, ou relance sans envoi), le livrable est enregistré dans l’exécution et la note le dit.

Vous n’avez rien à activer : l’outil apparaît dès qu’une destination existe. Pour l’inciter à s’en servir, dites-le dans le prompt, par exemple « envoie le rapport section par section, suite s’en charge, inutile de le demander en fin de prompt ».

Activé via checklist sur PATCH /v1/tasks/{slug} (le réglage n’est pas exposé dans le formulaire du portail ; le playground reste l’endroit où l’essayer), il demande au modèle d’établir une liste d’étapes avant de travailler, puis de la cocher au fil de l’eau. La liste lui est re-montrée à chaque tour et doit être entièrement terminée avant qu’il conclue.

Il sert quand une tâche enchaîne beaucoup de gestes et en oublie à la fin : livrer le résultat, journaliser, poser une facette de clôture. Il coûte un tour de plus à chaque exécution, et il est donc désactivé par défaut.

Chaque étape a un statut : pending, in_progress ou done. Les formulations courantes d’un modèle sont comprises (completed, finished, terminé, fait, in progress, en cours, todo, à faire…), quelle que soit la casse ou le séparateur. Un statut que la liste ne reconnaît pas est lu comme pending, et le compte rendu rendu au modèle le dit : une étape cochée ne redevient jamais ouverte en silence.

Une tâche récurrente redécouvre son chemin à chaque run : l’objectif, la forme du livrable, les étapes à suivre. Le contrat d’exécution capture tout cela une fois et le fait relire par le modèle à chaque exécution suivante, au lieu de le laisser le redécouvrir (et le repayer en tokens) à chaque fois.

Un contrat porte :

  • un objectif (une phrase, 300 caractères au plus) ;
  • le livrable attendu (forme, longueur et ton) ;
  • de 1 à 7 critères de réussite vérifiables ;
  • de 1 à 8 étapes, chacune avec, si pertinent, l’outil qui la clôt ;
  • les sources habituellement consultées (bases ou URL) ;
  • l’état retenu d’un run à l’autre (une synthèse courte, pas une mémoire structurée) ;
  • un budget attendu (tours, tokens), pour donner au modèle une idée de l’ampleur.

Il se lit et s’édite dans le tableau de bord de la tâche (carte « Contrat d’exécution ») ou par l’API. Une tâche sans contrat se comporte exactement comme avant : le mécanisme est entièrement optionnel.

Le prompt dit quoi faire. Le contrat dit comment le refaire à chaque fois.

PromptContrat d’exécution
RôleLa demande : le sujet, les données à utiliser, à qui s’adresse le résultatLa manière de faire : forme du résultat, étapes, vérifications
ObligatoireOuiNon
Quand l’écrireÀ la création de la tâcheUne fois la tâche rodée, après quelques exécutions réussies
Variables (${date}…) et documents cités par @OuiNon
Contrôlé par MiracaNonLes étapes liées à un outil
Exemple« Faites la veille des annonces IA de la semaine pour l’équipe. »Livrable : e-mail en trois sections. Étapes : chercher (web_search), lire, envoyer. Critère : chaque annonce cite sa source.

Tout pourrait tenir dans le prompt, et pour une tâche simple c’est suffisant. Le contrat apporte trois choses en plus :

  • un contrôle : une étape suivie d’un outil (par exemple « Chercher les annonces | web_search ») est vérifiée par Miraca ; si l’outil n’a jamais été appelé avec succès, le modèle est relancé une fois avant que le résultat parte ;
  • une proposition depuis les exécutions réussies (voir plus bas), que vous relisez avant de l’adopter ;
  • un historique : chaque version est numérotée, et chaque exécution garde le contrat sous lequel elle a tourné.

Le contrat est lu par le même modèle que le prompt, dans la même exécution. Les critères de réussite lui sont rappelés avant l’envoi, mais ne sont pas vérifiés par un autre modèle.

Plutôt que de le rédiger à la main, le tableau de bord propose, dès que la tâche compte au moins 3 exécutions réussies, de compiler un contrat à partir de ses derniers runs : un modèle relit les 5 dernières exécutions réussies (et les avis humains déjà posés dessus) et propose un contrat, affiché en différence avec le contrat actuel. Rien n’est appliqué automatiquement : la proposition attend un clic « Adopter » (ou « Écarter »).

Une proposition qui ne respecte pas les règles d’un contrat (texte rendu trop long, étape close par un outil que la tâche n’a pas) est renvoyée une fois au modèle, avec la raison du refus, pour qu’il la corrige. Ce second appel est facturé comme le premier. Si la correction est encore refusée, le tableau de bord affiche la raison : relancez la proposition ou rédigez le contrat à la main.

Si les deux dernières exécutions terminées ont échoué (une exécution en attente, en cours ou annulée n’est pas comptée), un bandeau signale que le contrat semble dépassé et suggère de le recompiler.

GET/PATCH /v1/tasks/{slug} exposent le contrat dans le corps de la tâche :

{
"execution_brief": {
"objectif": "Résumer les factures de la semaine et en vérifier le total.",
"livrable": { "forme": "email", "longueur": "5 lignes", "ton": "neutre" },
"criteres": [
"Chaque montant cite sa facture source.",
"Le total est recalculé, pas estimé."
],
"etapes": [
{ "titre": "Chercher les factures de la semaine", "outil_de_cloture": "kb_search" },
{ "titre": "Livrer le résumé", "outil_de_cloture": "deliver" }
],
"sources": ["factures"],
"etat": "Semaine du 22 déjà couverte.",
"budget_attendu": { "tours": 4, "tokens": 8000 }
},
"execution_brief_version": 3,
"has_execution_brief_proposal": false,
"execution_brief_proposal": null
}

PATCH avec "execution_brief": { … } remplace le contrat et incrémente execution_brief_version ; "execution_brief": null l’efface. Un contrat qui ne respecte pas les bornes ci-dessus (objectif trop long, aucune étape, plus de 7 critères…) renvoie 400 avec le détail du problème. execution_brief_proposal est en lecture seule par cette route : une proposition en attente s’adopte ou s’écarte seulement depuis le tableau de bord.

L’export d’un run (GET /v1/tasks/{slug}/runs/{run_id}) porte execution_brief_version : la version du contrat en vigueur au moment de ce run précis, même si la tâche a été recompilée depuis.

Par défaut, il n’y en a pas. Le modèle s’arrête quand il a fini de répondre, qu’il lui faille trois lignes ou quinze pages. Une tâche peut produire un livrable (rapport de veille, synthèse mensuelle) bien plus long qu’une réponse de chat, et rien ne vient le raboter.

Le champ Longueur maximale de la réponse sert donc à l’inverse : imposer une limite, en tokens de sortie (minimum 256 ; comptez environ 750 mots pour 1 000 tokens). Utile pour garantir des réponses courtes, ou pour borner une dépense. Laissé vide, il reprend le réglage de l’organisation (page Assistant), et à défaut il n’y a aucune limite.

Ce qu’il faut savoir si vous en posez un : au-delà du plafond, la réponse est coupée — et le dit. Le résultat porte alors une mention explicite de troncature, dans le tableau de bord comme dans l’email. Une réponse incomplète ne se fait jamais passer pour complète.

Un tour coupé par le plafond n’exécute ni écriture ni livraison : les arguments d’un outil coupé en plein milieu seraient incomplets, et un rapport amputé partirait par e-mail ou Slack. Ne sont donc pas lancés avec des arguments coupés : la livraison (deliver), l’ajout ou la modification dans une base ou une note, les actions d’une boîte mail, d’un agenda ou des fichiers d’un compte connecté, la mémoire, et les opérations d’écriture d’un connecteur. Le modèle en est informé et ré-émet son appel en entier au tour suivant, où il s’exécute. Les lectures et les scripts ne sont pas concernés.

Reste que générer prend du temps, et qu’un run n’est pas éternel : s’il dépasse le temps qui lui est imparti, la tâche rend ce qu’elle a produit jusque-là, avec une mention de réponse partielle. Si votre tâche produit régulièrement de longs documents, deux approches valent mieux qu’une seule réponse massive :

  • donnez-lui une base de connaissance en écriture et demandez-lui d’y écrire le document, la réponse ne portant qu’un résumé. Le document est alors consultable, cherchable et versionné, au lieu de vivre dans un email ;
  • ou faites-lui envoyer le livrable en plusieurs fois avec l’outil de livraison (section précédente) : chaque envoi a son propre budget.

Par API : champ output_max_tokens sur PATCH /v1/tasks/{slug}, ou le paramètre standard max_tokens sur /v1/chat/completions.

Le sélecteur de l’éditeur de tâche propose tous les modèles disponibles pour votre organisation (Gestion → Modèles), y compris ceux que vous ne proposez pas dans l’assistant. La colonne « Assistant » de cette page borne ce que vos utilisateurs peuvent choisir dans leurs conversations ; elle ne borne pas les automatisations que vous configurez vous-même au portail — sans quoi employer un modèle dans une tâche programmée obligerait à l’ouvrir à toute l’organisation.

À la création, le champ est pré-rempli avec le modèle de votre dernière tâche modifiée : on outille ses automatisations les unes après les autres, avec le même modèle. C’est une proposition, pas une contrainte — elle est figée dans la tâche créée, et modifier une tâche ne change jamais le modèle d’une autre.

« Modèle par défaut » suit le défaut « Tâches » de Gestion → Modèles s’il est réglé, sinon celui de l’assistant ; il peut donc changer. Pour choisir en connaissance de cause, voir Banc d’essai des modèles.

Chaque tâche a un niveau de réflexion, de 1 à 5 : Direct, Rapide, Standard (le défaut, y compris pour les tâches créées avant ce réglage), Approfondi et Maximal. C’est un seul réglage, que Miraca traduit pour le modèle qui exécute la tâche : le nombre de tours d’outils (1, 3, 8, 20 ou 99) et le raisonnement du modèle (le niveau visé s’il le propose, sinon celui qu’il propose juste en dessous ; voir le niveau de réflexion dans la référence). Vous n’avez donc plus à connaître les niveaux de raisonnement propres à chaque modèle : changer de modèle garde le même niveau, traduit pour le nouveau.

Choisissez selon la nature du travail : une tâche mécanique (extraire, reformater) tient en Direct ou Rapide ; une analyse croisée de plusieurs sources profite d’Approfondi. Un niveau plus haut coûte plus cher à chaque exécution.

Au portail, le champ Niveau de réflexion se trouve sous le choix du modèle, dans l’éditeur de la tâche ; chaque niveau y est décrit en une phrase. Une tâche neuve part du niveau par défaut de votre organisation (Gestion : Assistant), qu’elle soit créée au portail, proposée par l’assistant dans une conversation ou composée par le copilote (la carte de confirmation affiche ce niveau). C’est le seul réglage de profondeur que le portail propose : le nombre maximal de tours d’outils, le niveau de raisonnement propre au modèle et le mode planification n’y figurent plus. Le niveau choisi apparaît aussi dans la configuration de la tâche, sur sa page.

Les réglages experts priment : un nombre de tours (max_steps), un niveau de raisonnement (reasoning_effort, section suivante) ou le mode planification, s’ils sont posés sur la tâche, remplacent ce que le niveau aurait décidé. Une tâche réglée à la main garde donc exactement son comportement. Quand une tâche en porte, l’éditeur l’indique sous le niveau (« Réglages experts conservés, qui priment sur le niveau : … »), et le lien Les retirer les efface à l’enregistrement : le niveau reprend alors seul la main. L’organisation, elle, choisit les niveaux permis (page Assistant) : une tâche réglée sur un niveau éteint s’exécute au niveau permis le plus proche en dessous (ou au plus bas permis), sans échouer. Une organisation qui avait monté son ancien plafond de tours au-dessus de 8 avant l’arrivée des niveaux retrouve ses tâches avec ce nombre de tours en réglage expert (il préserve leur comportement d’avant).

Le coût estimé qu’affiche la carte d’une tâche proposée par l’assistant se calcule sur les exécutions des tâches du même niveau. Sans exécution comparable au-dessus de Standard, la carte donne un minimum (« ≥ ») et le dit : le coût réel sera plus élevé.

Par API : champ niveau sur PATCH /v1/tasks/{slug}, en entier (4) ou en clé ("approfondi") ; une valeur illisible est refusée (400) plutôt que ramenée en silence à Standard. GET renvoie niveau (l’entier) et niveau_cle. Une tâche proposée depuis une conversation de l’assistant porte elle aussi un niveau, affiché sur sa carte.

Certains modèles réfléchissent avant de répondre. Cette réflexion n’apparaît pas dans le résultat mais elle est facturée en tokens de sortie — et sur une tâche quotidienne, c’est une dépense qui revient tous les jours.

Ce réglage ne se pose plus que par API : le portail propose à sa place le niveau de réflexion, que Miraca traduit pour chaque modèle. Les niveaux acceptés dépendent du modèle (voir reasoning_efforts dans Modèles & pricing) :

  • absent (null) : c’est le niveau de réflexion de la tâche qui décide ;
  • none : coupe la réflexion. À privilégier sur les tâches répétitives et cadrées, où la procédure est déjà écrite dans le prompt ;
  • high : à réserver aux tâches d’analyse, où le raisonnement change le résultat.

Si vous changez de modèle au portail pour un modèle qui n’accepte pas le niveau de raisonnement posé, celui-ci est retiré à l’enregistrement, et le niveau de réflexion reprend la main. Posé par API sur un modèle qui ne l’accepte pas, il est ignoré au moment de l’exécution : une tâche programmée ne doit pas échouer sur un réglage expert.

Par API : champ reasoning_effort, réglable par PATCH /v1/tasks/{slug} et renvoyé par GET (y compris dans la réponse du PATCH lui-même), pour vérifier qu’un réglage envoyé a bien été enregistré sans repasser par le portail. Posé, il prime sur le niveau de réflexion ; null le retire, et le niveau reprend la main.

Chaque tâche a un réglage Exécutions simultanées (1 à 20, défaut 3) : le nombre de runs qui peuvent tourner en parallèle. Quand plusieurs déclenchements arrivent en même temps (par exemple plusieurs documents qui bougent lors d’un import), les runs au-delà de cette limite sont mis en file et s’exécutent dès qu’un créneau se libère, dans l’ordre d’arrivée. Aucun déclenchement n’est perdu (contrairement à un simple « saut »).

  • 1 : les runs s’enchaînent un par un — utile pour une tâche qui relit son historique (mode Dernier résultat), où l’ordre compte.
  • 3 (défaut) et au-delà : jusqu’à N runs en parallèle — plus rapide sur une rafale. Au-delà de ~3 runs agentiques d’une même personne, le débit est de toute façon borné par la limite de la clé (les runs supplémentaires patientent en file).

Un plafond de sécurité borne la file en cas d’emballement (import très volumineux) : au-delà, les déclenchements supplémentaires sont ignorés et tracés.

Si le fournisseur du modèle sature, dépasse son délai, est indisponible ou refuse la requête, l’exécution n’envoie jamais le message d’incident comme s’il était le rapport : rien ne part par e-mail, Slack ou webhook, et l’exécution ne se termine pas en « Terminée ».

  • Saturation, délai dépassé, indisponibilité : l’exécution est reprise automatiquement. Une saturation est reportée sans consommer de tentative. Si les tentatives sont épuisées, l’exécution est en échec et le message du fournisseur figure dans l’historique.
  • Refus du fournisseur (par exemple une requête que ce modèle ne prend pas en charge) : l’exécution est en échec tout de suite et n’est pas rejouée, puisque la même requête serait refusée de la même façon. Le motif est dans l’historique ; changer le modèle ou le prompt de la tâche s’impose.

Si le serveur est interrompu pendant une exécution (coupure, déploiement, plantage), le run est repris automatiquement à la minute suivante : il n’est ni perdu, ni laissé indéfiniment « en cours ». Le plafond d’exécutions simultanées reste respecté pendant la reprise.

L’exécution redémarre depuis le début du prompt — le travail déjà effectué par le modèle n’est pas rejoué à l’identique. Une tâche qui écrit dans une base doit donc rester idempotente (utiliser external_id pour un ajout, par exemple) si elle peut être reprise.

Une tâche planifiée bénéficie de la même tolérance : si le service qui déclenche les plannings est indisponible au moment précis où votre tâche devait partir (une interruption courte), le déclenchement est rattrapé dans les dix minutes qui suivent le retour du service, sans intervention de votre part. Au-delà de ce délai, ou si la tâche a été modifiée entre-temps, la minute manquée n’est plus rattrapée (pour ne pas déclencher, au retour d’une panne plus longue, une rafale d’exécutions qui ne correspondent plus à ce que vous avez programmé).

Une tâche est désactivée automatiquement si la personne qui l’a créée quitte l’organisation, ou perd l’accès au portail (rétrogradée dans un rôle qui n’en a pas). Une tâche s’exécute toujours au nom de son créateur : sans cet accès, elle n’a plus de périmètre valide à réutiliser.

La désactivation est signalée par un bandeau sur la carte de la tâche et sur son tableau de bord, avec le motif, et toutes ses exécutions encore en attente sont annulées plutôt que laissées à échouer une par une. Par API, ces informations se lisent avec enabled: false et disabled_reason sur GET/PATCH /v1/tasks/{slug}.

Pour réactiver une tâche désactivée automatiquement (PATCH avec {"enabled": true}, ou le bouton du portail), la personne qui l’a créée doit avoir retrouvé l’accès au portail : sinon la réactivation est refusée, avec le même motif. Une fois réactivée, le motif disparaît.

Le planning d’une tâche (schedule_cron) et la variable ${date} se lisent dans le fuseau de la tâche (schedule_tz, Europe/Paris par défaut). Un fuseau s’écrit comme un nom IANA, par exemple Europe/Paris ou America/New_York. Un nom que le serveur ne connaît pas (Paris, CET+1, UTC+1) est refusé à l’enregistrement : au portail, par le copilote et par l’API (PATCH /v1/tasks/{slug} répond 400 avec un exemple valide).

Une tâche enregistrée avant ce contrôle avec un fuseau illisible n’est plus exécutée à l’heure UTC : ses déclenchements sont refusés (409 par l’API, une exécution canceled dans l’historique pour un déclenchement planifié, et pour un déclenchement par un document à raison d’une par heure au plus) tant que le fuseau n’est pas corrigé. Désactiver la tâche reste possible.

Chaque tâche accepte un plafond de dépense, au total et/ou par jour (en euros, vides par défaut = pas de plafond). Une fois le plafond atteint, les déclenchements suivants sont ignorés plutôt qu’exécutés, avec une trace dans l’historique expliquant le blocage. Le budget quotidien se réinitialise à minuit, dans le fuseau de la tâche.

C’est le garde-fou à poser sur une tâche déclenchée par événement, dont le rythme dépend d’une source que vous ne maîtrisez pas entièrement (un import massif, une synchronisation, une autre tâche qui écrit). Un plafond en euros borne ce qui compte vraiment, la dépense, là où un simple nombre d’exécutions ne dit rien du coût réel.

Le coût d’une exécution n’étant connu qu’une fois celle-ci terminée, le contrôle porte sur la dépense déjà engagée : la dernière exécution peut donc dépasser légèrement le plafond. Réglez-le en conséquence si votre marge est serrée.

Une tâche peut, en option, relire ses propres exécutions passées (réglage dans le portail) : soit son dernier résultat, soit tout son historique (recherche). C’est utile pour des tâches incrémentales, par exemple « ne me signale que les nouveautés depuis le dernier passage ». C’est une lecture seule de ses propres sorties.

En mode dernier résultat, la tâche relit sa dernière exécution réussie lancée dans les mêmes conditions :

  • à la main, sur planning ou par l’API : la dernière exécution aux mêmes valeurs de variables. Une tâche paramétrée par ${dossier} garde ainsi une mémoire par dossier. Le context joint à un appel de l’API n’entre pas en compte : deux appels aux mêmes variables se relisent, quel que soit le contexte fourni ;
  • par un document : la dernière exécution pour ce même document et ce même événement. Une tâche abonnée aux modifications relit ce qu’elle avait produit à la modification précédente de la fiche. Une tâche abonnée aux seuls ajouts n’a pas de précédent à relire, puisqu’un document n’est ajouté qu’une fois.

Le résultat relu est placé en tête de la consigne, tronqué au-delà de 6 000 caractères : il compte dans les jetons d’entrée de l’exécution. Une relance avec option (sans envoi, autre modèle) n’est jamais relue.

Dans le mode historique complet, le filtre de statut de la recherche accepte les statuts d’une exécution (done, failed, pending, running, canceled) ou any pour toutes ; une valeur inconnue est signalée avec la liste des statuts, elle ne rend jamais « aucune exécution ».

Sur le tableau de bord d’une tâche, ouvrez une exécution réussie et laissez un feedback (« trop long », « cite tes sources », « tu as oublié les factures d’achat »). Ce retour est relu par la tâche à ses exécutions suivantes — via la mémoire d’exécution ci-dessus (il faut donc que « Accès à l’historique » soit réglé sur Dernier résultat ou Historique complet). C’est ainsi qu’une tâche s’améliore au fil du temps, sans que vous ayez à réécrire son prompt.

Écrire un bon feedback suppose de relire le résultat et le déroulé. Le bouton Demander un avis, au-dessus du champ, fait ce travail pour vous : le modèle relit la consigne de la tâche, ce qu’elle a réellement fait (outils appelés, échecs) et ce qu’elle a produit, puis propose un retour en quelques consignes actionnables.

Vous choisissez le modèle et, si votre organisation en a défini, la personnalité qui donne le ton. La proposition atterrit dans le champ, éditable : relisez-la, ajustez-la, puis enregistrez. Rien n’est posé sans votre validation, et l’analyse est facturée comme une requête ordinaire (sur votre consommation, au sein de l’organisation).

  • Nom : 200 caractères. Description : 2 000 caractères. Prompt : 50 000 caractères. Schéma de sortie (format JSON) : 100 000 caractères une fois sérialisé.
  • Variables déclarées : 50 au plus, description et valeur par défaut de chacune bornées à 2 000 caractères.
  • inputs d’un déclenchement : 50 clés au plus, chaque valeur tronquée à 8 000 caractères. Au-delà, les clés en trop sont ignorées plutôt que de faire échouer l’appel.
  • Le champ context d’un déclenchement (POST /v1/tasks/{slug}/run) est limité à 32 000 caractères.

Ces bornes protègent contre un abus ou une erreur de saisie (un objet inputs de plusieurs mégaoctets rejoué à chaque exécution) : aucune tâche ordinaire ne les approche.

Deux actions no-code, identiques d’une plateforme à l’autre :

  • Lister les tâches (GET /v1/tasks) : pour construire un menu dynamique de tâches.
  • Déclencher une tâche (POST /v1/tasks/{slug}/run) : sélection de la tâche dans une liste, inputs (objet JSON) et une option Attendre le résultat. Combinée à une sortie webhook de la tâche, cela ferme la boucle : votre scénario déclenche la tâche, la tâche répond sur le webhook du scénario. Trois champs optionnels complètent le déclenchement, avec la même signification que sur l’appel API brut (voir Relancer une exécution plus haut) : replay_of (relancer une exécution passée), deliver (n’envoyer aucune sortie) et model (comparer sur un autre modèle).

⚠️ L’option Attendre le résultat a ses limites côté plateforme no-code, indépendantes du délai serveur de Miraca : Zapier plafonne une action standard à 30 secondes (non extensible) et Make plafonne un module HTTP par défaut à 40 secondes. Sur une exécution un peu longue, c’est donc votre scénario qui expirera en premier, avant même que Miraca ait répondu. Pour une tâche susceptible de dépasser ces délais (déclenchée par événement, ressources volumineuses), préférez ne pas activer Attendre le résultat et fermez la boucle avec la sortie webhook de la tâche plutôt qu’avec une attente active.

Voir n8n / Make / code pour la configuration des connexions.

Un troisième réglage d’« Accès à l’historique », distinct des deux précédents : Espace de travail (état persistant), valeur history_access: "etat" en API. La tâche reçoit alors un espace de travail dédié, avec deux tiroirs :

  • un tiroir d’état, qui persiste d’une exécution à l’autre (identifiants déjà traités, curseur de pagination, courte synthèse), plafonné à 64 Ko au total ;
  • un tiroir de travail, vidé au début de chaque exécution.

C’est le réglage adapté à une veille incrémentale : la tâche y note ce qu’elle a déjà vu, et ne le recherche plus à l’exécution suivante. Contrairement au « dernier résultat » (qui ne conserve qu’un texte), l’état est structuré et lisible/modifiable dans le tableau de bord de la tâche, section « Mémoire de la tâche » : vous y voyez chaque entrée (nom, taille, date), pouvez la relire, la corriger, ou remettre la mémoire à zéro (action irréversible).

Une entrée d’état non réécrite depuis 180 jours est automatiquement supprimée.

⚠️ Une tâche en mode « Espace de travail » est limitée à une seule exécution simultanée : le tiroir de travail est vidé par chaque exécution, deux exécutions en parallèle se videraient l’une l’autre leur propre travail.

Sur l’API publique, history_access accepte les quatre valeurs "none" (défaut), "last" (dernier résultat), "full" (historique complet) et "etat" (espace de travail ci-dessus) sur PATCH /v1/tasks/{slug} ; toute autre valeur est refusée (400). La mémoire d’une tâche en mode "etat" ne se lit ni ne s’écrit par l’API publique : elle passe uniquement par le tableau de bord.