exec, wait e qualquer ferramenta exclusivamente direta cujo resultado estruturado não possa atravessar
a ponte do guest, que aceita apenas JSON. O modelo escreve um pequeno programa JavaScript ou TypeScript
que pesquisa, descreve e chama o catálogo oculto de ferramentas.
Esta página documenta o modo de código do OpenClaw, não o Codex Code Mode. Os dois recursos
compartilham um nome e os mesmos nomes de ferramentas de controle (exec, wait), mas são
implementações separadas:
- O Codex Code Mode é executado dentro do ambiente de programação do Codex. Sua ferramenta
execé uma ferramenta de gramática livre: o modelo escreve código-fonte JavaScript bruto (opcionalmente prefixado por uma linha de pragma// @exec: {...}para opções de execução), executado em um runtime Deno/V8. - O modo de código do OpenClaw é executado no runtime genérico de agentes do OpenClaw e fica
desativado, a menos que
tools.codeMode.enabled: trueesteja configurado. Sua ferramentaexecrecebe um payload JSON{ code, language }, executado em um worker QuickJS-WASI.
exec/wait com nomes idênticos.
O que ele faz
- A lista de ferramentas visível ao modelo passa a ser
exec,waite qualquer ferramenta exclusivamente direta, comocomputer, cujo resultado de imagem não possa atravessar a ponte do guest. execavalia JavaScript ou TypeScript gerado pelo modelo em uma thread de worker QuickJS-WASI isolada.- Todas as ferramentas habilitadas elegíveis para o catálogo (núcleo do OpenClaw, Plugin, MCP, cliente) são ocultadas do
prompt do modelo e expostas dentro do programa guest por meio de
ALL_TOOLSetools. - O código guest pesquisa o catálogo oculto, descreve o esquema de uma ferramenta e chama uma ferramenta pelo mesmo caminho de execução usado em turnos normais do agente (políticas, aprovações, hooks e telemetria continuam sendo aplicados).
- As ferramentas MCP são agrupadas no namespace
MCP; no modo de código, essa é a única maneira compatível de chamá-las. waitretoma uma execução suspensa do modo de código quando chamadas de ferramentas aninhadas ainda estão pendentes.
Por que usá-lo
- Superfície de prompt menor: os provedores recebem duas ferramentas de controle e apenas as poucas ferramentas diretas necessárias, em vez de dezenas ou centenas de esquemas completos de ferramentas.
- Melhor orquestração: o modelo pode usar loops, junções, pequenas transformações, lógica condicional e chamadas paralelas de ferramentas aninhadas dentro de uma única célula de código.
- Neutro em relação ao provedor: funciona com ferramentas do OpenClaw, de Plugins, MCP e de clientes sem depender da execução de código nativa do provedor.
- Falha de forma fechada: se o modo de código estiver ativado, mas o runtime QuickJS-WASI estiver indisponível, a execução falha em vez de recorrer silenciosamente à exposição direta ampla de ferramentas.
Ativá-lo
tools.codeMode é omitido, definido como false ou é um objeto
sem enabled: true.
Se você usa agentes em sandbox com servidores MCP configurados, também permita o
Plugin MCP integrado na política de ferramentas da sandbox, por exemplo,
tools.sandbox.tools.alsoAllow: ["bundle-mcp"]. Consulte
Configuração — ferramentas e provedores personalizados.
Defina limites explícitos para restrições mais rigorosas:
exec e
wait. Para obter o payload completo e censurado do provedor, adicione
OPENCLAW_DEBUG_MODEL_PAYLOAD=full-redacted durante uma breve sessão de depuração.
Visão geral técnica
O restante desta página aborda o contrato do runtime e os detalhes de implementação para mantenedores, autores de Plugins que estejam depurando a exposição de ferramentas e operadores que estejam validando implantações de alto risco.Status do runtime
Escopo
O modo de código controla o formato de orquestração voltado ao modelo para uma execução preparada. Ele não controla a seleção do modelo, o comportamento do canal, a autenticação, a política de ferramentas nem as implementações de ferramentas. Dentro do escopo: definições de ferramentas diretas/de controle visíveis ao modelo, construção do catálogo oculto de ferramentas, execução guest em JavaScript/TypeScript, o runtime do worker QuickJS-WASI, callbacks do host para pesquisar/descrever/chamar, estado retomável para programas guest suspensos, limites de saída/tempo limite/memória/chamadas pendentes/snapshot e projeção de telemetria/trajetória para chamadas de ferramentas aninhadas. Fora do escopo: execução remota de código nativa do provedor, semântica de execução de shell, alteração da autorização existente de ferramentas, scripts persistentes criados pelo usuário, acesso a gerenciador de pacotes/arquivos/rede/módulos no código guest e reutilização direta dos componentes internos do Codex Code Mode. Ferramentas controladas pelo provedor, como sandboxes Python remotas, são ferramentas separadas. Consulte Execução de código.Termos
- Modo de código: o modo de runtime do OpenClaw que oculta ferramentas do modelo compatíveis com o catálogo
e expõe
exec,waite as ferramentas exclusivamente diretas necessárias. - Runtime guest: a VM JavaScript QuickJS-WASI que avalia o código do modelo.
- Ponte do host: a superfície restrita de callbacks compatíveis com JSON, do código guest de volta ao OpenClaw.
- Catálogo: a lista de ferramentas efetivas no escopo da execução após a resolução normal de políticas de ferramentas, Plugins, MCP e ferramentas de clientes.
- Chamada de ferramenta aninhada: uma chamada de ferramenta feita pelo código guest por meio da ponte do host.
- Snapshot: estado serializado da VM QuickJS-WASI salvo para que
waitpossa continuar uma execução suspensa do modo de código.
Configuração
tools.codeMode.enabled é a condição de ativação; definir outros campos não
ativa o recurso por si só.
Se o modo de código estiver ativado, mas o QuickJS-WASI não puder ser carregado, o OpenClaw falhará de forma fechada
nessa execução; ele não exporá silenciosamente as ferramentas normais como alternativa.
Ativação
O modo de código é avaliado depois que a política efetiva de ferramentas é conhecida e antes que a solicitação final ao modelo seja montada:- Resolva o agente, o modelo, o provedor, a sandbox, o canal, o remetente e a política da execução.
- Construa a lista efetiva de ferramentas do OpenClaw, adicionando Plugins, ferramentas MCP e ferramentas de clientes elegíveis.
- Aplique a política de permissão/negação.
- Se
tools.codeMode.enabledfor falso, prossiga com a exposição normal das ferramentas. - Se estiver ativado e as ferramentas estiverem ativas para a execução, mantenha as ferramentas exclusivamente diretas necessárias e registre no catálogo do modo de código todas as ferramentas efetivas elegíveis para o catálogo.
- Remova as ferramentas catalogadas da lista visível ao modelo; adicione
execewaitjunto às ferramentas exclusivamente diretas mantidas.
disableTools: true
ou uma lista tools.allow vazia) não ativam a superfície do modo de código mesmo
quando tools.codeMode.enabled: true está configurado. O modo de código e o OpenClaw Tool
Search são mutuamente exclusivos em uma execução; se o modo de código for ativado, a
Compaction do Tool Search não será aplicada.
O catálogo do modo de código é limitado ao escopo da execução e não deve vazar ferramentas de outro
agente, sessão, remetente ou execução.
Ferramentas visíveis ao modelo
Quando o modo de código está ativo, o modelo vêexec, wait e qualquer ferramenta exclusivamente
direta necessária. Todas as outras ferramentas habilitadas ficam ocultas da lista de ferramentas voltada ao
modelo e são registradas no catálogo do modo de código.
Use exec para orquestração de ferramentas, junção de dados, loops, chamadas aninhadas paralelas
e transformações estruturadas. Use wait somente quando exec retornar um resultado retomável
waiting.
exec
exec inicia uma célula do modo de código e retorna um resultado. O código de entrada é gerado pelo modelo
e deve ser tratado como hostil.
Entrada:
- Um dos campos
codeoucommanddeve conter um valor não vazio. codeé o campo documentado voltado ao modelo.commandé aceito como um alias compatível com exec para políticas de hooks e reescritas confiáveis (a ferramenta normal de execução de shell do OpenClaw também usa um campocommand); quando ambos estão presentes, os valores devem ser iguais.- O padrão de
languageé"javascript"; o esquema o expõe como uma enumeração simples de strings ("javascript" | "typescript"), não como uma uniãooneOf/anyOf, pois alguns provedores rejeitam esses formatos. - Se
languagefor"typescript", o OpenClaw transpila o código antes da avaliação. execrejeitaimport,require, importação dinâmica e padrões de carregadores de módulos.execnunca expõe recursivamente a implementação normal deexecdo shell.- Eventos de hook do
execexterno do modo de código incluemtoolKind: "code_mode_exec"etoolInputKind: "javascript" | "typescript"(quando conhecido), para que as políticas possam distinguir células do modo de código de chamadas deexecno estilo shell que compartilham o mesmo nome de ferramenta.
exec retorna waiting quando a VM QuickJS é suspensa com um estado retomável que
ainda requer uma continuação visível para o modelo; o resultado inclui um runId para
wait. As chamadas da ponte de namespace, incluindo chamadas de namespace MCP, são processadas automaticamente
na mesma chamada exec/wait enquanto estiverem prontas, permitindo um código compacto
o bloco pode chamar uma ferramenta MCP sem forçar uma chamada de ferramenta do modelo por namespace
aguardado.
exec retorna completed somente quando a VM convidada não tem nenhum trabalho pendente e o
valor final é compatível com JSON após a execução do adaptador de saída do OpenClaw.
wait
wait retoma uma VM em modo de código suspensa.
Entrada:
CodeModeResult retornada por exec.
wait existe porque as ferramentas aninhadas do OpenClaw podem ser lentas, interativas, sujeitas a aprovação
ou transmitir atualizações parciais; o modelo não deve precisar manter uma longa
chamada exec aberta enquanto o host aguarda trabalho externo.
O snapshot/restauração do QuickJS-WASI é o mecanismo de retomada:
execavalia o código até a conclusão, falha ou suspensão.- Na suspensão, o OpenClaw cria um snapshot da VM do QuickJS e registra o trabalho pendente do host.
- Quando o trabalho pendente é concluído,
waitrestaura o snapshot da VM e registra novamente os callbacks do host usando nomes estáveis. - O OpenClaw entrega os resultados das ferramentas aninhadas à VM restaurada e processa os trabalhos pendentes do QuickJS.
waitretornacompleted,failedou outro resultadowaiting.
wait falha (como um resultado failed) quando:
runIdé desconhecido ou seu snapshot já expirou.- o chamador não está no mesmo escopo de execução/sessão que a execução suspensa.
- um
waitjá está em andamento para esserunId. - a restauração do QuickJS-WASI falha.
- a retomada excederia
maxOutputBytesoumaxSnapshotBytes.
API do runtime convidado
ALL_TOOLS contém metadados compactos do catálogo com escopo da execução; por padrão, ele não
contém esquemas completos.
source: "openclaw" com sourceName definido como o id do
Plugin proprietário; não há um valor de origem "plugin" separado. source: "mcp" é
usado apenas para entradas MCP nos metadados sourceName/mcp (e é filtrado
de ALL_TOOLS/tools.*; veja abaixo).
O esquema completo é carregado somente sob demanda:
tools.call(...) nem de funções de
conveniência no modo de código; elas são expostas somente por meio do namespace MCP
gerado. Arquivos de declaração no estilo TypeScript estão disponíveis por meio da superfície de arquivos virtuais
API somente leitura, permitindo que os agentes inspecionem as assinaturas MCP
sem adicionar esquemas MCP ao prompt:
API.read("mcp/<server>.d.ts") retorna declarações compactas inferidas dos metadados das ferramentas MCP:
exec no modo de código, o OpenClaw cria o catálogo de ferramentas com escopo da execução, mantém as entradas MCP visíveis, renderiza mcp/index.d.ts e um mcp/<server>.d.ts para cada servidor visível e injeta essa pequena tabela somente leitura no worker QuickJS. O código convidado vê apenas o objeto API: API.list(prefix?) retorna metadados de arquivos, e API.read(path) retorna o conteúdo da declaração selecionada. Caminhos desconhecidos e segmentos ./.. são rejeitados.
Isso mantém esquemas MCP grandes fora do prompt do modelo: o agente descobre que a API virtual existe pela descrição da ferramenta exec, lê apenas o arquivo de declaração necessário e então chama MCP.<server>.<tool>() com um argumento de objeto. MCP.<server>.$api() permanece disponível como fallback inline para uma resposta de esquema de uma única ferramenta dentro do programa.
O runtime convidado nunca vê objetos do host diretamente. Entradas e saídas atravessam a ponte como valores compatíveis com JSON, com limites de tamanho explícitos.
Namespaces internos
Namespaces internos fornecem ao modo de código uma API de domínio concisa sem adicionar mais ferramentas visíveis ao modelo. Uma integração controlada pelo loader registra um namespace comoIssues ou Calendar; o código convidado então chama esse namespace dentro do programa QuickJS, enquanto o modelo continua vendo a superfície compacta de controle/direta.
Por enquanto, os namespaces são internos. Não há uma API pública de namespace no SDK de plugins: namespaces de plugins externos precisam de um contrato controlado pelo loader para que a identidade do plugin, os manifestos instalados, o estado de autenticação e os descritores de catálogo em cache não fiquem dessincronizados das ferramentas do plugin que sustentam o namespace. O modo de código do core controla apenas o sandbox, a serialização, a restrição pelo catálogo e o despacho da ponte.
O código convidado pode usar tanto o global direto quanto o mapa namespaces:
Ciclo de vida do registro
O registro de namespaces é local ao processo e indexado pelo id do namespace:- Um loader confiável chama
registerCodeModeNamespaceForPlugin(pluginId, registration). - O modo de código cria o
ToolSearchRuntimeoculto para a execução e lê seu catálogo com escopo da execução. createCodeModeNamespaceRuntime(ctx, catalog)mantém apenas os registros cujosrequiredToolNamesestão todos visíveis e pertencem ao mesmopluginId.- Cada namespace visível chama
createScope(ctx)para a execução atual, recebendo contexto de execução comoagentId,sessionKey,sessionId,runId, configuração e estado de cancelamento. - Os dados do escopo são serializados em um descritor simples e injetados no QuickJS como globais diretos e
namespaces.<globalName>. - As chamadas do código convidado são suspensas pela ponte do worker, resolvem o caminho do namespace no host, mapeiam a chamada para uma ferramenta declarada do catálogo pertencente ao plugin e executam essa ferramenta por meio de
ToolSearchRuntime.callExactId. - As chamadas prontas da ponte de namespaces são drenadas automaticamente dentro da chamada ativa
exec/wait; se ainda houver trabalho de namespace pendente ao atingir o tempo limite ou se o código convidado ceder explicitamente,waitretoma posteriormente o mesmo runtime de namespace. - O rollback ou a desinstalação do plugin chama
clearCodeModeNamespacesForPlugin(pluginId)para que globais obsoletos não sobrevivam a uma falha no carregamento do plugin.
tools.call(...).
Formato do registro
Registre namespaces pela integração que controla as ferramentas subjacentes. Mantenha o escopo pequeno e exponha somente verbos de domínio que correspondam a ferramentas declaradas no catálogo.createCodeModeNamespaceTool(toolName, inputMapper) marca um membro do escopo como uma função de namespace chamável. O inputMapper opcional recebe os argumentos do código convidado e retorna o objeto de entrada para a ferramenta de catálogo subjacente; sem ele, o primeiro argumento do código convidado é usado, ou {} quando omitido.
Funções brutas do host são rejeitadas antes da execução do código convidado:
Propriedade e visibilidade
A propriedade do namespace é vinculada aopluginId do chamador do registro. requiredToolNames funciona tanto como restrição de visibilidade quanto como verificação de propriedade:
- toda ferramenta obrigatória deve existir no catálogo da execução
- toda ferramenta obrigatória deve ter
sourceName === pluginId - o namespace fica oculto quando qualquer ferramenta obrigatória está ausente ou pertence a outro plugin
- cada caminho chamável pode direcionar somente para uma ferramenta mencionada em
requiredToolNames
Regras de serialização do escopo
createScope(ctx) pode retornar um objeto simples contendo valores compatíveis com JSON, arrays, objetos aninhados e marcadores de chamada createCodeModeNamespaceTool(...). Objetos do host nunca entram diretamente no QuickJS.
O serializador rejeita:
- funções brutas
- grafos de objetos circulares
- segmentos de caminho não seguros:
__proto__,constructor,prototype, chaves vazias ou chaves contendo o separador de caminho interno - valores de
globalNameque não são identificadores JavaScript - colisões de
globalNamecom globais integradas do modo de código, comotools,namespaces,text,json,yield_control,MCP,API,ALL_TOOLSou__openclaw*
Prompts
Adescription e o prompt opcional do namespace são anexados ao esquema de
exec visível para o modelo somente quando o namespace está visível nessa
execução. Use-os para ensinar a menor superfície útil:
Limpeza
Os namespaces são registros locais do processo. Remova-os quando o plugin proprietário for desabilitado, desinstalado ou revertido:clearCodeModeNamespacesForTest() para evitar o vazamento de registros entre
casos.
Lista de verificação de testes
As alterações de namespace devem abranger o limite de segurança e o comportamento do código convidado:- o texto do prompt do namespace aparece somente quando as ferramentas subjacentes estão visíveis
- ferramentas com o mesmo nome provenientes de outro
sourceNamenão expõem o namespace - funções de escopo brutas são rejeitadas
- IDs de namespace forjados e caminhos forjados são rejeitados
- caminhos invocáveis não podem apontar para ferramentas não declaradas
- objetos aninhados e referências compartilhadas são serializados corretamente
- as chamadas de namespace são executadas por meio das ferramentas do catálogo e retornam detalhes seguros para JSON
- as falhas podem ser capturadas pelo código convidado
- chamadas de namespace suspensas são retomadas por meio de
wait - a reversão do plugin limpa os registros de namespace pertencentes a ele
tools.search/tools.call: use
o catálogo para ferramentas arbitrárias habilitadas do OpenClaw, de plugins e
de clientes; use MCP para ferramentas MCP; use outros namespaces para APIs de
domínio documentadas e pertencentes a plugins, nas quais código conciso é mais
confiável do que consultas repetidas ao esquema.
API de saída
text(value)acrescenta uma saída legível por humanos ao arrayoutput.json(value)acrescenta um item de saída estruturado após a serialização compatível com JSON.- O valor final retornado pelo código convidado torna-se
valueem um resultadocompleted.
maxOutputBytes; valores não serializáveis são convertidos em strings simples ou
erros; valores binários não são compatíveis. Imagens e arquivos são transmitidos por
ferramentas comuns do OpenClaw, não pela ponte do modo de código.
Catálogo de ferramentas
O catálogo oculto inclui as ferramentas após a filtragem efetiva por políticas, nesta ordem: ferramentas principais do OpenClaw, ferramentas de plugins incluídos, ferramentas de plugins externos, ferramentas MCP e, por fim, ferramentas fornecidas pelo cliente para a execução atual. Os ids do catálogo são estáveis dentro de uma execução e determinísticos entre conjuntos de ferramentas equivalentes, quando possível. Formato real:<source> é openclaw, mcp ou client (as ferramentas de plugins usam
openclaw com o id do plugin como <owner>; as ferramentas principais usam openclaw:core:*).
Exemplos:
exec, wait, tool_search_code,
tool_search, tool_describe, tool_call) e as ferramentas somente diretas. Os controles
não devem fazer chamadas recursivas pelo catálogo; as ferramentas somente diretas permanecem
visíveis para o modelo porque seus resultados estruturados não podem atravessar a ponte do QuickJS.
As entradas MCP permanecem no catálogo com escopo de execução para que políticas, aprovações, hooks,
telemetria, projeção da transcrição e ids exatos das ferramentas continuem compartilhados com
a execução normal de ferramentas. As visualizações voltadas ao guest ALL_TOOLS, tools.search(...),
tools.describe(...) e tools.call(...) omitem as entradas MCP. O namespace
gerado MCP.<server>.<tool>({ ...input }) é resolvido para o id exato do catálogo e despachado
pelo mesmo caminho do executor.
Interação com a Pesquisa de Ferramentas
O modo de código substitui a superfície de modelo da Pesquisa de Ferramentas do OpenClaw nas execuções em que está ativo. Quandotools.codeMode.enabled é true e o modo de código é ativado:
- O OpenClaw não expõe
tool_search_code,tool_search,tool_describenemtool_callcomo ferramentas visíveis para o modelo. - O mesmo conceito de catalogação é transferido para o runtime do guest.
- O runtime do guest recebe metadados compactos de
ALL_TOOLSe auxiliares de pesquisa/descrição/ chamada para ferramentas que não são MCP. - As chamadas MCP usam o namespace
MCPgerado e seus cabeçalhos$api()em vez detools.call(...). - As chamadas aninhadas são despachadas pelo mesmo caminho do executor do OpenClaw usado pela Pesquisa de Ferramentas.
Nomes de ferramentas e colisões
A ferramentaexec visível para o modelo é a ferramenta do modo de código. Se a ferramenta normal
de shell exec do OpenClaw estiver habilitada, ela ficará oculta para o modelo e será catalogada como
qualquer outra ferramenta.
Dentro do runtime convidado:
tools.call("openclaw:core:exec", input)pode chamar a ferramenta de execução do shell se a política permitir.tools.exec(...)é instalado somente se a entrada do catálogo de execução do shell tiver um nome seguro inequívoco.- a ferramenta
execdo modo de código nunca fica disponível recursivamente por meio detools.
tools.call(id, input).
Execução aninhada de ferramentas
Cada chamada aninhada de ferramenta atravessa a ponte do host e entra novamente no OpenClaw, preservando: id do agente ativo, id e chave da sessão, contexto do remetente e do canal, política de sandbox, política de aprovação, hooksbefore_tool_call do plugin, sinal de
interrupção, atualizações por streaming quando disponíveis e eventos de trajetória/auditoria.
As chamadas aninhadas são projetadas na transcrição como chamadas reais de ferramentas para que os
pacotes de suporte mostrem o que aconteceu, com a projeção identificando a chamada da ferramenta
pai do modo de código e o id da ferramenta aninhada.
Chamadas aninhadas paralelas são permitidas até maxPendingToolCalls.
Ciclo de vida da execução e do snapshot
Cada execução do modo de código é rastreada em um mapa em processo indexado porrunId (não
persistido em disco nem em um banco de dados). exec/wait retornam um de três estados de
resultado: completed, waiting ou failed.
- Um resultado
waitingarmazena o snapshot do QuickJS, as solicitações pendentes da ponte e os metadados de escopo (id da execução do agente, id/chave da sessão) até quewaito retome ou ele expire. - Valores de
runIdexpirados, de sessão incorreta, de execução incorreta e desconhecidos/já em retomada não produzem um estado terminal distinto; eles aparecem como um resultadofailed(code: "invalid_input") com uma mensagem comocode mode run is unavailable or expired.oucode mode run belongs to a different session.. - O snapshot de uma execução é removido do mapa assim que ela termina como
completedoufailed, ou é descartado no encerramento do Gateway (nada sobrevive a uma reinicialização: este é um estado transitório do runtime). - Para trabalho somente leitura,
execpode definirrestartSafe: true. O OpenClaw então rejeita chamadas de catálogo com efeitos colaterais e namespaces de plugins antes da execução e marca resultados suspensos como seguros para reprodução. Se uma reinicialização interromperwait, a recuperação após reinicialização reconstruirá o turno a partir da transcrição em vez de restaurar o snapshot local do processo. O próprio turno de recuperação permanece limitado a ferramentas principais auditadas somente leitura e ferramentas de plugins explicitamente seguras para reprodução. - O OpenClaw limita o número de execuções suspensas simultaneamente por processo (64) e
rejeita novas suspensões além desse limite com
too many suspended code mode runs..
maxSnapshotBytes por execução, pelo limite por processo
de execuções suspensas mencionado acima e por snapshotTtlSeconds.
Runtime QuickJS-WASI
O OpenClaw carregaquickjs-wasi como uma dependência direta no pacote proprietário; ele
não depende de uma cópia transitiva instalada para uma dependência não relacionada.
Responsabilidades do runtime: compilar/carregar o módulo WebAssembly do QuickJS-WASI;
criar uma VM isolada por execução ou retomada do modo de código; registrar callbacks do host
com nomes estáveis; definir limites de memória e interrupção; avaliar JavaScript; processar
tarefas pendentes; criar snapshots do estado suspenso da VM; restaurar snapshots para wait;
liberar identificadores de VM e snapshots após estados terminais.
O runtime é executado em uma thread worker do Node.js, fora do loop principal de
eventos do OpenClaw. Um loop infinito no convidado não deve bloquear o processo do Gateway
indefinidamente; o manipulador de interrupções do worker impõe o tempo limite de relógio
independentemente da cooperação do código convidado.
TypeScript
O suporte a TypeScript é apenas uma transformação de código-fonte: a entrada aceita é uma única string de código TypeScript; a saída é uma string JavaScript avaliada pelo QuickJS-WASI. Não há verificação de tipos, resolução de módulos nemimport/require. Os diagnósticos são retornados como resultados failed.
O compilador TypeScript é carregado de forma preguiçosa apenas para células TypeScript; células
JavaScript simples e o modo de código desativado nunca o carregam.
Limite de segurança
O código do modelo é hostil. O runtime usa defesa em profundidade:- executa o QuickJS-WASI fora do loop de eventos principal, em uma thread de trabalho
- carrega
quickjs-wasicomo uma dependência direta, não por meio do Codex nem de um pacote transitivo - não há sistema de arquivos, rede, subprocessos, importação de módulos, variáveis de ambiente nem objetos globais do host no ambiente convidado
- usa limites de memória e de interrupção do QuickJS, além de um tempo limite de relógio de parede no processo pai
- impõe limites de saída, snapshots, logs e chamadas pendentes
- serializa os valores da ponte do host por meio de um adaptador JSON restrito
- converte erros do host em erros simples no ambiente convidado, nunca em objetos do realm do host
- descarta snapshots em caso de tempo limite, cancelamento, encerramento da sessão ou expiração
- rejeita acesso recursivo a
exec,waite às ferramentas de controle do Tool Search - impede que colisões de nomes de conveniência ocultem os auxiliares do catálogo
Códigos de erro
invalid_input abrange argumentos inválidos de exec/wait, linguagens desativadas,
acesso rejeitado a módulos, falhas na transformação de TypeScript, valores de runId
desconhecidos, expirados ou de escopo incorreto e execuções suspensas em excesso. runtime_unavailable
abrange um worker do QuickJS que não consegue iniciar ou encerra com código diferente de zero.
Os erros retornados ao ambiente convidado são dados simples; instâncias de Error do host, objetos
de pilha, protótipos e funções do host não atravessam para o QuickJS.
Telemetria
O campotelemetry de cada resultado informa: o tamanho do catálogo oculto e uma
divisão por origem (contagens de openclaw/mcp/client), contagens acumuladas de
pesquisas/descrições/chamadas para o catálogo da execução e os nomes de ferramentas visíveis ao modelo (exec,
wait e ferramentas retidas somente para acesso direto).
A telemetria não deve incluir segredos, valores brutos de ambiente nem entradas de
ferramentas sem redação além do permitido pela política de trajetória existente do OpenClaw.
Depuração
Use o registro direcionado do transporte do modelo quando o modo de código se comportar de maneira diferente de uma execução normal de ferramenta:OPENCLAW_DEBUG_MODEL_PAYLOAD=full-redacted.
Isso registra um snapshot JSON limitado e redigido da solicitação ao modelo; use-o apenas
durante a depuração, pois prompts e texto de mensagens ainda podem aparecer.
Para depuração de stream, use OPENCLAW_DEBUG_SSE=peek para registrar os cinco primeiros
eventos SSE com dados sensíveis ocultados. O modo de código também falha de forma segura se o payload final do provedor
não contiver exatamente um exec, um wait e somente ferramentas
direct-only aprovadas após a ativação da superfície do modo de código.
Estrutura da implementação
- contrato de configuração:
tools.codeMode - construtor de catálogo: ferramentas efetivas convertidas em entradas compactas e mapa de IDs
- adaptador da superfície do modelo: substitui as ferramentas visíveis por ferramentas de controle/direct-only
- adaptador de runtime QuickJS-WASI: carregar, avaliar, criar snapshot, restaurar, descartar
- supervisor de workers: tempo limite, cancelamento, isolamento de falhas
- adaptador da ponte: callbacks do host compatíveis com JSON e entrega de resultados
- adaptador de transformação TypeScript
- armazenamento de snapshots: TTL, limites de tamanho, escopo de execução/sessão
- projeção de trajetória para chamadas de ferramentas aninhadas
- contadores de telemetria e diagnósticos
node:vm como sandbox.
Lista de verificação de validação
A cobertura do modo de código deve comprovar:- a configuração desabilitada mantém inalterada a exposição existente de ferramentas
- a configuração como objeto sem
enabled: truemantém o modo de código desabilitado - a configuração habilitada expõe
exec,waite somente as ferramentas direct-only necessárias ao modelo quando as ferramentas estão ativas para a execução - execuções brutas sem ferramentas,
disableToolse listas de permissões vazias não acionam a imposição do payload do modo de código - todas as ferramentas efetivas não MCP elegíveis para o catálogo aparecem em
ALL_TOOLS - as ferramentas direct-only permanecem visíveis ao modelo e não aparecem em
ALL_TOOLS - as ferramentas negadas não aparecem em
ALL_TOOLS tools.search,tools.describeetools.callfuncionam para ferramentas do OpenClawAPI.list("mcp")eAPI.read("mcp/<server>.d.ts")expõem declarações MCP no estilo TypeScript sem uma chamada de ponte/ferramenta- o
$api()do namespace MCP permanece disponível como fallback inline para esquemas - as chamadas do namespace MCP funcionam para ferramentas MCP visíveis com uma entrada de objeto, enquanto
as entradas diretas do catálogo MCP não aparecem em
tools.* - as ferramentas de controle da Busca de Ferramentas ficam ocultas tanto da superfície do modelo quanto do catálogo oculto
- as chamadas aninhadas preservam o comportamento de aprovação e dos hooks
- o
execdo shell fica oculto do modelo, mas pode ser chamado pelo ID do catálogo quando permitido execewaitrecursivos do modo de código não podem ser chamados pelo código convidado- a entrada TypeScript é transformada e avaliada sem carregar o TypeScript nos caminhos desabilitados ou exclusivos de JavaScript
- o acesso a
import,require, sistema de arquivos, rede e ambiente falha - loops infinitos atingem o tempo limite e não podem bloquear o Gateway
- falhas no limite de memória encerram a VM convidada
- os limites de saída e snapshot são aplicados a chamadas concluídas e suspensas
waitretoma um snapshot suspenso e retorna o valor final- valores
runIdexpirados, cancelados, de sessão incorreta e desconhecidos falham - a reprodução e a persistência da transcrição preservam as chamadas de controle do modo de código
- a transcrição e a telemetria mostram claramente as chamadas de ferramentas aninhadas
Plano de testes E2E
Execute estes testes como testes de integração ou de ponta a ponta ao alterar o runtime:- Inicie um Gateway com
tools.codeMode.enabled: false. - Envie um turno do agente com um pequeno conjunto de ferramentas diretas.
- Verifique se as ferramentas visíveis ao modelo permanecem inalteradas.
- Reinicie com
tools.codeMode.enabled: true. - Envie um turno do agente com ferramentas de teste do OpenClaw, de plugins, MCP e do cliente.
- Verifique se a lista de ferramentas visíveis ao modelo é composta por
exec,waite somente pelas ferramentas direct-only configuradas. - Em
exec, leiaALL_TOOLSe verifique se as ferramentas de teste efetivas elegíveis para o catálogo estão presentes, enquanto as ferramentas direct-only estão ausentes. - Em
exec, chame ferramentas do OpenClaw/de plugins/do cliente por meio detools.search,tools.describeetools.call. - Em
exec, chameAPI.list("mcp")eAPI.read("mcp/<server>.d.ts")e verifique se os arquivos de declaração descrevem as ferramentas MCP visíveis. - Em
exec, chame ferramentas MCP por meio deMCP.<server>.<tool>({ ...input })e verifique se as entradas diretas do catálogo MCP estão ausentes deALL_TOOLSetools.*. - Verifique se as ferramentas negadas estão ausentes e não podem ser chamadas por um ID presumido.
- Inicie uma chamada de ferramenta aninhada que seja resolvida depois que
execretornarwaiting. - Chame
waite verifique se a VM restaurada recebe o resultado da ferramenta. - Verifique se a resposta final contém a saída produzida após a restauração.
- Verifique se o tempo limite, o cancelamento e a expiração do snapshot limpam o estado do runtime.
- Exporte a trajetória e verifique se as chamadas aninhadas estão visíveis sob a chamada pai do modo de código.
pnpm check:docs.