---
read_when:
    - Вы хотите, чтобы агенты замечали, когда люди или другие агенты изменяют сеанс без их ведома
    - Вы отлаживаете уведомления об изменении состояния, курсоры наблюдения или изменения session_status с момента запуска
    - Вы хотите понять, как родительские агенты синхронизируются с дочерними сеансами
sidebarTitle: Session state awareness
summary: 'Журнал сигналов сохраняемого состояния сеанса: версии состояния, наблюдатели, уведомления об устаревшем состоянии и согласование'
title: Осведомлённость о состоянии сеанса
x-i18n:
    generated_at: "2026-07-13T18:05:26Z"
    model: gpt-5.6
    postprocess_version: locale-links-v1
    prompt_version: 24
    provider: openai
    source_hash: 06ec310fc482ce658eb37628ac33c4224349846d1ffd6e8edeac01bc84e56341
    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` | Человек отправляет реплику непосредственно в отслеживаемый сеанс | Да                |
| `goal_changed`         | Целевое состояние сеанса создаётся, обновляется или очищается | Да               |
| `child_spawned`        | Создаётся дочерний сеанс субагента или ACP               | Нет (инициализирует курсор) |
| `run_completed`        | Дочерний запуск успешно завершается                      | Нет (только журнал) |
| `run_failed`           | Дочерний запуск завершается с ошибкой, превышает время ожидания или отменяется | Нет (только журнал) |
| `compacted`            | История сеанса подвергается Compaction                   | Нет (только журнал) |

В каждом событии указан его инициатор (`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 команды прекращения наблюдения нет.

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

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

```
Сеанс "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; отмены нативных субагентов отображаются как общие ошибки.

## Связанные разделы

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