Aller au contenu

Sortie de fichier sous supervision humaine via NextPDF Connect

La barrière de confirmation avec supervision humaine (HITL) protège contre les écritures involontaires sur le système de fichiers. Lorsque output_pdf est appelé avec un file_path, la barrière intercepte l’appel et renvoie un défi à usage unique au lieu d’écrire le fichier. Une fois l’approbation donnée, l’agent rappelle l’outil avec le jeton, et le fichier n’est écrit qu’à ce moment-là. La sortie en base64 (sans file_path) n’est pas soumise à la barrière.

Fenêtre de terminal
composer require nextpdf/server

Lie un transport. Par défaut, output_pdf est classé au niveau de risque Approbation requise.

La barrière évalue le niveau de risque effectif, c’est-à-dire le niveau obtenu après application de toute substitution liée à la configuration ou à l’identité de l’appelant. Pour un outil en Approbation requise :

  • mode base64output_pdf sans file_path est rétrogradé au niveau Revue et autorisé sans confirmation. Aucun effet de bord sur le système de fichiers ne se produit.
  • mode fichieroutput_pdf avec un file_path reste au niveau Approbation requise. La barrière stocke un jeton à usage unique lié au nom de l’outil et renvoie un défi. Si le fichier cible existe déjà, le message du défi inclut un avertissement d’écrasement. Le jeton expire au bout d’une durée fixe.

Quel que soit le transport, le résultat de la barrière est une réponse normale. Une approbation en attente correspond à une pause du flux de travail, pas à un échec de transport (PSR-18 §3 ; PSR-18 §p2).

OutilRôleNiveau de risque
create_pdfOuvrir la sessionSûr
set_font, add_textConstruire le contenuPrudence
output_pdf (base64)Retour en ligne ; pas de barrièreRevue
output_pdf (fichier)Écriture sur le disque ; soumis à la barrièreApprobation requise

Le catalogue d’outils fait foi ; les outils disponibles dépendent de l’édition installée. L’échelle de risque et la barrière sont définies dans la référence des niveaux de risque HITL.

  1. create_pdf → construis le contenu avec set_font/add_text.
  2. output_pdf avec un file_path → la barrière renvoie une enveloppe de défi (le fichier n’est pas écrit).
  3. Transmets le défi à l’humain.
  4. Après approbation, rappelle output_pdf avec les mêmes arguments, en y ajoutant _confirmation_token défini sur le jeton issu du défi → le fichier est écrit et la session est détruite.
  • Traite toujours le défi comme une pause. Ne réessaie pas en boucle et ne crée pas de jeton toi-même.
  • Le jeton est à usage unique et lié au nom de l’outil. Un jeton émis pour output_pdf ne peut pas autoriser un autre outil.
  • Si l’humain refuse, ne rappelle pas l’outil. Pour récupérer les octets sans écriture de fichier, appelle plutôt output_pdf en mode base64. Cela nécessite que la session existe encore ; utilise donc destroy: false lors de l’appel soumis à la barrière si tu prévois d’en avoir besoin.
  • Si le jeton expire avant l’approbation, la barrière émet un nouveau défi. Transmets ce nouveau défi.
  • Jeton jamais fourni. L’opération reste en attente. L’humain doit approuver, puis transmettre le jeton et rappeler l’outil.
  • Jeton expiré. Un nouveau défi est émis. Retransmets-le.
  • Mauvais outil. Les jetons sont liés à l’outil. Sa réutilisation pour un autre outil échoue, et un nouveau défi est émis.
  • Chemin non absolu. Rejeté avant la barrière comme chemin invalide.
  • Pas de droit d’écriture / disque plein. C’est un échec d’écriture de fichier après approbation. Fais-le remonter. Ne réessaie pas aveuglément.
  • Session détruite avant le rappel. Si un output_pdf antérieur a utilisé destroy: true, la session a disparu. Utilise destroy: false lorsque tu prévois l’aller-retour d’approbation.

La barrière ajoute une consultation du magasin de jetons et un aller-retour pour l’approbation humaine. Le facteur humain domine le temps total, pas le serveur. Le profil est structural.

La barrière est la frontière de contrôle entre un agent et le système de fichiers du serveur. Elle existe parce qu’une écriture de fichier est un effet de bord irréversible qu’un humain devrait autoriser. Le jeton est à usage unique, lié à l’outil et limité dans le temps. Les arguments ne sont délibérément pas inclus dans son hachage, car les clients peuvent re-sérialiser le JSON avec un ordre de clés différent. La liaison repose donc sur outil + nonce + TTL, et non sur une correspondance exacte des arguments. Ne journalise pas le jeton. Traite-le comme un secret à usage unique.

ÉnoncéSpécificationClausereference_id
Une approbation en attente est une réponse normale, pas un échec.PSR-18§3
Le transport renvoie une réponse quel que soit le résultat.PSR-18§p2

Cette recette décrit le mécanisme de la barrière. Elle n’affirme pas que la barrière rend une quelconque opération « sûre ». La barrière fait en sorte qu’un effet de bord soit autorisé par un humain.

Sans objet — la barrière et output_pdf font partie de Core.

TransportDisponibleNotes
MCP (stdio)OuiLe défi est présenté à l’hôte sous forme de résultat d’outil que l’humain doit confirmer.
RESTOuiLe défi est renvoyé dans le corps de la réponse ; rappelle l’outil avec le jeton.
gRPCOuiUnaire ; le défi est le message de réponse ; rappelle l’outil avec le jeton.

L’échelle de risque est Sûr (0) → Prudence (1) → Revue (2) → Approbation requise (3). Seuls les outils classés en Approbation requise exigent une confirmation humaine. output_pdf est classé en Approbation requise. Le mode base64 le rétrograde en Revue et contourne la barrière. Le mode fichier conserve le niveau Approbation requise et applique la barrière. L’échelle canonique et la résolution de politique figurent dans la référence des niveaux de risque HITL.

Le résultat de la barrière prend exactement deux formes, telles qu’exposées par la barrière de confirmation du serveur :

Autorisé (Sûr/Prudence/Revue, ou un jeton valide consommé) :

{ "allowed": true }

Défi (Approbation requise sans jeton valide) :

{
"allowed": false,
"challenge": "⚠️ CONFIRMATION REQUIRED\n\nOperation: output_pdf\nDescription: <tool description>\n\nTo proceed, call output_pdf again with parameter _confirmation_token: \"confirm_<single-use-hex>\"\nExpires in 300 seconds.",
"token": "confirm_<single-use-hex>"
}

Lorsque le fichier cible existe déjà, le texte du challenge contient aussi une ligne d’avertissement d’écrasement. Le rappel du même outil avec _confirmation_token défini sur la valeur de token renvoie { "allowed": true }, et l’opération se poursuit. Le jeton est à usage unique et expire au terme de la fenêtre indiquée dans le défi.