Сессии и память

Инструменты сессий

Цель: небольшой, устойчивый к неправильному использованию набор инструментов, чтобы агенты могли выводить список сессий, получать историю и отправлять сообщения в другую сессию.

Названия инструментов

  • sessions_list
  • sessions_history
  • sessions_send
  • sessions_spawn

Ключевая модель

  • Основное прямое чат-хранилище всегда имеет буквальный ключ "main" (разрешается в основной ключ текущего агента).
  • Групповые чаты используют agent:<agentId>:<channel>:group:<id> или agent:<agentId>:<channel>:channel:<id> (передавайте полный ключ).
  • Cron-задачи используют cron:<job.id>.
  • Хуки используют hook:<uuid>, если не задано явно.
  • Сессии узлов используют node-<nodeId>, если не задано явно.

global и unknown являются зарезервированными значениями и никогда не отображаются в списках. Если session.scope = "global", мы псевдонимизируем его в main для всех инструментов, чтобы вызывающие стороны никогда не видели global.

sessions_list

Выводит список сессий в виде массива строк. Параметры:

  • kinds?: string[] фильтр: любой из "main" | "group" | "cron" | "hook" | "node" | "other"
  • limit?: number максимальное количество строк (по умолчанию: серверное значение по умолчанию, с ограничением, например, 200)
  • activeMinutes?: number только сессии, обновленные в течение N минут
  • messageLimit?: number 0 = без сообщений (по умолчанию 0); >0 = включить последние N сообщений

Поведение:

  • messageLimit > 0 получает chat.history для каждой сессии и включает последние N сообщений.
  • Результаты инструментов фильтруются в выводе списка; для сообщений инструментов используйте sessions_history.
  • При работе в песочничной сессии агента инструменты сессий по умолчанию используют видимость только созданных сессий (см. ниже).

Формат строки (JSON):

  • key: ключ сессии (строка)
  • kind: main | group | cron | hook | node | other
  • channel: whatsapp | telegram | discord | signal | imessage | webchat | internal | unknown
  • displayName (отображаемая метка группы, если доступна)
  • updatedAt (мс)
  • sessionId
  • model, contextTokens, totalTokens
  • thinkingLevel, verboseLevel, systemSent, abortedLastRun
  • sendPolicy (переопределение для сессии, если задано)
  • lastChannel, lastTo
  • deliveryContext (нормализованный { channel, to, accountId }, когда доступен)
  • transcriptPath (путь, полученный с наилучшими усилиями из директории хранилища + sessionId)
  • messages? (только при messageLimit > 0)

sessions_history

Получает транскрипт для одной сессии. Параметры:

  • sessionKey (обязательный; принимает ключ сессии или sessionId из sessions_list)
  • limit?: number максимальное количество сообщений (сервер ограничивает)
  • includeTools?: boolean (по умолчанию false)

Поведение:

  • includeTools=false фильтрует сообщения с role: "toolResult".
  • Возвращает массив сообщений в сыром формате транскрипта.
  • При передаче sessionId OpenClaw разрешает его в соответствующий ключ сессии (отсутствующие идентификаторы вызывают ошибку).

sessions_send

Отправляет сообщение в другую сессию. Параметры:

  • sessionKey (обязательный; принимает ключ сессии или sessionId из sessions_list)
  • message (обязательный)
  • timeoutSeconds?: number (по умолчанию >0; 0 = отправить и забыть)

Поведение:

  • timeoutSeconds = 0: ставит в очередь и возвращает { runId, status: "accepted" }.
  • timeoutSeconds > 0: ожидает до N секунд завершения, затем возвращает { runId, status: "ok", reply }.
  • Если время ожидания истекло: { runId, status: "timeout", error }. Выполнение продолжается; вызовите sessions_history позже.
  • Если выполнение завершилось с ошибкой: { runId, status: "error", error }.
  • Объявление о доставке запускается после завершения основного выполнения и является попыткой с наилучшими усилиями; status: "ok" не гарантирует доставку объявления.
  • Ожидание происходит через шлюз agent.wait (на стороне сервера), чтобы переподключения не прерывали ожидание.
  • Контекст сообщения агент-агент внедряется для основного выполнения.
  • Межсессионные сообщения сохраняются с message.provenance.kind = "inter_session", чтобы читатели транскриптов могли отличать маршрутизированные инструкции агента от внешнего пользовательского ввода.
  • После завершения основного выполнения OpenClaw запускает цикл ответов:
    • Раунды 2+ чередуются между агентом-инициатором и целевым агентом.
    • Ответьте точно REPLY_SKIP, чтобы остановить пинг-понг.
    • Максимальное количество ходов — session.agentToAgent.maxPingPongTurns (0–5, по умолчанию 5).
  • После завершения цикла OpenClaw запускает шаг объявления агент-агент (только для целевого агента):
    • Ответьте точно ANNOUNCE_SKIP, чтобы остаться в тишине.
    • Любой другой ответ отправляется в целевой канал.
    • Шаг объявления включает исходный запрос + ответ первого раунда + последний ответ пинг-понга.

Поле Channel

  • Для групп channel — это канал, записанный в записи сессии.
  • Для прямых чатов channel определяется из lastChannel.
  • Для cron/hook/node channel — это internal.
  • Если отсутствует, channelunknown.

Безопасность / Политика отправки

Блокировка на основе политики по каналу/типу чата (не по идентификатору сессии).

{
  "session": {
    "sendPolicy": {
      "rules": [
        {
          "match": { "channel": "discord", "chatType": "group" },
          "action": "deny"
        }
      ],
      "default": "allow"
    }
  }
}

Переопределение во время выполнения (для каждой записи сессии):

  • sendPolicy: "allow" | "deny" (не задано = наследовать из конфигурации)
  • Устанавливается через sessions.patch или только для владельца через /send on|off|inherit (отдельное сообщение).

Точки применения:

  • chat.send / agent (шлюз)
  • логика доставки автоответов

sessions_spawn

Создает выполнение под-агента в изолированной сессии и объявляет результат обратно в канал чата инициатора. Параметры:

  • task (обязательный)
  • label? (опционально; используется для логов/UI)
  • agentId? (опционально; создать под другим идентификатором агента, если разрешено)
  • model? (опционально; переопределяет модель под-агента; неверные значения вызывают ошибку)
  • thinking? (опционально; переопределяет уровень мышления для выполнения под-агента)
  • runTimeoutSeconds? (по умолчанию agents.defaults.subagents.runTimeoutSeconds, если задано, иначе 0; если задано, прерывает выполнение под-агента через N секунд)
  • thread? (по умолчанию false; запросить привязку маршрутизации к ветке для этого создания, когда поддерживается каналом/плагином)
  • mode? (run|session; по умолчанию run, но по умолчанию session при thread=true; mode="session" требует thread=true)
  • cleanup? (delete|keep, по умолчанию keep)
  • sandbox? (inherit|require, по умолчанию inherit; require отклоняет создание, если целевая дочерняя среда выполнения не является песочничной)
  • attachments? (опциональный массив встроенных файлов; только для среды выполнения под-агента, ACP отклоняет). Каждая запись: { name, content, encoding?: "utf8" | "base64", mimeType? }. Файлы материализуются в рабочей области потомка по пути .openclaw/attachments/<uuid>/. Возвращает квитанцию с sha256 для каждого файла.
  • attachAs? (опционально; { mountPath? } подсказка, зарезервированная для будущих реализаций монтирования)

Белый список:

  • agents.list[].subagents.allowAgents: список идентификаторов агентов, разрешенных через agentId (["*"] для разрешения любых). По умолчанию: только агент-инициатор.
  • Защита наследования песочницы: если сессия инициатора является песочничной, sessions_spawn отклоняет цели, которые будут выполняться вне песочницы.

Обнаружение:

  • Используйте agents_list, чтобы узнать, какие идентификаторы агентов разрешены для sessions_spawn.

Поведение:

  • Запускает новую сессию agent:<agentId>:subagent:<uuid> с deliver: false.
  • Под-агенты по умолчанию имеют полный набор инструментов минус инструменты сессий (настраивается через tools.subagents.tools).
  • Под-агентам запрещено вызывать sessions_spawn (без создания под-агента → под-агента).
  • Всегда неблокирующий: немедленно возвращает { status: "accepted", runId, childSessionKey }.
  • При thread=true плагины каналов могут привязывать доставку/маршрутизацию к цели ветки (поддержка Discord контролируется session.threadBindings.* и channels.discord.threadBindings.*).
  • После завершения OpenClaw запускает шаг объявления под-агента и публикует результат в канал чата инициатора.
    • Если финальный ответ помощника пуст, последний toolResult из истории под-агента включается как Result.
  • Ответьте точно ANNOUNCE_SKIP во время шага объявления, чтобы остаться в тишине.
  • Ответы объявления нормализуются в Status/Result/Notes; Status берется из результата выполнения среды (не из текста модели).
  • Сессии под-агентов автоматически архивируются через agents.defaults.subagents.archiveAfterMinutes (по умолчанию: 60).
  • Ответы объявления включают строку статистики (время выполнения, токены, sessionKey/sessionId, путь к транскрипту и опционально стоимость).

Видимость сессий в песочнице

Инструменты сессий могут быть ограничены по области видимости, чтобы уменьшить доступ между сессиями. Поведение по умолчанию:

  • tools.sessions.visibility по умолчанию tree (текущая сессия + созданные сессии под-агентов).
  • Для песочничных сессий agents.defaults.sandbox.sessionToolsVisibility может жестко ограничивать видимость.

Конфигурация:

{
  tools: {
    sessions: {
      // "self" | "tree" | "agent" | "all"
      // default: "tree"
      visibility: "tree",
    },
  },
  agents: {
    defaults: {
      sandbox: {
        // default: "spawned"
        sessionToolsVisibility: "spawned", // or "all"
      },
    },
  },
}

Примечания:

  • self: только текущий ключ сессии.
  • tree: текущая сессия + сессии, созданные текущей сессией.
  • agent: любая сессия, принадлежащая текущему идентификатору агента.
  • all: любая сессия (доступ между агентами все еще требует tools.agentToAgent).
  • Когда сессия является песочничной и sessionToolsVisibility="spawned", OpenClaw ограничивает видимость до tree, даже если вы установили tools.sessions.visibility="all".

Очистка сессийПамять