> ## Documentation Index
> Fetch the complete documentation index at: https://docs2.openclaw.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Режим кода

Режим кода — экспериментальная функция среды выполнения агентов 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` в конфигурацию агента или среды выполнения:

```json5 theme={"theme":{"light":"min-light","dark":"min-dark"}}
{
  tools: {
    codeMode: {
      enabled: true,
    },
  },
}
```

Также принимается сокращенная форма:

```json5 theme={"theme":{"light":"min-light","dark":"min-dark"}}
{
  tools: {
    codeMode: true,
  },
}
```

Режим кода остается отключенным, когда `tools.codeMode` отсутствует, равно `false` или является объектом
без `enabled: true`.

Когда вы используете изолированных агентов с настроенными MCP-серверами, также убедитесь, что
политика инструментов песочницы разрешает встроенный MCP Plugin, например через
`tools.sandbox.tools.alsoAllow: ["bundle-mcp"]`. См.
[Конфигурация — инструменты и пользовательские провайдеры](/ru/gateway/config-tools#mcp-and-plugin-tools-inside-sandbox-tool-policy).

Используйте явные лимиты, когда нужны более строгие границы:

```json5 theme={"theme":{"light":"min-light","dark":"min-dark"}}
{
  tools: {
    codeMode: {
      enabled: true,
      timeoutMs: 10000,
      memoryLimitBytes: 67108864,
      maxOutputBytes: 65536,
      maxSnapshotBytes: 10485760,
      maxPendingToolCalls: 16,
      snapshotTtlSeconds: 900,
      searchDefaultLimit: 8,
      maxSearchLimit: 50,
    },
  },
}
```

Чтобы подтвердить форму полезной нагрузки модели при отладке, запустите Gateway с
целевым логированием:

```bash theme={"theme":{"light":"min-light","dark":"min-dark"}}
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`](https://github.com/vercel-labs/quickjs-wasi).
* Состояние по умолчанию: отключено.
* Стабильность: экспериментальная поверхность OpenClaw; режим кода Codex — отдельная стабильная
  поверхность среды Codex.
* Целевая поверхность: общие запуски агентов OpenClaw.
* Позиция безопасности: код модели считается враждебным.
* Обещание для пользователей: включение режима кода никогда не приводит к тихому откату к широкому
  прямому показу инструментов.

## Область действия

Режим кода отвечает за обращенную к модели форму оркестрации для подготовленного запуска. Он не
отвечает за выбор модели, поведение каналов, аутентификацию, политику инструментов или
реализации инструментов.

Входит в область действия:

* видимые модели определения инструментов `exec` и `wait`
* построение скрытого каталога инструментов
* выполнение гостевого JavaScript и TypeScript
* рабочая среда QuickJS-WASI
* обратные вызовы хоста для поиска в каталоге, описания схемы и вызова инструмента
* возобновляемое состояние для приостановленных гостевых программ
* лимиты вывода, тайм-аута, памяти, ожидающих вызовов и снимков
* телеметрия и проекция траектории для вложенных вызовов инструментов

Не входит в область действия:

* нативное удаленное выполнение кода провайдером
* семантика выполнения оболочки
* изменение существующей авторизации инструментов
* постоянные пользовательские скрипты
* доступ к менеджеру пакетов, файлам, сети или модулям в гостевом коде
* прямое повторное использование внутренних компонентов режима кода Codex

Инструменты, принадлежащие провайдеру, такие как удаленные песочницы Python, остаются отдельными инструментами. См.
[Выполнение кода](/ru/tools/code-execution).

## Термины

**Режим кода** — режим среды выполнения 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 завершает этот запуск закрытым отказом.
Он не открывает обычные инструменты тихо в качестве отката.

## Активация

Режим кода оценивается после того, как известна эффективная политика инструментов, и до
сборки финального запроса к модели.

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

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 theme={"theme":{"light":"min-light","dark":"min-dark"}}
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` не предоставляет обычную реализацию shell `exec` рекурсивно.

Результат:

```typescript theme={"theme":{"light":"min-light","dark":"min-dark"}}
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` продолжает приостановленную ВМ в режиме кода.

Ввод:

```typescript theme={"theme":{"light":"min-light","dark":"min-dark"}}
type CodeModeWaitInput = {
  runId: string;
};
```

Вывод — тот же union `CodeModeResult`, который возвращает `exec`.

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

Снимок и восстановление QuickJS-WASI — механизм возобновления v1:

1. `exec` выполняет код до завершения, сбоя или приостановки.
2. При приостановке OpenClaw создает снимок ВМ QuickJS и записывает ожидающую работу
   хоста.
3. Когда ожидающая работа завершается, `wait` восстанавливает снимок ВМ.
4. OpenClaw повторно регистрирует callback-функции хоста по стабильным именам.
5. OpenClaw доставляет результаты вложенных инструментов в восстановленную ВМ.
6. OpenClaw опустошает ожидающие задания QuickJS.
7. `wait` возвращает результат `completed`, `failed` или еще один результат `waiting`.

Снимки — это состояние среды выполнения, а не пользовательские артефакты. Они имеют ограничение размера, срок действия
и область действия, ограниченную запуском и сессией, которые их создали.

`wait` завершается с ошибкой, когда:

* `runId` неизвестен.
* срок действия снимка истек.
* родительский запуск или сессия были прерваны.
* вызывающий находится не в той же области запуска/сессии.
* восстановление QuickJS-WASI завершается ошибкой.
* восстановление превысило бы настроенные лимиты.

## API гостевой среды выполнения

Гостевая среда выполнения предоставляет небольшой глобальный API:

```typescript theme={"theme":{"light":"min-light","dark":"min-dark"}}
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 theme={"theme":{"light":"min-light","dark":"min-dark"}}
type ToolCatalogEntry = {
  id: string;
  name: string;
  label?: string;
  description: string;
  source: "openclaw" | "plugin" | "mcp" | "client";
  sourceName?: string;
};
```

Полная схема загружается только по требованию:

```typescript theme={"theme":{"light":"min-light","dark":"min-dark"}}
type ToolCatalogEntryWithSchema = ToolCatalogEntry & {
  parameters: unknown;
};
```

Вспомогательные функции каталога:

```typescript theme={"theme":{"light":"min-light","dark":"min-dark"}}
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;
};
```

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

```typescript theme={"theme":{"light":"min-light","dark":"min-dark"}}
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 theme={"theme":{"light":"min-light","dark":"min-dark"}}
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 theme={"theme":{"light":"min-light","dark":"min-dark"}}
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`:

```javascript theme={"theme":{"light":"min-light","dark":"min-dark"}}
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`. Если работа пространства имен все еще ожидает при timeout или
   гость явно уступает управление, `wait` позже возобновляет ту же среду выполнения пространства имен.
8. Откат или удаление Plugin вызывает `clearCodeModeNamespacesForPlugin(pluginId)`,
   чтобы устаревшие глобальные объекты не пережили неудачную загрузку Plugin.

Важный инвариант: вызовы пространств имен — это вызовы инструментов каталога. Они используют те же
хуки политик, approvals, обработку прерывания, телеметрию, проекцию transcript
и поведение приостановки/возобновления, что и `tools.call(...)`.

### Форма регистрации

Регистрируйте пространства имен из интеграции, которая владеет базовыми инструментами. Держите
область небольшой и раскрывайте только доменные действия, которые сопоставляются с объявленными инструментами каталога.

```typescript theme={"theme":{"light":"min-light","dark":"min-dark"}}
import {
  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 theme={"theme":{"light":"min-light","dark":"min-dark"}}
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` только когда пространство имен видимо для этого запуска. Используйте их,
чтобы объяснить минимально полезную поверхность:

```typescript theme={"theme":{"light":"min-light","dark":"min-dark"}}
{
  description: "Fiction production service helpers.",
  prompt:
    "Use Fictions.riskAudit(), Fictions.promoteIfReady(id, status), and Fictions.unpaidOver(amount).",
}
```

Держите prompts о контракте пространства имен, а не о настройке аутентификации, истории
реализации или несвязанном поведении Plugin.

### Очистка

Пространства имен являются локальными для процесса регистрациями. Удаляйте их, когда владеющий Plugin
отключается, удаляется или откатывается:

```typescript theme={"theme":{"light":"min-light","dark":"min-dark"}}
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`.

Элемент вывода:

```typescript theme={"theme":{"light":"min-light","dark":"min-dark"}}
type CodeModeOutput = { type: "text"; text: string } | { type: "json"; value: unknown };
```

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

* порядок вывода соответствует вызовам гостевой среды
* вывод ограничивается `maxOutputBytes`
* несериализуемые значения преобразуются в обычные строки или ошибки
* двоичные значения не поддерживаются в v1
* изображения и файлы передаются через обычные инструменты OpenClaw, а не через
  мост code-mode

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

Скрытый каталог включает инструменты после фильтрации по эффективной политике:

1. Основные инструменты OpenClaw.
2. Инструменты встроенных Plugin.
3. Инструменты внешних Plugin.
4. Инструменты MCP.
5. Инструменты, предоставленные клиентом для текущего запуска.

Идентификаторы каталога стабильны в пределах одного запуска и по возможности детерминированы для эквивалентных
наборов инструментов.

Рекомендуемая форма идентификатора:

```text theme={"theme":{"light":"min-light","dark":"min-dark"}}
<source>:<owner>:<tool-name>
```

Примеры:

```text theme={"theme":{"light":"min-light","dark":"min-dark"}}
openclaw:core:message
plugin:browser:browser_request
mcp:github:create_issue
client:app:select_file
```

Каталог исключает управляющие инструменты code-mode:

* `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 })` разрешается обратно в
точный идентификатор каталога, а затем отправляется через тот же путь исполнителя.

## Взаимодействие 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](/ru/tools/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
* предотвращать затенение вспомогательных функций каталога из-за коллизий удобных имен

Песочница — один из уровней безопасности. Операторам все еще может потребоваться усиление на уровне ОС
для развертываний с высоким риском.

## Коды ошибок

```typescript theme={"theme":{"light":"min-light","dark":"min-dark"}}
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 ведет себя иначе, чем
обычный запуск инструмента:

```bash theme={"theme":{"light":"min-light","dark":"min-dark"}}
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` работают для инструментов OpenClaw
* `API.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:

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. Убедитесь, что запрещенные инструменты отсутствуют и не могут быть вызваны по предполагаемому id.
12. Запустите вложенный вызов инструмента, который завершается после того, как `exec` возвращает `waiting`.
13. Вызовите `wait` и убедитесь, что восстановленная VM получает результат инструмента.
14. Убедитесь, что итоговый ответ содержит вывод, созданный после восстановления.
15. Убедитесь, что тайм-аут, прерывание и истечение срока снимка очищают состояние runtime.
16. Экспортируйте траекторию и убедитесь, что вложенные вызовы видны под родительским
    вызовом режима кода.

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

## Связанные материалы

* [Tool Search](/ru/tools/tool-search)
* [Runtime агентов](/ru/concepts/agent-runtimes)
* [Инструмент exec](/ru/tools/exec)
* [Выполнение кода](/ru/tools/code-execution)
