Scrydon

Outils dynamiques (outils dérivés par connexion)

Déclarez un outil de découverte pour que la plateforme provisionne à l'exécution des outils propres à une connexion — objets personnalisés, champs personnalisés, types d'enregistrement personnalisés — sans reconstruire ni republier le code de l'intégration.

Vue d'ensemble

Certaines plateformes (systèmes CRM, outils de ticketing, moteurs de workflow) ont des schémas qui dépendent de la configuration de chaque client. Un outil de découverte permet à la plateforme de demander à l'instance connectée « quels outils sont disponibles en ce moment ? » et de provisionner pour l'agent un catalogue d'outils dérivés propre à la connexion.

Ce qui ne change pas :

  • Le code de l'intégration n'est jamais reconstruit ni réenvoyé pour chaque client.
  • Chaque outil dérivé s'exécute dans la même microVM Kata extension_code que l'outil statique qu'il encapsule.
  • Aucun nouveau code exécutable n'est introduit. Un outil dérivé est une vue typée plus étroite d'un exécuteur livré statiquement.

Fonctionnement

  1. Vous déclarez une capacité dynamicTools dans votre manifeste avec une référence discoveryToolId — le slug d'un outil statique existant du même toolkit.
  2. Lorsqu'un administrateur autorise les outils dérivés pour une connexion, la plateforme exécute votre outil de découverte une fois, via le chemin d'exécution gouverné existant.
  3. La plateforme applique un pipeline d'admission à six contrôles à chaque descripteur renvoyé par votre outil de découverte.
  4. Les descripteurs admis deviennent des outils dérivés dans le catalogue de l'agent. Ils sont stockés dans Postgres et actualisés selon un TTL ou sur déclenchement manuel par un administrateur.

Déclarer des outils dynamiques dans votre manifeste

// sdk-authoring: defineToolkit(...)
defineToolkit({
  id: "my-crm",
  name: "My CRM",
  // ... other toolkit fields ...

  dynamicTools: {
      discoveryToolId: "list-record-types", // slug of a static tool in this toolkit
      executors: [
        { toolId: "create-record", effect: "write" },
        { toolId: "update-record", effect: "write" },
        { toolId: "get-record",    effect: "read"  },
      ],
      maxTools: 50,                          // optional; server cap is always enforced
  },
});

discoveryToolId

Doit être le slug d'un outil déjà déclaré dans le même toolkit. Il ne doit accepter aucun paramètre obligatoire (ou uniquement des paramètres que la plateforme peut fournir depuis le profileConfig de la connexion active). C'est le seul outil que la plateforme appelle pour la découverte ; les descripteurs renvoyés ne sont jamais sélectionnables par l'agent.

executors

Un tableau d'objets { toolId, effect } — la liste blanche des cibles de dispatch. Un outil dérivé dont le dispatch.tool ne figure pas dans ce tableau est withheld (retenu) à l'admission, et reste visible pour examen par l'administrateur. effect est purement présentationnel : il pilote les libellés des cases à cocher dans la boîte de dialogue « Autoriser » de l'administrateur, ainsi que l'affordance « suppression — décochée par défaut par sécurité ». Il ne conditionne pas l'autorité : le contrôle de liste blanche du pipeline d'admission porte sur des identifiants d'outils exacts, et non sur l'effet déclaré. Un éditeur qui minimiserait un effet n'y gagnerait rien.

Écrire l'outil de découverte

Votre outil de découverte renvoie un tableau d'objets DynamicToolDescriptor.

import type { DynamicToolDescriptor } from "@scrydon/sdk-authoring/extensions";

// Example: return one derived tool per custom object type
export async function listRecordTypes(ctx: ToolContext): Promise<DynamicToolDescriptor[]> {
  const objectTypes = await ctx.http.get("/api/v2/object_types");

  return objectTypes.map((obj) => ({
    key: obj.id,             // stable unique key for this descriptor
    name: obj.label,         // shown in the agent catalog (character-allowlisted)
    description: obj.description ?? `Create a ${obj.label} record`,
    dispatch: {
      tool: "create-record",  // must be in the executors array above
      bind: {
        objectType: obj.id,  // bound parameter value (not a credential or header)
      },
    },
  }));
}

Règles applicables aux champs du descripteur

ChampObligatoireRemarques
keyOuiChaîne unique et stable. Utilisée pour une troncature de capacité déterministe.
nameOuiFiltré par liste blanche de caractères à l'admission. À garder court et lisible.
descriptionNonLongueur plafonnée et caractères de contrôle supprimés à l'admission.
dispatch.toolOuiSlug exact d'un outil statique du même toolkit. Doit correspondre à un identifiant d'outil exécuteur figurant dans l'enveloppe d'octroi de l'administrateur.
dispatch.bindNonValeurs de paramètres liées. Ne doit pas contenir de références à des credentials, d'en-têtes HTTP, de surcharges d'URL ni de sélecteurs de connexion.

Contrôles d'admission et rejet

La plateforme fait passer chaque descripteur par six contrôles avant de l'admettre :

  1. Validation structurelle — les descripteurs malformés sont rejetés.
  2. Liste blanche d'exécuteursdispatch.tool doit figurer dans l'ensemble d'exécuteurs approuvés par l'administrateur. Les descripteurs hors de cet ensemble sont retenus (visibles par l'administrateur, qui peut élargir l'enveloppe).
  3. Refus de liaison d'autorité — tout chemin bind qui référence un credential, un en-tête HTTP, une URL ou un sélecteur de connexion est rejeté et ne peut pas être contourné par un administrateur.
  4. Neutralisation du descripteur — les noms et descriptions sont nettoyés structurellement.
  5. Capacité — le nombre total d'outils admis est plafonné à min(grant.maxTools, MAX_DERIVED_TOOLS_PER_CONNECTION).
  6. Identité — un condensat portant sur le hash du code, l'identifiant de l'outil exécuteur, le contenu du descripteur et l'identifiant d'octroi est calculé puis stocké.

Les descripteurs withheld sont visibles par l'administrateur, qui peut élargir l'enveloppe. Les descripteurs rejected ne peuvent être approuvés par aucun administrateur.

Ce que voit l'agent

Les outils dérivés admis apparaissent dans le catalogue de l'agent avec :

  • id : l'identifiant scopé exact de l'outil exécuteur (par exemple org:acme:my-crm:create-record)
  • name : votre descriptor.name neutralisé
  • description : votre descriptor.description neutralisée
  • Schéma : dérivé de l'outil exécuteur, avec les valeurs bind pré-remplies

L'agent ne peut voir ni les valeurs bind brutes ni l'identifiant d'octroi. Le dispatch, la liaison des credentials et la résolution des politiques sont identiques, octet pour octet, à ceux de l'exécuteur statique.

Tester votre outil de découverte en local

Testez-le comme n'importe quel autre outil — isolément ou avec scrydon extension test :

scrydon extension test --tool list-record-types

Pour un test de bout en bout de l'admission des outils dérivés, utilisez une connexion de préproduction et le panneau Provides → Tools de la page des paramètres de l'intégration (décrit dans le guide administrateur).

Limites

LimiteValeur
Nombre maximal d'outils dérivés par connexion500 (MAX_DERIVED_TOOLS_PER_CONNECTION) ; un octroi peut l'abaisser
Longueur maximale de descriptor.name64 caractères (DESCRIPTOR_NAME_MAX)
Longueur maximale de descriptor.description512 caractères (DESCRIPTOR_DESCRIPTION_MAX)
Nombre maximal de clés dans dispatch.bind20
Longueur maximale d'une valeur dispatch.bind1024 caractères

FAQ

Un outil dérivé peut-il appeler un exécuteur différent selon la connexion ?

Non. dispatch.tool est validé au moment de l'admission ; il doit s'agir du même slug d'exécuteur pour tous les descripteurs d'une même synchronisation. Si vous avez besoin d'un routage par connexion, utilisez des produits distincts, ou livrez plusieurs outils exécuteurs et définissez plusieurs types d'outils dérivés.

Que se passe-t-il lorsque je modifie le schéma de l'outil exécuteur ?

Les outils dérivés héritent du schéma de l'exécuteur, mises à jour comprises. L'ensemble admis est actualisé à la synchronisation suivante ; les descripteurs qui ne passent plus l'admission sont supprimés.

Un éditeur peut-il déclarer dynamicTools pour un outil Scrydon natif ?

Non. La première version prend uniquement en charge les connexions installées par une organisation.

Après une modification du code installé ou de l’autorisation des outils d’une connexion, actualisez les outils découverts. Les outils admis pour un artefact ou une autorisation précédente restent indisponibles jusqu’à une nouvelle admission. Les clés de descripteur dupliquées sont rejetées ensemble ; les autres descripteurs valides peuvent toujours être admis.

Points de terminaison configurés par l’opérateur

Pour un service tel que Twenty dont l’hôte dépend de la connexion, déclarez explicitement une URL non secrète :

configFields: [{
  key: "baseUrl",
  label: "Instance URL",
  required: true,
  type: "url",
  purpose: "endpoint",
}]

Le code peut construire ses URL à partir de ctx.profileConfig.baseUrl. L’URL doit utiliser HTTPS sur le port 443, sans identifiants intégrés, paramètres de requête ni fragment. Conservez les clés API dans les identifiants de connexion, jamais dans l’URL ou son chemin. Les autres chaînes de configuration restent masquées ; type: "url" seul ne rend pas une valeur visible au code.

Un administrateur doit autoriser le domaine dans la liste d’autorisation de sortie de l’organisation. Chaque exécution est limitée à l’hôte exact configuré. La confiance accordée aux hôtes déclarés par l’éditeur et les domaines par défaut de la plateforme ne remplacent pas cette autorisation. Les protections DNS, adresses privées, redirections et adresses de métadonnées restent actives.

Sur cette page

Sur cette page