@researai/deepscientist 1.5.0 → 1.5.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/AGENTS.md +26 -0
- package/README.md +47 -161
- package/assets/connectors/lingzhu/openclaw-bridge/README.md +124 -0
- package/assets/connectors/lingzhu/openclaw-bridge/index.ts +162 -0
- package/assets/connectors/lingzhu/openclaw-bridge/openclaw.plugin.json +145 -0
- package/assets/connectors/lingzhu/openclaw-bridge/package.json +35 -0
- package/assets/connectors/lingzhu/openclaw-bridge/src/cli.ts +180 -0
- package/assets/connectors/lingzhu/openclaw-bridge/src/config.ts +196 -0
- package/assets/connectors/lingzhu/openclaw-bridge/src/debug-log.ts +111 -0
- package/assets/connectors/lingzhu/openclaw-bridge/src/events.ts +4 -0
- package/assets/connectors/lingzhu/openclaw-bridge/src/http-handler.ts +1133 -0
- package/assets/connectors/lingzhu/openclaw-bridge/src/image-cache.ts +75 -0
- package/assets/connectors/lingzhu/openclaw-bridge/src/lingzhu-tools.ts +246 -0
- package/assets/connectors/lingzhu/openclaw-bridge/src/transform.ts +541 -0
- package/assets/connectors/lingzhu/openclaw-bridge/src/types.ts +131 -0
- package/assets/connectors/lingzhu/openclaw-bridge/tsconfig.json +14 -0
- package/assets/connectors/lingzhu/openclaw.lingzhu.config.template.json +39 -0
- package/bin/ds.js +2048 -166
- package/docs/en/00_QUICK_START.md +152 -0
- package/docs/en/01_SETTINGS_REFERENCE.md +1104 -0
- package/docs/en/02_START_RESEARCH_GUIDE.md +404 -0
- package/docs/en/03_QQ_CONNECTOR_GUIDE.md +325 -0
- package/docs/en/04_LINGZHU_CONNECTOR_GUIDE.md +216 -0
- package/docs/en/05_TUI_GUIDE.md +141 -0
- package/docs/en/06_RUNTIME_AND_CANVAS.md +679 -0
- package/docs/en/07_MEMORY_AND_MCP.md +253 -0
- package/docs/en/08_FIGURE_STYLE_GUIDE.md +97 -0
- package/docs/en/09_DOCTOR.md +152 -0
- package/docs/en/90_ARCHITECTURE.md +247 -0
- package/docs/en/91_DEVELOPMENT.md +195 -0
- package/docs/en/99_ACKNOWLEDGEMENTS.md +29 -0
- package/docs/zh/00_QUICK_START.md +152 -0
- package/docs/zh/01_SETTINGS_REFERENCE.md +1137 -0
- package/docs/zh/02_START_RESEARCH_GUIDE.md +414 -0
- package/docs/zh/03_QQ_CONNECTOR_GUIDE.md +324 -0
- package/docs/zh/04_LINGZHU_CONNECTOR_GUIDE.md +230 -0
- package/docs/zh/05_TUI_GUIDE.md +128 -0
- package/docs/zh/06_RUNTIME_AND_CANVAS.md +271 -0
- package/docs/zh/07_MEMORY_AND_MCP.md +235 -0
- package/docs/zh/08_FIGURE_STYLE_GUIDE.md +97 -0
- package/docs/zh/09_DOCTOR.md +154 -0
- package/docs/zh/99_ACKNOWLEDGEMENTS.md +29 -0
- package/install.sh +41 -16
- package/package.json +5 -2
- package/pyproject.toml +1 -1
- package/src/deepscientist/__init__.py +6 -1
- package/src/deepscientist/artifact/guidance.py +9 -2
- package/src/deepscientist/artifact/service.py +1026 -39
- package/src/deepscientist/bash_exec/monitor.py +27 -5
- package/src/deepscientist/bash_exec/runtime.py +639 -0
- package/src/deepscientist/bash_exec/service.py +99 -16
- package/src/deepscientist/bridges/base.py +3 -0
- package/src/deepscientist/bridges/connectors.py +292 -13
- package/src/deepscientist/channels/qq.py +19 -2
- package/src/deepscientist/channels/relay.py +1 -0
- package/src/deepscientist/cli.py +32 -25
- package/src/deepscientist/config/models.py +28 -2
- package/src/deepscientist/config/service.py +202 -7
- package/src/deepscientist/connector_runtime.py +2 -0
- package/src/deepscientist/daemon/api/handlers.py +68 -6
- package/src/deepscientist/daemon/api/router.py +3 -0
- package/src/deepscientist/daemon/app.py +531 -15
- package/src/deepscientist/doctor.py +511 -0
- package/src/deepscientist/gitops/diff.py +3 -0
- package/src/deepscientist/home.py +26 -2
- package/src/deepscientist/latex_runtime.py +17 -4
- package/src/deepscientist/lingzhu_support.py +182 -0
- package/src/deepscientist/mcp/context.py +3 -1
- package/src/deepscientist/mcp/server.py +55 -2
- package/src/deepscientist/prompts/builder.py +222 -58
- package/src/deepscientist/quest/layout.py +2 -0
- package/src/deepscientist/quest/service.py +133 -14
- package/src/deepscientist/quest/stage_views.py +65 -1
- package/src/deepscientist/runners/codex.py +2 -0
- package/src/deepscientist/runtime_tools/__init__.py +16 -0
- package/src/deepscientist/runtime_tools/builtins.py +19 -0
- package/src/deepscientist/runtime_tools/models.py +29 -0
- package/src/deepscientist/runtime_tools/registry.py +40 -0
- package/src/deepscientist/runtime_tools/service.py +59 -0
- package/src/deepscientist/runtime_tools/tinytex.py +25 -0
- package/src/deepscientist/shared.py +44 -17
- package/src/deepscientist/tinytex.py +276 -0
- package/src/prompts/connectors/lingzhu.md +15 -0
- package/src/prompts/connectors/qq.md +121 -0
- package/src/prompts/system.md +214 -37
- package/src/skills/analysis-campaign/SKILL.md +46 -7
- package/src/skills/baseline/SKILL.md +12 -5
- package/src/skills/decision/SKILL.md +7 -5
- package/src/skills/experiment/SKILL.md +22 -5
- package/src/skills/finalize/SKILL.md +9 -5
- package/src/skills/idea/SKILL.md +6 -5
- package/src/skills/intake-audit/SKILL.md +277 -0
- package/src/skills/intake-audit/references/state-audit-template.md +41 -0
- package/src/skills/rebuttal/SKILL.md +409 -0
- package/src/skills/rebuttal/references/action-plan-template.md +63 -0
- package/src/skills/rebuttal/references/evidence-update-template.md +30 -0
- package/src/skills/rebuttal/references/response-letter-template.md +113 -0
- package/src/skills/rebuttal/references/review-matrix-template.md +55 -0
- package/src/skills/review/SKILL.md +295 -0
- package/src/skills/review/references/experiment-todo-template.md +29 -0
- package/src/skills/review/references/review-report-template.md +83 -0
- package/src/skills/review/references/revision-log-template.md +40 -0
- package/src/skills/scout/SKILL.md +6 -5
- package/src/skills/write/SKILL.md +8 -4
- package/src/tui/dist/components/WelcomePanel.js +17 -43
- package/src/tui/dist/components/messages/BashExecOperationMessage.js +3 -2
- package/src/tui/package.json +1 -1
- package/src/ui/dist/assets/{AiManusChatView-7v-dHngU.js → AiManusChatView-CZpg376x.js} +127 -597
- package/src/ui/dist/assets/{AnalysisPlugin-B_Xmz-KE.js → AnalysisPlugin-CtHA22g3.js} +1 -1
- package/src/ui/dist/assets/{AutoFigurePlugin-Cko-0tm1.js → AutoFigurePlugin-BSWmLMmF.js} +63 -8
- package/src/ui/dist/assets/{CliPlugin-BsU0ht7q.js → CliPlugin-CJ7jdm_s.js} +43 -609
- package/src/ui/dist/assets/{CodeEditorPlugin-DcMMP0Rt.js → CodeEditorPlugin-DhInVGFf.js} +8 -8
- package/src/ui/dist/assets/{CodeViewerPlugin-BqoQ5QyY.js → CodeViewerPlugin-D1n8S9r5.js} +5 -5
- package/src/ui/dist/assets/{DocViewerPlugin-D7eHNhU6.js → DocViewerPlugin-C4XM_kqk.js} +3 -3
- package/src/ui/dist/assets/{GitDiffViewerPlugin-DLJN42T5.js → GitDiffViewerPlugin-W6kS9r6v.js} +1 -1
- package/src/ui/dist/assets/{ImageViewerPlugin-gJMV7MOu.js → ImageViewerPlugin-DPeUx_Oz.js} +5 -6
- package/src/ui/dist/assets/{LabCopilotPanel-B857sfxP.js → LabCopilotPanel-eAelUaub.js} +12 -15
- package/src/ui/dist/assets/LabPlugin-BbOrBxKY.js +2676 -0
- package/src/ui/dist/assets/{LatexPlugin-DWKEo-Wj.js → LatexPlugin-C-HhkVXY.js} +16 -16
- package/src/ui/dist/assets/{MarkdownViewerPlugin-DBzoEmhv.js → MarkdownViewerPlugin-BDIzIBfh.js} +4 -4
- package/src/ui/dist/assets/{MarketplacePlugin-DoHc-8vo.js → MarketplacePlugin-DAOJphwr.js} +3 -3
- package/src/ui/dist/assets/{NotebookEditor-CKjKH-yS.js → NotebookEditor-BsoMvDoU.js} +3 -3
- package/src/ui/dist/assets/{PdfLoader-zFoL0VPo.js → PdfLoader-fiC7RtHf.js} +1 -1
- package/src/ui/dist/assets/{PdfMarkdownPlugin-DXPaL9Nt.js → PdfMarkdownPlugin-C5OxZBFK.js} +3 -3
- package/src/ui/dist/assets/{PdfViewerPlugin-DhK8qCFp.js → PdfViewerPlugin-CAbxQebk.js} +10 -10
- package/src/ui/dist/assets/{SearchPlugin-CdSi6krf.js → SearchPlugin-SE33Lb9B.js} +1 -1
- package/src/ui/dist/assets/{Stepper-V-WiDQJl.js → Stepper-0Av7GfV7.js} +1 -1
- package/src/ui/dist/assets/{TextViewerPlugin-hIs1Efiu.js → TextViewerPlugin-Daf2gJDI.js} +4 -4
- package/src/ui/dist/assets/{VNCViewer-DG8b0q2X.js → VNCViewer-BKrMUIOX.js} +9 -10
- package/src/ui/dist/assets/{bibtex-HDac6fVW.js → bibtex-JBdOEe45.js} +1 -1
- package/src/ui/dist/assets/{code-BnBeNxBc.js → code-B0TDFCZz.js} +1 -1
- package/src/ui/dist/assets/{file-content-IRQ3jHb8.js → file-content-3YtrSacz.js} +1 -1
- package/src/ui/dist/assets/{file-diff-panel-DZoQ9I6r.js → file-diff-panel-CJEg5OG1.js} +1 -1
- package/src/ui/dist/assets/{file-socket-BMCdLc-P.js → file-socket-CYQYdmB1.js} +1 -1
- package/src/ui/dist/assets/{file-utils-CltILB3w.js → file-utils-Cd1C9Ppl.js} +1 -1
- package/src/ui/dist/assets/{image-Boe6ffhu.js → image-B33ctrvC.js} +1 -1
- package/src/ui/dist/assets/{index-2Zf65FZt.js → index-9CLPVeZh.js} +1 -1
- package/src/ui/dist/assets/{index-DZqJ-qAM.js → index-BNQWqmJ2.js} +60 -2154
- package/src/ui/dist/assets/{index-DO43pFZP.js → index-BVXsmS7V.js} +84086 -84365
- package/src/ui/dist/assets/{index-BlplpvE1.js → index-Buw_N1VQ.js} +2 -2
- package/src/ui/dist/assets/{index-Bq2bvfkl.css → index-SwmFAld3.css} +2622 -2619
- package/src/ui/dist/assets/{message-square-mUHn_Ssb.js → message-square-D0cUJ9yU.js} +1 -1
- package/src/ui/dist/assets/{monaco-fe0arNEU.js → monaco-UZLYkp2n.js} +1 -1
- package/src/ui/dist/assets/{popover-D_7i19qU.js → popover-CTeiY-dK.js} +1 -1
- package/src/ui/dist/assets/{project-sync-DyVGrU7H.js → project-sync-Dbs01Xky.js} +2 -8
- package/src/ui/dist/assets/{sigma-BzazRyxQ.js → sigma-CM08S-xT.js} +1 -1
- package/src/ui/dist/assets/{tooltip-DN_yjHFH.js → tooltip-pDtzvU9p.js} +1 -1
- package/src/ui/dist/assets/trash-YvPCP-da.js +32 -0
- package/src/ui/dist/assets/{useCliAccess-DV2L2Qxy.js → useCliAccess-Bavi74Ac.js} +12 -42
- package/src/ui/dist/assets/{useFileDiffOverlay-DyTj-p_V.js → useFileDiffOverlay-CVXY6oeg.js} +1 -1
- package/src/ui/dist/assets/{wrap-text-ozYHtUwq.js → wrap-text-Cf4flRW7.js} +1 -1
- package/src/ui/dist/assets/{zoom-out-BN9MUyCQ.js → zoom-out-Hb0Z1YpT.js} +1 -1
- package/src/ui/dist/index.html +2 -2
- package/uv.lock +1155 -0
- package/assets/fonts/Inter-Variable.ttf +0 -0
- package/assets/fonts/NotoSerifSC-Regular-C94HN_ZN.ttf +0 -0
- package/assets/fonts/NunitoSans-Variable.ttf +0 -0
- package/assets/fonts/Satoshi-Medium-ByP-Zb-9.woff2 +0 -0
- package/assets/fonts/SourceSans3-Variable.ttf +0 -0
- package/assets/fonts/ds-fonts.css +0 -83
- package/src/ui/dist/assets/Inter-Variable-VF2RPR_K.ttf +0 -0
- package/src/ui/dist/assets/LabPlugin-bL7rpic8.js +0 -43
- package/src/ui/dist/assets/NotoSerifSC-Regular-C94HN_ZN-C94HN_ZN.ttf +0 -0
- package/src/ui/dist/assets/NunitoSans-Variable-B_ZymHAd.ttf +0 -0
- package/src/ui/dist/assets/Satoshi-Medium-ByP-Zb-9-GkA34YXu.woff2 +0 -0
- package/src/ui/dist/assets/SourceSans3-Variable-CD-WOsSK.ttf +0 -0
- package/src/ui/dist/assets/info-CcsK_htA.js +0 -18
- package/src/ui/dist/assets/user-plus-BusDx-hF.js +0 -79
package/AGENTS.md
CHANGED
|
@@ -28,9 +28,12 @@ The target is a focused core runtime, not a large platform.
|
|
|
28
28
|
Start with the files that actually exist in this checkout:
|
|
29
29
|
|
|
30
30
|
- `README.md`
|
|
31
|
+
- `docs/en/ARCHITECTURE.md`
|
|
32
|
+
- `docs/en/DEVELOPMENT.md`
|
|
31
33
|
- `docs/en/TUI_USAGE.md`
|
|
32
34
|
- `docs/en/SETTINGS_REFERENCE.md`
|
|
33
35
|
- `src/deepscientist/`
|
|
36
|
+
- `src/deepscientist/runtime_tools/`
|
|
34
37
|
- `src/prompts/`
|
|
35
38
|
- `src/skills/`
|
|
36
39
|
- `src/ui/src/`
|
|
@@ -81,6 +84,7 @@ Prefer small registries for:
|
|
|
81
84
|
- channels
|
|
82
85
|
- connector bridges
|
|
83
86
|
- skill discovery
|
|
87
|
+
- managed local runtime tools
|
|
84
88
|
- optional plugin adapters
|
|
85
89
|
|
|
86
90
|
Prefer `register_*()`, `get_*()`, and `list_*()` APIs over large dispatch branches.
|
|
@@ -119,6 +123,7 @@ Important runtime entry points:
|
|
|
119
123
|
- API handlers: `src/deepscientist/daemon/api/handlers.py`
|
|
120
124
|
- prompt builder: `src/deepscientist/prompts/builder.py`
|
|
121
125
|
- system prompt: `src/prompts/system.md`
|
|
126
|
+
- managed local tools: `src/deepscientist/runtime_tools/`
|
|
122
127
|
|
|
123
128
|
## Runtime Layout
|
|
124
129
|
|
|
@@ -185,6 +190,9 @@ If you add or rename a stage skill:
|
|
|
185
190
|
|
|
186
191
|
- Keep public docs clear and task-oriented.
|
|
187
192
|
- Prefer English and Chinese user docs under `docs/en/` and `docs/zh/`.
|
|
193
|
+
- Maintainer-facing source-of-truth docs live in:
|
|
194
|
+
- `docs/en/ARCHITECTURE.md`
|
|
195
|
+
- `docs/en/DEVELOPMENT.md`
|
|
188
196
|
- Keep docs names stable when they are linked from the UI.
|
|
189
197
|
- If a document is implementation planning rather than user guidance, keep it out of `docs/`.
|
|
190
198
|
|
|
@@ -218,6 +226,13 @@ If you add or rename a stage skill:
|
|
|
218
226
|
- User-facing delivery belongs in channels.
|
|
219
227
|
- Provider adaptation belongs in bridges.
|
|
220
228
|
|
|
229
|
+
### Managed local runtime tools
|
|
230
|
+
|
|
231
|
+
- Keep optional local tool installs behind `src/deepscientist/runtime_tools/`.
|
|
232
|
+
- Register new tools through the runtime tool registry instead of scattering ad hoc install logic.
|
|
233
|
+
- Reuse `RuntimeToolService` for status, install, and binary resolution.
|
|
234
|
+
- Document user-visible install or troubleshooting changes in docs.
|
|
235
|
+
|
|
221
236
|
### UI and TUI
|
|
222
237
|
|
|
223
238
|
- Preserve the shared contract between the two clients.
|
|
@@ -259,6 +274,17 @@ When changing connectors:
|
|
|
259
274
|
- update `src/deepscientist/bridges/`
|
|
260
275
|
- update connector tests
|
|
261
276
|
|
|
277
|
+
When changing managed local tools:
|
|
278
|
+
|
|
279
|
+
- update `src/deepscientist/runtime_tools/`
|
|
280
|
+
- update the concrete tool adapter such as `src/deepscientist/tinytex.py` if needed
|
|
281
|
+
- update any callers in CLI, doctor, or runtime services
|
|
282
|
+
- update maintainer docs:
|
|
283
|
+
- `docs/en/ARCHITECTURE.md`
|
|
284
|
+
- `docs/en/DEVELOPMENT.md`
|
|
285
|
+
- update user docs if install or troubleshooting changes are user-visible
|
|
286
|
+
- update or add tests for registration, status, install, and binary resolution
|
|
287
|
+
|
|
262
288
|
When changing API surface used by web and TUI:
|
|
263
289
|
|
|
264
290
|
- update `src/deepscientist/daemon/api/router.py`
|
package/README.md
CHANGED
|
@@ -6,210 +6,96 @@
|
|
|
6
6
|
|
|
7
7
|
<p align="center">
|
|
8
8
|
Local-first research operating system with a Python runtime, an npm launcher,
|
|
9
|
-
one
|
|
9
|
+
one quest per Git repository, and shared web plus TUI surfaces.
|
|
10
10
|
</p>
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
<a href="docs/en/TUI_USAGE.md">English Docs</a>
|
|
14
|
-
·
|
|
15
|
-
<a href="docs/zh/TUI_USAGE.md">中文文档</a>
|
|
16
|
-
·
|
|
17
|
-
<a href="CONTRIBUTING.md">Contributing</a>
|
|
18
|
-
</p>
|
|
19
|
-
|
|
20
|
-
## What DeepScientist is
|
|
21
|
-
|
|
22
|
-
DeepScientist is designed for long-running research quests that need durable state,
|
|
23
|
-
repeatable artifacts, Git-backed history, and a local copilot workspace.
|
|
24
|
-
|
|
25
|
-
Core product shape:
|
|
12
|
+
## Install
|
|
26
13
|
|
|
27
|
-
|
|
28
|
-
- Python is the authoritative runtime
|
|
29
|
-
- npm is the normal install and launch path
|
|
30
|
-
- both web UI and TUI talk to the same daemon API
|
|
31
|
-
- only three built-in MCP namespaces are public:
|
|
32
|
-
- `memory`
|
|
33
|
-
- `artifact`
|
|
34
|
-
- `bash_exec`
|
|
35
|
-
- prompts plus skills define most workflow behavior
|
|
36
|
-
|
|
37
|
-
## Installation
|
|
38
|
-
|
|
39
|
-
### Published npm package
|
|
40
|
-
|
|
41
|
-
The public npm package should be installed with the lowercase scoped name:
|
|
14
|
+
Install DeepScientist:
|
|
42
15
|
|
|
43
16
|
```bash
|
|
44
17
|
npm install -g @researai/deepscientist
|
|
45
18
|
```
|
|
46
19
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
```bash
|
|
50
|
-
ds --web
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
Useful launcher commands:
|
|
54
|
-
|
|
55
|
-
```bash
|
|
56
|
-
ds --web
|
|
57
|
-
ds --tui
|
|
58
|
-
ds --both
|
|
59
|
-
ds --stop
|
|
60
|
-
ds --restart
|
|
61
|
-
```
|
|
62
|
-
|
|
63
|
-
Notes:
|
|
64
|
-
|
|
65
|
-
- the daemon binds `0.0.0.0:20999` by default
|
|
66
|
-
- the browser is opened through `http://127.0.0.1:20999`
|
|
67
|
-
- the first startup bootstraps `~/DeepScientist/runtime/venv`
|
|
68
|
-
- the launcher also verifies that the `codex` runtime is available before starting
|
|
69
|
-
|
|
70
|
-
### From a source checkout
|
|
71
|
-
|
|
72
|
-
For local development from this repository:
|
|
20
|
+
## Start
|
|
73
21
|
|
|
74
22
|
```bash
|
|
75
|
-
bash install.sh
|
|
76
23
|
ds
|
|
77
24
|
```
|
|
78
25
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
- Node.js `>=18.18`
|
|
82
|
-
- npm `>=9`
|
|
83
|
-
- Python `>=3.11`
|
|
84
|
-
- Git on `PATH`
|
|
85
|
-
- access to the `codex` CLI used by the runtime
|
|
26
|
+
DeepScientist starts the local web workspace at `http://127.0.0.1:20999` by default.
|
|
86
27
|
|
|
87
|
-
|
|
28
|
+
On first start, `ds` will:
|
|
88
29
|
|
|
89
|
-
- a local
|
|
30
|
+
- bootstrap a local `uv` runtime manager automatically if your machine does not already have one
|
|
31
|
+
- use the bundled Codex CLI that ships with the npm package
|
|
32
|
+
- still require you to complete Codex login once if your account is not ready yet
|
|
90
33
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
1. Install the package or run `bash install.sh` from source.
|
|
94
|
-
2. Start the web UI with `ds --web` or both surfaces with `ds --both`.
|
|
95
|
-
3. Open the local workspace at `http://127.0.0.1:20999`.
|
|
96
|
-
4. Create a quest from the home page or from the CLI:
|
|
34
|
+
If you want another port:
|
|
97
35
|
|
|
98
36
|
```bash
|
|
99
|
-
ds
|
|
37
|
+
ds --port 21000
|
|
100
38
|
```
|
|
101
39
|
|
|
102
|
-
|
|
40
|
+
If you want to bind on all interfaces:
|
|
103
41
|
|
|
104
42
|
```bash
|
|
105
|
-
ds --
|
|
106
|
-
```
|
|
107
|
-
|
|
108
|
-
## Runtime Layout
|
|
109
|
-
|
|
110
|
-
Default runtime data lives under:
|
|
111
|
-
|
|
112
|
-
```text
|
|
113
|
-
~/DeepScientist/
|
|
114
|
-
config/
|
|
115
|
-
memory/
|
|
116
|
-
plugins/
|
|
117
|
-
quests/
|
|
118
|
-
logs/
|
|
119
|
-
cache/
|
|
120
|
-
runtime/
|
|
43
|
+
ds --host 0.0.0.0 --port 21000
|
|
121
44
|
```
|
|
122
45
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
## Documentation
|
|
126
|
-
|
|
127
|
-
### English
|
|
128
|
-
|
|
129
|
-
- [TUI Usage](docs/en/TUI_USAGE.md)
|
|
130
|
-
- [Settings Reference](docs/en/SETTINGS_REFERENCE.md)
|
|
131
|
-
- [Runtime Flow and Canvas](docs/en/RUNTIME_FLOW_AND_CANVAS.md)
|
|
132
|
-
- [Start Research Contract Reference](docs/en/START_RESEARCH_CONTRACT_REFERENCE.md)
|
|
133
|
-
- [QQ Connector Guide](docs/en/QQ_CONNECTOR_GUIDE.md)
|
|
134
|
-
- [MCP Semantics and Memory Protocol](docs/en/MCP_MEMORY_PROTOCOL.md)
|
|
135
|
-
- [Figure Style Guide](docs/en/FIGURE_STYLE_GUIDE.md)
|
|
136
|
-
- [Acknowledgements](docs/en/ACKNOWLEDGEMENTS.md)
|
|
137
|
-
|
|
138
|
-
### Chinese
|
|
139
|
-
|
|
140
|
-
- [TUI 使用说明](docs/zh/TUI_USAGE.md)
|
|
141
|
-
- [设置页参考](docs/zh/SETTINGS_REFERENCE.md)
|
|
142
|
-
- [运行流与 Canvas](docs/zh/RUNTIME_FLOW_AND_CANVAS.md)
|
|
143
|
-
- [Start Research 合同参考](docs/zh/START_RESEARCH_CONTRACT_REFERENCE.md)
|
|
144
|
-
- [QQ Connector 指南](docs/zh/QQ_CONNECTOR_GUIDE.md)
|
|
145
|
-
- [MCP 与 Memory 协议](docs/zh/MCP_MEMORY_PROTOCOL.md)
|
|
146
|
-
- [图表风格指南](docs/zh/FIGURE_STYLE_GUIDE.md)
|
|
147
|
-
- [致谢](docs/zh/ACKNOWLEDGEMENTS.md)
|
|
46
|
+
DeepScientist now uses `uv` to manage a locked local Python runtime. If a conda environment is active and already provides Python `>=3.11`, `ds` prefers it automatically; otherwise it bootstraps a managed `uv` + Python toolchain under `~/DeepScientist/runtime/`.
|
|
148
47
|
|
|
149
|
-
|
|
48
|
+
The default DeepScientist home is:
|
|
150
49
|
|
|
151
|
-
|
|
50
|
+
- macOS / Linux: `~/DeepScientist`
|
|
51
|
+
- Windows: `%USERPROFILE%\\DeepScientist`
|
|
152
52
|
|
|
153
|
-
|
|
154
|
-
- `assets/`
|
|
155
|
-
- `docs/`
|
|
156
|
-
- `src/deepscientist/`
|
|
157
|
-
- `src/prompts/`
|
|
158
|
-
- `src/skills/`
|
|
159
|
-
- `src/ui/`
|
|
160
|
-
- `src/tui/`
|
|
161
|
-
- `tests/`
|
|
53
|
+
Use `ds --home <path>` if you want to place the runtime somewhere else.
|
|
162
54
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
- launcher: `bin/ds.js`
|
|
166
|
-
- Python CLI: `src/deepscientist/cli.py`
|
|
167
|
-
- daemon: `src/deepscientist/daemon/app.py`
|
|
168
|
-
- MCP server: `src/deepscientist/mcp/server.py`
|
|
169
|
-
- prompt builder: `src/deepscientist/prompts/builder.py`
|
|
170
|
-
- system prompt: `src/prompts/system.md`
|
|
171
|
-
|
|
172
|
-
## Development
|
|
173
|
-
|
|
174
|
-
Install UI dependencies and build the web bundle:
|
|
55
|
+
## Troubleshooting
|
|
175
56
|
|
|
176
57
|
```bash
|
|
177
|
-
|
|
178
|
-
npm --prefix src/ui run build
|
|
58
|
+
ds doctor
|
|
179
59
|
```
|
|
180
60
|
|
|
181
|
-
|
|
61
|
+
`ds docker` is also accepted as a compatibility alias, but `ds doctor` is the documented command.
|
|
62
|
+
|
|
63
|
+
## Local PDF Compile
|
|
182
64
|
|
|
183
65
|
```bash
|
|
184
|
-
|
|
185
|
-
npm --prefix src/tui run build
|
|
66
|
+
ds latex install-runtime
|
|
186
67
|
```
|
|
187
68
|
|
|
188
|
-
|
|
69
|
+
This installs a lightweight TinyTeX `pdflatex` runtime for local paper compilation.
|
|
189
70
|
|
|
190
|
-
|
|
191
|
-
pytest
|
|
192
|
-
```
|
|
71
|
+
## QQ Connector
|
|
193
72
|
|
|
194
|
-
|
|
73
|
+
- [Quick Start (English)](docs/en/00_QUICK_START.md)
|
|
74
|
+
- [快速开始(中文)](docs/zh/00_QUICK_START.md)
|
|
75
|
+
- [QQ Connector Guide (English)](docs/en/03_QQ_CONNECTOR_GUIDE.md)
|
|
76
|
+
- [QQ Connector Guide (中文)](docs/zh/03_QQ_CONNECTOR_GUIDE.md)
|
|
195
77
|
|
|
196
|
-
|
|
197
|
-
npm pack --dry-run
|
|
198
|
-
```
|
|
78
|
+
## Maintainers
|
|
199
79
|
|
|
200
|
-
|
|
80
|
+
- [Architecture](docs/en/90_ARCHITECTURE.md)
|
|
81
|
+
- [Development Guide](docs/en/91_DEVELOPMENT.md)
|
|
201
82
|
|
|
202
|
-
|
|
83
|
+
## Citation
|
|
203
84
|
|
|
204
|
-
|
|
205
|
-
- `dist/` build output
|
|
206
|
-
- `__pycache__/`
|
|
207
|
-
- `.pytest_cache/`
|
|
208
|
-
- `.turbo/`
|
|
209
|
-
- local absolute workstation paths in docs or repo guidance
|
|
85
|
+
This project is currently contributed by Yixuan Weng, Shichen Li, Weixu Zhao, Minjun Zhu. If you find our work valuable, please cite:
|
|
210
86
|
|
|
211
|
-
|
|
212
|
-
|
|
87
|
+
本项目当前由 Yixuan Weng、Shichen Li、Weixu Zhao、Minjun Zhu 共同贡献。如果你觉得我们的工作有价值,请引用:
|
|
88
|
+
|
|
89
|
+
```bibtex
|
|
90
|
+
@inproceedings{
|
|
91
|
+
weng2026deepscientist,
|
|
92
|
+
title={DeepScientist: Advancing Frontier-Pushing Scientific Findings Progressively},
|
|
93
|
+
author={Yixuan Weng and Minjun Zhu and Qiujie Xie and QiYao Sun and Zhen Lin and Sifan Liu and Yue Zhang},
|
|
94
|
+
booktitle={The Fourteenth International Conference on Learning Representations},
|
|
95
|
+
year={2026},
|
|
96
|
+
url={https://openreview.net/forum?id=cZFgsLq8Gs}
|
|
97
|
+
}
|
|
98
|
+
```
|
|
213
99
|
|
|
214
100
|
## License
|
|
215
101
|
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
# OpenClaw Lingzhu
|
|
2
|
+
|
|
3
|
+
面向 Rokid/乐奇眼镜场景的 `Lingzhu <-> OpenClaw` 桥接插件。
|
|
4
|
+
|
|
5
|
+
本目录已随 DeepScientist 一起打包,可直接从当前仓库安装。
|
|
6
|
+
|
|
7
|
+
## 安装
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
# 在 DeepScientist 仓库根目录下安装
|
|
11
|
+
openclaw plugins install ./assets/connectors/lingzhu/openclaw-bridge
|
|
12
|
+
|
|
13
|
+
# 或以开发模式链接安装
|
|
14
|
+
openclaw plugins install --link ./assets/connectors/lingzhu/openclaw-bridge
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## 配置
|
|
18
|
+
|
|
19
|
+
在 `openclaw.json` 或 `moltbot.json` 中加入:
|
|
20
|
+
|
|
21
|
+
```json5
|
|
22
|
+
{
|
|
23
|
+
"gateway": {
|
|
24
|
+
"http": {
|
|
25
|
+
"endpoints": {
|
|
26
|
+
"chatCompletions": {
|
|
27
|
+
"enabled": true
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
"plugins": {
|
|
33
|
+
"entries": {
|
|
34
|
+
"lingzhu": {
|
|
35
|
+
"enabled": true,
|
|
36
|
+
"config": {
|
|
37
|
+
"authAk": "",
|
|
38
|
+
"agentId": "main",
|
|
39
|
+
"includeMetadata": true,
|
|
40
|
+
"requestTimeoutMs": 60000,
|
|
41
|
+
"sessionMode": "per_user",
|
|
42
|
+
"sessionNamespace": "lingzhu",
|
|
43
|
+
"defaultNavigationMode": "0",
|
|
44
|
+
"enableFollowUp": true,
|
|
45
|
+
"followUpMaxCount": 3,
|
|
46
|
+
"maxImageBytes": 5242880,
|
|
47
|
+
"systemPrompt": "你是部署在 Rokid 眼镜上的智能助手。",
|
|
48
|
+
"autoReceiptAck": true,
|
|
49
|
+
"visibleProgressHeartbeat": true,
|
|
50
|
+
"visibleProgressHeartbeatSec": 10,
|
|
51
|
+
"debugLogging": true,
|
|
52
|
+
"debugLogPayloads": false,
|
|
53
|
+
"debugLogDir": "",
|
|
54
|
+
"enableExperimentalNativeActions": true
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## CLI
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
openclaw lingzhu info
|
|
66
|
+
openclaw lingzhu status
|
|
67
|
+
openclaw lingzhu curl
|
|
68
|
+
openclaw lingzhu capabilities
|
|
69
|
+
openclaw lingzhu logpath
|
|
70
|
+
openclaw lingzhu doctor
|
|
71
|
+
openclaw lingzhu cache-cleanup
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## 健康检查
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
curl http://127.0.0.1:18789/metis/agent/api/health
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## 调试日志
|
|
81
|
+
|
|
82
|
+
启用 `debugLogging` 后,桥接日志默认写入插件目录下的 `logs/`:
|
|
83
|
+
|
|
84
|
+
- `logs/lingzhu-YYYY-MM-DD.log`
|
|
85
|
+
|
|
86
|
+
联调时建议先这样配置:
|
|
87
|
+
|
|
88
|
+
- `debugLogging: true`
|
|
89
|
+
- `debugLogPayloads: false`
|
|
90
|
+
|
|
91
|
+
只有在需要精确排查协议载荷时,再临时改为:
|
|
92
|
+
|
|
93
|
+
- `debugLogPayloads: true`
|
|
94
|
+
|
|
95
|
+
## 长时间兼容策略
|
|
96
|
+
|
|
97
|
+
这份 bridge 默认采用更稳妥的 Lingzhu 兼容策略:
|
|
98
|
+
|
|
99
|
+
- `autoReceiptAck: true`
|
|
100
|
+
- 请求进入后立即发一条可见回执,避免眼镜端等待模型首 token 时像“没收到”
|
|
101
|
+
- `visibleProgressHeartbeat: true`
|
|
102
|
+
- 长时间无正文输出时,补发轻量可见进度帧,而不仅仅是 SSE 注释心跳
|
|
103
|
+
- `visibleProgressHeartbeatSec: 10`
|
|
104
|
+
- 控制可见进度帧最短间隔,避免过于频繁刷屏
|
|
105
|
+
|
|
106
|
+
这会明显改善实际体验,但仍不能消除灵珠平台单次 SSE 请求的时长限制。
|
|
107
|
+
|
|
108
|
+
## 实验性原生动作
|
|
109
|
+
|
|
110
|
+
启用 `enableExperimentalNativeActions` 后,会额外向模型暴露这些实验动作:
|
|
111
|
+
|
|
112
|
+
- `send_notification`
|
|
113
|
+
- `send_toast`
|
|
114
|
+
- `speak_tts`
|
|
115
|
+
- `start_video_record`
|
|
116
|
+
- `stop_video_record`
|
|
117
|
+
- `open_custom_view`
|
|
118
|
+
|
|
119
|
+
这些动作是否被灵珠平台或眼镜端真实识别,仍需真机联调验证。
|
|
120
|
+
|
|
121
|
+
## 额外工具
|
|
122
|
+
|
|
123
|
+
- `openclaw lingzhu doctor`: 输出当前桥接自检结果,适合部署后快速核对配置。
|
|
124
|
+
- `openclaw lingzhu cache-cleanup`: 清理 24 小时前的图片缓存,避免联调过程中缓存目录持续膨胀。
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
import { lingzhuConfigSchema, resolveLingzhuConfig, generateAuthAk } from "./src/config.js";
|
|
5
|
+
import { createHttpHandler } from "./src/http-handler.js";
|
|
6
|
+
import { registerLingzhuCli } from "./src/cli.js";
|
|
7
|
+
import { createLingzhuTools } from "./src/lingzhu-tools.js";
|
|
8
|
+
import type { LingzhuConfig } from "./src/types.js";
|
|
9
|
+
|
|
10
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
11
|
+
const AK_FILE = path.join(__dirname, "../.lingzhu.ak"); // 存储在插件根目录
|
|
12
|
+
|
|
13
|
+
// 插件状态
|
|
14
|
+
let pluginConfig: LingzhuConfig = {};
|
|
15
|
+
let activeAuthAk = "";
|
|
16
|
+
let gatewayPort = 18789;
|
|
17
|
+
|
|
18
|
+
function maskSecret(secret: string): string {
|
|
19
|
+
if (!secret) {
|
|
20
|
+
return "(empty)";
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
if (secret.length <= 8) {
|
|
24
|
+
return "*".repeat(secret.length);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return `${secret.slice(0, 4)}${"*".repeat(secret.length - 8)}${secret.slice(-4)}`;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* 灵珠平台接入插件
|
|
32
|
+
*/
|
|
33
|
+
const lingzhuPlugin = {
|
|
34
|
+
id: "lingzhu",
|
|
35
|
+
name: "Lingzhu Bridge",
|
|
36
|
+
description: "灵珠平台 <-> OpenClaw 协议转换桥梁",
|
|
37
|
+
configSchema: lingzhuConfigSchema,
|
|
38
|
+
|
|
39
|
+
register(api: any) {
|
|
40
|
+
const logger = api.logger;
|
|
41
|
+
|
|
42
|
+
// 获取并解析配置
|
|
43
|
+
const rawConfig = api.config?.plugins?.entries?.lingzhu?.config;
|
|
44
|
+
pluginConfig = resolveLingzhuConfig(rawConfig);
|
|
45
|
+
// 生成或使用已有 AK
|
|
46
|
+
if (pluginConfig.authAk) {
|
|
47
|
+
activeAuthAk = pluginConfig.authAk;
|
|
48
|
+
} else {
|
|
49
|
+
// 尝试从本地文件读取
|
|
50
|
+
if (fs.existsSync(AK_FILE)) {
|
|
51
|
+
try {
|
|
52
|
+
activeAuthAk = fs.readFileSync(AK_FILE, "utf-8").trim();
|
|
53
|
+
logger.info("[Lingzhu] 已从本地记录加载 AK");
|
|
54
|
+
} catch (e) {
|
|
55
|
+
logger.warn(`[Lingzhu] 读取本地 AK 文件失败: ${e}`);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// 如果还是没有,则生成并保存
|
|
60
|
+
if (!activeAuthAk) {
|
|
61
|
+
activeAuthAk = generateAuthAk();
|
|
62
|
+
try {
|
|
63
|
+
fs.writeFileSync(AK_FILE, activeAuthAk, "utf-8");
|
|
64
|
+
logger.info("[Lingzhu] 已自动生成并持久化 AK");
|
|
65
|
+
} catch (e) {
|
|
66
|
+
logger.warn(`[Lingzhu] 持久化 AK 文件失败: ${e}`);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// 获取 Gateway 端口
|
|
72
|
+
gatewayPort = api.config?.gateway?.port ?? 18789;
|
|
73
|
+
|
|
74
|
+
// 配置/状态获取函数
|
|
75
|
+
const getConfig = () => pluginConfig;
|
|
76
|
+
const getRuntimeState = () => ({
|
|
77
|
+
config: pluginConfig,
|
|
78
|
+
authAk: activeAuthAk,
|
|
79
|
+
gatewayPort,
|
|
80
|
+
chatCompletionsEnabled: api.config?.gateway?.http?.endpoints?.chatCompletions?.enabled === true,
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
// 1. 注册 HTTP 路由
|
|
84
|
+
if (typeof api.registerHttpRoute === "function") {
|
|
85
|
+
const httpHandler = createHttpHandler(api, getRuntimeState);
|
|
86
|
+
api.registerHttpRoute({
|
|
87
|
+
path: "/metis/agent/api/sse",
|
|
88
|
+
handler: httpHandler,
|
|
89
|
+
auth: "plugin" as const,
|
|
90
|
+
match: "exact" as const,
|
|
91
|
+
});
|
|
92
|
+
api.registerHttpRoute({
|
|
93
|
+
path: "/metis/agent/api/health",
|
|
94
|
+
handler: httpHandler,
|
|
95
|
+
auth: "plugin" as const,
|
|
96
|
+
match: "exact" as const,
|
|
97
|
+
});
|
|
98
|
+
logger.info("[Lingzhu] 已注册 HTTP 路由: /metis/agent/api/sse, /metis/agent/api/health");
|
|
99
|
+
} else if (typeof api.registerHttpHandler === "function") {
|
|
100
|
+
api.registerHttpHandler(createHttpHandler(api, getRuntimeState));
|
|
101
|
+
logger.info("[Lingzhu] 已注册 HTTP 端点: POST /metis/agent/api/sse");
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// 2. 注册灵珠设备工具
|
|
105
|
+
logger.info(`[Lingzhu] 检查 registerTool API: ${typeof api.registerTool}`);
|
|
106
|
+
if (pluginConfig.enabled === false) {
|
|
107
|
+
logger.info("[Lingzhu] 插件已禁用,跳过设备工具注册");
|
|
108
|
+
} else if (typeof api.registerTool === "function") {
|
|
109
|
+
const tools = createLingzhuTools(pluginConfig.enableExperimentalNativeActions === true);
|
|
110
|
+
logger.info(`[Lingzhu] 准备注册 ${tools.length} 个工具`);
|
|
111
|
+
for (const tool of tools) {
|
|
112
|
+
try {
|
|
113
|
+
api.registerTool(tool, { optional: false });
|
|
114
|
+
logger.info(`[Lingzhu] 已注册工具: ${tool.name}`);
|
|
115
|
+
} catch (e) {
|
|
116
|
+
logger.error(`[Lingzhu] 注册工具失败: ${tool.name}, 错误: ${e}`);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
} else {
|
|
120
|
+
logger.warn("[Lingzhu] registerTool API 不可用,无法注册设备工具");
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// 3. 注册 CLI 命令
|
|
124
|
+
if (typeof api.registerCli === "function") {
|
|
125
|
+
api.registerCli(
|
|
126
|
+
(ctx: any) => registerLingzhuCli(ctx, getRuntimeState),
|
|
127
|
+
{ commands: ["lingzhu"] }
|
|
128
|
+
);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// 4. 注册后台服务
|
|
132
|
+
if (typeof api.registerService === "function") {
|
|
133
|
+
api.registerService({
|
|
134
|
+
id: "lingzhu-bridge",
|
|
135
|
+
start: () => {
|
|
136
|
+
if (pluginConfig.enabled === false) {
|
|
137
|
+
logger.info("[Lingzhu] 插件已禁用");
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
const url = `http://127.0.0.1:${gatewayPort}/metis/agent/api/sse`;
|
|
142
|
+
|
|
143
|
+
console.log("");
|
|
144
|
+
console.log("╔═══════════════════════════════════════════════════════════════════════╗");
|
|
145
|
+
console.log("║ Lingzhu Bridge 已启动 ║");
|
|
146
|
+
console.log("╠═══════════════════════════════════════════════════════════════════════╣");
|
|
147
|
+
console.log(`║ SSE 接口: ${url.padEnd(56)}║`);
|
|
148
|
+
console.log(`║ 鉴权 AK: ${maskSecret(activeAuthAk).padEnd(56)}║`);
|
|
149
|
+
console.log("╚═══════════════════════════════════════════════════════════════════════╝");
|
|
150
|
+
console.log("");
|
|
151
|
+
|
|
152
|
+
logger.info(`[Lingzhu] Bridge 已启动,端点: ${url}`);
|
|
153
|
+
},
|
|
154
|
+
stop: () => {
|
|
155
|
+
logger.info("[Lingzhu] Bridge 已停止");
|
|
156
|
+
},
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
},
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
export default lingzhuPlugin;
|