Skip to Content
Руководство для разработчиковDaemon Client AdaptersАдаптер Web Shell для демона

Адаптер Web Shell для демона

Цель

Веб-чат и клиенты веб-терминала должны потреблять qwen serve через HTTP/SSE API демона и отрисовывать транскрипт на стороне клиента. Нативные локальные TUI, канальные и IDE-интеграции пока сохраняют свои существующие пути по умолчанию.

Общий контракт UI

Используйте экспорты UI демона из TypeScript SDK как общую границу:

import { DaemonClient, DaemonSessionClient, createDaemonTranscriptStore, normalizeDaemonEvent, } from ' @qwen-code/sdk/daemon';

Разделение:

  • DaemonClient обрабатывает HTTP-маршруты демона.
  • DaemonSessionClient отвечает за создание/присоединение к сессии и воспроизведение SSE.
  • normalizeDaemonEvent() преобразует сетевые события демона в события UI.
  • createDaemonTranscriptStore() сворачивает события UI в блоки транскрипта.

React-клиенты могут использовать привязку, экспортируемую из Web Shell:

import { DaemonSessionProvider, useActions, useConnection, usePendingPermissions, useTranscriptBlocks, } from ' @qwen-code/web-shell/daemon-react-sdk';

Минимальная React-форма:

function App() { return ( <DaemonSessionProvider baseUrl="http://127.0.0.1:4170"> <Transcript /> <PromptBox /> </DaemonSessionProvider> ); } function Transcript() { const blocks = useTranscriptBlocks(); return blocks.map((block) => <RenderBlock key={block.id} block={block} />); }

Провайдер создаёт или присоединяется к сессии демона, подписывается на SSE, хранит последний event id на DaemonSessionClient и по умолчанию переподключает поток. Вызывающий код может отключить это через autoReconnect={false} для тестов или собственного управления подключением.

Варианты развёртывания в браузере

Локальный POC с одним источником

Страница, обслуживаемая демоном, может обращаться к демону напрямую, так как страница и API имеют один источник. Это предпочтительная форма раннего POC для валидации локального веб-чата и веб-терминала.

Удалённый веб-чат / веб-терминал

Продакшен-удалённое веб-приложение обычно должно обращаться к backend-for-frontend. BFF владеет URL демона, токеном, маршрутизацией рабочих пространств и метаданными сессии, а затем перенаправляет безопасные для браузера события приложения в браузер. Это исключает хранение bearer-токенов в браузере и позволяет развёртыванию определять, к какому демону/рабочему пространству пользователь может обращаться.

Локальный браузер против локального демона

Отдельный локальный dev-сервер имеет другой источник, чем qwen serve; он должен либо проксировать маршруты демона через тот же источник, либо обслуживаться самим демоном. Демон намеренно отклоняет произвольные запросы с браузерным Origin.

Ответственности рендеринга

Общая модель транскрипта семантическая, а не визуальная. UI-клиенты сами решают, как отрисовывать:

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

Веб-терминал — это браузерный семантический рендерер. Он должен выглядеть и ощущаться как терминал с моноширинной раскладкой, прокруткой, вводом промпта, горячими клавишами и потоковыми блоками, но он не является прямым PTY-прокси и не требует серверного рендеринга Ink.

Безопасность слияния

  • Нативный TUI qwen остаётся прямым и неизменным.
  • Пути --acp, каналов и IDE остаются неизменными по умолчанию.
  • Ядро UI SDK является аддитивным.
  • Привязка Web Shell React опциональна и работает только в клиентах, которые её импортируют.
  • Удалённый код демонстрационного TUI демона не должен рассматриваться как миграция продукта.

Дальнейшие шаги

  • Синхронизировать поведение Web Shell, обслуживаемого демоном, и встроенного хоста IDE.
  • Продолжить создание первоклассных рендереров чата и терминала на блоках транскрипта.
  • Добавлять более богатые типизированные события только там, где существующие события демона слишком низкоуровневые для стабильного поведения UI в браузере.
  • Рассмотреть выделенный пакет @qwen-code/daemon-ui-core, если потребители вне SDK нуждаются в ядре UI как в независимой зависимости.
Last updated on