Tool Payload Defaults
Goa-AI génère à partir de votre design Goa des structures typées pour les charges utiles d’outils, des schémas JSON et des codecs. Cette page décrit un comportement essentiel : l’application des valeurs par défaut aux charges utiles d’outils, et la raison pour laquelle elle dépend de la représentation des champs par pointeur ou par valeur.
Cette implémentation suit le modèle HTTP de Goa : décodage du corps → transformation.
Résumé
- Décoder le JSON dans un type auxiliaire dont les champs sont des pointeurs (la forme « decode-body ») afin que le codec distingue une valeur absente d’une valeur nulle.
- Transformer le type auxiliaire en charge utile finale avec
codegen.GoTransformde Goa. - Pour les charges utiles d’outils, la structure finale respecte la sémantique des valeurs par défaut de Goa : les primitives facultatives assorties d’une valeur par défaut peuvent devenir des valeurs (et non des pointeurs), ce qui permet à
GoTransformd’injecter les valeurs par défaut de manière déterministe.
Si ces contextes ne correspondent pas, le générateur peut produire des tests de nil ou des affectations invalides, et le code généré ne compile pas.
Les deux représentations
1) Type auxiliaire de décodage JSON (champs pointeurs)
Le JSON entrant est décodé dans une structure auxiliaire dont les champs primitifs sont des pointeurs :
- champ absent →
nil - champ fourni → pointeur non nil
Cette représentation sert à :
- vérifier les champs obligatoires ;
- attribuer précisément les erreurs de validation ;
- déterminer si l’appelant a fourni un champ.
2) Type final de la charge utile (avec valeurs par défaut)
Le type final de la charge utile est celui que consomment les adaptateurs et les exécuteurs.
Pour les charges utiles, les primitives facultatives assorties d’une valeur par défaut sont générées sous forme de valeurs, afin que la transformation applique les valeurs par défaut de manière déterministe.
Application des valeurs par défaut
Les valeurs par défaut sont appliquées pendant la transformation du type auxiliaire vers la charge utile :
- le type auxiliaire contient des pointeurs
nilpour les champs absents ; - la charge utile cible utilise des représentations compatibles avec les valeurs par défaut ;
codegen.GoTransformde Goa génère le code qui :- copie les valeurs lorsque les pointeurs du type auxiliaire ne sont pas nil ;
- affecte les littéraux par défaut lorsque ces pointeurs sont nil et qu’une valeur par défaut existe.
Validation à la frontière et erreurs de contrat
Les codecs d’outils générés constituent la frontière entre le JSON produit par
le modèle et les valeurs typées Goa-AI. Ils ne se contentent pas d’appeler
json.Unmarshal :
- les charges utiles et résultats qui sont des objets fermés refusent les champs inconnus ;
- un champ inconnu produit un problème structuré
unknown_fieldqui indique les clés autorisées à cet emplacement ; - une incompatibilité de type JSON produit un problème structuré
invalid_field_typecontenant les noms générés des types JSON attendu et observé ; - les codecs de résultats limités n’acceptent que les champs sémantiques du
résultat et les champs limités canoniques de Goa-AI (
returned,total,truncated,refinement_hintet, facultativement,next_cursor).
Un appel produit par le modèle qui ne respecte pas ce contrat est refusé avant
d’atteindre le planificateur ou l’exécuteur. Le client de modèle validé renvoie
model.OutputValidationError, puis le planificateur ou le runtime présente
l’échec sous forme de planner.OutputContractError, sans lancer de requête de
correction. Pour un appel construit par le planificateur,
planner.NewToolRequest renvoie directement l’erreur d’encodage.
La récupération structurée commence seulement après l’admission d’une charge
utile valide. Si l’exécuteur ou la frontière du domaine refuse ensuite
l’opération, il peut renvoyer un ToolFailure avec une RecoveryDirective.
Le runtime applique alors cette directive au tour suivant du planificateur.
Contrat des mainteneurs du générateur (à préserver)
Toute modification du générateur qui touche l’un des éléments suivants :
- matérialisation du type de charge utile d’outil ;
- génération du type auxiliaire de décodage ;
- métadonnées de clés des objets fermés et enrichissement de la validation ;
- transformations des adaptateurs (charge utile d’outil → charge utile de méthode de service) ;
doit conserver une sémantique cohérente des valeurs par défaut entre :
- la génération du type de charge utile d’outil ;
- les codecs et transformations générés qui lisent ses champs.
Dans le cas contraire, le générateur de transformations de Goa peut produire du code qui ne compile pas, par exemple :
if in.Field != nil { ... }lorsqueFieldest une valeur ;out.Field = "x"lorsqueFieldest un*T.