Building plugins
Создание плагинов бэкенда CLI
Плагины серверной части CLI позволяют OpenClaw вызывать локальный CLI ИИ в качестве серверной части для текстового инференса. Серверная часть отображается как префикс провайдера в ссылках на модели:
acme-cli/acme-largeИспользуйте серверную часть CLI, если интеграция с вышестоящей системой уже доступна в виде локальной команды, если CLI управляет локальным состоянием входа или как резервный вариант, когда API провайдеров недоступны.
За что отвечает плагин
Плагин серверной части CLI имеет три контракта:
| Контракт | Файл | Назначение |
|---|---|---|
| Точка входа пакета | package.json |
Указывает OpenClaw на модуль среды выполнения плагина |
| Владение манифестом | openclaw.plugin.json |
Объявляет идентификатор серверной части до загрузки среды выполнения |
| Регистрация среды выполнения | index.ts |
Вызывает api.registerCliBackend(...) со значениями команды по умолчанию |
Манифест представляет собой метаданные обнаружения: он не запускает CLI и не регистрирует
поведение среды выполнения. Поведение среды выполнения начинается, когда точка входа плагина вызывает
api.registerCliBackend(...).
Минимальный плагин серверной части
Создайте метаданные пакета
{ "name": "@acme/openclaw-acme-cli", "version": "1.0.0", "type": "module", "openclaw": { "extensions": ["./index.ts"], "compat": { "pluginApi": ">=2026.3.24-beta.2", "minGatewayVersion": "2026.3.24-beta.2" }, "build": { "openclawVersion": "2026.3.24-beta.2", "pluginSdkVersion": "2026.3.24-beta.2" } }, "dependencies": { "openclaw": "^2026.3.24" }, "devDependencies": { "typescript": "^5.9.0" }}Опубликованные пакеты должны включать собранные файлы среды выполнения JavaScript. Если точкой входа
исходного кода служит ./src/index.ts, добавьте openclaw.runtimeExtensions, указывающий на
соответствующий собранный файл JavaScript. См. раздел Точки входа.
Объявите владение серверной частью
{ "id": "acme-cli", "name": "Acme CLI", "description": "Запускайте локальный CLI ИИ Acme через OpenClaw", "cliBackends": ["acme-cli"], "setup": { "cliBackends": ["acme-cli"], "requiresRuntime": false }, "activation": { "onStartup": false }, "configSchema": { "type": "object", "additionalProperties": false }}cliBackends — это список владения средой выполнения; он позволяет OpenClaw автоматически загружать
плагин, когда в конфигурации или при выборе модели упоминается acme-cli/....
setup.cliBackends — это поверхность настройки, основанная прежде всего на дескрипторах. Добавьте её, если
обнаружение моделей, первоначальная настройка или состояние должны распознавать серверную часть
без загрузки среды выполнения плагина. Используйте requiresRuntime: false, только если
для настройки достаточно этих статических дескрипторов.
Зарегистрируйте серверную часть
import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";import { CLI_FRESH_WATCHDOG_DEFAULTS, CLI_RESUME_WATCHDOG_DEFAULTS, type CliBackendPlugin,} from "openclaw/plugin-sdk/cli-backend"; function buildAcmeCliBackend(): CliBackendPlugin { return { id: "acme-cli", liveTest: { defaultModelRef: "acme-cli/acme-large", defaultImageProbe: false, defaultMcpProbe: false, docker: { npmPackage: "@acme/acme-cli", binaryName: "acme", }, }, config: { command: "acme", args: ["chat", "--json"], output: "json", input: "stdin", modelArg: "--model", sessionArg: "--session", sessionMode: "existing", sessionIdFields: ["session_id", "conversation_id"], systemPromptFileArg: "--system-file", systemPromptWhen: "first", imageArg: "--image", imageMode: "repeat", reliability: { watchdog: { fresh: { ...CLI_FRESH_WATCHDOG_DEFAULTS }, resume: { ...CLI_RESUME_WATCHDOG_DEFAULTS }, }, }, serialize: true, }, };} export default definePluginEntry({ id: "acme-cli", name: "Acme CLI", description: "Запускайте локальный CLI ИИ Acme через OpenClaw", register(api) { api.registerCliBackend(buildAcmeCliBackend()); },});Идентификатор серверной части должен соответствовать записи cliBackends в манифесте.
Зарегистрированная config является лишь значением по умолчанию; пользовательская конфигурация в
agents.defaults.cliBackends.acme-cli объединяется с ней во время выполнения и имеет приоритет.
Структура конфигурации
CliBackendConfig описывает, как OpenClaw должен запускать CLI и разбирать его вывод:
| Поле | Назначение |
|---|---|
command |
Имя исполняемого файла или абсолютный путь к команде |
args |
Базовый набор аргументов для новых запусков |
resumeArgs |
Альтернативный набор аргументов для возобновлённых сеансов; поддерживает {sessionId} |
output / resumeOutput |
Парсер: json, jsonl или text |
jsonlDialect |
Диалект событий JSONL: claude-stream-json или gemini-stream-json |
liveSession |
Режим долгоживущего процесса CLI (claude-stdio) |
input |
Способ передачи запроса: arg или stdin |
maxPromptArgChars |
Максимальная длина запроса в режиме arg до перехода на стандартный ввод |
env / clearEnv |
Дополнительные переменные среды для добавления или имена переменных, удаляемых перед запуском |
modelArg |
Флаг, используемый перед идентификатором модели |
modelAliases |
Сопоставление идентификаторов моделей OpenClaw с нативными идентификаторами CLI |
sessionArg / sessionArgs |
Способ передачи идентификатора сеанса |
sessionMode |
always, existing или none |
sessionIdFields |
Поля JSON, которые OpenClaw считывает из вывода CLI |
systemPromptArg / systemPromptFileArg |
Способ передачи системного запроса |
systemPromptFileConfigArg / systemPromptFileConfigKey |
Способ передачи переопределения конфигурации для файла системного запроса (например, -c) |
systemPromptMode |
append или replace |
systemPromptWhen |
first, always или never |
imageArg / imageMode |
Флаг пути к изображению и способ передачи нескольких изображений (repeat или list) |
imagePathScope |
Место хранения подготовленных файлов изображений до передачи: temp или workspace |
serialize |
Сохранять порядок запусков одной серверной части |
reseedFromRawTranscriptWhenUncompacted |
Включить ограниченное повторное заполнение из необработанной расшифровки перед Compaction для безопасного сброса сеансов |
reliability.outputLimits |
Максимальное число символов/строк необработанного JSONL, сохраняемых для одного текущего обращения к CLI (серверные части с активными сеансами) |
reliability.watchdog |
Настройка тайм-аута при отсутствии вывода отдельно для новых и возобновлённых запусков |
Предпочитайте минимальную статическую конфигурацию, соответствующую CLI. Добавляйте обратные вызовы плагина только для поведения, которое действительно относится к серверной части.
Расширенные хуки серверной части
CliBackendPlugin также может определять:
| Хук | Назначение |
|---|---|
normalizeConfig(config, context) |
Перезаписать устаревшую пользовательскую конфигурацию после объединения |
resolveExecutionArgs(ctx) |
Добавить флаги уровня запроса, например интенсивность рассуждений или изоляцию побочных вопросов |
prepareExecution(ctx) |
Создать временные мосты аутентификации, конфигурации или среды перед запуском |
transformSystemPrompt(ctx) |
Применить окончательное преобразование системного запроса для конкретного CLI |
textTransforms |
Двунаправленные замены в запросах и выводе |
defaultAuthProfileId |
Предпочесть определённый профиль аутентификации OpenClaw |
authEpochMode |
Определить, как изменения аутентификации делают сохранённые сеансы CLI недействительными |
nativeToolMode |
Объявить, отсутствуют ли нативные инструменты, всегда ли они включены или могут выбираться хостом |
sideQuestionToolMode |
Объявить отключённые нативные инструменты для побочных вопросов /btw |
bundleMcp / bundleMcpMode |
Включить мост инструментов MCP OpenClaw через обратную петлю |
ownsNativeCompaction |
Серверная часть самостоятельно выполняет Compaction — OpenClaw откладывает её |
runtimeArtifact |
Ограничить средство запуска сценария полным деревом его комплектного пакета |
Эти хуки должны оставаться в ведении провайдера. Не добавляйте специфичные для CLI ветви в ядро, если поведение можно выразить через хук серверной части.
prepareExecution(ctx) получает ctx.contextTokenBudget — эффективный лимит токенов,
выбранный для запуска. Серверные части, самостоятельно выполняющие нативную Compaction, могут преобразовать этот
бюджет в свой контракт запуска CLI.
runtimeArtifact принадлежит плагину и не может быть переопределён пользователем. Он проверяется
только тогда, когда рабочий цикл инференса создаёт или повторно проверяет подтверждённые полномочия настройки;
обычные запуски CLI не требуют его. Бэкенд без этого объявления не может
создавать подтверждённые полномочия настройки CLI. Объявление bundled-package-tree указывает
точного владельца package.json и требует, чтобы точкой входа пакета была
команда. OpenClaw хеширует ограниченное полное дерево установленного пакета, включая
вложенные зависимости, и блокирует выполнение при перенаправляющих символических ссылках,
запускателях за пределами объявленного пакета, объявлениях обязательных внешних
зависимостей, слишком больших деревьях и неизвестных скриптах. Объявляйте это только тогда, когда
дерево содержит полную реализацию инференса; необязательные интеграции инструментов
не делают внешний граф реализации безопасным.
Если тот же бэкенд также поставляет самодостаточный нативный исполняемый файл, перечислите его
канонические базовые имена в nativeExecutableNames. Другие нативные команды остаются
неподтверждёнными, даже когда пользователь переопределяет команду бэкенда.
ctx.executionMode имеет значение "agent" для обычных циклов и "side-question" для
эфемерных вызовов /btw. Используйте его, когда CLI требуются другие одноразовые флаги,
например для отключения нативных инструментов, сохранения сеанса или возобновления работы
для BTW. Если у бэкенда обычно есть nativeToolMode: "always-on", но его
аргументы командной строки для побочного вопроса надёжно отключают эти инструменты, также задайте
sideQuestionToolMode: "disabled"; иначе OpenClaw блокирует выполнение, когда для BTW
требуется запуск CLI без инструментов.
Задавайте nativeToolMode: "selectable" только тогда, когда resolveExecutionArgs может отключить
все нативные инструменты бэкенда для отдельного запуска. Для таких ограниченных запусков
ctx.toolAvailability.native является пустым кортежем, а
ctx.toolAvailability.mcp — точным списком разрешённых MCP с изоляцией на стороне хоста. Хук
должен заменять конфликтующие флаги инструментов и возвращать аргументы командной строки, обеспечивающие оба значения;
OpenClaw вызывает его один раз с окончательными аргументами нового или возобновляемого запуска и блокирует выполнение, если
бэкенд не может обеспечить соблюдение ограничения. Имена MCP в этом контексте можно
безопасно подтверждать автоматически только потому, что хост уже ограничил создаваемую конфигурацию MCP
этими серверами и инструментами.
ownsNativeCompaction: отказ от Compaction OpenClaw
Если ваш бэкенд запускает агента, который выполняет Compaction собственной расшифровки, задайте
ownsNativeCompaction: true, чтобы защитный суммаризатор OpenClaw никогда не запускался
для его сеансов: жизненный цикл Compaction CLI ничего не делает, и
цикл продолжается. claude-cli объявляет это, поскольку Claude Code выполняет Compaction
внутренне, без конечной точки среды выполнения. Сеансы нативной среды выполнения, такие как Codex,
вместо этого продолжают направляться к конечной точке Compaction своей среды выполнения.
Объявляйте это, только если выполняются все следующие условия, иначе отложенный сеанс с превышенным бюджетом может остаться за пределами бюджета или устареть (OpenClaw больше не восстанавливает его):
- бэкенд надёжно выполняет Compaction или ограничивает собственную расшифровку по мере приближения к пределу контекстного окна;
- он сохраняет возобновляемый сеанс, чтобы состояние после Compaction сохранялось между циклами
(например,
--resume/--session-id); - это не сеанс Compaction нативной среды выполнения: соответствующие сеансы
agentHarnessIdвместо этого направляются к конечной точке среды выполнения.
Мост инструментов MCP
По умолчанию бэкенды CLI не получают инструменты OpenClaw. Если CLI может использовать конфигурацию MCP, включите эту возможность явно:
return { id: "acme-cli", bundleMcp: true, bundleMcpMode: "codex-config-overrides", config: { command: "acme", args: ["chat", "--json"], output: "json", },};Поддерживаемые режимы моста:
| Режим | Применение |
|---|---|
claude-config-file |
CLI, принимающие файл конфигурации MCP |
codex-config-overrides |
CLI, принимающие переопределения конфигурации в аргументах командной строки |
gemini-system-settings |
CLI, считывающие настройки MCP из каталога системных настроек |
Включайте мост только тогда, когда CLI действительно может его использовать. Если у CLI есть
собственный встроенный слой инструментов, который нельзя отключить, задайте nativeToolMode: "always-on", чтобы OpenClaw мог блокировать выполнение, когда вызывающей стороне требуется отсутствие нативных
инструментов. Если CLI может отключить все нативные инструменты для отдельного запуска, используйте "selectable" с
контрактом resolveExecutionArgs, описанным выше.
Пользовательская конфигурация
Пользователи могут переопределить любое значение бэкенда по умолчанию:
{ agents: { defaults: { cliBackends: { "acme-cli": { command: "/opt/acme/bin/acme", args: ["chat", "--json", "--profile", "work"], modelAliases: { large: "acme-large-2026", }, }, }, model: { primary: "openai/gpt-5.6-sol", fallbacks: ["acme-cli/large"], }, }, },}Документируйте минимальное переопределение, которое, вероятнее всего, потребуется пользователям, — обычно только
command, когда исполняемый файл находится за пределами PATH.
Проверка
Для встроенных плагинов добавьте целевой тест построителя и регистрации настройки, затем запустите целевой набор тестов плагина:
pnpm test extensions/acme-cliДля локальных или установленных плагинов проверьте обнаружение и один реальный запуск модели:
openclaw plugins inspect acme-cli --runtime --jsonopenclaw agent --message "reply exactly: backend ok" --model acme-cli/acme-largeЕсли бэкенд поддерживает изображения или MCP, добавьте проверочный запуск, подтверждающий эти пути с реальным CLI. Не полагайтесь на статическую проверку поведения запросов, изображений, MCP или возобновления сеанса.
Контрольный список
OPENCLAW_DOCS_MARKER:calloutOpen:Q2hlY2s
package.json содержит openclaw.extensions и собранные записи среды выполнения для опубликованных пакетов
OPENCLAW_DOCS_MARKER:calloutClose:
OPENCLAW_DOCS_MARKER:calloutOpen:Q2hlY2s
openclaw.plugin.json объявляет cliBackends и намеренно заданный activation.onStartup
OPENCLAW_DOCS_MARKER:calloutClose:
OPENCLAW_DOCS_MARKER:calloutOpen:Q2hlY2s
setup.cliBackends присутствует, когда настройка или обнаружение моделей должны видеть незапущенный бэкенд
OPENCLAW_DOCS_MARKER:calloutClose:
OPENCLAW_DOCS_MARKER:calloutOpen:Q2hlY2s
api.registerCliBackend(...) использует тот же идентификатор бэкенда, что и манифест
OPENCLAW_DOCS_MARKER:calloutClose:
OPENCLAW_DOCS_MARKER:calloutOpen:Q2hlY2s
Пользовательские переопределения в agents.defaults.cliBackends.<id> по-прежнему имеют приоритет
OPENCLAW_DOCS_MARKER:calloutClose: