@bigduu/lotus 2026.6.3 → 2026.6.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +148 -71
- package/README.zh-CN.md +184 -0
- package/dist/assets/{App-W1Kf_qp4.js → App-DGiMC-bc.js} +9 -9
- package/dist/assets/{MetricsService-CD6PrhIR.js → MetricsService-BwJoJM1I.js} +1 -1
- package/dist/assets/{SubAgentsPanel-DK1z7F4I.js → SubAgentsPanel-B7tWf8Y_.js} +1 -1
- package/dist/assets/{architectureDiagram-3BPJPVTR-m5clV_D3.js → architectureDiagram-3BPJPVTR-BebuBU7Q.js} +1 -1
- package/dist/assets/{blockDiagram-GPEHLZMM-CtzVuvsA.js → blockDiagram-GPEHLZMM-COwJ0V9U.js} +1 -1
- package/dist/assets/{c4Diagram-AAUBKEIU-ZdWEf_4Q.js → c4Diagram-AAUBKEIU-Dzi1f7rv.js} +1 -1
- package/dist/assets/{chunk-2J33WTMH-DeO3muwK.js → chunk-2J33WTMH-gGTSUslI.js} +1 -1
- package/dist/assets/{chunk-4BX2VUAB-BQCEOQJh.js → chunk-4BX2VUAB-Ba2pD5h_.js} +1 -1
- package/dist/assets/{chunk-55IACEB6-DXiyRneN.js → chunk-55IACEB6-Bgc2fQut.js} +1 -1
- package/dist/assets/{chunk-727SXJPM-C29YUAhR.js → chunk-727SXJPM-BbDzQZvf.js} +1 -1
- package/dist/assets/{chunk-AQP2D5EJ-DEmrjkPB.js → chunk-AQP2D5EJ-CNJIXQcJ.js} +1 -1
- package/dist/assets/{chunk-FMBD7UC4-D-iTD3Nb.js → chunk-FMBD7UC4-DxIxh6Ds.js} +1 -1
- package/dist/assets/{chunk-ND2GUHAM-Cd1xcwBQ.js → chunk-ND2GUHAM-s08Pzboe.js} +1 -1
- package/dist/assets/{chunk-QZHKN3VN-CGXe1Q5G.js → chunk-QZHKN3VN-BAzhPVsB.js} +1 -1
- package/dist/assets/classDiagram-4FO5ZUOK-DXcpWQD1.js +1 -0
- package/dist/assets/classDiagram-v2-Q7XG4LA2-DXcpWQD1.js +1 -0
- package/dist/assets/{cose-bilkent-S5V4N54A-De8zo0Tj.js → cose-bilkent-S5V4N54A-_w_xFpmi.js} +1 -1
- package/dist/assets/{dagre-BM42HDAG-Ddh9ynKq.js → dagre-BM42HDAG-DBuvyGu5.js} +1 -1
- package/dist/assets/{diagram-2AECGRRQ-C1X08pMD.js → diagram-2AECGRRQ-DBhlnTP6.js} +1 -1
- package/dist/assets/{diagram-5GNKFQAL-3x5G_-3R.js → diagram-5GNKFQAL-CfeEom2U.js} +1 -1
- package/dist/assets/{diagram-KO2AKTUF-B3LBcH_F.js → diagram-KO2AKTUF-BdVfrz_2.js} +1 -1
- package/dist/assets/{diagram-LMA3HP47-DTrWMl7o.js → diagram-LMA3HP47-CTH2TNUy.js} +1 -1
- package/dist/assets/{diagram-OG6HWLK6-BN3jcrDF.js → diagram-OG6HWLK6-BQM5_eCb.js} +1 -1
- package/dist/assets/{erDiagram-TEJ5UH35-Js5zjoj6.js → erDiagram-TEJ5UH35-B-21iS1U.js} +1 -1
- package/dist/assets/{flowDiagram-I6XJVG4X-DQRu1AbM.js → flowDiagram-I6XJVG4X-Pvjq-IGZ.js} +1 -1
- package/dist/assets/{ganttDiagram-6RSMTGT7-kCuyAcLR.js → ganttDiagram-6RSMTGT7-CsT06Nub.js} +1 -1
- package/dist/assets/{gitGraphDiagram-PVQCEYII-DUdINXyz.js → gitGraphDiagram-PVQCEYII-CHvUQAnK.js} +1 -1
- package/dist/assets/{index-3W1LV1SA.js → index-B2KftsrY.js} +1 -1
- package/dist/assets/{index-BJ3ANmOE.js → index-BLvTnbVM.js} +1 -1
- package/dist/assets/{index-Brgf2uQ2.js → index-CGPDORYG.js} +1 -1
- package/dist/assets/{index-CiGtwhMP.js → index-CWR9aGNs.js} +1 -1
- package/dist/assets/{index-BWbOqwQp.js → index-Czh1rLTB.js} +1 -1
- package/dist/assets/{index-DcsLc2YZ.js → index-DUN61Z32.js} +1 -1
- package/dist/assets/{index-CvZX-t6A.js → index-DlPD5pVw.js} +1 -1
- package/dist/assets/{index-CGYY6DOm.js → index-DsVVUUnV.js} +1 -1
- package/dist/assets/{index-a-yHOCrM.js → index-DtdE5mvd.js} +3 -3
- package/dist/assets/{index-BCFtep9w.js → index-WsBNH02d.js} +1 -1
- package/dist/assets/{index-BzelPcGb.js → index-qH5MzXB_.js} +1 -1
- package/dist/assets/{infoDiagram-5YYISTIA-BH60Z_kW.js → infoDiagram-5YYISTIA-DVnYFnCA.js} +1 -1
- package/dist/assets/{ishikawaDiagram-YF4QCWOH-DX__2fqL.js → ishikawaDiagram-YF4QCWOH-BilctuFn.js} +1 -1
- package/dist/assets/{journeyDiagram-JHISSGLW-Btbf-Yv-.js → journeyDiagram-JHISSGLW-BvpNGUEX.js} +1 -1
- package/dist/assets/{kanban-definition-UN3LZRKU-CupC3Y8c.js → kanban-definition-UN3LZRKU-Dq1kXZPB.js} +1 -1
- package/dist/assets/{main-DPVz9gTW.js → main-BNHHYyvu.js} +3 -3
- package/dist/assets/{mindmap-definition-RKZ34NQL-CVDbvdpU.js → mindmap-definition-RKZ34NQL-BM5Yg_Wt.js} +1 -1
- package/dist/assets/{pieDiagram-4H26LBE5-DIBPALXz.js → pieDiagram-4H26LBE5-CxzR0EiZ.js} +1 -1
- package/dist/assets/{quadrantDiagram-W4KKPZXB-CgLsRlfY.js → quadrantDiagram-W4KKPZXB-C6qm5TrW.js} +1 -1
- package/dist/assets/{requirementDiagram-4Y6WPE33-DuXsETX3.js → requirementDiagram-4Y6WPE33-Bfok6_yJ.js} +1 -1
- package/dist/assets/{sankeyDiagram-5OEKKPKP-C0arEfXn.js → sankeyDiagram-5OEKKPKP-CO-kBES5.js} +1 -1
- package/dist/assets/{sequenceDiagram-3UESZ5HK-FBSZs6xe.js → sequenceDiagram-3UESZ5HK-BA68KNvF.js} +1 -1
- package/dist/assets/{stateDiagram-AJRCARHV-BJ3Io4MV.js → stateDiagram-AJRCARHV-CPFv6QjH.js} +1 -1
- package/dist/assets/{stateDiagram-v2-BHNVJYJU-DGyYrZ6l.js → stateDiagram-v2-BHNVJYJU-C6FuGkH6.js} +1 -1
- package/dist/assets/{timeline-definition-PNZ67QCA-C3HbQJxG.js → timeline-definition-PNZ67QCA-DqkH57r5.js} +1 -1
- package/dist/assets/{vendor-charts-COf182R8.js → vendor-charts-C2gnH3Bq.js} +1 -1
- package/dist/assets/{vendor-mermaid-DT6Z2ihp.js → vendor-mermaid-EqIWbuOm.js} +3 -3
- package/dist/assets/{vendor-pdf-9vTbgVuO.js → vendor-pdf-BerqhPFN.js} +3 -3
- package/dist/assets/{vennDiagram-CIIHVFJN-uaSWNW5M.js → vennDiagram-CIIHVFJN-CakMDBwB.js} +1 -1
- package/dist/assets/{wardley-L42UT6IY-HJvlv64_.js → wardley-L42UT6IY-B1oAtJIM.js} +1 -1
- package/dist/assets/{wardleyDiagram-YWT4CUSO-WC_DkfK4.js → wardleyDiagram-YWT4CUSO-CxG6z1Fg.js} +1 -1
- package/dist/assets/{xychartDiagram-2RQKCTM6-jDKleAT-.js → xychartDiagram-2RQKCTM6-BCpc7XLL.js} +1 -1
- package/dist/index.html +2 -2
- package/package.json +1 -1
- package/dist/assets/classDiagram-4FO5ZUOK-CFu2BDCx.js +0 -1
- package/dist/assets/classDiagram-v2-Q7XG4LA2-CFu2BDCx.js +0 -1
package/README.md
CHANGED
|
@@ -1,107 +1,184 @@
|
|
|
1
|
-
# Lotus
|
|
1
|
+
# Lotus — The Living Interface
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
> 📖 中文版请看 **[README.zh-CN.md](./README.zh-CN.md)**
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
> React + Vite UI layer for Zenith · `@bigduu/lotus`
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
- Frontend unit/integration tests: Vitest
|
|
9
|
-
- Browser E2E tests: Playwright (`e2e/`)
|
|
10
|
-
- npm distribution artifact: `dist/` (package name: `@bigduu/lotus`)
|
|
7
|
+
---
|
|
11
8
|
|
|
12
|
-
|
|
13
|
-
- `bodhi/`: Tauri desktop shell that consumes Lotus build output
|
|
14
|
-
- `bamboo/`: Rust backend service
|
|
9
|
+
## What this is
|
|
15
10
|
|
|
16
|
-
|
|
11
|
+
Lotus is the pane of glass between you and an AI agent. You type, it answers — but the real magic is that **you can watch it think and work**: which file it's reading, which tool it's calling, the to-do list it drew up, the diagram it sketched, all streaming onto the screen live. It turns an otherwise black-box AI into a transparent, observable teammate you can interrupt at any time.
|
|
17
12
|
|
|
18
|
-
|
|
19
|
-
- npm
|
|
20
|
-
- Rust (required only when integrating with bamboo or running some E2E flows)
|
|
13
|
+
---
|
|
21
14
|
|
|
22
|
-
##
|
|
15
|
+
## Key capabilities at a glance
|
|
23
16
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
17
|
+
| Capability | What it gives you |
|
|
18
|
+
| --- | --- |
|
|
19
|
+
| **Live event stream** | Token-by-token answers, reasoning and tool calls over SSE, batched per animation frame (`requestAnimationFrame`) |
|
|
20
|
+
| **Command palette** | `Cmd/Ctrl + K` — one keystroke to jump to sessions, settings, themes, new tasks |
|
|
21
|
+
| **Settings center** | Providers, model limits, MCP, hooks, schedules, env vars, keyword masking, metrics dashboard |
|
|
22
|
+
| **Live to-do list** | The agent's plan, updating its progress as it runs |
|
|
23
|
+
| **Question dialog** | Pops up when the agent needs clarification; options + free text |
|
|
24
|
+
| **Mermaid rendering** | Diagrams render inline with zoom/pan and one-click AI fix |
|
|
25
|
+
| **Skill management** | Browse and toggle agent skills |
|
|
26
|
+
| **Multi-pane** | Split the layout to view multiple sessions side by side |
|
|
27
|
+
| **Bilingual + theming** | zh-CN / en-US, light/dark, VDI safe mode |
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## Architecture
|
|
32
|
+
|
|
33
|
+
Lotus is a **pure frontend** (React 18 + Vite 6 + TypeScript). It carries no business backend of its own — all agent execution lives in **bamboo** (the local Rust runtime). Lotus talks to bamboo over **HTTP + SSE**: plain requests via REST (`/api/v1/...`), live output via Server-Sent Events (`/api/v1/events/{sessionId}`, auto-reconnecting through the browser's native `EventSource`). The same build artifact (`dist/`) is loaded by the **bodhi** desktop shell and is equally runnable in a plain browser for development.
|
|
34
|
+
|
|
35
|
+
```mermaid
|
|
36
|
+
flowchart LR
|
|
37
|
+
subgraph Browser["Browser / Bodhi WebView"]
|
|
38
|
+
UI["Lotus UI<br/>React + Vite"]
|
|
39
|
+
ES["EventSource (SSE)"]
|
|
40
|
+
REST["fetch (REST)"]
|
|
41
|
+
Store["State: Jotai + Zustand<br/>Storage: Dexie (IndexedDB)"]
|
|
42
|
+
UI --- Store
|
|
43
|
+
UI --- ES
|
|
44
|
+
UI --- REST
|
|
45
|
+
end
|
|
46
|
+
ES -- "/api/v1/events/{sessionId}" --> Bamboo
|
|
47
|
+
REST -- "/api/v1/..." --> Bamboo
|
|
48
|
+
Bamboo["bamboo<br/>local Rust agent runtime"]
|
|
28
49
|
```
|
|
29
50
|
|
|
30
|
-
|
|
51
|
+
**Stack highlights (verified in `package.json`):**
|
|
31
52
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
53
|
+
- **UI / components**: Ant Design 5 (`antd`, `@ant-design/icons`)
|
|
54
|
+
- **State**: Jotai (`jotai`, `jotai-family`) for fine-grained streaming atoms + Zustand (`zustand`) for app/UI stores
|
|
55
|
+
- **Local storage**: Dexie (IndexedDB) — `src/services/storage/StorageDb.ts`
|
|
56
|
+
- **Markdown**: `react-markdown` + `remark-gfm` / `remark-breaks` + `rehype-sanitize` + `react-syntax-highlighter`
|
|
57
|
+
- **Diagrams**: `mermaid` (with `react-zoom-pan-pinch` viewer)
|
|
58
|
+
- **Metrics charts**: `recharts`
|
|
59
|
+
- **Export**: `jspdf` + `html2canvas`
|
|
60
|
+
- **i18n**: `i18next` + `react-i18next` (locales: `zh-CN`, `en-US`)
|
|
61
|
+
- **Virtualization**: `@tanstack/react-virtual`
|
|
62
|
+
|
|
63
|
+
**Source map (`src/`):**
|
|
64
|
+
|
|
65
|
+
```text
|
|
66
|
+
src/
|
|
67
|
+
├── app/ # App bootstrap, MainLayout (sidebar + panes + settings)
|
|
68
|
+
├── pages/
|
|
69
|
+
│ ├── ChatPage/ # The chat experience (the flagship)
|
|
70
|
+
│ │ ├── streaming/ # Jotai atoms + RAF-batched streaming state
|
|
71
|
+
│ │ ├── hooks/ # useAgentEventSubscription, useChatManager, ...
|
|
72
|
+
│ │ ├── components/ # ~50 cards: ToolCallCard, TodoListDisplay,
|
|
73
|
+
│ │ │ # StreamingMessageCard, PlanMessageCard, ...
|
|
74
|
+
│ │ ├── conversation/ workspace/ inspector/ services/ utils/
|
|
75
|
+
│ ├── SettingsPage/ # SystemSettingsPage + tabs (providers, MCP, metrics...)
|
|
76
|
+
│ ├── SetupPage/ PasswordGatePage/
|
|
77
|
+
├── components/ # Skill, TodoList, QuestionDialog
|
|
78
|
+
├── shared/
|
|
79
|
+
│ ├── components/ # CommandPalette, MermaidChart, Markdown, ResizableSplit...
|
|
80
|
+
│ ├── store/ # Zustand stores (appStore, theme, settingsView, uiLayout...)
|
|
81
|
+
│ ├── i18n/ # zh-CN + en-US resources
|
|
82
|
+
│ ├── services/ hooks/ theme/ types/ utils/
|
|
83
|
+
├── services/ # HTTP/SSE clients: api/, chat/ (AgentService), config/,
|
|
84
|
+
│ # mcp/, metrics/, skill/, workspace/, storage/, ...
|
|
39
85
|
```
|
|
40
86
|
|
|
41
|
-
|
|
87
|
+
---
|
|
42
88
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
-
|
|
46
|
-
|
|
89
|
+
## Signature deep-dives
|
|
90
|
+
|
|
91
|
+
### Real-time SSE event stream
|
|
92
|
+
|
|
93
|
+
This is the soul of Lotus. `src/services/chat/AgentService.ts` declares an event vocabulary mirroring bamboo's — dozens of types from `token`, `reasoning_token`, `tool_token`, through `tool_start` / `tool_complete` / `tool_error`, `task_list_updated`, `token_budget_updated`, `context_compression_status`, `sub_agent_started`, `need_clarification`, `plan_mode_entered`, and more. The UI subscribes per session via the native `EventSource` (with `withCredentials`, auto-reconnect, and `Last-Event-ID` resume) on `/api/v1/events/{sessionId}`; an account-level broadcast runs over a single long-lived feed in `accountFeed.ts`.
|
|
94
|
+
|
|
95
|
+
To keep token-by-token output buttery without melting the browser, streaming state is held in **Jotai atoms** and **committed per animation frame** via `requestAnimationFrame` in `pages/ChatPage/streaming/useKeyedRafAtomState.ts` — you get a smooth typewriter effect instead of a re-render per token.
|
|
96
|
+
|
|
97
|
+
### The chat experience
|
|
98
|
+
|
|
99
|
+
`pages/ChatPage` isn't a text box — it's a whole vocabulary of cards. Every kind of agent activity has its own visualization: `StreamingMessageCard` (live answers), `ToolCallCard` / `ToolResultCard` / `ToolSessionCard` (the full lifecycle of a tool call), `PlanMessageCard` (plan mode), `QuestionMessageCard` (clarifications), `FileChangeViewer` (diffs of edited files), `TokenUsageDisplay` (context budget), `SessionSummaryCard` (compression summaries) — roughly 50 components in all. `MultiPaneChatView` + `ResizableSplit` let you split panes for side-by-side sessions; long lists stay smooth via `@tanstack/react-virtual`.
|
|
47
100
|
|
|
48
|
-
|
|
101
|
+
### Command palette
|
|
49
102
|
|
|
50
|
-
|
|
103
|
+
Hit `Cmd/Ctrl + K` (bound in `app/MainLayout.tsx` and `shared/components/CommandPalette/index.tsx`). It unifies two entry types: **actions** (open Provider settings, model limits, prompts, skills, MCP, workflows, hooks, schedules, sessions, metrics, keyword masking, toggle theme, new task, collapse sidebar…) and **session search** (fuzzy-jump by title, with pinned markers). Every label is i18n-driven, identical across zh/en.
|
|
104
|
+
|
|
105
|
+
### Settings center
|
|
106
|
+
|
|
107
|
+
`pages/SettingsPage/components/SystemSettingsPage` is a tabbed console, lazy-loaded to keep startup light. Verified tabs: **Providers** (`ProviderSettings`), **Model limits** (`ModelLimitsSettings`), **Prompts** (`SystemPromptManager`), **MCP** (server forms + management), **Workflows**, **Hooks**, **Schedules**, **Sessions**, **Env vars**, **Keyword masking**, **Notifications**, **Mermaid settings**, **Access password**, **Network**, and a `recharts`-powered **Metrics dashboard** (`UnifiedMetricsDashboard` with token charts, memory trends, model distribution, forward-endpoint distribution, and more).
|
|
108
|
+
|
|
109
|
+
### Skills · questions · to-dos · Mermaid
|
|
110
|
+
|
|
111
|
+
- **Skill** (`src/components/Skill`): `SkillCard` / `SkillSelector` / `SkillManager` browse agent skills, toggle enable/disable, show license tags.
|
|
112
|
+
- **Question dialog** (`src/components/QuestionDialog`): pops up when the stream emits `need_clarification`, supports preset options and free text, and remembers per-session reasoning effort.
|
|
113
|
+
- **To-do list** (`src/components/TodoList` + `pages/ChatPage/components/TodoListDisplay`): live progress, status icons, dependencies and notes driven by `task_list_updated` and friends; collapsible and pinnable.
|
|
114
|
+
- **Mermaid** (`shared/components/MermaidChart`): lazy-loaded renderer, fits very wide diagrams to the viewport, zoom/pan via `react-zoom-pan-pinch`; on render failure exposes an `onFix` callback to hand the error back to the AI.
|
|
115
|
+
|
|
116
|
+
---
|
|
117
|
+
|
|
118
|
+
## Quick start
|
|
119
|
+
|
|
120
|
+
**Prerequisites:** Node.js LTS (20+) and npm. A running **bamboo** backend for live agent features (see below).
|
|
51
121
|
|
|
52
122
|
```bash
|
|
53
|
-
|
|
54
|
-
|
|
123
|
+
npm install
|
|
124
|
+
npm run dev # Vite dev server → http://localhost:1420
|
|
55
125
|
```
|
|
56
126
|
|
|
57
|
-
|
|
127
|
+
**Run against bamboo** — in a second terminal, from the repo root:
|
|
58
128
|
|
|
59
129
|
```bash
|
|
60
|
-
|
|
61
|
-
|
|
130
|
+
cargo run --manifest-path bamboo/Cargo.toml --bin bamboo -- \
|
|
131
|
+
serve --port 9562 --bind 127.0.0.1 --data-dir /tmp/bamboo-data
|
|
62
132
|
```
|
|
63
133
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
`package.json` is configured with:
|
|
67
|
-
- package name: `@bigduu/lotus`
|
|
68
|
-
- `publishConfig.access`: `public`
|
|
69
|
-
- `prepack`: automatically runs `npm run build` before publish
|
|
134
|
+
Lotus defaults to the backend at `http://127.0.0.1:9562/v1` (overridable via `VITE_BACKEND_BASE_URL`; see `src/shared/utils/backendBaseUrl.ts`).
|
|
70
135
|
|
|
71
|
-
|
|
136
|
+
### Verified scripts (`package.json`)
|
|
72
137
|
|
|
73
138
|
```bash
|
|
74
|
-
|
|
75
|
-
npm
|
|
76
|
-
npm
|
|
139
|
+
npm run dev # Vite dev server (port 1420)
|
|
140
|
+
npm run build # tsc + vite build → dist/
|
|
141
|
+
npm run preview # preview the production build
|
|
142
|
+
npm run type-check # tsc --noEmit
|
|
143
|
+
npm run lint # eslint src (lint:fix to autofix)
|
|
144
|
+
npm run format # prettier --write (format:check to verify)
|
|
145
|
+
|
|
146
|
+
npm run test # vitest (watch) test:ui / test:coverage
|
|
147
|
+
npm run test:run # vitest run (one-shot)
|
|
148
|
+
npm run test:e2e # Playwright (delegates to ./e2e)
|
|
149
|
+
npm run test:e2e:browser # Playwright against http://localhost:1420
|
|
150
|
+
npm run test:e2e:with-server # boots a throwaway bamboo, then runs Playwright
|
|
151
|
+
|
|
152
|
+
npm run pack:dry-run # inspect the npm package contents
|
|
77
153
|
```
|
|
78
154
|
|
|
79
|
-
|
|
155
|
+
### Packaging & branding (verified)
|
|
80
156
|
|
|
81
|
-
|
|
157
|
+
```bash
|
|
158
|
+
npm run build:bamboo-package # build, then stage dist into bamboo as a prebuilt frontend
|
|
159
|
+
npm run build:public # rebrand (public) + build
|
|
160
|
+
npm run build:internal # rebrand (internal) + build
|
|
161
|
+
npm run rebrand:check # verify branding state
|
|
162
|
+
```
|
|
82
163
|
|
|
83
|
-
|
|
84
|
-
- Tag push: `v*` or `lotus-v*`
|
|
85
|
-
- Manual trigger: `workflow_dispatch`
|
|
164
|
+
Published as **`@bigduu/lotus`** (`publishConfig.access: public`); `prepack` runs `npm run build` automatically.
|
|
86
165
|
|
|
87
|
-
|
|
166
|
+
---
|
|
88
167
|
|
|
89
|
-
|
|
168
|
+
## The rest of the stack
|
|
90
169
|
|
|
91
|
-
|
|
92
|
-
2. In GitHub repo settings, open `Settings -> Secrets and variables -> Actions`.
|
|
93
|
-
3. Add a repository secret named `NPM_TOKEN`.
|
|
94
|
-
4. The workflow authenticates with `NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}`.
|
|
170
|
+
Lotus is the UI layer within the Zenith monorepo. Sibling modules:
|
|
95
171
|
|
|
96
|
-
|
|
172
|
+
- [`../bamboo`](../bamboo) — local-first Rust agent runtime (the execution engine Lotus talks to over HTTP + SSE)
|
|
173
|
+
- [`../bodhi`](../bodhi) — desktop AI product surface (Tauri shell that loads Lotus's `dist/`)
|
|
174
|
+
- [`../bodhi-server`](../bodhi-server) — Go backend (auth / persistence / billing + quota / LLM proxy)
|
|
175
|
+
- [`../pavilion`](../pavilion) — official website & docs
|
|
176
|
+
- [`..`](..) — Zenith root (monorepo entry, submodule pointers, release train)
|
|
97
177
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
├── vite.config.ts # Vite configuration
|
|
106
|
-
└── package.json # package metadata and scripts
|
|
107
|
-
```
|
|
178
|
+
**In-module docs:**
|
|
179
|
+
|
|
180
|
+
- Frontend docs root: [`docs/README.md`](./docs/README.md)
|
|
181
|
+
- Frontend architecture: [`docs/architecture/FRONTEND_ARCHITECTURE.md`](./docs/architecture/FRONTEND_ARCHITECTURE.md)
|
|
182
|
+
- Design spec: [`docs/DESIGN_SPEC.md`](./docs/DESIGN_SPEC.md)
|
|
183
|
+
- Feature docs (Command Selector / Question Dialog / Mermaid): [`docs/features/`](./docs/features/)
|
|
184
|
+
- Development guides: [`docs/development/`](./docs/development/)
|
package/README.zh-CN.md
ADDED
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
# Lotus · 莲花交互层
|
|
2
|
+
|
|
3
|
+
> 📖 For English, see **[README.md](./README.md)**
|
|
4
|
+
|
|
5
|
+
> Zenith 的 React + Vite UI 层 · `@bigduu/lotus`
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 这是什么
|
|
10
|
+
|
|
11
|
+
Lotus 是你和 AI 智能体对话的那块「玻璃」。你打字、它回答——但更重要的是,你能**看见它在想什么、在做什么**:它正在读哪个文件、调用哪个工具、列了什么待办清单、画了什么流程图,全部实时呈现在屏幕上。它把一个原本黑箱的 AI,变成一个透明、可观察、可随时打断的工作伙伴。
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## 一览能力
|
|
16
|
+
|
|
17
|
+
| 能力 | 说明 |
|
|
18
|
+
| --- | --- |
|
|
19
|
+
| **实时事件流** | 通过 SSE 逐字渲染回答、推理、工具调用,帧级流畅(`requestAnimationFrame` 批处理) |
|
|
20
|
+
| **命令面板** | `Cmd/Ctrl + K` 一键跳转会话、设置、主题、新建任务 |
|
|
21
|
+
| **设置中心** | Providers、模型上限、MCP、Hooks、计划任务、环境变量、关键词脱敏、指标仪表盘 |
|
|
22
|
+
| **待办清单** | 智能体的任务计划随执行实时更新进度 |
|
|
23
|
+
| **追问对话** | 智能体需要澄清时弹出,支持选项与自由输入 |
|
|
24
|
+
| **Mermaid 渲染** | 回答中的图表自动渲染,可缩放拖拽、错误可一键让 AI 修复 |
|
|
25
|
+
| **技能管理** | 浏览、启用/停用智能体技能 |
|
|
26
|
+
| **多窗格** | 可拆分布局并排查看多个会话 |
|
|
27
|
+
| **双语 + 主题** | 中英文界面,明暗主题,VDI 安全模式 |
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## 架构
|
|
32
|
+
|
|
33
|
+
Lotus 是一个**纯前端**项目(React 18 + Vite 6 + TypeScript)。它本身不含业务逻辑后端——所有智能体的执行都发生在 **bamboo**(本地 Rust 运行时)里。Lotus 通过 **HTTP + SSE** 与 bamboo 对话:普通请求走 REST(`/api/v1/...`),实时输出走 Server-Sent Events(`/api/v1/events/{sessionId}`,由浏览器原生 `EventSource` 自动重连)。同一份构建产物(`dist/`)既被 **bodhi** 桌面外壳加载,也可在浏览器里直接开发调试。
|
|
34
|
+
|
|
35
|
+
```mermaid
|
|
36
|
+
flowchart LR
|
|
37
|
+
subgraph Browser["Browser / Bodhi WebView"]
|
|
38
|
+
UI["Lotus UI<br/>React + Vite"]
|
|
39
|
+
ES["EventSource (SSE)"]
|
|
40
|
+
REST["fetch (REST)"]
|
|
41
|
+
Store["State: Jotai + Zustand<br/>Storage: Dexie (IndexedDB)"]
|
|
42
|
+
UI --- Store
|
|
43
|
+
UI --- ES
|
|
44
|
+
UI --- REST
|
|
45
|
+
end
|
|
46
|
+
ES -- "/api/v1/events/{sessionId}" --> Bamboo
|
|
47
|
+
REST -- "/api/v1/..." --> Bamboo
|
|
48
|
+
Bamboo["bamboo<br/>local Rust agent runtime"]
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
**关键技术(已在 `package.json` 中验证):**
|
|
52
|
+
|
|
53
|
+
- **UI / 组件**: Ant Design 5 (`antd`, `@ant-design/icons`)
|
|
54
|
+
- **状态**: Jotai (`jotai`, `jotai-family`) 用于细粒度流式原子 + Zustand (`zustand`) 用于应用/UI 存储
|
|
55
|
+
- **本地存储**: Dexie (IndexedDB) — `src/services/storage/StorageDb.ts`
|
|
56
|
+
- **Markdown**: `react-markdown` + `remark-gfm` / `remark-breaks` + `rehype-sanitize` + `react-syntax-highlighter`
|
|
57
|
+
- **图表**: `mermaid`(配 `react-zoom-pan-pinch` 查看器)
|
|
58
|
+
- **指标图表**: `recharts`
|
|
59
|
+
- **导出**: `jspdf` + `html2canvas`
|
|
60
|
+
- **国际化**: `i18next` + `react-i18next`(语言:`zh-CN`、`en-US`)
|
|
61
|
+
- **虚拟化**: `@tanstack/react-virtual`
|
|
62
|
+
|
|
63
|
+
**源码地图(`src/`):**
|
|
64
|
+
|
|
65
|
+
```text
|
|
66
|
+
src/
|
|
67
|
+
├── app/ # App bootstrap, MainLayout (sidebar + panes + settings)
|
|
68
|
+
├── pages/
|
|
69
|
+
│ ├── ChatPage/ # The chat experience (the flagship)
|
|
70
|
+
│ │ ├── streaming/ # Jotai atoms + RAF-batched streaming state
|
|
71
|
+
│ │ ├── hooks/ # useAgentEventSubscription, useChatManager, ...
|
|
72
|
+
│ │ ├── components/ # ~50 cards: ToolCallCard, TodoListDisplay,
|
|
73
|
+
│ │ │ # StreamingMessageCard, PlanMessageCard, ...
|
|
74
|
+
│ │ ├── conversation/ workspace/ inspector/ services/ utils/
|
|
75
|
+
│ ├── SettingsPage/ # SystemSettingsPage + tabs (providers, MCP, metrics...)
|
|
76
|
+
│ ├── SetupPage/ PasswordGatePage/
|
|
77
|
+
├── components/ # Skill, TodoList, QuestionDialog
|
|
78
|
+
├── shared/
|
|
79
|
+
│ ├── components/ # CommandPalette, MermaidChart, Markdown, ResizableSplit...
|
|
80
|
+
│ ├── store/ # Zustand stores (appStore, theme, settingsView, uiLayout...)
|
|
81
|
+
│ ├── i18n/ # zh-CN + en-US resources
|
|
82
|
+
│ ├── services/ hooks/ theme/ types/ utils/
|
|
83
|
+
├── services/ # HTTP/SSE clients: api/, chat/ (AgentService), config/,
|
|
84
|
+
│ # mcp/, metrics/, skill/, workspace/, storage/, ...
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## 招牌深潜
|
|
90
|
+
|
|
91
|
+
### 实时事件流
|
|
92
|
+
|
|
93
|
+
这是 Lotus 的灵魂。`src/services/chat/AgentService.ts` 定义了与 bamboo 一一对应的事件类型——从 `token`、`reasoning_token`、`tool_token`,到 `tool_start` / `tool_complete` / `tool_error`、`task_list_updated`、`token_budget_updated`、`context_compression_status`、`sub_agent_started`、`need_clarification`、`plan_mode_entered` 等几十种。前端用浏览器原生 `EventSource`(带 `withCredentials`、自动重连、`Last-Event-ID` 续传)订阅每个会话的 `/api/v1/events/{sessionId}`;账号级广播则走 `accountFeed.ts` 的单一长连接。
|
|
94
|
+
|
|
95
|
+
为了让逐字输出既流畅又不拖垮浏览器,流式状态用 **Jotai 原子** 存储,并在 `pages/ChatPage/streaming/useKeyedRafAtomState.ts` 里用 `requestAnimationFrame` **按帧批量提交**——你看到的是丝滑的打字机效果,而不是每个 token 都触发一次重渲染。
|
|
96
|
+
|
|
97
|
+
### 对话体验
|
|
98
|
+
|
|
99
|
+
`pages/ChatPage` 不是一个聊天框,而是一整套「卡片」语言。每一种智能体活动都有对应的可视化组件:`StreamingMessageCard`(流式回答)、`ToolCallCard` / `ToolResultCard` / `ToolSessionCard`(工具调用全过程)、`PlanMessageCard`(计划模式)、`QuestionMessageCard`(追问)、`FileChangeViewer`(文件改动 diff)、`TokenUsageDisplay`(上下文预算)、`SessionSummaryCard`(上下文压缩摘要)等约 50 个组件。`MultiPaneChatView` + `ResizableSplit` 让你能拆分窗格并排看多个会话;长列表用 `@tanstack/react-virtual` 虚拟化保持流畅。
|
|
100
|
+
|
|
101
|
+
### 命令面板
|
|
102
|
+
|
|
103
|
+
按 `Cmd/Ctrl + K`(绑定在 `app/MainLayout.tsx` 与 `shared/components/CommandPalette/index.tsx`)即可呼出。它统一了两类入口:**动作**(打开 Provider 设置、模型上限、提示词、技能、MCP、工作流、Hooks、计划任务、会话、指标、关键词脱敏、切换主题、新建任务、折叠侧栏……)和**会话搜索**(按标题模糊匹配跳转,含置顶标记)。所有标签均走 i18n,中英文一致。
|
|
104
|
+
|
|
105
|
+
### 设置中心
|
|
106
|
+
|
|
107
|
+
`pages/SettingsPage/components/SystemSettingsPage` 是一个标签化的控制台,懒加载以保持启动轻量。已验证的标签包括:**Providers**(`ProviderSettings`)、**模型上限**(`ModelLimitsSettings`)、**提示词**(`SystemPromptManager`)、**MCP**(服务器表单与管理)、**工作流**、**Hooks**、**计划任务 / Schedules**、**会话 / Sessions**、**环境变量 / Env Vars**、**关键词脱敏 / Keyword Masking**、**通知 / Notifications**、**Mermaid 设置**、**访问密码 / Access Password**、**网络 / Network**,以及基于 `recharts` 的 **指标仪表盘 / Metrics**(`UnifiedMetricsDashboard`、token 图、内存趋势、模型分布、转发端点分布等)。
|
|
108
|
+
|
|
109
|
+
### 技能、追问、待办、Mermaid
|
|
110
|
+
|
|
111
|
+
- **技能 / Skill** (`src/components/Skill`): `SkillCard` / `SkillSelector` / `SkillManager` 浏览智能体技能,开关启用/停用,显示许可证标记。
|
|
112
|
+
- **追问对话 / Question dialog** (`src/components/QuestionDialog`): 当事件流出现 `need_clarification` 时弹出,支持预设选项与自由文本,并记住每个会话的推理强度(reasoning effort)。
|
|
113
|
+
- **待办清单 / To-do list** (`src/components/TodoList` + `pages/ChatPage/components/TodoListDisplay`): 随 `task_list_updated` 等事件实时刷新进度、状态图标、依赖与备注,可折叠、可置顶。
|
|
114
|
+
- **Mermaid 渲染** (`shared/components/MermaidChart`): 懒加载渲染器,超宽图自动适配视口,`react-zoom-pan-pinch` 缩放拖拽;渲染失败时提供 `onFix` 回调,把错误交给 AI 修复。
|
|
115
|
+
|
|
116
|
+
---
|
|
117
|
+
|
|
118
|
+
## 快速开始
|
|
119
|
+
|
|
120
|
+
**前置:** Node.js LTS (20+) 与 npm。实时智能体功能需要一个运行中的 **bamboo** 后端(见下文)。
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
npm install
|
|
124
|
+
npm run dev # Vite dev server → http://localhost:1420
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
**与 bamboo 联调** — 在第二个终端,从仓库根目录运行:
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
cargo run --manifest-path bamboo/Cargo.toml --bin bamboo -- \
|
|
131
|
+
serve --port 9562 --bind 127.0.0.1 --data-dir /tmp/bamboo-data
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
Lotus 默认连接 `http://127.0.0.1:9562/v1` 后端(可通过 `VITE_BACKEND_BASE_URL` 覆盖;见 `src/shared/utils/backendBaseUrl.ts`)。
|
|
135
|
+
|
|
136
|
+
### 常用脚本(`package.json`)
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
npm run dev # Vite dev server (port 1420)
|
|
140
|
+
npm run build # tsc + vite build → dist/
|
|
141
|
+
npm run preview # preview the production build
|
|
142
|
+
npm run type-check # tsc --noEmit
|
|
143
|
+
npm run lint # eslint src (lint:fix to autofix)
|
|
144
|
+
npm run format # prettier --write (format:check to verify)
|
|
145
|
+
|
|
146
|
+
npm run test # vitest (watch) test:ui / test:coverage
|
|
147
|
+
npm run test:run # vitest run (one-shot)
|
|
148
|
+
npm run test:e2e # Playwright (delegates to ./e2e)
|
|
149
|
+
npm run test:e2e:browser # Playwright against http://localhost:1420
|
|
150
|
+
npm run test:e2e:with-server # boots a throwaway bamboo, then runs Playwright
|
|
151
|
+
|
|
152
|
+
npm run pack:dry-run # inspect the npm package contents
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### 打包与品牌(已验证)
|
|
156
|
+
|
|
157
|
+
```bash
|
|
158
|
+
npm run build:bamboo-package # build, then stage dist into bamboo as a prebuilt frontend
|
|
159
|
+
npm run build:public # rebrand (public) + build
|
|
160
|
+
npm run build:internal # rebrand (internal) + build
|
|
161
|
+
npm run rebrand:check # verify branding state
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
以 **`@bigduu/lotus`** 发布(`publishConfig.access: public`);`prepack` 会自动运行 `npm run build`。
|
|
165
|
+
|
|
166
|
+
---
|
|
167
|
+
|
|
168
|
+
## 其余技术栈
|
|
169
|
+
|
|
170
|
+
Lotus 是 Zenith 单体仓库中的 UI 层,与以下模块协作:
|
|
171
|
+
|
|
172
|
+
- [`../bamboo`](../bamboo) — 本地优先的 Rust 智能体运行时(Lotus 通过 HTTP + SSE 对话的执行引擎)
|
|
173
|
+
- [`../bodhi`](../bodhi) — 桌面 AI 产品界面(加载 Lotus `dist/` 的 Tauri 外壳)
|
|
174
|
+
- [`../bodhi-server`](../bodhi-server) — Go 后端(认证 / 持久化 / 计费 + 配额 / LLM 代理)
|
|
175
|
+
- [`../pavilion`](../pavilion) — 官方网站与文档
|
|
176
|
+
- [`..`](..) — Zenith 根目录(单体仓库入口、子模块指针、发布列车)
|
|
177
|
+
|
|
178
|
+
**模块内文档:**
|
|
179
|
+
|
|
180
|
+
- 前端文档根目录: [`docs/README.md`](./docs/README.md)
|
|
181
|
+
- 前端架构: [`docs/architecture/FRONTEND_ARCHITECTURE.md`](./docs/architecture/FRONTEND_ARCHITECTURE.md)
|
|
182
|
+
- 设计规范: [`docs/DESIGN_SPEC.md`](./docs/DESIGN_SPEC.md)
|
|
183
|
+
- 功能文档(Command Selector / Question Dialog / Mermaid): [`docs/features/`](./docs/features/)
|
|
184
|
+
- 开发指南: [`docs/development/`](./docs/development/)
|