a2ui-render-in-dsh 0.1.1 → 0.1.2

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 CHANGED
@@ -2,13 +2,13 @@
2
2
 
3
3
  English | [中文](https://github.com/baihui-ai/a2ui-render-in-dsh/blob/main/README.zh.md)
4
4
 
5
- **A2UI interactive cards for the dsh web UI**: the agent adaptively renders **interactive, visual UI cards** right inside the conversation — quizzes, forms, dropdowns, product cards, ECharts charts, math function plots, Mermaid flowcharts/mind maps, KaTeX formulas, and step-by-step algorithm animations. User interactions flow back to the agent as plain-language messages, closing the loop.
5
+ **A2UI interactive cards for the dsh web UI**: the agent adaptively renders **interactive, visual UI cards** right inside the conversation — quizzes, forms, multi-step wizards, dropdowns, date pickers, product cards, sortable/filterable tables, ECharts charts, China map choropleths, math function plots, Mermaid flowcharts/mind maps, KaTeX formulas, Markdown long-form, image uploads, signature pads, and step-by-step algorithm animations. User interactions flow back to the agent as plain-language messages (images included), cards **stream in progressively** and can be **updated in place**, and everything visible is one click away from the clipboard.
6
6
 
7
7
  The UI protocol is [A2UI v0.9](https://github.com/google/A2UI) (a declarative Agent-to-UI protocol); rendering is powered by Ant Design X's official implementation, [`@ant-design/x-card`](https://www.npmjs.com/package/@ant-design/x-card).
8
8
 
9
- 📸 **[Feature showcase with GIFs → DEMO.md](https://github.com/baihui-ai/a2ui-render-in-dsh/blob/main/DEMO.md)**
9
+ 📸 **[Feature showcase with GIFs → DEMO.md](https://github.com/baihui-ai/a2ui-render-in-dsh/blob/main/DEMO.md)** · 🗺️ **[Scenario × component map](https://github.com/baihui-ai/a2ui-render-in-dsh/blob/main/docs/SCENARIOS.md)**
10
10
 
11
- ![Quiz interaction](https://raw.githubusercontent.com/baihui-ai/a2ui-render-in-dsh/main/docs/demo-quiz.gif)
11
+ ![Quiz interaction](https://raw.githubusercontent.com/baihui-ai/a2ui-render-in-dsh/main/docs/demo-study.gif)
12
12
 
13
13
  ---
14
14
 
@@ -18,21 +18,25 @@ The UI protocol is [A2UI v0.9](https://github.com/google/A2UI) (a declarative Ag
18
18
 
19
19
  ```
20
20
  a2ui-render-in-dsh (one npm package, a dsh bundle)
21
- ├─ Host half lib/index.js cordis plugin registering two agent tools
22
- │ ├─ a2ui_render renders a card (slim ~140-token description, always visible)
21
+ ├─ Host half lib/index.js cordis plugin registering three agent tools
22
+ │ ├─ a2ui_render renders a card (slim ~220-token description, always visible)
23
+ │ ├─ a2ui_update updates an already-rendered card in place (progress,
24
+ │ │ long tasks, live dashboards) via its surfaceId
23
25
  │ └─ a2ui_catalog returns the full component catalog & authoring
24
- │ rules (~975 tokens, loaded on demand, once)
25
- └─ Client half lib/client.js browser bundle registering the a2ui_render toolview
26
+ │ rules (loaded on demand, once per conversation)
27
+ └─ Client half lib/client.js browser bundle registering the toolviews
26
28
  ├─ x-card engine (A2UI command stream, data binding, action resolution)
27
- ├─ component catalog implementations (18 components, themed via --dsw-* tokens)
28
- └─ ECharts 6 / Mermaid 11 / KaTeX (fonts inlined) all bundled — zero external requests
29
+ ├─ component catalog implementations (44 components, themed via --dsw-* tokens)
30
+ ├─ streaming renderer (truncated-JSON repair cards appear while the model types)
31
+ └─ ECharts 6 / Mermaid 11 / KaTeX (fonts inlined) / China geoJSON all bundled
32
+ — zero external requests
29
33
  ```
30
34
 
31
35
  ### Key design decisions
32
36
 
33
- **1. Adaptive rendering, decided by the model.** Whether to use UI is entirely the model's call: the tool contract says "only when a card clearly beats prose". Verified both ways"quiz me" triggers a card, "explain X" stays plain text.
37
+ **1. Proactive rendering, decided by the model anchored on UI's purposes.** The tool contract frames the judgment as: would a card serve any of UI's four purposes better than prose? **Act** (the user must answer/choose/fill/adjust render a form), **browse** (the user wants to see or scan data — statistics, rankings, distributions, trends get a chart/table/map, and uncertain data never cancels the card: chart the best known, label the period, caveat in prose), **understand** (structure or notation aids comprehension math, code, flows, stepwise processes), or **feedback** (long multi-step work gets a progress card advanced via `a2ui_update`). None of the four → prose. Cards always **pair with prose**: the takeaway lives in 1–3 sentences of normal text, the structured content in the card, with no duplication. Grounded in HCI research (Norman's gulfs, the keyhole effect, external cognition) and verified with keyword-free prompts across all purposes plus prose negatives.
34
38
 
35
- **2. Skill-style context design (catalog on demand).** The full component catalog is NOT inlined in the tool description; it lives in a second tool, `a2ui_catalog`. Always-visible cost drops from ~1,200 to ~211 tokens (−82%). The model calls the catalog once before its first card in a conversation and reuses it for later cards; conversations that never draw a card pay nothing. The host validates component names and errors with a "call a2ui_catalog" hint, so the model can't silently guess wrong.
39
+ **2. Skill-style context design (catalog on demand).** The full component catalog is NOT inlined in the tool description; it lives in a second tool, `a2ui_catalog`. Always-visible cost stays at ~220 tokens even as the catalog grew to 44 components. The model calls the catalog once before its first card in a conversation and reuses it for later cards; conversations that never draw a card pay nothing. The host validates component names and errors with a "call a2ui_catalog" hint, so the model can't silently guess wrong.
36
40
 
37
41
  **3. Non-blocking answers over the native message path.** Submissions need no custom server channel: the client sends the submission through dsh's own `session.prompt` RPC as an ordinary user message. Messages are **plain language** (button label + chosen values, multi-line for forms) — readable for humans, parseable for the model, no raw JSON in the conversation:
38
42
 
@@ -46,16 +50,25 @@ Tracks: Backend, Data Analysis
46
50
 
47
51
  **5. Let the model do only what it's good at.** Function plotting: the model writes an expression (`tan(x)`); sampling and asymptote breaking are done by a built-in **safe expression evaluator** (whitelist shunting-yard parser, no eval, injection is rejected) — hand-enumerating data points would inevitably fail. Algorithm animations: the model simulates the algorithm into per-step frames (an LLM strength); playback, transitions, and controls belong to the component.
48
52
 
49
- **6. Fully self-contained display stack.** ECharts, Mermaid, and KaTeX (woff2 fonts as data URIs) are all bundled (~5MB, served locally, loaded once) — no CDN, works offline; light/dark theme follows the page automatically.
53
+ **6. Fully self-contained display stack.** ECharts, Mermaid, KaTeX (woff2 fonts as data URIs), and the China province geoJSON are all bundled (~5.5MB, served locally, loaded once) — no CDN, works offline; light/dark theme follows the page automatically.
54
+
55
+ **7. Live cards: streaming in, updating in place.** Cards render progressively while the model is still emitting JSON (a tolerant parser repairs the truncated stream and mounts complete components early), so a big dashboard appears piece by piece instead of after a long pause. And a rendered card is not frozen: `a2ui_update` addresses it by `surfaceId` to patch components or data in place — progress bars that actually move, task cards that fill in results, dashboards that refresh. Updates persist and replay after a page reload.
56
+
57
+ **8. Answers beyond text.** `Upload` (photos) and `Signature` (hand-drawn canvas) send images back through dsh's native prompt channel as real image parts — the model sees the picture, not a placeholder. `Suggestions` renders tappable follow-up chips that send themselves as the next user message. Voice recording is deliberately excluded: dsh's prompt channel carries text + images only.
50
58
 
51
59
  ## Highlights
52
60
 
53
61
  - 🎯 **Adaptive**: the model chooses text vs. card; verified reliable in both directions
54
- - 🪶 **Context-friendly**: skill-style catalog design, ~211 tokens always-visible
55
- - 💬 **Elegant answers**: plain-language submissions, not raw JSON strings
56
- - 🔒 **Submit-once locking**: forms can't double-submit, records persist; query buttons unaffected
57
- - 📊 **Full visualization family**: ECharts charts/dashboards, function plots, all Mermaid diagram types, KaTeX formulas (matrices are forced into formula rendering), video
58
- - 🎬 **Algorithm animations**: array/bars and grid/matrix forms, auto-detected; auto-plays once per card (component remounts never replay), manual replay, stepping, progress bar, legend
62
+ - 🪶 **Context-friendly**: skill-style catalog design, ~220 tokens always-visible for 44 components
63
+ - 💬 **Elegant answers**: plain-language submissions, not raw JSON strings; photos & signatures return as real images
64
+ - 🔒 **Submit-once locking**: forms can't double-submit, records persist, a "refill" button reopens them; query buttons unaffected
65
+ - **Streaming render**: cards appear progressively while the model is still writing the JSON
66
+ - 🔄 **In-place updates**: `a2ui_update` patches a live card by surfaceId moving progress bars, task cards that finish themselves, refreshing dashboards; survives page reloads
67
+ - 📊 **Full visualization family**: ECharts charts/dashboards, function plots, China map choropleth, all Mermaid diagram types, KaTeX formulas (matrices are forced into formula rendering), image compare slider, video
68
+ - 🎬 **Algorithm animations**: array/bars, grid/matrix, and graph/tree forms, auto-detected; auto-plays once per card (component remounts never replay), ↻ manual replay, stepping, progress bar, legend
69
+ - 🧾 **Interactive tables**: click-to-sort (numeric-aware), filter box, pagination, copy as TSV, CSV export, editable-table input
70
+ - 🧭 **Rich answer kit**: multi-step Wizard, Calendar date picking, drag-free RankList ordering, Suggestions follow-up chips, Upload, Signature
71
+ - 📋 **Quick copy everywhere**: Stat tiles click-copy, tables copy/export, CodeBlock copy, formulas copy their LaTeX, charts download as PNG, Markdown copies its source
59
72
  - ⛶ **Fullscreen zoom**: mind maps/flowcharts/charts/images go fullscreen with fit-to-viewport, wheel zoom + drag pan
60
73
  - 🧱 **Multi-column layout**: Grid for product comparisons and chart dashboards
61
74
  - 🎛️ **Complete input states**: dropdown single/multi select, preselection (dataModel seeds), component- and option-level disabling
@@ -85,18 +98,45 @@ Tracks: Backend, Data Analysis
85
98
  | `List` | `children, direction?` | List container |
86
99
  | `Divider` | — | Separator |
87
100
  | `Text` | `text, variant?: h1\|h2\|h3\|body\|caption\|strong` | Text |
101
+ | `Markdown` | `text` | **Rich long-form**: headings, bold/italic, links, lists, quotes, fenced code, `$...$` math; copy-source button |
88
102
  | `Image` | `url, alt?, width?, height?` | Images (incl. GIF), built-in fullscreen zoom |
89
103
  | `Tag` | `text, color?: blue\|green\|red\|orange\|gray` | Tag/badge |
90
104
  | `Math` | `tex, block?` | **KaTeX** formulas (fonts inlined, zero external requests); matrices/vectors must use this |
91
105
  | `Mermaid` | `code, caption?` | **Mermaid 11**: flowchart/mindmap/sequence/gantt etc., built-in fullscreen zoom |
92
- | `Chart` | `option, height?, functions?, xMin?, xMax?, samples?, yClip?` | **ECharts 6**: data mode (option verbatim) + function-plot mode (expressions sampled automatically, asymptote breaks), built-in fullscreen |
106
+ | `Chart` | `option, height?, functions?, params?, xMin?, xMax?, samples?, yClip?` | **ECharts 6**: data mode (option verbatim) + function-plot mode (expressions sampled automatically, asymptote breaks) + `params` live-bound constants (Slider→curve); fullscreen + PNG download |
107
+ | `Map` | `data, title?, unit?, height?` | **China choropleth**: province-level distribution (sales/users by region), geoJSON bundled |
93
108
  | `Video` | `url, poster?, loop?, muted?, autoplay?` | HTML5 video (mp4/webm) |
94
- | `Anim` | `frames, interval?, height?, autoplay?, labels?` | **Algorithm animation**: bars and grid/matrix forms auto-detected; auto-plays once per card per tab, ↻ replay / pause / step / reset / progress / legend |
109
+ | `ImageCompare` | `before, after` | Drag-divider before/after image comparison |
110
+ | `Anim` | `frames, interval?, height?, autoplay?, labels?` | **Algorithm animation**: bars, grid/matrix, and graph/tree (BFS/DFS, auto circle layout) forms auto-detected; auto-plays once per card per tab, ↻ replay / pause / step / reset / progress / legend |
95
111
  | `Button` | `label, variant?, submit?, action: {event: {name, context?}}` | Sends the submission; `submit` explicitly controls card locking |
96
112
  | `MultipleChoice` | `options, bind, maxAllowedSelections?, disabled?` | Flat multi/single select (`maxAllowedSelections: 1` = single), per-option disable |
97
113
  | `Select` | `options, bind, label?, placeholder?, multiple?, maxAllowedSelections?, disabled?` | **Dropdown**: single stores a value, multi stores an array; option descriptions/disabling |
98
114
  | `CheckBox` | `label, bind, disabled?` | Boolean toggle |
115
+ | `Slider` | `bind, label?, min?, max?, step?, unit?` | Numeric slider; pairs with Chart `params` for live parameter exploration |
116
+ | `Rate` | `bind, label?, max?` | Star rating |
117
+ | `Calc` | `expr, inputs, out, digits?` | Invisible derived value: live-recomputed expression written back to the data model (calculator engine) |
118
+ | `When` | `value, equals?/includes?/notEmpty?, children` | Conditional container: reveal follow-up fields on selection |
119
+ | `Tabs` | `tabs, children, bind?` | Tab switcher: dataset switching / content grouping |
120
+ | `Table` | `columns, rows, caption?, sortable?, filter?, pageSize?` | **Interactive tables**: click-to-sort (numeric-aware), filter box, pagination, copy TSV / CSV export; dictionary binding switches datasets |
121
+ | `Stat` | `label, value, unit?, trend?, hint?` | KPI tile, click to copy the value; combine in a Grid for metric overviews |
122
+ | `Steps` | `items` | Step list (done/current/pending) |
123
+ | `Progress` | `value, max?, label?` | Progress bar |
124
+ | `Timeline` | `items` | Timeline (history / event review) |
125
+ | `CodeBlock` | `code, language?, title?` | Code with line numbers, light highlighting, copy button |
126
+ | `Icon` | `name, size?, color?` | 32 built-in stroke icons |
127
+ | `Audio` | `url, title?` | Audio player |
128
+ | `Flashcard` | `front, back` | Tap-to-flip card (vocabulary / recall) |
129
+ | `Countdown` | `to?/seconds?, label?` | Live countdown |
99
130
  | `TextField` | `label?, placeholder?, multiline?, bind, disabled?` | Text input |
131
+ | `Wizard` | `steps, children, submitLabel?` | **Multi-step form**: one pane per step, prev/next + progress built in, final submit sends all collected fields |
132
+ | `Calendar` | `bind, label?, min?, max?` | Month-view date picker with range limits |
133
+ | `RankList` | `items, bind, label?` | Reorder options by priority; submits the ordered list |
134
+ | `EditableTable` | `columns, rows, bind, label?` | User edits cells inline; the whole grid submits |
135
+ | `Upload` | `bind?, label?, max?` | Image picker — chosen photos are sent back to the model as **real images** |
136
+ | `Signature` | `label?` | Handwritten signature pad; the drawing returns as an image |
137
+ | `Suggestions` | `items` | Tappable follow-up chips below an answer; tapping sends that question as the next user message |
138
+
139
+ **Inline math**: every text position (Text, option labels, table cells, steps, flashcards, animation captions) may embed KaTeX with `$...$` — math-quiz OPTIONS can be formulas. **Reactive bindings**: inputs write the data model and every `{"path"}` binding updates live — slider→curve (Chart `params`), choice→follow-up (When), input→computed result (Calc→Stat), switcher→dataset (Tabs / Table dictionary binding).
100
140
 
101
141
  Common to inputs: **preselect** by seeding `dataModel` at the bind path; **disable** via component-level `disabled: true` or per-option `disabled`. Data binding: `bind` is a write path WITHOUT a leading slash; display props read live values with `{"path": "/x"}` (WITH a slash).
102
142
 
@@ -109,7 +149,20 @@ Common to inputs: **preselect** by seeding `dataModel` at the bind path; **disab
109
149
  | dsh | `@deepseek-ai/dsh` ≥ 0.1.1-rc.1 with an initialized web profile (run `dsh web` once before installing) |
110
150
  | Node.js | ≥ 20 (with npm) |
111
151
 
112
- ### Option A · From source (recommended for now)
152
+ ### Option A · From npm (recommended)
153
+
154
+ ```sh
155
+ dsh plugin --profile web add a2ui-render-in-dsh
156
+ dsh web
157
+ ```
158
+
159
+ Zero runtime dependencies — two commands and you're done. If your npm mirror hasn't synced the latest version yet, point at the official registry explicitly:
160
+
161
+ ```sh
162
+ dsh plugin --profile web add a2ui-render-in-dsh --registry https://registry.npmjs.org
163
+ ```
164
+
165
+ ### Option B · From source (for developers / hacking on the plugin)
113
166
 
114
167
  ```sh
115
168
  # 1. Clone and build
@@ -117,27 +170,17 @@ git clone https://github.com/baihui-ai/a2ui-render-in-dsh.git
117
170
  cd a2ui-render-in-dsh
118
171
  npm install
119
172
  npm run build
120
- # Build emits two files: lib/index.js (host plugin) + lib/client.js (browser bundle).
173
+ # Build emits lib/index.js (host plugin) + lib/client.js (browser bundle).
121
174
  # lib/ is not committed — you MUST build after cloning or dsh won't find the entry.
122
175
 
123
- # 2. Install into dsh's web profile (link mode)
176
+ # 2. Install into dsh's web profile in link mode
124
177
  dsh plugin --profile web add link:$(pwd)
125
- # Equivalent to pnpm add link:<path> inside the profile; it also appends
126
- # a2ui-render-in-dsh to the profile's dsh.profile.bundles automatically.
178
+ # After code changes: just npm run build + restart dsh web, no reinstall.
127
179
 
128
180
  # 3. Start / restart dsh web
129
181
  dsh web
130
182
  ```
131
183
 
132
- Why link mode: upgrading is just `git pull && npm run build` plus a dsh web restart — no reinstall.
133
-
134
- ### Option B · From npm (once the package is published)
135
-
136
- ```sh
137
- dsh plugin --profile web add a2ui-render-in-dsh
138
- dsh web
139
- ```
140
-
141
184
  ### Verify in three steps
142
185
 
143
186
  ```sh
@@ -156,7 +199,10 @@ curl -s http://127.0.0.1:<port>/ | grep -o "a2ui-render-in-dsh/client.js[^\"]*"
156
199
  ### Upgrade & uninstall
157
200
 
158
201
  ```sh
159
- # upgrade (link install): rebuild after pulling, then restart dsh web
202
+ # upgrade (npm install)
203
+ dsh plugin --profile web update a2ui-render-in-dsh
204
+
205
+ # upgrade (source link install): rebuild after pulling, then restart dsh web
160
206
  git pull && npm run build
161
207
 
162
208
  # uninstall: removes the dependency and the bundles entry, then restart dsh web
package/README.zh.md CHANGED
@@ -2,13 +2,13 @@
2
2
 
3
3
  [English](https://github.com/baihui-ai/a2ui-render-in-dsh/blob/main/README.md) | 中文
4
4
 
5
- **dsh web 的 A2UI 交互卡片插件**:让 Agent 在对话流里自适应地渲染**可交互、可视化的 UI 卡片**——选择题、表单、下拉、商品卡、ECharts 图表、数学函数绘图、Mermaid 流程图/思维导图、KaTeX 公式、算法过程动画——用户的点击/勾选/输入以自然语言消息回传给 Agent,形成完整的交互闭环。
5
+ **dsh web 的 A2UI 交互卡片插件**:让 Agent 在对话流里自适应地渲染**可交互、可视化的 UI 卡片**——选择题、表单、分步向导、下拉、日历选日期、商品卡、可排序/筛选的表格、ECharts 图表、中国地图分布、数学函数绘图、Mermaid 流程图/思维导图、KaTeX 公式、Markdown 长文、图片上传、手写签名、算法过程动画——用户的点击/勾选/输入以自然语言消息回传给 Agent(图片也能回传),卡片**边生成边渲染**、还能**原地更新**,所见内容一键复制。
6
6
 
7
7
  UI 协议基于 [A2UI v0.9](https://github.com/google/A2UI)(Agent-to-UI 声明式界面协议),渲染引擎使用 Ant Design X 官方实现 [`@ant-design/x-card`](https://www.npmjs.com/package/@ant-design/x-card)。
8
8
 
9
- 📸 **[功能示例(含动图)→ DEMO.md](https://github.com/baihui-ai/a2ui-render-in-dsh/blob/main/DEMO.zh.md)**
9
+ 📸 **[功能示例(含动图)→ DEMO.md](https://github.com/baihui-ai/a2ui-render-in-dsh/blob/main/DEMO.zh.md)** · 🗺️ **[场景 × 组件映射](https://github.com/baihui-ai/a2ui-render-in-dsh/blob/main/docs/SCENARIOS.zh.md)**
10
10
 
11
- ![做题交互](https://raw.githubusercontent.com/baihui-ai/a2ui-render-in-dsh/main/docs/demo-quiz.gif)
11
+ ![做题交互](https://raw.githubusercontent.com/baihui-ai/a2ui-render-in-dsh/main/docs/demo-study.gif)
12
12
 
13
13
  ---
14
14
 
@@ -18,20 +18,24 @@ UI 协议基于 [A2UI v0.9](https://github.com/google/A2UI)(Agent-to-UI 声明
18
18
 
19
19
  ```
20
20
  a2ui-render-in-dsh (一个 npm 包,dsh bundle)
21
- ├─ 宿主端 lib/index.js cordis 插件,注册两个 Agent 工具
22
- │ ├─ a2ui_render 渲染卡片(描述仅 ~140 token,常驻)
23
- └─ a2ui_catalog 返回完整组件目录与写卡规则(~975 token,按需一次)
24
- └─ 客户端 lib/client.js 浏览器 bundle,注册 a2ui_render 的专属 toolview
21
+ ├─ 宿主端 lib/index.js cordis 插件,注册三个 Agent 工具
22
+ │ ├─ a2ui_render 渲染卡片(描述仅 ~220 token,常驻)
23
+ ├─ a2ui_update 按 surfaceId 原地更新已渲染的卡片
24
+ │ │ (进度推进、长任务回填、看板刷新)
25
+ │ └─ a2ui_catalog 返回完整组件目录与写卡规则(按需加载,每会话一次)
26
+ └─ 客户端 lib/client.js 浏览器 bundle,注册各工具的专属 toolview
25
27
  ├─ x-card 引擎(A2UI 命令流、数据绑定、action 解析)
26
- ├─ 组件目录实现(18 个组件,跟随 --dsw-* 主题令牌)
27
- └─ ECharts 6 / Mermaid 11 / KaTeX(字体内联)全部打入 bundle,零外部请求
28
+ ├─ 组件目录实现(44 个组件,跟随 --dsw-* 主题令牌)
29
+ ├─ 流式渲染器(截断 JSON 修复 模型边写卡片边出现)
30
+ └─ ECharts 6 / Mermaid 11 / KaTeX(字体内联)/ 中国省份 geoJSON
31
+ 全部打入 bundle,零外部请求
28
32
  ```
29
33
 
30
34
  ### 关键设计决策
31
35
 
32
- **1. 自适应渲染,由模型判断。** 是否用 UI 完全交给模型:工具契约写明"仅当卡片明显优于纯文本时调用"。实测:「出题考我」触发卡片,「解释一下 X」保持纯文本。
36
+ **1. 主动式渲染,由模型判断——锚定 UI 的目的。** 工具契约把判断框定为:卡片能否在 UI 的四个目的之一上胜过纯文本?**方便操作**(用户要回答/选择/填写/调节——渲染表单)、**方便浏览**(用户想看/扫数据——统计、排名、分布、趋势出图表/表格/地图,数据不确定也不取消卡片:画已知最好的数据、标注时间口径、正文说明局限)、**增强理解**(结构或记号帮助理解——数学、代码、流程、分步过程)、**状态反馈**(长/多步任务先出进度卡,`a2ui_update` 原地推进)。四者都不沾 → 纯文本。卡片始终**与文案搭配**:结论/看点用 1–3 句正文说,结构化内容进卡片,两边不重复。判断框架有 HCI 理论依据(Norman 双鸿沟、钥匙孔效应、外部认知),并用无关键词的自然语言提示词对各目的 + 纯文本反例实测。
33
37
 
34
- **2. skill 式上下文设计(目录按需加载)。** 完整组件目录不内联在工具描述里,而是放进 `a2ui_catalog` 工具:常驻上下文从 ~1200 token 降到 ~211 token(-82%);模型首次画卡前调用一次目录,同会话后续卡片直接复用;不画卡的会话零目录开销。服务端校验未知组件名并报错引导查目录,防止模型跳过目录瞎猜。
38
+ **2. skill 式上下文设计(目录按需加载)。** 完整组件目录不内联在工具描述里,而是放进 `a2ui_catalog` 工具:组件扩到 44 个,常驻上下文仍稳定在 ~220 token;模型首次画卡前调用一次目录,同会话后续卡片直接复用;不画卡的会话零目录开销。服务端校验未知组件名并报错引导查目录,防止模型跳过目录瞎猜。
35
39
 
36
40
  **3. 非阻塞回传,复用原生消息通路。** 卡片提交不需要自定义 server 通道:客户端通过 dsh 自身的 `session.prompt` RPC 把提交内容作为普通用户消息发回会话。消息是**自然语言**(按钮文案 + 所选内容,多字段换行列出),对人可读、对模型可解析,不污染对话观感:
37
41
 
@@ -45,16 +49,25 @@ a2ui-render-in-dsh (一个 npm 包,dsh bundle)
45
49
 
46
50
  **5. 模型只做擅长的事。** 数学函数绘图:模型只写表达式(`tan(x)`),采样、渐近线断线由内置**安全表达式求值器**完成(白名单 shunting-yard 解析,非 eval,注入即拒绝)——让模型手工枚举几百个数据点必然画错。算法动画:模型模拟算法输出逐帧状态(这是 LLM 强项),播放、过渡、控件由组件完成。
47
51
 
48
- **6. 展示组件全部自包含。** ECharts、Mermaid、KaTeX(含 woff2 字体 data-URI)全部打进 bundle(~5MB,本地服务一次加载),无 CDN 依赖、可离线;明暗主题按页面背景亮度自动跟随。
52
+ **6. 展示组件全部自包含。** ECharts、Mermaid、KaTeX(含 woff2 字体 data-URI)、中国省份 geoJSON 全部打进 bundle(~5.5MB,本地服务一次加载),无 CDN 依赖、可离线;明暗主题按页面背景亮度自动跟随。
53
+
54
+ **7. 活的卡片:流式渲染 + 原地更新。** 模型还在输出 JSON 时卡片就开始渲染(容错解析器修复截断的流,完整的组件提前挂载),大卡片逐块出现而不是长时间空白后一次性弹出。渲染完的卡片也不是死的:`a2ui_update` 按 `surfaceId` 原地替换组件或数据——进度条真的会动、任务卡自己填上结果、看板随时刷新;更新持久化,刷新页面后自动重放。
55
+
56
+ **8. 回答不止于文字。** `Upload`(拍照/截图)和 `Signature`(手写画板)走 dsh 原生消息通路把**真实图片**发回给模型——模型看到的是图,不是占位符。`Suggestions` 渲染可点的追问 chips,点一下即作为下一条用户消息发出。录音回传刻意不做:dsh 的 prompt 通道只支持文本 + 图片。
49
57
 
50
58
  ## 亮点
51
59
 
52
60
  - 🎯 **自适应**:模型自行判断"文本还是卡片",双向实测可靠
53
- - 🪶 **上下文友好**:skill 式目录设计,常驻开销 ~211 token
54
- - 💬 **优雅回传**:自然语言提交消息,非 JSON 裸串
55
- - 🔒 **提交即锁定**:表单防重复提交,记录持久化,查询按钮不受影响
56
- - 📊 **可视化全家桶**:ECharts 图表/仪表盘、函数绘图、Mermaid 全图型、KaTeX 公式(矩阵强制公式化渲染)、视频
57
- - 🎬 **算法动画**:数组/柱状 + 网格/矩阵双形态,自动识别;每卡只自动播一遍(组件重挂载不重播),↻ 手动重播、单步、进度条、图例
61
+ - 🪶 **上下文友好**:skill 式目录设计,44 个组件常驻开销仅 ~220 token
62
+ - 💬 **优雅回传**:自然语言提交消息,非 JSON 裸串;照片、签名以真实图片回传
63
+ - 🔒 **提交即锁定**:表单防重复提交,记录持久化,"重新填写"可解锁;查询按钮不受影响
64
+ - **流式渲染**:模型边写 JSON,卡片边逐块出现
65
+ - 🔄 **原地更新**:`a2ui_update` surfaceId 更新已渲染的卡片——进度条会动、任务卡自己填结果、看板可刷新;刷新页面后重放
66
+ - 📊 **可视化全家桶**:ECharts 图表/仪表盘、函数绘图、中国地图分布、Mermaid 全图型、KaTeX 公式(矩阵强制公式化渲染)、图片对比滑块、视频
67
+ - 🎬 **算法动画**:数组/柱状、网格/矩阵、图/树三形态自动识别;每卡只自动播一遍(组件重挂载不重播),↻ 手动重播、单步、进度条、图例
68
+ - 🧾 **交互表格**:点表头排序(识别数字)、筛选框、分页、复制 TSV、导出 CSV、可编辑表格输入
69
+ - 🧭 **丰富作答组件**:分步向导 Wizard、日历选日期、RankList 排优先级、Suggestions 追问 chips、图片上传、手写签名
70
+ - 📋 **一键复制**:指标块点击复制、表格复制/导出、代码块复制、公式复制 LaTeX 源码、图表下载 PNG、Markdown 复制原文
58
71
  - ⛶ **全屏放大**:思维导图/流程图/图表/图片一键全屏,自动适配视口,滚轮缩放 + 拖拽平移
59
72
  - 🧱 **一行多列**:Grid 布局做商品对比、图表仪表盘
60
73
  - 🎛️ **完整输入态**:下拉单选/多选、预选中(dataModel 初值)、组件级/选项级禁用
@@ -84,18 +97,45 @@ a2ui-render-in-dsh (一个 npm 包,dsh bundle)
84
97
  | `List` | `children, direction?` | 列表容器 |
85
98
  | `Divider` | — | 分隔线 |
86
99
  | `Text` | `text, variant?: h1\|h2\|h3\|body\|caption\|strong` | 文本 |
100
+ | `Markdown` | `text` | **富文本长文**:标题、加粗/斜体、链接、列表、引用、代码块、`$...$` 公式;带复制原文按钮 |
87
101
  | `Image` | `url, alt?, width?, height?` | 图片(含 GIF),自带全屏放大 |
88
102
  | `Tag` | `text, color?: blue\|green\|red\|orange\|gray` | 标签 |
89
103
  | `Math` | `tex, block?` | **KaTeX** 公式(字体内联零外部请求);矩阵/向量必须走此组件 |
90
104
  | `Mermaid` | `code, caption?` | **Mermaid 11**:流程图/思维导图/时序图/甘特图等,自带全屏放大 |
91
- | `Chart` | `option, height?, functions?, xMin?, xMax?, samples?, yClip?` | **ECharts 6**:数据模式(option 透传)+ 函数绘图模式(表达式自动采样、渐近线断线),自带全屏 |
105
+ | `Chart` | `option, height?, functions?, params?, xMin?, xMax?, samples?, yClip?` | **ECharts 6**:数据模式(option 透传)+ 函数绘图模式(表达式自动采样、渐近线断线)+ `params` 绑定常量(滑杆→曲线联动);全屏 + 下载 PNG |
106
+ | `Map` | `data, title?, unit?, height?` | **中国地图分布**:省级数据热力着色(分区销售/用户分布),geoJSON 内置 |
92
107
  | `Video` | `url, poster?, loop?, muted?, autoplay?` | HTML5 视频(mp4/webm) |
93
- | `Anim` | `frames, interval?, height?, autoplay?, labels?` | **算法动画**:数组/柱状与网格/矩阵双形态自动识别;每卡每页签只自动播一遍,↻ 重播/暂停/单步/重置/进度条/图例 |
108
+ | `ImageCompare` | `before, after` | 拖动分割线的图片前后对比(before/after、A/B) |
109
+ | `Anim` | `frames, interval?, height?, autoplay?, labels?` | **算法动画**:数组/柱状、网格/矩阵、图/树(BFS/DFS,自动圆形布局)三形态自动识别;每卡每页签只自动播一遍,↻ 重播/暂停/单步/重置/进度条/图例 |
94
110
  | `Button` | `label, variant?, submit?, action: {event: {name, context?}}` | 触发回传;`submit` 显式控制是否锁卡 |
95
111
  | `MultipleChoice` | `options, bind, maxAllowedSelections?, disabled?` | 平铺多选/单选(`maxAllowedSelections: 1` 单选),选项级禁用 |
96
112
  | `Select` | `options, bind, label?, placeholder?, multiple?, maxAllowedSelections?, disabled?` | **下拉选择**:单选存值、多选存数组,选项描述/禁用 |
97
113
  | `CheckBox` | `label, bind, disabled?` | 布尔勾选 |
114
+ | `Slider` | `bind, label?, min?, max?, step?, unit?` | 数值滑杆;配合 Chart `params` 做参数探索联动 |
115
+ | `Rate` | `bind, label?, max?` | 星级评分 |
116
+ | `Calc` | `expr, inputs, out, digits?` | 隐形派生值:表达式实时重算写回数据模型(计算器引擎) |
117
+ | `When` | `value, equals?/includes?/notEmpty?, children` | 条件容器:选中特定项才显示后续字段 |
118
+ | `Tabs` | `tabs, children, bind?` | 页签:数据集切换 / 内容分组 |
119
+ | `Table` | `columns, rows, caption?, sortable?, filter?, pageSize?` | **交互表格**:点表头排序(识别数字)、筛选框、分页、复制 TSV / 导出 CSV;字典绑定切换数据集 |
120
+ | `Stat` | `label, value, unit?, trend?, hint?` | KPI 指标块,点击复制数值;Grid 组合成速览行 |
121
+ | `Steps` | `items` | 步骤条(done/current/pending) |
122
+ | `Progress` | `value, max?, label?` | 进度条 |
123
+ | `Timeline` | `items` | 时间轴(历程/事件回顾) |
124
+ | `CodeBlock` | `code, language?, title?` | 代码块:行号 + 轻量高亮 + 复制按钮 |
125
+ | `Icon` | `name, size?, color?` | 内置 32 个常用线条图标 |
126
+ | `Audio` | `url, title?` | 音频播放器 |
127
+ | `Flashcard` | `front, back` | 点击翻面闪卡(背单词/问答记忆) |
128
+ | `Countdown` | `to?/seconds?, label?` | 实时倒计时 |
98
129
  | `TextField` | `label?, placeholder?, multiline?, bind, disabled?` | 文本输入 |
130
+ | `Wizard` | `steps, children, submitLabel?` | **分步表单**:每步一个面板,内置上一步/下一步 + 进度,最后一步提交全部字段 |
131
+ | `Calendar` | `bind, label?, min?, max?` | 月视图日期选择,支持范围限制 |
132
+ | `RankList` | `items, bind, label?` | 用户按优先级排序选项,提交排好的列表 |
133
+ | `EditableTable` | `columns, rows, bind, label?` | 用户直接改单元格,整表提交 |
134
+ | `Upload` | `bind?, label?, max?` | 图片选择器——所选照片以**真实图片**回传给模型 |
135
+ | `Signature` | `label?` | 手写签名画板,笔迹以图片回传 |
136
+ | `Suggestions` | `items` | 回答下方的可点追问 chips,点一下即作为下一条用户消息发出 |
137
+
138
+ **内联公式**:所有文本位置(Text、选项、表格单元格、步骤、闪卡、动画解说)支持 `$...$` 内嵌 KaTeX——数学选择题的选项可以直接是公式。**响应式联动**:输入组件写数据模型,所有 `{"path"}` 绑定即时更新——滑杆→曲线(Chart `params`)、选择→追问(When)、输入→计算结果(Calc→Stat)、切换→换表(Tabs/Table 字典绑定)。
99
139
 
100
140
  输入组件通用:**预选中**在 `dataModel` 给 bind 路径设初值;**禁用**用组件级 `disabled: true` 或选项级 `disabled`。数据绑定:`bind` 为不带前导斜杠的写入路径;展示属性用 `{"path": "/x"}`(带斜杠)读实时值。
101
141
 
@@ -108,7 +148,20 @@ a2ui-render-in-dsh (一个 npm 包,dsh bundle)
108
148
  | dsh | `@deepseek-ai/dsh` ≥ 0.1.1-rc.1,且 web profile 已初始化(装插件前先运行过一次 `dsh web`) |
109
149
  | Node.js | ≥ 20(含 npm) |
110
150
 
111
- ### 方式 A · 源码安装(当前推荐)
151
+ ### 方式 A · npm 安装(推荐)
152
+
153
+ ```sh
154
+ dsh plugin --profile web add a2ui-render-in-dsh
155
+ dsh web
156
+ ```
157
+
158
+ 零运行时依赖,两条命令装完即用。若你的 npm 镜像尚未同步最新版本,显式指定官方源:
159
+
160
+ ```sh
161
+ dsh plugin --profile web add a2ui-render-in-dsh --registry https://registry.npmjs.org
162
+ ```
163
+
164
+ ### 方式 B · 源码安装(开发者 / 需要改代码时)
112
165
 
113
166
  ```sh
114
167
  # 1. 克隆并构建
@@ -116,27 +169,17 @@ git clone https://github.com/baihui-ai/a2ui-render-in-dsh.git
116
169
  cd a2ui-render-in-dsh
117
170
  npm install
118
171
  npm run build
119
- # 构建产出两个文件:lib/index.js(宿主端插件)+ lib/client.js(浏览器 bundle)
172
+ # 构建产出:lib/index.js(宿主端)+ lib/client.js(浏览器 bundle)
120
173
  # lib/ 不在 git 里,克隆后必须先构建,否则 dsh 启动时找不到入口
121
174
 
122
175
  # 2. 以 link 方式装进 dsh 的 web profile
123
176
  dsh plugin --profile web add link:$(pwd)
124
- # 该命令等价于在 profile pnpm add link:<路径>,并自动把
125
- # a2ui-render-in-dsh 追加到 profile 的 dsh.profile.bundles
177
+ # 改码后只需 npm run build + 重启 dsh web,无需重装
126
178
 
127
179
  # 3. 启动 / 重启 dsh web
128
180
  dsh web
129
181
  ```
130
182
 
131
- link 方式的好处:后续升级只需 `git pull && npm run build` 再重启 dsh web,无需重装。
132
-
133
- ### 方式 B · npm 安装(包发布到 npm 后)
134
-
135
- ```sh
136
- dsh plugin --profile web add a2ui-render-in-dsh
137
- dsh web
138
- ```
139
-
140
183
  ### 三步验证
141
184
 
142
185
  ```sh
@@ -155,7 +198,10 @@ curl -s http://127.0.0.1:<port>/ | grep -o "a2ui-render-in-dsh/client.js[^\"]*"
155
198
  ### 升级与卸载
156
199
 
157
200
  ```sh
158
- # 升级(link 安装):拉新代码重新构建,重启 dsh web 即生效
201
+ # 升级(npm 安装)
202
+ dsh plugin --profile web update a2ui-render-in-dsh
203
+
204
+ # 升级(源码 link 安装):拉新代码重新构建,重启 dsh web 即生效
159
205
  git pull && npm run build
160
206
 
161
207
  # 卸载:从 profile 移除(依赖与 bundles 条目会一并清掉),重启 dsh web