RPC and API
Режим кода
Режим кода — экспериментальная функция среды выполнения агентов OpenClaw. По умолчанию он
отключен. Когда вы включаете его, OpenClaw меняет то, что модель видит для одного запуска:
вместо прямого показа каждой схемы включенного инструмента модель видит только
exec и wait.
Эта страница документирует режим кода OpenClaw. Это не режим кода Codex. У этих двух
функций общее название, но они реализованы разными средами выполнения и предоставляют
разные контракты exec:
- Режим кода Codex включен для потоков app-server Codex, если ограничительная
политика инструментов не отключает нативный режим кода. Он работает в среде
программирования Codex, где модель записывает команды оболочки через контракт
exec.command. - Режим кода OpenClaw отключен, если не настроено
tools.codeMode.enabled: true. Он работает в общей среде выполнения агентов OpenClaw, где модель записывает программы JavaScript или TypeScript через контрактexec.code.
Режим кода Codex и нативный для Codex динамический поиск инструментов — стабильные
поверхности среды Codex. Режим кода OpenClaw — принадлежащий OpenClaw экспериментальный
адаптер поверхности инструментов для общих запусков OpenClaw. Он использует quickjs-wasi,
скрытый каталог инструментов OpenClaw и обычный исполнитель инструментов OpenClaw.
Что это?
Режим кода OpenClaw позволяет модели написать небольшую программу на JavaScript или TypeScript вместо прямого выбора из длинного списка инструментов.
Когда режим кода активен:
- Список инструментов, видимый модели, — ровно
execиwait. execвыполняет созданный моделью JavaScript или TypeScript в ограниченном рабочем процессе QuickJS-WASI.- Обычные инструменты OpenClaw скрыты из подсказки модели и доступны внутри
гостевой программы через
ALL_TOOLSиtools. - Гостевой код может искать в скрытом каталоге, описывать инструмент и вызывать инструмент через тот же путь выполнения OpenClaw, который используется обычными ходами агента.
- Инструменты MCP сгруппированы в пространстве имен
MCP. В режиме кода это пространство имен является единственным поддерживаемым способом вызова инструментов MCP. waitвозобновляет приостановленный запуск в режиме кода, когда вложенные вызовы инструментов все еще ожидают завершения.
Важное различие: режим кода меняет обращенную к модели поверхность оркестрации. Он не заменяет инструменты OpenClaw, инструменты Plugin, инструменты MCP, аутентификацию, политику подтверждений, поведение каналов или выбор модели.
Почему это хорошо?
Режим кода упрощает использование больших каталогов инструментов моделями.
- Меньшая поверхность подсказки: провайдеры получают два управляющих инструмента вместо десятков или сотен полных схем инструментов.
- Лучшая оркестрация: модель может использовать циклы, объединения, небольшие преобразования, условную логику и параллельные вложенные вызовы инструментов внутри одной ячейки кода.
- Нейтральность к провайдерам: он работает для инструментов OpenClaw, Plugin, MCP и клиентских инструментов без зависимости от нативного выполнения кода провайдером.
- Существующая политика остается в силе: вложенные вызовы инструментов по-прежнему проходят через политику OpenClaw, подтверждения, хуки, контекст сессии и пути аудита.
- Ясный режим отказа: когда режим кода явно включен, а среда выполнения недоступна, OpenClaw завершает запуск закрытым отказом вместо отката к широкому прямому показу инструментов.
Режим кода особенно полезен для агентов с большим каталогом включенных инструментов или для рабочих процессов, где модели регулярно нужно искать, объединять и вызывать инструменты перед формированием ответа.
Как включить
Добавьте tools.codeMode.enabled: true в конфигурацию агента или среды выполнения:
{ tools: { codeMode: { enabled: true, }, },}Также принимается сокращенная форма:
{ tools: { codeMode: true, },}Режим кода остается отключенным, когда tools.codeMode отсутствует, равно false или является объектом
без enabled: true.
Когда вы используете изолированных агентов с настроенными MCP-серверами, также убедитесь, что
политика инструментов песочницы разрешает встроенный MCP Plugin, например через
tools.sandbox.tools.alsoAllow: ["bundle-mcp"]. См.
Конфигурация — инструменты и пользовательские провайдеры.
Используйте явные лимиты, когда нужны более строгие границы:
{ tools: { codeMode: { enabled: true, timeoutMs: 10000, memoryLimitBytes: 67108864, maxOutputBytes: 65536, maxSnapshotBytes: 10485760, maxPendingToolCalls: 16, snapshotTtlSeconds: 900, searchDefaultLimit: 8, maxSearchLimit: 50, }, },}Чтобы подтвердить форму полезной нагрузки модели при отладке, запустите Gateway с целевым логированием:
OPENCLAW_DEBUG_CODE_MODE=1 \OPENCLAW_DEBUG_MODEL_TRANSPORT=1 \OPENCLAW_DEBUG_MODEL_PAYLOAD=tools \openclaw gatewayПри активном режиме кода записанные в журнал имена инструментов, видимые модели, должны быть exec и
wait. Если нужна отредактированная полезная нагрузка провайдера, добавьте
OPENCLAW_DEBUG_MODEL_PAYLOAD=full-redacted на короткую сессию отладки.
Технический обзор
Остальная часть этой страницы описывает контракт среды выполнения и детали реализации. Она предназначена для сопровождающих, авторов Plugin, отлаживающих показ инструментов, и операторов, проверяющих развертывания с высоким риском.
Состояние среды выполнения
- Среда выполнения:
quickjs-wasi. - Состояние по умолчанию: отключено.
- Стабильность: экспериментальная поверхность OpenClaw; режим кода Codex — отдельная стабильная поверхность среды Codex.
- Целевая поверхность: общие запуски агентов OpenClaw.
- Позиция безопасности: код модели считается враждебным.
- Обещание для пользователей: включение режима кода никогда не приводит к тихому откату к широкому прямому показу инструментов.
Область действия
Режим кода отвечает за обращенную к модели форму оркестрации для подготовленного запуска. Он не отвечает за выбор модели, поведение каналов, аутентификацию, политику инструментов или реализации инструментов.
Входит в область действия:
- видимые модели определения инструментов
execиwait - построение скрытого каталога инструментов
- выполнение гостевого JavaScript и TypeScript
- рабочая среда QuickJS-WASI
- обратные вызовы хоста для поиска в каталоге, описания схемы и вызова инструмента
- возобновляемое состояние для приостановленных гостевых программ
- лимиты вывода, тайм-аута, памяти, ожидающих вызовов и снимков
- телеметрия и проекция траектории для вложенных вызовов инструментов
Не входит в область действия:
- нативное удаленное выполнение кода провайдером
- семантика выполнения оболочки
- изменение существующей авторизации инструментов
- постоянные пользовательские скрипты
- доступ к менеджеру пакетов, файлам, сети или модулям в гостевом коде
- прямое повторное использование внутренних компонентов режима кода Codex
Инструменты, принадлежащие провайдеру, такие как удаленные песочницы Python, остаются отдельными инструментами. См. Выполнение кода.
Термины
Режим кода — режим среды выполнения OpenClaw, который скрывает обычные инструменты модели и
предоставляет только exec и wait.
Гостевая среда выполнения — VM JavaScript QuickJS-WASI, которая выполняет код модели.
Мост хоста — узкая JSON-совместимая поверхность обратных вызовов из гостевого кода обратно в OpenClaw.
Каталог — ограниченный запуском список эффективных инструментов после обычной политики инструментов, Plugin, MCP и разрешения клиентских инструментов.
Вложенный вызов инструмента — вызов инструмента, сделанный из гостевого кода через мост хоста.
Снимок — сериализованное состояние VM QuickJS-WASI, сохраненное, чтобы wait мог продолжить
приостановленный запуск в режиме кода.
Конфигурация
tools.codeMode.enabled — переключатель активации. Установка других полей режима кода
не включает функцию.
Поддерживаемые поля:
enabled: boolean. По умолчаниюfalse. Включает режим кода только приtrue.runtime:"quickjs-wasi". Единственная поддерживаемая среда выполнения.mode:"only". Предоставляетexecиwait, скрывает обычные инструменты модели.languages: массив"javascript"и"typescript". По умолчанию включает оба.timeoutMs: лимит реального времени для одногоexecилиwait. По умолчанию10000. Ограничение среды выполнения: от100до60000.memoryLimitBytes: лимит кучи QuickJS. По умолчанию67108864. Ограничение среды выполнения: от1048576до1073741824.maxOutputBytes: лимит для возвращаемого текста, JSON и журналов. По умолчанию65536. Ограничение среды выполнения: от1024до10485760.maxSnapshotBytes: лимит для сериализованных снимков VM. По умолчанию10485760. Ограничение среды выполнения: от1024до268435456.maxPendingToolCalls: лимит параллельных вложенных вызовов инструментов. По умолчанию16. Ограничение среды выполнения: от1до128.snapshotTtlSeconds: как долго можно возобновлять приостановленную VM. По умолчанию900. Ограничение среды выполнения: от1до86400.searchDefaultLimit: количество результатов поиска в скрытом каталоге по умолчанию. По умолчанию8. Среда выполнения ограничивает это значение доmaxSearchLimit.maxSearchLimit: максимальное количество результатов поиска в скрытом каталоге. По умолчанию50. Ограничение среды выполнения: от1до50.
Если режим кода включен, но QuickJS-WASI не может загрузиться, OpenClaw завершает этот запуск закрытым отказом. Он не открывает обычные инструменты тихо в качестве отката.
Активация
Режим кода оценивается после того, как известна эффективная политика инструментов, и до сборки финального запроса к модели.
Порядок активации:
- Разрешить агента, модель, провайдера, песочницу, канал, отправителя и политику запуска.
- Построить эффективный список инструментов OpenClaw.
- Добавить подходящие инструменты Plugin, MCP и клиентские инструменты.
- Применить политики разрешения и запрета.
- Если
tools.codeMode.enabledравно false, продолжить с обычным показом инструментов. - Если включено и инструменты активны для запуска, зарегистрировать эффективные инструменты в каталоге режима кода.
- Удалить все обычные инструменты из списка инструментов, видимого модели.
- Добавить
execиwaitрежима кода.
Запуски, в которых намеренно нет инструментов, например прямые вызовы модели, disableTools
или пустой список разрешений, не активируют поверхность режима кода, даже если конфигурация
содержит tools.codeMode.enabled: true.
Каталог режима кода ограничен запуском. Он не должен допускать утечку инструментов из другого агента, сессии, отправителя или запуска.
Инструменты, видимые модели
Когда режим кода активен, модель видит ровно эти инструменты верхнего уровня:
execwait
Все остальные включенные инструменты скрыты из обращенного к модели списка инструментов и зарегистрированы в каталоге режима кода.
Модель должна использовать exec для оркестрации инструментов, объединения данных, циклов,
параллельных вложенных вызовов и структурированных преобразований. Модель должна использовать
wait только когда exec возвращает возобновляемый результат waiting.
exec
exec запускает ячейку режима кода и возвращает один результат. Входной код создан моделью
и должен рассматриваться как враждебный.
Ввод:
type CodeModeExecInput = { code?: string; command?: string; language?: "javascript" | "typescript";};Правила ввода:
- Одно из
codeилиcommandдолжно быть непустым. code— документированное обращенное к модели поле.commandпринимается как совместимый с exec псевдоним для политик хуков и доверенных переписываний; когда присутствуют оба, значения должны совпадать.- Внешние события хуков
execрежима кода включаютtoolKind: "code_mode_exec"и включаютtoolInputKind: "javascript" | "typescript", когда язык ввода известен, чтобы политики могли отличать ячейки режима кода от shell-style вызововexec, которые используют то же имя инструмента. languageпо умолчанию равно"javascript".- Если
languageравно"typescript", OpenClaw транспилирует перед выполнением. execотклоняетimport,require, динамический импорт и шаблоны загрузчика модулей в v1.execне предоставляет обычную реализацию shellexecрекурсивно.
Результат:
type CodeModeResult = CodeModeCompletedResult | CodeModeWaitingResult | CodeModeFailedResult; type CodeModeCompletedResult = { status: "completed"; value: unknown; output?: CodeModeOutput[]; telemetry: CodeModeTelemetry;}; type CodeModeWaitingResult = { status: "waiting"; runId: string; reason: "pending_tools" | "yield"; pendingToolCalls?: CodeModePendingToolCall[]; output?: CodeModeOutput[]; telemetry: CodeModeTelemetry;}; type CodeModeFailedResult = { status: "failed"; error: string; code?: CodeModeErrorCode; output?: CodeModeOutput[]; telemetry: CodeModeTelemetry;};exec возвращает waiting, когда VM QuickJS приостанавливается с возобновляемым состоянием, которому
все еще нужно продолжение, видимое модели. Результат включает runId для
wait. Вызовы моста пространства имен, включая вызовы пространства имен MCP, автоматически исчерпываются
внутри того же вызова exec/wait, пока они готовы, поэтому компактный блок кода
может проверить $api() и вызвать инструмент MCP без принудительного одного вызова инструмента модели на
каждое ожидание пространства имен.
exec возвращает completed только когда у гостевой ВМ нет ожидающей работы, а
итоговое значение JSON-совместимо после выполнения адаптера вывода OpenClaw.
wait
wait продолжает приостановленную ВМ в режиме кода.
Ввод:
type CodeModeWaitInput = { runId: string;};Вывод — тот же union CodeModeResult, который возвращает exec.
wait существует потому, что вложенные инструменты OpenClaw могут быть медленными, интерактивными, требующими approval
или передавать частичные обновления потоком. Модель не должна держать один длинный вызов
exec открытым, пока хост ждет внешнюю работу.
Снимок и восстановление QuickJS-WASI — механизм возобновления v1:
execвыполняет код до завершения, сбоя или приостановки.- При приостановке OpenClaw создает снимок ВМ QuickJS и записывает ожидающую работу хоста.
- Когда ожидающая работа завершается,
waitвосстанавливает снимок ВМ. - OpenClaw повторно регистрирует callback-функции хоста по стабильным именам.
- OpenClaw доставляет результаты вложенных инструментов в восстановленную ВМ.
- OpenClaw опустошает ожидающие задания QuickJS.
waitвозвращает результатcompleted,failedили еще один результатwaiting.
Снимки — это состояние среды выполнения, а не пользовательские артефакты. Они имеют ограничение размера, срок действия и область действия, ограниченную запуском и сессией, которые их создали.
wait завершается с ошибкой, когда:
runIdнеизвестен.- срок действия снимка истек.
- родительский запуск или сессия были прерваны.
- вызывающий находится не в той же области запуска/сессии.
- восстановление QuickJS-WASI завершается ошибкой.
- восстановление превысило бы настроенные лимиты.
API гостевой среды выполнения
Гостевая среда выполнения предоставляет небольшой глобальный API:
declare const ALL_TOOLS: ToolCatalogEntry[];declare const tools: ToolCatalog;declare const MCP: Record<string, unknown>;declare const namespaces: Record<string, unknown>; declare function text(value: unknown): void;declare function json(value: unknown): void;declare function yield_control(reason?: string): Promise<void>;ALL_TOOLS — компактные метаданные для каталога в области запуска. По умолчанию они не содержат
полные схемы.
type ToolCatalogEntry = { id: string; name: string; label?: string; description: string; source: "openclaw" | "plugin" | "mcp" | "client"; sourceName?: string;};Полная схема загружается только по требованию:
type ToolCatalogEntryWithSchema = ToolCatalogEntry & { parameters: unknown;};Вспомогательные функции каталога:
type ToolCatalog = { search(query: string, options?: { limit?: number }): Promise<ToolCatalogEntry[]>; describe(id: string): Promise<ToolCatalogEntryWithSchema>; call(id: string, input?: unknown): Promise<unknown>; [safeToolName: string]: unknown;};Удобные функции инструментов устанавливаются только для однозначных безопасных имен:
const files = await tools.search("read local file");const fileRead = await tools.describe(files[0].id);const content = await tools.call(fileRead.id, { path: "README.md" }); // If the hidden catalog has an unambiguous `web_search` entry:const hits = await tools.web_search({ query: "OpenClaw code mode" });Записи каталога MCP нельзя вызывать через tools.call(...) или удобные
функции в режиме кода. Они доступны только через сгенерированное пространство имен MCP.
Файлы объявлений в стиле TypeScript доступны через виртуальную файловую поверхность API
только для чтения, чтобы агенты могли просматривать сигнатуры MCP,
не добавляя схемы MCP в prompt:
const files = await API.list("mcp");const githubApi = await API.read("mcp/github.d.ts"); const issue = await MCP.github.createIssue({ owner: "openclaw", repo: "openclaw", title: "Investigate gateway logs",}); const snapshot = await MCP.chromeDevtools.takeSnapshot({ output: "markdown" });const resource = await MCP.docs.resources.read({ uri: "memo://one" });const prompt = await MCP.docs.prompts.get({ name: "brief", arguments: { topic: "release" },});API.read("mcp/<server>.d.ts") возвращает компактные объявления, выведенные из метаданных
инструментов MCP:
type McpToolResult = { content?: unknown[]; structuredContent?: unknown; isError?: boolean; [key: string]: unknown;}; declare namespace MCP.github { /** Return this TypeScript-style API header. */ function $api(toolName?: string, options?: { schema?: boolean }): Promise<McpApiHeader>; /** * Create a GitHub issue. * @param owner Repository owner * @param repo Repository name * @param title Issue title */ function createIssue(input: { owner: string; repo: string; title: string; body?: string; }): Promise<McpToolResult>;}Файлы объявлений виртуальные; это не файлы, записанные в workspace или
каталог состояния. Для каждого вызова exec в режиме кода OpenClaw строит каталог инструментов
в области запуска, сохраняет видимые записи MCP, формирует mcp/index.d.ts плюс одно
объявление mcp/<server>.d.ts для каждого видимого сервера и внедряет эту небольшую
таблицу только для чтения в worker QuickJS. Гостевой код видит только объект API:
API.list(prefix?) возвращает метаданные файлов, а API.read(path) возвращает
содержимое выбранного объявления. Неизвестные пути и сегменты . / .. отклоняются.
Это не дает большим схемам MCP попасть в prompt модели. Агент узнает о существовании
виртуального API из описания инструмента exec, читает только нужный
файл объявлений, а затем вызывает MCP.<server>.<tool>() с одним объектным аргументом.
MCP.<server>.$api() остается доступным как встроенный fallback, когда агенту
нужен ответ со схемой одного инструмента внутри программы.
Гостевая среда выполнения не должна напрямую раскрывать объекты хоста. Входы и выходы проходят через мост как JSON-совместимые значения с явными лимитами размера.
Внутренние пространства имен
Внутренние пространства имен дают режиму кода краткий доменный API без добавления новых
видимых для модели инструментов. Интеграция, принадлежащая загрузчику, может зарегистрировать пространство имен,
например Issues, Fictions или Calendar; затем гостевой код вызывает это пространство имен
внутри программы QuickJS, тогда как OpenClaw по-прежнему показывает модели только exec и wait.
Пока пространства имен внутренние. Публичного API пространства имен в Plugin SDK нет: внешним пространствам имен Plugin нужен контракт, принадлежащий загрузчику, чтобы идентичность Plugin, установленные манифесты, состояние аутентификации и кэшированные дескрипторы каталога не расходились с инструментами Plugin, на которых основано пространство имен. Базовый режим кода владеет только песочницей, сериализацией, ограничением каталога и диспетчеризацией через мост.
Гостевой код затем может использовать либо прямой глобальный объект, либо карту namespaces:
const open = await Issues.list({ state: "open" });const alsoOpen = await namespaces.Issues.list({ state: "open" });return { count: open.length, alsoCount: alsoOpen.length };Жизненный цикл реестра
Реестр пространств имен локален для процесса и индексируется по id пространства имен. Типичный запуск проходит такой путь:
- Доверенный загрузчик вызывает
registerCodeModeNamespaceForPlugin(pluginId, registration). - Режим кода создает скрытый
ToolSearchRuntimeдля запуска и читает его каталог в области запуска. createCodeModeNamespaceRuntime(ctx, catalog)сохраняет только регистрации, у которых всеrequiredToolNamesвидимы и принадлежат тому жеpluginId.- Каждое видимое пространство имен вызывает
createScope(ctx)для текущего запуска. Область получает контекст запуска, напримерagentId,sessionKey,sessionId,runId, конфигурацию и состояние прерывания. - Данные области сериализуются в простой дескриптор и внедряются в QuickJS как
прямые глобальные объекты и
namespaces.<globalName>. - Вызовы гостя приостанавливаются через мост worker, разрешают путь пространства имен на
хосте, сопоставляют вызов с объявленным инструментом каталога, принадлежащим Plugin, и выполняют
этот инструмент через
ToolSearchRuntime.call. - OpenClaw автоматически опустошает готовые вызовы моста пространства имен внутри активного
вызова инструмента
exec/wait. Если работа пространства имен все еще ожидает при timeout или гость явно уступает управление,waitпозже возобновляет ту же среду выполнения пространства имен. - Откат или удаление Plugin вызывает
clearCodeModeNamespacesForPlugin(pluginId), чтобы устаревшие глобальные объекты не пережили неудачную загрузку Plugin.
Важный инвариант: вызовы пространств имен — это вызовы инструментов каталога. Они используют те же
хуки политик, approvals, обработку прерывания, телеметрию, проекцию transcript
и поведение приостановки/возобновления, что и tools.call(...).
Форма регистрации
Регистрируйте пространства имен из интеграции, которая владеет базовыми инструментами. Держите область небольшой и раскрывайте только доменные действия, которые сопоставляются с объявленными инструментами каталога.
createCodeModeNamespaceTool, registerCodeModeNamespaceForPlugin,} from "../agents/code-mode-namespaces.js"; const pluginId = "github"; registerCodeModeNamespaceForPlugin(pluginId, { id: "github-issues", globalName: "Issues", description: "GitHub issue helpers for the current repository.", requiredToolNames: ["github_list_issues", "github_update_issue"], prompt: "Use Issues.list(params) and Issues.update(number, patch).", createScope: (ctx) => ({ repository: ctx.config, list: createCodeModeNamespaceTool("github_list_issues", ([params]) => params ?? {}), update: createCodeModeNamespaceTool("github_update_issue", ([number, patch]) => ({ number, patch, })), }),});createCodeModeNamespaceTool(toolName, inputMapper) помечает член области как
вызываемую функцию пространства имен. Необязательный inputMapper получает аргументы
гостя и возвращает объект ввода для базового инструмента каталога. Без
сопоставителя ввода используется первый аргумент гостя или {}, если он опущен.
Необработанные функции хоста отклоняются до запуска гостевого кода:
createScope: () => ({ // Wrong: this bypasses the catalog tool lifecycle and will be rejected. list: async () => githubClient.listIssues(),});Владение и видимость
Владение пространством имен привязано к pluginId вызывающего регистрацию.
requiredToolNames — это одновременно фильтр видимости и проверка владения:
- каждый требуемый инструмент должен существовать в каталоге запуска
- каждый требуемый инструмент должен иметь
sourceName === pluginId - пространство имен скрывается, когда любой требуемый инструмент отсутствует или принадлежит другому Plugin
- каждый вызываемый путь может указывать только на инструмент, имя которого есть в
requiredToolNames
Это не позволяет другому Plugin раскрыть пространство имен, зарегистрировав инструмент с тем же именем. Это также удерживает пространства имен в соответствии с обычной политикой агента: если запуск не видит базовые инструменты, он не видит и пространство имен.
Например, пространство имен GitHub должно находиться за расширением, принадлежащим GitHub, которое владеет аутентификацией GitHub, REST- или GraphQL-клиентами, лимитами запросов, approvals на запись и тестами. Базовый режим кода не должен встраивать API, обработку токенов или политику провайдера, специфичные для GitHub.
Правила сериализации области
createScope(ctx) может вернуть простой объект, содержащий JSON-совместимые значения,
массивы, вложенные объекты и маркеры вызовов createCodeModeNamespaceTool(...).
Объекты хоста никогда не попадают напрямую в QuickJS.
Сериализатор отклоняет:
- необработанные функции
- циклические графы объектов
- небезопасные сегменты пути:
__proto__,constructor,prototype, пустые ключи или ключи, содержащие внутренний разделитель пути - значения
globalName, которые не являются идентификаторами JavaScript - конфликты
globalNameсо встроенными глобальными объектами режима кода, такими какtools,namespaces,text,json,yield_controlили__openclaw*
Значения, которые нельзя сериализовать в JSON, преобразуются в JSON-безопасные fallback значения перед пересечением моста. Двоичные данные, дескрипторы, сокеты, клиенты и экземпляры классов должны оставаться за обычными инструментами каталога.
Prompts
description пространства имен и необязательный prompt добавляются в видимую модели
схему exec только когда пространство имен видимо для этого запуска. Используйте их,
чтобы объяснить минимально полезную поверхность:
{ description: "Fiction production service helpers.", prompt: "Use Fictions.riskAudit(), Fictions.promoteIfReady(id, status), and Fictions.unpaidOver(amount).",}Держите prompts о контракте пространства имен, а не о настройке аутентификации, истории реализации или несвязанном поведении Plugin.
Очистка
Пространства имен являются локальными для процесса регистрациями. Удаляйте их, когда владеющий Plugin отключается, удаляется или откатывается:
clearCodeModeNamespacesForPlugin(pluginId);Очистка code-mode принадлежит Plugin; очищайте регистрации пространств имен Plugin,
когда его жизненный цикл завершается, вместо хранения обработчиков очистки для каждого пространства имен. Тесты
могут вызывать clearCodeModeNamespacesForTest(), чтобы избежать утечки регистраций
между кейсами.
Контрольный список тестирования
Изменения пространств имен должны покрывать границу безопасности и поведение гостевой среды:
- текст подсказки пространства имен появляется только тогда, когда видны базовые инструменты
- инструменты с тем же именем из другого
sourceNameне раскрывают пространство имен - необработанные функции области действия отклоняются
- поддельные идентификаторы пространств имен и поддельные пути отклоняются
- вызываемые пути не могут нацеливаться на необъявленные инструменты
- вложенные объекты и общие ссылки сериализуются корректно
- вызовы пространств имен выполняются через инструменты каталога и возвращают JSON-безопасные сведения
- сбои могут быть перехвачены гостевым кодом
- приостановленные вызовы пространств имен возобновляются через
wait - откат Plugin очищает принадлежащие ему регистрации пространств имен
Пространства имен дополняют универсальный каталог tools.search / tools.call. Используйте
каталог для произвольных включенных инструментов OpenClaw, Plugin и клиентских инструментов; используйте MCP для
инструментов MCP; используйте другие пространства имен для принадлежащих Plugin документированных предметных API, где
краткий код надежнее повторяющихся поисков схем.
API вывода
text(value) добавляет человекочитаемый вывод в массив output.
json(value) добавляет структурированный элемент вывода после JSON-совместимой
сериализации.
Финальное возвращенное значение гостевого кода становится value в результате completed.
Элемент вывода:
type CodeModeOutput = { type: "text"; text: string } | { type: "json"; value: unknown };Правила вывода:
- порядок вывода соответствует вызовам гостевой среды
- вывод ограничивается
maxOutputBytes - несериализуемые значения преобразуются в обычные строки или ошибки
- двоичные значения не поддерживаются в v1
- изображения и файлы передаются через обычные инструменты OpenClaw, а не через мост code-mode
Каталог инструментов
Скрытый каталог включает инструменты после фильтрации по эффективной политике:
- Основные инструменты OpenClaw.
- Инструменты встроенных Plugin.
- Инструменты внешних Plugin.
- Инструменты MCP.
- Инструменты, предоставленные клиентом для текущего запуска.
Идентификаторы каталога стабильны в пределах одного запуска и по возможности детерминированы для эквивалентных наборов инструментов.
Рекомендуемая форма идентификатора:
<source>:<owner>:<tool-name>Примеры:
openclaw:core:messageplugin:browser:browser_requestmcp:github:create_issueclient:app:select_fileКаталог исключает управляющие инструменты code-mode:
execwaittool_search_codetool_searchtool_describetool_call
Это предотвращает рекурсию и сохраняет узким контракт, видимый модели.
Записи MCP остаются в каталоге, ограниченном запуском, чтобы политика, утверждения, хуки,
телеметрия, проекция стенограммы и точные идентификаторы инструментов оставались общими с обычным
выполнением инструментов. Представления гостевой среды ALL_TOOLS, tools.search(...),
tools.describe(...) и tools.call(...) исключают записи MCP. Сгенерированное
пространство имен MCP.<server>.<tool>({ ...input }) разрешается обратно в
точный идентификатор каталога, а затем отправляется через тот же путь исполнителя.
Взаимодействие Tool Search
Code mode заменяет модельную поверхность OpenClaw Tool Search для запусков, где он активен.
Когда tools.codeMode.enabled равно true и code mode активируется:
- OpenClaw не предоставляет
tool_search_code,tool_search,tool_describeилиtool_callкак инструменты, видимые модели. - Та же идея каталогизации переносится внутрь гостевой среды выполнения.
- Гостевая среда выполнения получает компактные метаданные
ALL_TOOLSи вспомогательные функции поиска, описания и вызова для инструментов не-MCP. - Вызовы MCP используют сгенерированное пространство имен
MCPи его заголовки$api()вместоtools.call(...). - Вложенные вызовы отправляются через тот же путь исполнителя OpenClaw, который использует Tool Search.
Существующая страница Tool Search описывает компактный
мост каталога OpenClaw. Code mode — универсальная альтернатива OpenClaw для запусков, которые могут
использовать exec и wait.
Имена инструментов и коллизии
Видимый модели инструмент exec — это инструмент code-mode. Если обычный shell-инструмент OpenClaw
exec включен, он скрывается от модели и каталогизируется как любой
другой инструмент.
Внутри гостевой среды выполнения:
tools.call("openclaw:core:exec", input)может вызвать shell-инструмент exec, если политика это разрешает.tools.exec(...)устанавливается только если запись каталога shell-инструмента exec имеет однозначное безопасное имя.- инструмент code-mode
execникогда не доступен рекурсивно черезtools.
Если два инструмента нормализуются в одно и то же безопасное удобное имя, OpenClaw исключает
удобную функцию и требует tools.call(id, input).
Вложенное выполнение инструментов
Каждый вложенный вызов инструмента пересекает мост хоста и повторно входит в OpenClaw.
Вложенное выполнение сохраняет:
- идентификатор активного агента
- идентификатор сеанса и ключ сеанса
- отправителя и контекст канала
- политику песочницы
- политику утверждений
- хуки Plugin
before_tool_call - сигнал прерывания
- потоковые обновления, где они доступны
- события траектории и аудита
Вложенные вызовы проецируются в стенограмму как реальные вызовы инструментов, чтобы пакеты поддержки могли показывать, что произошло. Проекция идентифицирует родительский вызов инструмента code-mode и идентификатор вложенного инструмента.
Параллельные вложенные вызовы разрешены до maxPendingToolCalls.
Состояние среды выполнения
Каждый запуск code-mode имеет конечный автомат:
running: VM выполняется или выполняются вложенные вызовы.waiting: снимок VM существует и может быть возобновлен с помощьюwait.completed: финальное значение возвращено; снимок удален.failed: ошибка возвращена; снимок удален.expired: снимок или ожидающее состояние превысили срок хранения; возобновление невозможно.aborted: родительский запуск/сеанс отменен; снимок удален.
Состояние ограничено запуском агента, сеансом и идентификатором вызова инструмента. Вызов wait из
другого запуска или сеанса завершается с ошибкой.
Хранилище снимков ограничено:
- максимальный размер снимка в байтах на запуск
- максимальное количество живых снимков на процесс
- TTL снимка
- очистка при завершении запуска
- очистка при завершении работы Gateway, если постоянное хранение не поддерживается
Среда выполнения QuickJS-WASI
OpenClaw загружает quickjs-wasi как прямую зависимость во владеющем пакете. Среда
выполнения не полагается на транзитивную копию, установленную для proxy, PAC или других
несвязанных зависимостей.
Обязанности среды выполнения:
- компилировать или загружать WebAssembly-модуль QuickJS-WASI
- создавать одну изолированную VM на запуск или возобновление code-mode
- регистрировать обратные вызовы хоста под стабильными именами
- задавать ограничения памяти и прерываний
- выполнять JavaScript
- выгружать ожидающие задания
- создавать снимок приостановленного состояния VM
- восстанавливать снимки для
wait - освобождать дескрипторы VM и снимки после терминальных состояний
Среда выполнения работает вне основного цикла событий OpenClaw в worker. Бесконечный цикл в гостевой среде не должен бессрочно блокировать процесс Gateway.
TypeScript
Поддержка TypeScript — только исходное преобразование:
- принимаемый ввод: одна строка кода TypeScript
- вывод: строка JavaScript, выполняемая QuickJS-WASI
- без проверки типов
- без разрешения модулей
- без
importилиrequireв v1 - диагностика возвращается как результаты
failed
Компилятор TypeScript загружается лениво только для ячеек TypeScript. Обычные ячейки JavaScript и отключенный code mode не загружают компилятор.
Преобразование по возможности должно сохранять полезные номера строк.
Граница безопасности
Код модели враждебен. Среда выполнения использует многоуровневую защиту:
- запускать QuickJS-WASI вне основного цикла событий
- загружать
quickjs-wasiкак прямую зависимость, а не через Codex или транзитивный пакет - без файловой системы, сети, подпроцессов, импорта модулей, переменных среды или глобальных объектов хоста в гостевой среде
- использовать ограничения памяти и прерываний QuickJS
- применять тайм-аут по wall-clock времени родительского процесса
- применять ограничения вывода, снимков, журналов и ожидающих вызовов
- сериализовать значения моста хоста через узкий JSON-адаптер
- преобразовывать ошибки хоста в обычные ошибки гостевой среды, никогда не в объекты области хоста
- удалять снимки при тайм-ауте, прерывании, завершении сеанса или истечении срока
- отклонять рекурсивный доступ к
exec,waitи управляющим инструментам Tool Search - предотвращать затенение вспомогательных функций каталога из-за коллизий удобных имен
Песочница — один из уровней безопасности. Операторам все еще может потребоваться усиление на уровне ОС для развертываний с высоким риском.
Коды ошибок
type CodeModeErrorCode = | "runtime_unavailable" | "invalid_config" | "invalid_input" | "unsupported_language" | "typescript_transform_failed" | "module_access_denied" | "timeout" | "memory_limit_exceeded" | "output_limit_exceeded" | "snapshot_limit_exceeded" | "snapshot_expired" | "snapshot_restore_failed" | "too_many_pending_tool_calls" | "nested_tool_failed" | "aborted" | "internal_error";Ошибки, возвращаемые гостевой среде, являются обычными данными. Экземпляры Error хоста, объекты стека,
прототипы и функции хоста не переходят в QuickJS.
Телеметрия
Code mode сообщает:
- видимые имена инструментов, отправленные модели
- размер скрытого каталога и разбивку по источникам
- количества
execиwait - количества вложенных поисков, описаний и вызовов
- идентификаторы вызванных вложенных инструментов
- сбои из-за ограничений тайм-аута, памяти, снимков и вывода
- события жизненного цикла снимков
Телеметрия не должна включать секреты, необработанные значения среды или неотредактированные входные данные инструментов сверх существующей политики траекторий OpenClaw.
Отладка
Используйте целевое логирование транспорта модели, когда code mode ведет себя иначе, чем обычный запуск инструмента:
OPENCLAW_DEBUG_CODE_MODE=1 \OPENCLAW_DEBUG_MODEL_TRANSPORT=1 \OPENCLAW_DEBUG_MODEL_PAYLOAD=tools \OPENCLAW_DEBUG_SSE=events \openclaw gatewayДля отладки формы полезной нагрузки используйте OPENCLAW_DEBUG_MODEL_PAYLOAD=full-redacted.
Это записывает ограниченный, отредактированный JSON-снимок запроса модели; его следует использовать только
во время отладки, поскольку подсказки и текст сообщений все еще могут появляться.
Для отладки потока используйте OPENCLAW_DEBUG_SSE=peek, чтобы записать первые пять
отредактированных событий SSE. Code mode также завершается закрыто, если финальная полезная нагрузка провайдера
не содержит ровно exec и wait после активации поверхности code-mode.
Схема реализации
Единицы реализации:
- контракт конфигурации:
tools.codeMode - построитель каталога: эффективные инструменты в компактные записи и карту идентификаторов
- адаптер модельной поверхности: заменить видимые инструменты на
execиwait - адаптер среды выполнения QuickJS-WASI: загрузить, выполнить eval, создать снимок, восстановить, освободить
- супервизор worker: тайм-аут, прерывание, изоляция сбоев
- адаптер моста: JSON-безопасные обратные вызовы хоста и доставка результатов
- адаптер преобразования TypeScript
- хранилище снимков: TTL, ограничения размера, область запуска/сеанса
- проекция траектории для вложенных вызовов инструментов
- счетчики телеметрии и диагностика
Реализация повторно использует концепции каталога и исполнителя из Tool Search, но
не использует дочерний node:vm как песочницу.
Контрольный список валидации
Покрытие code mode должно доказать:
- отключенная конфигурация оставляет существующую доступность инструментов без изменений
- объектная конфигурация без
enabled: trueоставляет режим кода отключенным - включенная конфигурация предоставляет модели только
execиwait, когда инструменты активны для запуска - сырые запуски без инструментов,
disableToolsи пустые списки разрешений не запускают принудительную проверку полезной нагрузки режима кода - все эффективные инструменты не-MCP отображаются в
ALL_TOOLS - запрещенные инструменты не отображаются в
ALL_TOOLS tools.search,tools.describeиtools.callработают для инструментов OpenClawAPI.list("mcp")иAPI.read("mcp/<server>.d.ts")предоставляют объявления MCP в стиле TypeScript без вызова моста/инструмента- пространство имен MCP
$api()остается доступным как встроенный резервный вариант для схем - вызовы пространства имен MCP работают для видимых инструментов MCP с одним объектным вводом, при этом
прямые записи каталога MCP отсутствуют в
tools.* - управляющие инструменты Tool Search скрыты как с поверхности модели, так и из скрытого каталога
- вложенные вызовы сохраняют поведение утверждений и хуков
- shell
execскрыт от модели, но вызывается по id каталога, если разрешен - рекурсивные
execиwaitрежима кода не могут вызываться из гостевого кода - ввод TypeScript преобразуется и выполняется без загрузки TypeScript на отключенных путях или путях только для JavaScript
- доступ к
import,require, файловой системе, сети и окружению завершается ошибкой - бесконечные циклы истекают по тайм-ауту и не могут заблокировать Gateway
- сбои ограничения памяти завершают гостевую VM
- ограничения вывода и снимков применяются для завершенных и приостановленных вызовов
waitвозобновляет приостановленный снимок и возвращает итоговое значение- истекшие, прерванные, относящиеся к неправильной сессии и неизвестные значения
runIdзавершаются ошибкой - воспроизведение и сохранение транскрипта сохраняют управляющие вызовы режима кода
- транскрипт и телеметрия ясно показывают вложенные вызовы инструментов
План E2E-тестирования
Запускайте эти проверки как интеграционные или end-to-end тесты при изменении runtime:
- Запустите Gateway с
tools.codeMode.enabled: false. - Отправьте ход агента с небольшим прямым набором инструментов.
- Убедитесь, что инструменты, видимые модели, не изменились.
- Перезапустите с
tools.codeMode.enabled: true. - Отправьте ход агента с тестовыми инструментами OpenClaw, plugin, MCP и клиента.
- Убедитесь, что список инструментов, видимых модели, ровно
exec,wait. - В
execпрочитайтеALL_TOOLSи убедитесь, что эффективные тестовые инструменты присутствуют. - В
execвызовите инструменты OpenClaw/plugin/клиента черезtools.search,tools.describeиtools.call. - В
execвызовитеAPI.list("mcp")иAPI.read("mcp/<server>.d.ts")и убедитесь, что файлы объявлений описывают видимые инструменты MCP. - В
execвызовите инструменты MCP черезMCP.<server>.<tool>({ ...input })и убедитесь, что прямые записи каталога MCP отсутствуют вALL_TOOLSиtools.*. - Убедитесь, что запрещенные инструменты отсутствуют и не могут быть вызваны по предполагаемому id.
- Запустите вложенный вызов инструмента, который завершается после того, как
execвозвращаетwaiting. - Вызовите
waitи убедитесь, что восстановленная VM получает результат инструмента. - Убедитесь, что итоговый ответ содержит вывод, созданный после восстановления.
- Убедитесь, что тайм-аут, прерывание и истечение срока снимка очищают состояние runtime.
- Экспортируйте траекторию и убедитесь, что вложенные вызовы видны под родительским вызовом режима кода.
Для изменений только в документации на этой странице все равно следует запускать pnpm check:docs.