Skip to Content
ДизайнАдаптеры статусов жизненного цикла каналов

Адаптеры статусов жизненного цикла каналов

Дата: 2026-07-01

Цель

Предоставить состояние жизненного цикла задачи через первые четыре адаптера каналов:

  • Telegram
  • Weixin
  • DingTalk
  • Feishu

Это продолжение задачи P1.1 по работе с идентификацией каналов и метаданными жизненного цикла. Цель — заставить каждый поддерживаемый канал отображать наилучший доступный нативный сигнал прогресса, не изменяя при этом общий контракт канала.

Не цели

  • Не реализовывать поведение для Slack.
  • Не реализовывать поведение для QQ Bot.
  • Не обновлять примеры моков/плагинов.
  • Не добавлять эмодзи терминального статуса для DingTalk.
  • Не вводить общую абстракцию для рендеринга статусов ради одного раунда специфичных для адаптеров маппингов.

Ссылки и согласованность

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

Текущее состояние

КаналСуществующая поверхность статусовТекущее поведение
TelegramИндикатор набора текстаНачинает набор при старте промпта и останавливает при его завершении.
WeixinИндикатор набора текстаНачинает набор при старте промпта и останавливает при его завершении.
DingTalkРеакция на сообщениеДобавляет реакцию «глаз» при старте промпта и отзывает её при завершении.
FeishuСтриминговая карточкаОтображает и обновляет стриминговую карточку, включая пути завершения и обработки ошибок.

Предлагаемый дизайн

Реализация должна быть локальной для каждого адаптера. Каждый адаптер потребляет хук события жизненного цикла и маппит событие на существующую нативную поверхность статусов платформы.

Событие жизненного циклаTelegramWeixinDingTalkFeishu
startedНачать набор.Начать набор.Добавить реакцию «глаз».Показать/обновить карточку как выполняющуюся.
text_chunkИгнорировать.Игнорировать.Игнорировать.Игнорировать в хуке жизненного цикла. Стриминг контента остается на существующем пути стриминга ответов/карточек.
tool_callИгнорировать.Игнорировать.Игнорировать.Игнорировать для UI.
completedОстановить набор.Остановить набор.Отозвать реакцию «глаз».Отметить карточку как завершенную.
cancelledОстановить набор.Остановить набор.Отозвать реакцию «глаз».Отметить карточку как отмененную.
failedОстановить набор.Остановить набор.Отозвать реакцию «глаз».Отметить карточку как завершенную с ошибкой.

Telegram

Telegram сохраняет существующую реализацию набора текста. Хук жизненного цикла должен маппить started на существующий путь начала набора текста, а все терминальные события — на путь остановки набора.

text_chunk и tool_call не требуют изменений в UI Telegram.

Weixin

Weixin следует той же структуре, что и Telegram. Хук жизненного цикла должен маппить started на setTyping(true), а терминальные события — на setTyping(false).

Дополнительные сообщения не отправляются.

DingTalk

DingTalk сохраняет существующее поведение реакции «глаз»:

  • started: добавить существующую реакцию «глаз».
  • completed, cancelled, failed: отозвать существующую реакцию «глаз».

В этом скоупе нет терминальных эмодзи. Задачи со статусом failed и cancelled не должны отправлять дополнительные сообщения о статусе, если только существующий путь обработки ошибок уже не делает этого.

Feishu

Feishu сохраняет стриминговую карточку в качестве поверхности статусов и делает терминальное состояние явным в содержимом карточки:

СостояниеМетка карточки
Выполняется运行中...
Завершено已完成
Отменено已取消
Ошибка已失败,请重试

Карточка по-прежнему стримит контент ответа, как и сегодня, через существующий хук стриминга ответов/карточек. Событие жизненного цикла text_chunk не потребляется адаптером напрямую в этом скоупе, что отменяет более раннюю идею использования чанков жизненного цикла для добавления контента в карточку на уровне адаптера. tool_call остается скрытым от UI карточки в этом скоупе.

Хелпер для markdown/карточек может принимать минимальную опцию метки статуса при необходимости, но не должен перерастать в универсальный фреймворк для рендеринга.

Поток данных

  1. Выполнение канала генерирует события жизненного цикла из базового слоя канала.
  2. Выбранный адаптер получает событие через свой хук жизненного цикла.
  3. Адаптер маппит событие на поверхность статусов платформы.
  4. Обновления статусов платформы выполняются в режиме best-effort и не влияют на выполнение задачи.

Полезная нагрузка события жизненного цикла должна предоставлять достаточно существующего контекста для идентификации сообщения/сессии канала. Если специфичный для платформы идентификатор отсутствует, адаптер пропускает обновление статуса.

Обработка ошибок

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

Терминальные события должны быть идемпотентными для сообщения/сессии. Повторные терминальные события не должны создавать дублирующиеся обновления статуса или оставлять устаревший индикатор выполнения.

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

План тестирования

Добавить целенаправленное юнит-покрытие в затронутые пакеты каналов:

  • Telegram: событие started запускает набор текста; терминальные события останавливают набор; не вводится дублирующий интервал набора.
  • Weixin: событие started вызывает setTyping(true); терминальные события вызывают setTyping(false).
  • DingTalk: событие started добавляет реакцию «глаз»; терминальные события отзывают её; терминальные эмодзи не отправляются.
  • Feishu: состояния карточки running, completed, cancelled и failed рендерят ожидаемые метки; событие text_chunk остается в ведении существующего пути стриминга, а не хука жизненного цикла; tool_call не добавляет вывод в UI.

Для верификации следует запустить локальные для пакета команды Vitest для затронутых адаптеров, затем выполнить сборку проекта и проверку типов перед отправкой PR.

Открытые вопросы

Отсутствуют. Текущий скоуп намеренно узок и следует существующим возможностям адаптеров.

Last updated on