Web interfaces

Вебчат

Стан: macOS/iOS SwiftUI chat UI напряму взаємодіє з Gateway WebSocket.

Що це

  • Нативний chat UI для Gateway (без вбудованого браузера й без локального статичного сервера).
  • Використовує ті самі сеанси та правила маршрутизації, що й інші канали.
  • Детермінована маршрутизація: відповіді завжди повертаються до WebChat.

Швидкий старт

  1. Запустіть Gateway.
  2. Відкрийте WebChat UI (застосунок macOS/iOS) або вкладку чату Control UI.
  3. Переконайтеся, що налаштовано чинний шлях автентифікації Gateway (за замовчуванням shared-secret, навіть на loopback).

Як це працює (поведінка)

  • UI підключається до Gateway WebSocket і використовує chat.history, chat.send і chat.inject.
  • chat.history обмежено для стабільності: Gateway може обрізати довгі текстові поля, пропускати важкі метадані та замінювати завеликі записи на [chat.history omitted: message too large].
  • chat.history дотримується активної гілки транскрипту для сучасних session-файлів із лише додаванням, тому покинуті гілки перезапису та замінені копії prompt не відображаються у WebChat.
  • Записи Compaction відображаються як явний розділювач стисненої історії. Розділювач пояснює, що попередні ходи збережено в checkpoint, і посилається на елементи керування checkpoint у Sessions, де оператори можуть створити гілку або відновити подання до Compaction, якщо їхні дозволи це допускають.
  • Control UI запам'ятовує базовий Gateway sessionId, повернений chat.history, і додає його до подальших викликів chat.send, тому повторні підключення й оновлення сторінки продовжують ту саму збережену розмову, якщо користувач не починає або не скидає сеанс.
  • Control UI об'єднує дублікати запитів у процесі виконання для того самого сеансу, повідомлення та вкладень перед створенням нового ідентифікатора запуску chat.send; Gateway все одно дедуплікує повторні запити, які повторно використовують той самий ключ ідемпотентності.
  • Файли запуску workspace і очікувані інструкції BOOTSTRAP.md передаються через Project Context системного prompt агента, а не копіюються в повідомлення користувача WebChat. Обрізання bootstrap додає лише стислий recovery-опис у системний prompt; докладні лічильники й параметри конфігурації залишаються на діагностичних поверхнях.
  • chat.history також нормалізується для відображення: runtime-only контекст OpenClaw, обгортки вхідних envelope, inline-теги директив доставки на кшталт [[reply_to_*]] і [[audio_as_voice]], plain-text XML-навантаження tool-call (зокрема <tool_call>...</tool_call>, <function_call>...</function_call>, <tool_calls>...</tool_calls>, <function_calls>...</function_calls> і обрізані блоки tool-call), а також витіклі ASCII/full-width керівні токени моделі вилучаються з видимого тексту, а записи assistant, увесь видимий текст яких є лише точним silent токеном NO_REPLY / no_reply, пропускаються.
  • Payload відповідей із прапорцем reasoning (isReasoning: true) вилучаються з вмісту assistant у WebChat, тексту повторного відтворення транскрипту та блоків аудіовмісту, тому payload лише для мислення не з'являються як видимі повідомлення assistant або відтворюване аудіо.
  • chat.inject додає нотатку assistant безпосередньо до транскрипту та транслює її в UI (без запуску агента).
  • Перервані запуски можуть залишати частковий вивід assistant видимим в UI.
  • Gateway зберігає перерваний частковий текст assistant в історії транскрипту, коли буферизований вивід існує, і позначає ці записи метаданими переривання.
  • Історія завжди отримується з Gateway (без локального відстеження файлів).
  • Якщо Gateway недоступний, WebChat працює лише для читання.

Модель транскрипту й доставки

WebChat має два окремі шляхи даних:

  • Session JSONL-файл є тривалим транскриптом моделі/runtime. Для звичайних запусків агента Pi зберігає видимі моделі повідомлення user, assistant і toolResult через свій менеджер сеансів. WebChat не записує довільний текст доставки, стану або допоміжний текст у цей транскрипт.
  • Події Gateway ReplyPayload є live-проєкцією доставки. Їх можна нормалізувати для відображення у WebChat/каналі, block streaming, тегів директив, вбудовування медіа, прапорців TTS/audio та fallback-поведінки UI. Вони самі по собі не є канонічним журналом сеансу.
  • WebChat вставляє записи assistant у транскрипт лише тоді, коли Gateway володіє відображеним повідомленням поза звичайним ходом Pi assistant: chat.inject, відповіді команд без агента, перерваний частковий вивід і керовані WebChat media-доповнення до транскрипту.
  • chat.history читає збережений транскрипт сеансу та застосовує проєкцію відображення WebChat. Якщо live-текст assistant з'являється під час запуску, але зникає після перезавантаження історії, спершу перевірте, чи сирий JSONL містить текст assistant, потім чи не вилучила його проєкція chat.history, а потім чи оптимістичне злиття tail у Control UI не замінило локальний стан доставки збереженим snapshot.

Фінальні відповіді звичайного agent-run мають бути тривалими, бо Pi записує message_end assistant. Будь-який fallback, що дзеркалить доставлений фінальний payload у транскрипт, спершу має уникнути дублювання ходу assistant, який Pi вже записав.

Панель інструментів агентів Control UI

  • Панель Tools у Control UI /agents має два окремі подання:
    • Доступно просто зараз використовує tools.effective(sessionKey=...) і показує, що поточний сеанс фактично може використовувати під час runtime, зокрема core-, plugin- і channel-owned tools.
    • Конфігурація інструментів використовує tools.catalog і зосереджується на профілях, override та семантиці catalog.
  • Runtime-доступність прив'язана до сеансу. Перемикання сеансів на тому самому агенті може змінити список Доступно просто зараз.
  • Редактор конфігурації не означає runtime-доступність; effective-доступ усе одно дотримується пріоритету policy (allow/deny, per-agent і provider/channel overrides).

Віддалене використання

  • Віддалений режим тунелює Gateway WebSocket через SSH/Tailscale.
  • Не потрібно запускати окремий сервер WebChat.

Довідник конфігурації (WebChat)

Повна конфігурація: Конфігурація

Опції WebChat:

  • gateway.webchat.chatHistoryMaxChars: максимальна кількість символів для текстових полів у відповідях chat.history. Коли запис транскрипту перевищує цей ліміт, Gateway обрізає довгі текстові поля й може замінювати завеликі повідомлення placeholder. Клієнт також може надсилати per-request maxChars, щоб перевизначити це значення за замовчуванням для одного виклику chat.history.

Пов'язані глобальні опції:

  • gateway.port, gateway.bind: host/port WebSocket.
  • gateway.auth.mode, gateway.auth.token, gateway.auth.password: автентифікація WebSocket зі спільним секретом.
  • gateway.auth.allowTailscale: вкладка чату браузерного Control UI може використовувати identity headers Tailscale Serve, коли це ввімкнено.
  • gateway.auth.mode: "trusted-proxy": автентифікація reverse-proxy для браузерних клієнтів за identity-aware джерелом proxy non-loopback (див. Автентифікація Trusted Proxy).
  • gateway.remote.url, gateway.remote.token, gateway.remote.password: ціль віддаленого Gateway.
  • session.*: сховище сеансів і значення main key за замовчуванням.

Пов'язане