Как собрать

Async SQLite в OpenClaw: миграция плагина до 31 декабря 2026

Порядок перевода плагина OpenClaw на асинхронные вызовы SQLite SDK: какие менять, что остаётся синхронным и когда придёт удаление.

· 4 мин чтения

Коротко

  • Синхронные SQLite-вызовы сессий поддерживаются до 31 декабря 2026 — это финальный день совместимости.
  • Заменяйте вызов на Async-версию с теми же аргументами и ждите результата перед чтением или внешним эффектом.
  • Фабрики, возвращающие адаптеры и подготовленные объекты чтения, могут оставаться синхронными. await нужен на операциях возвращённого объекта.

Сверено с документацией OpenClaw 2026.10.10, 3 ноября 2026.

Синхронные вызовы SQLite SDK в плагине OpenClaw уберут в первом стабильном релизе января 2027, без мажора Plugin SDK. Ниже порядок миграции: какие вызовы заменять, где брать исторический ключ транскрипта и что проверить до дедлайна.

Что нужно заранее

  • В документации 2026.10.10 есть устаревшие адаптеры и асинхронные замены для сессий, транскриптов и профилей авторизации.
  • Определите, какие подпути использует плагин: session-store-runtime, channel-inbound, provider-auth, agent-sessions.
  • Внешние плагины объявляют версию хоста, которая даёт нужные возможности. Встроенные плагины ориентируются на текущий хост.
  • Дедлайн общий для всех семейств вызовов: 31 декабря 2026.

Что уходит: сессии, транскрипты, записи

Документация сводит замены в таблицы «Before / After». Для чтений сессий добавьте await перед результатом и перейдите на Async-версию там, где она есть.

const entry = await api.runtime.agent.session.getSessionEntryAsync(target);
  • getConversationSession → await getConversationSessionAsync(...).
  • listSessionEntries → await listSessionEntriesAsync(...).
  • loadTranscriptEventsSync → await loadTranscriptEvents(...).
  • readTranscriptStatsSync → await readTranscriptStatsAsync(...).
  • statSessionEntrySync → await statSessionEntry(...).
  • readSessionUpdatedAt → await readSessionUpdatedAtAsync(...).

Записи сессий переводятся на подготовку владельцем или уже готовый патч. Колбэк, зависящий от сохранённой записи, заменяется на prepare.

await prepareSessionEntryPatch({ ...target, prepare: choosePatch });
  • updateLastRoute с assertCommitAllowed → await updateLastRouteWithAuthority(...).
  • upsertSessionUpstreamLink → await upsertSessionUpstreamLinkAsync(...).
  • deleteSessionUpstreamLink → await deleteSessionUpstreamLinkAsync(...).

Профили авторизации переезжают на публичный подпуть provider-auth. У AuthStorage асинхронными стали и получение хранилища, и сам доступ.

const auth = await AuthStorage.forAgentAsync(agentDir, config);
await auth.setAsync(providerId, credential);

Исторический ключ транскрипта

Транскрипт принадлежит конкретной сессии, и после сброса у неё остаются старые окна. Их владельца находит отдельная асинхронная функция из session-store-runtime.

import { resolveTranscriptSessionKeyBySessionIdAsync } from "openclaw/plugin-sdk/session-store-runtime";

const sessionKey = await resolveTranscriptSessionKeyBySessionIdAsync({
  agentId,
  sessionId,
  storePath,
});
  • Функция возвращает Promise<string | undefined> и принимает те же поля agentId, env, sessionId, storePath, что и синхронный хелпер.
  • Передавайте storePath, когда транскрипт лежит в настроенном или общем хранилище.
  • Отсутствующая база или неизвестная идентичность дают undefined, при этом база не создаётся.
  • getSessionEntryByIdAsync(...).sessionKey не заменяет исторический поиск: он читает текущие записи сессий.
  • Авторизацию на раскрытие транскрипта вызывающий код сохраняет на прежнем месте.

Граница миграции

  • Фабрики, возвращающие адаптеры или подготовленные объекты чтения, могут оставаться синхронными. await добавляется на операциях возвращённого объекта.
  • Обёртка, возвращающая Promise, над нативным колбэком базы всё равно выполняет колбэк в потоке вызывающего кода. Менять нужно контракт колбэка, а не только место вызова.
  • listSessionEntriesAsync возвращает проекцию метаданных только для чтения, без отсоединённых снапшотов и опций readOnly, snapshot-hydration, source-capture. Для полной публичной записи берётся getSessionEntryAsync.
  • Конверт входящего сообщения готовят один раз на сообщение. Билдер возвращает синхронный форматтер с телом строки, а путь хранилища берётся через runtime.channel.session.resolveStorePath.
  • Для своего форматирования дождитесь readSessionUpdatedAtAsync один раз и передайте метку времени в форматтер вместо колбэка, читающего базу.

Порядок работ

  1. Пройдите по семействам session-store-runtime и channel-inbound, выпишите синхронные вызовы.
  2. Переведите чтения на Async-версии и добавьте await перед чтением результата.
  3. Переведите записи на prepareSessionEntryPatch и applySessionEntryPatch, дождитесь завершения записи до публикации внешнего эффекта.
  4. Замените resolveTranscriptSessionKeyBySessionId на resolveTranscriptSessionKeyBySessionIdAsync.
  5. Проверьте фабрики: они могут остаться синхронными, await добавьте на операциях объекта.
  6. Замените вызовы forAgent, set, reload, remove, logout в AuthStorage на Async-варианты.
  7. Сверьте даты: 31 декабря 2026 — финальный день совместимости.

Как проверить

  • Синхронные методы сессий предупреждают один раз за метод на процесс.
  • Запись завершается до чтения: результат асинхронного вызова доступен сразу после await.
  • Исторический ключ находится через resolveTranscriptSessionKeyBySessionIdAsync и возвращает строку для известной сессии.

Если что-то пошло не так

  • Операция с await упала. Не повторяйте её через устаревший синхронный путь.
  • Хост не знает buildSystemPromptHintAsync. Сообщите о требовании обновления, а не делайте синхронное чтение базы.
const prepareHint = api.runtime.tts.buildSystemPromptHintAsync;
if (!prepareHint) {
  throw new Error("Update OpenClaw to use async TTS prompt preparation.");
}
  • resolveTranscriptSessionKeyBySessionIdAsync вернул undefined: базы нет или идентичность неизвестна. База при этом не создаётся.
  • Цели, привязанные к актору, и цели инкогнито отклоняют синхронный доступ к базе. Такие вызовы переводятся на путь с await.
  • Синхронный resolveTranscriptSessionKeyBySessionId пока доступен как устаревший адаптер и печатает ограниченное предупреждение с указанием замены.
  • После 31 декабря 2026 устаревшие адаптеры уберут.