Перейти к основному содержанию

Логика состояния строки меню

Что отображается

  • Мы отображаем текущее рабочее состояние агента в значке строки меню и в первой строке состояния меню.
  • Состояние здоровья скрывается, пока работа активна; оно возвращается, когда все сеансы бездействуют.
  • Блок «Nodes» в меню перечисляет только устройства (сопряжённые узлы через node.list), а не записи клиентов/присутствия.
  • Раздел «Usage» появляется под «Context», когда доступны снимки использования провайдера.

Модель состояний

  • Сеансы: события приходят с runId (per-run) плюс sessionKey в полезной нагрузке. «Основной» сеанс — это ключ main; если он отсутствует, используется наиболее недавно обновлённый сеанс.
  • Приоритет: основной всегда имеет приоритет. Если основной активен, его состояние отображается немедленно. Если основной бездействует, отображается наиболее недавно активный неосновной сеанс. Мы не «переключаемся туда‑сюда» в середине активности; переключение происходит только когда текущий сеанс становится бездействующим или основной становится активным.
  • Виды активности:
    • job: выполнение высокоуровневых команд (state: started|streaming|done|error).
    • tool: phase: start|result с toolName и meta/args.

Перечисление IconState (Swift)

  • idle
  • workingMain(ActivityKind)
  • workingOther(ActivityKind)
  • overridden(ActivityKind) (переопределение для отладки)

ActivityKind → глиф

  • exec → 💻
  • read → 📄
  • write → ✍️
  • edit → 📝
  • attach → 📎
  • default → 🛠️

Визуальное сопоставление

  • idle: обычный «криттер».
  • workingMain: бейдж с глифом, полная окраска, анимация «working» для лап.
  • workingOther: бейдж с глифом, приглушённая окраска, без «шуршания».
  • overridden: использует выбранные глиф/окраску независимо от активности.

Текст строки состояния (меню)

  • Пока работа активна: <Session role> · <activity label>
    • Примеры: Main · exec: pnpm test, Other · read: apps/macos/Sources/OpenClaw/AppState.swift.
  • В состоянии простоя: возвращается к сводке состояния здоровья.

Приём событий

  • Источник: события канала управления agent (ControlChannel.handleAgentEvent).
  • Разобранные поля:
    • stream: "job" с data.state для начала/окончания.
    • stream: "tool" с data.phase, name, необязательные meta/args.
  • Метки:
    • exec: первая строка args.command.
    • read/write: сокращённый путь.
    • edit: путь плюс предполагаемый тип изменения из meta/счётчиков diff.
    • fallback: имя инструмента.

Переопределение отладки

  • Настройки ▸ Debug ▸ селектор «Icon override»:
    • System (auto) (по умолчанию)
    • Working: main (по типу инструмента)
    • Working: other (по типу инструмента)
    • Idle
  • Сохраняется через @AppStorage("iconOverride"); сопоставляется с IconState.overridden.

Чек‑лист тестирования

  • Запустить задание основного сеанса: убедиться, что значок переключается немедленно и строка состояния показывает метку основного.
  • Запустить задание неосновного сеанса, пока основной простаивает: значок/статус показывает неосновной; остаётся стабильным до завершения.
  • Запустить основной, пока другой активен: значок мгновенно переключается на основной.
  • Быстрые серии инструментов: убедиться, что бейдж не мерцает (TTL‑поблажка на результаты инструментов).
  • Строка здоровья появляется снова, как только все сеансы бездействуют.