@researai/deepscientist 1.5.15 → 1.5.17
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 +385 -104
- package/bin/ds.js +1241 -110
- package/docs/en/00_QUICK_START.md +100 -19
- package/docs/en/01_SETTINGS_REFERENCE.md +34 -1
- package/docs/en/02_START_RESEARCH_GUIDE.md +7 -0
- package/docs/en/05_TUI_GUIDE.md +6 -0
- package/docs/en/06_RUNTIME_AND_CANVAS.md +4 -3
- package/docs/en/09_DOCTOR.md +25 -8
- package/docs/en/14_PROMPT_SKILLS_AND_MCP_GUIDE.md +63 -13
- package/docs/en/15_CODEX_PROVIDER_SETUP.md +37 -11
- package/docs/en/19_EXTERNAL_CONTROLLER_GUIDE.md +226 -0
- package/docs/en/19_LOCAL_BROWSER_AUTH.md +70 -0
- package/docs/en/20_WORKSPACE_MODES_GUIDE.md +250 -0
- package/docs/en/21_LOCAL_MODEL_BACKENDS_GUIDE.md +283 -0
- package/docs/en/91_DEVELOPMENT.md +237 -0
- package/docs/en/README.md +24 -2
- package/docs/zh/00_QUICK_START.md +89 -19
- package/docs/zh/01_SETTINGS_REFERENCE.md +34 -1
- package/docs/zh/02_START_RESEARCH_GUIDE.md +7 -0
- package/docs/zh/05_TUI_GUIDE.md +6 -0
- package/docs/zh/09_DOCTOR.md +26 -9
- package/docs/zh/14_PROMPT_SKILLS_AND_MCP_GUIDE.md +63 -13
- package/docs/zh/15_CODEX_PROVIDER_SETUP.md +37 -11
- package/docs/zh/19_EXTERNAL_CONTROLLER_GUIDE.md +226 -0
- package/docs/zh/19_LOCAL_BROWSER_AUTH.md +68 -0
- package/docs/zh/20_WORKSPACE_MODES_GUIDE.md +251 -0
- package/docs/zh/21_LOCAL_MODEL_BACKENDS_GUIDE.md +281 -0
- package/docs/zh/README.md +24 -2
- package/install.sh +46 -4
- package/package.json +2 -1
- package/pyproject.toml +1 -1
- package/src/deepscientist/__init__.py +1 -1
- package/src/deepscientist/acp/envelope.py +6 -0
- package/src/deepscientist/artifact/service.py +647 -22
- package/src/deepscientist/bash_exec/service.py +234 -9
- package/src/deepscientist/bridges/connectors.py +8 -2
- package/src/deepscientist/cli.py +115 -19
- package/src/deepscientist/codex_cli_compat.py +367 -22
- package/src/deepscientist/config/models.py +2 -1
- package/src/deepscientist/config/service.py +183 -13
- package/src/deepscientist/daemon/api/handlers.py +255 -31
- package/src/deepscientist/daemon/api/router.py +9 -0
- package/src/deepscientist/daemon/app.py +1146 -105
- package/src/deepscientist/diagnostics/__init__.py +6 -0
- package/src/deepscientist/diagnostics/runner_failures.py +130 -0
- package/src/deepscientist/doctor.py +207 -3
- package/src/deepscientist/gitops/__init__.py +10 -1
- package/src/deepscientist/gitops/diff.py +129 -0
- package/src/deepscientist/gitops/service.py +4 -1
- package/src/deepscientist/mcp/server.py +39 -0
- package/src/deepscientist/prompts/builder.py +275 -34
- package/src/deepscientist/quest/layout.py +15 -2
- package/src/deepscientist/quest/service.py +707 -55
- package/src/deepscientist/quest/stage_views.py +6 -1
- package/src/deepscientist/runners/codex.py +143 -43
- package/src/deepscientist/shared.py +19 -0
- package/src/deepscientist/skills/__init__.py +2 -2
- package/src/deepscientist/skills/installer.py +196 -5
- package/src/deepscientist/skills/registry.py +66 -0
- package/src/prompts/connectors/qq.md +18 -8
- package/src/prompts/connectors/weixin.md +16 -6
- package/src/prompts/contracts/shared_interaction.md +14 -2
- package/src/prompts/system.md +23 -5
- package/src/prompts/system_copilot.md +56 -0
- package/src/skills/analysis-campaign/SKILL.md +1 -0
- package/src/skills/baseline/SKILL.md +8 -0
- package/src/skills/decision/SKILL.md +8 -0
- package/src/skills/experiment/SKILL.md +8 -0
- package/src/skills/figure-polish/SKILL.md +1 -0
- package/src/skills/finalize/SKILL.md +1 -0
- package/src/skills/idea/SKILL.md +1 -0
- package/src/skills/intake-audit/SKILL.md +8 -0
- package/src/skills/mentor/SKILL.md +217 -0
- package/src/skills/mentor/references/correction-rules.md +210 -0
- package/src/skills/mentor/references/knowledge-profile.md +91 -0
- package/src/skills/mentor/references/persona-profile.md +138 -0
- package/src/skills/mentor/references/taste-profile.md +128 -0
- package/src/skills/mentor/references/thought-style-profile.md +138 -0
- package/src/skills/mentor/references/work-profile.md +289 -0
- package/src/skills/mentor/references/workflow-profile.md +240 -0
- package/src/skills/optimize/SKILL.md +1 -0
- package/src/skills/rebuttal/SKILL.md +1 -0
- package/src/skills/review/SKILL.md +1 -0
- package/src/skills/scout/SKILL.md +8 -0
- package/src/skills/write/SKILL.md +1 -0
- package/src/tui/dist/app/AppContainer.js +19 -11
- package/src/tui/dist/index.js +4 -1
- package/src/tui/dist/lib/api.js +33 -3
- package/src/tui/package.json +1 -1
- package/src/ui/dist/assets/AiManusChatView-Bv-Z8YpU.js +204 -0
- package/src/ui/dist/assets/AnalysisPlugin-BCKAfjba.js +1 -0
- package/src/ui/dist/assets/CliPlugin-BCKcpc35.js +109 -0
- package/src/ui/dist/assets/CodeEditorPlugin-DbOfSJ8K.js +2 -0
- package/src/ui/dist/assets/CodeViewerPlugin-CbaFRrUU.js +270 -0
- package/src/ui/dist/assets/DocViewerPlugin-DAjLVeQD.js +7 -0
- package/src/ui/dist/assets/GitCommitViewerPlugin-CIUqbUDO.js +1 -0
- package/src/ui/dist/assets/GitDiffViewerPlugin-CQACjoAA.js +6 -0
- package/src/ui/dist/assets/GitSnapshotViewer-0r4nLPke.js +30 -0
- package/src/ui/dist/assets/ImageViewerPlugin-nBOmI2v_.js +26 -0
- package/src/ui/dist/assets/LabCopilotPanel-BHxOxF4z.js +14 -0
- package/src/ui/dist/assets/LabPlugin-BKoZGs95.js +22 -0
- package/src/ui/dist/assets/LatexPlugin-ZwtV8pIp.js +25 -0
- package/src/ui/dist/assets/MarkdownViewerPlugin-DKqVfKyW.js +128 -0
- package/src/ui/dist/assets/MarketplacePlugin-BwxStZ9D.js +13 -0
- package/src/ui/dist/assets/NotebookEditor-BEQhaQbt.js +81 -0
- package/src/ui/dist/assets/{NotebookEditor-CccQYZjX.css → NotebookEditor-BHH8rdGj.css} +1 -1
- package/src/ui/dist/assets/NotebookEditor-BOr3x3Ej.css +1 -0
- package/src/ui/dist/assets/NotebookEditor-DB9N_T9q.js +361 -0
- package/src/ui/dist/assets/PdfLoader-Cy5jtWrr.css +1 -0
- package/src/ui/dist/assets/PdfLoader-eWBONbQP.js +16 -0
- package/src/ui/dist/assets/PdfMarkdownPlugin-D22YOZL3.js +1 -0
- package/src/ui/dist/assets/PdfViewerPlugin-c-RK9DLM.js +17 -0
- package/src/ui/dist/assets/PdfViewerPlugin-nwwE-fjJ.css +1 -0
- package/src/ui/dist/assets/SearchPlugin-CxF9ytAx.js +16 -0
- package/src/ui/dist/assets/SearchPlugin-DA4en4hK.css +1 -0
- package/src/ui/dist/assets/TextViewerPlugin-C5xqeeUH.js +54 -0
- package/src/ui/dist/assets/VNCViewer-BoLGLnHz.js +11 -0
- package/src/ui/dist/assets/bot-DREQOxzP.js +6 -0
- package/src/ui/dist/assets/browser-CTB2jwNe.js +8 -0
- package/src/ui/dist/assets/chevron-up-C9Qpx4DE.js +6 -0
- package/src/ui/dist/assets/code-WlFHE7z_.js +6 -0
- package/src/ui/dist/assets/file-content-BZMz3RYp.js +1 -0
- package/src/ui/dist/assets/file-diff-panel-CQhw0jS2.js +1 -0
- package/src/ui/dist/assets/file-jump-queue-DA-SdG__.js +1 -0
- package/src/ui/dist/assets/file-socket-CfQPKQKj.js +1 -0
- package/src/ui/dist/assets/git-commit-horizontal-DxZ8DCZh.js +6 -0
- package/src/ui/dist/assets/image-Bgl4VIyx.js +6 -0
- package/src/ui/dist/assets/index-BpV6lusQ.css +33 -0
- package/src/ui/dist/assets/index-CBNVuWcP.js +2496 -0
- package/src/ui/dist/assets/index-CwNu1aH4.js +11 -0
- package/src/ui/dist/assets/index-DrUnlf6K.js +1 -0
- package/src/ui/dist/assets/index-NW-h8VzN.js +1 -0
- package/src/ui/dist/assets/monaco-CiHMMNH_.js +1 -0
- package/src/ui/dist/assets/pdf-effect-queue-J8OnM0jE.js +6 -0
- package/src/ui/dist/assets/plugin-monaco-C8UgLomw.js +19 -0
- package/src/ui/dist/assets/plugin-notebook-HbW2K-1c.js +169 -0
- package/src/ui/dist/assets/plugin-pdf-CR8hgQBV.js +357 -0
- package/src/ui/dist/assets/plugin-terminal-MXFIPun8.js +227 -0
- package/src/ui/dist/assets/popover-CLc0pPP8.js +1 -0
- package/src/ui/dist/assets/project-sync-C9IdzdZW.js +1 -0
- package/src/ui/dist/assets/select-Cs2PmzwL.js +11 -0
- package/src/ui/dist/assets/sigma-ClKcHAXm.js +6 -0
- package/src/ui/dist/assets/trash-DwpbFr3w.js +11 -0
- package/src/ui/dist/assets/useCliAccess-NQ8m0Let.js +1 -0
- package/src/ui/dist/assets/useFileDiffOverlay-FuhcnKiw.js +1 -0
- package/src/ui/dist/assets/wrap-text-BC-Hltpd.js +11 -0
- package/src/ui/dist/assets/zoom-out-E_gaeAxL.js +11 -0
- package/src/ui/dist/index.html +5 -2
- package/src/ui/dist/assets/AiManusChatView-DDjbFnbt.js +0 -26597
- package/src/ui/dist/assets/AnalysisPlugin-Yb5IdmaU.js +0 -123
- package/src/ui/dist/assets/CliPlugin-e64sreyu.js +0 -31037
- package/src/ui/dist/assets/CodeEditorPlugin-C4D2TIkU.js +0 -427
- package/src/ui/dist/assets/CodeViewerPlugin-BVoNZIvC.js +0 -905
- package/src/ui/dist/assets/DocViewerPlugin-CLChbllo.js +0 -278
- package/src/ui/dist/assets/GitDiffViewerPlugin-C4xeFyFQ.js +0 -2661
- package/src/ui/dist/assets/ImageViewerPlugin-OiMUAcLi.js +0 -500
- package/src/ui/dist/assets/LabCopilotPanel-BjD2ThQF.js +0 -4104
- package/src/ui/dist/assets/LabPlugin-DQPg-NrB.js +0 -2677
- package/src/ui/dist/assets/LatexPlugin-CI05XAV9.js +0 -1792
- package/src/ui/dist/assets/MarkdownViewerPlugin-DpeBLYZf.js +0 -308
- package/src/ui/dist/assets/MarketplacePlugin-DolE58Q2.js +0 -413
- package/src/ui/dist/assets/NotebookEditor-7Qm2rSWD.js +0 -4214
- package/src/ui/dist/assets/NotebookEditor-C1kWaxKi.js +0 -84873
- package/src/ui/dist/assets/NotebookEditor-C3VQ7ylN.css +0 -1405
- package/src/ui/dist/assets/PdfLoader-BfOHw8Zw.js +0 -25468
- package/src/ui/dist/assets/PdfLoader-C-Y707R3.css +0 -49
- package/src/ui/dist/assets/PdfMarkdownPlugin-BulDREv1.js +0 -409
- package/src/ui/dist/assets/PdfViewerPlugin-C-daaOaL.js +0 -3095
- package/src/ui/dist/assets/PdfViewerPlugin-DQ11QcSf.css +0 -3627
- package/src/ui/dist/assets/SearchPlugin-CjpaiJ3A.js +0 -741
- package/src/ui/dist/assets/SearchPlugin-DDMrGDkh.css +0 -379
- package/src/ui/dist/assets/TextViewerPlugin-BxIyqPQC.js +0 -472
- package/src/ui/dist/assets/VNCViewer-HAg9mF7M.js +0 -18821
- package/src/ui/dist/assets/awareness-C0NPR2Dj.js +0 -292
- package/src/ui/dist/assets/bot-0DYntytV.js +0 -21
- package/src/ui/dist/assets/browser-BAcuE0Xj.js +0 -2895
- package/src/ui/dist/assets/code-B20Slj_w.js +0 -17
- package/src/ui/dist/assets/file-content-DT24KFma.js +0 -377
- package/src/ui/dist/assets/file-diff-panel-DK13YPql.js +0 -92
- package/src/ui/dist/assets/file-jump-queue-r5XKgJEV.js +0 -16
- package/src/ui/dist/assets/file-socket-B4T2o4nR.js +0 -58
- package/src/ui/dist/assets/function-B5QZkkHC.js +0 -1895
- package/src/ui/dist/assets/image-DSeR_sDS.js +0 -18
- package/src/ui/dist/assets/index-BrFje2Uk.js +0 -120
- package/src/ui/dist/assets/index-BwRJaoTl.js +0 -25
- package/src/ui/dist/assets/index-D_E4281X.js +0 -221322
- package/src/ui/dist/assets/index-DnYB3xb1.js +0 -159
- package/src/ui/dist/assets/index-G7AcWcMu.css +0 -12594
- package/src/ui/dist/assets/monaco-LExaAN3Y.js +0 -623
- package/src/ui/dist/assets/pdf-effect-queue-BJk5okWJ.js +0 -47
- package/src/ui/dist/assets/pdf_viewer-e0g1is2C.js +0 -8206
- package/src/ui/dist/assets/popover-D3Gg_FoV.js +0 -476
- package/src/ui/dist/assets/project-sync-C_ygLlVU.js +0 -297
- package/src/ui/dist/assets/select-CpAK6uWm.js +0 -1690
- package/src/ui/dist/assets/sigma-DEccaSgk.js +0 -22
- package/src/ui/dist/assets/square-check-big-uUfyVsbD.js +0 -17
- package/src/ui/dist/assets/trash-CXvwwSe8.js +0 -32
- package/src/ui/dist/assets/useCliAccess-Bnop4mgR.js +0 -957
- package/src/ui/dist/assets/useFileDiffOverlay-B8eUAX0I.js +0 -53
- package/src/ui/dist/assets/wrap-text-9vbOBpkW.js +0 -35
- package/src/ui/dist/assets/yjs-DncrqiZ8.js +0 -11243
- package/src/ui/dist/assets/zoom-out-BgVMmOW4.js +0 -34
|
@@ -4,13 +4,23 @@ import json
|
|
|
4
4
|
import os
|
|
5
5
|
import subprocess
|
|
6
6
|
import tempfile
|
|
7
|
-
from shutil import copy2
|
|
8
7
|
from copy import deepcopy
|
|
9
8
|
from pathlib import Path
|
|
10
9
|
from urllib.error import URLError
|
|
11
10
|
from urllib.request import Request
|
|
12
11
|
|
|
13
|
-
from ..codex_cli_compat import
|
|
12
|
+
from ..codex_cli_compat import (
|
|
13
|
+
active_provider_metadata_from_home,
|
|
14
|
+
adapt_profile_only_provider_config,
|
|
15
|
+
chat_wire_compatible_codex_version,
|
|
16
|
+
codex_cli_version,
|
|
17
|
+
format_codex_cli_version,
|
|
18
|
+
materialize_codex_runtime_home,
|
|
19
|
+
missing_provider_env_key,
|
|
20
|
+
missing_provider_env_key_from_text,
|
|
21
|
+
normalize_codex_reasoning_effort,
|
|
22
|
+
provider_base_url_looks_local,
|
|
23
|
+
)
|
|
14
24
|
from ..connector.connector_profiles import PROFILEABLE_CONNECTOR_NAMES, list_connector_profiles, normalize_connector_config
|
|
15
25
|
from ..connector_runtime import build_discovered_target, infer_connector_transport
|
|
16
26
|
from ..home import repo_root
|
|
@@ -1192,6 +1202,14 @@ Use **Test** when the file exposes runtime dependencies.
|
|
|
1192
1202
|
return "gpt-5.4"
|
|
1193
1203
|
return str(raw_model).strip()
|
|
1194
1204
|
|
|
1205
|
+
@staticmethod
|
|
1206
|
+
def _codex_effective_model(config: dict) -> str:
|
|
1207
|
+
requested = ConfigManager._codex_requested_model(config)
|
|
1208
|
+
profile = ConfigManager._codex_profile_name(config)
|
|
1209
|
+
if profile and not ConfigManager._codex_should_inherit_model(requested):
|
|
1210
|
+
return "inherit"
|
|
1211
|
+
return requested
|
|
1212
|
+
|
|
1195
1213
|
@staticmethod
|
|
1196
1214
|
def _codex_profile_name(config: dict) -> str:
|
|
1197
1215
|
raw_profile = config.get("profile")
|
|
@@ -1233,10 +1251,11 @@ Use **Test** when the file exposes runtime dependencies.
|
|
|
1233
1251
|
|
|
1234
1252
|
temp_home = tempfile.TemporaryDirectory(prefix="ds-codex-probe-")
|
|
1235
1253
|
temp_root = Path(temp_home.name)
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1254
|
+
materialize_codex_runtime_home(
|
|
1255
|
+
source_home=expanded,
|
|
1256
|
+
target_home=temp_root,
|
|
1257
|
+
profile=profile,
|
|
1258
|
+
)
|
|
1240
1259
|
write_text(temp_root / "config.toml", adapted_text)
|
|
1241
1260
|
return str(temp_root), warning, temp_home
|
|
1242
1261
|
|
|
@@ -1254,32 +1273,142 @@ Use **Test** when the file exposes runtime dependencies.
|
|
|
1254
1273
|
]
|
|
1255
1274
|
)
|
|
1256
1275
|
else:
|
|
1257
|
-
guidance.append("Run `codex
|
|
1276
|
+
guidance.append("Run `codex login` (or just `codex`) once and finish authentication before starting DeepScientist.")
|
|
1258
1277
|
guidance.append(
|
|
1259
1278
|
"If you use a custom Codex path, either set `runners.codex.binary` or launch with `ds --codex /absolute/path/to/codex`."
|
|
1260
1279
|
)
|
|
1261
1280
|
return guidance
|
|
1262
1281
|
|
|
1282
|
+
@staticmethod
|
|
1283
|
+
def _provider_profile_probe_hints(metadata: dict[str, object]) -> list[str]:
|
|
1284
|
+
base_url = str(metadata.get("base_url") or "").strip().lower()
|
|
1285
|
+
model = str(metadata.get("model") or "").strip().lower()
|
|
1286
|
+
provider = str(metadata.get("provider") or "").strip().lower()
|
|
1287
|
+
if "dashscope.aliyuncs.com" not in base_url and "bailian" not in provider and "qwen" not in model:
|
|
1288
|
+
return []
|
|
1289
|
+
if "coding.dashscope.aliyuncs.com" not in base_url:
|
|
1290
|
+
return [
|
|
1291
|
+
"Alibaba Bailian's generic DashScope / Qwen platform API is not supported by the Codex-backed DeepScientist path.",
|
|
1292
|
+
"If you want to use Qwen here, switch the profile to the Bailian Coding Plan endpoint: `https://coding.dashscope.aliyuncs.com/v1`.",
|
|
1293
|
+
]
|
|
1294
|
+
return [
|
|
1295
|
+
"For Qwen on Alibaba Bailian, only the Coding Plan endpoint is supported here; do not switch back to the generic Bailian / DashScope Qwen API.",
|
|
1296
|
+
]
|
|
1297
|
+
|
|
1298
|
+
@staticmethod
|
|
1299
|
+
def _local_provider_probe_hints(metadata: dict[str, object]) -> list[str]:
|
|
1300
|
+
base_url = str(metadata.get("base_url") or "").strip()
|
|
1301
|
+
wire_api = str(metadata.get("wire_api") or "").strip().lower()
|
|
1302
|
+
requires_openai_auth = metadata.get("requires_openai_auth")
|
|
1303
|
+
if not base_url:
|
|
1304
|
+
return []
|
|
1305
|
+
is_local_provider = provider_base_url_looks_local(base_url)
|
|
1306
|
+
if requires_openai_auth is not False and not is_local_provider:
|
|
1307
|
+
return []
|
|
1308
|
+
hints = [
|
|
1309
|
+
f"Verify the local provider directly: `curl {base_url}/models`.",
|
|
1310
|
+
f"Then verify the Responses API explicitly: `curl {base_url}/responses ...`.",
|
|
1311
|
+
"Latest Codex CLI requires `wire_api = \"responses\"`; chat-only provider configs are no longer accepted.",
|
|
1312
|
+
"If `/v1/chat/completions` works but `/v1/responses` fails, that backend is not currently compatible with the latest Codex runner.",
|
|
1313
|
+
"If the backend is chat-only and you still want to test it through Codex, try `@openai/codex@0.57.0` with top-level `model_provider` / `model` plus `wire_api = \"chat\"`.",
|
|
1314
|
+
"For local model backends, vLLM is the safest path. Ollama only works when its `/v1/responses` endpoint works; chat-only SGLang deployments will fail with the latest Codex.",
|
|
1315
|
+
]
|
|
1316
|
+
if requires_openai_auth is not False:
|
|
1317
|
+
hints.insert(
|
|
1318
|
+
0,
|
|
1319
|
+
"For local or self-hosted providers, add `requires_openai_auth = false` so DeepScientist can remove conflicting `OPENAI_*` auth variables.",
|
|
1320
|
+
)
|
|
1321
|
+
if not wire_api:
|
|
1322
|
+
hints.insert(0, "Your current provider config does not declare `wire_api`; set `wire_api = \"responses\"` first.")
|
|
1323
|
+
elif wire_api != "responses":
|
|
1324
|
+
hints.insert(0, f"Your current provider config uses `wire_api = \"{wire_api}\"`; switch it to `wire_api = \"responses\"` first.")
|
|
1325
|
+
return hints
|
|
1326
|
+
|
|
1327
|
+
@staticmethod
|
|
1328
|
+
def _missing_provider_env_guidance(
|
|
1329
|
+
*,
|
|
1330
|
+
profile: str,
|
|
1331
|
+
env_key: str,
|
|
1332
|
+
metadata: dict[str, object],
|
|
1333
|
+
) -> list[str]:
|
|
1334
|
+
guidance = [
|
|
1335
|
+
f"Set `runners.codex.env.{env_key}` in `~/DeepScientist/config/runners.yaml`, or export `{env_key}` before launching `ds`.",
|
|
1336
|
+
]
|
|
1337
|
+
if provider_base_url_looks_local(str(metadata.get("base_url") or "").strip()):
|
|
1338
|
+
guidance.append(
|
|
1339
|
+
f"If `{env_key}` is only a placeholder for a local OpenAI-compatible backend, any non-empty value such as `1234` is usually enough."
|
|
1340
|
+
)
|
|
1341
|
+
if metadata.get("requires_openai_auth") is not False:
|
|
1342
|
+
guidance.append(
|
|
1343
|
+
"Also add `requires_openai_auth = false` to that local provider profile so DeepScientist can remove conflicting `OPENAI_*` auth variables."
|
|
1344
|
+
)
|
|
1345
|
+
guidance.append(
|
|
1346
|
+
f"Before retrying DeepScientist, run a real request such as `codex exec --profile {profile} --json --cd /tmp --skip-git-repo-check -` and verify it returns `HELLO`."
|
|
1347
|
+
)
|
|
1348
|
+
return guidance
|
|
1349
|
+
|
|
1350
|
+
@staticmethod
|
|
1351
|
+
def _chat_wire_probe_version_block(
|
|
1352
|
+
metadata: dict[str, object],
|
|
1353
|
+
*,
|
|
1354
|
+
resolved_binary: str,
|
|
1355
|
+
) -> tuple[tuple[int, int, int] | None, dict[str, object] | None]:
|
|
1356
|
+
wire_api = str(metadata.get("wire_api") or "").strip().lower()
|
|
1357
|
+
if wire_api != "chat":
|
|
1358
|
+
return None, None
|
|
1359
|
+
detected_version = codex_cli_version(str(resolved_binary or ""))
|
|
1360
|
+
required_version = chat_wire_compatible_codex_version()
|
|
1361
|
+
if detected_version == required_version:
|
|
1362
|
+
return detected_version, None
|
|
1363
|
+
required_text = format_codex_cli_version(required_version)
|
|
1364
|
+
detected_text = format_codex_cli_version(detected_version)
|
|
1365
|
+
errors = [
|
|
1366
|
+
"This provider uses `wire_api = \"chat\"`, but DeepScientist only probes chat-mode providers with `codex-cli 0.57.0`.",
|
|
1367
|
+
]
|
|
1368
|
+
if detected_text:
|
|
1369
|
+
errors.append(f"Detected Codex CLI version: `{detected_text}`.")
|
|
1370
|
+
else:
|
|
1371
|
+
errors.append("DeepScientist could not determine the active Codex CLI version from the configured binary.")
|
|
1372
|
+
guidance = [
|
|
1373
|
+
"Install `npm install -g @openai/codex@0.57.0`, or point DeepScientist at a dedicated `0.57.0` binary with `ds --codex /absolute/path/to/codex`.",
|
|
1374
|
+
"If you want to stay on a newer Codex CLI, switch the provider/backend to `wire_api = \"responses\"` instead.",
|
|
1375
|
+
"For chat-mode fallback configs, keep the compatible top-level `model_provider` / `model` entries in `~/.codex/config.toml`.",
|
|
1376
|
+
]
|
|
1377
|
+
return (
|
|
1378
|
+
detected_version,
|
|
1379
|
+
{
|
|
1380
|
+
"summary": f"Codex startup probe blocked by chat-mode provider compatibility. Required Codex CLI: `{required_text}`.",
|
|
1381
|
+
"errors": errors,
|
|
1382
|
+
"guidance": guidance,
|
|
1383
|
+
},
|
|
1384
|
+
)
|
|
1385
|
+
|
|
1263
1386
|
def _codex_probe_failure_guidance(self, config: dict) -> tuple[list[str], list[str]]:
|
|
1264
1387
|
profile = self._codex_profile_name(config)
|
|
1388
|
+
config_dir = str(config.get("config_dir") or "~/.codex").strip()
|
|
1389
|
+
metadata = active_provider_metadata_from_home(config_dir, profile=profile or None) if config_dir else {}
|
|
1265
1390
|
if profile:
|
|
1391
|
+
provider_hints = self._provider_profile_probe_hints(metadata)
|
|
1392
|
+
local_hints = self._local_provider_probe_hints(metadata)
|
|
1266
1393
|
return (
|
|
1267
1394
|
[
|
|
1268
1395
|
f"Codex profile `{profile}` did not complete the startup hello probe successfully.",
|
|
1269
1396
|
],
|
|
1270
1397
|
[
|
|
1271
|
-
f"Run `codex --profile {profile}
|
|
1398
|
+
f"Run `codex exec --profile {profile} --json --cd /tmp --skip-git-repo-check -` in a terminal and confirm that a real `HELLO` request succeeds.",
|
|
1272
1399
|
"If the profile uses a custom provider, make sure its API key, Base URL, and model configuration are available to Codex.",
|
|
1273
1400
|
"If the provider expects the model from the Codex profile itself, set `model: inherit` in `~/DeepScientist/config/runners.yaml`.",
|
|
1401
|
+
*provider_hints,
|
|
1402
|
+
*local_hints,
|
|
1274
1403
|
"Then run `ds doctor` and start DeepScientist again.",
|
|
1275
1404
|
],
|
|
1276
1405
|
)
|
|
1277
1406
|
return (
|
|
1278
1407
|
[
|
|
1279
|
-
"Run `codex
|
|
1408
|
+
"Run `codex login` (or just `codex`) once and complete login before starting DeepScientist.",
|
|
1280
1409
|
],
|
|
1281
1410
|
[
|
|
1282
|
-
"Run `codex
|
|
1411
|
+
"Run `codex login` (or just `codex`) in a terminal and complete login or first-run setup.",
|
|
1283
1412
|
"If `codex` is missing, install it explicitly with `npm install -g @openai/codex`.",
|
|
1284
1413
|
"If the configured model is not available to your Codex account, update `~/DeepScientist/config/runners.yaml` and try again.",
|
|
1285
1414
|
"Then run `ds doctor` and start DeepScientist again.",
|
|
@@ -1361,6 +1490,7 @@ Use **Test** when the file exposes runtime dependencies.
|
|
|
1361
1490
|
resolved_binary = resolve_runner_binary(binary, runner_name="codex")
|
|
1362
1491
|
profile = self._codex_profile_name(config)
|
|
1363
1492
|
requested_model = self._codex_requested_model(config)
|
|
1493
|
+
effective_model = self._codex_effective_model(config)
|
|
1364
1494
|
raw_reasoning_effort = config.get("model_reasoning_effort")
|
|
1365
1495
|
requested_reasoning_effort = (
|
|
1366
1496
|
str(raw_reasoning_effort).strip()
|
|
@@ -1376,9 +1506,9 @@ Use **Test** when the file exposes runtime dependencies.
|
|
|
1376
1506
|
"resolved_binary": resolved_binary,
|
|
1377
1507
|
"config_dir": str(config.get("config_dir") or "~/.codex"),
|
|
1378
1508
|
"profile": profile,
|
|
1379
|
-
"model":
|
|
1509
|
+
"model": effective_model or "inherit",
|
|
1380
1510
|
"requested_model": requested_model or "inherit",
|
|
1381
|
-
"effective_model":
|
|
1511
|
+
"effective_model": effective_model or "inherit",
|
|
1382
1512
|
"approval_policy": str(config.get("approval_policy") or "on-request"),
|
|
1383
1513
|
"sandbox_mode": str(config.get("sandbox_mode") or "workspace-write"),
|
|
1384
1514
|
"reasoning_effort": reasoning_effort,
|
|
@@ -1416,10 +1546,37 @@ Use **Test** when the file exposes runtime dependencies.
|
|
|
1416
1546
|
env["CODEX_HOME"] = prepared_home
|
|
1417
1547
|
if profile_config_warning:
|
|
1418
1548
|
compatibility_warnings.append(profile_config_warning)
|
|
1549
|
+
metadata = active_provider_metadata_from_home(env.get("CODEX_HOME") or config_dir, profile=profile or None)
|
|
1550
|
+
if metadata.get("requires_openai_auth") is False:
|
|
1551
|
+
env.pop("OPENAI_API_KEY", None)
|
|
1552
|
+
env.pop("OPENAI_BASE_URL", None)
|
|
1553
|
+
configured_provider_env_key = missing_provider_env_key(metadata, env)
|
|
1554
|
+
details["provider_env_key"] = str(metadata.get("env_key") or "").strip() or None
|
|
1555
|
+
details["provider_env_missing"] = bool(configured_provider_env_key)
|
|
1556
|
+
details["provider_wire_api"] = str(metadata.get("wire_api") or "").strip() or None
|
|
1557
|
+
detected_codex_version, chat_wire_block = self._chat_wire_probe_version_block(
|
|
1558
|
+
metadata,
|
|
1559
|
+
resolved_binary=resolved_binary,
|
|
1560
|
+
)
|
|
1561
|
+
if detected_codex_version is not None:
|
|
1562
|
+
details["codex_cli_version"] = format_codex_cli_version(detected_codex_version) or None
|
|
1419
1563
|
prompt = "Reply with exactly HELLO."
|
|
1420
1564
|
if reasoning_effort_warning:
|
|
1421
1565
|
compatibility_warnings.append(reasoning_effort_warning)
|
|
1566
|
+
if profile and effective_model == "inherit" and not self._codex_should_inherit_model(requested_model):
|
|
1567
|
+
compatibility_warnings.append(
|
|
1568
|
+
f"Codex profile `{profile}` is provider-backed. DeepScientist is probing it with `model: inherit`."
|
|
1569
|
+
)
|
|
1422
1570
|
base_warnings: list[str] = list(compatibility_warnings)
|
|
1571
|
+
if chat_wire_block is not None:
|
|
1572
|
+
return {
|
|
1573
|
+
"ok": False,
|
|
1574
|
+
"summary": str(chat_wire_block["summary"]),
|
|
1575
|
+
"warnings": base_warnings,
|
|
1576
|
+
"errors": list(chat_wire_block["errors"]),
|
|
1577
|
+
"details": details,
|
|
1578
|
+
"guidance": list(chat_wire_block["guidance"]),
|
|
1579
|
+
}
|
|
1423
1580
|
|
|
1424
1581
|
def run_probe_once(model_for_command: str) -> tuple[list[str], subprocess.CompletedProcess[str] | None, subprocess.TimeoutExpired | None]:
|
|
1425
1582
|
command = self._build_codex_probe_command(
|
|
@@ -1445,7 +1602,7 @@ Use **Test** when the file exposes runtime dependencies.
|
|
|
1445
1602
|
return command, None, exc
|
|
1446
1603
|
return command, result, None
|
|
1447
1604
|
|
|
1448
|
-
command, result, timeout_error = run_probe_once(
|
|
1605
|
+
command, result, timeout_error = run_probe_once(effective_model)
|
|
1449
1606
|
if timeout_error is not None:
|
|
1450
1607
|
details.update(
|
|
1451
1608
|
{
|
|
@@ -1546,7 +1703,20 @@ Use **Test** when the file exposes runtime dependencies.
|
|
|
1546
1703
|
if details.get("model_fallback_attempted") and not details.get("model_fallback_used"):
|
|
1547
1704
|
warnings.append("DeepScientist also tried the current Codex default model, but that fallback probe did not succeed.")
|
|
1548
1705
|
errors.extend(self._codex_probe_failure_guidance(config)[0])
|
|
1706
|
+
missing_env_key = missing_provider_env_key_from_text(stdout_text, stderr_text) or configured_provider_env_key
|
|
1549
1707
|
failure_guidance = self._codex_probe_failure_guidance(config)[1]
|
|
1708
|
+
if not ok and missing_env_key and profile:
|
|
1709
|
+
errors.append(
|
|
1710
|
+
f"Codex profile `{profile}` requires environment variable `{missing_env_key}`, but DeepScientist did not receive it."
|
|
1711
|
+
)
|
|
1712
|
+
failure_guidance = [
|
|
1713
|
+
*self._missing_provider_env_guidance(
|
|
1714
|
+
profile=profile,
|
|
1715
|
+
env_key=missing_env_key,
|
|
1716
|
+
metadata=metadata,
|
|
1717
|
+
),
|
|
1718
|
+
*failure_guidance,
|
|
1719
|
+
]
|
|
1550
1720
|
return {
|
|
1551
1721
|
"ok": ok,
|
|
1552
1722
|
"summary": "Codex startup probe completed." if ok else "Codex startup probe failed.",
|