Créer un tool réel
Ce guide montre le parcours utilisateur pour relier un tool Touba à un handler.
1. Déclarer le contrat Touba
module examples.fetch_source
type FetchRequest
query is Text
type FetchResponse
body is Text
tool FetchSource
takes request as FetchRequest
gives FetchResponse
requires network
skill BuildSource
takes request as FetchRequest
gives FetchResponse
do
FetchSource
with request as request
into source
give source
Le fichier .tb ne contient pas de JavaScript ou de Python. Il déclare uniquement le contrat.
2. Préparer les artefacts
Dans un projet Touba :
touba prepare --mode plan
touba prepare --mode write
touba prepare --mode check
Résultat attendu :
- l’AIR est produit ;
- le manifest projet reçoit le binding du tool ;
- un squelette de handler est créé si nécessaire.
Le parcours manuel reste utile pour comprendre chaque étape séparément.
3. Compiler manuellement
touba compile fetch-source.tb --out fetch-source.air.json
4. Générer le manifest manuellement
touba manifest generate fetch-source.air.json --out touba.manifest.json
Relisez le manifest avant exécution. Le runtime ne le cherche pas automatiquement.
Vous pouvez y ajouter des contraintes simples sur le payload quand elles font partie du contrat d’exécution :
{
"bindings": {
"tool:examples.fetch_source/FetchSource": {
"payload_constraints": {
"input": {
"request.query": {
"non_empty": true,
"max_length": 120
},
"request.mode": {
"allowed_values": ["dry_run", "review", "execute"]
}
}
}
}
}
}
Le runtime vérifie cette contrainte après le schéma AIR et avant le handler. Le handler peut garder une validation défensive, mais il ne doit pas être la seule autorité pour ces limites simples.
allowed_values sert à fermer un champ sur un ensemble explicite de valeurs
autorisées, par exemple un mode d’exécution, un statut métier, un niveau de
risque ou une région supportée. La liste accepte seulement des scalaires JSON
portables (Text, Boolean, Int, Float) afin que le même contrat reste
exécutable par plusieurs runtimes Touba.
5. Générer le squelette de handler manuellement
touba handler stub fetch-source.air.json \
--tool-ref tool:examples.fetch_source/FetchSource \
--handler-root handlers
Le squelette refuse l’écrasement d’un fichier existant par défaut.
6. Implémenter le handler
import { defineTool } from "@touba/sdk";
await defineTool({
toolRef: "tool:examples.fetch_source/FetchSource",
inputSignature: [{ name: "request", type_ref: "type:examples.fetch_source/FetchRequest" }],
outputType: "type:examples.fetch_source/FetchResult",
requiredGrants: ["network"],
run: async ({ request }) => {
return {
body: `Result for ${request.query}`,
};
},
});
Pour un handler réel, remplacez le corps par l’appel nécessaire : API HTTP, base de données, service interne ou autre ressource hôte.
7. Exécuter
touba run fetch-source.air.json \
--manifest touba.manifest.json \
--inputs-json '{"request":{"query":"touba"}}' \
--trace-out trace.json
Par défaut, la sortie standard affiche les messages produits par show. Pour inspecter directement la valeur retournée par le programme :
touba run fetch-source.air.json \
--manifest touba.manifest.json \
--inputs-json '{"request":{"query":"touba"}}' \
--output result
À retenir
- Le fichier
.tbreste le contrat logique. - Le manifest est le raccordement explicite.
- Le handler est du code hôte borné.
- Le runtime reste l’autorité avant dispatch pour grants, secrets, scopes, schémas de payload et contraintes de payload.
showproduit la sortie utilisateur.--output resultaffiche la valeur retournée.--trace-outconserve l’audit d’exécution.