Ajout d'un Nouveau Package de Harnais
Ce guide couvre la création d'un nouveau package @ai-sdk/harness-<nom> pour un harnais d'agent.
Avant d'évaluer un runtime, lisez Exigences du Harnais pour les critères de faisabilité et les lacunes de capacités à documenter. Suivez les exigences lors de l'implémentation du package de harnais.
Un harnais peut être piloté par l'hôte, où le runtime s'exécute dans le processus hôte et utilise le sandbox à distance, ou soutenu par un pont, où un petit pont s'exécute à l'intérieur du sandbox car le runtime a besoin d'un accès local au système de fichiers ou à l'environnement de processus du sandbox. Privilégiez le piloté par l'hôte lorsque le runtime le prend en charge.
Harnais de Première Partie vs Tiers
- Packages tiers : Tout runtime peut publier un package de harnais externe.
- Packages
@ai-sdk/harness-<nom>de première partie : Créez d'abord un ticket pour discuter si le runtime appartient à ce dépôt.
Exemple de Référence
Voir https://github.com/vercel/ai/pull/16255/changes pour un exemple complet d'ajout d'un nouveau harnais.
Architecture du Harnais
Le SDK AI utilise une architecture de harnais en couches suivant le modèle d'adaptateur :
- Spécification du harnais (
@ai-sdk/harness) : Définit les interfaces commeHarnessV1etHarnessV1Session - Utilitaires (
@ai-sdk/harness/utils) : Code partagé pour implémenter les harnais - Implémentations du harnais (
@ai-sdk/harness-<nom>) : Adaptateurs concrets pour les harnais - Agent du harnais (
@ai-sdk/harness/agent) : L'APIHarnessAgentde haut niveau orientée utilisateur
Guide Pas à Pas
1. Créer la Structure du Package
Créez packages/harness-<nom> avec cette structure de base :
packages/harness-<nom>/
├── src/
│ ├── index.ts
│ ├── <nom>-harness.ts
│ ├── <nom>-harness.test.ts
│ └── <nom>-auth.ts # si le runtime a besoin de résolution d'authentification
├── package.json
├── tsconfig.json
├── tsconfig.build.json
├── tsdown.config.ts
├── turbo.json
├── vitest.node.config.js
└── README.md
Si le runtime doit s'exécuter à l'intérieur du sandbox, ajoutez également les fichiers de pont :
src/
├── <nom>-bridge-protocol.ts
├── <nom>-bridge-protocol.test.ts
└── bridge/
├── index.ts
├── package.json
└── pnpm-lock.yaml
Ajoutez un fichier CHANGELOG.md contenant uniquement l'en-tête du package (# @ai-sdk/harness-<nom>). Chaque package doit en avoir un.
2. Configurer package.json
Utilisez les packages de harnais existants comme source de vérité pour les scripts, les exports, les métadonnées du dépôt et les paramètres de publication.
Éléments de base requis pour le package :
"name": "@ai-sdk/harness-<nom>""type": "module""version": "0.0.0"(point de départ pour les nouveaux packages)"license": "Apache-2.0""sideEffects": false- dépendance envers
@ai-sdk/harnessviaworkspace:* - dépendance envers
@ai-sdk/provider-utilsviaworkspace:*lors de l'utilisation des utilitaires sandbox/auth/schema - dépendances SDK/CLI du runtime requises par le harnais
- dépendances de développement correspondant aux packages de harnais existants
"engines": { "node": ">=22" }
Pour les packages de pont, ajoutez toute étape de copie des assets du pont requise pour les fichiers sous src/bridge/.
Règles de dépendance du pont (harnais soutenus par un pont) :
- Les dépendances d'exécution du pont se trouvent dans
src/bridge/package.json(installées dans le sandbox au démarrage), pas dans lepackage.jsonprincipal. Après les avoir modifiées, régénérezsrc/bridge/pnpm-lock.yamlavecpnpm --dir packages/harness-<nom>/src/bridge install --lockfile-only --ignore-workspace(exécutable depuis la racine du dépôt). - Pour chaque import tiers dans
src/bridge/, ajoutez la dépendance àsrc/bridge/package.jsonafin qu'elle soit installée dans le sandbox. tsdown externalise automatiquement les dépendances, les pairs dépendances et les dépendances optionnelles déclarées par le package principal ; ajoutez les dépendances propres au pont qui n'y sont pas déclarées àdeps.neverBundledanstsdown.config.ts. Une dépendance manquante ou une exclusion requise peut se manifester uniquement au moment de l'exécution du sandbox comme une erreur de résolution de module. - Incluez les packages que le runtime importe paresseusement — par exemple les SDK fournisseurs (
@anthropic-ai/sdk,openai) résolus à partir de l'identifiant du modèle à l'exécution — danssrc/bridge/package.jsonmême si rien ne les importe directement. Ils n'ont pas besoin d'entréeneverBundleà moins que le source du pont ne les importe. Ceux-ci échouent uniquement lorsqu'un modèle de ce fournisseur est réellement utilisé. - Faites correspondre les versions des dépendances partagées (transport, schéma, outillage, SDK runtime) à celles actuellement utilisées par les autres packages de harnais — copiez depuis un package frère plutôt que de choisir vos propres versions. Des versions obsolètes dérivent des correctifs de sécurité et peuvent se désynchroniser du runtime du pont partagé ; vérifiez les versions actuelles au moment de la création.
3. Créer les Configurations TypeScript, Build et Tests
Copiez les fichiers de configuration du package de harnais existant le plus proche et ajustez les chemins/noms de packages :
tsconfig.jsontsconfig.build.jsontsdown.config.tsturbo.jsonvitest.node.config.js
Les packages de harnais utilisent actuellement uniquement des tests Node, sauf si l'implémentation a une raison spécifique d'ajouter un autre runtime.
4. Implémenter l'Adaptateur de Harnais
Exportez une fabrique depuis <nom>-harness.ts et réexportez-la depuis src/index.ts.
Utilisez le document d'architecture pour les détails du contrat. Au moment de l'implémentation, vérifiez :
- retourner un
HarnessV1avecspecificationVersion: 'harness-v1'; - utiliser un
harnessIdstable en kebab-case ; - exposer les outils natifs intégrés de l'adaptateur via
builtinTools; - garder la construction synchrone et sans effet de bord ;
- utiliser
startOpts.sandboxSessionetstartOpts.sessionWorkDir; ne jamais créer un sandbox séparé ; - lever
HarnessCapabilityUnsupportedErrordepuis la méthode qui a besoin d'une capacité de runtime non prise en charge ; - ne pas coder en dur un modèle par défaut à moins que le runtime le nécessite techniquement — certains SDK sous-jacents n'ont pas de défaut propre. Sinon, ne passer le modèle que lorsque le consommateur en a configuré un et laisser le défaut du SDK d'origine intact ; maintenir le
modelIdde la session cohérent avec ce qui est réellement envoyé (ne pas signaler un modèle que le pont a silencieusement remplacé) ; - gérer les
toolsetinstructionsquedoPromptTurn/doContinueTurnpeuvent recevoir : si le runtime ne peut pas accepter detoolspersonnalisés, leverHarnessCapabilityUnsupportedErrorpour que ce soit évident plutôt que silencieusement ignoré ; s'il n'y a pas d'entréeinstructionsnative, les ajouter au premier message utilisateur (la solution de contournement Codex/Claude Code) ; - échapper les chemins interpolés (
workDir, répertoire d'état du pont, …) lors de la construction de commandes shell poursandbox.run/sandbox.spawn— ils peuvent contenir des espaces.
Si le runtime nécessite une configuration dans le sandbox, exposez getBootstrap().
5. Implémenter les Préoccupations Spécifiques au Runtime
Ajoutez uniquement les préoccupations dont le runtime a besoin :
- résolution d'authentification — pour le support d'AI Gateway, utilisez le helper central
getAiGatewayAuthFromEnv()plutôt que de lire directement les variables d'environnement. Cela garantit queVERCEL_OIDC_TOKENetAI_GATEWAY_API_KEYsoient tous deux acceptés comme identifiants Gateway. Lorsque le runtime résout le fournisseur par modèle, résolvez le fournisseur à partir de l'identifiant du modèle et définissez les variables d'environnement de ce fournisseur ; si le routage passe par la gateway, notez que les conventions d'URL de base diffèrent selon le fournisseur (par exemple, un client Anthropic ajoute/v1/messagesà une URL racine, un client OpenAI ajoute à une base/v1) ; - attribution client AI Gateway — suivez la convention des packages de harnais existants : définissez une valeur d'application client versionnée telle que
ai-sdk/harness-<nom>/${VERSION}et utilisez-la pour les requêtes Gateway. Configurez les en-têtesUser-Agentetx-client-applorsque le runtime/SDK sous-jacent les prend en charge tous les deux ; au moins un de ces deux en-têtes est requis. Si le runtime ne peut pas définir d'en-têtes arbitraires directement, utilisez l'équivalent pris en charge par le runtime qui produit l'un de ces en-têtes (par exemple, une variable d'environnement d'application client SDK) ; - traduction de schéma d'outils personnalisés — si vous convertissez le schéma JSON des outils de l'hôte dans le format d'outil du runtime, convertissez récursivement (objets imbriqués,
itemsde tableaux, énumérations, descriptions) ; une conversion plate uniquement au niveau supérieur supprime silencieusement l'orientation structurée du modèle. Passer le schéma JSON directement, si le runtime l'accepte, évite le problème ; - matérialisation de compétences ou de fichiers de découverte ;
- traduction de protocole natif en flux/contrôle du harnais ;
- schéma d'état du cycle de vie ;
- protocole de pont et diagnostics.
Certaines conventions structurelles pour les adaptateurs de harnais sont appliquées via le CLI konsistent.
Exécutez pnpm konsistent une fois que vous avez terminé pour vérifier ces points. Corrigez toute violation signalée avant de continuer.
6. Écrire les Tests
Ajoutez des tests Node ciblés pour :
- les métadonnées et paramètres de la fabrique ;
- la résolution d'authentification ;
- l'utilisation du sandbox et le placement des chemins ;
- le comportement des opérations à distance pilotées par l'hôte ou du protocole de pont ;
- la traduction des événements d'invite/contrôle ;
- le comportement de reprise de session vs continuation de tour ;
- les erreurs de capacité non prise en charge ;
- la matérialisation des compétences, si prise en charge.
Utilisez des sessions sandbox simulées et des limites de pont/runtime lorsque cela est possible. N'exigez pas d'identifiants de fournisseur réels dans les tests unitaires.
getBootstrap() lit les assets de pont compilés (par exemple dist/bridge/index.mjs), qui n'existent pas lorsque les tests sont exécutés sur src, donc un test qui l'appelle générera une erreur ENOENT. Simulez readFile de node:fs/promises pour les chemins des assets de pont (voir les tests des harnais Codex/OpenCode pour le modèle).
7. Ajouter un README
Gardez le README court :
- objectif du package ;
- commande de configuration ;
- utilisation minimale de
HarnessAgent; - capacités sandbox requises, comme les ports pour les runtimes soutenus par un pont ;
- configuration d'authentification notable.
Liez vers la documentation principale du harnais pour les concepts plus larges.
8. Ajouter des Exemples
Ajoutez des exemples pertinents pour le nouveau harnais.
- Ajoutez des exemples d'API/fonctions requis sous
examples/ai-functions/src/harness-agentet des exemples interactifs sousexamples/harness-e2e-next.
9. Ajouter de la Documentation
Créez de la documentation dans content/providers/02-ai-sdk-harnesses/<numéro suivant>-<nom>.mdx.
Incluez :
- Instructions de configuration
- Capacités sandbox requises
- Configuration de l'authentification
- Options spécifiques au harnais
- Exemples d'utilisation
- Limitations connues
Mettez à jour content/docs/03-ai-sdk-harnesses/05-harness-adapters.mdx pour lister le nouveau harnais lorsqu'il est prêt à être rendu public.
10. Mettre à Jour les Références et Valider
Exécutez depuis la racine de l'espace de travail :
pnpm konsistent
pnpm update-references
pnpm --filter @ai-sdk/harness-<nom> build
pnpm --filter @ai-sdk/harness-<nom> test
pnpm type-check:full
Ajoutez un changeset avec pnpm changeset. Pour la première version d'un tout nouveau package de harnais, utilisez major (pas le patch habituel), comme les autres packages de harnais.
Exécutez les exemples de harnais pertinents avec un sandbox réel tôt — ne vous fiez pas uniquement aux tests unitaires et à type-check. Les contraintes de l'API runtime (par exemple, les rejets de paramètres de configuration inattendus, les noms exacts des événements de flux émis par le runtime, le format de l'URL de base de la gateway) n'apparaissent que lorsque le pont pilote réellement le runtime, et il est bien moins coûteux de les trouver avant que la documentation/les exemples ne soient construits par-dessus.
Liste de Vérification
- Structure du package créée dans
packages/harness-<nom> -
package.jsonconfiguré avec les bonnes dépendances - Configurations TypeScript configurées (
tsconfig.json,tsconfig.build.json) - Configuration de build (
tsdown.config.ts) - Configuration de test (
vitest.node.config.js) - Implémentation de l'adaptateur de harnais complète
- Placement du runtime géré sans créer de sandbox caché
- Assets de pont copiés pendant la build, si soutenu par un pont
- Résolution d'authentification implémentée, si nécessaire
- Les requêtes AI Gateway incluent l'attribution client
User-Agentet/oux-client-app - Infrastructure du harnais, compétences, code du pont et secrets gardés hors de
sessionWorkDir - Reprise de session et continuation de tour testés
- Tests unitaires écrits et réussis
- README.md écrit
-
CHANGELOG.mdajouté (en-tête du package ; requis parkonsistent) - Changeset ajouté (
majorpour une première version) - Exemples ajoutés
- Documentation ajoutée dans
content/providers/02-ai-sdk-harnesses/ - Liste des adaptateurs de harnais mise à jour, si public
- Validé avec un sandbox réel (pas seulement des tests unitaires / type-check)
-
pnpm update-referencesexécuté - Build du package réussie
- Tests du package réussis
- Vérification de type réussie (
pnpm type-check:fulldepuis la racine) - Exemples pertinents exécutés avec succès
Documentation Connexe
- Architecture d'Abstraction du Harnais
- README de
@ai-sdk/harness - Packages de harnais existants avec un placement de runtime similaire