Aller au contenu principal
Version: 1.0.0

Trigger

Un trigger décrit une entrée événementielle gouvernée.

Il répond à la question :

Définition
quand cet événement arrive,
lance cette stratégie Touba,
avec ces limites,
si le manifest l'active explicitement.

Un trigger n’est pas un cron libre, un webhook direct ou un handler qui décide seul de lancer un agent. Dans Touba, le trigger compile vers l’AIR, le manifest l’active, le runtime vérifie, puis la trace rend l’acceptation ou le refus observable.

Syntaxe​

daily_research.tb
trigger DailyResearchSchedule
on schedule "every 1s"
runs strategy DailyResearch
limits
max_runs_per_day as 1
timeout_ms as 30000

Touba accepte deux familles V1 :

Forme
trigger Name
on schedule "every 1s"
runs strategy StrategyName
limits
max_runs_per_day as 1
timeout_ms as 30000

trigger WebhookRun
on request POST "/webhook/run"
runs strategy StrategyName
with message as payload.message
limits
max_runs_per_day as 10
timeout_ms as 30000

Le runner schedule supporte les intervalles every <n>s, every <n>m et every <n>h. Le service d’ingress HTTP route les triggers request selon la méthode et le chemin déclarés. Sur un trigger request, une expression payload.<champ> dans une clause with déclare qu’un argument de stratégie doit être extrait du JSON entrant. Cette expression n’est pas une lecture générale du payload : elle compile vers un contrat de mapping, et le corps HTTP brut n’est pas stocké dans l’AIR, la queue, l’état ou la trace.

Exemple complet​

daily_research.tb
module examples.daily_research

strategy DailyResearch
takes topic as Text
do
show
with message as "Daily research run: " ++ topic

trigger DailyResearchSchedule
on schedule "every 1s"
runs strategy DailyResearch
with topic as "daily review"
limits
max_runs_per_day as 1
timeout_ms as 30000

Manifest​

Le trigger reste inactif tant que le manifest ne l’active pas.

touba.manifest.json
{
"manifest_version": "touba-manifest-v1",
"triggers": {
"trigger:examples.daily_research/DailyResearchSchedule": {
"enabled": true,
"source": {
"kind": "schedule"
},
"limits": {
"max_runs_per_day": 1,
"timeout_ms": 30000
}
}
}
}

Le manifest peut restreindre une limite déclarée dans le code Touba. Il ne peut pas l’élargir silencieusement.

Runner foreground​

Terminal
touba trigger run daily_research.air.json \
--manifest touba.manifest.json \
--trigger trigger:examples.daily_research/DailyResearchSchedule \
--max-runs 1 \
--state touba.triggers.sqlite

Le runner attend l’intervalle déclaré, génère un événement normalisé, puis laisse le runtime vérifier le manifest et les limites avant d’exécuter la stratégie. --max-runs est obligatoire. Le registre SQLite est créé par défaut dans .touba/triggers.sqlite ; --state permet de choisir son emplacement. L’état durable conserve les event_id, les refus et la clé de jour UTC utilisée par max_runs_per_day.

Service webhook​

Terminal
touba trigger serve webhook.air.json \
--manifest touba.manifest.json \
--state touba.triggers.sqlite \
--queue touba.trigger-queue.sqlite \
--host 127.0.0.1 \
--port 8787 \
--trace-dir traces

Le service ouvre un endpoint HTTP pour chaque trigger request activé par le manifest. Une requête POST /webhook/run est convertie en événement normalisé source_kind=request, placée dans la queue durable touba-trigger-queue-v1, puis exécutée par le runtime. Le payload HTTP brut n’est pas écrit dans la queue, l’état ou la trace ; le service conserve les métadonnées nécessaires, dont la taille et le digest SHA-256 du corps reçu.

Le manifest peut déclarer un contrat payload. Dans ce cas, le service accepte uniquement le format, les content-types et la taille déclarés, puis extrait les champs JSON listés dans payload.map. Ces champs deviennent les seuls arguments persistés de la stratégie cible, et le runtime les revalide contre la signature Touba avant l’exécution.

Quand le source Touba contient with message as payload.message, l’AIR porte le contrat correspondant et touba manifest generate produit l’entrée payload.map initiale :

touba.manifest.json
{
"triggers": {
"trigger:examples.webhook/WebhookRun": {
"enabled": true,
"source": { "kind": "request" },
"limits": {
"max_runs_per_day": 10,
"timeout_ms": 30000
},
"payload": {
"format": "json",
"content_types": ["application/json"],
"max_bytes": 65536,
"map": {
"message": "$.message"
}
}
}
}
}

Le header x-touba-event-id permet à l’appelant de fournir une identité d’événement stable. Si le même event_id est rejoué pour le même trigger, l’état TD-1 provoque un refus TriggerReplayRejected avant de relancer la stratégie. Sur une interface non loopback, le service exige --auth-token-env. Pour les webhooks exposés à un fournisseur externe, --signature-secret-env ajoute une vérification HMAC-SHA256 via x-touba-signature: sha256=<hex>. La queue remet en attente les entrées processing périmées et peut marquer les échecs répétés en dead_lettered.

Trace​

Un run déclenché par trigger peut produire des événements comme :

  • trigger_event_received
  • trigger_event_accepted
  • trigger_event_refused
  • trigger_execution_started
  • trigger_execution_completed

Les traces ne doivent pas contenir le payload externe brut, les secrets ou les credentials.

Contrat runtime​

info
  • Les entrées schedule et request gouvernées compilent vers l’AIR.
  • Le manifest active explicitement chaque trigger.
  • Le runtime vérifie les limites avant l’exécution.
  • Le service webhook persiste une queue touba-trigger-queue-v1.
  • Le payload JSON entrant est contractualisé depuis le source Touba et le manifest.
  • La signature HMAC-SHA256, les retries bornés, la reprise processing et le dead-letter sont disponibles.
  • Les schedulers distribués, queues distribuées, adapters cloud, déclenchements directs d’agents, auto-discovery de manifest et sandbox système complète relèvent de couches plateforme séparées.