1.1.0
Added (#113)
- REST-фолбэк отправки сообщений в чат (#113): при недоступности WebSocket (строгие корпоративные прокси, reverse-proxy без WS-upgrade, временный обрыв) WebUI автоматически деградирует в режим отправки через существующий
POST /api/v1/agents/{id}/chatи продолжает работать. Клиент:api.chat.sendвendpoints.ts(контракт —handler/chat.go SendMessage:{content, chat_id?}→{status, chat_id}, fire-and-forget); вChatStore— режимrestModeсо входом при исчерпании WS-ретраев (бюджет 10 при живавшем соединении, 3 если соединения не было вовсе — сценарий «прокси режет WS с самого начала») либо после первой успешной REST-отправки,sendRESTс оптимистичным баблом (сверка через role+content-fallback merge —client_temp_idREST-контракт не передаёт) и переиспользованиемchat_idREST-сессии, polling истории (2.5 c → 5 c → 10 c backoff по «пустым» тикам, кап 300 c = watchdog-hard) за финальной строкой хода — терминальные ролиassistant/interrupted/topic_break(error-тексты хода персистятся assistant-строкой, #371, так что финал есть всегда) при отсутствии несвёрнутых оптимистичных записей; polling переживает WS-reconnect (события REST-хода броадкастятся только подписчикам егоchat_id rest:...— в новое соединение не приходят) и закрывается финалом/таймаутом; при таймауте ожидающие баблы маркируютсяdelivery_failed+ warning-toast.ChatSendмаршрутизирует: вrestMode— сразу в REST без WS-ретраев, при исчерпании 5 быстрых ретраев — деградация в REST, при провале и REST — прежняя терминальная «нет соединения»; вложения блокируются до upload с тостом (REST-контракт без media). UI: жёлтыйChatModeBanner(«Прямое подключение недоступно. Сообщения отправляются через HTTP…»), композер остаётся рабочим (restFallbackослабляет только гейт Send; вложения/команды/Stop остаются WS-only), при восстановлении WS режим снимается сам (onopen → exitRestMode, редкий фоновый retry ~60 c внутри режима). Литерал/stopработает через REST (серверная приоритетная команда из любого канала). Осознанные ограничения режима: нет стриминга/хода мысли, вложений, ask_user-ответов и Stop-кнопки.scheduleReconnectбольше не ставит терминальную «Соединение потеряно. Обновите страницу.» — вместо неё деградация с баннером. Тесты (TS):sendRESThappy/failure//stop/chat_id-continuity, completion по терминальной строке, ожидание при только-user-строке, таймаут с маркировкой баблов, остановка polling’а destroy’ем, вход в restMode по бюджетам 3/10, выход по onopen, отсутствие входа при открытом WS, back-to-back одинаковые сообщения не схлопываются merge’ом;ChatSend— маршрутизация в REST из restMode, деградация после 5 ретраев, блок вложений, терминальный провал REST. ocr review — 3 раунда, все находки закрыты (destroyed-гарды на await-путях, backoff polling’а, in-flight-флаг против удвоения цепочки тиков, маркировка баблов при таймауте).