@researai/deepscientist 1.5.7 → 1.5.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -0
- package/bin/ds.js +220 -5
- package/docs/en/07_MEMORY_AND_MCP.md +40 -3
- package/docs/en/99_ACKNOWLEDGEMENTS.md +1 -0
- package/docs/zh/07_MEMORY_AND_MCP.md +40 -3
- package/docs/zh/99_ACKNOWLEDGEMENTS.md +1 -0
- package/install.sh +34 -0
- package/package.json +1 -1
- package/pyproject.toml +1 -1
- package/src/deepscientist/__init__.py +1 -1
- package/src/deepscientist/acp/envelope.py +1 -0
- package/src/deepscientist/artifact/metrics.py +813 -80
- package/src/deepscientist/artifact/schemas.py +1 -0
- package/src/deepscientist/artifact/service.py +1101 -99
- package/src/deepscientist/bash_exec/monitor.py +1 -1
- package/src/deepscientist/bash_exec/service.py +17 -9
- package/src/deepscientist/channels/qq.py +17 -0
- package/src/deepscientist/channels/relay.py +16 -0
- package/src/deepscientist/config/models.py +6 -0
- package/src/deepscientist/config/service.py +70 -2
- package/src/deepscientist/daemon/api/handlers.py +284 -14
- package/src/deepscientist/daemon/api/router.py +1 -0
- package/src/deepscientist/daemon/app.py +291 -20
- package/src/deepscientist/gitops/diff.py +6 -10
- package/src/deepscientist/mcp/server.py +188 -39
- package/src/deepscientist/prompts/builder.py +51 -18
- package/src/deepscientist/quest/service.py +83 -34
- package/src/deepscientist/quest/stage_views.py +74 -29
- package/src/deepscientist/runners/codex.py +1 -1
- package/src/prompts/connectors/qq.md +1 -1
- package/src/prompts/contracts/shared_interaction.md +14 -0
- package/src/prompts/system.md +106 -32
- package/src/skills/analysis-campaign/SKILL.md +10 -14
- package/src/skills/baseline/SKILL.md +51 -38
- package/src/skills/baseline/references/baseline-plan-template.md +2 -0
- package/src/skills/decision/SKILL.md +12 -8
- package/src/skills/experiment/SKILL.md +28 -16
- package/src/skills/experiment/references/main-experiment-plan-template.md +2 -0
- package/src/skills/figure-polish/SKILL.md +1 -0
- package/src/skills/finalize/SKILL.md +3 -8
- package/src/skills/idea/SKILL.md +2 -8
- package/src/skills/intake-audit/SKILL.md +2 -8
- package/src/skills/rebuttal/SKILL.md +2 -8
- package/src/skills/review/SKILL.md +2 -8
- package/src/skills/scout/SKILL.md +2 -8
- package/src/skills/write/SKILL.md +52 -16
- package/src/skills/write/templates/DEEPSCIENTIST_NOTES.md +21 -0
- package/src/skills/write/templates/README.md +408 -0
- package/src/skills/write/templates/UPSTREAM_LICENSE.txt +21 -0
- package/src/skills/write/templates/aaai2026/README.md +534 -0
- package/src/skills/write/templates/aaai2026/aaai2026-unified-supp.tex +144 -0
- package/src/skills/write/templates/aaai2026/aaai2026-unified-template.tex +952 -0
- package/src/skills/write/templates/aaai2026/aaai2026.bib +111 -0
- package/src/skills/write/templates/aaai2026/aaai2026.bst +1493 -0
- package/src/skills/write/templates/aaai2026/aaai2026.sty +315 -0
- package/src/skills/write/templates/acl/README.md +50 -0
- package/src/skills/write/templates/acl/acl.sty +312 -0
- package/src/skills/write/templates/acl/acl_latex.tex +377 -0
- package/src/skills/write/templates/acl/acl_lualatex.tex +101 -0
- package/src/skills/write/templates/acl/acl_natbib.bst +1940 -0
- package/src/skills/write/templates/acl/anthology.bib.txt +26 -0
- package/src/skills/write/templates/acl/custom.bib +70 -0
- package/src/skills/write/templates/acl/formatting.md +326 -0
- package/src/skills/write/templates/asplos2027/main.tex +459 -0
- package/src/skills/write/templates/asplos2027/references.bib +135 -0
- package/src/skills/write/templates/colm2025/README.md +3 -0
- package/src/skills/write/templates/colm2025/colm2025_conference.bib +11 -0
- package/src/skills/write/templates/colm2025/colm2025_conference.bst +1440 -0
- package/src/skills/write/templates/colm2025/colm2025_conference.sty +218 -0
- package/src/skills/write/templates/colm2025/colm2025_conference.tex +305 -0
- package/src/skills/write/templates/colm2025/fancyhdr.sty +485 -0
- package/src/skills/write/templates/colm2025/math_commands.tex +508 -0
- package/src/skills/write/templates/colm2025/natbib.sty +1246 -0
- package/src/skills/write/templates/iclr2026/fancyhdr.sty +485 -0
- package/src/skills/write/templates/iclr2026/iclr2026_conference.bib +24 -0
- package/src/skills/write/templates/iclr2026/iclr2026_conference.bst +1440 -0
- package/src/skills/write/templates/iclr2026/iclr2026_conference.sty +246 -0
- package/src/skills/write/templates/iclr2026/iclr2026_conference.tex +414 -0
- package/src/skills/write/templates/iclr2026/math_commands.tex +508 -0
- package/src/skills/write/templates/iclr2026/natbib.sty +1246 -0
- package/src/skills/write/templates/icml2026/algorithm.sty +79 -0
- package/src/skills/write/templates/icml2026/algorithmic.sty +201 -0
- package/src/skills/write/templates/icml2026/example_paper.bib +75 -0
- package/src/skills/write/templates/icml2026/example_paper.tex +662 -0
- package/src/skills/write/templates/icml2026/fancyhdr.sty +864 -0
- package/src/skills/write/templates/icml2026/icml2026.bst +1443 -0
- package/src/skills/write/templates/icml2026/icml2026.sty +767 -0
- package/src/skills/write/templates/neurips2025/Makefile +36 -0
- package/src/skills/write/templates/neurips2025/extra_pkgs.tex +53 -0
- package/src/skills/write/templates/neurips2025/main.tex +38 -0
- package/src/skills/write/templates/neurips2025/neurips.sty +382 -0
- package/src/skills/write/templates/nsdi2027/main.tex +426 -0
- package/src/skills/write/templates/nsdi2027/references.bib +151 -0
- package/src/skills/write/templates/nsdi2027/usenix-2020-09.sty +83 -0
- package/src/skills/write/templates/osdi2026/main.tex +429 -0
- package/src/skills/write/templates/osdi2026/references.bib +150 -0
- package/src/skills/write/templates/osdi2026/usenix-2020-09.sty +83 -0
- package/src/skills/write/templates/sosp2026/main.tex +532 -0
- package/src/skills/write/templates/sosp2026/references.bib +148 -0
- package/src/tui/package.json +1 -1
- package/src/ui/dist/assets/{AiManusChatView-BS3V4ZOk.js → AiManusChatView-m2FNtwbn.js} +110 -14
- package/src/ui/dist/assets/{AnalysisPlugin-DLPXQsmr.js → AnalysisPlugin-BMTF8EGL.js} +1 -1
- package/src/ui/dist/assets/{AutoFigurePlugin-C-Fr9knQ.js → AutoFigurePlugin-DxPdMUNb.js} +5 -5
- package/src/ui/dist/assets/{CliPlugin-Dd8AHzFg.js → CliPlugin-BEOWgxCI.js} +9 -9
- package/src/ui/dist/assets/{CodeEditorPlugin-Dg-RepTl.js → CodeEditorPlugin-BCXvjqmb.js} +8 -8
- package/src/ui/dist/assets/{CodeViewerPlugin-D2J_3nyt.js → CodeViewerPlugin-DaJcy3nD.js} +5 -5
- package/src/ui/dist/assets/{DocViewerPlugin-ChRLLKNb.js → DocViewerPlugin-ByfeIq4K.js} +3 -3
- package/src/ui/dist/assets/{GitDiffViewerPlugin-DgHfcved.js → GitDiffViewerPlugin-Cksf3VZ-.js} +830 -86
- package/src/ui/dist/assets/{ImageViewerPlugin-C89GZMBy.js → ImageViewerPlugin-CFz-OsTS.js} +5 -5
- package/src/ui/dist/assets/{LabCopilotPanel-BUfIwUcb.js → LabCopilotPanel-CJ1cJzoX.js} +10 -10
- package/src/ui/dist/assets/{LabPlugin-zvUmQUMq.js → LabPlugin-BF3dVJwa.js} +1 -1
- package/src/ui/dist/assets/{LatexPlugin-C1SSNuWp.js → LatexPlugin-DDkwZ6Sj.js} +7 -7
- package/src/ui/dist/assets/{MarkdownViewerPlugin-D2Mf5tU5.js → MarkdownViewerPlugin-HAuvurcT.js} +4 -4
- package/src/ui/dist/assets/{MarketplacePlugin-CF4LgiS2.js → MarketplacePlugin-BtoTYy2C.js} +3 -3
- package/src/ui/dist/assets/{index-Be0NAmh8.js → NotebookEditor-CSJYx7b-.js} +12 -155
- package/src/ui/dist/assets/{NotebookEditor-BM7Bgwlv.js → NotebookEditor-DQgRezm_.js} +1 -1
- package/src/ui/dist/assets/{PdfLoader-Bc5qfD-Z.js → PdfLoader-DPa_-fv6.js} +1 -1
- package/src/ui/dist/assets/{PdfMarkdownPlugin-sh1-IRcp.js → PdfMarkdownPlugin-BZpXOEjm.js} +3 -3
- package/src/ui/dist/assets/{PdfViewerPlugin-C_a7CpWG.js → PdfViewerPlugin-BT8a6wGR.js} +10 -10
- package/src/ui/dist/assets/{SearchPlugin-L4z3HcLf.js → SearchPlugin-D_blveZi.js} +1 -1
- package/src/ui/dist/assets/{Stepper-Dk4aQ3fN.js → Stepper-DH2k75Vo.js} +1 -1
- package/src/ui/dist/assets/{TextViewerPlugin-BsNtlKVo.js → TextViewerPlugin-Btx0M3hX.js} +4 -4
- package/src/ui/dist/assets/{VNCViewer-BpeDcZ5_.js → VNCViewer-DImJO4rO.js} +9 -9
- package/src/ui/dist/assets/{bibtex-C4QI-bbj.js → bibtex-B-Hqu0Sg.js} +1 -1
- package/src/ui/dist/assets/{code-DuMINRsg.js → code-BUfXGJSl.js} +1 -1
- package/src/ui/dist/assets/{file-content-C3N-432K.js → file-content-VqamwI3X.js} +1 -1
- package/src/ui/dist/assets/{file-diff-panel-CffQ4ZMg.js → file-diff-panel-C_wOoS7a.js} +1 -1
- package/src/ui/dist/assets/{file-socket-CRH59PCO.js → file-socket-D2bTuMVP.js} +1 -1
- package/src/ui/dist/assets/{file-utils-vYGtW2mI.js → file-utils--zJCPN1i.js} +1 -1
- package/src/ui/dist/assets/{image-DBVGaooo.js → image-BZkGJ4mM.js} +1 -1
- package/src/ui/dist/assets/{index-DjSFDmgB.js → index-CxkvSeKw.js} +2 -2
- package/src/ui/dist/assets/{index-BpjYH9Vg.js → index-D9QIGcmc.js} +1 -1
- package/src/ui/dist/assets/{index-Do9N28uB.css → index-DXZ1daiJ.css} +163 -34
- package/src/ui/dist/assets/index-DdRW6RMJ.js +159 -0
- package/src/ui/dist/assets/{index-B1P6hQRJ.js → index-DjggJovS.js} +3029 -1780
- package/src/ui/dist/assets/{message-square-BsPDBhiY.js → message-square-FUIPIhU2.js} +1 -1
- package/src/ui/dist/assets/{monaco-BTkdPojV.js → monaco-DHMc7kKM.js} +1 -1
- package/src/ui/dist/assets/{popover-cWjCk-vc.js → popover-B85oCgCS.js} +1 -1
- package/src/ui/dist/assets/{project-sync-CXn530xb.js → project-sync-DOMCcPac.js} +1 -1
- package/src/ui/dist/assets/{sigma-04Jr12jg.js → sigma-BO2rQrl3.js} +1 -1
- package/src/ui/dist/assets/{tooltip-BdVDl0G5.js → tooltip-B1OspAkx.js} +1 -1
- package/src/ui/dist/assets/{trash-CB_GlQyC.js → trash-BsVEH_dV.js} +1 -1
- package/src/ui/dist/assets/{useCliAccess-BL932NwS.js → useCliAccess-b8L6JuZm.js} +1 -1
- package/src/ui/dist/assets/{useFileDiffOverlay-B2WK7Tvq.js → useFileDiffOverlay-BY7uA9hV.js} +1 -1
- package/src/ui/dist/assets/{wrap-text-YC68g12z.js → wrap-text-BwyVuUIK.js} +1 -1
- package/src/ui/dist/assets/{zoom-out-C0RJvFiJ.js → zoom-out-RDpLugQP.js} +1 -1
- package/src/ui/dist/index.html +5 -2
- /package/src/ui/dist/assets/{index-CccQYZjX.css → NotebookEditor-CccQYZjX.css} +0 -0
package/README.md
CHANGED
|
@@ -17,6 +17,8 @@ Install DeepScientist:
|
|
|
17
17
|
npm install -g @researai/deepscientist
|
|
18
18
|
```
|
|
19
19
|
|
|
20
|
+
For the best experience, we recommend using GPT-5.4 in `xhigh` mode (for example, via the $20 GPT Plus plan or the $200 GPT Pro plan); if you are in China, we recommend the MiniMax-M2.7 Token Plan (Max plan): https://platform.minimaxi.com/subscribe/token-plan
|
|
21
|
+
|
|
20
22
|
## Start
|
|
21
23
|
|
|
22
24
|
```bash
|
|
@@ -124,6 +126,8 @@ This installs a lightweight TinyTeX `pdflatex` runtime for local paper compilati
|
|
|
124
126
|
- [快速开始(中文)](docs/zh/00_QUICK_START.md)
|
|
125
127
|
- [QQ Connector Guide (English)](docs/en/03_QQ_CONNECTOR_GUIDE.md)
|
|
126
128
|
- [QQ Connector Guide (中文)](docs/zh/03_QQ_CONNECTOR_GUIDE.md)
|
|
129
|
+
- [Memory and MCP Guide (English)](docs/en/07_MEMORY_AND_MCP.md)
|
|
130
|
+
- [Memory 与 MCP 指南(中文)](docs/zh/07_MEMORY_AND_MCP.md)
|
|
127
131
|
|
|
128
132
|
## Maintainers
|
|
129
133
|
|
package/bin/ds.js
CHANGED
|
@@ -220,6 +220,17 @@ function compareVersions(left, right) {
|
|
|
220
220
|
return 0;
|
|
221
221
|
}
|
|
222
222
|
|
|
223
|
+
function hasActiveBusyUpdate(state, currentVersion) {
|
|
224
|
+
if (!state || !state.busy) {
|
|
225
|
+
return false;
|
|
226
|
+
}
|
|
227
|
+
const targetVersion = normalizeVersion(state.target_version || state.latest_version || '');
|
|
228
|
+
if (!targetVersion) {
|
|
229
|
+
return false;
|
|
230
|
+
}
|
|
231
|
+
return compareVersions(targetVersion, currentVersion) > 0;
|
|
232
|
+
}
|
|
233
|
+
|
|
223
234
|
function detectInstallMode(rootPath = repoRoot) {
|
|
224
235
|
const normalized = String(rootPath || '');
|
|
225
236
|
return normalized.includes(`${path.sep}node_modules${path.sep}`) ? 'npm-package' : 'source-checkout';
|
|
@@ -326,6 +337,8 @@ function buildUpdateStatus(home, statePatch = {}) {
|
|
|
326
337
|
const support = updateSupportSummary(installMode, npmBinary, launcherPath);
|
|
327
338
|
const currentVersion = normalizeVersion(state.current_version || packageJson.version);
|
|
328
339
|
const latestVersion = normalizeVersion(state.latest_version || '');
|
|
340
|
+
const targetVersion = normalizeVersion(state.target_version || '');
|
|
341
|
+
const busy = hasActiveBusyUpdate(state, currentVersion);
|
|
329
342
|
const promptedVersion = normalizeVersion(state.last_prompted_version || '');
|
|
330
343
|
const updateAvailable = Boolean(latestVersion) && compareVersions(latestVersion, currentVersion) > 0;
|
|
331
344
|
const skippedVersion = normalizeVersion(state.last_skipped_version || '');
|
|
@@ -333,7 +346,7 @@ function buildUpdateStatus(home, statePatch = {}) {
|
|
|
333
346
|
const skippedCurrentTarget = Boolean(updateAvailable && skippedVersion && skippedVersion === latestVersion);
|
|
334
347
|
const promptRecommended =
|
|
335
348
|
Boolean(updateAvailable)
|
|
336
|
-
&& !
|
|
349
|
+
&& !busy
|
|
337
350
|
&& !promptedCurrentTarget
|
|
338
351
|
&& !skippedCurrentTarget
|
|
339
352
|
;
|
|
@@ -348,7 +361,7 @@ function buildUpdateStatus(home, statePatch = {}) {
|
|
|
348
361
|
latest_version: latestVersion || null,
|
|
349
362
|
update_available: updateAvailable,
|
|
350
363
|
prompt_recommended: promptRecommended,
|
|
351
|
-
busy
|
|
364
|
+
busy,
|
|
352
365
|
last_checked_at: state.last_checked_at || null,
|
|
353
366
|
last_check_error: state.last_check_error || null,
|
|
354
367
|
last_prompted_at: state.last_prompted_at || null,
|
|
@@ -358,7 +371,7 @@ function buildUpdateStatus(home, statePatch = {}) {
|
|
|
358
371
|
last_update_started_at: state.last_update_started_at || null,
|
|
359
372
|
last_update_finished_at: state.last_update_finished_at || null,
|
|
360
373
|
last_update_result: state.last_update_result || null,
|
|
361
|
-
target_version:
|
|
374
|
+
target_version: busy ? targetVersion || latestVersion || null : null,
|
|
362
375
|
manual_update_command: updateManualCommand(installMode),
|
|
363
376
|
reason: support.reason,
|
|
364
377
|
};
|
|
@@ -371,8 +384,16 @@ function checkForUpdates(home, { force = false, timeoutMs = 3500 } = {}) {
|
|
|
371
384
|
const npmBinary = resolveNpmBinary();
|
|
372
385
|
const launcherPath = resolveLauncherPath();
|
|
373
386
|
const support = updateSupportSummary(installMode, npmBinary, launcherPath);
|
|
387
|
+
const existingBusyIsStale = Boolean(existing.busy) && !hasActiveBusyUpdate(existing, currentVersion);
|
|
374
388
|
|
|
375
389
|
if (!force && existing.current_version === currentVersion && !isExpired(existing.last_checked_at, UPDATE_CHECK_TTL_MS)) {
|
|
390
|
+
if (existingBusyIsStale) {
|
|
391
|
+
const repaired = mergeUpdateState(home, {
|
|
392
|
+
busy: false,
|
|
393
|
+
target_version: null,
|
|
394
|
+
});
|
|
395
|
+
return buildUpdateStatus(home, repaired);
|
|
396
|
+
}
|
|
376
397
|
return buildUpdateStatus(home);
|
|
377
398
|
}
|
|
378
399
|
|
|
@@ -392,6 +413,13 @@ function checkForUpdates(home, { force = false, timeoutMs = 3500 } = {}) {
|
|
|
392
413
|
last_checked_at: new Date().toISOString(),
|
|
393
414
|
last_check_error: probe.ok ? null : probe.error,
|
|
394
415
|
});
|
|
416
|
+
if (Boolean(patched.busy) && !hasActiveBusyUpdate(patched, currentVersion)) {
|
|
417
|
+
const repaired = mergeUpdateState(home, {
|
|
418
|
+
busy: false,
|
|
419
|
+
target_version: null,
|
|
420
|
+
});
|
|
421
|
+
return buildUpdateStatus(home, repaired);
|
|
422
|
+
}
|
|
395
423
|
return buildUpdateStatus(home, patched);
|
|
396
424
|
}
|
|
397
425
|
|
|
@@ -1142,6 +1170,40 @@ function buildGlobalWrapperScript({ installDir, home, commandName }) {
|
|
|
1142
1170
|
return [
|
|
1143
1171
|
'#!/usr/bin/env bash',
|
|
1144
1172
|
'set -euo pipefail',
|
|
1173
|
+
'WRAPPER_PATH="${BASH_SOURCE[0]}"',
|
|
1174
|
+
'WRAPPER_DIR="$(cd "$(dirname "$WRAPPER_PATH")" && pwd)"',
|
|
1175
|
+
`PREFERRED_COMMAND="${commandName}"`,
|
|
1176
|
+
'LOOKUP_PATH=""',
|
|
1177
|
+
'OLD_IFS="$IFS"',
|
|
1178
|
+
'IFS=:',
|
|
1179
|
+
'for ENTRY in $PATH; do',
|
|
1180
|
+
' if [ -z "$ENTRY" ]; then',
|
|
1181
|
+
' continue',
|
|
1182
|
+
' fi',
|
|
1183
|
+
' ENTRY_REAL="$ENTRY"',
|
|
1184
|
+
' if ENTRY_CANONICAL="$(cd "$ENTRY" 2>/dev/null && pwd)"; then',
|
|
1185
|
+
' ENTRY_REAL="$ENTRY_CANONICAL"',
|
|
1186
|
+
' fi',
|
|
1187
|
+
' if [ "$ENTRY_REAL" = "$WRAPPER_DIR" ]; then',
|
|
1188
|
+
' continue',
|
|
1189
|
+
' fi',
|
|
1190
|
+
' if [ -z "$LOOKUP_PATH" ]; then',
|
|
1191
|
+
' LOOKUP_PATH="$ENTRY"',
|
|
1192
|
+
' else',
|
|
1193
|
+
' LOOKUP_PATH="$LOOKUP_PATH:$ENTRY"',
|
|
1194
|
+
' fi',
|
|
1195
|
+
'done',
|
|
1196
|
+
'IFS="$OLD_IFS"',
|
|
1197
|
+
'if [ -n "$LOOKUP_PATH" ]; then',
|
|
1198
|
+
' if RESOLVED_LAUNCHER="$(PATH="$LOOKUP_PATH" command -v "$PREFERRED_COMMAND" 2>/dev/null)"; then',
|
|
1199
|
+
' if [ -n "$RESOLVED_LAUNCHER" ] && [ "$RESOLVED_LAUNCHER" != "$WRAPPER_PATH" ]; then',
|
|
1200
|
+
' if [ -z "${DEEPSCIENTIST_HOME:-}" ]; then',
|
|
1201
|
+
` export DEEPSCIENTIST_HOME="${home}"`,
|
|
1202
|
+
' fi',
|
|
1203
|
+
' exec "$RESOLVED_LAUNCHER" "$@"',
|
|
1204
|
+
' fi',
|
|
1205
|
+
' fi',
|
|
1206
|
+
'fi',
|
|
1145
1207
|
'if [ -z "${DEEPSCIENTIST_HOME:-}" ]; then',
|
|
1146
1208
|
` export DEEPSCIENTIST_HOME="${home}"`,
|
|
1147
1209
|
'fi',
|
|
@@ -1150,6 +1212,18 @@ function buildGlobalWrapperScript({ installDir, home, commandName }) {
|
|
|
1150
1212
|
].join('\n');
|
|
1151
1213
|
}
|
|
1152
1214
|
|
|
1215
|
+
function buildLauncherWrapperScript({ launcherPath, home }) {
|
|
1216
|
+
return [
|
|
1217
|
+
'#!/usr/bin/env bash',
|
|
1218
|
+
'set -euo pipefail',
|
|
1219
|
+
'if [ -z "${DEEPSCIENTIST_HOME:-}" ]; then',
|
|
1220
|
+
` export DEEPSCIENTIST_HOME="${home}"`,
|
|
1221
|
+
'fi',
|
|
1222
|
+
`exec "${launcherPath}" "$@"`,
|
|
1223
|
+
'',
|
|
1224
|
+
].join('\n');
|
|
1225
|
+
}
|
|
1226
|
+
|
|
1153
1227
|
function writeExecutableScript(targetPath, content) {
|
|
1154
1228
|
ensureDir(path.dirname(targetPath));
|
|
1155
1229
|
fs.writeFileSync(targetPath, content, { encoding: 'utf8', mode: 0o755 });
|
|
@@ -1186,6 +1260,94 @@ function candidateWrapperPathsForCommand(commandName) {
|
|
|
1186
1260
|
return candidates;
|
|
1187
1261
|
}
|
|
1188
1262
|
|
|
1263
|
+
function parseLegacyWrapperCandidate(candidatePath) {
|
|
1264
|
+
let stat = null;
|
|
1265
|
+
try {
|
|
1266
|
+
stat = fs.lstatSync(candidatePath);
|
|
1267
|
+
} catch {
|
|
1268
|
+
return null;
|
|
1269
|
+
}
|
|
1270
|
+
|
|
1271
|
+
if (stat.isSymbolicLink()) {
|
|
1272
|
+
let resolved = null;
|
|
1273
|
+
try {
|
|
1274
|
+
resolved = fs.realpathSync(candidatePath);
|
|
1275
|
+
} catch {
|
|
1276
|
+
return null;
|
|
1277
|
+
}
|
|
1278
|
+
if (!/[\\/]cli[\\/]bin[\\/](?:ds|ds-cli|research|resear)(?:\.cmd)?$/.test(resolved)) {
|
|
1279
|
+
return null;
|
|
1280
|
+
}
|
|
1281
|
+
return {
|
|
1282
|
+
source: 'symlink',
|
|
1283
|
+
execPath: resolved,
|
|
1284
|
+
home: path.dirname(path.dirname(path.dirname(resolved))),
|
|
1285
|
+
};
|
|
1286
|
+
}
|
|
1287
|
+
|
|
1288
|
+
if (!stat.isFile()) {
|
|
1289
|
+
return null;
|
|
1290
|
+
}
|
|
1291
|
+
|
|
1292
|
+
let text = '';
|
|
1293
|
+
try {
|
|
1294
|
+
text = fs.readFileSync(candidatePath, 'utf8');
|
|
1295
|
+
} catch {
|
|
1296
|
+
return null;
|
|
1297
|
+
}
|
|
1298
|
+
|
|
1299
|
+
const execMatch = text.match(/exec "([^"\n]+[\\/]bin[\\/](?:ds|ds-cli|research|resear))" "\$@"/);
|
|
1300
|
+
if (!execMatch) {
|
|
1301
|
+
return null;
|
|
1302
|
+
}
|
|
1303
|
+
const execPath = execMatch[1];
|
|
1304
|
+
if (!/[\\/]cli[\\/]bin[\\/](?:ds|ds-cli|research|resear)$/.test(execPath)) {
|
|
1305
|
+
return null;
|
|
1306
|
+
}
|
|
1307
|
+
const homeMatch = text.match(/export DEEPSCIENTIST_HOME="([^"\n]+)"/);
|
|
1308
|
+
return {
|
|
1309
|
+
source: 'script',
|
|
1310
|
+
execPath,
|
|
1311
|
+
home: homeMatch ? homeMatch[1] : path.dirname(path.dirname(path.dirname(execPath))),
|
|
1312
|
+
};
|
|
1313
|
+
}
|
|
1314
|
+
|
|
1315
|
+
function repairLegacyPathWrappers({ home, launcherPath, force = false }) {
|
|
1316
|
+
if (process.platform === 'win32') {
|
|
1317
|
+
return [];
|
|
1318
|
+
}
|
|
1319
|
+
if (!launcherPath || !fs.existsSync(launcherPath)) {
|
|
1320
|
+
return [];
|
|
1321
|
+
}
|
|
1322
|
+
if (!force && detectInstallMode(repoRoot) !== 'npm-package') {
|
|
1323
|
+
return [];
|
|
1324
|
+
}
|
|
1325
|
+
|
|
1326
|
+
const rewritten = [];
|
|
1327
|
+
const seen = new Set();
|
|
1328
|
+
for (const commandName of launcherWrapperCommands) {
|
|
1329
|
+
for (const candidate of candidateWrapperPathsForCommand(commandName)) {
|
|
1330
|
+
if (seen.has(candidate)) {
|
|
1331
|
+
continue;
|
|
1332
|
+
}
|
|
1333
|
+
seen.add(candidate);
|
|
1334
|
+
const legacy = parseLegacyWrapperCandidate(candidate);
|
|
1335
|
+
if (!legacy) {
|
|
1336
|
+
continue;
|
|
1337
|
+
}
|
|
1338
|
+
writeExecutableScript(
|
|
1339
|
+
candidate,
|
|
1340
|
+
buildLauncherWrapperScript({
|
|
1341
|
+
launcherPath,
|
|
1342
|
+
home: legacy.home || home,
|
|
1343
|
+
})
|
|
1344
|
+
);
|
|
1345
|
+
rewritten.push(candidate);
|
|
1346
|
+
}
|
|
1347
|
+
}
|
|
1348
|
+
return rewritten;
|
|
1349
|
+
}
|
|
1350
|
+
|
|
1189
1351
|
function rewriteLauncherWrappersIfPointingAtSource({ sourceHome, targetHome }) {
|
|
1190
1352
|
if (process.platform === 'win32') {
|
|
1191
1353
|
return [];
|
|
@@ -2622,19 +2784,45 @@ function spawnDetachedNode(args, options = {}) {
|
|
|
2622
2784
|
async function performSelfUpdate(home, options = {}) {
|
|
2623
2785
|
const status = checkForUpdates(home, { force: true });
|
|
2624
2786
|
if (!status.update_available) {
|
|
2787
|
+
const message = `DeepScientist is already on the latest version (${status.current_version}).`;
|
|
2788
|
+
mergeUpdateState(home, {
|
|
2789
|
+
current_version: status.current_version,
|
|
2790
|
+
latest_version: status.latest_version,
|
|
2791
|
+
busy: false,
|
|
2792
|
+
target_version: null,
|
|
2793
|
+
last_update_finished_at: new Date().toISOString(),
|
|
2794
|
+
last_update_result: {
|
|
2795
|
+
ok: true,
|
|
2796
|
+
target_version: null,
|
|
2797
|
+
message,
|
|
2798
|
+
},
|
|
2799
|
+
});
|
|
2625
2800
|
return {
|
|
2626
2801
|
ok: true,
|
|
2627
2802
|
updated: false,
|
|
2628
2803
|
status,
|
|
2629
|
-
message
|
|
2804
|
+
message,
|
|
2630
2805
|
};
|
|
2631
2806
|
}
|
|
2632
2807
|
if (!status.can_self_update) {
|
|
2808
|
+
const message = status.reason || `Manual update required: ${status.manual_update_command}`;
|
|
2809
|
+
mergeUpdateState(home, {
|
|
2810
|
+
current_version: status.current_version,
|
|
2811
|
+
latest_version: status.latest_version,
|
|
2812
|
+
busy: false,
|
|
2813
|
+
target_version: null,
|
|
2814
|
+
last_update_finished_at: new Date().toISOString(),
|
|
2815
|
+
last_update_result: {
|
|
2816
|
+
ok: false,
|
|
2817
|
+
target_version: status.latest_version || null,
|
|
2818
|
+
message,
|
|
2819
|
+
},
|
|
2820
|
+
});
|
|
2633
2821
|
return {
|
|
2634
2822
|
ok: false,
|
|
2635
2823
|
updated: false,
|
|
2636
2824
|
status,
|
|
2637
|
-
message
|
|
2825
|
+
message,
|
|
2638
2826
|
};
|
|
2639
2827
|
}
|
|
2640
2828
|
|
|
@@ -2697,6 +2885,11 @@ async function performSelfUpdate(home, options = {}) {
|
|
|
2697
2885
|
};
|
|
2698
2886
|
}
|
|
2699
2887
|
|
|
2888
|
+
repairLegacyPathWrappers({
|
|
2889
|
+
home,
|
|
2890
|
+
launcherPath: resolveLauncherPath(),
|
|
2891
|
+
});
|
|
2892
|
+
|
|
2700
2893
|
const restartDaemon =
|
|
2701
2894
|
options.restartDaemon === true
|
|
2702
2895
|
|| (options.restartDaemon !== false && Boolean(daemonState?.pid || daemonState?.daemon_id));
|
|
@@ -2799,6 +2992,22 @@ async function startBackgroundUpdateWorker(home, options = {}) {
|
|
|
2799
2992
|
};
|
|
2800
2993
|
}
|
|
2801
2994
|
const status = checkForUpdates(home, { force: false });
|
|
2995
|
+
if (!status.update_available) {
|
|
2996
|
+
return {
|
|
2997
|
+
ok: true,
|
|
2998
|
+
started: false,
|
|
2999
|
+
message: `DeepScientist is already on the latest version (${status.current_version}).`,
|
|
3000
|
+
status,
|
|
3001
|
+
};
|
|
3002
|
+
}
|
|
3003
|
+
if (!status.can_self_update) {
|
|
3004
|
+
return {
|
|
3005
|
+
ok: false,
|
|
3006
|
+
started: false,
|
|
3007
|
+
message: status.reason || `Manual update required: ${status.manual_update_command}`,
|
|
3008
|
+
status,
|
|
3009
|
+
};
|
|
3010
|
+
}
|
|
2802
3011
|
mergeUpdateState(home, {
|
|
2803
3012
|
current_version: status.current_version,
|
|
2804
3013
|
latest_version: status.latest_version,
|
|
@@ -3311,6 +3520,10 @@ async function launcherMain(rawArgs) {
|
|
|
3311
3520
|
const home = options.home || resolveHome(rawArgs);
|
|
3312
3521
|
applyLauncherProxy(options.proxy);
|
|
3313
3522
|
ensureDir(home);
|
|
3523
|
+
repairLegacyPathWrappers({
|
|
3524
|
+
home,
|
|
3525
|
+
launcherPath: resolveLauncherPath(),
|
|
3526
|
+
});
|
|
3314
3527
|
|
|
3315
3528
|
if (options.stop) {
|
|
3316
3529
|
await stopDaemon(home);
|
|
@@ -3460,6 +3673,8 @@ module.exports = {
|
|
|
3460
3673
|
parseLauncherArgs,
|
|
3461
3674
|
normalizeProxyUrl,
|
|
3462
3675
|
parseMigrateArgs,
|
|
3676
|
+
parseLegacyWrapperCandidate,
|
|
3677
|
+
repairLegacyPathWrappers,
|
|
3463
3678
|
useEditableProjectInstall,
|
|
3464
3679
|
compareVersions,
|
|
3465
3680
|
detectInstallMode,
|
|
@@ -209,7 +209,44 @@ Example:
|
|
|
209
209
|
Do not replace an experiment artifact with a memory card.
|
|
210
210
|
Do not replace a reusable lesson with a progress artifact.
|
|
211
211
|
|
|
212
|
-
## 4.
|
|
212
|
+
## 4. Artifact metric-contract rules
|
|
213
|
+
|
|
214
|
+
Use `artifact` as the authoritative submission surface for baseline and main-experiment metrics.
|
|
215
|
+
|
|
216
|
+
### `artifact.confirm_baseline(...)`
|
|
217
|
+
|
|
218
|
+
For a confirmed baseline:
|
|
219
|
+
|
|
220
|
+
- the canonical metric contract should live in `<baseline_root>/json/metric_contract.json`
|
|
221
|
+
- the canonical `metrics_summary` should be a flat top-level dictionary keyed by the paper-facing metric ids
|
|
222
|
+
- if the raw evaluator output is nested, map each required canonical metric through explicit `origin_path` fields inside `metric_contract.metrics`
|
|
223
|
+
- every canonical baseline metric entry should explain where the number came from:
|
|
224
|
+
- `description`
|
|
225
|
+
- either `derivation` or `origin_path`
|
|
226
|
+
- `source_ref`
|
|
227
|
+
- keep `primary_metric` as the headline metric only; do not use it to erase the rest of the accepted paper-facing comparison surface
|
|
228
|
+
|
|
229
|
+
### `artifact.record_main_experiment(...)`
|
|
230
|
+
|
|
231
|
+
For a main experiment recorded against a confirmed baseline:
|
|
232
|
+
|
|
233
|
+
- use the confirmed baseline metric-contract JSON as the canonical comparison contract
|
|
234
|
+
- report every required baseline metric id in the main experiment submission
|
|
235
|
+
- extra metrics are allowed, but missing required baseline metrics are not
|
|
236
|
+
- keep the original evaluation code and metric definitions for the canonical baseline metrics
|
|
237
|
+
- if an extra evaluator is genuinely necessary, record it as supplementary evidence instead of replacing the canonical comparator
|
|
238
|
+
|
|
239
|
+
### Validation and temporary notes
|
|
240
|
+
|
|
241
|
+
- when the MCP tool runs strict validation, contract failures return structured error payloads such as:
|
|
242
|
+
- `missing_metric_ids`
|
|
243
|
+
- `baseline_metric_ids`
|
|
244
|
+
- `baseline_metric_details`
|
|
245
|
+
- `evaluation_protocol_mismatch`
|
|
246
|
+
- `Result/metric.md` may be used as temporary scratch memory while working, but it is optional and not authoritative
|
|
247
|
+
- if `Result/metric.md` exists, reconcile it against the final baseline or main-experiment submission before calling the artifact tool
|
|
248
|
+
|
|
249
|
+
## 5. Bash exec usage
|
|
213
250
|
|
|
214
251
|
Use `bash_exec` for monitored commands:
|
|
215
252
|
|
|
@@ -226,7 +263,7 @@ bash_exec.bash_exec(mode="read", id="<bash_id>")
|
|
|
226
263
|
|
|
227
264
|
Use `kill` only when the quest truly needs to stop the session.
|
|
228
265
|
|
|
229
|
-
##
|
|
266
|
+
## 6. Prompt-level expectations
|
|
230
267
|
|
|
231
268
|
The agent should normally follow this discipline:
|
|
232
269
|
|
|
@@ -237,7 +274,7 @@ The agent should normally follow this discipline:
|
|
|
237
274
|
5. `bash_exec` for durable shell work
|
|
238
275
|
6. `memory.write(...)` only after a real durable finding appears
|
|
239
276
|
|
|
240
|
-
##
|
|
277
|
+
## 7. UI expectation
|
|
241
278
|
|
|
242
279
|
In `/projects/{id}` Studio trace:
|
|
243
280
|
|
|
@@ -11,6 +11,7 @@ We especially thank the following projects for their ideas, research direction,
|
|
|
11
11
|
- AlphaEvolve
|
|
12
12
|
- OpenEvolve
|
|
13
13
|
- EvoScientist
|
|
14
|
+
- Orchestra-Research
|
|
14
15
|
- Orchestra-Research/AI-Research-SKILLs
|
|
15
16
|
|
|
16
17
|
These projects have been important references for thinking about automated research, open-ended exploration, evolutionary search, experiment organization, and long-horizon research agents.
|
|
@@ -192,7 +192,44 @@ updated_at: 2026-03-11T18:00:00+00:00
|
|
|
192
192
|
不要用 memory 代替实验 artifact。
|
|
193
193
|
不要用 artifact 代替可复用知识卡。
|
|
194
194
|
|
|
195
|
-
## 4.
|
|
195
|
+
## 4. Artifact 指标契约规则
|
|
196
|
+
|
|
197
|
+
baseline 与主实验的正式指标提交,应以 `artifact` 为唯一权威入口。
|
|
198
|
+
|
|
199
|
+
### `artifact.confirm_baseline(...)`
|
|
200
|
+
|
|
201
|
+
对于已确认的 baseline:
|
|
202
|
+
|
|
203
|
+
- canonical metric contract 应保存在 `<baseline_root>/json/metric_contract.json`
|
|
204
|
+
- canonical `metrics_summary` 应是顶层扁平字典,key 直接使用论文面对比时的 metric id
|
|
205
|
+
- 如果原始评测输出是嵌套结构,应在 `metric_contract.metrics` 中为每个必需 canonical metric 提供显式 `origin_path`,而不是直接提交嵌套 blob
|
|
206
|
+
- 每个 canonical baseline metric 都应说明数值来源,至少包含:
|
|
207
|
+
- `description`
|
|
208
|
+
- `derivation` 或 `origin_path`
|
|
209
|
+
- `source_ref`
|
|
210
|
+
- `primary_metric` 只是 headline metric,不能借此删掉其他论文面对比所需指标
|
|
211
|
+
|
|
212
|
+
### `artifact.record_main_experiment(...)`
|
|
213
|
+
|
|
214
|
+
对于基于已确认 baseline 的主实验:
|
|
215
|
+
|
|
216
|
+
- 默认以已确认 baseline 的 metric-contract JSON 作为 canonical comparison contract
|
|
217
|
+
- 主实验提交时必须覆盖 baseline 的全部必需 metric id
|
|
218
|
+
- 可以多报额外指标,但不能缺少 baseline 的必需指标
|
|
219
|
+
- canonical baseline metrics 应继续使用原有评测代码和指标定义
|
|
220
|
+
- 如果确实需要额外评测器,应把它作为 supplementary evidence 记录,而不是替换 canonical comparator
|
|
221
|
+
|
|
222
|
+
### 校验失败与临时记录
|
|
223
|
+
|
|
224
|
+
- 当 MCP 工具开启严格校验时,失败会返回结构化错误字段,例如:
|
|
225
|
+
- `missing_metric_ids`
|
|
226
|
+
- `baseline_metric_ids`
|
|
227
|
+
- `baseline_metric_details`
|
|
228
|
+
- `evaluation_protocol_mismatch`
|
|
229
|
+
- `Result/metric.md` 只可作为工作过程中的临时草稿/记忆文件,不是必需文件,也不是权威来源
|
|
230
|
+
- 如果存在 `Result/metric.md`,请在调用 artifact 提交前用它核对最终 baseline 或主实验提交内容,避免遗漏或写错
|
|
231
|
+
|
|
232
|
+
## 5. Bash exec 的基本用法
|
|
196
233
|
|
|
197
234
|
用于可监控命令:
|
|
198
235
|
|
|
@@ -209,7 +246,7 @@ bash_exec.bash_exec(mode="read", id="<bash_id>")
|
|
|
209
246
|
|
|
210
247
|
只有在确实需要停止时才使用 `kill`。
|
|
211
248
|
|
|
212
|
-
##
|
|
249
|
+
## 6. Prompt 级纪律(建议)
|
|
213
250
|
|
|
214
251
|
通常推荐遵循:
|
|
215
252
|
|
|
@@ -220,7 +257,7 @@ bash_exec.bash_exec(mode="read", id="<bash_id>")
|
|
|
220
257
|
5. 长任务 shell 用 `bash_exec`
|
|
221
258
|
6. 有真正的可复用发现才 `memory.write(...)`
|
|
222
259
|
|
|
223
|
-
##
|
|
260
|
+
## 7. UI 期望
|
|
224
261
|
|
|
225
262
|
在 `/projects/{id}` 的 Studio trace 中:
|
|
226
263
|
|
package/install.sh
CHANGED
|
@@ -421,6 +421,40 @@ write_global_wrapper() {
|
|
|
421
421
|
cat >"$target_path" <<EOF
|
|
422
422
|
#!/usr/bin/env bash
|
|
423
423
|
set -euo pipefail
|
|
424
|
+
WRAPPER_PATH="\${BASH_SOURCE[0]}"
|
|
425
|
+
WRAPPER_DIR="\$(cd "\$(dirname "\$WRAPPER_PATH")" && pwd)"
|
|
426
|
+
PREFERRED_COMMAND="$command_name"
|
|
427
|
+
LOOKUP_PATH=""
|
|
428
|
+
OLD_IFS="\$IFS"
|
|
429
|
+
IFS=:
|
|
430
|
+
for ENTRY in \$PATH; do
|
|
431
|
+
if [ -z "\$ENTRY" ]; then
|
|
432
|
+
continue
|
|
433
|
+
fi
|
|
434
|
+
ENTRY_REAL="\$ENTRY"
|
|
435
|
+
if ENTRY_CANONICAL="\$(cd "\$ENTRY" 2>/dev/null && pwd)"; then
|
|
436
|
+
ENTRY_REAL="\$ENTRY_CANONICAL"
|
|
437
|
+
fi
|
|
438
|
+
if [ "\$ENTRY_REAL" = "\$WRAPPER_DIR" ]; then
|
|
439
|
+
continue
|
|
440
|
+
fi
|
|
441
|
+
if [ -z "\$LOOKUP_PATH" ]; then
|
|
442
|
+
LOOKUP_PATH="\$ENTRY"
|
|
443
|
+
else
|
|
444
|
+
LOOKUP_PATH="\$LOOKUP_PATH:\$ENTRY"
|
|
445
|
+
fi
|
|
446
|
+
done
|
|
447
|
+
IFS="\$OLD_IFS"
|
|
448
|
+
if [ -n "\$LOOKUP_PATH" ]; then
|
|
449
|
+
if RESOLVED_LAUNCHER="\$(PATH="\$LOOKUP_PATH" command -v "\$PREFERRED_COMMAND" 2>/dev/null)"; then
|
|
450
|
+
if [ -n "\$RESOLVED_LAUNCHER" ] && [ "\$RESOLVED_LAUNCHER" != "\$WRAPPER_PATH" ]; then
|
|
451
|
+
if [ -z "\${DEEPSCIENTIST_HOME:-}" ]; then
|
|
452
|
+
export DEEPSCIENTIST_HOME="$BASE_DIR"
|
|
453
|
+
fi
|
|
454
|
+
exec "\$RESOLVED_LAUNCHER" "\$@"
|
|
455
|
+
fi
|
|
456
|
+
fi
|
|
457
|
+
fi
|
|
424
458
|
if [ -z "\${DEEPSCIENTIST_HOME:-}" ]; then
|
|
425
459
|
export DEEPSCIENTIST_HOME="$BASE_DIR"
|
|
426
460
|
fi
|
package/package.json
CHANGED
package/pyproject.toml
CHANGED
|
@@ -85,6 +85,7 @@ def build_session_descriptor(
|
|
|
85
85
|
"mcp_servers": [
|
|
86
86
|
{"name": "memory", "transport": "stdio", "scope": "quest-local"},
|
|
87
87
|
{"name": "artifact", "transport": "stdio", "scope": "quest-local"},
|
|
88
|
+
{"name": "bash_exec", "transport": "stdio", "scope": "quest-local"},
|
|
88
89
|
],
|
|
89
90
|
"slash_commands": build_slash_commands(quest_id),
|
|
90
91
|
"meta": {
|