y83 code / справочник

Зависание хода и блокировка диалога

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

раздел
Чат с агентом (Codex)
пунктов возможностей
100
источник
docs/codex/stuck-and-block.md

Раздел нужен, чтобы понимать, когда агенту нужно просто время, когда пора нажать Stop, а когда диалог пришлось разблокировать вручную.

Два разных состояния, которые легко спутать

Подозрение на зависание и блокировка диалога выглядят похоже, но означают разное.

  • Подозрение на зависание означает, что от агента долго нет событий, и приложение пока не знает, жив ход или нет.
  • Подозрение ничего не прерывает само: решение остаётся за вами, а ход на сервере может продолжаться прямо сейчас.
  • Блокировка диалога означает, что ход потерян настолько, что отправлять в него новые сообщения опасно.
  • При блокировке приложение не отправляет ни очередь, ни новое сообщение и ждёт, пока вы нажмёте Unlock.
  • Подозрение снимается само, как только агент снова подаст признаки жизни: плашка исчезает без всяких действий с вашей стороны.
  • Блокировка сама не проходит: её снимает либо подтверждение окончания хода, либо ваша кнопка Unlock.

Когда появляется подозрение на зависание

Приложение считает признаком жизни любое событие хода: текст, размышления, запуск команды, вызов инструмента, счётчик токенов. Как только такое событие приходит, отсчёт тишины начинается заново с нуля.

  • Полная тишина длиной четыре минуты считается подозрительной и включает сверку хода с сервером.
  • Сверка спрашивает у сервера статус последнего хода и сравнивает его с тем, что видит приложение.
  • Сторож смотрит на состояние хода каждые тридцать секунд, а не постоянно.
  • Проверка не чаще одного раза в две минуты, поэтому плашка может висеть заметно дольше первой сверки.
  • Пока в ленте висит открытый вопрос агента, подозрение не возникает: тишина ожидаема, ведь ход специально ждёт вашего ответа.
  • Пока план ждёт вашего одобрения, подозрение не возникает по той же причине: ход уже закончился и ждёт решения.
  • Пока идёт сжатие переписки, подозрение не возникает: сжатие идёт отдельным ходом без единого события.
  • Пока агент выполняет ещё не законченную команду, подозрение не возникает: команда может молча работать долго, и это нормально.

Плашка в ленте

Плашка появляется в ленте над сообщениями и всегда оформлена одинаково: жёлтый фон, треугольник с восклицательным знаком и подпись. Подпись всегда начинается со слова WARNING, а дальше идёт объяснение, что именно случилось.

  • При подозрении текст плашки сообщает, что агент не отвечает, и показывает, сколько минут прошло с начала тишины.
  • При блокировке текст плашки сообщает, что ход на сервере был потерян, и напоминает, что сообщения стоят в очереди до разблокировки.
  • Кнопки у двух состояний разные: при подозрении это Check и Stop, при блокировке остаётся одна кнопка Unlock.
  • Плашка живёт в ленте, а не поверх неё, поэтому она прокручивается вместе с сообщениями.
  • Плашка встаёт после карточек вопросов и разрешений, а перед сообщениями и ответами агента.
  • Число минут округляется вниз до целых, но показывается хотя бы одна минута, поэтому плашка никогда не пишет ноль минут.

Кнопка Check

Кнопка Check отвечает на один вопрос: продолжает ли агент работать или ход уже закончился, а приложение просто не получило об этом событие.

  • Check делает ровно то же, что и автоматическая сверка, но не ждёт двухминутной паузы.
  • После нажатия кнопка сразу спрашивает у сервера статус последнего хода и смотрит на ответ.
  • Если сервер отвечает, что ход ещё идёт, приложение ничего не меняет: подозрение остаётся, а прерывание предлагает кнопка Stop.
  • Если сервер отвечает, что ход закончен, прерван или упал, приложение закрывает ход у себя и отправляет накопленную очередь.
  • Если сервер отвечает, что хода нет вообще, приложение делает то же самое: закрывает ход локально.
  • Если сервер ответил, что такого хода нет, приложение тоже считает ход закрытым и освобождает очередь.
  • Если запрос не дошёл до сервера, приложение ничего не решает и повторит проверку позже.
  • Check работает только пока ход ещё числится активным: если ход уже закрыт, кнопка ничего не делает.

Кнопка Stop

Кнопка Stop прерывает текущий ход агента и освобождает диалог для новых сообщений. Такая же кнопка есть в поле ввода под лентой, и она работает одинаково.

  • Stop отправляет серверу команду преривания хода и сразу гасит саму кнопку, чтобы второе нажатие не прошло.
  • Пока прерывание в работе, кнопка Stop в поле ввода не нажимается: она выглядит погасшей и ждёт ответа сервера.
  • Если ход ещё только стартует, приложение ждёт его идентификатор и прерывает сразу, как только тот появился.
  • Ожидание идентификатора длится до трёх секунд с проверкой каждые сто миллисекунд.
  • Если за эти секунды ход так и не начался, приложение просто закрывает ход у себя, чтобы индикаторы не висели.
  • Если сервер отвечает, что активного хода у него нет, приложение закрывает ход локально без дополнительных действий.
  • Если команда прерывания не дошла до сервера, приложение закрывает ход локально и блокирует диалог: ход на сервере мог остаться в работе.
  • После команды прерывания приложение двадцать секунд ждёт подтверждения, что ход действительно закончился.
  • Если через двадцать секунд сервер всё ещё пишет, что ход идёт, приложение оставляет локальное состояние как есть и ждёт дальше.
  • Если через двадцать секунд хода на сервере уже нет, приложение закрывает его локально, и тогда уходят индикаторы работы и освобождается очередь.
  • Долгие ходы обрывать не нужно: если агент молчит, но сервер пишет, что ход в работе, кнопка Stop не поможет.

Блокировка диалога

Блокировка появляется не от долгого молчания, а только когда ход потерян технически.

  • Единственная причина блокировки: команда прерывания не дошла до сервера, а сам ход при этом ещё числится работающим.
  • Блокировка помнит конкретный диалог: застрявший ход одного диалога не мешает работать остальным.
  • Пока диалог заблокирован, отправка сообщений в него не уходит, даже если вы напишете в поле ввода и нажмёте Send.
  • Сообщение при блокировке встаёт в локальный буфер, а не в очередь на стороне агента, и ждёт разблокировки.
  • Строка статуса под лентой пишет thread blocked красным цветом, чтобы состояние было видно и без плашки.
  • Блокировка защищает от цикла, в котором новое сообщение запускает ход, ход снова молчит, вы жмёте Stop, и всё повторяется заново.
  • Блокировка живёт только в памяти приложения: после перезапуска телефона она исчезает сама.

Когда блокировка снимается сама

Иногда разблокировка происходит без вас, и это хороший знак: значит, движок жив и ход просто дошёл до конца.

  • Подтверждение окончания хода снимает блокировку сразу и разрешает отправку накопленной очереди.
  • Успешный запуск нового хода тоже снимает блокировку, потому что сервер принял сообщение и начал работу.
  • Кнопка Unlock снимает блокировку вручную и показывает уведомление об успешной разблокировке.
  • После разблокировки очередь уходит сразу, без ожидания следующего хода.
  • Разблокировка попутно снимает и подозрение на зависание, если оно было в этот момент.
  • Разблокировка ничего не спрашивает у сервера, поэтому снять её можно, даже когда связи нет.

Потерянный диалог и потерянная рабочая папка

Иногда сообщение не отправляется вовсе, и вместо ошибки появляется вопрос: продолжать ли работу в новом диалоге.

  • Диалог считается недоступным, если движок не находит сам диалог или рабочую папку, в которой он жил.
  • Обычная причина: движок перезапустился или папка проекта исчезла с диска.
  • Приложение не отправляет сообщение молча, а показывает окно с вопросом и сохраняет ваш текст.
  • Окно называется Thread unavailable и объясняет, что агент не может открыть этот диалог здесь.
  • Перед окном приложение один раз пробует поднять диалог заново и отправить сообщение повторно.
  • Кнопка Continue in new создаёт новый диалог и отправляет в него сохранённое сообщение сразу.
  • Кнопка New thread создаёт новый диалог, а текст возвращает в поле ввода, чтобы вы решили сами.
  • Кнопка Cancel закрывает окно, ничего не создавая и не отправляя, а сохранённый текст при этом теряется.
  • Окно можно закрыть и тапом мимо него, это равносильно Cancel.
  • Если сообщение отвергли только потому, что шёл другой ход, окно не открывается: сообщение встаёт в полосу очереди и ждёт конца хода.

Сверка хода при возврате в приложение

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

  • При возврате из фона с открытым ходом приложение спрашивает у сервера статус хода и сверяет его со своим.
  • Если ход на сервере идёт, а лента отстала, приложение перечитывает хвост диалога и догоняет пропущенные шаги.
  • Если ход на сервере другой, чем тот, который считает приложение, приложение принимает серверный и помечает свой как закрытый без уведомления.
  • Если сервер отвечает, что ход закончен, приложение закрывает его у себя и освобождает очередь.
  • Если ход уже закрыт, а экран всё ещё рисует работу, приложение просто гасит индикаторы и ничего не переигрывает.
  • Если сервер не назвал статус хода, приложение ничего не меняет и решит вопрос позже.
  • Ход, который приложение подхватило у сервера, проверяется ещё раз через шесть секунд: вдруг он уже закончился.
  • Если за эти шесть секунд события хода пришли, значит ход живой, и лишней проверки не будет.
  • После обрыва связи подписка на события теряется, поэтому сверка при возврате — единственный способ узнать, чем кончился ход.
  • Обновление списка диалогов тоже сверяет статусы: ход, который сервер считает свободным, перестаёт быть рабочим.
  • Живой ход, который приложение видит у себя, серверному статусу «свободен» не подчиняется, пока не прошло десять секунд тишины.

Как зависание видно в списке диалогов

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

  • У диалога в списке подпись читается как stuck и рядом показывает, сколько минут молчит ход.
  • У проекта в списке собирается сводка вида «два работают, один ждёт, один завис» по всем его диалогам.
  • Если в проекте есть хотя бы один работающий диалог, сводка говорит о работе и не упоминает зависшие.
  • Приоритет в сводке такой: работа важнее зависания, а зависание важнее ожидания.
  • Пока не идёт ни работа, ни ожидание, ни подозрение, у диалога вообще нет статусной подписи.
  • Диалог, который ждёт вашего ответа, получает подпись awaiting you, а не зависание.
  • После перезапуска приложения старый рабочий ход может выглядеть зависшим: если запись о ходе пролежала дольше десяти минут, она помечается как подозрительная.
  • Если список диалогов три раза подряд не обновился, все диалоги, которые рисуются рабочими, получают знак предупреждения: их статус может быть недостоверным.
  • Успешное обновление списка снимает это предупреждение автоматически.

Технические данные

ПараметрЗначение
Порог тишины, после которого начинается сверка4 минуты
Как часто сторож смотрит на состояние ходакаждые 30 секунд
Минимальный интервал между сверками хода2 минуты
Грейс живости: сколько тишины терпит серверный статус «свободен»10 секунд
Ожидание идентификатора только что стартовавшего ходадо 3 секунд с шагом 100 мс
Ожидание подтверждения после прерывания20 секунд
Чтение статуса после прерывания, тайм-аут6 секунд
Повторная проверка хода, принятого у серверачерез 6 секунд
Сверка хода при возврате из фоначтение статуса хода у сервера
Тайм-аут сверки при возврате из фона6 секунд
Порог устаревания записи хода после перезапуска10 минут
Неудачных обновлений списка диалогов до пометки сомнения3
Период фонового обновления списка диалогов20 секунд
Формат подписи зависшего диалогаstuck · silence Nм
Формат подписи в строке статусаsuspected hang · silence Nм
Подпись при блокировкеthread blocked
Подпись плашки при подозренииагент не отвечает, N мин
Подпись плашки при блокировкеход на сервере потерян, сообщения в очереди
Кнопки плашки при подозренииCheck и Stop
Кнопки плашки при блокировкеUnlock
Уведомление после ручной разблокировкиThread unlocked
Заголовок окна потерянного диалогаThread unavailable
Кнопки окна потерянного диалогаContinue in new, New thread, Cancel
Цвет строки статуса при подозрении и блокировкецвет ошибки
Радиус скругления плашки16dp
Отступы внутри плашки16dp по горизонтали, 8dp по вертикали
Отступы вокруг плашки4dp со всех сторон
Значок предупреждения в плашке14dp
Троттлинг записи времени активности в интерфейсне чаще одного раза в 100 мс
Сообщение в журнале после ручной разблокировкиthread unblocked by user

Что агент умеет

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

Ограничения

  • Приложение не прерывает ход само по таймеру: молчание четыре минуты и дольше только показывает подозрение, а решение остаётся за вами.
  • Подозрение на зависание нельзя снять без события от агента: если ход на самом деле жив, плашка будет висеть до вашего Stop.
  • Блокировку диалога нельзя снять, не нажав Unlock: приложение намеренно не отправляет сообщения в застрявший ход.
  • Разблокировка не проверяет сервер, поэтому снять её можно и тогда, когда ход на самом деле всё ещё работает: сообщения уйдут в занятый ход.
  • Проверка живости хода отвечает только на вопрос «идёт ход или уже закончен» и не показывает, на чём именно агент застрял.
  • Окно потерянного диалога предлагает только новый диалог: восстановить старую рабочую папку из приложения нельзя.
  • Текст, сохранённый при потерянном диалоге, не переживает ни закрытие приложения, ни нажатие Cancel: нажать Continue in new или New thread.
  • Пометка подозрения в списке диалогов после перезапуска опирается на время сохранённой записи, а не на реальную проверку хода.
  • Предупреждение о недостоверных статусах в списке появляется после трёх неудачных обновлений подряд и держится до первого успешного.
  • При остановке хода приложение ждёт двадцать секунд подтверждения, поэтому признаки работы могут остаться на экране ещё на это время.

Источник: docs/codex/stuck-and-block.md. Страница собрана из документации проекта при сборке сайта — без пересказа.

Зависание хода и блокировка диалога Вернуться к справочнику