RPC and API

Режим коду

Режим коду — експериментальна функція середовища виконання агентів OpenClaw. За замовчуванням її вимкнено. Коли ви її вмикаєте, OpenClaw змінює те, що модель бачить для одного запуску: замість прямого показу кожної ввімкненої схеми інструмента модель бачить лише exec і wait.

Ця сторінка документує режим коду OpenClaw. Це не режим коду Codex. Ці дві функції мають спільну назву, але реалізовані різними середовищами виконання та надають різні контракти exec:

  • Codex Code Mode увімкнено для потоків сервера застосунку Codex, якщо обмежувальна політика інструментів не вимикає нативний режим коду. Він працює в середовищі програмування Codex, де модель записує команди оболонки через контракт exec.command.
  • Режим коду OpenClaw вимкнено, якщо не налаштовано tools.codeMode.enabled: true. Він працює в загальному середовищі виконання агентів OpenClaw, де модель записує програми JavaScript або TypeScript через контракт exec.code.

Codex Code Mode і нативний для 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 до конфігурації агента або середовища виконання:

json5
{  tools: {    codeMode: {      enabled: true,    },  },}

Також приймається скорочена форма:

json5
{  tools: {    codeMode: true,  },}

Режим коду залишається вимкненим, коли tools.codeMode пропущено, має значення false або є об’єктом без enabled: true.

Коли ви використовуєте ізольованих агентів із налаштованими серверами MCP, також переконайтеся, що політика інструментів пісочниці дозволяє вбудований Plugin MCP, наприклад через tools.sandbox.tools.alsoAllow: ["bundle-mcp"]. Див. Конфігурація - інструменти та власні провайдери.

Використовуйте явні обмеження, коли потрібні жорсткіші межі:

json5
{  tools: {    codeMode: {      enabled: true,      timeoutMs: 10000,      memoryLimitBytes: 67108864,      maxOutputBytes: 65536,      maxSnapshotBytes: 10485760,      maxPendingToolCalls: 16,      snapshotTtlSeconds: 900,      searchDefaultLimit: 8,      maxSearchLimit: 50,    },  },}

Щоб під час налагодження підтвердити форму корисного навантаження моделі, запустіть Gateway із цільовим журналюванням:

bash
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 Code mode є окремою стабільною поверхнею середовища Codex.
  • Цільова поверхня: загальні запуски агентів OpenClaw.
  • Позиція щодо безпеки: код моделі є ворожим.
  • Обіцянка для користувача: увімкнення режиму коду ніколи безшумно не повертається до широкого прямого показу інструментів.

Область дії

Режим коду відповідає за форму оркестрації, звернену до моделі, для підготовленого запуску. Він не відповідає за вибір моделі, поведінку каналів, автентифікацію, політику інструментів або реалізації інструментів.

Входить до області дії:

  • видимі моделі визначення інструментів exec і wait
  • побудова прихованого каталогу інструментів
  • виконання гостьового JavaScript і TypeScript
  • середовище виконання воркера QuickJS-WASI
  • зворотні виклики хоста для пошуку в каталозі, опису схеми та виклику інструмента
  • відновлюваний стан для призупинених гостьових програм
  • обмеження виводу, часу очікування, пам’яті, очікуваних викликів і знімків
  • телеметрія та проєкція траєкторії для вкладених викликів інструментів

Поза областю дії:

  • нативне для провайдера віддалене виконання коду
  • семантика виконання оболонки
  • зміна наявної авторизації інструментів
  • постійні скрипти, написані користувачем
  • доступ до менеджера пакетів, файлів, мережі або модулів у гостьовому коді
  • пряме повторне використання внутрішніх компонентів Codex Code mode

Інструменти, якими володіє провайдер, як-от віддалені пісочниці Python, залишаються окремими інструментами. Див. Виконання коду.

Терміни

Режим коду — це режим середовища виконання OpenClaw, який приховує звичайні інструменти моделі та надає лише exec і wait.

Гостьове середовище виконання — це VM JavaScript QuickJS-WASI, яка оцінює код моделі.

Міст хоста — це вузька JSON-сумісна поверхня зворотних викликів із гостьового коду назад в OpenClaw.

Каталог — це обмежений запуском список ефективних інструментів після звичайної політики інструментів і розв’язання Plugin, MCP та клієнтських інструментів.

Вкладений виклик інструмента — це виклик інструмента, зроблений із гостьового коду через міст хоста.

Знімок — це серіалізований стан VM QuickJS-WASI, збережений, щоб wait міг продовжити призупинений запуск у режимі коду.

Конфігурація

tools.codeMode.enabled — це перемикач активації. Налаштування інших полів режиму коду не вмикає функцію.

Підтримувані поля:

  • enabled: булеве значення. За замовчуванням 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 завершує цей запуск із закритою відмовою. Він безшумно не показує звичайні інструменти як запасний варіант.

Активація

Режим коду оцінюється після визначення ефективної політики інструментів і перед складанням остаточного запиту до моделі.

Порядок активації:

  1. Розв’язати агента, модель, провайдера, пісочницю, канал, відправника та політику запуску.
  2. Побудувати ефективний список інструментів OpenClaw.
  3. Додати придатні інструменти Plugin, MCP і клієнтські інструменти.
  4. Застосувати політики дозволу та заборони.
  5. Якщо tools.codeMode.enabled має значення false, продовжити зі звичайним показом інструментів.
  6. Якщо ввімкнено і для запуску активні інструменти, зареєструвати ефективні інструменти в каталозі режиму коду.
  7. Видалити всі звичайні інструменти зі списку інструментів, видимого моделі.
  8. Додати exec і wait режиму коду.

Запуски, які навмисно не мають інструментів, як-от необроблені виклики моделі, disableTools або порожній список дозволених, не активують поверхню режиму коду, навіть якщо конфігурація містить tools.codeMode.enabled: true.

Каталог режиму коду обмежений запуском. Він не повинен пропускати інструменти з іншого агента, сеансу, відправника або запуску.

Інструменти, видимі моделі

Коли режим коду активний, модель бачить рівно ці інструменти верхнього рівня:

  • exec
  • wait

Усі інші ввімкнені інструменти приховано зі списку інструментів, зверненого до моделі, і зареєстровано в каталозі режиму коду.

Модель має використовувати exec для оркестрації інструментів, об’єднання даних, циклів, паралельних вкладених викликів і структурованих перетворень. Модель має використовувати wait лише тоді, коли exec повертає відновлюваний результат waiting.

exec

exec запускає комірку режиму коду та повертає один результат. Вхідний код генерується моделлю і має вважатися ворожим.

Вхід:

typescript
type CodeModeExecInput = {  code?: string;  command?: string;  language?: "javascript" | "typescript";};

Правила входу:

  • Одне з code або command має бути непорожнім.
  • code — задокументоване поле, звернене до моделі.
  • command приймається як сумісний з exec псевдонім для політик хуків і довірених переписувань; коли присутні обидва поля, значення мають збігатися.
  • Зовнішні події хуків exec режиму коду містять toolKind: "code_mode_exec" і містять toolInputKind: "javascript" | "typescript", коли мова входу відома, щоб політики могли відрізняти комірки режиму коду від викликів exec у стилі оболонки, які мають таку саму назву інструмента.
  • language за замовчуванням має значення "javascript".
  • Якщо language має значення "typescript", OpenClaw транспілює перед оцінюванням.
  • exec відхиляє import, require, динамічний import і шаблони завантажувача модулів у v1.
  • exec не надає звичайну реалізацію оболонки exec рекурсивно.

Результат:

typescript
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 лише тоді, коли гостьова VM не має незавершеної роботи, а фінальне значення є JSON-сумісним після виконання адаптера виводу OpenClaw.

wait

wait продовжує призупинену VM режиму коду.

Вхідні дані:

typescript
type CodeModeWaitInput = {  runId: string;};

Вивід є тим самим об’єднанням CodeModeResult, яке повертає exec.

wait існує тому, що вкладені інструменти OpenClaw можуть бути повільними, інтерактивними, обмеженими схваленням або транслювати часткові оновлення. Модель не повинна тримати один довгий виклик exec відкритим, поки хост чекає на зовнішню роботу.

Знімок і відновлення QuickJS-WASI є механізмом відновлення v1:

  1. exec виконує код до завершення, помилки або призупинення.
  2. Під час призупинення OpenClaw створює знімок QuickJS VM і записує очікувану роботу хоста.
  3. Коли очікувана робота завершується, wait відновлює знімок VM.
  4. OpenClaw повторно реєструє callback-и хоста за стабільними іменами.
  5. OpenClaw передає результати вкладених інструментів у відновлену VM.
  6. OpenClaw вичерпує очікувані завдання QuickJS.
  7. wait повертає completed, failed або інший результат waiting.

Знімки є станом runtime, а не користувацькими артефактами. Вони мають обмеження розміру, строк дії та область, обмежену запуском і сесією, які їх створили.

wait завершується помилкою, коли:

  • runId невідомий.
  • строк дії знімка минув.
  • батьківський запуск або сесію було перервано.
  • викликач не перебуває в тій самій області запуску/сесії.
  • відновлення QuickJS-WASI завершується помилкою.
  • відновлення перевищило б налаштовані ліміти.

API гостьового runtime

Гостьовий runtime надає невеликий глобальний API:

typescript
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 — це компактні метадані для каталогу в межах запуску. За замовчуванням вони не містять повних схем.

typescript
type ToolCatalogEntry = {  id: string;  name: string;  label?: string;  description: string;  source: "openclaw" | "plugin" | "mcp" | "client";  sourceName?: string;};

Повна схема завантажується лише на вимогу:

typescript
type ToolCatalogEntryWithSchema = ToolCatalogEntry & {  parameters: unknown;};

Помічники каталогу:

typescript
type ToolCatalog = {  search(query: string, options?: { limit?: number }): Promise&lt;ToolCatalogEntry[]&gt;;  describe(id: string): Promise&lt;ToolCatalogEntryWithSchema&gt;;  call(id: string, input?: unknown): Promise<unknown>;  [safeToolName: string]: unknown;};

Зручні функції інструментів встановлюються лише для однозначних безпечних імен:

typescript
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:

typescript
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:

typescript
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&lt;McpApiHeader&gt;;   /**   * 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&lt;McpToolResult&gt;;}

Файли декларацій є віртуальними, а не файлами, записаними в робочу область або каталог стану. Для кожного виклику 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() залишається доступним як вбудований запасний варіант, коли агенту потрібна відповідь зі схемою одного інструмента всередині програми.

Гостьовий runtime не повинен напряму відкривати об’єкти хоста. Вхідні та вихідні дані перетинають міст як JSON-сумісні значення з явними обмеженнями розміру.

Внутрішні простори імен

Внутрішні простори імен дають режиму коду стислий доменний API без додавання більшої кількості видимих для моделі інструментів. Інтеграція, якою володіє завантажувач, може зареєструвати простір імен, як-от Issues, Fictions або Calendar; гостьовий код тоді викликає цей простір імен усередині програми QuickJS, тоді як OpenClaw усе ще показує моделі лише exec і wait.

Простори імен наразі є внутрішніми. Публічного API простору імен у plugin SDK немає: зовнішнім просторам імен Plugin потрібен контракт, яким володіє завантажувач, щоб ідентичність Plugin, установлені маніфести, стан автентифікації та кешовані дескриптори каталогу не розходилися з інструментами Plugin, які підтримують простір імен. Основний режим коду володіє лише пісочницею, серіалізацією, обмеженням каталогу та диспетчеризацією мосту.

Гостьовий код тоді може використовувати або прямий глобальний об’єкт, або мапу namespaces:

javascript
const open = await Issues.list({ state: "open" });const alsoOpen = await namespaces.Issues.list({ state: "open" });return { count: open.length, alsoCount: alsoOpen.length };

Життєвий цикл реєстру

Реєстр просторів імен є локальним для процесу та ключується за id простору імен. Типовий запуск проходить таким шляхом:

  1. Довірений завантажувач викликає registerCodeModeNamespaceForPlugin(pluginId, registration).
  2. Режим коду створює прихований ToolSearchRuntime для запуску та читає його каталог у межах запуску.
  3. createCodeModeNamespaceRuntime(ctx, catalog) залишає лише реєстрації, у яких усі requiredToolNames видимі та належать тому самому pluginId.
  4. Кожен видимий простір імен викликає createScope(ctx) для поточного запуску. Область отримує контекст запуску, як-от agentId, sessionKey, sessionId, runId, конфігурацію та стан переривання.
  5. Дані області серіалізуються у простий дескриптор і вводяться в QuickJS як прямі глобальні об’єкти та namespaces.<globalName>.
  6. Гостьові виклики призупиняються через міст worker, визначають шлях простору імен на хості, зіставляють виклик із оголошеним інструментом каталогу, яким володіє Plugin, і виконують цей інструмент через ToolSearchRuntime.call.
  7. OpenClaw автоматично вичерпує готові виклики мосту простору імен усередині активного виклику інструмента exec/wait. Якщо робота простору імен усе ще очікує на момент тайм-ауту або гість явно поступається керуванням, wait пізніше відновлює той самий runtime простору імен.
  8. Відкат або видалення Plugin викликає clearCodeModeNamespacesForPlugin(pluginId), щоб застарілі глобальні об’єкти не пережили невдале завантаження Plugin.

Важливий інваріант: виклики простору імен є викликами інструментів каталогу. Вони використовують ті самі policy hooks, схвалення, обробку переривання, телеметрію, проєкцію transcript і поведінку призупинення/відновлення, що й tools.call(...).

Форма реєстрації

Реєструйте простори імен з інтеграції, яка володіє базовими інструментами. Тримайте область малою та відкривайте лише доменні дієслова, які зіставляються з оголошеними інструментами каталогу.

typescript
   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 отримує гостьові аргументи та повертає об’єкт вхідних даних для базового інструмента каталогу. Без мапера вхідних даних використовується перший гостьовий аргумент або {}, якщо його пропущено.

Сирі функції хоста відхиляються до запуску гостьового коду:

typescript
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, обмеженнями швидкості, схваленнями запису та тестами. Основний режим коду не повинен вбудовувати API, специфічні для GitHub, обробку токенів або політику provider.

Правила серіалізації області

createScope(ctx) може повертати простий об’єкт, що містить JSON-сумісні значення, масиви, вкладені об’єкти та маркери виклику createCodeModeNamespaceTool(...). Об’єкти хоста ніколи не потрапляють безпосередньо в QuickJS.

Серіалізатор відхиляє:

  • сирі функції
  • циклічні графи об’єктів
  • небезпечні сегменти шляху: __proto__, constructor, prototype, порожні ключі або ключі, що містять внутрішній розділювач шляху
  • значення globalName, які не є ідентифікаторами JavaScript
  • конфлікти globalName з вбудованими глобальними об’єктами режиму коду, як-от tools, namespaces, text, json, yield_control або __openclaw*

Значення, які не можна JSON-серіалізувати, перетворюються на JSON-безпечні запасні значення перед перетином мосту. Бінарні дані, дескриптори, сокети, клієнти та екземпляри класів мають залишатися за звичайними інструментами каталогу.

Prompts

description простору імен і необов’язковий prompt додаються до видимої для моделі схеми exec лише тоді, коли простір імен видимий для цього запуску. Використовуйте їх, щоб навчити найменшій корисній поверхні:

typescript
{  description: "Fiction production service helpers.",  prompt:    "Use Fictions.riskAudit(), Fictions.promoteIfReady(id, status), and Fictions.unpaidOver(amount).",}

Тримайте prompts про контракт простору імен, а не про налаштування автентифікації, історію реалізації чи непов’язану поведінку Plugin.

Очищення

Namespaces є локальними для процесу реєстраціями. Видаляйте їх, коли Plugin-власник вимкнено, видалено або відкочено:

typescript
clearCodeModeNamespacesForPlugin(pluginId);

Очищення режиму коду належить Plugin; очищайте реєстрації простору імен Plugin, коли його життєвий цикл завершується, замість зберігання обробників демонтажу для кожного простору імен. Тести можуть викликати clearCodeModeNamespacesForTest(), щоб уникнути витоку реєстрацій між випадками.

Контрольний список тестування

Зміни просторів імен мають покривати межу безпеки та поведінку гостьового коду:

  • текст підказки простору імен з'являється лише тоді, коли базові інструменти видимі
  • інструменти з такою самою назвою з іншого sourceName не відкривають простір імен
  • необроблені функції області дії відхиляються
  • підроблені ідентифікатори просторів імен і підроблені шляхи відхиляються
  • викличні шляхи не можуть націлюватися на неоголошені інструменти
  • вкладені об'єкти та спільні посилання серіалізуються правильно
  • виклики простору імен виконуються через інструменти каталогу й повертають JSON-безпечні деталі
  • помилки може перехоплювати гостьовий код
  • призупинені виклики простору імен відновлюються через wait
  • відкат Plugin очищає реєстрації простору імен, що йому належать

Namespaces доповнюють загальний каталог tools.search / tools.call. Використовуйте каталог для довільних увімкнених інструментів OpenClaw, Plugin і клієнта; використовуйте MCP для інструментів MCP; використовуйте інші простори імен для належних Plugin задокументованих доменних API, де лаконічний код надійніший за повторні пошуки схем.

API виводу

text(value) додає читабельний для людини вивід до масиву output.

json(value) додає структурований елемент виводу після JSON-сумісної серіалізації.

Кінцеве повернене значення гостьового коду стає value у результаті completed.

Елемент виводу:

typescript
type CodeModeOutput = { type: "text"; text: string } | { type: "json"; value: unknown };

Правила виводу:

  • порядок виводу відповідає викликам гостьового коду
  • вивід обмежено maxOutputBytes
  • несеріалізовані значення перетворюються на звичайні рядки або помилки
  • двійкові значення не підтримуються у v1
  • зображення та файли передаються через звичайні інструменти OpenClaw, а не через міст режиму коду

Каталог інструментів

Прихований каталог містить інструменти після ефективної фільтрації політик:

  1. Основні інструменти OpenClaw.
  2. Інструменти вбудованих Plugin.
  3. Інструменти зовнішніх Plugin.
  4. Інструменти MCP.
  5. Інструменти, надані клієнтом, для поточного запуску.

Ідентифікатори каталогу стабільні в межах одного запуску й, коли можливо, детерміновані між еквівалентними наборами інструментів.

Рекомендована форма ідентифікатора:

text
<source>:<owner>:<tool-name>

Приклади:

text
openclaw:core:messageplugin:browser:browser_requestmcp:github:create_issueclient:app:select_file

Каталог не містить керівних інструментів режиму коду:

  • exec
  • wait
  • tool_search_code
  • tool_search
  • tool_describe
  • tool_call

Це запобігає рекурсії та звужує контракт, видимий моделі.

Записи MCP залишаються в каталозі, обмеженому запуском, щоб політика, затвердження, хуки, телеметрія, проєкція транскрипту й точні ідентифікатори інструментів залишалися спільними зі звичайним виконанням інструментів. Подання ALL_TOOLS, tools.search(...), tools.describe(...) і tools.call(...), видимі гостьовому коду, не містять записів MCP. Згенерований простір імен MCP.<server>.<tool>({ ...input }) зіставляється назад із точним ідентифікатором каталогу, а потім диспетчеризується через той самий шлях виконавця.

Взаємодія з пошуком інструментів

Режим коду замінює поверхню моделі OpenClaw для пошуку інструментів у запусках, де він активний.

Коли tools.codeMode.enabled дорівнює true і режим коду активується:

  • OpenClaw не відкриває tool_search_code, tool_search, tool_describe або tool_call як інструменти, видимі моделі.
  • Та сама ідея каталогізації переходить усередину гостьового середовища виконання.
  • Гостьове середовище виконання отримує компактні метадані ALL_TOOLS і помічники пошуку, опису та виклику для інструментів не-MCP.
  • Виклики MCP використовують згенерований простір імен MCP та його заголовки $api() замість tools.call(...).
  • Вкладені виклики диспетчеризуються через той самий шлях виконавця OpenClaw, який використовує пошук інструментів.

Наявна сторінка Пошук інструментів описує компактний каталожний міст OpenClaw. Режим коду є загальною альтернативою OpenClaw для запусків, які можуть використовувати exec і wait.

Назви інструментів і колізії

Видимий моделі інструмент exec є інструментом режиму коду. Якщо звичайний інструмент оболонки OpenClaw exec увімкнено, він прихований від моделі й каталогізується як будь-який інший інструмент.

Усередині гостьового середовища виконання:

  • tools.call("openclaw:core:exec", input) може викликати інструмент оболонки exec, якщо політика це дозволяє.
  • tools.exec(...) встановлюється лише тоді, коли запис каталогу оболонки exec має однозначну безпечну назву.
  • інструмент режиму коду exec ніколи не доступний рекурсивно через tools.

Якщо два інструменти нормалізуються до тієї самої безпечної зручної назви, OpenClaw пропускає зручну функцію й вимагає tools.call(id, input).

Вкладене виконання інструментів

Кожен вкладений виклик інструмента перетинає міст хоста й повторно входить в OpenClaw.

Вкладене виконання зберігає:

  • ідентифікатор активного агента
  • ідентифікатор сеансу та ключ сеансу
  • контекст відправника й каналу
  • політику пісочниці
  • політику затверджень
  • хуки Plugin before_tool_call
  • сигнал переривання
  • потокові оновлення, де вони доступні
  • події траєкторії та аудиту

Вкладені виклики проєктуються в транскрипт як справжні виклики інструментів, щоб пакети підтримки могли показати, що сталося. Проєкція ідентифікує батьківський виклик інструмента режиму коду та ідентифікатор вкладеного інструмента.

Паралельні вкладені виклики дозволено до maxPendingToolCalls.

Стан середовища виконання

Кожен запуск режиму коду має машину станів:

  • running: VM виконується або вкладені виклики ще тривають.
  • waiting: знімок VM існує й може бути відновлений через wait.
  • completed: кінцеве значення повернено; знімок видалено.
  • failed: помилку повернено; знімок видалено.
  • expired: знімок або очікуваний стан перевищив строк зберігання; відновлення неможливе.
  • aborted: батьківський запуск/сеанс скасовано; знімок видалено.

Стан обмежено запуском агента, сеансом та ідентифікатором виклику інструмента. Виклик wait з іншого запуску або сеансу завершується помилкою.

Сховище знімків обмежене:

  • максимальна кількість байтів знімка на запуск
  • максимальна кількість активних знімків на процес
  • TTL знімка
  • очищення після завершення запуску
  • очищення під час вимкнення Gateway, де сталість не підтримується

Середовище виконання QuickJS-WASI

OpenClaw завантажує quickjs-wasi як пряму залежність у пакеті-власнику. Середовище виконання не покладається на транзитивну копію, встановлену для proxy, PAC або інших непов'язаних залежностей.

Обов'язки середовища виконання:

  • компілювати або завантажувати WebAssembly-модуль QuickJS-WASI
  • створювати одну ізольовану VM для кожного запуску або відновлення режиму коду
  • реєструвати зворотні виклики хоста за стабільними назвами
  • встановлювати обмеження пам'яті та переривань
  • оцінювати JavaScript
  • спорожнювати очікувані завдання
  • створювати знімок призупиненого стану VM
  • відновлювати знімки для wait
  • звільняти дескриптори VM і знімки після термінальних станів

Середовище виконання працює поза головним циклом подій OpenClaw у worker. Нескінченний цикл у гостьовому коді не повинен безстроково блокувати процес Gateway.

TypeScript

Підтримка TypeScript є лише перетворенням джерела:

  • прийнятий вхід: один рядок коду TypeScript
  • вихід: рядок JavaScript, який оцінюється QuickJS-WASI
  • без перевірки типів
  • без розв'язання модулів
  • без import або require у v1
  • діагностика повертається як результати failed

Компілятор TypeScript завантажується ліниво лише для комірок TypeScript. Звичайні комірки JavaScript і вимкнений режим коду не завантажують компілятор.

Перетворення має зберігати корисні номери рядків, де це можливо.

Межа безпеки

Код моделі є ворожим. Середовище виконання використовує багаторівневий захист:

  • запускати QuickJS-WASI поза головним циклом подій
  • завантажувати quickjs-wasi як пряму залежність, а не через Codex або транзитивний пакет
  • без файлової системи, мережі, підпроцесів, імпорту модулів, змінних середовища або глобальних об'єктів хоста в гостьовому коді
  • використовувати обмеження пам'яті та переривань QuickJS
  • застосовувати таймаут настінного часу батьківського процесу
  • застосовувати ліміти виводу, знімків, журналів і очікуваних викликів
  • серіалізувати значення мосту хоста через вузький JSON-адаптер
  • перетворювати помилки хоста на звичайні помилки гостьового коду, ніколи не на об'єкти realm хоста
  • відкидати знімки під час таймауту, переривання, завершення сеансу або закінчення строку дії
  • відхиляти рекурсивний доступ до exec, wait і керівних інструментів пошуку інструментів
  • запобігати тому, щоб колізії зручних назв затіняли помічники каталогу

Пісочниця є одним шаром безпеки. Операторам усе ще може знадобитися посилення на рівні ОС для розгортань із високим ризиком.

Коди помилок

typescript
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.

Телеметрія

Режим коду повідомляє:

  • видимі назви інструментів, надіслані моделі
  • розмір прихованого каталогу та розподіл за джерелами
  • кількість exec і wait
  • кількість вкладених пошуків, описів і викликів
  • ідентифікатори викликаних вкладених інструментів
  • збої через таймаут, пам'ять, знімки та ліміти виводу
  • події життєвого циклу знімків

Телеметрія не повинна містити секрети, необроблені значення середовища або нередаговані вхідні дані інструментів поза чинною політикою траєкторії OpenClaw.

Налагодження

Використовуйте цільове журналювання транспорту моделі, коли режим коду поводиться інакше, ніж звичайний запуск інструмента:

bash
OPENCLAW_DEBUG_CODE_MODE=1 \OPENCLAW_DEBUG_MODEL_TRANSPORT=1 \OPENCLAW_DEBUG_MODEL_PAYLOAD=tools \OPENCLAW_DEBUG_SSE=events \openclaw gateway

Для налагодження форми payload використовуйте OPENCLAW_DEBUG_MODEL_PAYLOAD=full-redacted. Це журналює обмежений, відредагований JSON-знімок запиту моделі; його слід використовувати лише під час налагодження, тому що підказки й текст повідомлень усе ще можуть з'являтися.

Для налагодження потоку використовуйте OPENCLAW_DEBUG_SSE=peek, щоб журналювати перші п'ять відредагованих подій SSE. Режим коду також закривається з помилкою, якщо кінцевий payload провайдера не містить рівно exec і wait після активації поверхні режиму коду.

Схема реалізації

Одиниці реалізації:

  • контракт конфігурації: tools.codeMode
  • побудовник каталогу: ефективні інструменти в компактні записи та карту ідентифікаторів
  • адаптер поверхні моделі: замінює видимі інструменти на exec і wait
  • адаптер середовища виконання QuickJS-WASI: завантаження, eval, знімок, відновлення, звільнення
  • supervisor worker: таймаут, переривання, ізоляція аварій
  • адаптер мосту: JSON-безпечні зворотні виклики хоста та доставка результатів
  • адаптер перетворення TypeScript
  • сховище знімків: TTL, ліміти розміру, обмеження запуском/сеансом
  • проєкція траєкторії для вкладених викликів інструментів
  • лічильники телеметрії та діагностика

Реалізація повторно використовує концепції каталогу та виконавця з пошуку інструментів, але не використовує дочірній процес node:vm як пісочницю.

Контрольний список валідації

Покриття режиму коду має довести:

  • вимкнена конфігурація залишає наявну експозицію інструментів без змін
  • об’єктна конфігурація без enabled: true залишає режим коду вимкненим
  • увімкнена конфігурація відкриває моделі лише exec і wait, коли інструменти активні для запуску
  • сирі запуски без інструментів, disableTools і порожні allowlist не запускають примусове застосування payload режиму коду
  • усі ефективні інструменти не-MCP з’являються в ALL_TOOLS
  • заборонені інструменти не з’являються в ALL_TOOLS
  • tools.search, tools.describe і tools.call працюють для інструментів OpenClaw
  • API.list("mcp") і API.read("mcp/<server>.d.ts") відкривають оголошення MCP у стилі TypeScript без виклику мосту/інструмента
  • простір імен MCP $api() залишається доступним як вбудований fallback для схем
  • виклики простору імен MCP працюють для видимих інструментів MCP з одним об’єктним вводом, тоді як прямі записи каталогу MCP відсутні в tools.*
  • керівні інструменти Tool Search приховані і від поверхні моделі, і від прихованого каталогу
  • вкладені виклики зберігають поведінку затверджень і хуків
  • shell exec прихований від моделі, але його можна викликати за ідентифікатором каталогу, коли це дозволено
  • рекурсивні exec і wait режиму коду не можна викликати з гостьового коду
  • ввід TypeScript трансформується та оцінюється без завантаження TypeScript на вимкнених шляхах або шляхах лише JavaScript
  • доступ до import, require, файлової системи, мережі та середовища завершується невдачею
  • нескінченні цикли завершуються за тайм-аутом і не можуть блокувати Gateway
  • збої через обмеження пам’яті завершують роботу гостьової VM
  • обмеження виводу та snapshot застосовуються для завершених і призупинених викликів
  • wait відновлює призупинений snapshot і повертає фінальне значення
  • прострочені, перервані, неправильні для сеансу та невідомі значення runId завершуються невдачею
  • відтворення transcript і persistence зберігають керівні виклики режиму коду
  • transcript і telemetry чітко показують вкладені виклики інструментів

План E2E-тестування

Запускайте їх як інтеграційні або наскрізні тести під час зміни runtime:

  1. Запустіть Gateway з tools.codeMode.enabled: false.
  2. Надішліть хід агента з невеликим прямим набором інструментів.
  3. Переконайтеся, що видимі для моделі інструменти не змінилися.
  4. Перезапустіть із tools.codeMode.enabled: true.
  5. Надішліть хід агента з тестовими інструментами OpenClaw, Plugin, MCP і клієнта.
  6. Переконайтеся, що видимий для моделі список інструментів точно дорівнює exec, wait.
  7. У exec прочитайте ALL_TOOLS і переконайтеся, що ефективні тестові інструменти присутні.
  8. У exec викличте інструменти OpenClaw/Plugin/клієнта через tools.search, tools.describe і tools.call.
  9. У exec викличте API.list("mcp") і API.read("mcp/<server>.d.ts") та переконайтеся, що файли оголошень описують видимі інструменти MCP.
  10. У exec викличте інструменти MCP через MCP.<server>.<tool>({ ...input }) і переконайтеся, що прямі записи каталогу MCP відсутні в ALL_TOOLS і tools.*.
  11. Переконайтеся, що заборонені інструменти відсутні та їх не можна викликати за вгаданим ідентифікатором.
  12. Запустіть вкладений виклик інструмента, який завершується після того, як exec повертає waiting.
  13. Викличте wait і переконайтеся, що відновлена VM отримує результат інструмента.
  14. Переконайтеся, що фінальна відповідь містить вивід, створений після відновлення.
  15. Переконайтеся, що тайм-аут, переривання та завершення строку дії snapshot очищають стан runtime.
  16. Експортуйте trajectory і переконайтеся, що вкладені виклики видимі під батьківським викликом режиму коду.

Для змін лише в документації на цій сторінці все одно слід запускати pnpm check:docs.

Пов’язане

Was this useful?
On this page

On this page