exec y wait. El modelo escribe un pequeño programa en JavaScript o TypeScript que busca, describe y llama al catálogo de herramientas oculto.
Esta página documenta el modo de código de OpenClaw, no Codex Code Mode. Las dos funciones comparten un nombre y los mismos nombres de herramientas visibles para el modelo (exec, wait), pero son implementaciones separadas:
- Codex Code Mode se ejecuta dentro del arnés de programación de Codex. Su herramienta
execes una herramienta de gramática libre: el modelo escribe código fuente JavaScript sin procesar (opcionalmente precedido por una línea pragma// @exec: {...}para opciones de ejecución), ejecutado en un runtime Deno/V8. - El modo de código de OpenClaw se ejecuta en el runtime genérico de agentes de OpenClaw y está deshabilitado salvo que se configure
tools.codeMode.enabled: true. Su herramientaexecrecibe una carga JSON{ code, language }, ejecutada en un worker QuickJS-WASI.
exec/wait con nombres idénticos.
Qué hace
- La lista de herramientas visible para el modelo pasa a ser exactamente
execywait. execevalúa JavaScript o TypeScript generado por el modelo en un hilo worker QuickJS-WASI aislado.- Todas las demás herramientas habilitadas (núcleo de OpenClaw, Plugin, MCP, cliente) se ocultan del prompt del modelo y se exponen dentro del programa invitado mediante
ALL_TOOLSytools. - El código invitado busca en el catálogo oculto, describe el esquema de una herramienta y llama a una herramienta a través de la misma ruta de ejecución usada por los turnos normales del agente (política, aprobaciones, hooks y telemetría siguen aplicándose).
- Las herramientas MCP se agrupan bajo el espacio de nombres
MCP; en modo de código, esta es la única forma admitida de llamarlas. waitreanuda una ejecución suspendida en modo de código cuando todavía hay llamadas a herramientas anidadas pendientes.
Por qué usarlo
- Superficie de prompt más pequeña: los proveedores reciben dos herramientas de control en lugar de docenas o cientos de esquemas completos de herramientas.
- Mejor orquestación: el modelo puede usar bucles, uniones, pequeñas transformaciones, lógica condicional y llamadas a herramientas anidadas en paralelo dentro de una celda de código.
- Neutral respecto al proveedor: funciona con herramientas de OpenClaw, Plugin, MCP y cliente sin depender de ejecución de código nativa del proveedor.
- Falla de forma cerrada: si el modo de código está habilitado pero el runtime QuickJS-WASI no está disponible, la ejecución falla en lugar de volver silenciosamente a una exposición directa amplia de herramientas.
Habilitarlo
tools.codeMode se omite, es false o es un objeto sin enabled: true.
Si usas agentes en sandbox con servidores MCP configurados, permite también el Plugin MCP incluido en la política de herramientas del sandbox, por ejemplo tools.sandbox.tools.alsoAllow: ["bundle-mcp"]. Consulta Configuración: herramientas y proveedores personalizados.
Define límites explícitos para cotas más estrictas:
exec y wait. Para la carga completa censurada del proveedor, añade OPENCLAW_DEBUG_MODEL_PAYLOAD=full-redacted durante una sesión breve de depuración.
Recorrido técnico
El resto de esta página cubre el contrato de runtime y los detalles de implementación para mantenedores, autores de Plugin que depuran la exposición de herramientas y operadores que validan despliegues de alto riesgo.Estado del runtime
| Runtime | quickjs-wasi |
| Estado predeterminado | deshabilitado |
| Estabilidad | superficie experimental de OpenClaw (Codex Code Mode es una superficie separada y estable del arnés de Codex) |
| Superficie objetivo | ejecuciones genéricas de agentes de OpenClaw |
| Postura de seguridad | el código del modelo es hostil |
| Promesa de cara al usuario | habilitar el modo de código nunca vuelve silenciosamente a una exposición directa amplia de herramientas |
Alcance
El modo de código es dueño de la forma de orquestación orientada al modelo para una ejecución preparada. No es dueño de la selección de modelo, el comportamiento de canal, la autenticación, la política de herramientas ni las implementaciones de herramientas. Dentro del alcance: definiciones deexec/wait visibles para el modelo, construcción del catálogo de herramientas oculto, ejecución invitada de JavaScript/TypeScript, runtime worker QuickJS-WASI, callbacks de host para buscar/describir/llamar, estado reanudable para programas invitados suspendidos, límites de salida/tiempo de espera/memoria/llamadas pendientes/snapshot y proyección de telemetría/trayectoria para llamadas a herramientas anidadas.
Fuera del alcance: ejecución remota de código nativa del proveedor, semántica de ejecución de shell, cambios en la autorización existente de herramientas, scripts persistentes escritos por usuarios, acceso a gestor de paquetes/archivo/red/módulo en código invitado y reutilización directa de elementos internos de Codex Code Mode.
Las herramientas propiedad del proveedor, como sandboxes remotos de Python, son herramientas separadas. Consulta Ejecución de código.
Términos
- Modo de código: el modo de runtime de OpenClaw que oculta las herramientas normales del modelo y expone solo
execywait. - Runtime invitado: la VM JavaScript QuickJS-WASI que evalúa el código del modelo.
- Puente de host: la superficie estrecha de callbacks compatible con JSON desde el código invitado de vuelta a OpenClaw.
- Catálogo: la lista con alcance de ejecución de herramientas efectivas después de la resolución normal de política de herramientas, Plugin, MCP y herramientas de cliente.
- Llamada a herramienta anidada: una llamada a herramienta hecha desde código invitado a través del puente de host.
- Snapshot: estado serializado de la VM QuickJS-WASI guardado para que
waitpueda continuar una ejecución suspendida en modo de código.
Configuración
tools.codeMode.enabled es la puerta de activación; definir otros campos no habilita la función por sí solo.
| Campo | Predeterminado | Límite |
|---|---|---|
enabled | false | booleano; solo true habilita el modo de código |
runtime | "quickjs-wasi" | único valor admitido |
mode | "only" | expone exec/wait, oculta las herramientas normales del modelo |
languages | ["javascript", "typescript"] | cualquier subconjunto de los dos |
timeoutMs | 10000 | 100-60000 |
memoryLimitBytes | 67108864 | 1048576-1073741824 |
maxOutputBytes | 65536 | 1024-10485760 |
maxSnapshotBytes | 10485760 | 1024-268435456 |
maxPendingToolCalls | 16 | 1-128 |
snapshotTtlSeconds | 900 | 1-86400 |
searchDefaultLimit | 8 | limitado a maxSearchLimit |
maxSearchLimit | 50 | 1-50 |
Activación
El modo de código se evalúa después de conocer la política efectiva de herramientas y antes de ensamblar la solicitud final al modelo:- Resolver el agente, modelo, proveedor, sandbox, canal, remitente y política de ejecución.
- Crear la lista efectiva de herramientas de OpenClaw, añadiendo herramientas elegibles de Plugin, MCP y cliente.
- Aplicar la política de permitir/denegar.
- Si
tools.codeMode.enabledes falso, continuar con la exposición normal de herramientas. - Si está habilitado y las herramientas están activas para la ejecución, registrar las herramientas efectivas en el catálogo de modo de código.
- Eliminar todas las herramientas normales de la lista visible para el modelo; añadir
execywait.
disableTools: true o una lista tools.allow vacía) no activan la superficie de modo de código incluso cuando tools.codeMode.enabled: true está configurado. El modo de código y OpenClaw Tool Search son mutuamente excluyentes para una ejecución; si se activa el modo de código, la Compaction de Tool Search no lo hace.
El catálogo de modo de código tiene alcance de ejecución y no debe filtrar herramientas de otro agente, sesión, remitente o ejecución.
Herramientas visibles para el modelo
Cuando el modo de código está activo, el modelo ve exactamenteexec y wait. Todas las demás herramientas habilitadas se ocultan de la lista de herramientas orientada al modelo y se registran en el catálogo de modo de código.
Usa exec para orquestación de herramientas, unión de datos, bucles, llamadas anidadas en paralelo y transformaciones estructuradas. Usa wait solo cuando exec devuelva un resultado reanudable waiting.
exec
exec inicia una celda de modo de código y devuelve un resultado. El código de entrada es generado por el modelo y debe tratarse como hostil.
Entrada:
- Uno de
codeocommanddebe no estar vacío. codees el campo documentado orientado al modelo.commandse acepta como un alias compatible con exec para políticas de hooks y reescrituras de confianza (la herramienta normalexecde shell de OpenClaw también usa un campocommand); cuando ambos están presentes, los valores deben coincidir.languagetoma"javascript"como valor predeterminado; el esquema lo expone como un enum de cadena plano ("javascript" | "typescript"), no como una uniónoneOf/anyOf, ya que algunos proveedores rechazan esas formas.- Si
languagees"typescript", OpenClaw transpila antes de evaluar. execrechazaimport,require, importación dinámica y patrones de cargador de módulos.execnunca expone recursivamente la implementación normal de shellexec.- Los eventos de hook externos de
execen modo de código llevantoolKind: "code_mode_exec"ytoolInputKind: "javascript" | "typescript"(cuando se conoce), para que las políticas puedan distinguir celdas de modo de código de llamadasexecde estilo shell que comparten el mismo nombre de herramienta.
exec devuelve waiting cuando la VM de QuickJS se suspende con estado reanudable que
aún necesita una continuación visible para el modelo; el resultado incluye un runId para
wait. Las llamadas de puente de espacios de nombres, incluidas las llamadas de espacios de nombres MCP, se drenan automáticamente
dentro de la misma llamada exec/wait mientras están listas, por lo que un bloque de código
compacto puede llamar a una herramienta MCP sin forzar una llamada de herramienta del modelo por cada espera
de espacio de nombres.
exec devuelve completed solo cuando la VM invitada no tiene trabajo pendiente y el
valor final es compatible con JSON después de que se ejecute el adaptador de salida de OpenClaw.
wait
wait continúa una VM de modo código suspendida.
Entrada:
CodeModeResult que devuelve exec.
wait existe porque las herramientas anidadas de OpenClaw pueden ser lentas, interactivas, estar
bloqueadas por aprobaciones o transmitir actualizaciones parciales; el modelo no debería tener que
mantener abierta una llamada exec larga mientras el anfitrión espera trabajo externo.
La instantánea/restauración de QuickJS-WASI es el mecanismo de reanudación:
execevalúa el código hasta completarse, fallar o suspenderse.- Al suspenderse, OpenClaw toma una instantánea de la VM de QuickJS y registra el trabajo pendiente del anfitrión.
- Cuando el trabajo pendiente se resuelve,
waitrestaura la instantánea de la VM y vuelve a registrar las devoluciones de llamada del anfitrión mediante nombres estables. - OpenClaw entrega resultados de herramientas anidadas en la VM restaurada y drena los trabajos pendientes de QuickJS.
waitdevuelvecompleted,failedu otro resultadowaiting.
wait falla (como resultado failed) cuando:
runIdes desconocido o su instantánea ya caducó.- el llamador no está en el mismo ámbito de ejecución/sesión que la ejecución suspendida.
- ya hay un
waiten curso para eserunId. - falla la restauración de QuickJS-WASI.
- la reanudación superaría
maxOutputBytesomaxSnapshotBytes.
API del entorno de ejecución invitado
ALL_TOOLS es metadato compacto para el catálogo con ámbito de ejecución; no
contiene esquemas completos de forma predeterminada.
source: "openclaw" con sourceName establecido en el id del
Plugin propietario; no hay un valor de origen "plugin" separado. source: "mcp" se
usa solo para entradas MCP en metadatos sourceName/mcp (y se filtra
de ALL_TOOLS/tools.*; consulta abajo).
El esquema completo se carga solo bajo demanda:
tools.call(...) ni funciones de conveniencia
en modo código; se exponen solo a través del espacio de nombres MCP
generado. Los archivos de declaración de estilo TypeScript están disponibles a través de la
superficie de archivo virtual API de solo lectura, de modo que los agentes puedan inspeccionar las firmas MCP
sin agregar esquemas MCP al prompt:
API.read("mcp/<server>.d.ts") devuelve declaraciones compactas inferidas a partir de los
metadatos de herramientas MCP:
exec de modo código, OpenClaw crea el catálogo de herramientas
con ámbito de ejecución, conserva las entradas MCP visibles, renderiza mcp/index.d.ts más un
mcp/<server>.d.ts por cada servidor visible e inyecta esa pequeña tabla de solo lectura
en el worker de QuickJS. El código invitado ve solo el objeto API:
API.list(prefix?) devuelve metadatos de archivo y API.read(path) devuelve el
contenido de declaración seleccionado. Se rechazan las rutas desconocidas y los segmentos
./...
Esto mantiene los esquemas MCP grandes fuera del prompt del modelo: el agente aprende que la
API virtual existe a partir de la descripción de la herramienta exec, lee solo el archivo de
declaración necesario y luego llama a MCP.<server>.<tool>() con un argumento de objeto.
MCP.<server>.$api() sigue disponible como alternativa en línea para una
respuesta de esquema de una sola herramienta dentro del programa.
El entorno de ejecución invitado nunca ve objetos del anfitrión directamente. Las entradas y salidas cruzan
el puente como valores compatibles con JSON con límites de tamaño explícitos.
Espacios de nombres internos
Los espacios de nombres internos dan al modo código una API de dominio concisa sin agregar más herramientas visibles para el modelo. Una integración propiedad del cargador registra un espacio de nombres comoIssues o Calendar; el código invitado llama entonces a ese espacio de nombres dentro del
programa QuickJS mientras el modelo sigue viendo solo exec y wait.
Los espacios de nombres son internos por ahora. No hay una API pública de espacios de nombres del SDK de Plugin:
los espacios de nombres de plugins externos necesitan un contrato propiedad del cargador para que la identidad del Plugin,
los manifiestos instalados, el estado de autenticación y los descriptores de catálogo en caché no puedan desviarse
de las herramientas de Plugin que respaldan el espacio de nombres. El modo código de core posee solo el
sandbox, la serialización, el control del catálogo y el despacho del puente.
El código invitado puede usar el global directo o el mapa namespaces:
Ciclo de vida del registro
El registro de espacios de nombres es local al proceso y se indexa por id de espacio de nombres:- Un cargador de confianza llama a
registerCodeModeNamespaceForPlugin(pluginId, registration). - El modo código crea el
ToolSearchRuntimeoculto para la ejecución y lee su catálogo con ámbito de ejecución. createCodeModeNamespaceRuntime(ctx, catalog)conserva solo los registros cuyosrequiredToolNamesson todos visibles y propiedad del mismopluginId.- Cada espacio de nombres visible llama a
createScope(ctx)para la ejecución actual, y recibe contexto de ejecución comoagentId,sessionKey,sessionId,runId, configuración y estado de aborto. - Los datos de ámbito se serializan en un descriptor plano y se inyectan en QuickJS
como globales directos y
namespaces.<globalName>. - Las llamadas invitadas se suspenden a través del puente del worker, resuelven la ruta del espacio de nombres
en el anfitrión, asignan la llamada a una herramienta de catálogo declarada propiedad del Plugin y
ejecutan esa herramienta mediante
ToolSearchRuntime.callExactId. - Las llamadas de puente de espacio de nombres listas se drenan automáticamente dentro de la llamada
exec/waitactiva; si el trabajo del espacio de nombres sigue pendiente al agotarse el tiempo de espera o el invitado cede explícitamente,waitreanuda el mismo entorno de ejecución de espacio de nombres más tarde. - La reversión o desinstalación del Plugin llama a
clearCodeModeNamespacesForPlugin(pluginId)para que los globales obsoletos no sobrevivan a una carga fallida del Plugin.
tools.call(...).
Forma del registro
Registra espacios de nombres desde la integración que posee las herramientas subyacentes. Mantén el ámbito pequeño y expón solo verbos de dominio que se asignen a herramientas de catálogo declaradas.createCodeModeNamespaceTool(toolName, inputMapper) marca un miembro de ámbito como una
función de espacio de nombres invocable. El inputMapper opcional recibe los argumentos
del invitado y devuelve el objeto de entrada para la herramienta de catálogo subyacente; sin
uno, se usa el primer argumento del invitado, o {} cuando se omite.
Las funciones sin procesar del anfitrión se rechazan antes de que se ejecute el código invitado:
Propiedad y visibilidad
La propiedad del espacio de nombres está vinculada alpluginId del llamador del registro.
requiredToolNames es a la vez una puerta de visibilidad y una verificación de propiedad:
- cada herramienta requerida debe existir en el catálogo de ejecución
- cada herramienta requerida debe tener
sourceName === pluginId - el espacio de nombres se oculta cuando falta alguna herramienta requerida o pertenece a otro Plugin
- cada ruta invocable solo puede apuntar a una herramienta nombrada en
requiredToolNames
Reglas de serialización de ámbito
createScope(ctx) puede devolver un objeto plano que contenga valores compatibles con JSON,
arreglos, objetos anidados y marcadores de llamada createCodeModeNamespaceTool(...).
Los objetos del anfitrión nunca entran directamente en QuickJS.
El serializador rechaza:
- funciones sin procesar
- grafos de objetos circulares
- segmentos de ruta inseguros:
__proto__,constructor,prototype, claves vacías, o claves que contengan el separador interno de ruta - valores de
globalNameque no son identificadores de JavaScript - colisiones de
globalNamecon globales integrados de modo código comotools,namespaces,text,json,yield_control,MCP,API,ALL_TOOLSo__openclaw*
Prompts
Ladescription del espacio de nombres y el prompt opcional se anexan al esquema
exec visible para el modelo solo cuando el espacio de nombres es visible para esa ejecución. Úsalos
para enseñar la superficie útil más pequeña:
Limpieza
Los espacios de nombres son registros locales del proceso. Elimínalos cuando el plugin propietario se deshabilite, desinstale o revierta:clearCodeModeNamespacesForTest() para evitar filtrar
registros entre casos.
Lista de comprobación de pruebas
Los cambios de espacios de nombres deben cubrir el límite de seguridad y el comportamiento del invitado:- el texto del prompt del espacio de nombres aparece solo cuando las herramientas de respaldo son visibles
- las herramientas con el mismo nombre de otro
sourceNameno exponen el espacio de nombres - se rechazan las funciones de alcance sin procesar
- se rechazan los ids de espacios de nombres falsificados y las rutas falsificadas
- las rutas invocables no pueden apuntar a herramientas no declaradas
- los objetos anidados y las referencias compartidas se serializan correctamente
- las llamadas al espacio de nombres se ejecutan mediante herramientas del catálogo y devuelven detalles seguros para JSON
- el código invitado puede capturar los fallos
- las llamadas suspendidas al espacio de nombres se reanudan mediante
wait - la reversión del plugin borra los registros de espacios de nombres propietarios
tools.search/tools.call: usa el
catálogo para herramientas arbitrarias habilitadas de OpenClaw, plugins y clientes; usa MCP
para herramientas MCP; usa otros espacios de nombres para APIs de dominio documentadas y propiedad del plugin
cuando el código conciso sea más fiable que las búsquedas repetidas de esquemas.
API de salida
text(value)anexa salida legible por humanos al arrayoutput.json(value)anexa un elemento de salida estructurado después de una serialización compatible con JSON.- El valor devuelto final del código invitado se convierte en
valueen un resultadocompleted.
maxOutputBytes; los valores no serializables se convierten en cadenas simples o
errores; no se admiten valores binarios. Las imágenes y los archivos viajan mediante
herramientas ordinarias de OpenClaw, no mediante el puente del modo de código.
Catálogo de herramientas
El catálogo oculto incluye herramientas después del filtrado de política efectivo, en este orden: herramientas principales de OpenClaw, herramientas de plugins incluidos, herramientas de plugins externos, herramientas MCP y luego herramientas proporcionadas por el cliente para la ejecución actual. Los ids de catálogo son estables dentro de una ejecución y deterministas entre conjuntos de herramientas equivalentes cuando es posible. Forma real:<source> es openclaw, mcp o client (las herramientas de plugin usan
openclaw con el id del plugin como <owner>; las herramientas principales usan openclaw:core:*).
Ejemplos:
exec, wait, tool_search_code,
tool_search, tool_describe, tool_call. Esto evita la recursión y mantiene
estrecho el contrato orientado al modelo.
Las entradas MCP permanecen en el catálogo con alcance de ejecución para que la política, las aprobaciones, los hooks,
la telemetría, la proyección de transcripción y los ids exactos de herramientas sigan compartidos con
la ejecución normal de herramientas. Las vistas orientadas al invitado ALL_TOOLS, tools.search(...),
tools.describe(...) y tools.call(...) omiten las entradas MCP. El
espacio de nombres generado MCP.<server>.<tool>({ ...input }) se resuelve de vuelta al
id exacto del catálogo y se despacha mediante la misma ruta del ejecutor.
Interacción con Búsqueda de herramientas
El modo de código sustituye la superficie del modelo de Búsqueda de herramientas de OpenClaw en ejecuciones donde está activo. Cuandotools.codeMode.enabled es true y se activa el modo de código:
- OpenClaw no expone
tool_search_code,tool_search,tool_describenitool_callcomo herramientas visibles para el modelo. - La misma idea de catalogación se mueve dentro del runtime invitado.
- El runtime invitado recibe metadatos compactos de
ALL_TOOLSy helpers de búsqueda/descripción/ llamada para herramientas que no son MCP. - Las llamadas MCP usan el espacio de nombres generado
MCPy sus encabezados$api()en lugar detools.call(...). - Las llamadas anidadas se despachan mediante la misma ruta de ejecutor de OpenClaw que usa Búsqueda de herramientas.
Nombres de herramientas y colisiones
La herramientaexec visible para el modelo es la herramienta de modo de código. Si la herramienta normal de shell de OpenClaw
exec está habilitada, se oculta del modelo y se cataloga como
cualquier otra herramienta.
Dentro del runtime invitado:
tools.call("openclaw:core:exec", input)puede llamar a la herramienta shell exec si la política lo permite.tools.exec(...)se instala solo si la entrada de catálogo shell exec tiene un nombre seguro no ambiguo.- la herramienta
execde modo de código nunca está disponible recursivamente mediantetools.
tools.call(id, input).
Ejecución de herramientas anidadas
Cada llamada de herramienta anidada cruza el puente del host y vuelve a entrar en OpenClaw, preservando: id de agente activo, id y clave de sesión, contexto de remitente y canal, política de sandbox, política de aprobación, hooksbefore_tool_call de plugin, señal de cancelación,
actualizaciones de streaming cuando estén disponibles y eventos de trayectoria/auditoría.
Las llamadas anidadas se proyectan en la transcripción como llamadas de herramientas reales para que los paquetes de
soporte muestren lo ocurrido, con la proyección identificando la llamada de herramienta
de modo de código padre y el id de herramienta anidada.
Se permiten llamadas anidadas paralelas hasta maxPendingToolCalls.
Ciclo de vida de ejecución e instantánea
Cada ejecución de modo de código se rastrea en un mapa en proceso indexado porrunId (no
persistido en disco ni en una base de datos). exec/wait devuelven uno de tres estados de resultado:
completed, waiting o failed.
- Un resultado
waitingalmacena la instantánea de QuickJS, las solicitudes pendientes del puente y metadatos de alcance (id de ejecución del agente, id/clave de sesión) hasta quewaitlo reanuda o caduca. - Los valores de
runIdcaducados, de sesión incorrecta, de ejecución incorrecta y desconocidos/ya en reanudación no producen un estado terminal distinto; emergen como un resultadofailed(code: "invalid_input") con un mensaje comocode mode run is unavailable or expired.ocode mode run belongs to a different session.. - La instantánea de una ejecución se elimina del mapa tan pronto como se resuelve como
completedofailed, o se descarta al apagar el Gateway (nada sobrevive a un reinicio, por diseño: esto es estado transitorio del runtime). - OpenClaw limita el número de ejecuciones suspendidas simultáneamente por proceso (64) y
rechaza nuevas suspensiones por encima de ese límite con
too many suspended code mode runs..
maxSnapshotBytes por ejecución, el límite por proceso
de ejecuciones suspendidas anterior y snapshotTtlSeconds.
Runtime QuickJS-WASI
OpenClaw cargaquickjs-wasi como dependencia directa en el paquete propietario; no
depende de una copia transitiva instalada para una dependencia no relacionada.
Responsabilidades del runtime: compilar/cargar el módulo WebAssembly QuickJS-WASI;
crear una VM aislada por cada ejecución o reanudación de modo de código; registrar callbacks del host
con nombres estables; establecer límites de memoria e interrupción; evaluar JavaScript; drenar
trabajos pendientes; crear instantáneas del estado suspendido de la VM; restaurar instantáneas para wait;
desechar manejadores de VM e instantáneas después de estados terminales.
El runtime se ejecuta en un hilo worker de Node.js, fuera del bucle de eventos principal de OpenClaw.
Un bucle infinito del invitado no debe bloquear indefinidamente el proceso Gateway;
el manejador de interrupciones del worker aplica el tiempo límite de reloj de pared
independientemente de que el código invitado coopere.
TypeScript
El soporte de TypeScript es solo una transformación de fuente: la entrada aceptada es una cadena de código TypeScript; la salida es una cadena JavaScript evaluada por QuickJS-WASI. No hay comprobación de tipos, resolución de módulos niimport/require. Los diagnósticos se devuelven como resultados failed.
El compilador de TypeScript se carga de forma diferida solo para celdas TypeScript; las celdas de
JavaScript simple y el modo de código deshabilitado nunca lo cargan.
Límite de seguridad
El código del modelo es hostil. El runtime usa defensa en profundidad:- ejecuta QuickJS-WASI fuera del bucle de eventos principal, en un hilo worker
- carga
quickjs-wasicomo dependencia directa, no mediante Codex ni un paquete transitivo - sin sistema de archivos, red, subprocesos, importación de módulos, variables de entorno ni objetos globales del host en el invitado
- usa límites de memoria e interrupción de QuickJS más un tiempo límite de reloj de pared del proceso padre
- aplica límites de salida, instantánea, registro y llamadas pendientes
- serializa los valores del puente del host mediante un adaptador JSON estrecho
- convierte errores del host en errores simples del invitado, nunca en objetos del ámbito del host
- descarta instantáneas por timeout, cancelación, fin de sesión o caducidad
- rechaza acceso recursivo a
exec,waity herramientas de control de Búsqueda de herramientas - evita que las colisiones de nombres de conveniencia oculten helpers del catálogo
Códigos de error
invalid_input cubre argumentos incorrectos de exec/wait, lenguajes deshabilitados,
acceso a módulos rechazado, fallos de transformación de TypeScript, valores de runId desconocidos/caducados/
con alcance incorrecto y demasiadas ejecuciones suspendidas. runtime_unavailable
cubre un worker QuickJS que no logra iniciar o sale con código distinto de cero.
Los errores devueltos al invitado son datos simples; las instancias Error del host, objetos de pila,
prototipos y funciones del host no cruzan a QuickJS.
Telemetría
El campotelemetry de cada resultado informa: tamaño del catálogo oculto y desglose por fuente
(conteos openclaw/mcp/client), conteos acumulados de búsqueda/descripción/llamada
para el catálogo de la ejecución y los nombres de herramientas visibles para el modelo (exec,
wait).
La telemetría no debe incluir secretos, valores de entorno sin procesar ni entradas de herramientas
sin redactar más allá de la política de trayectoria existente de OpenClaw.
Depuración
Usa registro dirigido del transporte del modelo cuando el modo de código se comporte de forma distinta a una ejecución normal de herramienta:OPENCLAW_DEBUG_MODEL_PAYLOAD=full-redacted.
Esto registra una instantánea JSON limitada y redactada de la solicitud del modelo; úsalo solo
durante la depuración, ya que los prompts y el texto de mensajes aún pueden aparecer.
Para depurar streams, usa OPENCLAW_DEBUG_SSE=peek para registrar los primeros cinco
eventos SSE redactados. El modo de código también falla en cerrado si el payload final del proveedor
no contiene exactamente exec y wait después de que la superficie de modo de código
se haya activado.
Diseño de implementación
- contrato de configuración:
tools.codeMode - constructor de catálogo: herramientas efectivas a entradas compactas y mapa de ids
- adaptador de superficie del modelo: reemplazar herramientas visibles por
execywait - adaptador de runtime QuickJS-WASI: cargar, evaluar, crear instantánea, restaurar, desechar
- supervisor de worker: timeout, cancelación, aislamiento de fallos
- adaptador de puente: callbacks del host seguros para JSON y entrega de resultados
- adaptador de transformación de TypeScript
- almacén de instantáneas: TTL, límites de tamaño, alcance de ejecución/sesión
- proyección de trayectoria para llamadas de herramientas anidadas
- contadores de telemetría y diagnósticos
node:vm como sandbox.
Lista de comprobación de validación
La cobertura del modo de código debe demostrar:- la configuración deshabilitada deja sin cambios la exposición existente de herramientas
- la configuración de objeto sin
enabled: truedeja deshabilitado el modo código - la configuración habilitada expone solo
execywaital modelo cuando las herramientas están activas para la ejecución - las ejecuciones sin herramientas en bruto,
disableToolsy las listas de permitidos vacías no activan la aplicación de la carga útil del modo código - todas las herramientas no MCP efectivas aparecen en
ALL_TOOLS - las herramientas denegadas no aparecen en
ALL_TOOLS tools.search,tools.describeytools.callfuncionan para las herramientas de OpenClawAPI.list("mcp")yAPI.read("mcp/<server>.d.ts")exponen declaraciones MCP de estilo TypeScript sin una llamada de puente/herramienta- el espacio de nombres MCP
$api()sigue disponible como alternativa en línea para esquemas - las llamadas al espacio de nombres MCP funcionan para herramientas MCP visibles con una entrada de objeto, mientras
las entradas directas del catálogo MCP están ausentes de
tools.* - las herramientas de control de Búsqueda de herramientas están ocultas tanto de la superficie del modelo como del catálogo oculto
- las llamadas anidadas conservan el comportamiento de aprobación y hooks
execde shell está oculto para el modelo, pero se puede llamar por id de catálogo cuando está permitidoexecywaitrecursivos en modo código no se pueden llamar desde código invitado- la entrada TypeScript se transforma y evalúa sin cargar TypeScript en rutas deshabilitadas o solo JavaScript
import,require, el sistema de archivos, la red y el acceso al entorno fallan- los bucles infinitos agotan el tiempo de espera y no pueden bloquear el Gateway
- los fallos del límite de memoria terminan la VM invitada
- los límites de salida e instantánea se aplican para llamadas completadas y suspendidas
waitreanuda una instantánea suspendida y devuelve el valor final- los valores de
runIdexpirados, cancelados, de sesión incorrecta y desconocidos fallan - la reproducción y persistencia de la transcripción conservan las llamadas de control del modo código
- la transcripción y la telemetría muestran claramente las llamadas a herramientas anidadas
Plan de pruebas E2E
Ejecuta estas pruebas como pruebas de integración o de extremo a extremo al cambiar el runtime:- Inicia un Gateway con
tools.codeMode.enabled: false. - Envía un turno de agente con un pequeño conjunto directo de herramientas.
- Afirma que las herramientas visibles para el modelo no han cambiado.
- Reinicia con
tools.codeMode.enabled: true. - Envía un turno de agente con herramientas de prueba de OpenClaw, plugin, MCP y cliente.
- Afirma que la lista de herramientas visibles para el modelo es exactamente
exec,wait. - En
exec, leeALL_TOOLSy afirma que las herramientas de prueba efectivas están presentes. - En
exec, llama a herramientas de OpenClaw/plugin/cliente mediantetools.search,tools.describeytools.call. - En
exec, llama aAPI.list("mcp")yAPI.read("mcp/<server>.d.ts")y afirma que los archivos de declaración describen herramientas MCP visibles. - En
exec, llama a herramientas MCP medianteMCP.<server>.<tool>({ ...input })y afirma que las entradas directas del catálogo MCP están ausentes deALL_TOOLSytools.*. - Afirma que las herramientas denegadas están ausentes y no pueden llamarse mediante un id adivinado.
- Inicia una llamada a herramienta anidada que se resuelve después de que
execdevuelvawaiting. - Llama a
waity afirma que la VM restaurada recibe el resultado de la herramienta. - Afirma que la respuesta final contiene la salida producida después de la restauración.
- Afirma que el tiempo de espera agotado, la cancelación y la expiración de instantáneas limpian el estado del runtime.
- Exporta la trayectoria y afirma que las llamadas anidadas son visibles bajo la llamada principal de modo código.
pnpm check:docs.