← Web App

Stack and chat shell

web app · workzone
Frontend
stack — libraries
Shell and render
React Vite TypeScript
Styling and components
Tailwind CSS shadcn/ui · Base UI
Data and state
TanStack Query SSE client
i18n and routing
react-i18next client routing → Auth / Security
Chat shell ↓ below
assistant-ui
structure — files · frontend/src/
frontend/src/
├── routes/      pages under routes — /chat · /account
├── components/  UI primitives — shadcn on Base UI
├── features/    chat — assistant-ui wrapper + our layer
├── i18n/        locales — ru · en
└── lib/         API client · SSE adapter · helpers
Why a thin client
The heavy conversation logic — the flow of the conversation, retrieval, grounding — is run by Query Engine, one API for all surfaces; Web App keeps conversation management (list, retention) and rendering. The frontend receives one SSE answer stream and one conversation schema — and draws them in the shell.
The surface's chat shell — off the shelf
assistant-ui MIT · headless

The web surface doesn't build the chat from scratch: the thread, history, streaming, and “new conversation” come from a mature library. Our domain is custom components inside its thread and a thin conversation-management layer around it, not a rewritten shell.

from the library
thread composer history streaming new conversation auto-scroll markdown a11y
ours — inside the thread
sources [n] grounding states feedback /
ours — around the thread
conversation management retention “new chat” semantics
Two integration seams
SSE → adapter. The Query Engine stream (StreamingResponse · SSE) is consumed by a ChatModelAdapter on the client — the library doesn't dictate the backend, and the LLM keys stay with us.
The skin is ours. We take the headless primitives and style them with our own shadcn tokens on @base-ui/react, not the library's stock Radix theme: the look stays house-style, and we don't pull in a second set of primitives.