CommunityProgramación y desarrollogithub.com

clanker25/ai

Guía para añadir nuevos paquetes de adaptador (harness) del AI SDK. Úsalo al crear un nuevo paquete @ai-sdk/harness-<nombre> que adapte un runtime de agente de codificación a HarnessV1.

¿Qué es ai?

Esta habilidad proporciona una guía completa y detallada para crear nuevos paquetes de tipo "harness" (adaptador) dentro del ecosistema del Vercel AI SDK. Un harness actúa como un puente entre un runtime de agente de codificación (por ejemplo, Codex o Claude Code) y la interfaz estandarizada `HarnessV1` del SDK, permitiendo que diferentes herramientas de IA funcionen de manera intercambiable. La guía cubre todo el proceso, desde la creación de la estructura del paquete y la configuración hasta la implementación del adaptador, la escritura de pruebas y la documentación. También distingue entre harnesses "host-driven" (impulsados por el anfitrión) y "bridge-backed" (respaldados por un puente), y explica las reglas para paquetes de primera parte frente a los de terceros. Al seguir esta guía, los desarrolladores pueden integrar nuevos runtimes de agentes en el estándar HarnessV1 de manera consistente y robusta.

Compatible con✓Claude Code✓Codex CLI~Cursor✓OpenCode
npx skills add https://github.com/clanker25/ai/tree/HEAD/skills/add-harness-package

Installed? Explore more Programación y desarrollo skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

Preguntar en tu IA favorita

Abre un nuevo chat con esta habilidad de agente ya precargada.

Documentación

Añadir un Nuevo Paquete de Harness

Esta guía cubre la creación de un nuevo paquete @ai-sdk/harness-<nombre> para un harness de agente.

Antes de evaluar un runtime, lee Requisitos de Harness para conocer los criterios de viabilidad y las brechas de capacidad que debes documentar. Sigue los requisitos mientras implementas el paquete del harness.

Un harness puede ser host-driven (impulsado por el anfitrión), donde el runtime se ejecuta en el proceso anfitrión y utiliza el sandbox de forma remota, o bridge-backed (respaldado por un puente), donde un pequeño puente se ejecuta dentro del sandbox porque el runtime necesita acceso local al sistema de archivos o al entorno de proceso del sandbox. Prefiere host-driven cuando el runtime lo soporte.

Harnesses de Primera Parte vs. de Terceros

  • Paquetes de terceros: Cualquier runtime puede publicar un paquete de harness externo.
  • Paquetes @ai-sdk/harness-<nombre> de primera parte: Primero crea un issue para discutir si el runtime pertenece a este repositorio.

Ejemplo de Referencia

Consulta https://github.com/vercel/ai/pull/16255/changes para ver un ejemplo completo de cómo añadir un nuevo harness.

Arquitectura del Harness

El AI SDK utiliza una arquitectura de harness en capas que sigue el patrón de adaptador:

  1. Especificación del harness (@ai-sdk/harness): Define interfaces como HarnessV1 y HarnessV1Session
  2. Utilidades (@ai-sdk/harness/utils): Código compartido para implementar harnesses
  3. Implementaciones del harness (@ai-sdk/harness-<nombre>): Adaptadores concretos para harnesses
  4. Agente del harness (@ai-sdk/harness/agent): La API de alto nivel HarnessAgent orientada al usuario final

Guía Paso a Paso

1. Crear la Estructura del Paquete

Crea packages/harness-<nombre> con esta estructura base:

packages/harness-<nombre>/
├── src/
│   ├── index.ts
│   ├── <nombre>-harness.ts
│   ├── <nombre>-harness.test.ts
│   └── <nombre>-auth.ts              # si el runtime necesita resolución de autenticación
├── package.json
├── tsconfig.json
├── tsconfig.build.json
├── tsdown.config.ts
├── turbo.json
├── vitest.node.config.js
└── README.md

Si el runtime debe ejecutarse dentro del sandbox, añade también los archivos del puente:

src/
├── <nombre>-bridge-protocol.ts
├── <nombre>-bridge-protocol.test.ts
└── bridge/
    ├── index.ts
    ├── package.json
    └── pnpm-lock.yaml

Añade un CHANGELOG.md que contenga solo el encabezado del paquete (# @ai-sdk/harness-<nombre>). Todos los paquetes deben tener uno.

2. Configurar package.json

Utiliza los paquetes de harness existentes como fuente de verdad para scripts, exportaciones, metadatos del repositorio y ajustes de publicación.

Requisitos básicos del paquete:

  • "name": "@ai-sdk/harness-<nombre>"
  • "type": "module"
  • "version": "0.0.0" (punto de partida para paquetes nuevos)
  • "license": "Apache-2.0"
  • "sideEffects": false
  • dependencia de @ai-sdk/harness mediante workspace:*
  • dependencia de @ai-sdk/provider-utils mediante workspace:* cuando se utilicen utilidades de sandbox/autenticación/esquema
  • dependencias del SDK/CLI del runtime requeridas por el harness
  • dependencias de desarrollo que coincidan con los paquetes de harness existentes
  • "engines": { "node": ">=22" }

Para paquetes con puente, añade cualquier paso de copia de activos del puente necesario para los archivos en src/bridge/.

Reglas de dependencias del puente (harnesses bridge-backed):

  • Las dependencias de runtime del puente residen en src/bridge/package.json (instaladas dentro del sandbox al iniciar), no en el package.json principal. Después de modificarlas, regenera src/bridge/pnpm-lock.yaml con pnpm --dir packages/harness-<nombre>/src/bridge install --lockfile-only --ignore-workspace (ejecutable desde la raíz del repositorio).
  • Para cada importación de terceros en src/bridge/, añade la dependencia a src/bridge/package.json para que se instale en el sandbox. tsdown externaliza automáticamente las dependencias, dependencias entre pares y dependencias opcionales declaradas por el paquete principal; añade las dependencias exclusivas del puente que no estén declaradas allí a deps.neverBundle en tsdown.config.ts. Una dependencia faltante o exclusión requerida puede manifestarse solo en tiempo de ejecución del sandbox como un error de resolución de módulo.
  • Incluye paquetes que el runtime importa perezosamente — por ejemplo, SDKs de proveedores (@anthropic-ai/sdk, openai) resueltos a partir del ID del modelo en tiempo de ejecución — en src/bridge/package.json aunque nada los importe directamente. No necesitan una entrada en neverBundle a menos que el código fuente del puente los importe. Estos fallan solo cuando se utiliza realmente un modelo de ese proveedor.
  • Haz coincidir las versiones de dependencias compartidas (transporte, esquema, herramientas, SDKs de runtime) con las que usan actualmente los otros paquetes de harness — copia de un paquete hermano en lugar de elegir tus propias versiones. Las versiones obsoletas se desvían de los parches de seguridad y pueden desincronizarse del runtime del puente compartido; verifica las versiones actuales en el momento de la creación.

3. Crear Configuraciones de TypeScript, Compilación y Pruebas

Copia los archivos de configuración del paquete de harness existente más cercano y ajusta las rutas/nombres de paquetes:

  • tsconfig.json
  • tsconfig.build.json
  • tsdown.config.ts
  • turbo.json
  • vitest.node.config.js

Los paquetes de harness actualmente usan solo pruebas de Node a menos que la implementación tenga una razón específica para añadir otro runtime.

4. Implementar el Adaptador del Harness

Exporta una fábrica desde <nombre>-harness.ts y re-expórtala desde src/index.ts.

Usa el documento de arquitectura para los detalles del contrato. Al momento de la implementación, verifica:

  • devuelve un HarnessV1 con specificationVersion: 'harness-v1';
  • usa un harnessId estable en kebab-case;
  • expone las herramientas integradas nativas del adaptador a través de builtinTools;
  • mantén la construcción síncrona y sin efectos secundarios;
  • usa startOpts.sandboxSession y startOpts.sessionWorkDir; nunca crees un sandbox separado;
  • lanza HarnessCapabilityUnsupportedError desde el método que necesita una capacidad del runtime no soportada;
  • no codifiques un modelo predeterminado a menos que el runtime técnicamente lo requiera — algunos SDK subyacentes no tienen un valor predeterminado propio. De lo contrario, pasa el modelo solo cuando el consumidor haya configurado uno y deja intacto el valor predeterminado del SDK original; mantén el modelId de la sesión coherente con lo que realmente se envía (no informes un modelo que el puente haya sobrescrito silenciosamente);
  • maneja las tools e instructions que doPromptTurn/doContinueTurn puedan recibir: si el runtime no acepta tools personalizadas, lanza HarnessCapabilityUnsupportedError para que sea obvio en lugar de ignorarlas silenciosamente; si no tiene una entrada nativa de instructions, prepéndelas al primer mensaje del usuario (la solución alternativa de Codex/Claude Code);
  • cita las rutas interpoladas (workDir, directorio de estado del puente, …) al construir comandos de shell para sandbox.run/sandbox.spawn — pueden contener espacios.

Si el runtime necesita configuración dentro del sandbox, expone getBootstrap().

5. Implementar Aspectos Específicos del Runtime

Añade solo los aspectos que el runtime necesite:

  • resolución de autenticación — para soporte de AI Gateway, usa la ayuda central getAiGatewayAuthFromEnv() en lugar de leer directamente las variables de entorno. Esto asegura que tanto VERCEL_OIDC_TOKEN como AI_GATEWAY_API_KEY se acepten como credenciales de Gateway. Cuando el runtime resuelve el proveedor por modelo, resuelve el proveedor a partir del ID del modelo y establece las variables de entorno de ese proveedor; si se enruta a través del gateway, ten en cuenta que las convenciones de URL base difieren según el proveedor (por ejemplo, un cliente de Anthropic añade /v1/messages a una URL base raíz, un cliente de OpenAI añade a una base /v1);
  • atribución de cliente de AI Gateway — sigue la convención en los paquetes de harness existentes: define un valor de aplicación de cliente versionado, como ai-sdk/harness-<nombre>/${VERSION}, y úsalo para las solicitudes de Gateway. Configura tanto los encabezados User-Agent como x-client-app cuando el runtime/SDK subyacente los soporte; al menos uno de esos dos encabezados es obligatorio. Si el runtime no puede establecer encabezados arbitrarios directamente, usa el equivalente soportado por el runtime que produzca uno de esos encabezados (por ejemplo, una variable de entorno de aplicación de cliente del SDK);
  • traducción de esquemas de herramientas personalizadas — si conviertes el esquema JSON de las herramientas del anfitrión al formato de herramientas del runtime, convierte recursivamente (objetos anidados, items de arrays, enumeraciones, descripciones); una conversión plana solo a nivel superior descarta silenciosamente la guía estructurada del modelo. Pasar el esquema JSON directamente, si el runtime lo acepta, evita el problema;
  • materialización de habilidades o archivos de descubrimiento;
  • traducción de protocolo nativo a flujo/control del harness;
  • esquema de estado del ciclo de vida;
  • protocolo del puente y diagnósticos.

Ciertas convenciones estructurales para los adaptadores de harness se están aplicando a través del CLI konsistent. Ejecuta pnpm konsistent una vez que hayas terminado para verificarlas. Corrige cualquier infracción marcada antes de continuar.

6. Escribir Pruebas

Añade pruebas de Node enfocadas para:

  • metadatos y configuración de la fábrica;
  • resolución de autenticación;
  • uso del sandbox y ubicación de rutas;
  • operaciones remotas host-driven o comportamiento del protocolo del puente;
  • traducción de eventos de solicitud/control;
  • comportamiento de reanudación de sesión frente a continuación de turno;
  • errores de capacidad no soportada;
  • materialización de habilidades, si se soporta.

Usa sesiones de sandbox simuladas y límites de puente/runtime cuando sea posible. No requieras credenciales de proveedor en vivo en las pruebas unitarias.

getBootstrap() lee los activos del puente compilados (por ejemplo, dist/bridge/index.mjs), que no existen cuando las pruebas se ejecutan contra src, por lo que una prueba que lo llame encontrará ENOENT. Simula readFile de node:fs/promises para las rutas de activos del puente (consulta las pruebas del harness de Codex/OpenCode para ver el patrón).

7. Añadir README

Mantén el README breve:

  • propósito del paquete;
  • comando de configuración;
  • uso mínimo de HarnessAgent;
  • capacidades del sandbox requeridas, como puertos para runtimes bridge-backed;
  • configuración de autenticación notable.

Enlaza a la documentación principal del harness para conceptos más amplios.

8. Añadir Ejemplos

Añade ejemplos relevantes para el nuevo harness.

  • Añade ejemplos de funciones/API requeridos en examples/ai-functions/src/harness-agent y ejemplos interactivos en examples/harness-e2e-next.

9. Añadir Documentación

Crea documentación en content/providers/02-ai-sdk-harnesses/<siguiente-número>-<nombre>.mdx.

Incluye:

  • Instrucciones de configuración
  • Capacidades del sandbox requeridas
  • Configuración de autenticación
  • Opciones específicas del harness
  • Ejemplos de uso
  • Limitaciones conocidas

Actualiza content/docs/03-ai-sdk-harnesses/05-harness-adapters.mdx para listar el nuevo harness cuando esté listo para ser público.

10. Actualizar Referencias y Validar

Ejecuta desde la raíz del espacio de trabajo:

pnpm konsistent
pnpm update-references
pnpm --filter @ai-sdk/harness-<nombre> build
pnpm --filter @ai-sdk/harness-<nombre> test
pnpm type-check:full

Añade un changeset con pnpm changeset. Para el primer lanzamiento de un paquete de harness completamente nuevo, usa major (no el habitual patch), coincidiendo con los otros paquetes de harness.

Ejecuta los ejemplos de harness relevantes contra un sandbox en vivo temprano — no te bases solo en pruebas unitarias y type-check. Las limitaciones de la API del runtime (por ejemplo, rechazos inesperados de opciones de configuración, los nombres exactos de eventos de streaming que emite el runtime, el formato de la URL base de Gateway) solo se manifiestan cuando el puente realmente impulsa el runtime, y es mucho más barato encontrarlos antes de que se construyan los documentos/ejemplos encima.

Lista de Verificación

  • Estructura del paquete creada en packages/harness-<nombre>
  • package.json configurado con las dependencias correctas
  • Configuraciones de TypeScript configuradas (tsconfig.json, tsconfig.build.json)
  • Configuración de compilación (tsdown.config.ts)
  • Configuración de pruebas (vitest.node.config.js)
  • Implementación del adaptador del harness completa
  • Ubicación del runtime manejada sin crear un sandbox oculto
  • Activos del puente copiados durante la compilación, si es bridge-backed
  • Resolución de autenticación implementada, si es necesario
  • Las solicitudes de AI Gateway incluyen atribución de cliente User-Agent y/o x-client-app
  • Infraestructura del harness, habilidades, código del puente y secretos mantenidos fuera de sessionWorkDir
  • Reanudación de sesión y continuación de turno probados
  • Pruebas unitarias escritas y pasando
  • README.md escrito
  • CHANGELOG.md añadido (encabezado del paquete; requerido por konsistent)
  • Changeset añadido (major para un primer lanzamiento)
  • Ejemplos añadidos
  • Documentación añadida en content/providers/02-ai-sdk-harnesses/
  • Lista de adaptadores de harness actualizada, si es pública
  • Validado contra un sandbox en vivo (no solo pruebas unitarias / type-check)
  • pnpm update-references ejecutado
  • Compilación del paquete pasando
  • Pruebas del paquete pasando
  • Verificación de tipos pasando (pnpm type-check:full desde la raíz)
  • Ejemplos relevantes ejecutados con éxito

Documentación Relacionada

Individual skills in this repo

This repo contains 3 individual skills — each has its own dedicated page.

Skills relacionados