Plugin SDK reference
Вспомогательные средства среды выполнения плагина
Справочник по объекту api.runtime, внедряемому в каждый плагин при регистрации. Используйте эти вспомогательные средства вместо прямого импорта внутренних компонентов хоста.
Пошаговое руководство по использованию этих вспомогательных средств в контексте плагинов каналов.
Пошаговое руководство по использованию этих вспомогательных средств в контексте плагинов провайдеров.
register(api) { const runtime = api.runtime;}api.runtime.version — текущая версия продукта OpenClaw, полученная из общего средства определения версии, поэтому плагины видят то же значение, которое сообщает CLI.
Загрузка и запись конфигурации
Предпочитайте конфигурацию, уже переданную в активный путь вызова, например api.config при регистрации или аргумент cfg в обратных вызовах канала или провайдера. Это позволяет использовать один снимок процесса на протяжении всей операции вместо повторного разбора конфигурации в часто выполняемых путях.
Используйте api.runtime.config.current() только тогда, когда долгоживущему обработчику нужен текущий снимок процесса, а конфигурация не была передана этой функции. Возвращаемое значение доступно только для чтения; перед редактированием клонируйте его или используйте вспомогательное средство изменения.
Фабрики инструментов получают ctx.runtimeConfig вместе с ctx.getRuntimeConfig(). Используйте функцию получения внутри обратного вызова execute долгоживущего инструмента, если конфигурация может измениться после создания определения инструмента.
Сохраняйте изменения с помощью api.runtime.config.mutateConfigFile(...) или api.runtime.config.replaceConfigFile(...). Для каждой записи необходимо выбрать явную политику afterWrite:
afterWrite: { mode: "auto" }позволяет планировщику перезагрузки Gateway принять решение.afterWrite: { mode: "restart", reason: "..." }принудительно выполняет чистый перезапуск, когда выполняющий запись компонент знает, что горячая перезагрузка небезопасна.afterWrite: { mode: "none", reason: "..." }подавляет автоматическую перезагрузку или перезапуск только тогда, когда вызывающая сторона отвечает за последующие действия.
Вспомогательные средства изменения возвращают afterWrite вместе с типизированной сводкой followUp, чтобы вызывающие стороны могли журналировать или проверять, запросили ли они перезапуск. Gateway по-прежнему определяет, когда этот перезапуск фактически произойдёт.
При прямом импорте из SDK предпочитайте специализированные подпути конфигурации общему совместимому модулю openclaw/plugin-sdk/config-runtime: config-contracts для типов, plugin-config-runtime для проверок уже загруженной конфигурации и поиска точки входа плагина, runtime-config-snapshot для текущих снимков процесса и config-mutation для записи. Тесты встроенных плагинов должны напрямую имитировать эти специализированные подпути вместо общего совместимого модуля.
Внутренний код среды выполнения OpenClaw следует тому же подходу: загружает конфигурацию один раз на границе CLI, Gateway или процесса, а затем передаёт это значение дальше. Успешная запись изменений обновляет снимок конфигурации среды выполнения процесса и увеличивает его внутреннюю ревизию; долгоживущие кеши должны использовать ключ кеша, принадлежащий среде выполнения, вместо локальной сериализации конфигурации. Для долгоживущих модулей среды выполнения действует сканер с нулевой терпимостью к фоновым вызовам loadConfig(); используйте переданный cfg, context.getRuntimeConfig() запроса или getRuntimeConfig() на явно заданной границе процесса.
Пути выполнения провайдера и канала должны использовать активный снимок конфигурации среды выполнения, а не снимок файла, возвращаемый для чтения или редактирования конфигурации. Снимки файлов сохраняют исходные значения, например маркеры SecretRef, для пользовательского интерфейса и записи; обратным вызовам провайдера требуется разрешённое представление среды выполнения. Если вспомогательное средство может вызываться как с активным исходным снимком, так и с активным снимком среды выполнения, перед чтением учётных данных направляйте вызов через selectApplicableRuntimeConfig().
Повторно используемые утилиты среды выполнения
Используйте входящие факты botLoopProtection для входящих сообщений, созданных ботами. Ядро применяет общую скользящую оконную защиту в памяти до записи сеанса и диспетчеризации, не привязывая политику к одному каналу. Защита отслеживает ключи (scopeId, conversationId, participant pair), совместно подсчитывает оба направления пары, применяет период ожидания после превышения лимита окна и при удобном случае удаляет неактивные записи.
Плагины каналов, предоставляющие операторам доступ к этому поведению, должны предпочитать общую структуру channels.defaults.botLoopProtection для базовых лимитов, а затем накладывать поверх неё переопределения, специфичные для канала или провайдера. Общая конфигурация использует секунды, поскольку она предназначена для пользователей:
type ChannelBotLoopProtectionConfig = { enabled?: boolean; maxEventsPerWindow?: number; windowSeconds?: number; cooldownSeconds?: number;};Передавайте нормализованные данные о паре ботов вместе с разрешённым ходом. Ядро определяет значения по умолчанию, преобразование единиц и семантику enabled:
return { channel: "example", routeSessionKey, storePath, ctxPayload, recordInboundSession, runDispatch, botLoopProtection: { scopeId: "account-1", conversationId: "channel-1", senderId: "bot-a", receiverId: "bot-b", config: channelConfig.botLoopProtection, defaultsConfig: runtimeConfig.channels?.defaults?.botLoopProtection, defaultEnabled: allowBotsMode !== "off", },};Используйте openclaw/plugin-sdk/pair-loop-guard-runtime напрямую только для пользовательских
двусторонних циклов событий, которые не проходят через общий обработчик входящих ответов.
Пространства имён среды выполнения
api.runtime.agent
Идентификация агента, каталоги и управление сеансами.
// Определить рабочий каталог агента (agentId обязателен)const agentDir = api.runtime.agent.resolveAgentDir(cfg, agentId); // Определить рабочее пространство агентаconst workspaceDir = api.runtime.agent.resolveAgentWorkspaceDir(cfg, agentId); // Получить идентификационные данные агентаconst identity = api.runtime.agent.resolveAgentIdentity(cfg); // Получить уровень рассуждения по умолчаниюconst thinking = api.runtime.agent.resolveThinkingDefault({ cfg, provider, model,}); // Проверить предоставленный пользователем уровень рассуждения по активному профилю провайдераconst policy = api.runtime.agent.resolveThinkingPolicy({ provider, model });const level = api.runtime.agent.normalizeThinkingLevel("extra high");if (level && policy.levels.some((entry) => entry.id === level)) { // передать уровень во встроенный запуск} // Получить время ожидания агентаconst timeoutMs = api.runtime.agent.resolveAgentTimeoutMs(cfg); // Убедиться, что рабочее пространство существуетawait api.runtime.agent.ensureAgentWorkspace(cfg); // Выполнить встроенный ход агентаconst result = await api.runtime.agent.runEmbeddedAgent({ sessionId: "my-plugin:task-1", runId: crypto.randomUUID(), workspaceDir: api.runtime.agent.resolveAgentWorkspaceDir(cfg, agentId), prompt: "Кратко изложите последние изменения", timeoutMs: api.runtime.agent.resolveAgentTimeoutMs(cfg),});runEmbeddedAgent(...) — нейтральное вспомогательное средство для запуска обычного хода агента OpenClaw из кода плагина. Оно использует те же механизмы определения провайдера и модели, а также выбора среды агента, что и ответы, инициированные каналом.
runEmbeddedPiAgent(...) сохраняется как устаревший псевдоним совместимости для существующих плагинов. В новом коде следует использовать runEmbeddedAgent(...).
resolveThinkingPolicy(...) возвращает поддерживаемые провайдером и моделью уровни рассуждения и необязательное значение по умолчанию. Плагины провайдеров управляют профилем конкретной модели через свои перехватчики рассуждения, поэтому плагины инструментов должны вызывать это вспомогательное средство среды выполнения вместо импорта или дублирования списков провайдера.
normalizeThinkingLevel(...) преобразует пользовательский текст, например on, x-high или extra high, в канонический сохраняемый уровень перед его проверкой по определённой политике.
Вспомогательные средства хранилища сеансов находятся в api.runtime.agent.session:
const entry = api.runtime.agent.session.getSessionEntry({ agentId, sessionKey });for (const { sessionKey, entry } of api.runtime.agent.session.listSessionEntries({ agentId })) { // Перебирать строки сеансов без зависимости от устаревшей структуры sessions.json.}await api.runtime.agent.session.patchSessionEntry({ agentId, sessionKey, update: (entry) => ({ thinkingLevel: "high" }),}); const created = await api.runtime.agent.session.createSessionEntry({ cfg, key: "agent:main:my-plugin:task-1", initialEntry: { agentHarnessId: "my-harness", modelSelectionLocked: true, pluginExtensions: { "my-plugin": { phase: "initializing" } }, }, afterCreate: async () => ({ pluginExtensions: { "my-plugin": { phase: "ready" } }, }),}); const storePath = api.runtime.agent.session.resolveStorePath(cfg.session?.store, { agentId });await api.runtime.agent.session.runWithWorkAdmission( { storePath, sessionKey }, async (signal) => { // Создать или обновить сеанс, затем передать signal в допущенный запуск агента. },);Для рабочих процессов сеансов предпочитайте getSessionEntry(...), listSessionEntries(...), patchSessionEntry(...) или upsertSessionEntry(...). Эти вспомогательные средства адресуют сеансы по идентификаторам агента и сеанса, чтобы плагины не зависели от устаревшей структуры хранения sessions.json. Используйте preserveActivity: true для изменений только метаданных, которые не должны обновлять активность сеанса, а replaceEntry: true — только когда обратный вызов возвращает полную запись и удалённые поля должны оставаться удалёнными. Пути диагностики и миграции могут сочетать fallbackEntry, skipMaintenance и requireWriteSuccess для одного атомарного исправления канонического хранилища.
createSessionEntry(...) создаёт новую каноническую строку сеанса и расшифровку. Его доверенная поверхность initialEntry намеренно ограничена: непустой agentHarnessId, необязательный modelSelectionLocked: true и необязательный pluginExtensions. Внедрённая среда выполнения принимает только идентификаторы сред, принадлежащих вызывающему плагину через registerAgentHarness(...); это инвариант владения, а не песочница между плагинами внутри одного процесса. Она отклоняет существующую строку; label и spawnedCwd являются отдельными полями создания, а не доверенными изменениями записи.
Во время создания блокировка изменений жизненного цикла сеанса удерживается через afterCreate, поэтому новая работа ожидает завершения инициализации, принадлежащей плагину, а наличие ранее допущенной работы приводит к сбою создания. Обратный вызов получает клон созданного состояния. Если он возвращает изменение, оно может содержать только pluginExtensions, а его значение представляет собой полное итоговое поле pluginExtensions. Сбой обратного вызова или окончательного сохранения откатывает неизменённую новую строку и расшифровку; защищённый откат сохраняет строку, изменённую или занятую параллельно. recoverMatchingInitialEntry: true предназначен только для повторной попытки прерванной инициализации, когда сохранённые доверенные поля точно совпадают, а для восстановления требуется, чтобы afterCreate вернул итоговое изменение.
Используйте runWithWorkAdmission(...), когда плагин начинает работу с сохранённым сеансом. Обратный вызов отклоняет архивированные или параллельно заменённые сеансы, обеспечивает координацию операций архивирования, сброса и удаления до завершения и получает AbortSignal, который необходимо передать запуску агента. Среда может явно указывать доверенных делегатов выполнения через своё экспериментальное поле регистрации delegatedExecutionPluginIds. Делегаты могут допускать и выполнять только точно соответствующий существующий сеанс с зафиксированной моделью; все изменения сеанса остаются доступны только владельцу среды. См. Плагины среды агента.
Плагины обслуживания и исправления могут использовать deleteSessionEntry(...) для одной записи сеанса в заданной области, cleanupSessionLifecycleArtifacts(...) для временных сеансов, принадлежащих жизненному циклу, и resolveSessionStoreBackupPaths(...) перед изменением хранилища. Это узкие поверхности исправления и управления жизненным циклом, а не универсальный API удаления хранилища.
resolveStorePath(...) и updateSessionStoreEntry(...) дополняют набор вспомогательных функций для сеансов: resolveStorePath определяет путь к хранилищу сеансов для заданной области, а updateSessionStoreEntry({ storePath, sessionKey, update }) напрямую изменяет одну запись по пути к хранилищу, если вызывающему коду он уже известен.
loadTranscriptEventsSync(...) доступна для синхронных процедур doctor и восстановления, которые не могут использовать асинхронную среду выполнения транскриптов. Она возвращает необработанные записи SessionStoreTranscriptEvent. В обычном коде среды выполнения плагина следует предпочитать openclaw/plugin-sdk/session-transcript-runtime.
formatSqliteSessionFileMarker(...), parseSqliteSessionFileMarker(...) и sqliteSessionFileMarkerMatchesSession(...) — переходные вспомогательные функции для кода, который всё ещё получает устаревшее поле с именем sessionFile. Разобранный маркер SQLite указывает на активный целевой транскрипт SQLite; это не путь в файловой системе. Новые API должны передавать типизированные данные идентификации сеанса вместо строковых маркеров.
Для чтения и записи транскриптов импортируйте openclaw/plugin-sdk/session-transcript-runtime и используйте resolveSessionTranscriptIdentity(...), resolveSessionTranscriptTarget(...), readSessionTranscriptEvents(...), readVisibleSessionTranscriptMessageEntries(...), appendSessionTranscriptMessageByIdentity(...), publishSessionTranscriptUpdateByIdentity(...) или withSessionTranscriptWriteLock(...) совместно с { agentId, sessionKey, sessionId }. Эти API позволяют плагинам идентифицировать транскрипт, читать необработанные события или видимые записи сообщений с учётом безопасных ветвей, добавлять сообщения, публиковать обновления и выполнять связанные операции под одной и той же блокировкой записи транскрипта, не завися от путей к файлам активных транскриптов. readVisibleSessionTranscriptMessageEntries(...) возвращает упорядоченные метаданные чтения; её поле seq не является курсором, с которого можно возобновить чтение.
Устаревшие вспомогательные функции для всего хранилища и файлов активных транскриптов больше не экспортируются из SDK плагинов. Используйте вспомогательные функции записей с областью действия для метаданных сеансов и вспомогательные функции идентификации транскриптов для операций с активными транскриптами. Процессы архивирования и поддержки, которым нужны файловые артефакты, должны использовать предназначенные для этого интерфейсы архивирования вместо API среды выполнения активных сеансов.
api.runtime.agent.defaults
Константы модели и провайдера по умолчанию:
const model = api.runtime.agent.defaults.model; // например, "gpt-5.6-sol"const provider = api.runtime.agent.defaults.provider; // например, "openai"api.runtime.llm
Выполняйте управляемое хостом дополнение текста, не импортируя внутренние компоненты провайдера и не дублируя подготовку модели, аутентификации и базового URL OpenClaw.
const result = await api.runtime.llm.complete({ messages: [{ role: "user", content: "Суммируй этот транскрипт." }], purpose: "my-plugin.summary", maxTokens: 512, temperature: 0.2,});Механизм оркестрации провайдера также может получить настроенный жизненный цикл локальной службы перед отправкой HTTP-запроса:
const lease = await api.runtime.llm.acquireLocalService( { providerId, baseUrl, headers, }, signal,);try { // Отправьте и полностью обработайте запрос провайдера.} finally { await lease?.release();}acquireLocalService(...) — стабильный универсальный контракт SDK
службы провайдера. Хост определяет конфигурацию процесса из
models.providers.<providerId>.localService; вызывающий код не может передавать
команду, аргументы, окружение или политику жизненного цикла. Запуск процесса,
проверка готовности, диагностика и политика остановки при простое остаются внутренними функциями хоста.
Передавайте точный идентификатор настроенного провайдера и определённый базовый URL запроса. Не
заменяйте псевдонимы идентификатором адаптера: разные псевдонимы могут указывать на разные
локальные хосты с GPU. Хост отклоняет конечные точки, которые не соответствуют настроенному
базовому URL провайдера, за исключением нормализации /v1, используемой адаптерами Ollama и LM
Studio. Хост управляет сериализацией запуска, проверками готовности,
арендой запросов, обработкой прерывания и завершением работы при простое.
Вспомогательная функция использует тот же путь подготовки простого дополнения, что и встроенная
среда выполнения OpenClaw, а также принадлежащий хосту снимок конфигурации среды выполнения. Механизмы контекста
получают привязанную к сеансу возможность llm.complete, поэтому вызовы модели используют
агента активного сеанса и не переходят незаметно к агенту по умолчанию. Результат
содержит сведения о провайдере, модели и агенте, а также нормализованные данные об использовании токенов,
кеша и расчётной стоимости, если они доступны.
api.runtime.gateway
Вызывайте другой метод Gateway внутри процесса, сохраняя доверенную идентичность среды выполнения текущего плагина. Это предназначено для встроенных или доверенных официальных плагинов, которые объединяют принадлежащие плагинам возможности Gateway без открытия локального WebSocket-соединения.
if (await api.runtime.gateway.isAvailable()) { const result = await api.runtime.gateway.request<{ callId: string }>( "voicecall.start", { to: "+15550001234", mode: "conversation" }, { timeoutMs: 60_000 }, );}Запросы используют область operator.write и не предоставляют область администратора. Вызовы из произвольных внешних
плагинов отклоняются. При сбое метода создаётся исключение GatewayClientRequestError с сохранением структурированных
details, метаданных повторной попытки и кода ошибки Gateway для процессов восстановления. Используйте isAvailable(),
прежде чем выбирать этот путь в инструментах, которые также могут работать в автономных процессах агента.
api.runtime.subagent
Запускайте фоновые выполнения субагентов и управляйте ими.
// Запуск выполнения субагентаconst { runId } = await api.runtime.subagent.run({ sessionKey: "agent:main:subagent:search-helper", message: "Преобразуй этот запрос в набор целевых уточняющих поисковых запросов.", provider: "openai", // необязательное переопределение model: "gpt-5.6-sol", // необязательное переопределение deliver: false,}); // Ожидание завершенияconst result = await api.runtime.subagent.waitForRun({ runId, timeoutMs: 30000 }); // Чтение сообщений сеансаconst { messages } = await api.runtime.subagent.getSessionMessages({ sessionKey: "agent:main:subagent:search-helper", limit: 10,}); // Удаление сеансаawait api.runtime.subagent.deleteSession({ sessionKey: "agent:main:subagent:search-helper",});deleteSession(...) может удалять сеансы, созданные тем же плагином через api.runtime.subagent.run(...). Для удаления произвольных сеансов пользователей или операторов по-прежнему требуется запрос Gateway с областью администратора.
api.runtime.nodes
Получайте список подключённых узлов и вызывайте команды узла-хоста из кода плагина, загруженного Gateway, или из CLI-команд плагина. Используйте это, когда плагин управляет локальной работой на сопряжённом устройстве, например мостом браузера или аудио на другом Mac.
const { nodes } = await api.runtime.nodes.list({ connected: true }); const result = await api.runtime.nodes.invoke({ nodeId: "mac-studio", command: "my-plugin.command", params: { action: "start" }, timeoutMs: 30000,});nodes.list(...) содержит объявленные каждым подключённым узлом
дескрипторы nodePluginTools, если этот узел предоставляет агенту инструменты
на основе плагинов или MCP. Эти дескрипторы отражают текущее состояние подключения: Gateway
удаляет их при отключении узла, а узел может заменить их через
node.pluginTools.update после изменения локального состава плагинов или MCP.
Внутри Gateway эта среда выполнения работает в процессе. В CLI-командах плагина она вызывает настроенный Gateway через RPC, поэтому такие команды, как openclaw googlemeet recover-tab, могут проверять сопряжённые узлы из терминала. Команды узлов по-прежнему проходят обычное сопряжение узлов Gateway, списки разрешённых команд, политики вызова узлов плагинами и локальную обработку команд на узлах.
Плагины, предоставляющие размещённые на узлах инструменты агента, могут задать agentTool.defaultPlatforms для безопасных команд, которые должны быть разрешены по умолчанию. Не указывайте его, если операторы должны явно разрешить команды с помощью gateway.nodes.allowCommands. Для опасных команд узла-хоста следует зарегистрировать политику вызова узла с помощью api.registerNodeInvokePolicy(...); политика выполняется в Gateway после проверки списка разрешённых команд и до передачи команды узлу, поэтому прямые вызовы node.invoke, размещённые на узлах инструменты плагинов и высокоуровневые инструменты плагинов используют единый путь применения ограничений.
api.runtime.tasks
Привязывайте состояние потока задач и выполнения задачи к существующему ключу сеанса OpenClaw или доверенному контексту инструмента.
api.runtime.tasks.managedFlowsподдерживает изменения: создание, продвижение и отмену потоков задач.api.runtime.tasks.flowsиapi.runtime.tasks.runs— доступные только для чтения представления DTO для получения списков и проверки состояния; оба предоставляютbindSession(...)/fromToolContext(...), а такжеget,list,findLatestиresolve.api.runtime.tasks.flow— устаревший псевдоним дляmanagedFlows.
Поток задач отслеживает долговременное состояние многоэтапного рабочего процесса. Это не планировщик:
используйте Cron или api.session.workflow.scheduleSessionTurn(...) для будущих
пробуждений, а затем вызывайте managedFlows из запланированного хода, когда для этой работы
требуется состояние потока, дочерние задачи, ожидание или отмена.
const taskFlow = api.runtime.tasks.managedFlows.fromToolContext(ctx); const created = taskFlow.createManaged({ controllerId: "my-plugin/review-batch", goal: "Проверить новые запросы на слияние",}); const child = taskFlow.runTask({ flowId: created.flowId, runtime: "acp", childSessionKey: "agent:main:subagent:reviewer", task: "Проверить PR #123", status: "running", startedAt: Date.now(),}); const waiting = taskFlow.setWaiting({ flowId: created.flowId, expectedRevision: created.revision, currentStep: "await-human-reply", waitJson: { kind: "reply", channel: "telegram" },});Используйте bindSession({ sessionKey, requesterOrigin }), если у вас уже есть доверенный ключ сеанса OpenClaw из собственного уровня привязки. Не выполняйте привязку на основе необработанного пользовательского ввода.
api.runtime.tts
Синтез речи из текста.
// Стандартный TTSconst clip = await api.runtime.tts.textToSpeech({ text: "Привет от OpenClaw", cfg: api.config,}); // TTS, оптимизированный для телефонииconst telephonyClip = await api.runtime.tts.textToSpeechTelephony({ text: "Привет от OpenClaw", cfg: api.config,}); // Список доступных голосовconst voices = await api.runtime.tts.listVoices({ provider: "elevenlabs", cfg: api.config,});Использует основную конфигурацию messages.tts и выбор провайдера. Возвращает аудиобуфер PCM и частоту дискретизации. textToSpeechStream также доступна для потокового синтеза.
api.runtime.mediaUnderstanding
Анализ изображений, аудио и видео.
// Описать изображениеconst image = await api.runtime.mediaUnderstanding.describeImageFile({ filePath: "/tmp/inbound-photo.jpg", cfg: api.config, agentDir: "/tmp/agent",}); // Транскрибировать аудиоconst { text } = await api.runtime.mediaUnderstanding.transcribeAudioFile({ filePath: "/tmp/inbound-audio.ogg", cfg: api.config, mime: "audio/ogg", // необязательно, если MIME невозможно определить}); // Описать видеоconst video = await api.runtime.mediaUnderstanding.describeVideoFile({ filePath: "/tmp/inbound-video.mp4", cfg: api.config,}); // Универсальный анализ файлаconst result = await api.runtime.mediaUnderstanding.runFile({ filePath: "/tmp/inbound-file.pdf", cfg: api.config,}); // Структурированное извлечение данных из изображения с помощью конкретного провайдера и модели.// Укажите хотя бы одно изображение; текстовые входные данные служат дополнительным контекстом.const evidence = await api.runtime.mediaUnderstanding.extractStructuredWithModel({ provider: "codex", model: "gpt-5.6-sol", input: [ { type: "image", buffer: receiptImageBuffer, fileName: "receipt.png", mime: "image/png", }, { type: "text", text: "Предпочитать напечатанную итоговую сумму рукописным примечаниям." }, ], instructions: "Извлечь продавца, итоговую сумму и теги для поиска.", schemaName: "receipt.evidence", jsonSchema: { type: "object", properties: { vendor: { type: "string" }, total: { type: "number" }, tags: { type: "array", items: { type: "string" } }, }, required: ["vendor", "total"], }, cfg: api.config,});Возвращает { text: undefined }, если выходные данные не созданы (например, входные данные были пропущены).
describeImageFileWithModel(...) описывает уже известное изображение с помощью конкретного провайдера и модели, обходя стандартное определение активной модели, которое использует describeImageFile(...).
api.runtime.imageGeneration
Генерация изображений.
const result = await api.runtime.imageGeneration.generate({ prompt: "Робот рисует закат", cfg: api.config,}); const providers = api.runtime.imageGeneration.listProviders({ cfg: api.config });api.runtime.videoGeneration
Генерация видео с интерфейсом, аналогичным генерации изображений.
const result = await api.runtime.videoGeneration.generate({ prompt: "Съёмка с дрона, летящего над побережьем на рассвете", cfg: api.config,}); const providers = api.runtime.videoGeneration.listProviders({ cfg: api.config });api.runtime.musicGeneration
Генерация музыки с интерфейсом, аналогичным генерации изображений.
const result = await api.runtime.musicGeneration.generate({ prompt: "Бодрая композиция в стиле lo-fi для сеанса программирования", cfg: api.config,}); const providers = api.runtime.musicGeneration.listProviders({ cfg: api.config });api.runtime.webSearch
Веб-поиск.
const providers = api.runtime.webSearch.listProviders({ config: api.config }); const result = await api.runtime.webSearch.search({ config: api.config, args: { query: "SDK плагинов OpenClaw", count: 5 },});api.runtime.media
Низкоуровневые утилиты для работы с медиафайлами.
const webMedia = await api.runtime.media.loadWebMedia(url);const mime = await api.runtime.media.detectMime(buffer);const kind = api.runtime.media.mediaKindFromMime("image/jpeg"); // "изображение"const isVoice = api.runtime.media.isVoiceCompatibleAudio(filePath);const metadata = await api.runtime.media.getImageMetadata(filePath);const resized = await api.runtime.media.resizeToJpeg(buffer, { maxWidth: 800 });const terminalQr = await api.runtime.media.renderQrTerminal("https://openclaw.ai");const pngQr = await api.runtime.media.renderQrPngBase64("https://openclaw.ai", { scale: 6, // 1-12 marginModules: 4, // 0-16});const pngQrDataUrl = await api.runtime.media.renderQrPngDataUrl("https://openclaw.ai");const tmpRoot = resolvePreferredOpenClawTmpDir();const pngQrFile = await api.runtime.media.writeQrPngTempFile("https://openclaw.ai", { tmpRoot, dirPrefix: "my-plugin-qr-", fileName: "qr.png",});api.runtime.config
Текущий снимок конфигурации среды выполнения и транзакционная запись конфигурации. Предпочитайте
конфигурацию, уже переданную в активный путь вызова; используйте
current() только тогда, когда обработчику требуется непосредственно снимок процесса.
const cfg = api.runtime.config.current();await api.runtime.config.mutateConfigFile({ afterWrite: { mode: "auto" }, mutate(draft) { draft.plugins ??= {}; },});mutateConfigFile(...) и replaceConfigFile(...) возвращают значение followUp,
например { mode: "restart", requiresRestart: true, reason },
которое фиксирует намерение записывающего компонента, не передавая ему от
Gateway управление перезапуском.
api.runtime.system
Утилиты системного уровня.
await api.runtime.system.enqueueSystemEvent(event);api.runtime.system.requestHeartbeat({ source: "other", intent: "event", reason: "plugin-event",});api.runtime.system.requestHeartbeatNow({ reason: "plugin-event" }); // Устаревший псевдоним совместимости.const heartbeatResult = await api.runtime.system.runHeartbeatOnce({ reason: "plugin-triggered-check",});const output = await api.runtime.system.runCommandWithTimeout(cmd, args, opts);const hint = api.runtime.system.formatNativeDependencyHint(pkg);runHeartbeatOnce(...) немедленно запускает один цикл Heartbeat в обход обычного таймера объединения. Передайте { heartbeat: { target: "last" } }, чтобы принудительно доставить сообщение в последний активный канал вместо стандартного подавления target: "none".
runCommandWithTimeout(...) возвращает перехваченные stdout и stderr, необязательные
счётчики усечения, code, signal, killed, termination и
noOutputTimedOut. Результаты тайм-аута и тайм-аута отсутствия вывода содержат code: 124,
если дочерний процесс не предоставляет ненулевой код завершения. Завершение
по сигналу без тайм-аута также может вернуть code: null, поэтому используйте termination и
noOutputTimedOut, чтобы различать причины тайм-аута.
api.runtime.events
Подписки на события.
api.runtime.events.onAgentEvent((event) => { /* ... */});api.runtime.events.onSessionTranscriptUpdate((update) => { /* ... */});api.runtime.logging
Ведение журналов.
const verbose = api.runtime.logging.shouldLogVerbose();const childLogger = api.runtime.logging.getChildLogger({ plugin: "my-plugin" }, { level: "debug" });api.runtime.modelAuth
Определение аутентификации модели и провайдера.
const auth = await api.runtime.modelAuth.getApiKeyForModel({ model, cfg }); // Готовая к запросу аутентификация, включая обмены в среде выполнения провайдера (например, обновление OAuth)const runtimeAuth = await api.runtime.modelAuth.getRuntimeAuthForModel({ model, cfg }); const providerAuth = await api.runtime.modelAuth.resolveApiKeyForProvider({ provider: "openai", cfg,});api.runtime.state
Определение каталога состояния и хранилище по ключам на основе SQLite.
const stateDir = api.runtime.state.resolveStateDir(process.env);const store = api.runtime.state.openKeyedStore<MyRecord>({ namespace: "my-feature", maxEntries: 200, defaultTtlMs: 15 * 60_000,}); await store.register("key-1", { value: "hello" });const claimed = await store.registerIfAbsent("dedupe-key", { value: "first" });const value = await store.lookup("key-1");await store.consume("key-1");await store.clear();Хранилища по ключам сохраняются после перезапусков и изолируются по идентификатору плагина, привязанному к среде выполнения. Используйте registerIfAbsent(...) для атомарного резервирования при дедупликации: он возвращает true, если ключ отсутствовал или истёк и был зарегистрирован, либо false, если актуальное значение уже существует, не перезаписывая его значение, время создания или TTL. Ограничения: maxEntries на пространство имён, 50,000 актуальных строк на плагин, значения JSON размером менее 64KB и необязательное истечение TTL. По умолчанию запись при достижении любого из ограничений на количество строк удаляет самые старые актуальные строки из записываемого пространства имён; соседние пространства имён при этой записи не вытесняются, а запись всё равно завершается ошибкой, если пространство имён не может освободить достаточно строк. Установите overflowPolicy: "reject-new" для долговременных записей владения, которые нельзя вытеснять: новые ключи завершаются ошибкой при достижении любого ограничения, а существующие ключи по-прежнему можно обновлять.
openSyncKeyedStore<T>(...) возвращает хранилище той же структуры с синхронными методами (register, registerIfAbsent, lookup, consume, clear возвращают значения непосредственно, а не промисы) для вызывающих компонентов, которые не могут использовать ожидание.
openChannelIngressQueue<TPayload>(...) открывает сохраняемую очередь входящих данных, ограниченную вызывающим плагином, для буферизации входящих событий, которым требуется обработка с гарантией не менее одного раза после перезапусков. Если восстановление устаревшего резервирования использует shouldRecover, также укажите shouldRecoverCorrupt, если повреждённые зарезервированные полезные данные следует поместить в карантин: его не зависящий от полезных данных идентификатор резервирования позволяет плагину сохранить действующую политику владельца и полосы до того, как очередь пометит строку как удалённую.
api.runtime.channel
Вспомогательные функции среды выполнения для конкретных каналов (доступны, когда загружен плагин канала). Сгруппированы по назначению:
| Группа | Назначение |
|---|---|
text |
Разбиение на фрагменты (chunkText, chunkMarkdownText, resolveChunkMode), обнаружение управляющих команд, преобразование таблиц Markdown. |
reply |
Отправка ответов буферизованными блоками, форматирование конвертов, определение эффективной конфигурации сообщений и задержки, имитирующей действия человека. |
routing |
buildAgentSessionKey, resolveAgentRoute. |
pairing |
buildPairingReply, чтение списков разрешений, вставка или обновление запросов на сопряжение. |
media |
Удалённая загрузка и сохранение медиафайлов (см. ниже). |
activity |
Запись и чтение последней активности канала. |
session |
Метаданные сеанса из входящих событий, обновление последнего маршрута. |
mentions |
Вспомогательные функции политики упоминаний (см. ниже). |
reactions |
Дескрипторы реакций-подтверждений для индикаторов выполняющейся обработки. |
groups |
Определение групповой политики и требования упоминания. |
debounce |
Устранение дребезга входящих сообщений. |
commands |
Авторизация команд и управление доступностью текстовых команд. |
outbound |
Загрузка адаптера исходящих сообщений канала. |
inbound |
Формирование контекста входящего события и запуск общего ядра обработки входящих событий и ответов. |
threadBindings |
Настройка тайм-аута бездействия и максимального возраста для привязанных веток сеансов. |
runtimeContexts |
Регистрация, чтение и отслеживание локального для процесса контекста по каналам, учётным записям и возможностям. |
api.runtime.channel.media — предпочтительный интерфейс для загрузки и хранения медиафайлов каналов:
const saved = await api.runtime.channel.media.saveRemoteMedia({ url, subdir: "inbound", maxBytes, filePathHint: fileName,});Используйте saveRemoteMedia(...), когда удалённый URL требуется преобразовать в медиафайл OpenClaw. Используйте saveResponseMedia(...), когда плагин уже получил Response с собственной обработкой аутентификации, перенаправлений или списка разрешений. Используйте readRemoteMediaBuffer(...), только когда плагину нужны необработанные байты для проверки, преобразования, расшифровки или повторной отправки. fetchRemoteMedia(...) остаётся устаревшим псевдонимом совместимости для readRemoteMediaBuffer(...).
api.runtime.channel.mentions — это общая поверхность политики входящих упоминаний для встроенных плагинов каналов, использующих внедрение среды выполнения:
const mentionMatch = api.runtime.channel.mentions.matchesMentionWithExplicit(text, { mentionRegexes, mentionPatterns,}); const decision = api.runtime.channel.mentions.resolveInboundMentionDecision({ facts: { canDetectMention: true, wasMentioned: mentionMatch.matched, implicitMentionKinds: api.runtime.channel.mentions.implicitMentionKindWhen( "reply_to_bot", isReplyToBot, ), }, policy: { isGroup, requireMention, allowTextCommands, hasControlCommand, commandAuthorized, },});Доступные вспомогательные функции для упоминаний:
buildMentionRegexesmatchesMentionPatternsmatchesMentionWithExplicitimplicitMentionKindWhenresolveInboundMentionDecision
api.runtime.channel.mentions намеренно не предоставляет устаревшие вспомогательные функции совместимости resolveMentionGating*. Предпочитайте нормализованный путь { facts, policy }.
Несколько полей в reply, session и inbound содержат относящиеся к отдельным полям примечания @deprecated, указывающие на текущее ядро обработки хода канала или адаптеры исходящих сообщений канала; прежде чем создавать новый код на основе конкретной вспомогательной функции, ознакомьтесь с её встроенной документацией JSDoc.
Хранение ссылок на среду выполнения
Используйте createPluginRuntimeStore, чтобы сохранить ссылку на среду выполнения для использования вне обратного вызова register:
Создайте хранилище
import { createPluginRuntimeStore } from "openclaw/plugin-sdk/runtime-store";import type { PluginRuntime } from "openclaw/plugin-sdk/runtime-store"; const store = createPluginRuntimeStore<PluginRuntime>({ pluginId: "my-plugin", errorMessage: "my-plugin runtime not initialized",});Подключите к точке входа
export default defineChannelPluginEntry({ id: "my-plugin", name: "My Plugin", description: "Example", plugin: myPlugin, setRuntime: store.setRuntime,});Получите доступ из других файлов
export function getRuntime() { return store.getRuntime(); // throws if not initialized} export function tryGetRuntime() { return store.tryGetRuntime(); // returns null if not initialized}Другие поля верхнего уровня api
Помимо api.runtime, объект API также предоставляет:
api.idstringИдентификатор плагина.
api.namestringОтображаемое имя плагина.
api.configOpenClawConfigТекущий снимок конфигурации (активный снимок среды выполнения в памяти, если доступен).
OPENCLAW_DOCS_MARKER:paramOpen:IHBhdGg9ImFwaS5wbHVnaW5Db25maWciIHR5cGU9IlJlY29yZDxzdHJpbmcsIHVua25vd24
">
Конфигурация плагина из plugins.entries.<id>.config.
api.loggerPluginLoggerРегистратор с ограниченной областью действия (debug, info, warn, error).
api.registrationModePluginRegistrationModeТекущий режим загрузки: "full" (активация в реальном времени), "discovery" / "tool-discovery" (обнаружение возможностей только для чтения), "setup-only" (облегчённая точка входа настройки), "setup-runtime" (процесс настройки, которому также требуется точка входа канала среды выполнения) или "cli-metadata" (сбор метаданных команд CLI).
api.resolvePath(input)"(string)Связанные материалы
- Внутреннее устройство плагинов — модель возможностей и реестр
- Точки входа SDK — параметры
definePluginEntry - Обзор SDK — справочник по подпутям