Pipeline de carga
Al iniciarse, OpenClaw hace aproximadamente lo siguiente:- descubre las raíces de plugins candidatas
- lee los manifiestos de paquetes nativos o compatibles y los metadatos de paquetes
- rechaza los candidatos no seguros
- normaliza la configuración de los plugins (
plugins.enabled,allow,deny,entries,slots,load.paths) - decide la habilitación de cada candidato
- carga los módulos nativos habilitados: los módulos incluidos y compilados usan un cargador nativo; el código fuente TypeScript local de terceros usa el mecanismo de reserva de emergencia Jiti
- llama a los hooks nativos
register(api)y recopila los registros en el registro de plugins - expone el registro a los comandos y las superficies de tiempo de ejecución
- su punto de entrada resuelto sale de la raíz del plugin
- su ruta (o su directorio raíz) permite la escritura a cualquier usuario
- para los plugins no incluidos, la propiedad de la ruta no coincide con el uid actual (o root)
chmod (las instalaciones npm/globales pueden distribuir directorios de paquetes con 0777) antes de volver a ejecutar la comprobación; las comprobaciones de propiedad se omiten por completo para el origen incluido.
Los candidatos bloqueados siguen incluyendo el id de su plugin en el diagnóstico emitido cuando se conoce (incluidos los ids resueltos a partir de un manifiesto dentro de un directorio rechazado por otros motivos), de modo que la configuración que hace referencia a ese id muestra un plugin bloqueado vinculado a una advertencia de seguridad de la ruta, en lugar de un error no relacionado de «plugin desconocido».
Comportamiento basado primero en el manifiesto
El manifiesto es la fuente de verdad del plano de control. OpenClaw lo utiliza para:- identificar el plugin
- descubrir los canales, Skills, esquemas de configuración o capacidades del paquete declarados
- validar
plugins.entries.<id>.config - ampliar las etiquetas y los textos de marcador de posición de la interfaz de control
- mostrar los metadatos de instalación y catálogo
- conservar descriptores ligeros de activación y configuración sin cargar el tiempo de ejecución del plugin
activation y setup del manifiesto permanecen en el plano de control. Son descriptores exclusivamente de metadatos para planificar la activación y descubrir la configuración; no sustituyen el registro en tiempo de ejecución, register(...) ni setupEntry. Los consumidores de activación en vivo utilizan las indicaciones de comandos, canales y proveedores del manifiesto para limitar la carga de plugins antes de una materialización más amplia del registro:
- la carga de la CLI se limita a los plugins que poseen el comando principal solicitado
- la configuración del canal o resolución del plugin se limita a los plugins que poseen el id de canal solicitado
- la configuración explícita o resolución en tiempo de ejecución del proveedor se limita a los plugins que poseen el id de proveedor solicitado
- la planificación del inicio del Gateway utiliza
activation.onStartuppara las importaciones explícitas de inicio; los plugins sin metadatos de inicio solo se cargan mediante activadores de activación más específicos
activation.* de la alternativa basada en la propiedad del manifiesto:
Esta separación de motivos es el límite de compatibilidad: los metadatos de plugins existentes siguen funcionando, mientras que el código nuevo puede detectar indicaciones amplias o comportamientos alternativos sin cambiar la semántica de carga en tiempo de ejecución.
Las precargas en tiempo de ejecución durante las solicitudes que piden el ámbito amplio
all siguen derivando un conjunto explícito de ids de plugins efectivos a partir de la configuración, la planificación del inicio, los canales configurados, los slots y las reglas de habilitación automática (resolveEffectivePluginIds en src/plugins/effective-plugin-ids.ts). Si ese conjunto derivado está vacío, OpenClaw mantiene el ámbito vacío en lugar de ampliarlo a todos los plugins detectables.
El descubrimiento de configuración prefiere ids pertenecientes a descriptores, como setup.providers y setup.cliBackends, para limitar los plugins candidatos antes de recurrir a setup-api para los plugins que aún necesitan hooks de tiempo de ejecución durante la configuración. Las listas de configuración de proveedores utilizan providerAuthChoices del manifiesto, las opciones de configuración derivadas de descriptores y los metadatos del catálogo de instalación sin cargar el tiempo de ejecución del proveedor. Un setup.requiresRuntime: false explícito es un punto de corte exclusivo del descriptor; si se omite requiresRuntime, se conserva la alternativa de la API de configuración heredada por compatibilidad. Si más de un plugin descubierto reclama el mismo proveedor de configuración normalizado o id de backend de la CLI, la búsqueda de configuración rechaza el propietario ambiguo en lugar de depender del orden de descubrimiento. Cuando se ejecuta el tiempo de ejecución de configuración, los diagnósticos del registro notifican las discrepancias entre setup.providers / setup.cliBackends y los proveedores o backends de la CLI registrados realmente por la API de configuración, sin bloquear los plugins heredados.
Límite de caché de plugins
OpenClaw no almacena en caché los resultados del descubrimiento de plugins ni los datos directos del registro de manifiestos mediante intervalos de reloj. Las instalaciones, las modificaciones de manifiestos y los cambios en las rutas de carga deben hacerse visibles en la siguiente lectura explícita de metadatos o reconstrucción de una instantánea. El analizador de archivos de manifiesto mantiene una caché limitada de firmas de archivo cuya clave combina la ruta del manifiesto abierto con el dispositivo/inodo, el tamaño y mtime/ctime; esa caché solo evita volver a analizar bytes sin cambios y no debe almacenar en caché respuestas de descubrimiento, registro, propiedad ni política. La ruta rápida y segura para los metadatos es la propiedad explícita de los objetos, no una caché oculta. Las rutas críticas del inicio del Gateway deben pasar elPluginMetadataSnapshot actual, el PluginLookUpTable derivado o un registro explícito de manifiestos a través de la cadena de llamadas. La validación de la configuración, la habilitación automática durante el inicio, el arranque de plugins y la selección de proveedores pueden reutilizar esos objetos mientras representen la configuración y el inventario de plugins actuales. La búsqueda de configuración sigue reconstruyendo los metadatos del manifiesto bajo demanda, salvo que la ruta de configuración específica reciba un registro explícito de manifiestos; esto debe mantenerse como alternativa de ruta no crítica en lugar de añadir cachés de búsqueda ocultas. Cuando cambie la entrada, se debe reconstruir y sustituir la instantánea en lugar de modificarla o conservar copias históricas. Las vistas del registro de plugins activo y los auxiliares de arranque de los canales incluidos deben volver a calcularse a partir del registro o la raíz actuales. Los mapas de corta duración son aceptables dentro de una única llamada para desduplicar trabajo o proteger contra la reentrada; no deben convertirse en cachés de metadatos del proceso.
Para la carga de plugins, la capa de caché persistente corresponde a la carga en tiempo de ejecución. Puede reutilizar el estado del cargador cuando se cargan realmente el código o los artefactos instalados, como:
PluginLoaderCacheStatey registros activos de tiempo de ejecución compatibles- cachés de jiti/módulos y cachés de cargadores de superficies públicas utilizadas para evitar importar repetidamente la misma superficie de tiempo de ejecución
- cachés del sistema de archivos para los artefactos de plugins instalados
- mapas de corta duración por llamada para normalizar rutas o resolver duplicados
- resultados del descubrimiento
- registros directos de manifiestos
- registros de manifiestos reconstruidos a partir del índice de plugins instalados
- la búsqueda del propietario del proveedor, la supresión de modelos, la política de proveedores o los metadatos de artefactos públicos
- cualquier otra respuesta derivada de manifiestos en la que un cambio en el manifiesto, el índice instalado o la ruta de carga deba ser visible en la siguiente lectura de metadatos
Modelo de registro
Los plugins cargados no modifican directamente variables globales arbitrarias del núcleo. Se registran en un registro central de plugins (PluginRegistry en src/plugins/registry-types.ts), que realiza el seguimiento de los registros de plugins (identidad, fuente, origen, estado y diagnósticos), además de matrices para cada capacidad: herramientas, hooks heredados y hooks tipados, canales, proveedores, controladores RPC del Gateway, rutas HTTP, registradores de la CLI, servicios en segundo plano, comandos pertenecientes a plugins y muchas otras familias tipadas de proveedores (voz, embeddings, generación de imágenes/vídeos/música, obtención/búsqueda web, arneses de agentes, acciones de sesión, etc.).
A continuación, las funciones del núcleo leen ese registro en lugar de comunicarse directamente con los módulos de plugins. Esto mantiene la carga unidireccional:
- módulo del plugin -> registro en el registro
- tiempo de ejecución del núcleo -> consumo del registro
Callbacks de vinculación de conversaciones
Los plugins que vinculan una conversación pueden reaccionar cuando se resuelve una aprobación. Utiliceapi.onConversationBindingResolved(...) para recibir un callback después de que una solicitud de vinculación se apruebe o deniegue:
status:"approved"o"denied"decision:"allow-once","allow-always"o"deny"binding: la vinculación resuelta para las solicitudes aprobadasrequest: el resumen de la solicitud original, la indicación de desvinculación, el id del remitente y los metadatos de la conversación
Hooks de tiempo de ejecución del proveedor
Los plugins de proveedores tienen tres capas:- Metadatos del manifiesto para búsquedas ligeras previas al tiempo de ejecución:
setup.providers[].envVars,providerAuthAliases,providerAuthChoicesychannelConfigs. - Hooks durante la configuración:
catalogmásapplyConfigDefaults. - Hooks de tiempo de ejecución: más de 40 hooks opcionales que abarcan la autenticación, la resolución de modelos, el encapsulado de flujos, los niveles de razonamiento, la política de reproducción y los endpoints de uso. Consulte Orden y uso de los hooks.
setup.providers[].envVars del manifiesto cuando el proveedor tenga
credenciales basadas en variables de entorno que las rutas genéricas de autenticación, estado y selector de modelos deban detectar sin
cargar el entorno de ejecución del plugin. Use
providerAuthAliases del manifiesto cuando un identificador de proveedor deba reutilizar las variables de entorno, los perfiles de autenticación,
la autenticación respaldada por configuración y la opción de incorporación mediante clave de API de otro identificador de proveedor. Use
providerAuthChoices del manifiesto cuando las superficies de CLI de incorporación y elección de autenticación deban conocer el
identificador de opción del proveedor, las etiquetas de grupo y la configuración sencilla de autenticación mediante una sola opción,
sin cargar el entorno de ejecución del proveedor. Reserve
envVars del entorno de ejecución del proveedor para indicaciones dirigidas a operadores, como las etiquetas de incorporación o las variables
de configuración del identificador y el secreto de cliente de OAuth.
Describa la configuración y autenticación del canal basadas en variables de entorno mediante los descriptores de
channelConfigs.<id>.schema y configuración correspondientes.
Orden y uso de los hooks
Para los plugins de modelos y proveedores, OpenClaw llama a los hooks aproximadamente en este orden. La columna «Cuándo usarlo» es la guía rápida para tomar decisiones. Los campos de proveedor exclusivos para compatibilidad que OpenClaw ya no invoca, comoProviderPlugin.capabilities y suppressBuiltInModel, no se
incluyen aquí de forma intencionada.
normalizeModelId, normalizeTransport y normalizeConfig comprueban primero el
plugin del proveedor coincidente y luego continúan con otros plugins de proveedores
compatibles con hooks hasta que uno cambie realmente el identificador del modelo o
el transporte/la configuración. Esto permite que los adaptadores de proveedor de
alias/compatibilidad sigan funcionando sin exigir que el llamador sepa qué plugin
incluido es responsable de la reescritura. Si ningún hook de proveedor reescribe una
entrada de configuración compatible de la familia Google, el normalizador de
configuración de Google incluido sigue aplicando esa limpieza de compatibilidad.
Si el proveedor necesita un protocolo de comunicación totalmente personalizado o
un ejecutor de solicitudes personalizado, se trata de una clase de extensión
diferente. Estos hooks son para comportamientos de proveedores que siguen
ejecutándose en el bucle de inferencia normal de OpenClaw.
resolveUsageAuth decide si OpenClaw debe llamar a fetchUsageSnapshot o
recurrir a la resolución genérica de credenciales para las superficies de uso/estado.
Devuelva { token, accountId?, subscriptionType?, rateLimitTier? } cuando el proveedor
tenga una credencial de uso (los metadatos opcionales del plan pasan a
fetchUsageSnapshot), devuelva
{ handled: true } cuando la autenticación de uso gestionada por el proveedor haya
procesado la solicitud y deba suprimir la alternativa genérica de clave de API/OAuth,
y devuelva null o undefined
cuando el proveedor no haya gestionado la autenticación de uso.
Declare las credenciales de organización o facturación en el manifiesto
providerUsageAuthEnvVars. Esto permite que las superficies genéricas de descubrimiento y
eliminación de secretos las reconozcan sin convertirlas en candidatas para la
autenticación de inferencia.
Ejemplo de proveedor
Ejemplos integrados
Los plugins de proveedores incluidos combinan los hooks anteriores para adaptarse a las necesidades de catálogo, autenticación, razonamiento, reproducción y uso de cada proveedor. El conjunto de hooks autoritativo reside en cada plugin bajoextensions/; esta página ilustra las estructuras en lugar de reproducir la
lista.
Proveedores de catálogo de paso directo
Proveedores de catálogo de paso directo
OpenRouter, Kilocode, Z.AI y xAI registran
catalog junto con
resolveDynamicModel / prepareDynamicModel para poder presentar los
identificadores de modelos ascendentes antes que el catálogo estático de OpenClaw.Proveedores de OAuth y endpoints de uso
Proveedores de OAuth y endpoints de uso
GitHub Copilot, Gemini CLI, ChatGPT Codex, MiniMax, Xiaomi y z.ai combinan
prepareRuntimeAuth o formatApiKey con resolveUsageAuth +
fetchUsageSnapshot para gestionar el intercambio de tokens y la integración
de /usage.Familias de limpieza de reproducciones y transcripciones
Familias de limpieza de reproducciones y transcripciones
Las familias compartidas con nombre (
google-gemini, passthrough-gemini,
anthropic-by-model, hybrid-anthropic-openai) permiten que los proveedores adopten
la política de transcripciones mediante buildReplayPolicy, en lugar de que
cada plugin vuelva a implementar la limpieza.Proveedores solo de catálogo
Proveedores solo de catálogo
byteplus, cloudflare-ai-gateway, huggingface, kimi-coding, nvidia,
qianfan, synthetic, together, venice, vercel-ai-gateway y
volcengine solo registran catalog y utilizan el bucle de inferencia compartido.Ayudantes de flujo específicos de Anthropic
Ayudantes de flujo específicos de Anthropic
Los encabezados beta,
/fast / serviceTier y context1m residen en la
interfaz pública api.ts / contract-api.ts del plugin de Anthropic
(wrapAnthropicProviderStream, resolveAnthropicBetas,
resolveAnthropicFastMode, resolveAnthropicServiceTier), en lugar de
en el SDK genérico.Ayudantes de tiempo de ejecución
Los plugins pueden acceder a determinados ayudantes del núcleo medianteapi.runtime. Para TTS:
textToSpeechdevuelve la carga útil de salida TTS normal del núcleo para superficies de archivos/notas de voz.- Utiliza la configuración
ttsy la selección de proveedor del núcleo. - Devuelve un búfer de audio PCM y la frecuencia de muestreo. Los plugins deben remuestrear/codificar para los proveedores.
listVoiceses opcional para cada proveedor. Se utiliza para selectores de voz o flujos de configuración gestionados por el proveedor.- El núcleo pasa un plazo de solicitud resuelto a los hooks
listVoicesdel proveedor; los ajustes de tiempo de espera específicos del proveedor pueden reemplazarlo. - Las listas de voces pueden incluir metadatos más completos, como configuración regional, género y etiquetas de personalidad, para selectores conscientes del proveedor.
- OpenAI y ElevenLabs admiten actualmente telefonía. Microsoft no.
api.registerSpeechProvider(...).
- Mantenga en el núcleo la política de TTS, las alternativas y la entrega de respuestas.
- Utilice proveedores de voz para el comportamiento de síntesis gestionado por el proveedor.
- La entrada heredada
edgede Microsoft se normaliza al identificador de proveedormicrosoft. - El modelo de propiedad preferido está orientado a empresas: un plugin de proveedor puede gestionar proveedores de texto, voz, imágenes y medios futuros a medida que OpenClaw añada esos contratos de capacidades.
- Mantenga en el núcleo la orquestación, las alternativas, la configuración y la conexión con canales.
- Mantenga el comportamiento del proveedor en el plugin del proveedor.
- La ampliación aditiva debe conservar los tipos: nuevos métodos opcionales, nuevos campos de resultados opcionales y nuevas capacidades opcionales.
- La generación de vídeo ya sigue el mismo patrón:
- el núcleo gestiona el contrato de capacidades y el ayudante de tiempo de ejecución
- los plugins de proveedores registran
api.registerVideoGenerationProvider(...) - los plugins de funcionalidades/canales consumen
api.runtime.videoGeneration.*
api.runtime.mediaUnderstanding.*es la superficie compartida preferida para la comprensión de imágenes/audio/vídeo.extractStructuredWithModel(...)es la interfaz orientada a plugins para la extracción acotada, centrada primero en imágenes y gestionada por el proveedor. Incluya al menos una entrada de imagen; las entradas de texto son contexto complementario. Los plugins de producto gestionan sus rutas y esquemas, mientras que OpenClaw gestiona el límite entre el proveedor y el tiempo de ejecución.- Utiliza la configuración de audio de comprensión multimedia del núcleo (
tools.media.audio) y el orden de alternativas de proveedores. - Devuelve
{ text: undefined }cuando no se produce ninguna salida de transcripción (por ejemplo, una entrada omitida/no compatible).
api.runtime.subagent:
providerymodelson reemplazos opcionales por ejecución, no cambios persistentes de la sesión.toolsAlsoAllowacepta nombres de herramientas exactos y con propietario único registrados por el plugin llamador. Se rechazan los nombres del núcleo y los ambiguos. Se añade al perfil normal, pero las listas de permisos y denegaciones del operador siguen siendo autoritativas.- OpenClaw solo respeta esos campos de reemplazo para llamadores de confianza.
- Para las ejecuciones alternativas gestionadas por plugins, los operadores deben habilitarlas explícitamente con
plugins.entries.<id>.subagent.allowModelOverride: true. - Utilice
plugins.entries.<id>.subagent.allowedModelspara restringir los plugins de confianza a destinos canónicosprovider/modelespecíficos, o"*"para permitir explícitamente cualquier destino. - Las ejecuciones de subagentes de plugins que no son de confianza siguen funcionando, pero las solicitudes de reemplazo se rechazan en lugar de recurrir silenciosamente a una alternativa.
- Las sesiones de subagentes creadas por plugins se etiquetan con el identificador del plugin creador. El mecanismo alternativo
api.runtime.subagent.deleteSession(...)solo puede eliminar esas sesiones propias; la eliminación arbitraria de sesiones sigue requiriendo una solicitud del Gateway con ámbito de administrador.
api.registerWebSearchProvider(...).
Notas:
- Mantenga en el núcleo la selección de proveedores, la resolución de credenciales y la semántica compartida de las solicitudes.
- Utilice proveedores de búsqueda web para transportes de búsqueda específicos del proveedor.
api.runtime.webSearch.*es la superficie compartida preferida para plugins de funcionalidades/canales que necesitan comportamiento de búsqueda sin depender del contenedor de herramientas del agente.
api.runtime.imageGeneration
generate(...): genera una imagen mediante la cadena de proveedores de generación de imágenes configurada.listProviders(...): enumera los proveedores de generación de imágenes disponibles y sus capacidades.
Rutas HTTP del Gateway
Los plugins pueden exponer endpoints HTTP conapi.registerHttpRoute(...).
path: ruta dentro del servidor HTTP del Gateway.auth: obligatorio,"gateway"o"plugin". Use"gateway"para exigir la autenticación normal del Gateway, o"plugin"para la autenticación o verificación de Webhooks gestionada por el plugin.match: opcional."exact"(predeterminado) o"prefix".handleUpgrade: controlador opcional para solicitudes de actualización a WebSocket en la misma ruta.replaceExisting: opcional. Permite que el mismo plugin sustituya su propio registro de ruta existente.handler: devuelvetruecuando la ruta haya gestionado la solicitud.
api.registerHttpHandler(...)se eliminó y provocará un error al cargar el plugin. Useapi.registerHttpRoute(...)en su lugar.- Las rutas de plugins deben declarar
authexplícitamente. - Los conflictos exactos de
path + matchse rechazan salvo que se usereplaceExisting: true, y un plugin no puede sustituir la ruta de otro plugin. - Las rutas superpuestas con distintos niveles de
authse rechazan. Mantenga las cadenas de continuidadexact/prefixúnicamente en el mismo nivel de autenticación. - Las rutas
auth: "plugin"no reciben automáticamente ámbitos de ejecución del operador. Están destinadas a Webhooks o a la verificación de firmas gestionados por el plugin, no a llamadas privilegiadas a los auxiliares del Gateway. - Las rutas
auth: "gateway"se ejecutan dentro del ámbito de ejecución de una solicitud del Gateway. La superficie predeterminada (gatewayRuntimeScopeSurface: "write-default") es intencionadamente conservadora:- la autenticación de portador mediante secreto compartido (
gateway.auth.mode = "token"/"password") y cualquier método de autenticación que no sea de proxy de confianza obtienen un único ámbitooperator.write, incluso si el llamador envíax-openclaw-scopes - los llamadores
trusted-proxysin un encabezadox-openclaw-scopesexplícito también conservan la superficie heredada limitada aoperator.write - los llamadores
trusted-proxyque sí envíanx-openclaw-scopesobtienen en su lugar los ámbitos declarados - una ruta puede optar por
gatewayRuntimeScopeSurface: "trusted-operator"para respetar siemprex-openclaw-scopesen los modos de autenticación que incluyen identidad (y recurrir al conjunto completo de ámbitos predeterminados de la CLI cuando el encabezado no está presente)
- la autenticación de portador mediante secreto compartido (
- Las pestañas externas aisladas de la interfaz de control respaldadas por rutas
auth: "gateway"usan una concesión de cookie firmada y de corta duración, emitida únicamente mediante un arranque autenticado; las pestañas con autenticación de plugin conservan su ruta directa de iframe. Antes del montaje, el elemento principal ejecuta una comprobación propiedad de la ruta dentro del mismo entorno aislado opaco y bloquea el acceso cuando la política de privacidad del navegador impide usar la cookie. La concesión está vinculada al plugin propietario, a la raíz de la ruta coincidente y a la generación de autenticación actual; el nombre aleatorio por proceso de su cookie evita que Gateways de confianza del mismo host se sobrescriban entre sí, pero las cookies nunca aíslan los puertos TCP. Por tanto, el nombre de host del Gateway constituye un único límite de credenciales: no aloje conjuntamente servicios que no confíen entre sí en ese nombre de host, ni siquiera en otros puertos. El enrutamiento rechaza reutilizarla en una ruta anidada propiedad de otro plugin. Como los descendientes del entorno aislado son sitios distintos a efectos de las cookies, la concesión solo aceptaGETyHEADconoperator.read; las mutaciones y actualizaciones a WebSocket permanecen en superficies con autenticación explícita del Gateway. La cookie no puede usar CHIPS intencionadamente: los navegadores actuales incluyen un bit de ancestro entre sitios en la clave de partición, por lo que los marcos aislados opacos anidados perderían el acceso a los recursos de la misma ruta. La cookie requiere un contexto seguro y permiso del navegador para usar cookies entre sitios, por lo que las pestañas externas con autenticación del Gateway no están disponibles en orígenes LAN con HTTP simple ni cuando se bloquean por completo las cookies de terceros; use HTTPS/Tailscale Serve o un bucle local de confianza para el navegador con una política de cookies compatible. - La concesión impide la divulgación del token de portador del Gateway y la reutilización accidental de rutas o ámbitos; no crea un límite de seguridad entre plugins nativos. El código de los plugins nativos y el contenido de la interfaz que sirven siguen formando parte del mismo límite de confianza del plugin dentro del proceso.
- Regla práctica: no suponga que una ruta de plugin con autenticación del Gateway sea implícitamente una superficie administrativa. Si la ruta necesita un comportamiento exclusivo para administradores, opte por la superficie de ámbitos
trusted-operator, exija un modo de autenticación que incluya identidad y documente el contrato explícito del encabezadox-openclaw-scopes. - Después de encontrar la ruta y autenticar la solicitud, los controladores normales participan en la admisión de trabajo raíz del Gateway. Un Gateway preparado o en proceso de reinicio devuelve
503antes de invocar el controlador. La única excepción limitada es una rutaauth: "gateway"autorizada por el manifiesto que también opte por la superficie específica de la rutatrusted-operator; permanece accesible para que el enrutamiento del control de suspensión no quede bloqueado, mientras que las demás rutas normales del mismo plugin permanecen detrás del límite de admisión. La propiedad dehandleUpgradede WebSocket utiliza el mismo límite de admisión atómico; una vez que el controlador acepta un socket, su ciclo de vida posterior pertenece al plugin y este límite no realiza su seguimiento.
Rutas de importación del SDK de plugins
Use subrutas específicas del SDK en lugar del barrel raíz monolíticoopenclaw/plugin-sdk al crear plugins nuevos. Subrutas principales:
Los plugins de canal eligen entre una familia de interfaces específicas:
channel-setup,
setup-runtime, setup-tools, channel-pairing,
channel-contract, channel-feedback, channel-inbound, channel-outbound,
command-auth, secret-input, webhook-ingress,
channel-targets y channel-actions. El comportamiento de aprobación debe consolidarse
en un único contrato approvalCapability en lugar de mezclarse entre campos
de plugins no relacionados. Consulte Plugins de canal.
Los auxiliares de ejecución y configuración se encuentran en subrutas específicas de *-runtime
correspondientes (approval-runtime, agent-runtime, lazy-runtime, directory-runtime,
text-runtime, runtime-store, system-event-runtime, heartbeat-runtime,
channel-activity-runtime, etc.). Prefiera config-contracts,
plugin-config-runtime, runtime-config-snapshot y config-mutation
en lugar del amplio barrel de compatibilidad config-runtime.
openclaw/plugin-sdk/channel-lifecycle, las pequeñas fachadas auxiliares de canales,
openclaw/plugin-sdk/config-runtime y openclaw/plugin-sdk/infra-runtime
son adaptadores de compatibilidad obsoletos para plugins antiguos. El código nuevo debe importar
primitivas genéricas más específicas en su lugar.index.js— punto de entrada del plugin incluidoapi.js— barrel de auxiliares y tiposruntime-api.js— barrel exclusivo de ejecuciónsetup-entry.js— punto de entrada de configuración del plugin
openclaw/plugin-sdk/*. Nunca
importe el src/* del paquete de otro plugin desde el núcleo ni desde otro plugin.
Los puntos de entrada cargados mediante fachadas prefieren la instantánea activa de la configuración de ejecución cuando
existe y, en caso contrario, recurren al archivo de configuración resuelto en el disco.
Existen subrutas específicas de capacidades como image-generation, media-understanding
y speech porque los plugins incluidos las usan actualmente. No son
automáticamente contratos externos inmutables a largo plazo; consulte la página de referencia
del SDK correspondiente antes de depender de ellas.
Esquemas de la herramienta de mensajes
Los plugins deben ser propietarios de las contribuciones al esquemadescribeMessageTool(...)
específicas del canal para primitivas que no sean mensajes, como reacciones, lecturas y encuestas.
La presentación compartida de envíos debe usar el contrato genérico MessagePresentation
en lugar de campos de botones, componentes, bloques o tarjetas nativos del proveedor.
Consulte Presentación de mensajes para conocer el contrato,
las reglas de degradación, la asignación de proveedores y la lista de comprobación para autores de plugins.
Los plugins con capacidad de envío declaran lo que pueden representar mediante capacidades de mensajes:
presentationpara bloques de presentación semántica (text,context,divider,chart,table,buttons,select)delivery-pinpara solicitudes de entrega fijada
Resolución de destinos de canales
Los plugins de canal deben ser propietarios de la semántica de destino específica del canal. Mantenga genérico el host de salida compartido y use la superficie del adaptador de mensajería para las reglas del proveedor:messaging.inferTargetChatType({ to })decide si un destino normalizado debe tratarse comodirect,groupochannelantes de buscarlo en el directorio.messaging.targetResolver.looksLikeId(raw, normalized)indica al núcleo si una entrada debe pasar directamente a una resolución similar a un identificador en lugar de buscar en el directorio.messaging.targetResolver.reservedLiteralsenumera las palabras sin formato que son referencias de canal o sesión para ese proveedor. La resolución conserva las entradas configuradas del directorio antes de rechazar los literales reservados y, después, se bloquea si no encuentra una coincidencia en el directorio.messaging.targetResolver.resolveTarget(...)es la alternativa del plugin cuando el núcleo necesita una resolución final propiedad del proveedor tras la normalización o después de no encontrar una coincidencia en el directorio.messaging.resolveOutboundSessionRoute(...)controla la construcción de rutas de sesión específicas del proveedor una vez resuelto el destino.
- Use
inferTargetChatTypepara las decisiones de categoría que deban tomarse antes de buscar pares o grupos. - Use
looksLikeIdpara comprobar si «esto debe tratarse como un identificador de destino explícito o nativo». - Use
resolveTargetcomo alternativa de normalización específica del proveedor, no para búsquedas amplias en el directorio. - Mantenga los identificadores nativos del proveedor, como identificadores de chat, de hilos, JID, nombres de usuario e identificadores
de salas, dentro de los valores
targeto de parámetros específicos del proveedor, no en campos genéricos del SDK.
Directorios respaldados por la configuración
Los plugins que derivan entradas de directorio de la configuración deben conservar esa lógica en el plugin y reutilizar los auxiliares compartidos deopenclaw/plugin-sdk/directory-runtime.
Use esto cuando un canal necesite pares o grupos respaldados por la configuración, como:
- pares de mensajes directos controlados mediante una lista de permitidos
- asignaciones configuradas de canales o grupos
- alternativas de directorio estáticas limitadas a una cuenta
directory-runtime solo gestionan operaciones genéricas:
- filtrado de consultas
- aplicación de límites
- auxiliares de desduplicación y normalización
- creación de
ChannelDirectoryEntry[]
Catálogos de proveedores
Los plugins de proveedores pueden definir catálogos de modelos para inferencia conregisterProvider({ catalog: { run(...) { ... } } }).
catalog.run(...) devuelve la misma estructura que OpenClaw escribe en
models.providers:
{ provider }para una entrada de proveedor{ providers }para varias entradas de proveedor
catalog cuando el plugin sea propietario de identificadores de modelos específicos del proveedor, valores predeterminados de la URL base
o metadatos de modelos sujetos a autenticación.
catalog.order controla cuándo se combina el catálogo de un plugin con respecto a los proveedores implícitos
integrados de OpenClaw:
simple: proveedores simples basados en claves de API o variables de entornoprofile: proveedores que aparecen cuando existen perfiles de autenticaciónpaired: proveedores que sintetizan varias entradas de proveedor relacionadaslate: última pasada, después de los demás proveedores implícitos
api.registerModelCatalogProvider({ provider, kinds, staticCatalog, liveCatalog }). Esta es la vía futura para las superficies de lista/ayuda/selector y admite
filas text, voice, image_generation, video_generation y music_generation.
Los plugins de proveedores siguen siendo responsables de las llamadas activas a endpoints, el intercambio de tokens y
la asignación de respuestas del proveedor; el núcleo es responsable de la forma común de las filas, las etiquetas de origen y
el formato de la ayuda de las herramientas multimedia. Los registros de proveedores de generación multimedia sintetizan
automáticamente filas estáticas del catálogo a partir de defaultModel, models y
capabilities.
Compatibilidad:
discoverysigue funcionando como alias heredado, pero emite una advertencia de obsolescencia- si se registran tanto
catalogcomodiscovery, OpenClaw usacatalogy emite una advertencia augmentModelCatalogestá obsoleto; los proveedores incluidos deben publicar filas complementarias medianteregisterModelCatalogProvider
Inspección de canales de solo lectura
Si el plugin registra un canal, se recomienda implementarplugin.config.inspectAccount(cfg, accountId) junto con resolveAccount(...).
Motivos:
resolveAccount(...)es la ruta de ejecución. Puede asumir que las credenciales están completamente materializadas y fallar de inmediato cuando faltan secretos obligatorios.- Las rutas de comandos de solo lectura, como
openclaw status,openclaw status --all,openclaw channels status,openclaw channels resolvey los flujos de reparación de doctor/configuración, no deberían necesitar materializar credenciales de ejecución solo para describir la configuración.
inspectAccount(...):
- Devuelva únicamente el estado descriptivo de la cuenta.
- Conserve
enabledyconfigured. - Incluya campos de origen/estado de las credenciales cuando corresponda, como:
tokenSource,tokenStatusbotTokenSource,botTokenStatusappTokenSource,appTokenStatussigningSecretSource,signingSecretStatus
- No es necesario devolver los valores sin procesar de los tokens solo para informar sobre la disponibilidad
de solo lectura. Devolver
tokenStatus: "available"(y el campo de origen correspondiente) es suficiente para los comandos de estado. - Use
configured_unavailablecuando una credencial esté configurada mediante SecretRef, pero no esté disponible en la ruta de comandos actual.
Paquetes de plugins
Un directorio de plugin puede incluir unpackage.json con openclaw.extensions:
<manifestOrPackageName>/<fileBase> (el identificador del manifiesto prevalece cuando
está presente; de lo contrario, se usa el nombre package.json sin ámbito).
Si el plugin importa dependencias de npm, instálelas en ese directorio para que
node_modules esté disponible (npm install / pnpm install).
Medida de seguridad: cada entrada openclaw.extensions debe permanecer dentro del directorio del plugin
después de resolver los enlaces simbólicos. Se rechazan las entradas que escapen del directorio del paquete.
Nota de seguridad: openclaw plugins install instala las dependencias del plugin con un
npm install --omit=dev --ignore-scripts local del proyecto (sin scripts del ciclo de vida
ni dependencias de desarrollo durante la ejecución), e ignora la configuración global heredada de instalación de npm.
Mantenga los árboles de dependencias de los plugins como «JS/TS puro» y evite paquetes que requieran
compilaciones postinstall.
Opcional: openclaw.setupEntry puede apuntar a un módulo ligero exclusivo para la configuración.
Cuando OpenClaw necesita superficies de configuración para un plugin de canal deshabilitado, o
cuando un plugin de canal está habilitado pero aún no está configurado, carga setupEntry
en lugar de la entrada completa del plugin. Esto reduce la carga del inicio y la configuración
cuando la entrada principal del plugin también conecta herramientas, hooks u otro código exclusivo
de la ejecución.
Opcional: openclaw.startup.deferConfiguredChannelFullLoadUntilAfterListen
puede incorporar un plugin de canal a la misma ruta setupEntry durante la fase de inicio
anterior a la escucha del gateway, incluso cuando el canal ya está configurado.
Use esta opción únicamente cuando setupEntry cubra por completo la superficie de inicio que debe existir
antes de que el gateway comience a escuchar. En la práctica, esto significa que la entrada de configuración
debe registrar todas las capacidades propiedad del canal de las que depende el inicio, como:
- el propio registro del canal
- todas las rutas HTTP que deban estar disponibles antes de que el gateway comience a escuchar
- todos los métodos, herramientas o servicios del gateway que deban existir durante ese mismo periodo
singleAccountKeysToMovenamedAccountPromotionKeysresolveSingleAccountPromotionTarget(...)
channels.<id>.accounts.* sin cargar la entrada completa del plugin.
Matrix es el ejemplo incluido actual: mueve únicamente las claves de autenticación/inicialización a una
cuenta promovida con nombre cuando ya existen cuentas con nombre, y puede conservar una
clave configurada de cuenta predeterminada no canónica en lugar de crear siempre
accounts.default.
Esos adaptadores de parches de configuración mantienen diferido el descubrimiento de superficies de contrato incluidas. El tiempo
de importación sigue siendo reducido; la superficie de promoción solo se carga en el primer uso, en lugar de
volver a ejecutar el inicio del canal incluido al importar el módulo.
Cuando esas superficies de inicio incluyan métodos RPC del gateway, manténgalos bajo un
prefijo específico del plugin. Los espacios de nombres administrativos del núcleo (config.*,
exec.approvals.*, wizard.*, update.*) permanecen reservados y siempre se resuelven
como operator.admin, incluso si un plugin solicita un ámbito más restringido.
Ejemplo:
Metadatos del catálogo de canales
Los plugins de canales pueden anunciar metadatos de configuración/descubrimiento medianteopenclaw.channel y
sugerencias de instalación mediante openclaw.install. Esto evita que el catálogo del núcleo contenga datos.
Ejemplo:
openclaw.channel adicionales al ejemplo mínimo:
detailLabel: etiqueta secundaria para superficies de catálogo/estado más completasdocsLabel: sobrescribe el texto del enlace a la documentaciónpreferOver: identificadores de plugins/canales de menor prioridad que esta entrada del catálogo debe superarselectionDocsPrefix,selectionDocsOmitLabel,selectionExtras: controles de texto de la superficie de selecciónmarkdownCapable: marca el canal como compatible con Markdown para las decisiones de formato salienteexposure.configured: oculta el canal en las superficies de listado de canales configurados cuando se establece enfalseexposure.setup: oculta el canal en los selectores interactivos de configuración cuando se establece enfalseexposure.docs: marca el canal como interno/privado para las superficies de navegación de la documentaciónquickstartAllowFrom: incorpora el canal al flujo estándar de inicio rápidoallowFromforceAccountBinding: exige una vinculación explícita de la cuenta incluso cuando solo existe unapreferSessionLookupForAnnounceTarget: prioriza la búsqueda de sesiones al resolver los destinos de anuncios
~/.openclaw/mpm/plugins.json~/.openclaw/mpm/catalog.json~/.openclaw/plugins/catalog.json
OPENCLAW_PLUGIN_CATALOG_PATHS (o OPENCLAW_MPM_CATALOG_PATHS) apunte a
uno o varios archivos JSON (delimitados por comas, puntos y coma o PATH). Cada archivo debe
contener { "entries": [ { "name": "@scope/pkg", "openclaw": { "channel": {...}, "install": {...} } } ] }. El analizador también acepta "packages" o "plugins" como alias heredados de la clave "entries".
Las entradas generadas del catálogo de canales y las entradas del catálogo de instalación de proveedores exponen
datos normalizados del origen de instalación junto al bloque openclaw.install sin procesar. Los
datos normalizados identifican si la especificación de npm es una versión exacta o un
selector flotante, si están presentes los metadatos de integridad esperados y si también hay disponible una
ruta de origen local. Cuando se conoce la identidad del catálogo/paquete, los
datos normalizados advierten si el nombre del paquete npm analizado difiere de dicha identidad.
También advierten cuando defaultChoice no es válido o apunta a un origen que no está
disponible, y cuando existen metadatos de integridad de npm sin un origen npm
válido. Los consumidores deben tratar installSource como un campo opcional aditivo para que
las entradas creadas manualmente y los adaptadores de catálogos no tengan que sintetizarlo.
Esto permite que la incorporación y los diagnósticos expliquen el estado del plano de origen sin
importar la ejecución del plugin.
Las entradas npm externas oficiales deben priorizar un npmSpec exacto junto con
expectedIntegrity. Los nombres de paquetes sin versión y las etiquetas de distribución siguen funcionando por
compatibilidad, pero muestran advertencias del plano de origen para que el catálogo pueda avanzar
hacia instalaciones fijadas y verificadas mediante integridad sin interrumpir los plugins existentes.
Cuando la incorporación instala desde una ruta de catálogo local, registra una entrada administrada
en el índice de plugins con source: "path" y un
sourcePath relativo al espacio de trabajo cuando sea posible. La ruta de carga operativa absoluta permanece en
plugins.load.paths; el registro de instalación evita duplicar rutas de la estación de trabajo local
en la configuración persistente. Esto mantiene las instalaciones de desarrollo local visibles para
los diagnósticos del plano de origen sin añadir una segunda superficie de divulgación de rutas
del sistema de archivos sin procesar. La tabla SQLite persistente installed_plugin_index es la
fuente de verdad de la instalación y puede actualizarse sin cargar los módulos de ejecución del plugin.
Su mapa installRecords es persistente incluso cuando falta el manifiesto de un plugin o
no es válido; su carga útil plugins es una vista reconstruible del manifiesto.
Plugins del motor de contexto
Los plugins del motor de contexto son responsables de la orquestación del contexto de sesión para la ingesta, el ensamblaje y la Compaction. Regístrelos desde el plugin conapi.registerContextEngine(id, factory) y, a continuación, seleccione el motor activo con
plugins.slots.contextEngine.
Use esta opción cuando el plugin necesite reemplazar o ampliar el pipeline de contexto
predeterminado, en lugar de limitarse a añadir búsqueda en memoria o hooks.
ctx expone valores opcionales config, agentDir y workspaceDir
para la inicialización durante la construcción.
El host completa la preparación asíncrona registrada del prompt de memoria antes de llamar a
assemble() de un motor no heredado. buildMemorySystemPromptAddition(...) permanece
síncrono y lee esa instantánea inmutable de la ejecución mientras assemble() está activo.
Pase sin cambios el contexto proporcionado de herramientas y citas para que la instantánea
no pueda cruzar los límites de la ejecución.
assemble() puede devolver contextProjection cuando el arnés activo tiene un
hilo persistente del backend. Omítalo para la proyección heredada por turno. Devuelva
{ mode: "thread_bootstrap", epoch } cuando el contexto ensamblado deba
inyectarse una vez en un hilo del backend y reutilizarse hasta que cambie la época. Cambie
la época después de que cambie el contexto semántico del motor, por ejemplo, tras una
pasada de Compaction gestionada por el motor. Los hosts pueden conservar los metadatos de llamadas a herramientas, la forma
de la entrada y los resultados censurados de las herramientas en una proyección de arranque del hilo para que los
hilos nuevos del backend mantengan la continuidad de las herramientas sin copiar cargas
sin procesar que contengan secretos.
Si el motor no controla el algoritmo de Compaction, mantenga compact()
implementado y deléguelo explícitamente:
Añadir una capacidad nueva
Cuando un plugin necesite un comportamiento que no encaje en la API actual, no eluda el sistema de plugins accediendo de forma privada a sus componentes internos. Añada la capacidad que falta. Secuencia recomendada:- Defina el contrato del núcleo. Decida qué comportamiento compartido debe controlar el núcleo: políticas, mecanismo alternativo, combinación de configuración, ciclo de vida, semántica orientada a canales y forma del asistente de tiempo de ejecución.
- Añada superficies tipadas de registro y tiempo de ejecución de plugins. Amplíe
OpenClawPluginApiy/oapi.runtimecon la superficie tipada de capacidad útil más pequeña. - Conecte el núcleo y los consumidores de canales/funcionalidades. Los canales y plugins de funcionalidades deben consumir la nueva capacidad a través del núcleo, no importando directamente una implementación de un proveedor.
- Registre las implementaciones de los proveedores. A continuación, los plugins de los proveedores registran sus backends para la capacidad.
- Añada cobertura del contrato. Añada pruebas para que la propiedad y la forma del registro permanezcan explícitas con el tiempo.
Lista de comprobación de capacidades
Cuando añada una capacidad nueva, la implementación normalmente debe abarcar conjuntamente estas superficies:- tipos de contratos del núcleo en
src/<capability>/types.ts - ejecutor o asistente de tiempo de ejecución del núcleo en
src/<capability>/runtime.ts - superficie de registro de la API de plugins en
src/plugins/types.ts - conexión del registro de plugins en
src/plugins/registry.ts - exposición del tiempo de ejecución del plugin en
src/plugins/runtime/*cuando los plugins de funcionalidades o canales necesiten consumirla - asistentes de captura y pruebas en
src/test-utils/plugin-registration.ts - aserciones de propiedad y contrato en
src/plugins/contracts/registry.ts - documentación para operadores y plugins en
docs/
Plantilla de capacidad
Patrón mínimo:src/plugins/contracts/registry.ts expone búsquedas de
propiedad como providerContractPluginIds; las pruebas verifican que la lista
contracts.videoGenerationProviders de un plugin coincida con lo que realmente registra):
- el núcleo controla el contrato y la orquestación de la capacidad
- los plugins de los proveedores controlan sus implementaciones
- los plugins de funcionalidades y canales consumen los asistentes de tiempo de ejecución
- las pruebas de contratos mantienen explícita la propiedad
Contenido relacionado
- Arquitectura de plugins — modelo público de capacidades y formas
- Subrutas del SDK de plugins
- Configuración del SDK de plugins
- Creación de plugins