---
read_when:
    - Вы хотите, чтобы агенты замечали, когда люди или другие агенты изменяют сеанс без их ведома
    - Вы отлаживаете уведомления об изменении состояния, курсоры наблюдения или `session_status changesSince`
    - Вы хотите понять, как родительские агенты синхронизируются с дочерними сессиями
sidebarTitle: Session state awareness
summary: 'Журнал сигналов устойчивого состояния сеанса: версии состояния, наблюдатели, уведомления об устаревшем состоянии и согласование'
title: Осведомлённость о состоянии сеанса
x-i18n:
    generated_at: "2026-07-16T16:22:48Z"
    model: gpt-5.6
    postprocess_version: locale-links-v1
    prompt_version: 32
    provider: openai
    source_hash: bb4126a0802e1ca4418f225c792490493a78886089b81c3b4567f72090ce34f4
    source_path: concepts/session-state.md
    workflow: 16
---

Когда несколько сессий работают над одной задачей — менеджер делегирует её дочерним сессиям, человек напрямую подключается к рабочей сессии, два агента координируются через [`sessions_send`](/ru/concepts/session-tool) — каждая сессия формирует предположения о других. Эти предположения устаревают, как только вмешивается другой участник. Механизм осведомлённости о состоянии сессий обнаруживает вмешательство, однократно уведомляет затронутую сессию и предоставляет ей экономичный способ получить актуальные данные перед выполнением действий.

Совместно работают три компонента:

1. **Долговечный журнал сигналов** регистрирует выбранные изменения состояния для каждой сессии.
2. **Наблюдатели** хранят курсоры для каждой целевой сессии и получают одно объединённое уведомление об устаревшем состоянии.
3. **Сверка** получает точную дельту через `session_status` с `changesSince`.

## Журнал сигналов

OpenClaw добавляет типизированное событие в общую базу данных состояния (`session_state_events`), когда отслеживаемая сессия существенно изменяется. События содержат метаданные и однострочное описание, но никогда не содержат текст сообщений.

| Тип                    | Когда регистрируется                                     | Уведомляет наблюдателей |
| ---------------------- | -------------------------------------------------------- | ----------------------- |
| `human_direct_message` | Человек отправляет ход непосредственно в отслеживаемую сессию | Да                      |
| `upstream_missing`     | Исчезает вышестоящий источник принятой сессии            | Да                      |
| `goal_changed`         | Состояние цели сессии создаётся, обновляется или очищается | Да                      |
| `child_spawned`        | Создаётся сессия дочернего агента или дочерняя сессия ACP | Нет (инициализирует курсор) |
| `run_completed`        | Дочерний запуск успешно завершается                      | Нет (только журнал)     |
| `run_failed`           | Дочерний запуск завершается с ошибкой, превышает время ожидания или отменяется | Нет (только журнал)     |
| `compacted`            | История сессии подвергается Compaction                   | Нет (только журнал)     |
| `adopted`              | Сессия из каталога принимается в OpenClaw                | Нет (только журнал)     |

Каждое событие указывает своего инициатора (`human`, `agent` или `system`). Отменённые дочерние запуски и запуски с превышением времени ожидания регистрируются как ошибки, при этом точный результат (`cancelled`, `timeout` или `error`) сохраняется в полезной нагрузке события.

**Версия состояния** сессии — это просто наибольший порядковый номер в её журнале, отслеживаемый в долговечной записи заголовка каждой сессии, которая сохраняется после очистки. Строки `sessions_list` содержат `stateVersion`, если в журнале сессии зарегистрированы изменения; `session_status` всегда возвращает это значение.

Типы, записываемые только в журнал, предназначены для истории сверки, а не для уведомлений: обычная доставка сведений о завершении дочернего запуска остаётся ответственностью [объявлений дочерних агентов](/ru/tools/subagents), и журнал сигналов никогда её не дублирует.

## Наблюдатели

Наблюдатель — это сессия, которая хранит курсор (`session_watch_cursors`) целевой сессии. Курсоры создаются двумя способами:

- **Неявно (связи порождения).** Когда сессия порождает дочернего агента или дочернюю сессию ACP, курсор родительской сессии автоматически инициализируется версией дочерней сессии на момент её порождения. Родительские сессии никогда не подписываются вручную.
- **Явно (`sessions_send watch: true`).** Любой координатор может отслеживать цель, которую он не породил: передайте `watch: true` в `sessions_send`, и после успешной отправки сообщения отправитель будет зарегистрирован как наблюдатель сессии, фактически получившей сообщение. Регистрация начинается с текущей версии состояния целевой сессии — предыдущая история никогда не создаёт уведомлений. Если параметр был задан, результат инструмента содержит `watched: true|false`.

Идентификатор наблюдателя должен быть ключом сессии с указанием агента. При `session.scope="global"` общий ключ `global` неоднозначен для разных агентов, поэтому такие сессии получают долговечный журнал и `changesSince`, но не получают упреждающих уведомлений.

Отслеживания очищаются автоматически: строки курсоров истекают вместе со сроком хранения журнала сигналов, удаляются при сбросе сессии-наблюдателя и удаляются вместе с любой из двух сессий. В v1 команды прекращения отслеживания нет.

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

Если вышестоящий источник принятой сессии удалён извне, три последовательные проверки, не обнаружившие его (примерно три такта монитора), создают один сигнал `upstream_missing` для её наблюдателей и удаляют ссылку на вышестоящий источник. При следующем продолжении сессии из каталога создаётся новая ссылка.

## Уведомления: одно, а не множество

Когда регистрируется событие, допускающее уведомление, а курсор наблюдателя отстаёт, наблюдатель получает одно системное уведомление при следующем ходе:

```
Сессия "agent:main:subagent:child" изменилась (другой участник). Выполните сверку перед действием: session_status sessionKey "agent:main:subagent:child" changesSince 12.
```

Наблюдатели в основных сессиях также немедленно пробуждаются через Heartbeat; вложенные наблюдатели — дочерние агенты получают уведомление при следующем ходе.

Протокол намеренно предотвращает спам:

- **Одно ожидающее уведомление для каждой пары наблюдатель/цель.** Пока уведомление ожидает доставки, его текст остаётся побайтово неизменным, а очередь системных событий устраняет его дубликаты, поэтому даже двадцать быстрых изменений одной цели по-прежнему создают только одну строку в запросе наблюдателя.
- **Зафиксированная отметка.** Когда уведомление ставится в очередь, курсор фиксирует позицию, о которой было сообщено. Последующие существенные события продвигают только отметку существенных изменений и не создают повторных уведомлений.
- **Подтверждение при извлечении, повторное открытие только при чередующихся изменениях.** Когда ход наблюдателя получает уведомление, курсор продвигается. Если между постановкой в очередь и извлечением появились дополнительные существенные события, для оставшихся событий создаётся ровно одно новое уведомление.
- **Подавление собственных событий.** Наблюдатель никогда не получает уведомления о событиях, которые вызвал сам.
- **Восстановление после перезапуска.** Ожидающие уведомления находятся в очереди в памяти; после перезапуска Gateway проверка при запуске повторно создаёт их на основе долговечных курсоров.

## Сверка

В уведомлении точно указано, что должен сделать наблюдатель. `session_status` с `changesSince: <version>` возвращает типизированные события после указанной версии (до 200), не продвигая курсоры:

```json
{
  "stateVersion": 19,
  "stateChanges": {
    "events": [
      {
        "sequence": 14,
        "kind": "human_direct_message",
        "actorType": "human",
        "summary": "сообщение человека через telegram"
      },
      { "sequence": 19, "kind": "goal_changed", "actorType": "human", "summary": "цель обновлена" }
    ],
    "historyGap": false
  }
}
```

`historyGap: true` означает, что запрошенная версия предшествует сохранённой истории — вместо интерпретации ответа как точной дельты обновите всё состояние сессии (`sessions_history`, `session_status`). Сигнал о пробеле точен: он формируется на основе отметки очистки для каждой сессии, а не выводится арифметически из порядковых номеров.

## Хранение и ограничения

История хранится в общей базе данных состояния и ограничена 30 днями и 50 000 строками; заголовки отдельных сессий сохраняют монотонность после очистки. Запись выполняется по мере возможности — ошибка добавления регистрируется в журнале и никогда не приводит к сбою исходного хода, — поэтому `stateVersion` является заголовком журнала сигналов, а не транзакционной версией журнала изменений.

Текущие ограничения:

- Доставка уведомлений предполагает, что общей базой данных состояния управляет один процесс Gateway. Несколько процессов Gateway используют общий долговечный журнал и `changesSince`, но v1 не передаёт уведомления между процессами.
- События Compaction охватывают владельцев Compaction встроенной среды выполнения; Compaction, выполняемая только нативной тестовой обвязкой, регистрируется не полностью.
- Подробности полезной нагрузки результата отмены сейчас создаются дочерними запусками ACP; отмены нативных дочерних агентов отображаются как общие ошибки.
- Обнаружение собственного эха вышестоящего источника сравнивает нормализованный пользовательский текст. Внешний запрос, совпадающий с одним из 10 последних пользовательских сообщений сессии на стороне OpenClaw, считается собственным эхом.
- Одна локальная строка Claude JSONL размером более 1 МиБ, превышающая ограничение сканирования за один цикл, блокирует курсор этой сессии в v1; неклассифицированные байты никогда не пропускаются.
- При проверках Claude на сопряжённых узлах за один цикл классифицируются последние 50 элементов истории. Более крупные всплески могут оказаться за пределами окна сканирования v1.
- Чтение истории Claude на сопряжённых узлах не предоставляет однозначного результата об отсутствии ветки, поэтому удалённые ветки Claude в v1 не классифицируются как `upstream_missing`.
- Сессии каталога, которые не были приняты, в v1 остаются за пределами слоя осведомлённости.
- Сессии, принятые до появления этой функции, не содержат ссылки на вышестоящий источник; один раз продолжите их из каталога, чтобы начать мониторинг вышестоящего источника.
- Ссылки на вышестоящие источники предполагают, что каждый ключ принятой сессии соответствует одному агенту-владельцу (при принятии используется агент хранилища по умолчанию). Принятие одной внешней ветки несколькими агентами в v1 не отслеживается.

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

- [Инструменты сессий](/ru/concepts/session-tool) — `sessions_send`, `session_status`, `sessions_list`
- [Дочерние агенты](/ru/tools/subagents) — связи порождения и объявления о завершении
- [Heartbeat](/ru/gateway/heartbeat) — как уведомления из очереди пробуждают основные сессии
- [Управление сессиями](/ru/concepts/session) — ключи, области действия и жизненный цикл сессий
