@researai/deepscientist 1.5.0 → 1.5.1

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.
Files changed (163) hide show
  1. package/AGENTS.md +26 -0
  2. package/README.md +19 -179
  3. package/assets/connectors/lingzhu/openclaw-bridge/README.md +124 -0
  4. package/assets/connectors/lingzhu/openclaw-bridge/index.ts +162 -0
  5. package/assets/connectors/lingzhu/openclaw-bridge/openclaw.plugin.json +145 -0
  6. package/assets/connectors/lingzhu/openclaw-bridge/package.json +35 -0
  7. package/assets/connectors/lingzhu/openclaw-bridge/src/cli.ts +180 -0
  8. package/assets/connectors/lingzhu/openclaw-bridge/src/config.ts +196 -0
  9. package/assets/connectors/lingzhu/openclaw-bridge/src/debug-log.ts +111 -0
  10. package/assets/connectors/lingzhu/openclaw-bridge/src/events.ts +4 -0
  11. package/assets/connectors/lingzhu/openclaw-bridge/src/http-handler.ts +1133 -0
  12. package/assets/connectors/lingzhu/openclaw-bridge/src/image-cache.ts +75 -0
  13. package/assets/connectors/lingzhu/openclaw-bridge/src/lingzhu-tools.ts +246 -0
  14. package/assets/connectors/lingzhu/openclaw-bridge/src/transform.ts +541 -0
  15. package/assets/connectors/lingzhu/openclaw-bridge/src/types.ts +131 -0
  16. package/assets/connectors/lingzhu/openclaw-bridge/tsconfig.json +14 -0
  17. package/assets/connectors/lingzhu/openclaw.lingzhu.config.template.json +39 -0
  18. package/bin/ds.js +233 -53
  19. package/docs/en/00_QUICK_START.md +134 -0
  20. package/docs/en/01_SETTINGS_REFERENCE.md +1104 -0
  21. package/docs/en/02_START_RESEARCH_GUIDE.md +404 -0
  22. package/docs/en/03_QQ_CONNECTOR_GUIDE.md +325 -0
  23. package/docs/en/04_LINGZHU_CONNECTOR_GUIDE.md +216 -0
  24. package/docs/en/05_TUI_GUIDE.md +141 -0
  25. package/docs/en/06_RUNTIME_AND_CANVAS.md +679 -0
  26. package/docs/en/07_MEMORY_AND_MCP.md +253 -0
  27. package/docs/en/08_FIGURE_STYLE_GUIDE.md +97 -0
  28. package/docs/en/09_DOCTOR.md +108 -0
  29. package/docs/en/90_ARCHITECTURE.md +245 -0
  30. package/docs/en/91_DEVELOPMENT.md +195 -0
  31. package/docs/en/99_ACKNOWLEDGEMENTS.md +29 -0
  32. package/docs/zh/00_QUICK_START.md +134 -0
  33. package/docs/zh/01_SETTINGS_REFERENCE.md +1137 -0
  34. package/docs/zh/02_START_RESEARCH_GUIDE.md +414 -0
  35. package/docs/zh/03_QQ_CONNECTOR_GUIDE.md +324 -0
  36. package/docs/zh/04_LINGZHU_CONNECTOR_GUIDE.md +230 -0
  37. package/docs/zh/05_TUI_GUIDE.md +128 -0
  38. package/docs/zh/06_RUNTIME_AND_CANVAS.md +271 -0
  39. package/docs/zh/07_MEMORY_AND_MCP.md +235 -0
  40. package/docs/zh/08_FIGURE_STYLE_GUIDE.md +97 -0
  41. package/docs/zh/09_DOCTOR.md +112 -0
  42. package/docs/zh/99_ACKNOWLEDGEMENTS.md +29 -0
  43. package/install.sh +32 -8
  44. package/package.json +4 -2
  45. package/pyproject.toml +1 -1
  46. package/src/deepscientist/artifact/guidance.py +9 -2
  47. package/src/deepscientist/artifact/service.py +482 -22
  48. package/src/deepscientist/bash_exec/monitor.py +27 -5
  49. package/src/deepscientist/bash_exec/runtime.py +639 -0
  50. package/src/deepscientist/bash_exec/service.py +99 -16
  51. package/src/deepscientist/bridges/base.py +3 -0
  52. package/src/deepscientist/bridges/connectors.py +292 -13
  53. package/src/deepscientist/channels/qq.py +19 -2
  54. package/src/deepscientist/channels/relay.py +1 -0
  55. package/src/deepscientist/cli.py +32 -25
  56. package/src/deepscientist/config/models.py +28 -2
  57. package/src/deepscientist/config/service.py +201 -6
  58. package/src/deepscientist/connector_runtime.py +2 -0
  59. package/src/deepscientist/daemon/api/handlers.py +50 -5
  60. package/src/deepscientist/daemon/api/router.py +1 -0
  61. package/src/deepscientist/daemon/app.py +442 -15
  62. package/src/deepscientist/doctor.py +444 -0
  63. package/src/deepscientist/home.py +1 -0
  64. package/src/deepscientist/latex_runtime.py +17 -4
  65. package/src/deepscientist/lingzhu_support.py +182 -0
  66. package/src/deepscientist/mcp/server.py +49 -2
  67. package/src/deepscientist/prompts/builder.py +181 -58
  68. package/src/deepscientist/quest/layout.py +1 -0
  69. package/src/deepscientist/quest/service.py +63 -2
  70. package/src/deepscientist/quest/stage_views.py +19 -1
  71. package/src/deepscientist/runtime_tools/__init__.py +16 -0
  72. package/src/deepscientist/runtime_tools/builtins.py +19 -0
  73. package/src/deepscientist/runtime_tools/models.py +29 -0
  74. package/src/deepscientist/runtime_tools/registry.py +40 -0
  75. package/src/deepscientist/runtime_tools/service.py +59 -0
  76. package/src/deepscientist/runtime_tools/tinytex.py +25 -0
  77. package/src/deepscientist/tinytex.py +276 -0
  78. package/src/prompts/connectors/lingzhu.md +12 -0
  79. package/src/prompts/connectors/qq.md +121 -0
  80. package/src/prompts/system.md +177 -33
  81. package/src/skills/analysis-campaign/SKILL.md +22 -6
  82. package/src/skills/baseline/SKILL.md +5 -4
  83. package/src/skills/decision/SKILL.md +4 -3
  84. package/src/skills/experiment/SKILL.md +5 -4
  85. package/src/skills/finalize/SKILL.md +5 -4
  86. package/src/skills/idea/SKILL.md +5 -4
  87. package/src/skills/intake-audit/SKILL.md +277 -0
  88. package/src/skills/intake-audit/references/state-audit-template.md +41 -0
  89. package/src/skills/rebuttal/SKILL.md +407 -0
  90. package/src/skills/rebuttal/references/action-plan-template.md +63 -0
  91. package/src/skills/rebuttal/references/evidence-update-template.md +30 -0
  92. package/src/skills/rebuttal/references/response-letter-template.md +113 -0
  93. package/src/skills/rebuttal/references/review-matrix-template.md +55 -0
  94. package/src/skills/review/SKILL.md +293 -0
  95. package/src/skills/review/references/experiment-todo-template.md +29 -0
  96. package/src/skills/review/references/review-report-template.md +83 -0
  97. package/src/skills/review/references/revision-log-template.md +40 -0
  98. package/src/skills/scout/SKILL.md +5 -4
  99. package/src/skills/write/SKILL.md +7 -3
  100. package/src/tui/dist/components/WelcomePanel.js +17 -43
  101. package/src/tui/dist/components/messages/BashExecOperationMessage.js +3 -2
  102. package/src/tui/package.json +1 -1
  103. package/src/ui/dist/assets/{AiManusChatView-7v-dHngU.js → AiManusChatView-w5lF2Ttt.js} +109 -575
  104. package/src/ui/dist/assets/{AnalysisPlugin-B_Xmz-KE.js → AnalysisPlugin-DJOED79I.js} +1 -1
  105. package/src/ui/dist/assets/{AutoFigurePlugin-Cko-0tm1.js → AutoFigurePlugin-DaG61Y0M.js} +63 -8
  106. package/src/ui/dist/assets/{CliPlugin-BsU0ht7q.js → CliPlugin-CV4LqUB_.js} +43 -609
  107. package/src/ui/dist/assets/{CodeEditorPlugin-DcMMP0Rt.js → CodeEditorPlugin-DylfAea4.js} +8 -8
  108. package/src/ui/dist/assets/{CodeViewerPlugin-BqoQ5QyY.js → CodeViewerPlugin-F7saY0LM.js} +5 -5
  109. package/src/ui/dist/assets/{DocViewerPlugin-D7eHNhU6.js → DocViewerPlugin-COP0c7jf.js} +3 -3
  110. package/src/ui/dist/assets/{GitDiffViewerPlugin-DLJN42T5.js → GitDiffViewerPlugin-CAS05pT9.js} +1 -1
  111. package/src/ui/dist/assets/{ImageViewerPlugin-gJMV7MOu.js → ImageViewerPlugin-Bco1CN_w.js} +5 -6
  112. package/src/ui/dist/assets/{LabCopilotPanel-B857sfxP.js → LabCopilotPanel-CvMlCD99.js} +12 -15
  113. package/src/ui/dist/assets/LabPlugin-BYankkE4.js +2676 -0
  114. package/src/ui/dist/assets/LabPlugin-D9jVIo0A.css +2698 -0
  115. package/src/ui/dist/assets/{LatexPlugin-DWKEo-Wj.js → LatexPlugin-LDSMR-t-.js} +16 -16
  116. package/src/ui/dist/assets/{MarkdownViewerPlugin-DBzoEmhv.js → MarkdownViewerPlugin-B7o80jgm.js} +4 -4
  117. package/src/ui/dist/assets/{MarketplacePlugin-DoHc-8vo.js → MarketplacePlugin-CM6ZOcpC.js} +3 -3
  118. package/src/ui/dist/assets/{NotebookEditor-CKjKH-yS.js → NotebookEditor-Dc61cXmK.js} +3 -3
  119. package/src/ui/dist/assets/{PdfLoader-zFoL0VPo.js → PdfLoader-DWowuQwx.js} +1 -1
  120. package/src/ui/dist/assets/{PdfMarkdownPlugin-DXPaL9Nt.js → PdfMarkdownPlugin-BsJM1q_a.js} +3 -3
  121. package/src/ui/dist/assets/{PdfViewerPlugin-DhK8qCFp.js → PdfViewerPlugin-DB2eEEFQ.js} +10 -10
  122. package/src/ui/dist/assets/{SearchPlugin-CdSi6krf.js → SearchPlugin-CraThSvt.js} +1 -1
  123. package/src/ui/dist/assets/{Stepper-V-WiDQJl.js → Stepper-CgocRTPq.js} +1 -1
  124. package/src/ui/dist/assets/{TextViewerPlugin-hIs1Efiu.js → TextViewerPlugin-B1JGhKtd.js} +4 -4
  125. package/src/ui/dist/assets/{VNCViewer-DG8b0q2X.js → VNCViewer-CclFC7FM.js} +9 -10
  126. package/src/ui/dist/assets/{bibtex-HDac6fVW.js → bibtex-D3IKsMl7.js} +1 -1
  127. package/src/ui/dist/assets/{code-BnBeNxBc.js → code-BP37Xx0p.js} +1 -1
  128. package/src/ui/dist/assets/{file-content-IRQ3jHb8.js → file-content-BAJSu-9r.js} +1 -1
  129. package/src/ui/dist/assets/{file-diff-panel-DZoQ9I6r.js → file-diff-panel-DUGeCTuy.js} +1 -1
  130. package/src/ui/dist/assets/{file-socket-BMCdLc-P.js → file-socket-CXc1Ojf7.js} +1 -1
  131. package/src/ui/dist/assets/{file-utils-CltILB3w.js → file-utils-2J21jt7M.js} +1 -1
  132. package/src/ui/dist/assets/{image-Boe6ffhu.js → image-CMMmgvcn.js} +1 -1
  133. package/src/ui/dist/assets/{index-BlplpvE1.js → index-BaVumsQT.js} +2 -2
  134. package/src/ui/dist/assets/{index-DZqJ-qAM.js → index-CWgMgpow.js} +60 -2154
  135. package/src/ui/dist/assets/{index-DO43pFZP.js → index-DmwmJmbW.js} +6372 -8434
  136. package/src/ui/dist/assets/{index-Bq2bvfkl.css → index-KGt-z-dD.css} +225 -2920
  137. package/src/ui/dist/assets/{index-2Zf65FZt.js → index-s7aHnNQ4.js} +1 -1
  138. package/src/ui/dist/assets/{message-square-mUHn_Ssb.js → message-square-CQRfX0Am.js} +1 -1
  139. package/src/ui/dist/assets/{monaco-fe0arNEU.js → monaco-B4TbdsrF.js} +1 -1
  140. package/src/ui/dist/assets/{popover-D_7i19qU.js → popover-B8Rokodk.js} +1 -1
  141. package/src/ui/dist/assets/{project-sync-DyVGrU7H.js → project-sync-D_i96KH4.js} +2 -8
  142. package/src/ui/dist/assets/{sigma-BzazRyxQ.js → sigma-D12PnzCN.js} +1 -1
  143. package/src/ui/dist/assets/{tooltip-DN_yjHFH.js → tooltip-B6YrI4aJ.js} +1 -1
  144. package/src/ui/dist/assets/trash-Bc8jGp0V.js +32 -0
  145. package/src/ui/dist/assets/{useCliAccess-DV2L2Qxy.js → useCliAccess-mXVCYSZ-.js} +12 -42
  146. package/src/ui/dist/assets/{useFileDiffOverlay-DyTj-p_V.js → useFileDiffOverlay-Bg6b9H9K.js} +1 -1
  147. package/src/ui/dist/assets/{wrap-text-ozYHtUwq.js → wrap-text-Drh5GEnL.js} +1 -1
  148. package/src/ui/dist/assets/{zoom-out-BN9MUyCQ.js → zoom-out-CJj9DZLn.js} +1 -1
  149. package/src/ui/dist/index.html +2 -2
  150. package/assets/fonts/Inter-Variable.ttf +0 -0
  151. package/assets/fonts/NotoSerifSC-Regular-C94HN_ZN.ttf +0 -0
  152. package/assets/fonts/NunitoSans-Variable.ttf +0 -0
  153. package/assets/fonts/Satoshi-Medium-ByP-Zb-9.woff2 +0 -0
  154. package/assets/fonts/SourceSans3-Variable.ttf +0 -0
  155. package/assets/fonts/ds-fonts.css +0 -83
  156. package/src/ui/dist/assets/Inter-Variable-VF2RPR_K.ttf +0 -0
  157. package/src/ui/dist/assets/LabPlugin-bL7rpic8.js +0 -43
  158. package/src/ui/dist/assets/NotoSerifSC-Regular-C94HN_ZN-C94HN_ZN.ttf +0 -0
  159. package/src/ui/dist/assets/NunitoSans-Variable-B_ZymHAd.ttf +0 -0
  160. package/src/ui/dist/assets/Satoshi-Medium-ByP-Zb-9-GkA34YXu.woff2 +0 -0
  161. package/src/ui/dist/assets/SourceSans3-Variable-CD-WOsSK.ttf +0 -0
  162. package/src/ui/dist/assets/info-CcsK_htA.js +0 -18
  163. 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,50 @@
6
6
 
7
7
  <p align="center">
8
8
  Local-first research operating system with a Python runtime, an npm launcher,
9
- one-quest-one-repository state, and shared web plus TUI control surfaces.
9
+ one quest per Git repository, and shared web plus TUI surfaces.
10
10
  </p>
11
11
 
12
- <p align="center">
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:
26
-
27
- - one quest = one Git repository
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:
12
+ ## Install
42
13
 
43
14
  ```bash
44
- npm install -g @researai/deepscientist
15
+ npm install -g @openai/codex @researai/deepscientist
45
16
  ```
46
17
 
47
- Then start DeepScientist:
18
+ ## Start
48
19
 
49
20
  ```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:
73
-
74
- ```bash
75
- bash install.sh
76
21
  ds
77
22
  ```
78
23
 
79
- ## Requirements
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
86
-
87
- Optional:
88
-
89
- - a local LaTeX toolchain is only needed when you want to compile paper PDFs locally
90
-
91
- ## Quick Start
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:
97
-
98
- ```bash
99
- ds new "reproduce the baseline and test one stronger idea"
100
- ```
101
-
102
- 5. Stop the local runtime when needed:
103
-
104
- ```bash
105
- ds --stop
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/
121
- ```
122
-
123
- Every quest is stored under `~/DeepScientist/quests/<quest_id>/` and remains a standalone Git repository.
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
24
+ DeepScientist starts the local web workspace at `http://127.0.0.1:20999` by default.
139
25
 
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)
148
-
149
- ## Repository Layout
150
-
151
- Main code and assets live here:
152
-
153
- - `bin/`
154
- - `assets/`
155
- - `docs/`
156
- - `src/deepscientist/`
157
- - `src/prompts/`
158
- - `src/skills/`
159
- - `src/ui/`
160
- - `src/tui/`
161
- - `tests/`
162
-
163
- Important entry points:
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:
26
+ ## Troubleshooting
175
27
 
176
28
  ```bash
177
- npm --prefix src/ui install
178
- npm --prefix src/ui run build
29
+ ds doctor
179
30
  ```
180
31
 
181
- Build the TUI bundle:
32
+ `ds docker` is also accepted as a compatibility alias, but `ds doctor` is the documented command.
182
33
 
183
- ```bash
184
- npm --prefix src/tui install
185
- npm --prefix src/tui run build
186
- ```
187
-
188
- Run tests:
34
+ ## Local PDF Compile
189
35
 
190
36
  ```bash
191
- pytest
37
+ ds latex install-runtime
192
38
  ```
193
39
 
194
- Verify npm packaging before publishing:
195
-
196
- ```bash
197
- npm pack --dry-run
198
- ```
40
+ This installs a lightweight TinyTeX `pdflatex` runtime for local paper compilation.
199
41
 
200
- ## Open-Source Hygiene
42
+ ## QQ Connector
201
43
 
202
- This repository should not commit local machine artifacts such as:
44
+ - [Quick Start (English)](docs/en/00_QUICK_START.md)
45
+ - [快速开始(中文)](docs/zh/00_QUICK_START.md)
46
+ - [QQ Connector Guide (English)](docs/en/03_QQ_CONNECTOR_GUIDE.md)
47
+ - [QQ Connector Guide (中文)](docs/zh/03_QQ_CONNECTOR_GUIDE.md)
203
48
 
204
- - `node_modules/`
205
- - `dist/` build output
206
- - `__pycache__/`
207
- - `.pytest_cache/`
208
- - `.turbo/`
209
- - local absolute workstation paths in docs or repo guidance
49
+ ## Maintainers
210
50
 
211
- User-facing documentation belongs in `docs/en/` and `docs/zh/`.
212
- Internal planning notes and temporary implementation checklists should not be kept there.
51
+ - [Architecture](docs/en/90_ARCHITECTURE.md)
52
+ - [Development Guide](docs/en/91_DEVELOPMENT.md)
213
53
 
214
54
  ## License
215
55
 
@@ -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;