mirror of
https://github.com/hanzoai/chat.git
synced 2026-08-06 23:06:55 +00:00
main
Adds the two affordances the app implied and never offered: a top-right control cluster, and a dockable bottom bar. NAMING FIRST, because this collided once already. Upstream owns Chat/Dock — a HORIZONTAL column of iframe cards beside the conversation. An earlier pass built a VERTICAL bottom dock and called it the same thing. Upstream keeps its name; this is Chat/BottomBar (BottomBar, BottomBarGroup, BottomBarTab), with store keys, translation keys and test ids renamed to match. Both now render together: ["messages-view","chat-column","dock-panel","controls-nav"]. PanelControls: full width (Maximize2/Minimize2 over the existing store.maximizeChatSpace), the companions menu (Monitor, highlighted while the bar is open) opening a right-aligned DropdownPopup with "Side chat ⌥⌘S" and "Browser ⌘T", and the Controls panel. Shortcuts are one document keydown effect testing e.code, because Option+S types ß on macOS. Three things were adapted to today's main rather than force-applied: - OpenSidebar is NOT mounted in the header. Upstream moved that toggle into the rail and Header.spec.tsx exists to keep the header's left edge empty; a second one would be the duplicate the rail was invented to remove. The component still becomes a real toggle (navVisible, aria-expanded, PanelLeft) for its three existing call sites. - The right-panel control is SlidersHorizontal, not PanelRight: upstream's CanvasToggle already wears PanelRight in the same cluster for the artifacts canvas. Same rule as the Dock — whoever took the glyph keeps it. The panel calls itself Controls in its own aria-label, which is what sliders say. - SidePanel/Preview/Panel was still mounted nowhere, so the bar gives it a home rather than adding a second frame. Two shared-package fixes in DropdownPopup. `kbd` hardcoded a ⌘ prefix (cannot express ⌥⌘S, wrong on non-Apple keyboards) and rendered only on hover. And `placement` had to move to useMenuStore — Ariakit reads it off the store and ignores it on <Menu>. That one had a LIVE call site: SidePanel/Agents/Images.tsx passed placement="bottom", which type-errored and did nothing. tsc goes 819 -> 818 because of it. The right panel's open state also moves out of React state inside SidePanelGroup's subtree — which is exactly why the header could not reach it — into store.sidePanelOpen, reconciled to the imperative handle by one effect. Consequence to know: that state is now binary, so the default hides the ~50px icon rail main shows today; the header button is the replacement affordance. Measured in Chromium, not asserted: menu rows 44.0px, right edge 1381 vs button 1379, Escape unmounts and returns aria-expanded=false; right panel 0->352->0; bottom bar tabs 1->2 (+) ->3 (⌘T) ->2 (×), drag 315.3->475.0px, floor holding at 135.7px under a 700px overdrag, composer clear at 415.7 vs 584.7 and still clear at the floor; scrollWidth === clientWidth at 1440 and 390; open bar, 2 tabs and height all restored across reload; a DOM stamp on <main> survives the toggle, so the conversation never remounts. Upstream's Dock still resizes 427.4->592.1px. Failing-suite list is byte-identical to clean origin/main (81 files, same names); +1 suite and +8 tests are BottomBar.spec.tsx. Co-authored-by: Hanzo Dev <dev@hanzo.ai>
…
…
…
…
…
…
…
…
…
…
…
Hanzo Chat
The chat surface of the Hanzo AI cloud: multi-model chat with agents, tools, and retrieval, running on Hanzo's backend. Live at hanzo.chat.
Hanzo Chat is a sibling to hanzo.app (the app builder) and the Hanzo console (admin). All inference, code execution, and web search route through the unified Hanzo API at api.hanzo.ai/v1, and sign-in is federated to Hanzo IAM (hanzo.id).
Features
- Multi-model chat — the Zen model family and other frontier models, served through
api.hanzo.ai. - Agents — build agents in the thread, or run your Hanzo Cloud agents (
/v1/agents) with an/agentcommand or@mention. - MCP tools — connect Model Context Protocol servers for tool use.
- RAG — chat over your own files and documents.
- Web search — grounded answers via Hanzo web search.
- Code interpreter — run code in a sandboxed runtime.
- Image generation — generate images inline.
- Guest chat — try a free Zen model with no account (optional, off by default).
Requirements
- Node.js 24 (see
.nvmrc) - pnpm 10
- A Hanzo API key — get one at hanzo.ai/dashboard
Quick start (Docker)
git clone https://github.com/hanzoai/chat.git
cd chat
cp .env.example .env # set HANZO_API_KEY
make up
Open http://localhost:3080. make up starts the full stack (app, MongoDB, Meilisearch) from compose.yml; make down stops it.
Development
pnpm install # install workspace dependencies
pnpm build:packages # build the shared workspace packages
pnpm backend:dev # API server on :3080 (nodemon)
pnpm frontend:dev # Vite client dev server (second terminal)
Tests and checks:
pnpm test:all # all workspace tests
pnpm e2e # Playwright end-to-end tests
pnpm lint # ESLint
pnpm format # Prettier
Configuration
Secrets live in .env; the model catalog and endpoints live in chat.yaml (copy chat.example.yaml). Key variables:
HANZO_API_KEY= # Hanzo API key — inference, tools, search
MONGO_URI= # MongoDB connection — chat history, users
JWT_SECRET= # session token signing
CREDS_KEY= # credential encryption
CREDS_IV=
Sign-in is federated to Hanzo IAM over OpenID Connect (OPENID_ISSUER=https://hanzo.id, client hanzo-chat).
Workspace
api/ Express backend (:3080) — routes, controllers, Mongoose models
client/ React frontend (Vite)
packages/ data-provider · data-schemas · api · client · agents · mcp
Documentation
- Docs: https://hanzo.ai/docs/chat
- Deployment, IAM, and platform notes:
docs/ - Issues: https://github.com/hanzoai/chat/issues
License
Languages
TypeScript
68.3%
JavaScript
22%
Python
6.5%
HTML
2.1%
CSS
0.5%
Other
0.5%