deepseek-harness-intelligent-ui 0.0.0-stage → 0.2.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/CHANGELOG.md +62 -0
- package/LICENSE +21 -0
- package/README.md +237 -2
- package/README.zh-CN.md +230 -0
- package/THIRD_PARTY_NOTICES.md +25 -0
- package/bin/cli.mjs +236 -0
- package/client/client.js +445 -0
- package/cordis.patch.yml +5 -0
- package/locale/en.json +6 -0
- package/locale/zh.json +6 -0
- package/package.json +113 -4
- package/src/catalog/catalog.js +533 -0
- package/src/catalog/expr.js +177 -0
- package/src/commands.js +41 -0
- package/src/compat.js +18 -0
- package/src/config.js +68 -0
- package/src/guidance.js +53 -0
- package/src/plugin.js +38 -0
- package/src/tools/render.js +84 -0
- package/src/tools/widget.js +117 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project are documented here. The format follows
|
|
4
|
+
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and the project uses
|
|
5
|
+
[Semantic Versioning](https://semver.org/) (pre-1.0: a minor bump may break).
|
|
6
|
+
|
|
7
|
+
## [Unreleased]
|
|
8
|
+
|
|
9
|
+
## [0.2.2]
|
|
10
|
+
|
|
11
|
+
### Fixed
|
|
12
|
+
|
|
13
|
+
- npm co-installation with the supported DSH 0.2.0-rc and 0.2.1-alpha lines now uses explicit prerelease peer ranges.
|
|
14
|
+
- README installation examples use the 0.2.2 release version, explain the optional `next` tag, and link to versioned documentation and media outside the tarball.
|
|
15
|
+
|
|
16
|
+
### Changed
|
|
17
|
+
|
|
18
|
+
- Release reruns verify registry integrity, exact package contents and provenance before reusing a version. GitHub Release assets come from that registry tarball and conflicting assets are refused.
|
|
19
|
+
- Release preflight requires the tagged commit to belong to main. Actions use immutable commit SHAs, and publishing can opt into npm Trusted Publishing after account-side setup.
|
|
20
|
+
|
|
21
|
+
## [0.2.1]
|
|
22
|
+
|
|
23
|
+
### Changed
|
|
24
|
+
|
|
25
|
+
- Rebuilt the client bundle with esbuild 0.28 and idiomorph 0.8 (widget DOM morphing). The catalog sources also type-check against React 19 types.
|
|
26
|
+
- CI and release workflows use `actions/checkout@v7`, `actions/setup-node@v7`, `actions/upload-artifact@v7` and `pnpm/action-setup@v6`. Browser E2E runs in isolated workspaces and cleans up its processes reliably.
|
|
27
|
+
|
|
28
|
+
### Fixed
|
|
29
|
+
|
|
30
|
+
- Real-model evaluation now reads `DEEPSEEK_API_KEY` from the environment, validates requested rendered components and multi-turn data, acknowledges all tool calls, and exits nonzero on failures. Partial runs no longer combine historical results under a new timestamp. API errors and missing messages fail clearly; requests have a timeout.
|
|
31
|
+
- Marked the legacy evaluation report's missing-Chart false positive and clarified the limits of API-only evaluation in both READMEs.
|
|
32
|
+
|
|
33
|
+
## 0.2.0 (development milestone)
|
|
34
|
+
|
|
35
|
+
### Changed
|
|
36
|
+
|
|
37
|
+
- **Renamed the npm package to `deepseek-harness-intelligent-ui`** (`dsh-intelligent-ui` belongs to an unrelated project on npm). The bundle row id stays `intelligent-ui`, so existing `cordis.patch.yml` overrides keep working. Remove the old `file:` install with `dsh plugin --profile web remove dsh-intelligent-ui` before installing this one.
|
|
38
|
+
- **Supports DeepSeek Harness `>=0.1.7-rc.1 <0.3.0`** instead of only `0.2.0-rc.1`, which DSH refused to install on `0.2.0-rc.2` and later. The peers are marked optional because DSH provides them, so pnpm no longer warns about "missing peers".
|
|
39
|
+
|
|
40
|
+
### Added
|
|
41
|
+
|
|
42
|
+
- Live streaming previews on DSH 0.2.1+. DSH 0.2.1 removed the `useToolCallArgumentsPartial` hook that tool views used to receive the streamed arguments. The views now fall back to the call's growing `args` view, so catalog UIs and widgets still render progressively and still survive a stopped generation.
|
|
43
|
+
- One-command install from npm: `dsh plugin --profile web add deepseek-harness-intelligent-ui`.
|
|
44
|
+
- `npx deepseek-harness-intelligent-ui install | uninstall | doctor`: checks Node, dsh (and that its version is supported), pnpm and the profile, then runs DSH's own plugin manager.
|
|
45
|
+
- Cross-platform E2E (Windows, Linux, macOS). It also waits for DSH 0.1.x's delayed first-run notice.
|
|
46
|
+
- Chrome is detected per platform, process cleanup works on POSIX, and `--spec` installs a packed tarball or a registry version.
|
|
47
|
+
- GitHub Actions:
|
|
48
|
+
- CI on 3 OSes × Node 22.13/24.
|
|
49
|
+
- A nightly compatibility matrix across DSH versions (install smoke test plus browser E2E).
|
|
50
|
+
- A tag-driven release that publishes to npm with provenance and creates the GitHub Release.
|
|
51
|
+
|
|
52
|
+
## 0.1.0 (development milestone)
|
|
53
|
+
|
|
54
|
+
### Added
|
|
55
|
+
|
|
56
|
+
- Initial release:
|
|
57
|
+
- The declarative component catalog (`ui_render`) and sandboxed streaming HTML widgets (`ui_render_widget`).
|
|
58
|
+
- The `/ui` command and the guidance system-prompt section.
|
|
59
|
+
|
|
60
|
+
[Unreleased]: https://github.com/dreamfarer-space/deepseek-harness-intelligent-ui/compare/v0.2.2...HEAD
|
|
61
|
+
[0.2.2]: https://github.com/dreamfarer-space/deepseek-harness-intelligent-ui/compare/v0.2.1...v0.2.2
|
|
62
|
+
[0.2.1]: https://github.com/dreamfarer-space/deepseek-harness-intelligent-ui/releases/tag/v0.2.1
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 dreamfarer-space
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,238 @@
|
|
|
1
|
-
#
|
|
1
|
+
# DeepSeek Harness Intelligent UI
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
English | [中文](README.zh-CN.md)
|
|
4
|
+
|
|
5
|
+
[](https://github.com/dreamfarer-space/deepseek-harness-intelligent-ui/actions/workflows/ci.yml) [](https://www.npmjs.com/package/deepseek-harness-intelligent-ui)
|
|
6
|
+
|
|
7
|
+
Generative, interactive UI for [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) (DSH). Ask in plain language and the agent decides on its own whether to answer with text, with native components (dashboards, tables, charts, timelines, live function plots, KaTeX math, Mermaid diagrams, forms), or with a fully custom **sandboxed live widget** (Three.js scenes, canvas simulations, mini-apps). The UI renders progressively in the chat while the answer streams. Sliders, rotation, zoom, sorting and tabs respond instantly in the browser. Only explicit actions (a button, a form, `Bridge.sendPrompt`) go back to the agent.
|
|
8
|
+
|
|
9
|
+
It ports the ideas of CopilotKit's [OpenIntelligentUI](https://github.com/CopilotKit/OpenIntelligentUI) (Open Generative UI + A2UI-style declarative components) onto DSH's own extension points. It needs no CopilotKit, LangGraph, or external router.
|
|
10
|
+
|
|
11
|
+
## Demo
|
|
12
|
+
|
|
13
|
+

|
|
14
|
+
|
|
15
|
+
🎥 **Full-quality video (H.264, ~2 min):** [docs/assets/demo.mp4](https://github.com/dreamfarer-space/deepseek-harness-intelligent-ui/blob/v0.2.1/docs/assets/demo.mp4)
|
|
16
|
+
|
|
17
|
+
> The recording comes from the real DSH Web 0.2.0-rc.1 with this plugin installed, driven by `npm run e2e:all -- --record`. The model behind it is the **scripted mock** in `scripts/e2e/` (no API key was available), so the answers are canned. Everything you see (streaming, rendering, interaction, the round trips, persistence, isolation) is the real plugin running in DSH.
|
|
18
|
+
>
|
|
19
|
+
> To get an inline player on GitHub, drag `docs/assets/demo.mp4` into a GitHub comment or release editor and paste the resulting `https://github.com/user-attachments/assets/…` URL on its own line here. GitHub only renders inline video for uploaded attachments, not for repository files.
|
|
20
|
+
|
|
21
|
+
| Dashboard streams in, then settles | Three.js widget: R slider, rotate, zoom |
|
|
22
|
+
|:---:|:---:|
|
|
23
|
+
|  |  |
|
|
24
|
+
| *Stat, Grid, Tabs, stacked bar chart with hover tooltip, sortable table, timeline, form* | *`x²+y²+z²=2Rz` via `UI.three()`: the slider re-shapes the surface locally* |
|
|
25
|
+
|
|
26
|
+
| Math, live Plot, Mermaid | Form → agent → new UI |
|
|
27
|
+
|:---:|:---:|
|
|
28
|
+
|  |  |
|
|
29
|
+
| *KaTeX formula, `Plot` with parameter sliders (no model call), Mermaid flowchart* | *Submitted values reach the agent, which answers with a forecast chart* |
|
|
30
|
+
|
|
31
|
+
| Streaming preview (same iframe becomes final) | Stopped mid-generation |
|
|
32
|
+
|:---:|:---:|
|
|
33
|
+
|  |  |
|
|
34
|
+
|
|
35
|
+
| Dark theme | Phone width (dark) | After reload |
|
|
36
|
+
|:---:|:---:|:---:|
|
|
37
|
+
|  |  |  |
|
|
38
|
+
|
|
39
|
+
## How the agent decides
|
|
40
|
+
|
|
41
|
+
The plugin injects a system-prompt section (`src/guidance.js`) that makes the model route each turn itself. There is no command and no external router:
|
|
42
|
+
|
|
43
|
+
- **Plain text** for greetings, short facts, explanations, code to copy, and workspace/coding work.
|
|
44
|
+
- **`ui_render`** for structured answers: comparisons, data, dashboards, processes, formulas, functions to explore, choices, input collection.
|
|
45
|
+
- **`ui_render_widget`** when the user wants to explore, manipulate or watch something the catalog cannot draw: 3D, simulations, animations, games, custom tools.
|
|
46
|
+
- **Local first:** anything computable in the browser (sliders, rotation, zoom, filtering, sorting, recomputing) must update instantly without a message to the model.
|
|
47
|
+
|
|
48
|
+
`/ui <request>` still exists to force a UI answer.
|
|
49
|
+
|
|
50
|
+
## Tools
|
|
51
|
+
|
|
52
|
+
| Tool | Use it for | Rendering |
|
|
53
|
+
|---|---|---|
|
|
54
|
+
| `ui_render` | Structured answers | Native React components from a fixed catalog, rendered progressively as the JSON streams |
|
|
55
|
+
| `ui_render_widget` | Custom visuals, 3D, simulations, mini-apps | HTML/CSS/JS in an opaque-origin sandboxed iframe: CSS first, HTML morphed in live, JS last, all in **one** iframe |
|
|
56
|
+
|
|
57
|
+
### Component catalog (`ui_render`)
|
|
58
|
+
|
|
59
|
+
`Card`, `Stack`, `Grid`, `Tabs` (keyboard navigable), `Text` (markdown subset), `Code`, `Alert`, `Badge`, `Divider`, `Stat`, `Progress`, `List`, `Table` (sortable), `Chart` (bar / line / area / pie, stacked, hover tooltip, toggleable legend), `Timeline`, **`Plot`** (y = f(x) with parameter sliders that redraw instantly; expressions run in a safe compiler, never `eval`), **`Math`** (KaTeX), **`Mermaid`** (flowchart, sequence, class, state, ER, gantt, mindmap…), `Button` (sends a prompt), and `Form` (text, number, **range slider**, select, checkbox, date, textarea; submits the values as a message).
|
|
60
|
+
|
|
61
|
+
A UI travels as a **flat node list with id references**, because DSH's tool-schema subset has no recursion. The Host validates it before acknowledging: unknown types or props, dangling or duplicate ids, cycles, two parents, chart length mismatches, `Plot` expressions that do not compile, slider defaults out of range, and so on. Problems come back as `ok:false` with paths, so the model can fix them and retry.
|
|
62
|
+
|
|
63
|
+
`Math` and `Mermaid` render inside the same sandbox as widgets, loading KaTeX or Mermaid from the CDN allowlist. No third-party code runs in the DSH page and the host bundle stays small (~127 KB). If the CDN is unreachable, the source text is shown instead.
|
|
64
|
+
|
|
65
|
+
### Widgets (`ui_render_widget`)
|
|
66
|
+
|
|
67
|
+
Fields follow the OpenIntelligentUI streaming contract, **in this order**: `title`, `initialHeight`, `placeholderMessages`, `css`, `html`, `jsFunctions`, `jsExpressions`.
|
|
68
|
+
|
|
69
|
+
- **Streaming:** placeholder lines show until `css` is complete. Then a preview frame opens and the cleaned partial `html` is morphed in ([idiomorph](https://github.com/bigskysoftware/idiomorph)). When the arguments are complete, the **same frame is finalized in place**: the final HTML is morphed and the code runs. There is no rebuild, blank flash or height jump.
|
|
70
|
+
- **Runtime helpers** (global `UI`):
|
|
71
|
+
- `UI.three(el, { camera, target, autoRotate })` returns a renderer, scene, lights and OrbitControls (drag rotates, wheel/pinch zooms), renders on demand, and handles resize.
|
|
72
|
+
- `UI.canvas(el, draw)` gives a HiDPI 2D canvas that is redrawn on resize and theme change.
|
|
73
|
+
- `UI.state` / `UI.setState()` persist state. Inputs with an `id` are persisted and restored automatically.
|
|
74
|
+
- `UI.color('accent')` returns an opaque theme color for three.js/canvas, and `UI.css()` returns a raw value.
|
|
75
|
+
- `UI.onTheme(cb)`, `UI.scheme` and `UI.reducedMotion` are also available.
|
|
76
|
+
- Helper classes: `.ui-row`, `.ui-control`, `.ui-card`, `.ui-stage`.
|
|
77
|
+
- **Bridge:** `Bridge.sendPrompt({ text })` disables the clicked control until the host answers, so double clicks cannot queue duplicates. `Bridge.openLink({ url })` opens links, and `Websandbox.connection.remote.*` is kept for OpenIntelligentUI compatibility.
|
|
78
|
+
- **Libraries:** an importmap maps `three`, `three/addons/…`, `d3`, `chart.js/auto`, `gsap` and `canvas-confetti` to esm.sh.
|
|
79
|
+
- **Recovery:** script errors show a count with **Reload** and **Ask to fix** (the latter sends the errors to the agent).
|
|
80
|
+
|
|
81
|
+
### Where the UI appears, and what survives
|
|
82
|
+
|
|
83
|
+
- While a turn runs, the UI renders inline inside the tool call. One component instance spans preparing → running → result, so interaction state carries over.
|
|
84
|
+
- When the turn ends, DSH folds tool calls into the "process" section. The plugin re-presents each UI **beneath the reply** (`conversation.chat.turnTail`), and the inline copy shrinks to a pointer.
|
|
85
|
+
- **Interaction state persists per tool call:** the open tab, table sort, form values, the submitted lock, Plot sliders, widget controls and `UI.state`, and frame heights. It lives in memory and in `localStorage` (bounded), so moving beneath the reply or reloading the page restores it. The UIs themselves are rebuilt from the durable session log.
|
|
86
|
+
- **Stopped generation:**
|
|
87
|
+
- If the call already reached DSH, the view keeps the finished part (a static widget preview or the completed components) with a notice and a **Regenerate** button.
|
|
88
|
+
- If the user stops while the arguments are still streaming, DSH drops the call entirely. The plugin stashes what was streamed and shows it beneath the stopped turn the same way.
|
|
89
|
+
|
|
90
|
+
## Security model
|
|
91
|
+
|
|
92
|
+
- **Widget isolation:** widgets run in `<iframe sandbox="allow-scripts allow-forms">` with `srcdoc` and **no** `allow-same-origin`. They cannot reach the DSH page, its cookies or storage, or its API. The E2E checks this in the browser: `parent.document`, `localStorage` and `document.cookie` all throw `SecurityError`, `fetch` is blocked, and `window.origin === "null"`.
|
|
93
|
+
- **CSP:**
|
|
94
|
+
- `default-src 'none'`.
|
|
95
|
+
- Scripts, styles, fonts and images load only from `cdnAllowlist`.
|
|
96
|
+
- `connect-src 'none'` unless `allowNetwork` is on.
|
|
97
|
+
- `form-action 'none'` and `base-uri 'none'`.
|
|
98
|
+
- **Messages from the frame:** they are accepted only from that frame's `contentWindow`, must carry a per-frame random token, and are shape-checked. Persisted widget state is size-limited JSON. The E2E checks that forged messages from the page or the frame are dropped.
|
|
99
|
+
- **`sendPrompt` limits:**
|
|
100
|
+
- It is refused during the first second after mount.
|
|
101
|
+
- At most one send every 2 seconds.
|
|
102
|
+
- Text is capped at `sendPromptMaxChars`.
|
|
103
|
+
- The message is queued as a normal user message.
|
|
104
|
+
- **`openLink`:** https only, optionally restricted to `openLinkAllowedOrigins`.
|
|
105
|
+
- **Catalog:** text renders as React elements, never raw HTML. `Plot` expressions are compiled by a tokenizer/parser over a fixed math function table, with no `eval`, `Function`, or property access.
|
|
106
|
+
|
|
107
|
+
## Install
|
|
108
|
+
|
|
109
|
+
You need [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) **0.1.7 – 0.2.x** (`>=0.1.7-rc.1 <0.3.0`) and Node.js ≥ 22.13, on Windows, Linux or macOS. Nothing is compiled during install. The package ships its prebuilt browser bundle and declares no install scripts.
|
|
110
|
+
|
|
111
|
+
```sh
|
|
112
|
+
dsh plugin --profile web add deepseek-harness-intelligent-ui
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
To have your environment checked first, use the guided installer instead. It verifies Node, the `dsh` version, pnpm and the profile, then runs the same `dsh plugin add`:
|
|
116
|
+
|
|
117
|
+
```sh
|
|
118
|
+
npx deepseek-harness-intelligent-ui install # --profile <name>, --dsh <path>, --dry-run
|
|
119
|
+
npx deepseek-harness-intelligent-ui doctor # diagnose only
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
| Task | Command |
|
|
123
|
+
|---|---|
|
|
124
|
+
| Upgrade | `dsh plugin --profile web add deepseek-harness-intelligent-ui@latest` |
|
|
125
|
+
| Try a prerelease (only when the `next` dist-tag exists) | `dsh plugin --profile web add deepseek-harness-intelligent-ui@next` |
|
|
126
|
+
| Pin a version | `dsh plugin --profile web add deepseek-harness-intelligent-ui@0.2.2` |
|
|
127
|
+
| Uninstall | `dsh plugin --profile web remove deepseek-harness-intelligent-ui` (or `npx deepseek-harness-intelligent-ui uninstall`) |
|
|
128
|
+
| From a checkout | `dsh plugin --profile web add file:/path/to/deepseek-harness-intelligent-ui` |
|
|
129
|
+
|
|
130
|
+
Supported DSH versions and the CI matrix are in [docs/compatibility.md](https://github.com/dreamfarer-space/deepseek-harness-intelligent-ui/blob/v0.2.2/docs/compatibility.md).
|
|
131
|
+
|
|
132
|
+
**Troubleshooting**
|
|
133
|
+
|
|
134
|
+
- *`pnpm was not found`*: DSH installs plugins with pnpm. Run `corepack enable` (it ships with Node) or `npm i -g pnpm`.
|
|
135
|
+
- *`… is incompatible with dsh X`*: your DSH is outside the supported range. Upgrade DSH (`npm i -g @deepseek-ai/dsh@latest`) or check [compatibility](https://github.com/dreamfarer-space/deepseek-harness-intelligent-ui/blob/v0.2.2/docs/compatibility.md) for a plugin release that supports it.
|
|
136
|
+
- *Upgrading from 0.1.x (`dsh-intelligent-ui` via `file:`)*: run `dsh plugin --profile web remove dsh-intelligent-ui` first. Both packages insert the same `intelligent-ui` row, and `doctor` reports the conflict.
|
|
137
|
+
- *The UI does not appear*: restart DSH Web after installing, and make sure you started the profile you installed into (`dsh web`).
|
|
138
|
+
|
|
139
|
+
Restart DSH Web afterwards. The bundle patch inserts the plugin row automatically. To change settings, add to your profile's `cordis.patch.yml`:
|
|
140
|
+
|
|
141
|
+
```yaml
|
|
142
|
+
- id: intelligent-ui
|
|
143
|
+
config:
|
|
144
|
+
allowNetwork: true
|
|
145
|
+
cdnAllowlist: [https://esm.sh, https://cdn.jsdelivr.net]
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
| Option | Default | Meaning |
|
|
149
|
+
|---|---|---|
|
|
150
|
+
| `enableCatalog` | `true` | Register `ui_render` |
|
|
151
|
+
| `enableWidget` | `true` | Register `ui_render_widget` |
|
|
152
|
+
| `injectGuidance` | `true` | Add the "when to use UI" system-prompt section |
|
|
153
|
+
| `cdnAllowlist` | esm.sh, jsdelivr, unpkg | Origins widgets (and Math/Mermaid) may load resources from |
|
|
154
|
+
| `allowNetwork` | `false` | Let widgets `fetch` and use WebSocket to those origins |
|
|
155
|
+
| `maxWidgetHeight` | `2400` | Maximum frame height (px) |
|
|
156
|
+
| `maxWidgetBytes` | `400000` | Reject larger widgets |
|
|
157
|
+
| `sendPromptMaxChars` | `4000` | Longest message a widget, button or form may send |
|
|
158
|
+
| `openLinkAllowedOrigins` | `[]` | If non-empty, the only origins `openLink` may open |
|
|
159
|
+
|
|
160
|
+
## Develop and verify
|
|
161
|
+
|
|
162
|
+
```sh
|
|
163
|
+
npm install
|
|
164
|
+
npm run build # client-src/ → client/client.js (DSH __ModuleLoader__ factory; React and Cordis external)
|
|
165
|
+
npm test # vitest (catalog, expressions, tools, plugin mount, streaming parser, frame/CSP/bridge, state, theme, views, interruption, turn tail, DSH compatibility gate, installer CLI)
|
|
166
|
+
npm run typecheck
|
|
167
|
+
npm run e2e:all # build → install into a temp DSH home → mock model + real DSH Web → 24 browser checks
|
|
168
|
+
npm run e2e:all -- --record # also re-records docs/assets/demo.mp4 / demo.gif (needs ffmpeg)
|
|
169
|
+
npm run e2e:all -- --spec ./deepseek-harness-intelligent-ui-<v>.tgz # E2E the packed tarball instead of the checkout
|
|
170
|
+
npm run smoke -- --spec ./deepseek-harness-intelligent-ui-<v>.tgz # install smoke test (no browser): version gate, bundle row, DSH Web boot
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
The E2E runs on Windows, Linux and macOS. It finds Chrome per platform (set `CHROME_PATH` to override) and uses `DSH_BIN` to test another `dsh` binary. CI runs everything on all three OSes against every supported DSH line ([compatibility](https://github.com/dreamfarer-space/deepseek-harness-intelligent-ui/blob/v0.2.2/docs/compatibility.md)).
|
|
174
|
+
|
|
175
|
+
**Releasing** (maintainers):
|
|
176
|
+
|
|
177
|
+
See [release security and OIDC setup](https://github.com/dreamfarer-space/deepseek-harness-intelligent-ui/blob/main/docs/releasing.md).
|
|
178
|
+
|
|
179
|
+
1. Add the notes under a new `## [x.y.z]` heading in [CHANGELOG.md](CHANGELOG.md).
|
|
180
|
+
2. Run `npm version x.y.z` (or `npm version prerelease --preid rc`). This rebuilds `client/client.js` with the new version and tags the commit.
|
|
181
|
+
3. Run `git push --follow-tags`. The tag triggers the Release workflow, which:
|
|
182
|
+
- runs the full CI matrix;
|
|
183
|
+
- publishes to npm with provenance (dist-tag `next` for prereleases);
|
|
184
|
+
- smoke-tests the published package on Windows, Linux and macOS;
|
|
185
|
+
- creates the GitHub Release with the changelog section and the tarball.
|
|
186
|
+
4. Run `npm run release:check` to perform the same preflight locally.
|
|
187
|
+
|
|
188
|
+
- **Layout:** `src/` is the Host half (plain ESM, no build). `client-src/` is the browser half (TSX, bundled with esbuild). `client/client.js` is committed and published so npm, `file:` and git installs need no build step. CI fails if it is stale. Never add a `prepare`/`postinstall` script, because DSH's pnpm blocks plugin build scripts.
|
|
189
|
+
- **What the E2E checks** (`scripts/e2e/browser.mjs`, report in [`docs/e2e-report.json`](https://github.com/dreamfarer-space/deepseek-harness-intelligent-ui/blob/v0.2.1/docs/e2e-report.json)):
|
|
190
|
+
- Plain Q&A stays text.
|
|
191
|
+
- The dashboard streams progressively.
|
|
192
|
+
- Chart hover, table sort and tabs are local.
|
|
193
|
+
- A form round-trip returns a new UI.
|
|
194
|
+
- The preview iframe is finalized in place.
|
|
195
|
+
- The Three.js scene renders, and the R slider, drag-rotate and wheel-zoom work.
|
|
196
|
+
- The `Bridge.sendPrompt` round trip works.
|
|
197
|
+
- KaTeX and Mermaid render.
|
|
198
|
+
- Plot sliders work.
|
|
199
|
+
- Earlier UIs keep their state.
|
|
200
|
+
- Stop → static preview → Regenerate works.
|
|
201
|
+
- The sandbox is isolated and forged messages are ignored.
|
|
202
|
+
- Dark theme reaches cards and widgets.
|
|
203
|
+
- Phone width has no overflow.
|
|
204
|
+
- A reload restores the UIs and their state.
|
|
205
|
+
- No plugin console errors appear.
|
|
206
|
+
- Requires Chrome (`CHROME_PATH`), `dsh` on PATH and, for `--record`, `ffmpeg`. Headless Chrome uses SwiftShader for WebGL.
|
|
207
|
+
|
|
208
|
+
## Real-model Evaluation
|
|
209
|
+
|
|
210
|
+
The API suite checks model routing, tool-argument schemas, and selected requested components or data across 15 prompts. It does **not** execute model-generated widgets in a browser or verify factual data, visual quality, physics, or interaction behavior. The separate browser E2E uses scripted model responses.
|
|
211
|
+
|
|
212
|
+
The checked-in [historical report](https://github.com/dreamfarer-space/deepseek-harness-intelligent-ui/blob/v0.2.1/docs/real-model-eval-report.json) was produced by the earlier evaluator. Its 15/15 result is not a current pass rate: B3 was incorrectly accepted despite containing no Chart. Other cases need a new run under the stricter assertions; the original report is retained with an audit note.
|
|
213
|
+
|
|
214
|
+
The current suite requires rendered components (not orphan nodes), a sortable table for B2, a four-quarter multi-series bar chart for B3, range/checkbox form controls for B4, and parameter sliders for a native C2 Plot. Multi-turn cases validate all tool calls, acknowledge each call, require the submitted APAC/4/Optimistic parameters, and check all three requested screen sizes while retaining existing table values. These are automated assertions, not a complete quality assessment.
|
|
215
|
+
|
|
216
|
+
Set `DEEPSEEK_API_KEY` in the environment before running; no credentials file is read:
|
|
217
|
+
|
|
218
|
+
```sh
|
|
219
|
+
export DEEPSEEK_API_KEY='<your-key>'
|
|
220
|
+
node scripts/run-real-model-suite.mjs all # A, B, C, D or all
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
```powershell
|
|
224
|
+
$env:DEEPSEEK_API_KEY = '<your-key>'
|
|
225
|
+
node scripts/run-real-model-suite.mjs all
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
Each invocation writes only that run's cases to `docs/real-model-eval-report.json`. A partial run does not merge older cases into a new timestamp. Failed assertions/API calls exit with code 1; an invalid category or missing key fails before changing the report. Keep keys out of git.
|
|
229
|
+
|
|
230
|
+
## Limitations
|
|
231
|
+
|
|
232
|
+
- Widgets, Math and Mermaid need the CDN allowlist to be reachable. Offline, Math/Mermaid fall back to source text and `UI.three` reports a script error.
|
|
233
|
+
- Persisted interaction state is per browser (`localStorage`), not synced across devices.
|
|
234
|
+
- Matching a dropped (stopped-while-streaming) call to its turn uses the turn's start/end times. A large clock offset between a remote DSH host and the browser could hide that card. Calls that reached the session log are unaffected.
|
|
235
|
+
|
|
236
|
+
## Credits
|
|
237
|
+
|
|
238
|
+
Concepts, the streaming widget contract, and parts of the prompt guidance come from [CopilotKit/OpenIntelligentUI](https://github.com/CopilotKit/OpenIntelligentUI) (MIT). See [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md). Licensed under MIT.
|
package/README.zh-CN.md
ADDED
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
# DeepSeek Harness Intelligent UI(智能界面)
|
|
2
|
+
|
|
3
|
+
[English](README.md) | 中文
|
|
4
|
+
|
|
5
|
+
[](https://github.com/dreamfarer-space/deepseek-harness-intelligent-ui/actions/workflows/ci.yml) [](https://www.npmjs.com/package/deepseek-harness-intelligent-ui)
|
|
6
|
+
|
|
7
|
+
为 [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness)(DSH)提供**生成式、可交互的 UI**。用户用自然语言提问,Agent 自行决定怎样作答:
|
|
8
|
+
|
|
9
|
+
- 普通文本;
|
|
10
|
+
- 原生组件:看板、表格、图表、时间线、带滑块的函数图像、KaTeX 公式、Mermaid 流程图、表单;
|
|
11
|
+
- 完全自定义的**沙箱实时组件**:Three.js 三维场景、Canvas 模拟、小应用。
|
|
12
|
+
|
|
13
|
+
界面随回答流式、渐进地出现。滑块、旋转、缩放、排序、切换标签页都在浏览器内即时响应,只有显式操作(按钮、表单、`Bridge.sendPrompt`)才会回到 Agent。
|
|
14
|
+
|
|
15
|
+
本插件把 CopilotKit [OpenIntelligentUI](https://github.com/CopilotKit/OpenIntelligentUI) 的思路(Open Generative UI + A2UI 风格声明式组件)移植到 DSH 自带的扩展点上,不依赖 CopilotKit、LangGraph 或外部路由服务。
|
|
16
|
+
|
|
17
|
+
## 演示
|
|
18
|
+
|
|
19
|
+

|
|
20
|
+
|
|
21
|
+
🎥 **高清视频(H.264,约 2 分钟):** [docs/assets/demo.mp4](https://github.com/dreamfarer-space/deepseek-harness-intelligent-ui/blob/v0.2.1/docs/assets/demo.mp4)
|
|
22
|
+
|
|
23
|
+
> **录制方式:** 演示视频录自真实的 DSH Web 0.2.0-rc.1,装好本插件后由 `npm run e2e:all -- --record` 自动驱动。
|
|
24
|
+
>
|
|
25
|
+
> **关于模型:** 背后的模型是 `scripts/e2e/` 中的**脚本化 mock**(当时没有 API Key),回答内容是预设的。画面中的流式渲染、交互、双向通信、持久化和隔离,都是插件在 DSH 中真实运行的结果。
|
|
26
|
+
>
|
|
27
|
+
> **在 GitHub 内联播放:** 把 `docs/assets/demo.mp4` 拖进 GitHub 的评论或 Release 编辑框,再把生成的 `https://github.com/user-attachments/assets/…` 链接单独一行粘贴到这里。GitHub 只对上传的附件内联播放视频,不支持仓库内的文件。
|
|
28
|
+
|
|
29
|
+
| 看板流式出现并定稿 | Three.js 组件:R 滑块、旋转、缩放 |
|
|
30
|
+
|:---:|:---:|
|
|
31
|
+
|  |  |
|
|
32
|
+
| *指标卡、栅格、标签页、带悬停提示的堆叠柱状图、可排序表格、时间线、表单* | *用 `UI.three()` 绘制 `x²+y²+z²=2Rz`,拖动滑块在本地即时改变曲面* |
|
|
33
|
+
|
|
34
|
+
| 公式、实时函数图像、Mermaid | 表单 → Agent → 新界面 |
|
|
35
|
+
|:---:|:---:|
|
|
36
|
+
|  |  |
|
|
37
|
+
|
|
38
|
+
| 流式预览(同一个 iframe 直接定稿) | 生成中途停止 |
|
|
39
|
+
|:---:|:---:|
|
|
40
|
+
|  |  |
|
|
41
|
+
|
|
42
|
+
| 深色主题 | 手机宽度(深色) | 刷新后恢复 |
|
|
43
|
+
|:---:|:---:|:---:|
|
|
44
|
+
|  |  |  |
|
|
45
|
+
|
|
46
|
+
## Agent 如何选择呈现方式
|
|
47
|
+
|
|
48
|
+
插件注入一段系统提示(`src/guidance.js`),让模型每一轮自行选择,用户无需输入任何命令:
|
|
49
|
+
|
|
50
|
+
- **普通文本**:寒暄、简短事实、解释说明、要复制的代码、工作区内的编程任务。
|
|
51
|
+
- **`ui_render`**:结构化内容,例如对比、数据、看板、流程、公式、可调参数的函数、选项、收集输入。
|
|
52
|
+
- **`ui_render_widget`**:用户想探索、操作或观察组件目录画不出的东西,例如三维、模拟、动画、游戏、自定义工具。
|
|
53
|
+
- **本地优先**:凡是能在浏览器里算出来的(滑块、旋转、缩放、筛选、排序、重新计算),都必须即时更新,不调用模型。
|
|
54
|
+
|
|
55
|
+
`/ui <需求>` 命令仍然保留,用于强制以 UI 作答。
|
|
56
|
+
|
|
57
|
+
## 组件目录(`ui_render`)
|
|
58
|
+
|
|
59
|
+
| 类别 | 组件 |
|
|
60
|
+
|---|---|
|
|
61
|
+
| 布局 | `Card`、`Stack`、`Grid`、`Tabs`(支持键盘操作) |
|
|
62
|
+
| 文本与提示 | `Text`(markdown 子集)、`Code`、`Alert`、`Badge`、`Divider` |
|
|
63
|
+
| 数据 | `Stat`、`Progress`、`List`、`Table`(可排序)、`Timeline` |
|
|
64
|
+
| 图表 | `Chart`(柱状、折线、面积、饼图;可堆叠,悬停提示,可点图例显隐系列) |
|
|
65
|
+
| 数学与图示 | **`Plot`**、**`Math`**(KaTeX)、**`Mermaid`** |
|
|
66
|
+
| 交互 | `Button`、`Form` |
|
|
67
|
+
|
|
68
|
+
- **`Plot`**:绘制 y = f(x),参数滑块拖动后曲线即时重绘。表达式由安全编译器解析,不使用 `eval`。
|
|
69
|
+
- **`Form`**:字段类型有文本、数字、**范围滑块**、下拉、勾选、日期、多行文本。
|
|
70
|
+
- **`Button` 与 `Form`**:点击或提交后,内容作为下一条用户消息发给 Agent。
|
|
71
|
+
|
|
72
|
+
**传输与校验:** DSH 的工具 schema 不支持递归,所以界面以**扁平节点列表加 id 引用**的形式传输。Host 先校验再确认,检查项包括:
|
|
73
|
+
|
|
74
|
+
- 未知类型或属性;
|
|
75
|
+
- id 悬空、重复或成环;
|
|
76
|
+
- 一个节点有多个父节点;
|
|
77
|
+
- 图表数据长度不一致;
|
|
78
|
+
- `Plot` 表达式无法编译、参数默认值越界等。
|
|
79
|
+
|
|
80
|
+
发现问题时返回 `ok:false` 并附带出错路径,模型据此修正后重试。
|
|
81
|
+
|
|
82
|
+
**`Math` 与 `Mermaid` 的渲染:** 两者在与组件相同的沙箱中,从 CDN 白名单加载 KaTeX 或 Mermaid。第三方代码不在 DSH 页面中运行,宿主包体积保持在约 127 KB。CDN 不可用时,显示源码文本。
|
|
83
|
+
|
|
84
|
+
## 沙箱组件(`ui_render_widget`)
|
|
85
|
+
|
|
86
|
+
字段顺序固定:`title`、`initialHeight`、`placeholderMessages`、`css`、`html`、`jsFunctions`、`jsExpressions`。
|
|
87
|
+
|
|
88
|
+
- **流式过程:**
|
|
89
|
+
1. `css` 完成前,显示占位文字。
|
|
90
|
+
2. `css` 完成后打开预览 iframe,把清洗过的部分 HTML 实时 morph 进去。
|
|
91
|
+
3. 参数完整后,在**同一个 iframe 内原地定稿**:morph 最终 HTML,然后执行代码。iframe 不重建,没有白屏闪烁,高度也不跳动。
|
|
92
|
+
- **运行时辅助(全局 `UI`):**
|
|
93
|
+
- `UI.three(el, opts)`:返回 renderer、场景、灯光和 OrbitControls(拖动旋转,滚轮或双指缩放),按需渲染并自适应尺寸。
|
|
94
|
+
- `UI.canvas(el, draw)`:高清 2D 画布,尺寸或主题变化时自动重绘。
|
|
95
|
+
- `UI.state` / `UI.setState()`:持久化状态;带 `id` 的输入控件会自动保存并恢复。
|
|
96
|
+
- `UI.color('accent')`:返回不透明的主题色,可直接用于 three.js 和 Canvas。
|
|
97
|
+
- `UI.onTheme(cb)`、`UI.scheme`、`UI.reducedMotion`:响应主题变化与减少动效偏好。
|
|
98
|
+
- 辅助样式类:`.ui-row`、`.ui-control`、`.ui-card`、`.ui-stage`。
|
|
99
|
+
- **Bridge:**
|
|
100
|
+
- `Bridge.sendPrompt({ text })`:在宿主应答前,自动禁用触发它的按钮,防止重复提交。
|
|
101
|
+
- `Bridge.openLink({ url })`:打开链接。
|
|
102
|
+
- `Websandbox.connection.remote.*`:为兼容 OpenIntelligentUI 而保留。
|
|
103
|
+
- **依赖库:** 通过 importmap 从 esm.sh 引入 `three`、`three/addons/…`、`d3`、`chart.js/auto`、`gsap`、`canvas-confetti`。
|
|
104
|
+
- **错误恢复:** 出现脚本错误时显示错误数量,并提供“重新加载”和“让模型修复”两个按钮。后者会把错误信息发给 Agent。
|
|
105
|
+
|
|
106
|
+
## 显示位置与状态保持
|
|
107
|
+
|
|
108
|
+
- **显示位置:**
|
|
109
|
+
- 回合进行中,UI 在工具调用处内联显示。从准备、执行到结果,始终是同一个组件实例,交互状态不会丢。
|
|
110
|
+
- 回合结束后,插件通过 `conversation.chat.turnTail` 把 UI **重新显示在回复下方**,内联处改为一行提示。
|
|
111
|
+
- **按工具调用保存的交互状态:** 当前标签页、表格排序、表单值、已提交锁定、Plot 滑块、组件控件值、`UI.state`、iframe 高度。这些状态保存在内存和 `localStorage` 中(有容量上限),移到回复下方或刷新页面后都会恢复。UI 本身则从持久化的会话日志重建。
|
|
112
|
+
- **中途停止:**
|
|
113
|
+
- 已进入会话日志的调用:保留已完成的部分(组件的静态预览,或已生成的组件),并显示提示和“重新生成”按钮。
|
|
114
|
+
- 参数仍在流式输出时就被停止的调用:DSH 会整体丢弃它。插件会暂存已生成的内容,同样在被停止的回合下方显示。
|
|
115
|
+
|
|
116
|
+
## 安全模型
|
|
117
|
+
|
|
118
|
+
- **隔离:**
|
|
119
|
+
- iframe 设置 `sandbox="allow-scripts allow-forms"` 并使用 `srcdoc`,**不加** `allow-same-origin`。
|
|
120
|
+
- E2E 在浏览器中实测:访问 `parent.document`、`localStorage`、`cookie` 均抛出 `SecurityError`,`fetch` 被拦截,`window.origin` 为 `"null"`。
|
|
121
|
+
- **CSP:**
|
|
122
|
+
- `default-src 'none'`;
|
|
123
|
+
- 脚本、样式、字体、图片只能来自 `cdnAllowlist`;
|
|
124
|
+
- 默认 `connect-src 'none'`;
|
|
125
|
+
- `form-action 'none'`、`base-uri 'none'`。
|
|
126
|
+
- **消息校验:**
|
|
127
|
+
- 宿主只接受来自该 iframe 的 `contentWindow`、带随机 token、且格式合法的消息。
|
|
128
|
+
- 持久化的组件状态是有大小上限的 JSON。
|
|
129
|
+
- E2E 实测,从页面或 iframe 伪造的消息都会被丢弃。
|
|
130
|
+
- **sendPrompt 限制:**
|
|
131
|
+
- 挂载后 1 秒内拒绝发送;
|
|
132
|
+
- 2 秒内最多发送一次;
|
|
133
|
+
- 长度受 `sendPromptMaxChars` 限制;
|
|
134
|
+
- 以普通的排队用户消息发送。
|
|
135
|
+
- **openLink:** 只允许 https,可用白名单进一步限制。
|
|
136
|
+
- **Plot 表达式:** 由分词器和解析器编译,只能调用固定的数学函数表,无法使用 `eval`、`Function` 或访问属性。
|
|
137
|
+
|
|
138
|
+
## 安装
|
|
139
|
+
|
|
140
|
+
需要 [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) **0.1.7 – 0.2.x**(`>=0.1.7-rc.1 <0.3.0`)和 Node.js ≥ 22.13,Windows、Linux、macOS 均可。安装过程不需要编译:npm 包自带预构建的浏览器端 bundle,也没有任何安装脚本。
|
|
141
|
+
|
|
142
|
+
```sh
|
|
143
|
+
dsh plugin --profile web add deepseek-harness-intelligent-ui
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
也可以用引导式安装器。它会先检查 Node、`dsh` 版本、pnpm 和 profile,检查通过后执行同样的 `dsh plugin add`:
|
|
147
|
+
|
|
148
|
+
```sh
|
|
149
|
+
npx deepseek-harness-intelligent-ui install # 可选 --profile <名称>、--dsh <路径>、--dry-run
|
|
150
|
+
npx deepseek-harness-intelligent-ui doctor # 只诊断,不做修改
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
| 操作 | 命令 |
|
|
154
|
+
|---|---|
|
|
155
|
+
| 升级 | `dsh plugin --profile web add deepseek-harness-intelligent-ui@latest` |
|
|
156
|
+
| 试用预发布版(仅在存在 `next` 标签时) | `dsh plugin --profile web add deepseek-harness-intelligent-ui@next` |
|
|
157
|
+
| 固定版本 | `dsh plugin --profile web add deepseek-harness-intelligent-ui@0.2.2` |
|
|
158
|
+
| 卸载 | `dsh plugin --profile web remove deepseek-harness-intelligent-ui`(或 `npx deepseek-harness-intelligent-ui uninstall`) |
|
|
159
|
+
| 从源码目录安装 | `dsh plugin --profile web add file:/path/to/deepseek-harness-intelligent-ui` |
|
|
160
|
+
|
|
161
|
+
安装后需要重启 DSH Web。bundle patch 会自动插入 `intelligent-ui` 这一行。要修改配置,在 profile 的 `cordis.patch.yml` 中添加 `- id: intelligent-ui` 和对应的 `config:`,配置项见英文 README 的表格。支持的 DSH 版本和 CI 测试矩阵见 [docs/compatibility.md](https://github.com/dreamfarer-space/deepseek-harness-intelligent-ui/blob/v0.2.2/docs/compatibility.md)。
|
|
162
|
+
|
|
163
|
+
**常见问题**
|
|
164
|
+
|
|
165
|
+
- *提示 `pnpm was not found`*:DSH 用 pnpm 安装插件。运行 `corepack enable`(Node 自带)或 `npm i -g pnpm`。
|
|
166
|
+
- *提示 `… is incompatible with dsh X`*:当前 DSH 版本不在支持范围内。可以升级 DSH(`npm i -g @deepseek-ai/dsh@latest`),或在[兼容性文档](https://github.com/dreamfarer-space/deepseek-harness-intelligent-ui/blob/v0.2.2/docs/compatibility.md)里找支持该版本的插件发行版。
|
|
167
|
+
- *从 0.1.x 升级(以前用 `file:` 安装的 `dsh-intelligent-ui`)*:先运行 `dsh plugin --profile web remove dsh-intelligent-ui`。新旧两个包会插入同一个 `intelligent-ui` 行,`doctor` 能检测到这种冲突。
|
|
168
|
+
- *界面没有出现*:安装后要重启 DSH Web,并确认启动的是安装插件时指定的 profile(`dsh web`)。
|
|
169
|
+
|
|
170
|
+
## 开发与验证
|
|
171
|
+
|
|
172
|
+
```sh
|
|
173
|
+
npm install
|
|
174
|
+
npm run build
|
|
175
|
+
npm test # 单元/组件测试(含 DSH 兼容性检查与安装器 CLI)
|
|
176
|
+
npm run typecheck
|
|
177
|
+
npm run e2e:all # 构建 → 安装到临时 DSH 目录 → mock 模型 + 真实 DSH Web → 24 项浏览器检查
|
|
178
|
+
npm run e2e:all -- --record # 同时重新录制 docs/assets/demo.mp4 / demo.gif(需要 ffmpeg)
|
|
179
|
+
npm run e2e:all -- --spec ./deepseek-harness-intelligent-ui-<版本>.tgz # 改为对 npm pack 打出的包做 E2E
|
|
180
|
+
npm run smoke -- --spec ./deepseek-harness-intelligent-ui-<版本>.tgz # 安装冒烟测试(不需要浏览器)
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
E2E 可以在 Windows、Linux、macOS 上运行。它会按平台自动查找 Chrome(可用 `CHROME_PATH` 指定),`DSH_BIN` 可指定其他 `dsh` 可执行文件。检查项见 `scripts/e2e/browser.mjs`,最近一次报告在 [`docs/e2e-report.json`](https://github.com/dreamfarer-space/deepseek-harness-intelligent-ui/blob/v0.2.1/docs/e2e-report.json)。GitHub Actions 会在三个系统上,针对每个受支持的 DSH 版本跑完全部测试。
|
|
184
|
+
|
|
185
|
+
`client/client.js` 已提交到仓库并随包发布,所以 npm、`file:` 和 git 安装都不需要构建。不要添加 `prepare` 或 `postinstall` 脚本,因为 DSH 使用的 pnpm 会拦截插件的构建脚本。
|
|
186
|
+
|
|
187
|
+
**发布流程**(维护者):
|
|
188
|
+
|
|
189
|
+
发布安全与 OIDC 配置见[维护者说明](https://github.com/dreamfarer-space/deepseek-harness-intelligent-ui/blob/main/docs/releasing.md)。
|
|
190
|
+
|
|
191
|
+
1. 在 [CHANGELOG.md](CHANGELOG.md) 中新增 `## [x.y.z]` 小节。
|
|
192
|
+
2. 运行 `npm version x.y.z`(或 `npm version prerelease --preid rc`)。这一步会用新版本号重新构建 `client/client.js` 并打 tag。
|
|
193
|
+
3. 运行 `git push --follow-tags`。tag 推送后,Release 工作流会依次执行:
|
|
194
|
+
- 运行完整的 CI 矩阵;
|
|
195
|
+
- 带 provenance 发布到 npm(预发布版使用 `next` 标签);
|
|
196
|
+
- 在三个系统上对已发布的包做冒烟测试;
|
|
197
|
+
- 用 CHANGELOG 的对应小节和 tarball 创建 GitHub Release。
|
|
198
|
+
4. 本地可以先运行 `npm run release:check` 做同样的预检。
|
|
199
|
+
|
|
200
|
+
## 真实模型评测
|
|
201
|
+
|
|
202
|
+
API 测试套件覆盖 15 个提示词,检查模型路由、工具参数格式,以及部分指定组件和数据。它**不会在浏览器中执行模型生成的组件**,也不验证数据事实、视觉质量、物理正确性或交互行为。独立浏览器 E2E 使用脚本化模型回复。
|
|
203
|
+
|
|
204
|
+
仓库保留的[历史报告](https://github.com/dreamfarer-space/deepseek-harness-intelligent-ui/blob/v0.2.1/docs/real-model-eval-report.json)来自旧判分器,其中 15/15 不能作为当前通过率:B3 没有 Chart,却被判为通过。报告已标注此问题;其他用例需在新规则下重新运行,不能据此继续宣称全量通过。
|
|
205
|
+
|
|
206
|
+
新版要求组件可从根节点到达,B2 必须有可排序表格,B3 必须有四季度多系列柱状图,B4 表单必须有滑块和复选框,原生 C2 Plot 必须有参数滑块。多轮测试会校验所有工具调用并逐个回复,要求后续内容包含提交的 APAC、4 个季度和乐观情景,并核对三个型号的屏幕尺寸及原表格数据。这些自动断言不代表完整质量评估。
|
|
207
|
+
|
|
208
|
+
运行前设置环境变量 `DEEPSEEK_API_KEY`,不再读取固定路径的凭据文件:
|
|
209
|
+
|
|
210
|
+
```sh
|
|
211
|
+
export DEEPSEEK_API_KEY='<你的密钥>'
|
|
212
|
+
node scripts/run-real-model-suite.mjs all # 可选 A、B、C、D 或 all
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
```powershell
|
|
216
|
+
$env:DEEPSEEK_API_KEY = '<你的密钥>'
|
|
217
|
+
node scripts/run-real-model-suite.mjs all
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
每次仅将本次用例写入 `docs/real-model-eval-report.json`,分类运行不混入旧结果。断言或 API 请求失败时返回退出码 1;类别错误或密钥缺失会在改写报告前退出。请勿将密钥提交到 git。
|
|
221
|
+
|
|
222
|
+
## 已知限制
|
|
223
|
+
|
|
224
|
+
- 沙箱组件、`Math` 和 `Mermaid` 需要能访问 CDN 白名单。离线时,`Math` 和 `Mermaid` 退回显示源码,`UI.three` 会报告脚本错误。
|
|
225
|
+
- 交互状态保存在当前浏览器的 `localStorage` 中,不跨设备同步。
|
|
226
|
+
- 对“流式中途被丢弃的调用”,插件按回合的起止时间归属。如果远程 DSH 主机与浏览器的时钟偏差较大,这张卡片可能不显示。已进入会话日志的调用不受影响。
|
|
227
|
+
|
|
228
|
+
## 致谢
|
|
229
|
+
|
|
230
|
+
概念、流式组件协议和部分提示词来自 [CopilotKit/OpenIntelligentUI](https://github.com/CopilotKit/OpenIntelligentUI)(MIT 许可)。本项目采用 MIT 许可。
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Third-party notices
|
|
2
|
+
|
|
3
|
+
## CopilotKit/OpenIntelligentUI — MIT License
|
|
4
|
+
|
|
5
|
+
https://github.com/CopilotKit/OpenIntelligentUI
|
|
6
|
+
|
|
7
|
+
This plugin adapts the following from OpenIntelligentUI. It contains no verbatim source files; the code was rewritten for DeepSeek Harness.
|
|
8
|
+
|
|
9
|
+
- **Widget streaming contract:** the field order `initialHeight`, `placeholderMessages`, `css`, `html`, `jsFunctions`, `jsExpressions`.
|
|
10
|
+
- **Frame layout:** CSP, then importmap, then design CSS, then widget CSS, then body.
|
|
11
|
+
- **Partial-HTML sanitization approach.**
|
|
12
|
+
- **`sendPrompt` bridge semantics.**
|
|
13
|
+
- **Guidance wording:** parts of the agent prompt guidance (`apps/agent/src/prompt.py`).
|
|
14
|
+
|
|
15
|
+
Copyright (c) CopilotKit. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, subject to the condition that the above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND.
|
|
16
|
+
|
|
17
|
+
## idiomorph — 0BSD License
|
|
18
|
+
|
|
19
|
+
https://github.com/bigskysoftware/idiomorph (v0.7.4). Its minified build is embedded in `client/client.js` and injected into widget preview frames.
|
|
20
|
+
|
|
21
|
+
Copyright (c) Big Sky Software. Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES.
|
|
22
|
+
|
|
23
|
+
## React — MIT License
|
|
24
|
+
|
|
25
|
+
React is provided at runtime by the DSH Web shell. It is not bundled.
|