@researai/deepscientist 1.5.17 → 1.6.0
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 +309 -130
- package/AISB/catalog/aisb.b1.agentic_coding.yaml +244 -0
- package/AISB/catalog/aisb.b10.climate_earth.yaml +235 -0
- package/AISB/catalog/aisb.b11.model_efficiency.yaml +231 -0
- package/AISB/catalog/aisb.b12.embodied_ai.yaml +238 -0
- package/AISB/catalog/aisb.b2.agent_systems.yaml +229 -0
- package/AISB/catalog/aisb.b3.self_evolving_rl.yaml +237 -0
- package/AISB/catalog/aisb.b4.lm_reasoning.yaml +240 -0
- package/AISB/catalog/aisb.b5.math_proof.yaml +235 -0
- package/AISB/catalog/aisb.b6.research_process.yaml +243 -0
- package/AISB/catalog/aisb.b7.multimodal_fusion.yaml +232 -0
- package/AISB/catalog/aisb.b8.lifesci_drug.yaml +275 -0
- package/AISB/catalog/aisb.b9.material_science.yaml +237 -0
- package/AISB/catalog/aisb.t3.001_savvy.yaml +159 -0
- package/AISB/catalog/aisb.t3.001_savvy.zh.yaml +121 -0
- package/AISB/catalog/aisb.t3.002_pinet.yaml +189 -0
- package/AISB/catalog/aisb.t3.002_pinet.zh.yaml +130 -0
- package/AISB/catalog/aisb.t3.004_decentralattn.yaml +184 -0
- package/AISB/catalog/aisb.t3.004_decentralattn.zh.yaml +153 -0
- package/AISB/catalog/aisb.t3.005_tsae.yaml +193 -0
- package/AISB/catalog/aisb.t3.005_tsae.zh.yaml +139 -0
- package/AISB/catalog/aisb.t3.006_physense.yaml +194 -0
- package/AISB/catalog/aisb.t3.006_physense.zh.yaml +118 -0
- package/AISB/catalog/aisb.t3.007_reasoningiqa.yaml +169 -0
- package/AISB/catalog/aisb.t3.007_reasoningiqa.zh.yaml +133 -0
- package/AISB/catalog/aisb.t3.008_meanflows.yaml +188 -0
- package/AISB/catalog/aisb.t3.008_meanflows.zh.yaml +140 -0
- package/AISB/catalog/aisb.t3.009_scoremissing.yaml +179 -0
- package/AISB/catalog/aisb.t3.009_scoremissing.zh.yaml +119 -0
- package/AISB/catalog/aisb.t3.010_suitabilityfilter.yaml +221 -0
- package/AISB/catalog/aisb.t3.010_suitabilityfilter.zh.yaml +141 -0
- package/AISB/catalog/aisb.t3.011_osd.yaml +206 -0
- package/AISB/catalog/aisb.t3.011_osd.zh.yaml +163 -0
- package/AISB/catalog/aisb.t3.012_efficientqat.yaml +206 -0
- package/AISB/catalog/aisb.t3.012_efficientqat.zh.yaml +159 -0
- package/AISB/catalog/aisb.t3.013_appl.yaml +152 -0
- package/AISB/catalog/aisb.t3.013_appl.zh.yaml +126 -0
- package/AISB/catalog/aisb.t3.014_piguard.yaml +207 -0
- package/AISB/catalog/aisb.t3.014_piguard.zh.yaml +164 -0
- package/AISB/catalog/aisb.t3.015_frspec.yaml +209 -0
- package/AISB/catalog/aisb.t3.015_frspec.zh.yaml +163 -0
- package/AISB/catalog/aisb.t3.016_mathfusion.yaml +166 -0
- package/AISB/catalog/aisb.t3.016_mathfusion.zh.yaml +145 -0
- package/AISB/catalog/aisb.t3.017_multimodalglp.yaml +171 -0
- package/AISB/catalog/aisb.t3.017_multimodalglp.zh.yaml +122 -0
- package/AISB/catalog/aisb.t3.018_cotsynth.yaml +206 -0
- package/AISB/catalog/aisb.t3.018_cotsynth.zh.yaml +162 -0
- package/AISB/catalog/aisb.t3.019_dyscaleut.yaml +211 -0
- package/AISB/catalog/aisb.t3.019_dyscaleut.zh.yaml +148 -0
- package/AISB/catalog/aisb.t3.020_aristotle.yaml +173 -0
- package/AISB/catalog/aisb.t3.020_aristotle.zh.yaml +119 -0
- package/AISB/catalog/aisb.t3.021_tokenrecycling.yaml +160 -0
- package/AISB/catalog/aisb.t3.021_tokenrecycling.zh.yaml +129 -0
- package/AISB/catalog/aisb.t3.022_chainofreasoning.yaml +204 -0
- package/AISB/catalog/aisb.t3.022_chainofreasoning.zh.yaml +161 -0
- package/AISB/catalog/aisb.t3.023_guidedembed.yaml +211 -0
- package/AISB/catalog/aisb.t3.023_guidedembed.zh.yaml +189 -0
- package/AISB/catalog/aisb.t3.024_outputcentric.yaml +148 -0
- package/AISB/catalog/aisb.t3.024_outputcentric.zh.yaml +131 -0
- package/AISB/catalog/aisb.t3.025_deeper.yaml +143 -0
- package/AISB/catalog/aisb.t3.025_deeper.zh.yaml +116 -0
- package/AISB/catalog/aisb.t3.026_gartkg.yaml +195 -0
- package/AISB/catalog/aisb.t3.026_gartkg.zh.yaml +127 -0
- package/AISB/catalog/aisb.t3.027_citeeval.yaml +182 -0
- package/AISB/catalog/aisb.t3.027_citeeval.zh.yaml +135 -0
- package/AISB/catalog/aisb.t3.028_sbam.yaml +206 -0
- package/AISB/catalog/aisb.t3.028_sbam.zh.yaml +166 -0
- package/AISB/catalog/aisb.t3.029_cdqgeoembed.yaml +224 -0
- package/AISB/catalog/aisb.t3.029_cdqgeoembed.zh.yaml +142 -0
- package/AISB/catalog/aisb.t3.030_processrm.yaml +211 -0
- package/AISB/catalog/aisb.t3.030_processrm.zh.yaml +166 -0
- package/AISB/catalog/aisb.t3.031_circuitstability.yaml +172 -0
- package/AISB/catalog/aisb.t3.031_circuitstability.zh.yaml +134 -0
- package/AISB/catalog/aisb.t3.032_ptsolver.yaml +169 -0
- package/AISB/catalog/aisb.t3.032_ptsolver.zh.yaml +135 -0
- package/AISB/catalog/aisb.t3.033_gcse.yaml +144 -0
- package/AISB/catalog/aisb.t3.033_gcse.zh.yaml +126 -0
- package/AISB/catalog/aisb.t3.034_ensemblewm.yaml +183 -0
- package/AISB/catalog/aisb.t3.034_ensemblewm.zh.yaml +146 -0
- package/AISB/catalog/aisb.t3.035_moralvalueswa.yaml +207 -0
- package/AISB/catalog/aisb.t3.035_moralvalueswa.zh.yaml +165 -0
- package/AISB/catalog/aisb.t3.036_weakstrongpref.yaml +210 -0
- package/AISB/catalog/aisb.t3.036_weakstrongpref.zh.yaml +194 -0
- package/AISB/catalog/aisb.t3.037_dementiamask.yaml +172 -0
- package/AISB/catalog/aisb.t3.037_dementiamask.zh.yaml +132 -0
- package/AISB/catalog/aisb.t3.038_tinysam.yaml +284 -0
- package/AISB/catalog/aisb.t3.038_tinysam.zh.yaml +240 -0
- package/AISB/catalog/aisb.t3.039_calf.yaml +224 -0
- package/AISB/catalog/aisb.t3.039_calf.zh.yaml +194 -0
- package/AISB/catalog/aisb.t3.040_graniteguardian.yaml +199 -0
- package/AISB/catalog/aisb.t3.040_graniteguardian.zh.yaml +174 -0
- package/AISB/catalog/aisb.t3.041_amdm.yaml +149 -0
- package/AISB/catalog/aisb.t3.041_amdm.zh.yaml +137 -0
- package/AISB/catalog/aisb.t3.042_xpatch.yaml +216 -0
- package/AISB/catalog/aisb.t3.042_xpatch.zh.yaml +182 -0
- package/AISB/catalog/aisb.t3.043_vhm.yaml +268 -0
- package/AISB/catalog/aisb.t3.043_vhm.zh.yaml +193 -0
- package/AISB/catalog/aisb.t3.044_rgvi.yaml +224 -0
- package/AISB/catalog/aisb.t3.044_rgvi.zh.yaml +176 -0
- package/AISB/catalog/aisb.t3.045_pslstm.yaml +203 -0
- package/AISB/catalog/aisb.t3.045_pslstm.zh.yaml +179 -0
- package/AISB/catalog/aisb.t3.046_nonstatts.yaml +208 -0
- package/AISB/catalog/aisb.t3.046_nonstatts.zh.yaml +194 -0
- package/AISB/catalog/aisb.t3.047_timepfn.yaml +156 -0
- package/AISB/catalog/aisb.t3.047_timepfn.zh.yaml +124 -0
- package/AISB/catalog/aisb.t3.048_proxyspex.yaml +148 -0
- package/AISB/catalog/aisb.t3.048_proxyspex.zh.yaml +125 -0
- package/AISB/catalog/aisb.t3.049_hogwildinference.yaml +183 -0
- package/AISB/catalog/aisb.t3.049_hogwildinference.zh.yaml +138 -0
- package/AISB/catalog/aisb.t3.050_causalpfn.yaml +214 -0
- package/AISB/catalog/aisb.t3.050_causalpfn.zh.yaml +190 -0
- package/AISB/catalog/aisb.t3.051_flashtp.yaml +169 -0
- package/AISB/catalog/aisb.t3.051_flashtp.zh.yaml +124 -0
- package/AISB/catalog/aisb.t3.052_nsdiff.yaml +155 -0
- package/AISB/catalog/aisb.t3.052_nsdiff.zh.yaml +138 -0
- package/AISB/catalog/aisb.t3.053_k2vae.yaml +158 -0
- package/AISB/catalog/aisb.t3.053_k2vae.zh.yaml +132 -0
- package/AISB/catalog/aisb.t3.054_timebase.yaml +178 -0
- package/AISB/catalog/aisb.t3.054_timebase.zh.yaml +158 -0
- package/AISB/catalog/aisb.t3.055_csbrain.yaml +238 -0
- package/AISB/catalog/aisb.t3.055_csbrain.zh.yaml +184 -0
- package/AISB/catalog/aisb.t3.056_infosam.yaml +224 -0
- package/AISB/catalog/aisb.t3.056_infosam.zh.yaml +189 -0
- package/AISB/catalog/aisb.t3.057_mdreid.yaml +129 -0
- package/AISB/catalog/aisb.t3.057_mdreid.zh.yaml +117 -0
- package/AISB/catalog/aisb.t3.058_mindglitch.yaml +171 -0
- package/AISB/catalog/aisb.t3.058_mindglitch.zh.yaml +145 -0
- package/AISB/catalog/aisb.t3.059_selfsupervised.yaml +154 -0
- package/AISB/catalog/aisb.t3.059_selfsupervised.zh.yaml +125 -0
- package/AISB/catalog/aisb.t3.060_iaggad.yaml +121 -0
- package/AISB/catalog/aisb.t3.060_iaggad.zh.yaml +100 -0
- package/AISB/catalog/aisb.t3.061_hsgkn.yaml +136 -0
- package/AISB/catalog/aisb.t3.061_hsgkn.zh.yaml +113 -0
- package/AISB/catalog/aisb.t3.062_visionts.yaml +237 -0
- package/AISB/catalog/aisb.t3.062_visionts.zh.yaml +216 -0
- package/AISB/catalog/aisb.t3.063_tsrag.yaml +162 -0
- package/AISB/catalog/aisb.t3.063_tsrag.zh.yaml +138 -0
- package/AISB/catalog/aisb.t3.064_pir.yaml +221 -0
- package/AISB/catalog/aisb.t3.064_pir.zh.yaml +197 -0
- package/AISB/catalog/aisb.t3.065_proteinbinding.yaml +234 -0
- package/AISB/catalog/aisb.t3.065_proteinbinding.zh.yaml +167 -0
- package/AISB/catalog/aisb.t3.066_tropicalattention.yaml +267 -0
- package/AISB/catalog/aisb.t3.066_tropicalattention.zh.yaml +229 -0
- package/AISB/catalog/aisb.t3.067_kanad.yaml +193 -0
- package/AISB/catalog/aisb.t3.067_kanad.zh.yaml +167 -0
- package/AISB/catalog/aisb.t3.068_sempo.yaml +187 -0
- package/AISB/catalog/aisb.t3.068_sempo.zh.yaml +148 -0
- package/AISB/catalog/aisb.t3.069_treehfd.yaml +129 -0
- package/AISB/catalog/aisb.t3.069_treehfd.zh.yaml +111 -0
- package/AISB/catalog/aisb.t3.070_certifiedunlearning.yaml +224 -0
- package/AISB/catalog/aisb.t3.070_certifiedunlearning.zh.yaml +171 -0
- package/AISB/catalog/aisb.t3.071_neuralmjd.yaml +142 -0
- package/AISB/catalog/aisb.t3.071_neuralmjd.zh.yaml +120 -0
- package/AISB/catalog/aisb.t3.072_fedgmt.yaml +181 -0
- package/AISB/catalog/aisb.t3.072_fedgmt.zh.yaml +158 -0
- package/AISB/catalog/aisb.t3.073_rld.yaml +161 -0
- package/AISB/catalog/aisb.t3.073_rld.zh.yaml +129 -0
- package/AISB/catalog/aisb.t3.074_lsvi.yaml +163 -0
- package/AISB/catalog/aisb.t3.074_lsvi.zh.yaml +129 -0
- package/AISB/catalog/aisb.t3.075_treeslicedentropy.yaml +201 -0
- package/AISB/catalog/aisb.t3.075_treeslicedentropy.zh.yaml +148 -0
- package/AISB/catalog/aisb.t3.076_aanet.yaml +169 -0
- package/AISB/catalog/aisb.t3.076_aanet.zh.yaml +129 -0
- package/AISB/catalog/aisb.t3.077_cmnn.yaml +199 -0
- package/AISB/catalog/aisb.t3.077_cmnn.zh.yaml +165 -0
- package/AISB/catalog/aisb.t3.078_conformalanomaly.yaml +146 -0
- package/AISB/catalog/aisb.t3.078_conformalanomaly.zh.yaml +117 -0
- package/AISB/catalog/aisb.t3.079_dpfkmeans.yaml +131 -0
- package/AISB/catalog/aisb.t3.079_dpfkmeans.zh.yaml +104 -0
- package/AISB/catalog/aisb.t3.080_latentscorereweight.yaml +169 -0
- package/AISB/catalog/aisb.t3.080_latentscorereweight.zh.yaml +123 -0
- package/AISB/catalog/aisb.t3.081_qmamba.yaml +150 -0
- package/AISB/catalog/aisb.t3.081_qmamba.zh.yaml +117 -0
- package/AISB/catalog/aisb.t3.082_onlinellmrouting.yaml +160 -0
- package/AISB/catalog/aisb.t3.082_onlinellmrouting.zh.yaml +133 -0
- package/AISB/catalog/aisb.t3.083_starformer.yaml +178 -0
- package/AISB/catalog/aisb.t3.083_starformer.zh.yaml +140 -0
- package/AISB/catalog/aisb.t3.084_ift.yaml +139 -0
- package/AISB/catalog/aisb.t3.084_ift.zh.yaml +111 -0
- package/AISB/catalog/aisb.t3.085_neuralsurv.yaml +183 -0
- package/AISB/catalog/aisb.t3.085_neuralsurv.zh.yaml +143 -0
- package/AISB/catalog/aisb.t3.086_stella.yaml +197 -0
- package/AISB/catalog/aisb.t3.086_stella.zh.yaml +142 -0
- package/AISB/catalog/aisb.t3.087_moses.yaml +167 -0
- package/AISB/catalog/aisb.t3.087_moses.zh.yaml +132 -0
- package/AISB/catalog/aisb.t3.088_channelnorm.yaml +140 -0
- package/AISB/catalog/aisb.t3.088_channelnorm.zh.yaml +109 -0
- package/AISB/catalog/aisb.t3.089_causalvelocity.yaml +730 -0
- package/AISB/catalog/aisb.t3.089_causalvelocity.zh.yaml +668 -0
- package/AISB/catalog/aisb.t3.090_rstib.yaml +144 -0
- package/AISB/catalog/aisb.t3.090_rstib.zh.yaml +109 -0
- package/AISB/catalog/aisb.t3.091_timeawarecausal.yaml +132 -0
- package/AISB/catalog/aisb.t3.091_timeawarecausal.zh.yaml +107 -0
- package/AISB/catalog/aisb.t3.092_kmeanslocalopt.yaml +138 -0
- package/AISB/catalog/aisb.t3.092_kmeanslocalopt.zh.yaml +110 -0
- package/AISB/catalog/aisb.t3.093_fedwmsam.yaml +134 -0
- package/AISB/catalog/aisb.t3.093_fedwmsam.zh.yaml +106 -0
- package/AISB/catalog/aisb.t3.094_boundre.yaml +147 -0
- package/AISB/catalog/aisb.t3.094_boundre.zh.yaml +114 -0
- package/AISB/catalog/aisb.t3.095_fastfeaturecp.yaml +153 -0
- package/AISB/catalog/aisb.t3.095_fastfeaturecp.zh.yaml +118 -0
- package/AISB/catalog/aisb.t3.096_m3svm.yaml +189 -0
- package/AISB/catalog/aisb.t3.096_m3svm.zh.yaml +149 -0
- package/AISB/catalog/aisb.t3.097_wassersteintl.yaml +212 -0
- package/AISB/catalog/aisb.t3.097_wassersteintl.zh.yaml +169 -0
- package/AISB/catalog/aisb.t3.098_xmahalanobis.yaml +171 -0
- package/AISB/catalog/aisb.t3.098_xmahalanobis.zh.yaml +127 -0
- package/AISB/catalog/aisb.t3.099_ollalanding.yaml +248 -0
- package/AISB/catalog/aisb.t3.099_ollalanding.zh.yaml +182 -0
- package/AISB/catalog/aisb.t3.100_invmissingdata.yaml +179 -0
- package/AISB/catalog/aisb.t3.100_invmissingdata.zh.yaml +150 -0
- package/AISB/catalog/aisb.t3.101_acia.yaml +164 -0
- package/AISB/catalog/aisb.t3.101_acia.zh.yaml +109 -0
- package/AISB/catalog/aisb.t3.102_stochasticff.yaml +178 -0
- package/AISB/catalog/aisb.t3.102_stochasticff.zh.yaml +130 -0
- package/AISB/catalog/aisb.t3.103_qdcp.yaml +150 -0
- package/AISB/catalog/aisb.t3.103_qdcp.zh.yaml +116 -0
- package/AISB/catalog/aisb.t3.104_balancedactiveinf.yaml +137 -0
- package/AISB/catalog/aisb.t3.104_balancedactiveinf.zh.yaml +104 -0
- package/AISB/catalog/aisb.t3.105_binaryclasseval.yaml +161 -0
- package/AISB/catalog/aisb.t3.105_binaryclasseval.zh.yaml +130 -0
- package/AISB/image/001_aisb.t3.001_savvy.jpg +0 -0
- package/AISB/image/002_aisb.t3.002_pinet.jpg +0 -0
- package/AISB/image/003_aisb.t3.003_dmsqd.jpg +0 -0
- package/AISB/image/004_aisb.t3.004_decentralattn.jpg +0 -0
- package/AISB/image/005_aisb.t3.005_tsae.jpg +0 -0
- package/AISB/image/006_aisb.t3.006_physense.jpg +0 -0
- package/AISB/image/007_aisb.t3.007_reasoningiqa.jpg +0 -0
- package/AISB/image/008_aisb.t3.008_meanflows.jpg +0 -0
- package/AISB/image/009_aisb.t3.009_scoremissing.jpg +0 -0
- package/AISB/image/010_aisb.t3.010_suitabilityfilter.jpg +0 -0
- package/AISB/image/011_aisb.t3.011_osd.jpg +0 -0
- package/AISB/image/012_aisb.t3.012_efficientqat.jpg +0 -0
- package/AISB/image/013_aisb.t3.013_appl.jpg +0 -0
- package/AISB/image/014_aisb.t3.014_piguard.jpg +0 -0
- package/AISB/image/015_aisb.t3.015_frspec.jpg +0 -0
- package/AISB/image/016_aisb.t3.016_mathfusion.jpg +0 -0
- package/AISB/image/017_aisb.t3.017_multimodalglp.jpg +0 -0
- package/AISB/image/018_aisb.t3.018_cotsynth.jpg +0 -0
- package/AISB/image/019_aisb.t3.019_dyscaleut.jpg +0 -0
- package/AISB/image/020_aisb.t3.020_aristotle.jpg +0 -0
- package/AISB/image/021_aisb.t3.021_tokenrecycling.jpg +0 -0
- package/AISB/image/022_aisb.t3.022_chainofreasoning.jpg +0 -0
- package/AISB/image/023_aisb.t3.023_guidedembed.jpg +0 -0
- package/AISB/image/024_aisb.t3.024_outputcentric.jpg +0 -0
- package/AISB/image/025_aisb.t3.025_deeper.jpg +0 -0
- package/AISB/image/026_aisb.t3.026_gartkg.jpg +0 -0
- package/AISB/image/027_aisb.t3.027_citeeval.jpg +0 -0
- package/AISB/image/028_aisb.t3.028_sbam.jpg +0 -0
- package/AISB/image/029_aisb.t3.029_cdqgeoembed.jpg +0 -0
- package/AISB/image/030_aisb.t3.030_processrm.jpg +0 -0
- package/AISB/image/031_aisb.t3.031_circuitstability.jpg +0 -0
- package/AISB/image/032_aisb.t3.032_ptsolver.jpg +0 -0
- package/AISB/image/033_aisb.t3.033_gcse.jpg +0 -0
- package/AISB/image/034_aisb.t3.034_ensemblewm.jpg +0 -0
- package/AISB/image/035_aisb.t3.035_moralvalueswa.jpg +0 -0
- package/AISB/image/036_aisb.t3.036_weakstrongpref.jpg +0 -0
- package/AISB/image/037_aisb.t3.037_dementiamask.jpg +0 -0
- package/AISB/image/038_aisb.t3.038_tinysam.jpg +0 -0
- package/AISB/image/039_aisb.t3.039_calf.jpg +0 -0
- package/AISB/image/040_aisb.t3.040_graniteguardian.jpg +0 -0
- package/AISB/image/041_aisb.t3.041_amdm.jpg +0 -0
- package/AISB/image/042_aisb.t3.042_xpatch.jpg +0 -0
- package/AISB/image/043_aisb.t3.043_vhm.jpg +0 -0
- package/AISB/image/044_aisb.t3.044_rgvi.jpg +0 -0
- package/AISB/image/045_aisb.t3.045_pslstm.jpg +0 -0
- package/AISB/image/046_aisb.t3.046_nonstatts.jpg +0 -0
- package/AISB/image/047_aisb.t3.047_timepfn.jpg +0 -0
- package/AISB/image/048_aisb.t3.048_proxyspex.jpg +0 -0
- package/AISB/image/049_aisb.t3.049_hogwildinference.jpg +0 -0
- package/AISB/image/050_aisb.t3.050_causalpfn.jpg +0 -0
- package/AISB/image/051_aisb.t3.051_flashtp.jpg +0 -0
- package/AISB/image/052_aisb.t3.052_nsdiff.jpg +0 -0
- package/AISB/image/053_aisb.t3.053_k2vae.jpg +0 -0
- package/AISB/image/054_aisb.t3.054_timebase.jpg +0 -0
- package/AISB/image/055_aisb.t3.055_csbrain.jpg +0 -0
- package/AISB/image/056_aisb.t3.056_infosam.jpg +0 -0
- package/AISB/image/057_aisb.t3.057_mdreid.jpg +0 -0
- package/AISB/image/058_aisb.t3.058_mindglitch.jpg +0 -0
- package/AISB/image/059_aisb.t3.059_selfsupervised.jpg +0 -0
- package/AISB/image/060_aisb.t3.060_iaggad.jpg +0 -0
- package/AISB/image/061_aisb.t3.061_hsgkn.jpg +0 -0
- package/AISB/image/062_aisb.t3.062_visionts.jpg +0 -0
- package/AISB/image/063_aisb.t3.063_tsrag.jpg +0 -0
- package/AISB/image/064_aisb.t3.064_pir.jpg +0 -0
- package/AISB/image/065_aisb.t3.065_proteinbinding.jpg +0 -0
- package/AISB/image/066_aisb.t3.066_tropicalattention.jpg +0 -0
- package/AISB/image/067_aisb.t3.067_kanad.jpg +0 -0
- package/AISB/image/068_aisb.t3.068_sempo.jpg +0 -0
- package/AISB/image/069_aisb.t3.069_treehfd.jpg +0 -0
- package/AISB/image/070_aisb.t3.070_certifiedunlearning.jpg +0 -0
- package/AISB/image/071_aisb.t3.071_neuralmjd.jpg +0 -0
- package/AISB/image/072_aisb.t3.072_fedgmt.jpg +0 -0
- package/AISB/image/073_aisb.t3.073_rld.jpg +0 -0
- package/AISB/image/074_aisb.t3.074_lsvi.jpg +0 -0
- package/AISB/image/075_aisb.t3.075_treeslicedentropy.jpg +0 -0
- package/AISB/image/076_aisb.t3.076_aanet.jpg +0 -0
- package/AISB/image/077_aisb.t3.077_cmnn.jpg +0 -0
- package/AISB/image/078_aisb.t3.078_conformalanomaly.jpg +0 -0
- package/AISB/image/079_aisb.t3.079_dpfkmeans.jpg +0 -0
- package/AISB/image/080_aisb.t3.080_latentscorereweight.jpg +0 -0
- package/AISB/image/081_aisb.t3.081_qmamba.jpg +0 -0
- package/AISB/image/082_aisb.t3.082_onlinellmrouting.jpg +0 -0
- package/AISB/image/083_aisb.t3.083_starformer.jpg +0 -0
- package/AISB/image/084_aisb.t3.084_ift.jpg +0 -0
- package/AISB/image/085_aisb.t3.085_neuralsurv.jpg +0 -0
- package/AISB/image/086_aisb.t3.086_stella.jpg +0 -0
- package/AISB/image/087_aisb.t3.087_moses.jpg +0 -0
- package/AISB/image/088_aisb.t3.088_channelnorm.jpg +0 -0
- package/AISB/image/089_aisb.t3.089_causalvelocity.jpg +0 -0
- package/AISB/image/090_aisb.t3.090_rstib.jpg +0 -0
- package/AISB/image/091_aisb.t3.091_timeawarecausal.jpg +0 -0
- package/AISB/image/092_aisb.t3.092_kmeanslocalopt.jpg +0 -0
- package/AISB/image/093_aisb.t3.093_fedwmsam.jpg +0 -0
- package/AISB/image/094_aisb.t3.094_boundre.jpg +0 -0
- package/AISB/image/095_aisb.t3.095_fastfeaturecp.jpg +0 -0
- package/AISB/image/096_aisb.t3.096_m3svm.jpg +0 -0
- package/AISB/image/097_aisb.t3.097_wassersteintl.jpg +0 -0
- package/AISB/image/098_aisb.t3.098_xmahalanobis.jpg +0 -0
- package/AISB/image/099_aisb.t3.099_ollalanding.jpg +0 -0
- package/AISB/image/100_aisb.t3.100_invmissingdata.jpg +0 -0
- package/AISB/image/101_aisb.t3.101_acia.jpg +0 -0
- package/AISB/image/102_aisb.t3.102_stochasticff.jpg +0 -0
- package/AISB/image/103_aisb.t3.103_qdcp.jpg +0 -0
- package/AISB/image/104_aisb.t3.104_balancedactiveinf.jpg +0 -0
- package/AISB/image/105_aisb.t3.105_binaryclasseval.jpg +0 -0
- package/AISB/image/106_aisb.t1.reasoning_lite.jpg +0 -0
- package/AISB/image/107_aisb.t2.paper_audit.jpg +0 -0
- package/AISB/image/108_aisb.t3.multi_gpu_search.jpg +0 -0
- package/AISB/image/109_aisb.t3.tdc_admet.jpg +0 -0
- package/AISB/image/aisb.b1.agentic_coding.svg +16 -0
- package/AISB/image/aisb.b10.climate_earth.svg +16 -0
- package/AISB/image/aisb.b11.model_efficiency.svg +16 -0
- package/AISB/image/aisb.b12.embodied_ai.svg +16 -0
- package/AISB/image/aisb.b2.agent_systems.svg +16 -0
- package/AISB/image/aisb.b3.self_evolving_rl.svg +16 -0
- package/AISB/image/aisb.b4.lm_reasoning.svg +16 -0
- package/AISB/image/aisb.b5.math_proof.svg +16 -0
- package/AISB/image/aisb.b6.research_process.svg +16 -0
- package/AISB/image/aisb.b7.multimodal_fusion.svg +16 -0
- package/AISB/image/aisb.b8.lifesci_drug.svg +16 -0
- package/AISB/image/aisb.b9.material_science.svg +16 -0
- package/README.md +132 -11
- package/bin/ds.js +376 -49
- package/docs/en/00_QUICK_START.md +135 -18
- package/docs/en/01_SETTINGS_REFERENCE.md +468 -96
- package/docs/en/02_START_RESEARCH_GUIDE.md +26 -5
- package/docs/en/03_QQ_CONNECTOR_GUIDE.md +14 -3
- package/docs/en/04_LINGZHU_CONNECTOR_GUIDE.md +2 -0
- package/docs/en/05_TUI_GUIDE.md +171 -2
- package/docs/en/07_MEMORY_AND_MCP.md +38 -2
- package/docs/en/09_DOCTOR.md +64 -4
- package/docs/en/10_WEIXIN_CONNECTOR_GUIDE.md +38 -1
- package/docs/en/11_LICENSE_AND_RISK.md +4 -0
- package/docs/en/12_GUIDED_WORKFLOW_TOUR.md +15 -0
- package/docs/en/14_PROMPT_SKILLS_AND_MCP_GUIDE.md +9 -0
- package/docs/en/15_CODEX_PROVIDER_SETUP.md +622 -187
- package/docs/en/16_TELEGRAM_CONNECTOR_GUIDE.md +14 -0
- package/docs/en/17_WHATSAPP_CONNECTOR_GUIDE.md +14 -0
- package/docs/en/18_FEISHU_CONNECTOR_GUIDE.md +14 -0
- package/docs/en/21_LOCAL_MODEL_BACKENDS_GUIDE.md +105 -2
- package/docs/en/22_BENCHSTORE_YAML_REFERENCE.md +469 -0
- package/docs/en/23_BENCHSTORE_GITHUB_RELEASES_SPEC.md +316 -0
- package/docs/en/24_CLAUDE_CODE_PROVIDER_SETUP.md +469 -0
- package/docs/en/25_OPENCODE_PROVIDER_SETUP.md +653 -0
- package/docs/en/26_CITATION_AND_ATTRIBUTION.md +119 -0
- package/docs/en/27_KIMI_CODE_PROVIDER_SETUP.md +180 -0
- package/docs/en/28_DISCORD_CONNECTOR_GUIDE.md +61 -0
- package/docs/en/29_SLACK_CONNECTOR_GUIDE.md +60 -0
- package/docs/en/30_SETTINGS_CONTROL_CENTER_GUIDE.md +371 -0
- package/docs/en/{19_LOCAL_BROWSER_AUTH.md → 31_LOCAL_BROWSER_AUTH.md} +1 -1
- package/docs/en/32_WINDOWS_WSL2_DEPLOYMENT_GUIDE.md +273 -0
- package/docs/en/33_WORKSPACE_EXPLORER_QA.md +121 -0
- package/docs/en/91_DEVELOPMENT.md +29 -0
- package/docs/en/99_ACKNOWLEDGEMENTS.md +24 -19
- package/docs/en/README.md +44 -7
- package/docs/images/admin/admin-connectors-health-en.png +0 -0
- package/docs/images/admin/admin-controllers-en.png +0 -0
- package/docs/images/admin/admin-diagnostics-en.png +0 -0
- package/docs/images/admin/admin-errors-en.png +0 -0
- package/docs/images/admin/admin-issues-en.png +0 -0
- package/docs/images/admin/admin-logs-en.png +0 -0
- package/docs/images/admin/admin-quest-detail-en.png +0 -0
- package/docs/images/admin/admin-quests-en.png +0 -0
- package/docs/images/admin/admin-repairs-en.png +0 -0
- package/docs/images/admin/admin-runtime-en.png +0 -0
- package/docs/images/admin/admin-search-en.png +0 -0
- package/docs/images/admin/admin-stats-en.png +0 -0
- package/docs/images/admin/admin-summary-en.png +0 -0
- package/docs/images/connectors/connector-discord-en.png +0 -0
- package/docs/images/connectors/connector-feishu-en.png +0 -0
- package/docs/images/connectors/connector-lingzhu-en.png +0 -0
- package/docs/images/connectors/connector-qq-en.png +0 -0
- package/docs/images/connectors/connector-slack-en.png +0 -0
- package/docs/images/connectors/connector-telegram-en.png +0 -0
- package/docs/images/connectors/connector-weixin-en.png +0 -0
- package/docs/images/connectors/connector-whatsapp-en.png +0 -0
- package/docs/images/settings/settings-baselines-en.png +0 -0
- package/docs/images/settings/settings-config-en.png +0 -0
- package/docs/images/settings/settings-connectors-overview-en.png +0 -0
- package/docs/images/settings/settings-deepxiv-en.png +0 -0
- package/docs/images/settings/settings-mcp-servers-en.png +0 -0
- package/docs/images/settings/settings-plugins-en.png +0 -0
- package/docs/images/settings/settings-runners-en.png +0 -0
- package/docs/zh/00_QUICK_START.md +92 -17
- package/docs/zh/01_SETTINGS_REFERENCE.md +219 -98
- package/docs/zh/02_START_RESEARCH_GUIDE.md +26 -5
- package/docs/zh/05_TUI_GUIDE.md +171 -2
- package/docs/zh/07_MEMORY_AND_MCP.md +29 -2
- package/docs/zh/09_DOCTOR.md +39 -4
- package/docs/zh/10_WEIXIN_CONNECTOR_GUIDE.md +24 -1
- package/docs/zh/11_LICENSE_AND_RISK.md +4 -0
- package/docs/zh/12_GUIDED_WORKFLOW_TOUR.md +15 -0
- package/docs/zh/14_PROMPT_SKILLS_AND_MCP_GUIDE.md +9 -0
- package/docs/zh/15_CODEX_PROVIDER_SETUP.md +550 -188
- package/docs/zh/21_LOCAL_MODEL_BACKENDS_GUIDE.md +105 -2
- package/docs/zh/22_BENCHSTORE_YAML_REFERENCE.md +459 -0
- package/docs/zh/23_BENCHSTORE_GITHUB_RELEASES_SPEC.md +287 -0
- package/docs/zh/23_CLAUDE_RUNNER_GUIDE.md +103 -0
- package/docs/zh/24_CLAUDE_CODE_PROVIDER_SETUP.md +460 -0
- package/docs/zh/25_OPENCODE_PROVIDER_SETUP.md +660 -0
- package/docs/zh/26_CITATION_AND_ATTRIBUTION.md +102 -0
- package/docs/zh/27_KIMI_CODE_PROVIDER_SETUP.md +51 -0
- package/docs/zh/{19_LOCAL_BROWSER_AUTH.md → 31_LOCAL_BROWSER_AUTH.md} +1 -1
- package/docs/zh/32_WINDOWS_WSL2_DEPLOYMENT_GUIDE.md +264 -0
- package/docs/zh/33_WORKSPACE_EXPLORER_QA.md +127 -0
- package/docs/zh/99_ACKNOWLEDGEMENTS.md +23 -19
- package/docs/zh/README.md +29 -7
- package/install.sh +122 -16
- package/package.json +4 -1
- package/pyproject.toml +2 -1
- package/src/deepscientist/__init__.py +1 -1
- package/src/deepscientist/acp/envelope.py +13 -0
- package/src/deepscientist/admin/__init__.py +3 -0
- package/src/deepscientist/admin/charts.py +681 -0
- package/src/deepscientist/admin/logs.py +119 -0
- package/src/deepscientist/admin/repairs.py +217 -0
- package/src/deepscientist/admin/service.py +1310 -0
- package/src/deepscientist/admin/system_info.py +700 -0
- package/src/deepscientist/admin/tasks.py +465 -0
- package/src/deepscientist/admin/tool_metrics.py +600 -0
- package/src/deepscientist/artifact/guidance.py +8 -4
- package/src/deepscientist/artifact/schemas.py +115 -0
- package/src/deepscientist/artifact/service.py +4268 -260
- package/src/deepscientist/bash_exec/monitor.py +30 -3
- package/src/deepscientist/bash_exec/service.py +134 -1
- package/src/deepscientist/benchstore/__init__.py +4 -0
- package/src/deepscientist/benchstore/prompt_builder.py +224 -0
- package/src/deepscientist/benchstore/service.py +1716 -0
- package/src/deepscientist/channels/weixin_ilink.py +8 -1
- package/src/deepscientist/cli.py +92 -17
- package/src/deepscientist/codex_cli_compat.py +2 -2
- package/src/deepscientist/config/models.py +82 -11
- package/src/deepscientist/config/service.py +927 -91
- package/src/deepscientist/connector/weixin_support.py +48 -17
- package/src/deepscientist/daemon/api/handlers.py +697 -210
- package/src/deepscientist/daemon/api/router.py +76 -1
- package/src/deepscientist/daemon/app.py +1054 -51
- package/src/deepscientist/diagnostics/runner_failures.py +147 -0
- package/src/deepscientist/doctor.py +212 -65
- package/src/deepscientist/evidence_packets.py +590 -0
- package/src/deepscientist/home.py +52 -4
- package/src/deepscientist/kimi_cli_compat.py +50 -0
- package/src/deepscientist/latex_runtime.py +2 -2
- package/src/deepscientist/mcp/context.py +2 -0
- package/src/deepscientist/mcp/schemas.py +114 -0
- package/src/deepscientist/mcp/server.py +1566 -126
- package/src/deepscientist/memory/service.py +203 -16
- package/src/deepscientist/process_control.py +8 -1
- package/src/deepscientist/prompts/builder.py +836 -92
- package/src/deepscientist/quest/__init__.py +2 -2
- package/src/deepscientist/quest/layout.py +12 -1
- package/src/deepscientist/quest/node_traces.py +10 -0
- package/src/deepscientist/quest/service.py +1430 -139
- package/src/deepscientist/quest/stage_views.py +1 -1
- package/src/deepscientist/runners/__init__.py +18 -0
- package/src/deepscientist/runners/base.py +89 -1
- package/src/deepscientist/runners/builtins.py +13 -1
- package/src/deepscientist/runners/claude.py +391 -0
- package/src/deepscientist/runners/codex.py +421 -21
- package/src/deepscientist/runners/codex_telemetry.py +127 -0
- package/src/deepscientist/runners/kimi.py +334 -0
- package/src/deepscientist/runners/metadata.py +68 -0
- package/src/deepscientist/runners/opencode.py +414 -0
- package/src/deepscientist/runners/runtime_overrides.py +100 -0
- package/src/deepscientist/runners/simple_cli.py +538 -0
- package/src/deepscientist/runtime_storage.py +303 -0
- package/src/deepscientist/shared.py +61 -16
- package/src/deepscientist/skills/installer.py +37 -0
- package/src/deepscientist/skills/registry.py +2 -0
- package/src/deepscientist/tinytex.py +2 -2
- package/src/deepscientist/tui.py +10 -3
- package/src/prompts/benchstore/system.md +77 -0
- package/src/prompts/connectors/qq.md +33 -2
- package/src/prompts/connectors/weixin.md +208 -23
- package/src/prompts/contracts/admin_ops.md +74 -0
- package/src/prompts/contracts/admin_ops_knowledge.md +138 -0
- package/src/prompts/contracts/shared_interaction.md +5 -11
- package/src/prompts/start_setup/system.md +422 -0
- package/src/prompts/system.md +409 -315
- package/src/prompts/system_copilot.md +88 -12
- package/src/skills/analysis-campaign/SKILL.md +239 -578
- package/src/skills/analysis-campaign/references/artifact-flow-examples.md +102 -0
- package/src/skills/analysis-campaign/references/boundary-cases.md +98 -0
- package/src/skills/analysis-campaign/references/campaign-checklist-template.md +39 -24
- package/src/skills/analysis-campaign/references/campaign-design.md +26 -10
- package/src/skills/analysis-campaign/references/campaign-plan-template.md +53 -54
- package/src/skills/analysis-campaign/references/operational-guidance.md +97 -0
- package/src/skills/analysis-campaign/references/writing-facing-slice-examples.md +10 -20
- package/src/skills/baseline/SKILL.md +183 -461
- package/src/skills/baseline/references/artifact-flow-examples.md +106 -0
- package/src/skills/baseline/references/artifact-payload-examples.md +1 -1
- package/src/skills/baseline/references/baseline-checklist-template.md +27 -35
- package/src/skills/baseline/references/baseline-plan-template.md +37 -76
- package/src/skills/baseline/references/boundary-cases.md +86 -0
- package/src/skills/baseline/references/codebase-audit-checklist.md +2 -6
- package/src/skills/baseline/references/comparability-contract.md +7 -12
- package/src/skills/baseline/references/operational-guidance.md +56 -0
- package/src/skills/baseline/references/route-selection.md +5 -25
- package/src/skills/decision/SKILL.md +113 -306
- package/src/skills/decision/references/checkpoint-memory-template.md +47 -0
- package/src/skills/decision/references/operational-guidance.md +94 -0
- package/src/skills/decision/references/research-route-criteria.md +7 -8
- package/src/skills/decision/references/strategic-decision-template.md +13 -26
- package/src/skills/experiment/SKILL.md +132 -670
- package/src/skills/experiment/references/execution-playbook.md +374 -0
- package/src/skills/experiment/references/main-experiment-checklist-template.md +26 -2
- package/src/skills/experiment/references/main-experiment-plan-template.md +28 -17
- package/src/skills/experiment/references/operational-guidance.md +108 -0
- package/src/skills/finalize/SKILL.md +62 -0
- package/src/skills/finalize/references/checkpoint-memory-template.md +49 -0
- package/src/skills/finalize/references/resume-packet-template.md +7 -0
- package/src/skills/idea/SKILL.md +228 -15
- package/src/skills/idea/references/controlled-brainstorming-playbook.md +78 -0
- package/src/skills/idea/references/current-board-packet-template.md +61 -0
- package/src/skills/idea/references/high-value-idea-sourcing.md +119 -0
- package/src/skills/idea/references/idea-generation-playbook.md +21 -0
- package/src/skills/idea/references/idea-thinking-flow.md +6 -0
- package/src/skills/idea/references/literature-survey-template.md +3 -0
- package/src/skills/idea/references/objective-contract-template.md +54 -0
- package/src/skills/idea/references/outline-seeding-example.md +56 -0
- package/src/skills/idea/references/pre-idea-draft-template.md +105 -0
- package/src/skills/idea/references/related-work-playbook.md +75 -2
- package/src/skills/idea/references/research-history-playbook.md +114 -0
- package/src/skills/idea/references/selection-gate.md +58 -6
- package/src/skills/intake-audit/SKILL.md +43 -2
- package/src/skills/intake-audit/references/state-audit-template.md +10 -0
- package/src/skills/nature-data/SKILL.md +128 -0
- package/src/skills/nature-data/UPSTREAM_LICENSE.txt +21 -0
- package/src/skills/nature-data/agents/openai.yaml +4 -0
- package/src/skills/nature-data/references/chinese-author-alignment.md +84 -0
- package/src/skills/nature-data/references/fair-metadata-checklist.md +105 -0
- package/src/skills/nature-data/references/policy-principles.md +103 -0
- package/src/skills/nature-data/references/repository-and-identifiers.md +96 -0
- package/src/skills/nature-data/references/source-basis.md +54 -0
- package/src/skills/nature-data/references/statement-patterns.md +153 -0
- package/src/skills/nature-figure/SKILL.md +197 -0
- package/src/skills/nature-figure/UPSTREAM_LICENSE.txt +21 -0
- package/src/skills/nature-figure/agents/openai.yaml +4 -0
- package/src/skills/nature-figure/evals/evals.json +37 -0
- package/src/skills/nature-figure/references/api.md +428 -0
- package/src/skills/nature-figure/references/backend-selection.md +100 -0
- package/src/skills/nature-figure/references/chart-types.md +281 -0
- package/src/skills/nature-figure/references/common-patterns.md +349 -0
- package/src/skills/nature-figure/references/design-theory.md +436 -0
- package/src/skills/nature-figure/references/figure-contract.md +93 -0
- package/src/skills/nature-figure/references/nature-2026-observations.md +112 -0
- package/src/skills/nature-figure/references/qa-contract.md +119 -0
- package/src/skills/nature-figure/references/r-template-index.md +66 -0
- package/src/skills/nature-figure/references/r-workflow.md +161 -0
- package/src/skills/nature-figure/references/tutorials.md +250 -0
- package/src/skills/nature-paper2ppt/SKILL.md +507 -0
- package/src/skills/nature-paper2ppt/UPSTREAM_LICENSE.txt +21 -0
- package/src/skills/nature-paper2ppt/agents/openai.yaml +4 -0
- package/src/skills/nature-polishing/SKILL.md +385 -0
- package/src/skills/nature-polishing/UPSTREAM_LICENSE.txt +21 -0
- package/src/skills/nature-polishing/agents/openai.yaml +4 -0
- package/src/skills/nature-polishing/references/phrasebank-playbook.md +162 -0
- package/src/skills/nature-polishing/references/section-moves.md +240 -0
- package/src/skills/nature-polishing/references/style-guardrails.md +94 -0
- package/src/skills/nature-polishing/references/writing-strategy.md +148 -0
- package/src/skills/optimize/SKILL.md +177 -1568
- package/src/skills/optimize/references/brief-shaping-playbook.md +95 -0
- package/src/skills/optimize/references/candidate-board-template.md +13 -0
- package/src/skills/optimize/references/candidate-ranking-template.md +51 -0
- package/src/skills/optimize/references/codegen-route-playbook.md +50 -0
- package/src/skills/optimize/references/debug-response-template.md +29 -0
- package/src/skills/optimize/references/frontier-review-template.md +32 -0
- package/src/skills/optimize/references/fusion-playbook.md +36 -0
- package/src/skills/optimize/references/method-brief-template.md +73 -0
- package/src/skills/optimize/references/operational-guidance.md +621 -0
- package/src/skills/optimize/references/optimization-memory-template.md +30 -0
- package/src/skills/optimize/references/optimize-checklist-template.md +18 -0
- package/src/skills/optimize/references/plateau-response-playbook.md +28 -0
- package/src/skills/optimize/references/prompt-patterns.md +49 -0
- package/src/skills/paper-outline/SKILL.md +227 -0
- package/src/skills/paper-outline/references/outline-patterns.md +87 -0
- package/src/skills/paper-plot/SKILL.md +79 -0
- package/src/skills/paper-plot/agents/openai.yaml +4 -0
- package/src/skills/paper-plot/references/bar_grouped_hatch.md +96 -0
- package/src/skills/paper-plot/references/bar_paired_delta.md +72 -0
- package/src/skills/paper-plot/references/line_confidence_band.md +75 -0
- package/src/skills/paper-plot/references/line_loss_with_inset.md +65 -0
- package/src/skills/paper-plot/references/line_training_curve.md +44 -0
- package/src/skills/paper-plot/references/radar_dual_series.md +59 -0
- package/src/skills/paper-plot/references/scatter_broken_axis.md +59 -0
- package/src/skills/paper-plot/references/scatter_tsne_cluster.md +72 -0
- package/src/skills/paper-plot/scripts/bar_memevolve.py +109 -0
- package/src/skills/paper-plot/scripts/bar_spice.py +166 -0
- package/src/skills/paper-plot/scripts/line_aime.py +94 -0
- package/src/skills/paper-plot/scripts/line_loss_inset.py +157 -0
- package/src/skills/paper-plot/scripts/line_selfdistill.py +168 -0
- package/src/skills/paper-plot/scripts/radar_dora.py +151 -0
- package/src/skills/paper-plot/scripts/scatter_break.py +169 -0
- package/src/skills/paper-plot/scripts/scatter_tsne.py +133 -0
- package/src/skills/rebuttal/SKILL.md +9 -0
- package/src/skills/references/tool-usage-by-stage.md +438 -0
- package/src/skills/review/SKILL.md +105 -7
- package/src/skills/science/PROVENANCE.md +44 -0
- package/src/skills/science/SKILL.md +137 -0
- package/src/skills/science/references/artifact-science-tool.md +110 -0
- package/src/skills/science/references/claim-type-discipline.md +56 -0
- package/src/skills/science/references/domain-index.md +422 -0
- package/src/skills/science/references/hpc-via-bash-exec.md +42 -0
- package/src/skills/science/references/package-check-playbook.md +64 -0
- package/src/skills/science/references/package-index.min.json +3616 -0
- package/src/skills/science/references/packages/abinit.md +80 -0
- package/src/skills/science/references/packages/acts.md +73 -0
- package/src/skills/science/references/packages/aiida-core.md +80 -0
- package/src/skills/science/references/packages/alamode.md +80 -0
- package/src/skills/science/references/packages/amuse.md +88 -0
- package/src/skills/science/references/packages/anndata.md +88 -0
- package/src/skills/science/references/packages/arbor.md +80 -0
- package/src/skills/science/references/packages/arc.md +73 -0
- package/src/skills/science/references/packages/astropy.md +88 -0
- package/src/skills/science/references/packages/astroquery.md +88 -0
- package/src/skills/science/references/packages/atomate2.md +80 -0
- package/src/skills/science/references/packages/atomsmltr.md +73 -0
- package/src/skills/science/references/packages/awkward.md +73 -0
- package/src/skills/science/references/packages/batman.md +88 -0
- package/src/skills/science/references/packages/biopython.md +88 -0
- package/src/skills/science/references/packages/bloqade.md +73 -0
- package/src/skills/science/references/packages/brian2.md +73 -0
- package/src/skills/science/references/packages/bullet3.md +73 -0
- package/src/skills/science/references/packages/calculix.md +80 -0
- package/src/skills/science/references/packages/cantera.md +73 -0
- package/src/skills/science/references/packages/cavity-md-ipi.md +80 -0
- package/src/skills/science/references/packages/ccdproc.md +88 -0
- package/src/skills/science/references/packages/celerite2.md +88 -0
- package/src/skills/science/references/packages/cellrank.md +73 -0
- package/src/skills/science/references/packages/cesm.md +80 -0
- package/src/skills/science/references/packages/chemicals.md +73 -0
- package/src/skills/science/references/packages/chempy.md +73 -0
- package/src/skills/science/references/packages/cirq.md +73 -0
- package/src/skills/science/references/packages/coffea.md +73 -0
- package/src/skills/science/references/packages/cp2k.md +88 -0
- package/src/skills/science/references/packages/custodian.md +80 -0
- package/src/skills/science/references/packages/dart.md +73 -0
- package/src/skills/science/references/packages/datamol.md +88 -0
- package/src/skills/science/references/packages/dd4hep.md +73 -0
- package/src/skills/science/references/packages/dealii.md +80 -0
- package/src/skills/science/references/packages/deepchem.md +88 -0
- package/src/skills/science/references/packages/delphes.md +73 -0
- package/src/skills/science/references/packages/devito.md +80 -0
- package/src/skills/science/references/packages/dftb.md +88 -0
- package/src/skills/science/references/packages/dftd4.md +88 -0
- package/src/skills/science/references/packages/dftk-jl.md +80 -0
- package/src/skills/science/references/packages/dolfinx.md +80 -0
- package/src/skills/science/references/packages/drake.md +73 -0
- package/src/skills/science/references/packages/dumux.md +73 -0
- package/src/skills/science/references/packages/elk.md +80 -0
- package/src/skills/science/references/packages/elmerfem.md +80 -0
- package/src/skills/science/references/packages/enzo-e.md +88 -0
- package/src/skills/science/references/packages/espresso.md +80 -0
- package/src/skills/science/references/packages/exoplanet.md +88 -0
- package/src/skills/science/references/packages/fairroot.md +73 -0
- package/src/skills/science/references/packages/fbpic.md +80 -0
- package/src/skills/science/references/packages/fdtdbath-meep.md +80 -0
- package/src/skills/science/references/packages/geant4.md +73 -0
- package/src/skills/science/references/packages/geosx.md +80 -0
- package/src/skills/science/references/packages/gprmax.md +80 -0
- package/src/skills/science/references/packages/gromacs.md +80 -0
- package/src/skills/science/references/packages/gwaslab.md +73 -0
- package/src/skills/science/references/packages/gz-sim.md +73 -0
- package/src/skills/science/references/packages/hail.md +88 -0
- package/src/skills/science/references/packages/hiphive.md +80 -0
- package/src/skills/science/references/packages/hoomd-blue.md +80 -0
- package/src/skills/science/references/packages/itensor.md +73 -0
- package/src/skills/science/references/packages/itensors-jl.md +73 -0
- package/src/skills/science/references/packages/jdftx.md +73 -0
- package/src/skills/science/references/packages/jobflow.md +80 -0
- package/src/skills/science/references/packages/kadanoffbaym-jl.md +73 -0
- package/src/skills/science/references/packages/kite.md +80 -0
- package/src/skills/science/references/packages/kratos.md +80 -0
- package/src/skills/science/references/packages/kwant.md +73 -0
- package/src/skills/science/references/packages/lammps.md +80 -0
- package/src/skills/science/references/packages/lightkurve.md +88 -0
- package/src/skills/science/references/packages/limix.md +73 -0
- package/src/skills/science/references/packages/maxwelllink.md +80 -0
- package/src/skills/science/references/packages/mcdc.md +73 -0
- package/src/skills/science/references/packages/meep.md +80 -0
- package/src/skills/science/references/packages/mfem.md +80 -0
- package/src/skills/science/references/packages/mitgcm.md +73 -0
- package/src/skills/science/references/packages/modflow6.md +73 -0
- package/src/skills/science/references/packages/molecool.md +73 -0
- package/src/skills/science/references/packages/mom6.md +73 -0
- package/src/skills/science/references/packages/moose.md +80 -0
- package/src/skills/science/references/packages/mpas-model.md +73 -0
- package/src/skills/science/references/packages/mujoco.md +73 -0
- package/src/skills/science/references/packages/mumax3.md +73 -0
- package/src/skills/science/references/packages/nekrs.md +80 -0
- package/src/skills/science/references/packages/nessi.md +73 -0
- package/src/skills/science/references/packages/nest-simulator.md +73 -0
- package/src/skills/science/references/packages/netket.md +73 -0
- package/src/skills/science/references/packages/neuron.md +73 -0
- package/src/skills/science/references/packages/nextflow.md +88 -0
- package/src/skills/science/references/packages/nwchem.md +88 -0
- package/src/skills/science/references/packages/openbabel.md +88 -0
- package/src/skills/science/references/packages/openems.md +80 -0
- package/src/skills/science/references/packages/openff-toolkit.md +88 -0
- package/src/skills/science/references/packages/openfoam-dev.md +80 -0
- package/src/skills/science/references/packages/openmc.md +73 -0
- package/src/skills/science/references/packages/openmm.md +80 -0
- package/src/skills/science/references/packages/openmoc.md +73 -0
- package/src/skills/science/references/packages/openmx.md +80 -0
- package/src/skills/science/references/packages/opensees.md +80 -0
- package/src/skills/science/references/packages/opensn.md +80 -0
- package/src/skills/science/references/packages/opm-simulators.md +73 -0
- package/src/skills/science/references/packages/oqupy.md +73 -0
- package/src/skills/science/references/packages/packmol.md +80 -0
- package/src/skills/science/references/packages/palabos.md +80 -0
- package/src/skills/science/references/packages/parflow.md +80 -0
- package/src/skills/science/references/packages/pennylane.md +88 -0
- package/src/skills/science/references/packages/perceval.md +73 -0
- package/src/skills/science/references/packages/phono3py.md +73 -0
- package/src/skills/science/references/packages/phonopy.md +73 -0
- package/src/skills/science/references/packages/photutils.md +88 -0
- package/src/skills/science/references/packages/picongpu.md +80 -0
- package/src/skills/science/references/packages/plink-ng.md +88 -0
- package/src/skills/science/references/packages/precice.md +73 -0
- package/src/skills/science/references/packages/psc.md +80 -0
- package/src/skills/science/references/packages/psi4.md +88 -0
- package/src/skills/science/references/packages/pybinding.md +73 -0
- package/src/skills/science/references/packages/pyfr.md +80 -0
- package/src/skills/science/references/packages/pyhf.md +73 -0
- package/src/skills/science/references/packages/pyiron_base.md +80 -0
- package/src/skills/science/references/packages/pylcp.md +73 -0
- package/src/skills/science/references/packages/pylith.md +80 -0
- package/src/skills/science/references/packages/pynbody.md +88 -0
- package/src/skills/science/references/packages/pysam.md +88 -0
- package/src/skills/science/references/packages/pyscf.md +88 -0
- package/src/skills/science/references/packages/q-e.md +73 -0
- package/src/skills/science/references/packages/qibo.md +73 -0
- package/src/skills/science/references/packages/qiskit.md +73 -0
- package/src/skills/science/references/packages/quantica-jl.md +73 -0
- package/src/skills/science/references/packages/quantumoptics-jl.md +73 -0
- package/src/skills/science/references/packages/quimb.md +73 -0
- package/src/skills/science/references/packages/qulacs.md +73 -0
- package/src/skills/science/references/packages/qutip.md +73 -0
- package/src/skills/science/references/packages/rdkit.md +88 -0
- package/src/skills/science/references/packages/rmg-py.md +73 -0
- package/src/skills/science/references/packages/root.md +73 -0
- package/src/skills/science/references/packages/scanpy.md +88 -0
- package/src/skills/science/references/packages/scikit-allel.md +88 -0
- package/src/skills/science/references/packages/scikit-bio.md +88 -0
- package/src/skills/science/references/packages/scqubits.md +73 -0
- package/src/skills/science/references/packages/scuff-em.md +80 -0
- package/src/skills/science/references/packages/scvi-tools.md +73 -0
- package/src/skills/science/references/packages/seissol.md +73 -0
- package/src/skills/science/references/packages/sfepy.md +80 -0
- package/src/skills/science/references/packages/sisl.md +73 -0
- package/src/skills/science/references/packages/smilei.md +80 -0
- package/src/skills/science/references/packages/snakemake.md +88 -0
- package/src/skills/science/references/packages/specfem3d-globe.md +80 -0
- package/src/skills/science/references/packages/specutils.md +88 -0
- package/src/skills/science/references/packages/spglib.md +80 -0
- package/src/skills/science/references/packages/squidpy.md +88 -0
- package/src/skills/science/references/packages/starry.md +88 -0
- package/src/skills/science/references/packages/strawberryfields.md +73 -0
- package/src/skills/science/references/packages/su2.md +80 -0
- package/src/skills/science/references/packages/sunny-jl.md +73 -0
- package/src/skills/science/references/packages/sw4.md +73 -0
- package/src/skills/science/references/packages/swift.md +88 -0
- package/src/skills/science/references/packages/tdnegf.md +73 -0
- package/src/skills/science/references/packages/tenpy.md +73 -0
- package/src/skills/science/references/packages/thermo.md +73 -0
- package/src/skills/science/references/packages/tkwant.md +73 -0
- package/src/skills/science/references/packages/tvb-root.md +73 -0
- package/src/skills/science/references/packages/uproot5.md +73 -0
- package/src/skills/science/references/packages/vampire.md +80 -0
- package/src/skills/science/references/packages/wannier_tools.md +73 -0
- package/src/skills/science/references/packages/warpx.md +80 -0
- package/src/skills/science/references/packages/wrf.md +73 -0
- package/src/skills/science/references/packages/xtb.md +88 -0
- package/src/skills/science/references/packages/yt.md +73 -0
- package/src/skills/science/references/science-task-brief-template.md +71 -0
- package/src/skills/scout/SKILL.md +83 -425
- package/src/skills/scout/references/literature-scout-template.md +5 -24
- package/src/skills/scout/references/operational-guidance.md +191 -0
- package/src/skills/scout/references/paper-triage-playbook.md +11 -35
- package/src/skills/write/SKILL.md +744 -1246
- package/src/skills/write/references/experiments_analysis_patterns.md +129 -0
- package/src/skills/write/references/oral_package_patterns.md +252 -0
- package/src/skills/write/references/oral_writing_principles.md +291 -0
- package/src/skills/write/references/section_rewrite_checklist.md +234 -0
- package/src/tui/dist/app/AppContainer.js +1314 -27
- package/src/tui/dist/components/Composer.js +26 -1
- package/src/tui/dist/components/ConfigScreen.js +2 -1
- package/src/tui/dist/components/InputPrompt.js +25 -9
- package/src/tui/dist/components/MainContent.js +18 -3
- package/src/tui/dist/components/QuestScreen.js +3 -2
- package/src/tui/dist/components/UtilityScreen.js +37 -0
- package/src/tui/dist/hooks/useSafeInput.js +10 -0
- package/src/tui/dist/index.js +13 -1
- package/src/tui/dist/layouts/DefaultAppLayout.js +11 -8
- package/src/tui/dist/lib/api.js +89 -1
- package/src/tui/package.json +1 -1
- package/src/ui/dist/assets/{AnalysisPlugin-BCKAfjba.js → AnalysisPlugin-CA94NGmI.js} +1 -1
- package/src/ui/dist/assets/CliPlugin-DHBzphZU.js +79 -0
- package/src/ui/dist/assets/CodeEditorPlugin-BOFwD2rn.js +2 -0
- package/src/ui/dist/assets/{CodeViewerPlugin-CbaFRrUU.js → CodeViewerPlugin-CqDpgjik.js} +4 -4
- package/src/ui/dist/assets/{DocViewerPlugin-DAjLVeQD.js → DocViewerPlugin-UDBgt8-4.js} +3 -3
- package/src/ui/dist/assets/GitCommitViewerPlugin-BmHtZ0bZ.js +6 -0
- package/src/ui/dist/assets/{GitDiffViewerPlugin-CQACjoAA.js → GitDiffViewerPlugin-CAxjNorQ.js} +2 -2
- package/src/ui/dist/assets/{GitSnapshotViewer-0r4nLPke.js → GitSnapshotViewer-CweA6VON.js} +2 -2
- package/src/ui/dist/assets/{ImageViewerPlugin-nBOmI2v_.js → ImageViewerPlugin-C8wHGvGN.js} +5 -5
- package/src/ui/dist/assets/LabPlugin-COyyLUol.js +32 -0
- package/src/ui/dist/assets/{LatexPlugin-ZwtV8pIp.js → LatexPlugin-BQjAaA5J.js} +4 -4
- package/src/ui/dist/assets/{MarkdownViewerPlugin-DKqVfKyW.js → MarkdownViewerPlugin-Dy1NE2dI.js} +3 -3
- package/src/ui/dist/assets/{MarketplacePlugin-BwxStZ9D.js → MarketplacePlugin-DMIZtEJ2.js} +2 -2
- package/src/ui/dist/assets/NotebookEditor-CFHMq_Qt.js +91 -0
- package/src/ui/dist/assets/{NotebookEditor-DB9N_T9q.js → NotebookEditor-WFyd8Ybt.js} +3 -3
- package/src/ui/dist/assets/{PdfLoader-eWBONbQP.js → PdfLoader-CLE5u5TS.js} +3 -3
- package/src/ui/dist/assets/{PdfMarkdownPlugin-D22YOZL3.js → PdfMarkdownPlugin-_iNK_H83.js} +1 -1
- package/src/ui/dist/assets/PdfViewerPlugin-DgWsbInT.js +22 -0
- package/src/ui/dist/assets/SearchPlugin-DrZmn5iw.js +11 -0
- package/src/ui/dist/assets/{TextViewerPlugin-C5xqeeUH.js → TextViewerPlugin-D1-T3aC7.js} +4 -4
- package/src/ui/dist/assets/branding/runner-claude.svg +107 -0
- package/src/ui/dist/assets/branding/runner-codex.svg +10 -0
- package/src/ui/dist/assets/branding/runner-kimi.svg +14 -0
- package/src/ui/dist/assets/branding/runner-opencode.svg +7 -0
- package/src/ui/dist/assets/cli-store-CoZ-x5Ip.js +1 -0
- package/src/ui/dist/assets/{code-WlFHE7z_.js → code-DbsmSd3Y.js} +1 -1
- package/src/ui/dist/assets/file-diff-panel-DsvyRz47.js +1 -0
- package/src/ui/dist/assets/{wrap-text-BC-Hltpd.js → file-jump-queue-DeQBikaw.js} +3 -3
- package/src/ui/dist/assets/{file-socket-CfQPKQKj.js → file-socket-DA5XIx88.js} +1 -1
- package/src/ui/dist/assets/fonts/ds-fonts.css +50 -4
- package/src/ui/dist/assets/images/deepxiv/register-guide.png +0 -0
- package/src/ui/dist/assets/index-39vY9LmZ.js +1 -0
- package/src/ui/dist/assets/{index-CwNu1aH4.js → index-BsO46tJA.js} +1 -1
- package/src/ui/dist/assets/index-CHzJ2xtB.js +3530 -0
- package/src/ui/dist/assets/index-DH-zxoZ3.css +33 -0
- package/src/ui/dist/assets/{plugin-notebook-HbW2K-1c.js → plugin-notebook-JRhysCqj.js} +2 -2
- package/src/ui/dist/assets/{project-sync-C9IdzdZW.js → project-sync-DPmWKmKD.js} +1 -1
- package/src/ui/dist/assets/{zoom-out-E_gaeAxL.js → zoom-out-DAukFWen.js} +3 -3
- package/src/ui/dist/index.html +3 -3
- package/src/skills/analysis-campaign/references/artifact-orchestration.md +0 -58
- package/src/skills/baseline/references/memory-playbook.md +0 -40
- package/src/skills/baseline/references/publishable-baseline-package.md +0 -30
- package/src/skills/write/references/outline-evidence-contract-example.md +0 -107
- package/src/skills/write/references/paper-experiment-matrix-template.md +0 -131
- package/src/skills/write/references/paper-section-playbook.md +0 -64
- package/src/skills/write/references/reviewer-first-writing.md +0 -64
- package/src/skills/write/references/revision-checklist.md +0 -70
- package/src/skills/write/references/section-contracts.md +0 -82
- package/src/skills/write/references/sentence-level-proofing.md +0 -49
- package/src/ui/dist/assets/AiManusChatView-Bv-Z8YpU.js +0 -204
- package/src/ui/dist/assets/CliPlugin-BCKcpc35.js +0 -109
- package/src/ui/dist/assets/CodeEditorPlugin-DbOfSJ8K.js +0 -2
- package/src/ui/dist/assets/GitCommitViewerPlugin-CIUqbUDO.js +0 -1
- package/src/ui/dist/assets/LabCopilotPanel-BHxOxF4z.js +0 -14
- package/src/ui/dist/assets/LabPlugin-BKoZGs95.js +0 -22
- package/src/ui/dist/assets/NotebookEditor-BEQhaQbt.js +0 -81
- package/src/ui/dist/assets/PdfViewerPlugin-c-RK9DLM.js +0 -17
- package/src/ui/dist/assets/SearchPlugin-CxF9ytAx.js +0 -16
- package/src/ui/dist/assets/VNCViewer-BoLGLnHz.js +0 -11
- package/src/ui/dist/assets/bot-DREQOxzP.js +0 -6
- package/src/ui/dist/assets/chevron-up-C9Qpx4DE.js +0 -6
- package/src/ui/dist/assets/file-content-BZMz3RYp.js +0 -1
- package/src/ui/dist/assets/file-diff-panel-CQhw0jS2.js +0 -1
- package/src/ui/dist/assets/file-jump-queue-DA-SdG__.js +0 -1
- package/src/ui/dist/assets/git-commit-horizontal-DxZ8DCZh.js +0 -6
- package/src/ui/dist/assets/image-Bgl4VIyx.js +0 -6
- package/src/ui/dist/assets/index-BpV6lusQ.css +0 -33
- package/src/ui/dist/assets/index-CBNVuWcP.js +0 -2496
- package/src/ui/dist/assets/index-DrUnlf6K.js +0 -1
- package/src/ui/dist/assets/index-NW-h8VzN.js +0 -1
- package/src/ui/dist/assets/pdf-effect-queue-J8OnM0jE.js +0 -6
- package/src/ui/dist/assets/popover-CLc0pPP8.js +0 -1
- package/src/ui/dist/assets/select-Cs2PmzwL.js +0 -11
- package/src/ui/dist/assets/sigma-ClKcHAXm.js +0 -6
- package/src/ui/dist/assets/trash-DwpbFr3w.js +0 -11
- package/src/ui/dist/assets/useCliAccess-NQ8m0Let.js +0 -1
- package/src/ui/dist/assets/useFileDiffOverlay-FuhcnKiw.js +0 -1
|
@@ -2,11 +2,14 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
import json
|
|
4
4
|
import os
|
|
5
|
+
import shlex
|
|
6
|
+
import shutil
|
|
5
7
|
import subprocess
|
|
6
8
|
import tempfile
|
|
7
9
|
from copy import deepcopy
|
|
8
10
|
from pathlib import Path
|
|
9
11
|
from urllib.error import URLError
|
|
12
|
+
from urllib.parse import urlencode
|
|
10
13
|
from urllib.request import Request
|
|
11
14
|
|
|
12
15
|
from ..codex_cli_compat import (
|
|
@@ -21,6 +24,7 @@ from ..codex_cli_compat import (
|
|
|
21
24
|
normalize_codex_reasoning_effort,
|
|
22
25
|
provider_base_url_looks_local,
|
|
23
26
|
)
|
|
27
|
+
from ..kimi_cli_compat import materialize_kimi_runtime_home
|
|
24
28
|
from ..connector.connector_profiles import PROFILEABLE_CONNECTOR_NAMES, list_connector_profiles, normalize_connector_config
|
|
25
29
|
from ..connector_runtime import build_discovered_target, infer_connector_transport
|
|
26
30
|
from ..home import repo_root
|
|
@@ -49,8 +53,9 @@ from ..connector.qq_profiles import (
|
|
|
49
53
|
)
|
|
50
54
|
from ..connector.weixin_support import normalize_weixin_base_url, normalize_weixin_cdn_base_url
|
|
51
55
|
from ..network import urlopen_with_proxy as urlopen
|
|
56
|
+
from ..runners.metadata import get_runner_metadata, list_builtin_runner_names
|
|
52
57
|
from ..runners.runtime_overrides import apply_codex_runtime_overrides, apply_runners_runtime_overrides
|
|
53
|
-
from ..shared import read_json, read_text, read_yaml, resolve_runner_binary, run_command, sha256_text, utc_now, which, write_text, write_yaml
|
|
58
|
+
from ..shared import ensure_utf8_subprocess_env, read_json, read_text, read_yaml, resolve_runner_binary, run_command, sha256_text, utc_now, utf8_text_subprocess_kwargs, which, write_json, write_text, write_yaml
|
|
54
59
|
from .models import (
|
|
55
60
|
CONFIG_NAMES,
|
|
56
61
|
OPTIONAL_CONFIG_NAMES,
|
|
@@ -211,31 +216,83 @@ class ConfigManager:
|
|
|
211
216
|
return prepared
|
|
212
217
|
|
|
213
218
|
def _invalidate_codex_bootstrap_state_if_runner_changed(self, previous: dict, current: dict) -> None:
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
219
|
+
tracked_keys_by_runner = {
|
|
220
|
+
"codex": (
|
|
221
|
+
"binary",
|
|
222
|
+
"config_dir",
|
|
223
|
+
"profile",
|
|
224
|
+
"model",
|
|
225
|
+
"model_reasoning_effort",
|
|
226
|
+
"approval_policy",
|
|
227
|
+
"sandbox_mode",
|
|
228
|
+
"env",
|
|
229
|
+
"mcp_tool_timeout_sec",
|
|
230
|
+
),
|
|
231
|
+
"claude": (
|
|
232
|
+
"binary",
|
|
233
|
+
"config_dir",
|
|
234
|
+
"model",
|
|
235
|
+
"permission_mode",
|
|
236
|
+
"mcp_timeout_ms",
|
|
237
|
+
"mcp_tool_timeout_ms",
|
|
238
|
+
"env",
|
|
239
|
+
),
|
|
240
|
+
"kimi": (
|
|
241
|
+
"binary",
|
|
242
|
+
"config_dir",
|
|
243
|
+
"model",
|
|
244
|
+
"agent",
|
|
245
|
+
"thinking",
|
|
246
|
+
"yolo",
|
|
247
|
+
"mcp_tool_timeout_ms",
|
|
248
|
+
"env",
|
|
249
|
+
),
|
|
250
|
+
"opencode": (
|
|
251
|
+
"binary",
|
|
252
|
+
"config_dir",
|
|
253
|
+
"model",
|
|
254
|
+
"permission_mode",
|
|
255
|
+
"default_agent",
|
|
256
|
+
"variant",
|
|
257
|
+
"mcp_timeout_ms",
|
|
258
|
+
"env",
|
|
259
|
+
),
|
|
260
|
+
}
|
|
261
|
+
changed_runners: list[str] = []
|
|
262
|
+
for runner_name, tracked_keys in tracked_keys_by_runner.items():
|
|
263
|
+
previous_runner = previous.get(runner_name) if isinstance(previous.get(runner_name), dict) else {}
|
|
264
|
+
current_runner = current.get(runner_name) if isinstance(current.get(runner_name), dict) else {}
|
|
265
|
+
if all(previous_runner.get(key) == current_runner.get(key) for key in tracked_keys):
|
|
266
|
+
continue
|
|
267
|
+
changed_runners.append(runner_name)
|
|
268
|
+
if not changed_runners:
|
|
227
269
|
return
|
|
228
270
|
config = self.load_named_normalized("config")
|
|
229
271
|
bootstrap = config.get("bootstrap") if isinstance(config.get("bootstrap"), dict) else {}
|
|
230
|
-
bootstrap
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
"
|
|
238
|
-
|
|
272
|
+
runner_readiness = bootstrap.get("runner_readiness") if isinstance(bootstrap.get("runner_readiness"), dict) else {}
|
|
273
|
+
checked_at = utc_now()
|
|
274
|
+
for runner_name in changed_runners:
|
|
275
|
+
try:
|
|
276
|
+
runner_label = get_runner_metadata(runner_name).label
|
|
277
|
+
except KeyError:
|
|
278
|
+
runner_label = runner_name
|
|
279
|
+
summary = f"{runner_label} runner configuration changed. A new startup probe is required."
|
|
280
|
+
runner_readiness[runner_name] = {
|
|
281
|
+
"ready": False,
|
|
282
|
+
"last_checked_at": checked_at,
|
|
283
|
+
"last_result": {
|
|
284
|
+
"ok": False,
|
|
285
|
+
"summary": summary,
|
|
286
|
+
"warnings": [],
|
|
287
|
+
"errors": [],
|
|
288
|
+
"guidance": [],
|
|
289
|
+
},
|
|
290
|
+
}
|
|
291
|
+
bootstrap["runner_readiness"] = runner_readiness
|
|
292
|
+
codex_state = runner_readiness.get("codex") if isinstance(runner_readiness.get("codex"), dict) else {}
|
|
293
|
+
bootstrap["codex_ready"] = bool(codex_state.get("ready", False))
|
|
294
|
+
bootstrap["codex_last_checked_at"] = codex_state.get("last_checked_at")
|
|
295
|
+
bootstrap["codex_last_result"] = codex_state.get("last_result") if isinstance(codex_state.get("last_result"), dict) else {}
|
|
239
296
|
config["bootstrap"] = bootstrap
|
|
240
297
|
self.save_named_text("config", self.render_named_payload("config", config))
|
|
241
298
|
|
|
@@ -476,12 +533,12 @@ The **Test** button checks:
|
|
|
476
533
|
|
|
477
534
|
This is a safe local smoke test.
|
|
478
535
|
|
|
479
|
-
##
|
|
536
|
+
## Runner startup gate
|
|
480
537
|
|
|
481
|
-
-
|
|
482
|
-
-
|
|
483
|
-
-
|
|
484
|
-
-
|
|
538
|
+
- the launcher runs a real hello probe for the selected runner before first daemon start
|
|
539
|
+
- `codex`, `claude`, `kimi`, and `opencode` can each record readiness under `bootstrap.runner_readiness`
|
|
540
|
+
- if the selected runner fails, DeepScientist writes the failure summary back into config and blocks only that requested startup path
|
|
541
|
+
- you can start with the default runner first, then configure or switch Claude Code / Kimi Code / OpenCode from Settings
|
|
485
542
|
|
|
486
543
|
## Figure and chart style policy
|
|
487
544
|
|
|
@@ -497,15 +554,16 @@ This page edits `{home_text}/config/runners.yaml`.
|
|
|
497
554
|
## Recommended v1 choice
|
|
498
555
|
|
|
499
556
|
- keep `codex.enabled: true`
|
|
500
|
-
-
|
|
501
|
-
-
|
|
557
|
+
- enable whichever runners you actually plan to use (`codex`, `claude`, `kimi`, `opencode`)
|
|
558
|
+
- keep the others disabled if their local CLI or credentials are not ready yet
|
|
502
559
|
- set `codex.profile` only when your Codex CLI uses a named provider profile such as `m27`
|
|
503
560
|
- when you launch DeepScientist ad hoc with a provider profile, you can also use `ds --codex-profile <name>`
|
|
504
561
|
- when you want a one-off Codex binary override, you can also use `ds --codex /absolute/path/to/codex`
|
|
505
562
|
- keep `codex.model_reasoning_effort: xhigh` unless you explicitly want a lighter default
|
|
506
563
|
- keep `codex.retry_on_failure: true` so transient Codex failures can resume automatically
|
|
507
|
-
- keep retry timing near `10s / 6x / 1800s max` so Codex backs off exponentially and the
|
|
508
|
-
- DeepScientist hard-limits one turn to at most `
|
|
564
|
+
- keep retry timing near `10s / 6x / 1800s max` so Codex backs off exponentially and the final retries sit at the 30-minute cap
|
|
565
|
+
- DeepScientist hard-limits one turn to at most `7` total attempts, even if the config says more
|
|
566
|
+
- one-off diagnostics can target a runner without permanently enabling it: `ds doctor --runner claude`, `ds doctor --runner kimi`, or `ds doctor --runner opencode`
|
|
509
567
|
|
|
510
568
|
## Test behavior
|
|
511
569
|
|
|
@@ -513,7 +571,7 @@ The **Test** button checks:
|
|
|
513
571
|
|
|
514
572
|
- whether the configured runner binaries are on PATH
|
|
515
573
|
- whether disabled runners are intentionally skipped
|
|
516
|
-
- for
|
|
574
|
+
- for enabled runners, it also runs a real hello probe so login problems, profile misconfiguration, and first-run setup issues surface before quest execution
|
|
517
575
|
- it does not simulate the full failure/retry loop, so use quest runtime logs when debugging recovery behavior
|
|
518
576
|
"""
|
|
519
577
|
if name == "plugins":
|
|
@@ -607,21 +665,159 @@ Use **Test** when the file exposes runtime dependencies.
|
|
|
607
665
|
rendered = self.render_named_payload(name, payload)
|
|
608
666
|
return self.test_named_text(name, rendered, live=live, delivery_targets=delivery_targets)
|
|
609
667
|
|
|
610
|
-
def
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
668
|
+
def test_deepxiv_payload(self, payload: dict | None = None) -> dict:
|
|
669
|
+
normalized = self._normalize_named_payload("config", payload if isinstance(payload, dict) else self.load_named_normalized("config"))
|
|
670
|
+
literature = normalized.get("literature") if isinstance(normalized.get("literature"), dict) else {}
|
|
671
|
+
deepxiv = literature.get("deepxiv") if isinstance(literature.get("deepxiv"), dict) else {}
|
|
672
|
+
base_url = str(deepxiv.get("base_url") or "https://data.rag.ac.cn").strip() or "https://data.rag.ac.cn"
|
|
673
|
+
direct_token = str(deepxiv.get("token") or "").strip()
|
|
674
|
+
token_env_name = str(deepxiv.get("token_env") or "").strip()
|
|
675
|
+
env_token = str(os.environ.get(token_env_name) or "").strip() if token_env_name else ""
|
|
676
|
+
resolved_token = direct_token or env_token
|
|
677
|
+
query = "transformers"
|
|
678
|
+
result_size = max(1, int(deepxiv.get("default_result_size") or 10))
|
|
679
|
+
preview_characters = max(200, int(deepxiv.get("preview_characters") or 1200))
|
|
680
|
+
request_timeout_seconds = max(3, int(deepxiv.get("request_timeout_seconds") or 20))
|
|
681
|
+
details = {
|
|
682
|
+
"base_url": base_url,
|
|
683
|
+
"query": query,
|
|
684
|
+
"result_size": result_size,
|
|
685
|
+
"preview_characters": preview_characters,
|
|
686
|
+
"request_timeout_seconds": request_timeout_seconds,
|
|
687
|
+
"token_source": "direct_token" if direct_token else ("env" if env_token else "missing"),
|
|
688
|
+
"token_env": token_env_name or None,
|
|
689
|
+
}
|
|
690
|
+
if not resolved_token:
|
|
691
|
+
return {
|
|
692
|
+
"ok": False,
|
|
693
|
+
"summary": "DeepXiv test failed: token is missing.",
|
|
694
|
+
"warnings": [],
|
|
695
|
+
"errors": ["Provide a DeepXiv token before running the test."],
|
|
696
|
+
"details": details,
|
|
697
|
+
"results": [],
|
|
698
|
+
"preview": "",
|
|
699
|
+
}
|
|
700
|
+
url = f"{base_url.rstrip('/')}/arxiv/?{urlencode({'type': 'retrieve', 'query': query, 'size': str(result_size)})}"
|
|
701
|
+
request = Request(
|
|
702
|
+
url,
|
|
703
|
+
headers={
|
|
704
|
+
"Accept": "application/json",
|
|
705
|
+
"Authorization": f"Bearer {resolved_token}",
|
|
706
|
+
"User-Agent": "DeepScientist/DeepXivTest",
|
|
707
|
+
},
|
|
708
|
+
)
|
|
709
|
+
try:
|
|
710
|
+
with urlopen(request, timeout=request_timeout_seconds) as response: # noqa: S310
|
|
711
|
+
response_text = response.read().decode("utf-8", errors="replace")
|
|
712
|
+
except Exception as exc:
|
|
713
|
+
details["request_url"] = url
|
|
714
|
+
return {
|
|
715
|
+
"ok": False,
|
|
716
|
+
"summary": "DeepXiv test request failed.",
|
|
717
|
+
"warnings": [],
|
|
718
|
+
"errors": [str(exc)],
|
|
719
|
+
"details": details,
|
|
720
|
+
"results": [],
|
|
721
|
+
"preview": "",
|
|
722
|
+
}
|
|
723
|
+
try:
|
|
724
|
+
parsed = json.loads(response_text)
|
|
725
|
+
except json.JSONDecodeError:
|
|
726
|
+
preview = response_text[:preview_characters].rstrip()
|
|
727
|
+
if len(response_text) > preview_characters:
|
|
728
|
+
preview = f"{preview}\n...[truncated]"
|
|
729
|
+
details["request_url"] = url
|
|
730
|
+
return {
|
|
731
|
+
"ok": False,
|
|
732
|
+
"summary": "DeepXiv test returned invalid JSON.",
|
|
733
|
+
"warnings": [],
|
|
734
|
+
"errors": ["DeepXiv returned invalid JSON."],
|
|
735
|
+
"details": details,
|
|
736
|
+
"results": [],
|
|
737
|
+
"preview": preview,
|
|
738
|
+
}
|
|
739
|
+
results = parsed.get("results") if isinstance(parsed.get("results"), list) else []
|
|
740
|
+
if not results and isinstance(parsed.get("result"), list):
|
|
741
|
+
results = parsed.get("result") or []
|
|
742
|
+
total = parsed.get("total")
|
|
743
|
+
if total is None:
|
|
744
|
+
total = parsed.get("total_count")
|
|
745
|
+
preview_payload = {
|
|
746
|
+
"total": total,
|
|
747
|
+
"took": parsed.get("took"),
|
|
748
|
+
"results": results[: min(3, len(results))],
|
|
749
|
+
}
|
|
750
|
+
preview = json.dumps(preview_payload, ensure_ascii=False, indent=2)
|
|
751
|
+
if len(preview) > preview_characters:
|
|
752
|
+
preview = f"{preview[:preview_characters].rstrip()}\n...[truncated]"
|
|
753
|
+
details.update(
|
|
754
|
+
{
|
|
755
|
+
"request_url": url,
|
|
756
|
+
"total": total,
|
|
757
|
+
"result_count": len(results),
|
|
758
|
+
"first_title": str((results[0] or {}).get("title") or "").strip() if results else None,
|
|
759
|
+
}
|
|
760
|
+
)
|
|
761
|
+
ok = len(results) > 0
|
|
762
|
+
return {
|
|
763
|
+
"ok": ok,
|
|
764
|
+
"summary": "DeepXiv returned search results for `transformers`." if ok else "DeepXiv returned no search results for `transformers`.",
|
|
765
|
+
"warnings": [],
|
|
766
|
+
"errors": [] if ok else ["No results were returned for `transformers`."],
|
|
767
|
+
"details": details,
|
|
768
|
+
"results": results[:5],
|
|
769
|
+
"preview": preview,
|
|
770
|
+
}
|
|
771
|
+
|
|
772
|
+
def probe_runner_bootstrap(self, runner_name: str, *, persist: bool = False, payload: dict | None = None) -> dict:
|
|
773
|
+
normalized_runner = str(runner_name or "codex").strip().lower() or "codex"
|
|
774
|
+
runners_payload = payload if isinstance(payload, dict) else self.load_runners_config()
|
|
775
|
+
runner_payload = runners_payload.get(normalized_runner) if isinstance(runners_payload.get(normalized_runner), dict) else {}
|
|
776
|
+
if normalized_runner == "codex":
|
|
777
|
+
result = self._probe_codex_runner(runner_payload)
|
|
778
|
+
elif normalized_runner == "claude":
|
|
779
|
+
result = self._probe_claude_runner(runner_payload)
|
|
780
|
+
elif normalized_runner == "kimi":
|
|
781
|
+
result = self._probe_kimi_runner(runner_payload)
|
|
782
|
+
elif normalized_runner == "opencode":
|
|
783
|
+
result = self._probe_opencode_runner(runner_payload)
|
|
784
|
+
else:
|
|
785
|
+
raise KeyError(f"Unknown runner `{normalized_runner}`.")
|
|
614
786
|
if persist:
|
|
615
|
-
self.
|
|
787
|
+
self._persist_runner_bootstrap_result(normalized_runner, result)
|
|
616
788
|
return result
|
|
617
789
|
|
|
618
|
-
def
|
|
790
|
+
def runner_bootstrap_state(self, runner_name: str) -> dict:
|
|
791
|
+
normalized_runner = str(runner_name or "codex").strip().lower() or "codex"
|
|
619
792
|
config = self.load_named_normalized("config")
|
|
620
793
|
bootstrap = config.get("bootstrap") if isinstance(config.get("bootstrap"), dict) else {}
|
|
794
|
+
runner_readiness = bootstrap.get("runner_readiness") if isinstance(bootstrap.get("runner_readiness"), dict) else {}
|
|
795
|
+
runner_state = runner_readiness.get(normalized_runner) if isinstance(runner_readiness.get(normalized_runner), dict) else {}
|
|
796
|
+
if normalized_runner == "codex" and not runner_state:
|
|
797
|
+
runner_state = {
|
|
798
|
+
"ready": bool(bootstrap.get("codex_ready", False)),
|
|
799
|
+
"last_checked_at": bootstrap.get("codex_last_checked_at"),
|
|
800
|
+
"last_result": bootstrap.get("codex_last_result") if isinstance(bootstrap.get("codex_last_result"), dict) else {},
|
|
801
|
+
}
|
|
802
|
+
return {
|
|
803
|
+
"runner": normalized_runner,
|
|
804
|
+
"ready": bool(runner_state.get("ready", False)),
|
|
805
|
+
"last_checked_at": runner_state.get("last_checked_at"),
|
|
806
|
+
"last_result": runner_state.get("last_result") if isinstance(runner_state.get("last_result"), dict) else {},
|
|
807
|
+
}
|
|
808
|
+
|
|
809
|
+
def runner_readiness_map(self) -> dict[str, dict[str, Any]]:
|
|
810
|
+
return {name: self.runner_bootstrap_state(name) for name in list_builtin_runner_names()}
|
|
811
|
+
|
|
812
|
+
def probe_codex_bootstrap(self, *, persist: bool = False, payload: dict | None = None) -> dict:
|
|
813
|
+
return self.probe_runner_bootstrap("codex", persist=persist, payload=payload)
|
|
814
|
+
|
|
815
|
+
def codex_bootstrap_state(self) -> dict:
|
|
816
|
+
state = self.runner_bootstrap_state("codex")
|
|
621
817
|
return {
|
|
622
|
-
"codex_ready": bool(
|
|
623
|
-
"codex_last_checked_at":
|
|
624
|
-
"codex_last_result":
|
|
818
|
+
"codex_ready": bool(state.get("ready")),
|
|
819
|
+
"codex_last_checked_at": state.get("last_checked_at"),
|
|
820
|
+
"codex_last_result": state.get("last_result") if isinstance(state.get("last_result"), dict) else {},
|
|
625
821
|
}
|
|
626
822
|
|
|
627
823
|
def git_readiness(self) -> dict:
|
|
@@ -701,7 +897,8 @@ Use **Test** when the file exposes runtime dependencies.
|
|
|
701
897
|
|
|
702
898
|
def _test_runners_payload(self, payload: dict, *, live: bool) -> dict:
|
|
703
899
|
items = []
|
|
704
|
-
|
|
900
|
+
normalized_payload = apply_runners_runtime_overrides(self._normalize_named_payload("runners", payload))
|
|
901
|
+
for name, config in normalized_payload.items():
|
|
705
902
|
if not isinstance(config, dict):
|
|
706
903
|
continue
|
|
707
904
|
enabled = bool(config.get("enabled", False))
|
|
@@ -724,8 +921,8 @@ Use **Test** when the file exposes runtime dependencies.
|
|
|
724
921
|
"live_probe_executed": False,
|
|
725
922
|
},
|
|
726
923
|
}
|
|
727
|
-
if enabled and
|
|
728
|
-
probe = self.
|
|
924
|
+
if enabled and exists and live:
|
|
925
|
+
probe = self.probe_runner_bootstrap(name, persist=False, payload=normalized_payload)
|
|
729
926
|
item["ok"] = bool(probe.get("ok"))
|
|
730
927
|
item["warnings"] = [*warnings, *list(probe.get("warnings") or [])]
|
|
731
928
|
item["errors"] = list(probe.get("errors") or [])
|
|
@@ -1221,7 +1418,7 @@ Use **Test** when the file exposes runtime dependencies.
|
|
|
1221
1418
|
def _codex_runner_env(config: dict) -> dict[str, str]:
|
|
1222
1419
|
raw_env = config.get("env")
|
|
1223
1420
|
if not isinstance(raw_env, dict):
|
|
1224
|
-
return {}
|
|
1421
|
+
return ensure_utf8_subprocess_env({})
|
|
1225
1422
|
resolved: dict[str, str] = {}
|
|
1226
1423
|
for key, value in raw_env.items():
|
|
1227
1424
|
env_key = str(key or "").strip()
|
|
@@ -1231,7 +1428,7 @@ Use **Test** when the file exposes runtime dependencies.
|
|
|
1231
1428
|
if env_value == "":
|
|
1232
1429
|
continue
|
|
1233
1430
|
resolved[env_key] = env_value
|
|
1234
|
-
return resolved
|
|
1431
|
+
return ensure_utf8_subprocess_env(resolved)
|
|
1235
1432
|
|
|
1236
1433
|
def _prepare_codex_probe_home(
|
|
1237
1434
|
self,
|
|
@@ -1324,6 +1521,14 @@ Use **Test** when the file exposes runtime dependencies.
|
|
|
1324
1521
|
hints.insert(0, f"Your current provider config uses `wire_api = \"{wire_api}\"`; switch it to `wire_api = \"responses\"` first.")
|
|
1325
1522
|
return hints
|
|
1326
1523
|
|
|
1524
|
+
@staticmethod
|
|
1525
|
+
def _codex_direct_hello_probe_command(*, profile: str = "") -> str:
|
|
1526
|
+
profile_args = f" --profile {shlex.quote(profile)}" if profile else ""
|
|
1527
|
+
return (
|
|
1528
|
+
"printf 'Reply with exactly HELLO.' | "
|
|
1529
|
+
f"codex --search{profile_args} exec --json --cd /tmp --skip-git-repo-check -"
|
|
1530
|
+
)
|
|
1531
|
+
|
|
1327
1532
|
@staticmethod
|
|
1328
1533
|
def _missing_provider_env_guidance(
|
|
1329
1534
|
*,
|
|
@@ -1343,7 +1548,8 @@ Use **Test** when the file exposes runtime dependencies.
|
|
|
1343
1548
|
"Also add `requires_openai_auth = false` to that local provider profile so DeepScientist can remove conflicting `OPENAI_*` auth variables."
|
|
1344
1549
|
)
|
|
1345
1550
|
guidance.append(
|
|
1346
|
-
|
|
1551
|
+
"Before retrying DeepScientist, run a real request such as "
|
|
1552
|
+
f"`{ConfigManager._codex_direct_hello_probe_command(profile=profile)}` and verify it returns `HELLO`."
|
|
1347
1553
|
)
|
|
1348
1554
|
return guidance
|
|
1349
1555
|
|
|
@@ -1383,7 +1589,52 @@ Use **Test** when the file exposes runtime dependencies.
|
|
|
1383
1589
|
},
|
|
1384
1590
|
)
|
|
1385
1591
|
|
|
1386
|
-
|
|
1592
|
+
@staticmethod
|
|
1593
|
+
def _codex_probe_text_looks_auth_related(stdout_text: str, stderr_text: str) -> bool:
|
|
1594
|
+
haystack = f"{stdout_text}\n{stderr_text}".lower()
|
|
1595
|
+
markers = (
|
|
1596
|
+
"please login",
|
|
1597
|
+
"not logged in",
|
|
1598
|
+
"login required",
|
|
1599
|
+
"authentication required",
|
|
1600
|
+
"auth required",
|
|
1601
|
+
"oauth",
|
|
1602
|
+
"unauthenticated",
|
|
1603
|
+
"missing credentials",
|
|
1604
|
+
"no credentials",
|
|
1605
|
+
)
|
|
1606
|
+
return any(marker in haystack for marker in markers)
|
|
1607
|
+
|
|
1608
|
+
@staticmethod
|
|
1609
|
+
def _codex_probe_text_looks_network_related(stdout_text: str, stderr_text: str) -> bool:
|
|
1610
|
+
haystack = f"{stdout_text}\n{stderr_text}".lower()
|
|
1611
|
+
markers = (
|
|
1612
|
+
"connection refused",
|
|
1613
|
+
"connection reset",
|
|
1614
|
+
"connection timed out",
|
|
1615
|
+
"network is unreachable",
|
|
1616
|
+
"name or service not known",
|
|
1617
|
+
"temporary failure in name resolution",
|
|
1618
|
+
"dns",
|
|
1619
|
+
"proxy",
|
|
1620
|
+
"tls",
|
|
1621
|
+
"certificate",
|
|
1622
|
+
"ssl",
|
|
1623
|
+
"timeout",
|
|
1624
|
+
"timed out",
|
|
1625
|
+
"econnreset",
|
|
1626
|
+
"econnrefused",
|
|
1627
|
+
"enotfound",
|
|
1628
|
+
)
|
|
1629
|
+
return any(marker in haystack for marker in markers)
|
|
1630
|
+
|
|
1631
|
+
def _codex_probe_failure_guidance(
|
|
1632
|
+
self,
|
|
1633
|
+
config: dict,
|
|
1634
|
+
*,
|
|
1635
|
+
stdout_text: str = "",
|
|
1636
|
+
stderr_text: str = "",
|
|
1637
|
+
) -> tuple[list[str], list[str]]:
|
|
1387
1638
|
profile = self._codex_profile_name(config)
|
|
1388
1639
|
config_dir = str(config.get("config_dir") or "~/.codex").strip()
|
|
1389
1640
|
metadata = active_provider_metadata_from_home(config_dir, profile=profile or None) if config_dir else {}
|
|
@@ -1395,7 +1646,7 @@ Use **Test** when the file exposes runtime dependencies.
|
|
|
1395
1646
|
f"Codex profile `{profile}` did not complete the startup hello probe successfully.",
|
|
1396
1647
|
],
|
|
1397
1648
|
[
|
|
1398
|
-
f"Run `
|
|
1649
|
+
f"Run `{self._codex_direct_hello_probe_command(profile=profile)}` in a terminal and confirm that a real `HELLO` request succeeds.",
|
|
1399
1650
|
"If the profile uses a custom provider, make sure its API key, Base URL, and model configuration are available to Codex.",
|
|
1400
1651
|
"If the provider expects the model from the Codex profile itself, set `model: inherit` in `~/DeepScientist/config/runners.yaml`.",
|
|
1401
1652
|
*provider_hints,
|
|
@@ -1403,14 +1654,49 @@ Use **Test** when the file exposes runtime dependencies.
|
|
|
1403
1654
|
"Then run `ds doctor` and start DeepScientist again.",
|
|
1404
1655
|
],
|
|
1405
1656
|
)
|
|
1657
|
+
if self._codex_probe_text_looks_auth_related(stdout_text, stderr_text):
|
|
1658
|
+
return (
|
|
1659
|
+
[
|
|
1660
|
+
"Codex reported an authentication or first-run setup problem during the startup hello probe.",
|
|
1661
|
+
"Run `codex login` (or just `codex`) once and complete login before starting DeepScientist.",
|
|
1662
|
+
],
|
|
1663
|
+
[
|
|
1664
|
+
"Run `codex login` (or just `codex`) in a terminal and complete login or first-run setup.",
|
|
1665
|
+
"Then run `printf 'Reply with exactly HELLO.' | codex --search exec --json --cd /tmp --skip-git-repo-check -` and confirm the real request succeeds.",
|
|
1666
|
+
"If login succeeds but the direct probe still fails, check the configured model, provider profile, proxy, and Codex account access.",
|
|
1667
|
+
"Then run `ds doctor` and start DeepScientist again.",
|
|
1668
|
+
],
|
|
1669
|
+
)
|
|
1670
|
+
if self._codex_model_unavailable(stdout_text, stderr_text):
|
|
1671
|
+
return (
|
|
1672
|
+
[
|
|
1673
|
+
"Codex authentication may be working, but the configured startup probe model was not accepted.",
|
|
1674
|
+
],
|
|
1675
|
+
[
|
|
1676
|
+
"Run `printf 'Reply with exactly HELLO.' | codex --search exec --json --cd /tmp --skip-git-repo-check -` in the same shell and confirm the current Codex default model works.",
|
|
1677
|
+
"Set `runners.codex.model: inherit` in `~/DeepScientist/config/runners.yaml`, or set it to a model that your Codex account can actually use.",
|
|
1678
|
+
"Then run `ds doctor` and start DeepScientist again.",
|
|
1679
|
+
],
|
|
1680
|
+
)
|
|
1681
|
+
if self._codex_probe_text_looks_network_related(stdout_text, stderr_text):
|
|
1682
|
+
return (
|
|
1683
|
+
[
|
|
1684
|
+
"Codex CLI was found, but the real startup hello request appears to have failed at the network, proxy, TLS, or provider layer.",
|
|
1685
|
+
],
|
|
1686
|
+
[
|
|
1687
|
+
"Run `printf 'Reply with exactly HELLO.' | codex --search exec --json --cd /tmp --skip-git-repo-check -` from the same shell and verify the request succeeds.",
|
|
1688
|
+
"If this host needs a proxy, export `HTTP_PROXY`, `HTTPS_PROXY`, and `NO_PROXY` before launching `ds`; for managed or supervised runs, also put required environment variables under `runners.codex.env`.",
|
|
1689
|
+
"Then run `ds doctor` and start DeepScientist again.",
|
|
1690
|
+
],
|
|
1691
|
+
)
|
|
1406
1692
|
return (
|
|
1407
1693
|
[
|
|
1408
|
-
"
|
|
1694
|
+
"Codex CLI was found, but its real startup hello request did not complete successfully.",
|
|
1409
1695
|
],
|
|
1410
1696
|
[
|
|
1411
|
-
"Run `
|
|
1412
|
-
"If `
|
|
1413
|
-
"If the configured model is not available to your Codex account,
|
|
1697
|
+
"Run `printf 'Reply with exactly HELLO.' | codex --search exec --json --cd /tmp --skip-git-repo-check -` in the same shell and inspect the Codex stderr/stdout.",
|
|
1698
|
+
"If that direct command succeeds but `ds doctor` fails, compare `which codex`, `CODEX_HOME`, proxy variables, and `~/DeepScientist/config/runners.yaml`.",
|
|
1699
|
+
"If the configured model is not available to your Codex account, set `runners.codex.model: inherit` or another accessible model.",
|
|
1414
1700
|
"Then run `ds doctor` and start DeepScientist again.",
|
|
1415
1701
|
],
|
|
1416
1702
|
)
|
|
@@ -1533,8 +1819,8 @@ Use **Test** when the file exposes runtime dependencies.
|
|
|
1533
1819
|
approval_policy = str(config.get("approval_policy") or "on-request").strip()
|
|
1534
1820
|
sandbox_mode = str(config.get("sandbox_mode") or "workspace-write").strip()
|
|
1535
1821
|
|
|
1536
|
-
env = os.environ.copy()
|
|
1537
|
-
env.update(self._codex_runner_env(config))
|
|
1822
|
+
env = ensure_utf8_subprocess_env(os.environ.copy())
|
|
1823
|
+
env.update(self._claude_auth_runner_env(self._codex_runner_env(config)))
|
|
1538
1824
|
config_dir = str(config.get("config_dir") or "~/.codex").strip()
|
|
1539
1825
|
probe_home_handle: tempfile.TemporaryDirectory[str] | None = None
|
|
1540
1826
|
compatibility_warnings: list[str] = []
|
|
@@ -1593,10 +1879,10 @@ Use **Test** when the file exposes runtime dependencies.
|
|
|
1593
1879
|
input=prompt,
|
|
1594
1880
|
cwd=str(repo_root()),
|
|
1595
1881
|
env=env,
|
|
1596
|
-
text=True,
|
|
1597
1882
|
capture_output=True,
|
|
1598
1883
|
timeout=90,
|
|
1599
1884
|
check=False,
|
|
1885
|
+
**utf8_text_subprocess_kwargs(),
|
|
1600
1886
|
)
|
|
1601
1887
|
except subprocess.TimeoutExpired as exc:
|
|
1602
1888
|
return command, None, exc
|
|
@@ -1604,25 +1890,32 @@ Use **Test** when the file exposes runtime dependencies.
|
|
|
1604
1890
|
|
|
1605
1891
|
command, result, timeout_error = run_probe_once(effective_model)
|
|
1606
1892
|
if timeout_error is not None:
|
|
1893
|
+
stdout_text = str(timeout_error.stdout or "")
|
|
1894
|
+
stderr_text = str(timeout_error.stderr or "")
|
|
1607
1895
|
details.update(
|
|
1608
1896
|
{
|
|
1609
1897
|
"exit_code": None,
|
|
1610
|
-
"stdout_excerpt": self._compact_probe_text(
|
|
1611
|
-
"stderr_excerpt": self._compact_probe_text(
|
|
1898
|
+
"stdout_excerpt": self._compact_probe_text(stdout_text),
|
|
1899
|
+
"stderr_excerpt": self._compact_probe_text(stderr_text),
|
|
1612
1900
|
"probe_command": command,
|
|
1613
1901
|
}
|
|
1614
1902
|
)
|
|
1903
|
+
failure_errors, failure_guidance = self._codex_probe_failure_guidance(
|
|
1904
|
+
config,
|
|
1905
|
+
stdout_text=stdout_text,
|
|
1906
|
+
stderr_text=stderr_text,
|
|
1907
|
+
)
|
|
1615
1908
|
return {
|
|
1616
1909
|
"ok": False,
|
|
1617
1910
|
"summary": "Codex startup probe timed out.",
|
|
1618
1911
|
"warnings": base_warnings,
|
|
1619
1912
|
"errors": [
|
|
1620
1913
|
"Codex did not answer the startup hello probe within 90 seconds.",
|
|
1621
|
-
*
|
|
1914
|
+
*failure_errors,
|
|
1622
1915
|
],
|
|
1623
1916
|
"details": details,
|
|
1624
1917
|
"guidance": [
|
|
1625
|
-
*
|
|
1918
|
+
*failure_guidance,
|
|
1626
1919
|
"If `codex` is missing on PATH, install it explicitly with `npm install -g @openai/codex`.",
|
|
1627
1920
|
"Confirm the configured model is available to your Codex setup. DeepScientist currently probes Codex with the configured runner model first.",
|
|
1628
1921
|
],
|
|
@@ -1702,9 +1995,19 @@ Use **Test** when the file exposes runtime dependencies.
|
|
|
1702
1995
|
warnings.append("Codex returned stderr during the startup probe.")
|
|
1703
1996
|
if details.get("model_fallback_attempted") and not details.get("model_fallback_used"):
|
|
1704
1997
|
warnings.append("DeepScientist also tried the current Codex default model, but that fallback probe did not succeed.")
|
|
1705
|
-
errors.extend(
|
|
1998
|
+
errors.extend(
|
|
1999
|
+
self._codex_probe_failure_guidance(
|
|
2000
|
+
config,
|
|
2001
|
+
stdout_text=stdout_text,
|
|
2002
|
+
stderr_text=stderr_text,
|
|
2003
|
+
)[0]
|
|
2004
|
+
)
|
|
1706
2005
|
missing_env_key = missing_provider_env_key_from_text(stdout_text, stderr_text) or configured_provider_env_key
|
|
1707
|
-
failure_guidance = self._codex_probe_failure_guidance(
|
|
2006
|
+
failure_guidance = self._codex_probe_failure_guidance(
|
|
2007
|
+
config,
|
|
2008
|
+
stdout_text=stdout_text,
|
|
2009
|
+
stderr_text=stderr_text,
|
|
2010
|
+
)[1]
|
|
1708
2011
|
if not ok and missing_env_key and profile:
|
|
1709
2012
|
errors.append(
|
|
1710
2013
|
f"Codex profile `{profile}` requires environment variable `{missing_env_key}`, but DeepScientist did not receive it."
|
|
@@ -1726,38 +2029,402 @@ Use **Test** when the file exposes runtime dependencies.
|
|
|
1726
2029
|
"guidance": [] if ok else failure_guidance,
|
|
1727
2030
|
}
|
|
1728
2031
|
|
|
1729
|
-
def
|
|
2032
|
+
def _persist_runner_bootstrap_result(self, runner_name: str, result: dict) -> None:
|
|
2033
|
+
normalized_runner = str(runner_name or "codex").strip().lower() or "codex"
|
|
1730
2034
|
config = self.load_named_normalized("config")
|
|
1731
2035
|
bootstrap = config.get("bootstrap") if isinstance(config.get("bootstrap"), dict) else {}
|
|
1732
2036
|
details = result.get("details") if isinstance(result.get("details"), dict) else {}
|
|
1733
|
-
bootstrap
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
"
|
|
1737
|
-
"
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
2037
|
+
runner_readiness = bootstrap.get("runner_readiness") if isinstance(bootstrap.get("runner_readiness"), dict) else {}
|
|
2038
|
+
runner_readiness[normalized_runner] = {
|
|
2039
|
+
"ready": bool(result.get("ok")),
|
|
2040
|
+
"last_checked_at": details.get("checked_at") or utc_now(),
|
|
2041
|
+
"last_result": {
|
|
2042
|
+
"ok": bool(result.get("ok")),
|
|
2043
|
+
"summary": result.get("summary"),
|
|
2044
|
+
"warnings": list(result.get("warnings") or []),
|
|
2045
|
+
"errors": list(result.get("errors") or []),
|
|
2046
|
+
"guidance": list(result.get("guidance") or []),
|
|
2047
|
+
"binary": details.get("binary"),
|
|
2048
|
+
"resolved_binary": details.get("resolved_binary"),
|
|
2049
|
+
"model": details.get("model"),
|
|
2050
|
+
"requested_model": details.get("requested_model"),
|
|
2051
|
+
"effective_model": details.get("effective_model"),
|
|
2052
|
+
"exit_code": details.get("exit_code"),
|
|
2053
|
+
"stdout_excerpt": details.get("stdout_excerpt"),
|
|
2054
|
+
"stderr_excerpt": details.get("stderr_excerpt"),
|
|
2055
|
+
"profile": details.get("profile"),
|
|
2056
|
+
"permission_mode": details.get("permission_mode"),
|
|
2057
|
+
"variant": details.get("variant"),
|
|
2058
|
+
},
|
|
1755
2059
|
}
|
|
2060
|
+
bootstrap["runner_readiness"] = runner_readiness
|
|
2061
|
+
if normalized_runner == "codex":
|
|
2062
|
+
codex_state = runner_readiness["codex"]
|
|
2063
|
+
bootstrap["codex_ready"] = bool(codex_state.get("ready"))
|
|
2064
|
+
bootstrap["codex_last_checked_at"] = codex_state.get("last_checked_at")
|
|
2065
|
+
bootstrap["codex_last_result"] = codex_state.get("last_result")
|
|
1756
2066
|
config["bootstrap"] = bootstrap
|
|
1757
2067
|
self.save_named_payload("config", config)
|
|
1758
|
-
if bool(result.get("ok")) and bool(details.get("model_fallback_used")):
|
|
2068
|
+
if normalized_runner == "codex" and bool(result.get("ok")) and bool(details.get("model_fallback_used")):
|
|
1759
2069
|
self._persist_codex_model_inherit(details.get("requested_model"))
|
|
1760
2070
|
|
|
2071
|
+
def _persist_codex_bootstrap_result(self, result: dict) -> None:
|
|
2072
|
+
self._persist_runner_bootstrap_result("codex", result)
|
|
2073
|
+
|
|
2074
|
+
@staticmethod
|
|
2075
|
+
def _copy_runner_file_if_exists(source: Path, target: Path) -> None:
|
|
2076
|
+
if not source.exists() or not source.is_file():
|
|
2077
|
+
return
|
|
2078
|
+
target.parent.mkdir(parents=True, exist_ok=True)
|
|
2079
|
+
shutil.copy2(source, target)
|
|
2080
|
+
|
|
2081
|
+
@staticmethod
|
|
2082
|
+
def _claude_auth_runner_env(env: dict[str, str]) -> dict[str, str]:
|
|
2083
|
+
resolved = dict(env)
|
|
2084
|
+
auth_token = str(resolved.get("ANTHROPIC_AUTH_TOKEN") or "").strip()
|
|
2085
|
+
api_key = str(resolved.get("ANTHROPIC_API_KEY") or "").strip()
|
|
2086
|
+
if auth_token and not api_key:
|
|
2087
|
+
resolved["ANTHROPIC_API_KEY"] = auth_token
|
|
2088
|
+
return resolved
|
|
2089
|
+
|
|
2090
|
+
def _runner_missing_binary_guidance(self, runner_name: str, config: dict) -> list[str]:
|
|
2091
|
+
normalized_runner = str(runner_name or "").strip().lower()
|
|
2092
|
+
binary = str(config.get("binary") or normalized_runner).strip() or normalized_runner
|
|
2093
|
+
if normalized_runner == "codex":
|
|
2094
|
+
return self._codex_missing_binary_guidance(config)
|
|
2095
|
+
if normalized_runner == "claude":
|
|
2096
|
+
return [
|
|
2097
|
+
f"Install Claude Code and make sure `{binary} --version` works in the current shell.",
|
|
2098
|
+
"If Claude Code is already installed elsewhere, set `runners.claude.binary` to the absolute path.",
|
|
2099
|
+
]
|
|
2100
|
+
if normalized_runner == "opencode":
|
|
2101
|
+
return [
|
|
2102
|
+
f"Install OpenCode and make sure `{binary} --version` works in the current shell.",
|
|
2103
|
+
"If OpenCode is already installed elsewhere, set `runners.opencode.binary` to the absolute path.",
|
|
2104
|
+
]
|
|
2105
|
+
if normalized_runner == "kimi":
|
|
2106
|
+
return [
|
|
2107
|
+
f"Install Kimi Code and make sure `{binary} --version` works in the current shell.",
|
|
2108
|
+
"Run `kimi login` (or just `kimi`) once to complete the first-run login flow.",
|
|
2109
|
+
"If Kimi Code uses a custom home, point `runners.kimi.config_dir` at the correct `~/.kimi`-style directory that contains `config.toml` and `mcp.json`.",
|
|
2110
|
+
]
|
|
2111
|
+
return [f"Install runner `{normalized_runner}` and ensure `{binary}` is on PATH."]
|
|
2112
|
+
|
|
2113
|
+
def _probe_claude_runner(self, config: dict) -> dict:
|
|
2114
|
+
checked_at = utc_now()
|
|
2115
|
+
binary = str(config.get("binary") or "claude").strip() or "claude"
|
|
2116
|
+
resolved_binary = resolve_runner_binary(binary, runner_name="claude")
|
|
2117
|
+
requested_model = str(config.get("model") or "inherit").strip() or "inherit"
|
|
2118
|
+
permission_mode = str(config.get("permission_mode") or "bypassPermissions").strip() or "bypassPermissions"
|
|
2119
|
+
details: dict[str, object] = {
|
|
2120
|
+
"binary": binary,
|
|
2121
|
+
"resolved_binary": resolved_binary,
|
|
2122
|
+
"config_dir": str(config.get("config_dir") or "~/.claude"),
|
|
2123
|
+
"model": requested_model,
|
|
2124
|
+
"requested_model": requested_model,
|
|
2125
|
+
"effective_model": requested_model,
|
|
2126
|
+
"permission_mode": permission_mode,
|
|
2127
|
+
"checked_at": checked_at,
|
|
2128
|
+
}
|
|
2129
|
+
if not resolved_binary:
|
|
2130
|
+
return {
|
|
2131
|
+
"ok": False,
|
|
2132
|
+
"summary": "Claude Code startup probe failed before execution.",
|
|
2133
|
+
"warnings": [],
|
|
2134
|
+
"errors": [f"Claude Code binary `{binary}` is not available."],
|
|
2135
|
+
"details": details,
|
|
2136
|
+
"guidance": self._runner_missing_binary_guidance("claude", config),
|
|
2137
|
+
}
|
|
2138
|
+
env = ensure_utf8_subprocess_env(os.environ.copy())
|
|
2139
|
+
env.update(self._claude_auth_runner_env(self._codex_runner_env(config)))
|
|
2140
|
+
temp_home_handle = tempfile.TemporaryDirectory()
|
|
2141
|
+
try:
|
|
2142
|
+
temp_home = Path(temp_home_handle.name)
|
|
2143
|
+
source_home = Path(str(config.get("config_dir") or Path.home() / ".claude")).expanduser()
|
|
2144
|
+
for filename in (".credentials.json", "settings.json", "settings.local.json"):
|
|
2145
|
+
self._copy_runner_file_if_exists(source_home / filename, temp_home / filename)
|
|
2146
|
+
env["CLAUDE_CONFIG_DIR"] = str(temp_home)
|
|
2147
|
+
command = [
|
|
2148
|
+
resolved_binary,
|
|
2149
|
+
"-p",
|
|
2150
|
+
"--input-format",
|
|
2151
|
+
"text",
|
|
2152
|
+
"--output-format",
|
|
2153
|
+
"json",
|
|
2154
|
+
"--add-dir",
|
|
2155
|
+
str(repo_root()),
|
|
2156
|
+
"--no-session-persistence",
|
|
2157
|
+
"--permission-mode",
|
|
2158
|
+
permission_mode,
|
|
2159
|
+
]
|
|
2160
|
+
if requested_model.lower() not in {"", "inherit", "default", "claude-default"}:
|
|
2161
|
+
command.extend(["--model", requested_model])
|
|
2162
|
+
command.extend(["--tools", ""])
|
|
2163
|
+
result = subprocess.run(
|
|
2164
|
+
command,
|
|
2165
|
+
input="Reply with exactly HELLO.",
|
|
2166
|
+
cwd=str(repo_root()),
|
|
2167
|
+
env=env,
|
|
2168
|
+
capture_output=True,
|
|
2169
|
+
timeout=90,
|
|
2170
|
+
check=False,
|
|
2171
|
+
**utf8_text_subprocess_kwargs(),
|
|
2172
|
+
)
|
|
2173
|
+
except subprocess.TimeoutExpired as exc:
|
|
2174
|
+
details.update({
|
|
2175
|
+
"exit_code": None,
|
|
2176
|
+
"stdout_excerpt": self._compact_probe_text(exc.stdout or ""),
|
|
2177
|
+
"stderr_excerpt": self._compact_probe_text(exc.stderr or ""),
|
|
2178
|
+
})
|
|
2179
|
+
return {
|
|
2180
|
+
"ok": False,
|
|
2181
|
+
"summary": "Claude Code startup probe timed out.",
|
|
2182
|
+
"warnings": [],
|
|
2183
|
+
"errors": ["Claude Code did not answer the startup probe within 90 seconds."],
|
|
2184
|
+
"details": details,
|
|
2185
|
+
"guidance": [
|
|
2186
|
+
"Run a small headless Claude Code request manually and confirm it can answer before starting DeepScientist.",
|
|
2187
|
+
],
|
|
2188
|
+
}
|
|
2189
|
+
finally:
|
|
2190
|
+
temp_home_handle.cleanup()
|
|
2191
|
+
stdout_text = (result.stdout or "").strip()
|
|
2192
|
+
stderr_text = (result.stderr or "").strip()
|
|
2193
|
+
ok = result.returncode == 0 and "HELLO" in f"{stdout_text}\n{stderr_text}".upper()
|
|
2194
|
+
details.update({
|
|
2195
|
+
"exit_code": result.returncode,
|
|
2196
|
+
"stdout_excerpt": self._compact_probe_text(stdout_text),
|
|
2197
|
+
"stderr_excerpt": self._compact_probe_text(stderr_text),
|
|
2198
|
+
"probe_command": command,
|
|
2199
|
+
})
|
|
2200
|
+
return {
|
|
2201
|
+
"ok": ok,
|
|
2202
|
+
"summary": "Claude Code startup probe completed." if ok else "Claude Code startup probe failed.",
|
|
2203
|
+
"warnings": ["Claude Code returned stderr during the startup probe."] if stderr_text else [],
|
|
2204
|
+
"errors": [] if ok else ["Claude Code did not complete the startup hello probe successfully."],
|
|
2205
|
+
"details": details,
|
|
2206
|
+
"guidance": [] if ok else [
|
|
2207
|
+
"Run `claude -p \"Reply with exactly HELLO.\" --output-format json --tools \"\"` manually and confirm it returns `HELLO`.",
|
|
2208
|
+
"If Claude Code uses a custom account or credential path, point `runners.claude.config_dir` at the correct home.",
|
|
2209
|
+
],
|
|
2210
|
+
}
|
|
2211
|
+
|
|
2212
|
+
def _probe_opencode_runner(self, config: dict) -> dict:
|
|
2213
|
+
checked_at = utc_now()
|
|
2214
|
+
binary = str(config.get("binary") or "opencode").strip() or "opencode"
|
|
2215
|
+
resolved_binary = resolve_runner_binary(binary, runner_name="opencode")
|
|
2216
|
+
requested_model = str(config.get("model") or "inherit").strip() or "inherit"
|
|
2217
|
+
variant = str(config.get("variant") or "").strip() or None
|
|
2218
|
+
permission_mode = str(config.get("permission_mode") or "allow").strip().lower() or "allow"
|
|
2219
|
+
details: dict[str, object] = {
|
|
2220
|
+
"binary": binary,
|
|
2221
|
+
"resolved_binary": resolved_binary,
|
|
2222
|
+
"config_dir": str(config.get("config_dir") or "~/.config/opencode"),
|
|
2223
|
+
"model": requested_model,
|
|
2224
|
+
"requested_model": requested_model,
|
|
2225
|
+
"effective_model": requested_model,
|
|
2226
|
+
"variant": variant,
|
|
2227
|
+
"permission_mode": permission_mode,
|
|
2228
|
+
"checked_at": checked_at,
|
|
2229
|
+
}
|
|
2230
|
+
if not resolved_binary:
|
|
2231
|
+
return {
|
|
2232
|
+
"ok": False,
|
|
2233
|
+
"summary": "OpenCode startup probe failed before execution.",
|
|
2234
|
+
"warnings": [],
|
|
2235
|
+
"errors": [f"OpenCode binary `{binary}` is not available."],
|
|
2236
|
+
"details": details,
|
|
2237
|
+
"guidance": self._runner_missing_binary_guidance("opencode", config),
|
|
2238
|
+
}
|
|
2239
|
+
env = ensure_utf8_subprocess_env(os.environ.copy())
|
|
2240
|
+
env.update(self._codex_runner_env(config))
|
|
2241
|
+
temp_home_handle = tempfile.TemporaryDirectory()
|
|
2242
|
+
try:
|
|
2243
|
+
temp_home = Path(temp_home_handle.name)
|
|
2244
|
+
config_root = temp_home / ".config" / "opencode"
|
|
2245
|
+
config_root.mkdir(parents=True, exist_ok=True)
|
|
2246
|
+
source_root = Path(str(config.get("config_dir") or Path.home() / ".config" / "opencode")).expanduser()
|
|
2247
|
+
self._copy_runner_file_if_exists(source_root / "opencode.json", config_root / "opencode.json")
|
|
2248
|
+
env["HOME"] = str(temp_home)
|
|
2249
|
+
env["XDG_CONFIG_HOME"] = str(temp_home / ".config")
|
|
2250
|
+
command = [
|
|
2251
|
+
resolved_binary,
|
|
2252
|
+
"run",
|
|
2253
|
+
"--format",
|
|
2254
|
+
"json",
|
|
2255
|
+
"--pure",
|
|
2256
|
+
"--dir",
|
|
2257
|
+
str(repo_root()),
|
|
2258
|
+
]
|
|
2259
|
+
if requested_model.lower() not in {"", "inherit", "default", "opencode-default"}:
|
|
2260
|
+
command.extend(["--model", requested_model])
|
|
2261
|
+
if variant:
|
|
2262
|
+
command.extend(["--variant", variant])
|
|
2263
|
+
command.append("Reply with exactly HELLO")
|
|
2264
|
+
result = subprocess.run(
|
|
2265
|
+
command,
|
|
2266
|
+
cwd=str(repo_root()),
|
|
2267
|
+
env=env,
|
|
2268
|
+
capture_output=True,
|
|
2269
|
+
timeout=90,
|
|
2270
|
+
check=False,
|
|
2271
|
+
**utf8_text_subprocess_kwargs(),
|
|
2272
|
+
)
|
|
2273
|
+
except subprocess.TimeoutExpired as exc:
|
|
2274
|
+
details.update({
|
|
2275
|
+
"exit_code": None,
|
|
2276
|
+
"stdout_excerpt": self._compact_probe_text(exc.stdout or ""),
|
|
2277
|
+
"stderr_excerpt": self._compact_probe_text(exc.stderr or ""),
|
|
2278
|
+
})
|
|
2279
|
+
return {
|
|
2280
|
+
"ok": False,
|
|
2281
|
+
"summary": "OpenCode startup probe timed out.",
|
|
2282
|
+
"warnings": [],
|
|
2283
|
+
"errors": ["OpenCode did not answer the startup probe within 90 seconds."],
|
|
2284
|
+
"details": details,
|
|
2285
|
+
"guidance": [
|
|
2286
|
+
"Run a small `opencode run --format json` request manually and confirm it can answer before starting DeepScientist.",
|
|
2287
|
+
],
|
|
2288
|
+
}
|
|
2289
|
+
finally:
|
|
2290
|
+
temp_home_handle.cleanup()
|
|
2291
|
+
stdout_text = (result.stdout or "").strip()
|
|
2292
|
+
stderr_text = (result.stderr or "").strip()
|
|
2293
|
+
ok = result.returncode == 0 and "HELLO" in f"{stdout_text}\n{stderr_text}".upper()
|
|
2294
|
+
details.update({
|
|
2295
|
+
"exit_code": result.returncode,
|
|
2296
|
+
"stdout_excerpt": self._compact_probe_text(stdout_text),
|
|
2297
|
+
"stderr_excerpt": self._compact_probe_text(stderr_text),
|
|
2298
|
+
"probe_command": command,
|
|
2299
|
+
})
|
|
2300
|
+
return {
|
|
2301
|
+
"ok": ok,
|
|
2302
|
+
"summary": "OpenCode startup probe completed." if ok else "OpenCode startup probe failed.",
|
|
2303
|
+
"warnings": ["OpenCode returned stderr during the startup probe."] if stderr_text else [],
|
|
2304
|
+
"errors": [] if ok else ["OpenCode did not complete the startup hello probe successfully."],
|
|
2305
|
+
"details": details,
|
|
2306
|
+
"guidance": [] if ok else [
|
|
2307
|
+
"Run `opencode run --format json \"Reply with exactly HELLO\"` manually and confirm it succeeds.",
|
|
2308
|
+
"If OpenCode uses a custom config root, point `runners.opencode.config_dir` at the correct directory.",
|
|
2309
|
+
],
|
|
2310
|
+
}
|
|
2311
|
+
|
|
2312
|
+
def _probe_kimi_runner(self, config: dict) -> dict:
|
|
2313
|
+
checked_at = utc_now()
|
|
2314
|
+
binary = str(config.get("binary") or "kimi").strip() or "kimi"
|
|
2315
|
+
resolved_binary = resolve_runner_binary(binary, runner_name="kimi")
|
|
2316
|
+
requested_model = str(config.get("model") or "inherit").strip() or "inherit"
|
|
2317
|
+
agent_name = str(config.get("agent") or "").strip() or None
|
|
2318
|
+
yolo_enabled = bool(config.get("yolo", True))
|
|
2319
|
+
thinking_enabled = bool(config.get("thinking", False))
|
|
2320
|
+
details: dict[str, object] = {
|
|
2321
|
+
"binary": binary,
|
|
2322
|
+
"resolved_binary": resolved_binary,
|
|
2323
|
+
"config_dir": str(config.get("config_dir") or "~/.kimi"),
|
|
2324
|
+
"model": requested_model,
|
|
2325
|
+
"requested_model": requested_model,
|
|
2326
|
+
"effective_model": requested_model,
|
|
2327
|
+
"agent": agent_name,
|
|
2328
|
+
"thinking": thinking_enabled,
|
|
2329
|
+
"yolo": yolo_enabled,
|
|
2330
|
+
"checked_at": checked_at,
|
|
2331
|
+
}
|
|
2332
|
+
if not resolved_binary:
|
|
2333
|
+
return {
|
|
2334
|
+
"ok": False,
|
|
2335
|
+
"summary": "Kimi Code startup probe failed before execution.",
|
|
2336
|
+
"warnings": [],
|
|
2337
|
+
"errors": [f"Kimi Code binary `{binary}` is not available."],
|
|
2338
|
+
"details": details,
|
|
2339
|
+
"guidance": self._runner_missing_binary_guidance("kimi", config),
|
|
2340
|
+
}
|
|
2341
|
+
env = ensure_utf8_subprocess_env(os.environ.copy())
|
|
2342
|
+
env.update(self._codex_runner_env(config))
|
|
2343
|
+
temp_home_handle = tempfile.TemporaryDirectory()
|
|
2344
|
+
try:
|
|
2345
|
+
temp_home = Path(temp_home_handle.name)
|
|
2346
|
+
kimi_home = materialize_kimi_runtime_home(
|
|
2347
|
+
source_home=Path(str(config.get("config_dir") or Path.home() / ".kimi")).expanduser(),
|
|
2348
|
+
target_home=temp_home,
|
|
2349
|
+
)
|
|
2350
|
+
mcp_config_path = kimi_home / "mcp.json"
|
|
2351
|
+
write_json(mcp_config_path, {"mcpServers": {}})
|
|
2352
|
+
env["HOME"] = str(temp_home)
|
|
2353
|
+
env["USERPROFILE"] = str(temp_home)
|
|
2354
|
+
command = [
|
|
2355
|
+
resolved_binary,
|
|
2356
|
+
"--print",
|
|
2357
|
+
"--input-format",
|
|
2358
|
+
"text",
|
|
2359
|
+
"--output-format",
|
|
2360
|
+
"stream-json",
|
|
2361
|
+
"--work-dir",
|
|
2362
|
+
str(repo_root()),
|
|
2363
|
+
"--mcp-config-file",
|
|
2364
|
+
str(mcp_config_path),
|
|
2365
|
+
]
|
|
2366
|
+
if yolo_enabled:
|
|
2367
|
+
command.append("--yolo")
|
|
2368
|
+
if requested_model.lower() not in {"", "inherit", "default", "kimi-default"}:
|
|
2369
|
+
command.extend(["--model", requested_model])
|
|
2370
|
+
if agent_name:
|
|
2371
|
+
command.extend(["--agent", agent_name])
|
|
2372
|
+
if thinking_enabled:
|
|
2373
|
+
command.append("--thinking")
|
|
2374
|
+
result = subprocess.run(
|
|
2375
|
+
command,
|
|
2376
|
+
input="Reply with exactly HELLO.",
|
|
2377
|
+
cwd=str(repo_root()),
|
|
2378
|
+
env=env,
|
|
2379
|
+
capture_output=True,
|
|
2380
|
+
timeout=90,
|
|
2381
|
+
check=False,
|
|
2382
|
+
**utf8_text_subprocess_kwargs(),
|
|
2383
|
+
)
|
|
2384
|
+
except subprocess.TimeoutExpired as exc:
|
|
2385
|
+
details.update(
|
|
2386
|
+
{
|
|
2387
|
+
"exit_code": None,
|
|
2388
|
+
"stdout_excerpt": self._compact_probe_text(exc.stdout or ""),
|
|
2389
|
+
"stderr_excerpt": self._compact_probe_text(exc.stderr or ""),
|
|
2390
|
+
}
|
|
2391
|
+
)
|
|
2392
|
+
return {
|
|
2393
|
+
"ok": False,
|
|
2394
|
+
"summary": "Kimi Code startup probe timed out.",
|
|
2395
|
+
"warnings": [],
|
|
2396
|
+
"errors": ["Kimi Code did not answer the startup probe within 90 seconds."],
|
|
2397
|
+
"details": details,
|
|
2398
|
+
"guidance": [
|
|
2399
|
+
"Run a small `kimi --print --output-format stream-json` request manually and confirm it can answer before starting DeepScientist.",
|
|
2400
|
+
],
|
|
2401
|
+
}
|
|
2402
|
+
finally:
|
|
2403
|
+
temp_home_handle.cleanup()
|
|
2404
|
+
stdout_text = (result.stdout or "").strip()
|
|
2405
|
+
stderr_text = (result.stderr or "").strip()
|
|
2406
|
+
ok = result.returncode == 0 and "HELLO" in f"{stdout_text}\n{stderr_text}".upper()
|
|
2407
|
+
details.update(
|
|
2408
|
+
{
|
|
2409
|
+
"exit_code": result.returncode,
|
|
2410
|
+
"stdout_excerpt": self._compact_probe_text(stdout_text),
|
|
2411
|
+
"stderr_excerpt": self._compact_probe_text(stderr_text),
|
|
2412
|
+
"probe_command": command,
|
|
2413
|
+
}
|
|
2414
|
+
)
|
|
2415
|
+
return {
|
|
2416
|
+
"ok": ok,
|
|
2417
|
+
"summary": "Kimi Code startup probe completed." if ok else "Kimi Code startup probe failed.",
|
|
2418
|
+
"warnings": ["Kimi Code returned stderr during the startup probe."] if stderr_text else [],
|
|
2419
|
+
"errors": [] if ok else ["Kimi Code did not complete the startup hello probe successfully."],
|
|
2420
|
+
"details": details,
|
|
2421
|
+
"guidance": [] if ok else [
|
|
2422
|
+
"Run `kimi --print --input-format text --output-format stream-json --yolo` manually and confirm it returns `HELLO`.",
|
|
2423
|
+
"Run `kimi login` first if this machine has not completed the Kimi Code login flow yet.",
|
|
2424
|
+
"If Kimi Code uses a custom home, point `runners.kimi.config_dir` at the correct `~/.kimi`-style directory.",
|
|
2425
|
+
],
|
|
2426
|
+
}
|
|
2427
|
+
|
|
1761
2428
|
@staticmethod
|
|
1762
2429
|
def _compact_probe_text(value: str, *, limit: int = 1200) -> str:
|
|
1763
2430
|
text = str(value or "").strip()
|
|
@@ -2012,11 +2679,31 @@ Use **Test** when the file exposes runtime dependencies.
|
|
|
2012
2679
|
defaults = default_payload(name, self.home)
|
|
2013
2680
|
if name == "runners":
|
|
2014
2681
|
normalized = self._deep_merge(defaults, prepared)
|
|
2682
|
+
runtime_enabled_runners = self._runtime_enabled_runner_names()
|
|
2015
2683
|
codex = normalized.get("codex")
|
|
2016
|
-
if isinstance(codex, dict)
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2684
|
+
if isinstance(codex, dict):
|
|
2685
|
+
if self._looks_like_legacy_codex_retry_profile(codex):
|
|
2686
|
+
codex["retry_initial_backoff_sec"] = 10.0
|
|
2687
|
+
codex["retry_backoff_multiplier"] = 6.0
|
|
2688
|
+
codex["retry_max_backoff_sec"] = 1800.0
|
|
2689
|
+
if self._looks_like_preupgrade_codex_retry_attempt_profile(codex):
|
|
2690
|
+
codex["retry_max_attempts"] = 7
|
|
2691
|
+
claude = normalized.get("claude")
|
|
2692
|
+
if isinstance(claude, dict):
|
|
2693
|
+
legacy_approval_policy = str(claude.get("approval_policy") or "").strip().lower()
|
|
2694
|
+
if legacy_approval_policy and not str(claude.get("permission_mode") or "").strip():
|
|
2695
|
+
if legacy_approval_policy == "never":
|
|
2696
|
+
claude["permission_mode"] = "bypassPermissions"
|
|
2697
|
+
elif legacy_approval_policy in {"on-request", "default"}:
|
|
2698
|
+
claude["permission_mode"] = "default"
|
|
2699
|
+
if "approval_policy" in claude:
|
|
2700
|
+
claude.pop("approval_policy", None)
|
|
2701
|
+
if "sandbox_mode" in claude:
|
|
2702
|
+
claude.pop("sandbox_mode", None)
|
|
2703
|
+
for runner_name in runtime_enabled_runners:
|
|
2704
|
+
runner_config = normalized.get(runner_name)
|
|
2705
|
+
if isinstance(runner_config, dict):
|
|
2706
|
+
runner_config["enabled"] = True
|
|
2020
2707
|
return normalized
|
|
2021
2708
|
if name == "connectors":
|
|
2022
2709
|
normalized = deepcopy(defaults)
|
|
@@ -2061,9 +2748,44 @@ Use **Test** when the file exposes runtime dependencies.
|
|
|
2061
2748
|
return normalized
|
|
2062
2749
|
return self._deep_merge(defaults, prepared)
|
|
2063
2750
|
|
|
2751
|
+
@staticmethod
|
|
2752
|
+
def _normalize_runtime_runner_name(value: object) -> str:
|
|
2753
|
+
normalized = str(value or "").strip().lower().replace("_", "-")
|
|
2754
|
+
if normalized in {"claude-code", "claudecode"}:
|
|
2755
|
+
return "claude"
|
|
2756
|
+
if normalized in {"kimi-code", "kimicode"}:
|
|
2757
|
+
return "kimi"
|
|
2758
|
+
if normalized in {"open-code", "open code", "opencode-ai", "opencodeai"}:
|
|
2759
|
+
return "opencode"
|
|
2760
|
+
return normalized.replace("-", "")
|
|
2761
|
+
|
|
2762
|
+
@classmethod
|
|
2763
|
+
def _runtime_enabled_runner_names(cls) -> set[str]:
|
|
2764
|
+
names: set[str] = set()
|
|
2765
|
+
raw_values = [
|
|
2766
|
+
os.environ.get("DEEPSCIENTIST_DEFAULT_RUNNER"),
|
|
2767
|
+
os.environ.get("DS_DEFAULT_RUNNER"),
|
|
2768
|
+
os.environ.get("DEEPSCIENTIST_ENABLE_RUNNER"),
|
|
2769
|
+
os.environ.get("DS_ENABLE_RUNNER"),
|
|
2770
|
+
os.environ.get("DEEPSCIENTIST_ENABLE_RUNNERS"),
|
|
2771
|
+
os.environ.get("DS_ENABLE_RUNNERS"),
|
|
2772
|
+
]
|
|
2773
|
+
for raw_value in raw_values:
|
|
2774
|
+
for item in str(raw_value or "").replace(";", ",").split(","):
|
|
2775
|
+
normalized = cls._normalize_runtime_runner_name(item)
|
|
2776
|
+
if normalized:
|
|
2777
|
+
names.add(normalized)
|
|
2778
|
+
return names
|
|
2779
|
+
|
|
2064
2780
|
def _normalize_config_payload(self, payload: dict) -> dict:
|
|
2065
2781
|
defaults = default_payload("config", self.home)
|
|
2066
2782
|
normalized = self._deep_merge(defaults, payload)
|
|
2783
|
+
default_runner_override = str(
|
|
2784
|
+
os.environ.get("DEEPSCIENTIST_DEFAULT_RUNNER") or os.environ.get("DS_DEFAULT_RUNNER") or ""
|
|
2785
|
+
).strip().lower()
|
|
2786
|
+
default_runner_override = self._normalize_runtime_runner_name(default_runner_override)
|
|
2787
|
+
if default_runner_override:
|
|
2788
|
+
normalized["default_runner"] = default_runner_override
|
|
2067
2789
|
bootstrap = normalized.get("bootstrap") if isinstance(normalized.get("bootstrap"), dict) else {}
|
|
2068
2790
|
raw_bootstrap = payload.get("bootstrap") if isinstance(payload.get("bootstrap"), dict) else {}
|
|
2069
2791
|
connectors = normalized.get("connectors") if isinstance(normalized.get("connectors"), dict) else {}
|
|
@@ -2090,6 +2812,25 @@ Use **Test** when the file exposes runtime dependencies.
|
|
|
2090
2812
|
bootstrap["locale_initialized_from_browser"] = locale_initialized_from_browser
|
|
2091
2813
|
bootstrap["locale_initialized_at"] = bootstrap.get("locale_initialized_at")
|
|
2092
2814
|
bootstrap["locale_initialized_browser_locale"] = bootstrap.get("locale_initialized_browser_locale")
|
|
2815
|
+
runner_readiness = bootstrap.get("runner_readiness") if isinstance(bootstrap.get("runner_readiness"), dict) else {}
|
|
2816
|
+
normalized_runner_readiness: dict[str, dict[str, Any]] = {}
|
|
2817
|
+
for runner_name in list_builtin_runner_names():
|
|
2818
|
+
state = runner_readiness.get(runner_name) if isinstance(runner_readiness.get(runner_name), dict) else {}
|
|
2819
|
+
if runner_name == "codex" and not state:
|
|
2820
|
+
state = {
|
|
2821
|
+
"ready": bool(bootstrap.get("codex_ready", False)),
|
|
2822
|
+
"last_checked_at": bootstrap.get("codex_last_checked_at"),
|
|
2823
|
+
"last_result": bootstrap.get("codex_last_result") if isinstance(bootstrap.get("codex_last_result"), dict) else {},
|
|
2824
|
+
}
|
|
2825
|
+
normalized_runner_readiness[runner_name] = {
|
|
2826
|
+
"ready": bool(state.get("ready", False)),
|
|
2827
|
+
"last_checked_at": state.get("last_checked_at"),
|
|
2828
|
+
"last_result": state.get("last_result") if isinstance(state.get("last_result"), dict) else {},
|
|
2829
|
+
}
|
|
2830
|
+
bootstrap["runner_readiness"] = normalized_runner_readiness
|
|
2831
|
+
bootstrap["codex_ready"] = bool(normalized_runner_readiness.get("codex", {}).get("ready", False))
|
|
2832
|
+
bootstrap["codex_last_checked_at"] = normalized_runner_readiness.get("codex", {}).get("last_checked_at")
|
|
2833
|
+
bootstrap["codex_last_result"] = normalized_runner_readiness.get("codex", {}).get("last_result") if isinstance(normalized_runner_readiness.get("codex", {}).get("last_result"), dict) else {}
|
|
2093
2834
|
normalized["bootstrap"] = bootstrap
|
|
2094
2835
|
raw_system_enabled = raw_connectors.get("system_enabled") if isinstance(raw_connectors.get("system_enabled"), dict) else {}
|
|
2095
2836
|
default_system_enabled = (
|
|
@@ -2110,6 +2851,85 @@ Use **Test** when the file exposes runtime dependencies.
|
|
|
2110
2851
|
for name in SYSTEM_CONNECTOR_NAMES
|
|
2111
2852
|
}
|
|
2112
2853
|
normalized["connectors"] = connectors
|
|
2854
|
+
hardware = normalized.get("hardware") if isinstance(normalized.get("hardware"), dict) else {}
|
|
2855
|
+
raw_hardware = payload.get("hardware") if isinstance(payload.get("hardware"), dict) else {}
|
|
2856
|
+
gpu_selection_mode = str(raw_hardware.get("gpu_selection_mode") or hardware.get("gpu_selection_mode") or "all").strip().lower()
|
|
2857
|
+
if gpu_selection_mode not in {"all", "selected"}:
|
|
2858
|
+
gpu_selection_mode = "all"
|
|
2859
|
+
raw_selected_gpu_ids = raw_hardware.get("selected_gpu_ids", hardware.get("selected_gpu_ids", []))
|
|
2860
|
+
selected_gpu_ids: list[str] = []
|
|
2861
|
+
if isinstance(raw_selected_gpu_ids, list):
|
|
2862
|
+
for item in raw_selected_gpu_ids:
|
|
2863
|
+
normalized_id = str(item or "").strip()
|
|
2864
|
+
if normalized_id and normalized_id not in selected_gpu_ids:
|
|
2865
|
+
selected_gpu_ids.append(normalized_id)
|
|
2866
|
+
elif isinstance(raw_selected_gpu_ids, str):
|
|
2867
|
+
for item in raw_selected_gpu_ids.split(","):
|
|
2868
|
+
normalized_id = item.strip()
|
|
2869
|
+
if normalized_id and normalized_id not in selected_gpu_ids:
|
|
2870
|
+
selected_gpu_ids.append(normalized_id)
|
|
2871
|
+
hardware["gpu_selection_mode"] = gpu_selection_mode
|
|
2872
|
+
hardware["selected_gpu_ids"] = selected_gpu_ids
|
|
2873
|
+
hardware["include_system_hardware_in_prompt"] = self._coerce_bool(
|
|
2874
|
+
raw_hardware.get(
|
|
2875
|
+
"include_system_hardware_in_prompt",
|
|
2876
|
+
hardware.get("include_system_hardware_in_prompt", True),
|
|
2877
|
+
),
|
|
2878
|
+
default=True,
|
|
2879
|
+
)
|
|
2880
|
+
normalized["hardware"] = hardware
|
|
2881
|
+
memory = normalized.get("memory") if isinstance(normalized.get("memory"), dict) else {}
|
|
2882
|
+
raw_memory = payload.get("memory") if isinstance(payload.get("memory"), dict) else {}
|
|
2883
|
+
read_visibility_mode = str(
|
|
2884
|
+
raw_memory.get("read_visibility_mode", memory.get("read_visibility_mode", "independent")) or "independent"
|
|
2885
|
+
).strip().lower()
|
|
2886
|
+
if read_visibility_mode not in {"independent", "shared_across_quests"}:
|
|
2887
|
+
read_visibility_mode = "independent"
|
|
2888
|
+
memory["read_visibility_mode"] = read_visibility_mode
|
|
2889
|
+
normalized["memory"] = memory
|
|
2890
|
+
literature = normalized.get("literature") if isinstance(normalized.get("literature"), dict) else {}
|
|
2891
|
+
raw_literature = payload.get("literature") if isinstance(payload.get("literature"), dict) else {}
|
|
2892
|
+
default_literature = defaults.get("literature") if isinstance(defaults.get("literature"), dict) else {}
|
|
2893
|
+
deepxiv_defaults = default_literature.get("deepxiv") if isinstance(default_literature.get("deepxiv"), dict) else {}
|
|
2894
|
+
deepxiv = literature.get("deepxiv") if isinstance(literature.get("deepxiv"), dict) else {}
|
|
2895
|
+
raw_deepxiv = raw_literature.get("deepxiv") if isinstance(raw_literature.get("deepxiv"), dict) else {}
|
|
2896
|
+
deepxiv["enabled"] = self._coerce_bool(
|
|
2897
|
+
raw_deepxiv.get("enabled", deepxiv.get("enabled", deepxiv_defaults.get("enabled", False))),
|
|
2898
|
+
default=bool(deepxiv_defaults.get("enabled", False)),
|
|
2899
|
+
)
|
|
2900
|
+
deepxiv["base_url"] = str(
|
|
2901
|
+
raw_deepxiv.get("base_url", deepxiv.get("base_url", deepxiv_defaults.get("base_url", "https://data.rag.ac.cn"))) or ""
|
|
2902
|
+
).strip() or str(deepxiv_defaults.get("base_url") or "https://data.rag.ac.cn")
|
|
2903
|
+
deepxiv["token"] = str(raw_deepxiv.get("token", deepxiv.get("token", "")) or "").strip() or None
|
|
2904
|
+
deepxiv["token_env"] = str(
|
|
2905
|
+
raw_deepxiv.get("token_env", deepxiv.get("token_env", deepxiv_defaults.get("token_env", "DEEPXIV_TOKEN"))) or ""
|
|
2906
|
+
).strip() or None
|
|
2907
|
+
try:
|
|
2908
|
+
raw_result_size = raw_deepxiv.get(
|
|
2909
|
+
"default_result_size",
|
|
2910
|
+
deepxiv.get("default_result_size", deepxiv_defaults.get("default_result_size", 10)),
|
|
2911
|
+
)
|
|
2912
|
+
deepxiv["default_result_size"] = max(1, int(raw_result_size))
|
|
2913
|
+
except (TypeError, ValueError):
|
|
2914
|
+
deepxiv["default_result_size"] = int(deepxiv_defaults.get("default_result_size", 10) or 10)
|
|
2915
|
+
try:
|
|
2916
|
+
raw_preview_characters = raw_deepxiv.get(
|
|
2917
|
+
"preview_characters",
|
|
2918
|
+
deepxiv.get("preview_characters", deepxiv_defaults.get("preview_characters", 1200)),
|
|
2919
|
+
)
|
|
2920
|
+
deepxiv["preview_characters"] = max(200, int(raw_preview_characters))
|
|
2921
|
+
except (TypeError, ValueError):
|
|
2922
|
+
deepxiv["preview_characters"] = int(deepxiv_defaults.get("preview_characters", 1200) or 1200)
|
|
2923
|
+
try:
|
|
2924
|
+
raw_timeout = raw_deepxiv.get(
|
|
2925
|
+
"request_timeout_seconds",
|
|
2926
|
+
deepxiv.get("request_timeout_seconds", deepxiv_defaults.get("request_timeout_seconds", 20)),
|
|
2927
|
+
)
|
|
2928
|
+
deepxiv["request_timeout_seconds"] = max(3, int(raw_timeout))
|
|
2929
|
+
except (TypeError, ValueError):
|
|
2930
|
+
deepxiv["request_timeout_seconds"] = int(deepxiv_defaults.get("request_timeout_seconds", 20) or 20)
|
|
2931
|
+
literature["deepxiv"] = deepxiv
|
|
2932
|
+
normalized["literature"] = literature
|
|
2113
2933
|
return normalized
|
|
2114
2934
|
|
|
2115
2935
|
@staticmethod
|
|
@@ -2122,6 +2942,22 @@ Use **Test** when the file exposes runtime dependencies.
|
|
|
2122
2942
|
return False
|
|
2123
2943
|
return abs(initial - 1.0) < 1e-9 and abs(multiplier - 2.0) < 1e-9 and abs(max_backoff - 8.0) < 1e-9
|
|
2124
2944
|
|
|
2945
|
+
@staticmethod
|
|
2946
|
+
def _looks_like_preupgrade_codex_retry_attempt_profile(payload: dict) -> bool:
|
|
2947
|
+
try:
|
|
2948
|
+
max_attempts = int(payload.get("retry_max_attempts"))
|
|
2949
|
+
initial = float(payload.get("retry_initial_backoff_sec"))
|
|
2950
|
+
multiplier = float(payload.get("retry_backoff_multiplier"))
|
|
2951
|
+
max_backoff = float(payload.get("retry_max_backoff_sec"))
|
|
2952
|
+
except (TypeError, ValueError):
|
|
2953
|
+
return False
|
|
2954
|
+
return (
|
|
2955
|
+
max_attempts == 5
|
|
2956
|
+
and abs(initial - 10.0) < 1e-9
|
|
2957
|
+
and abs(multiplier - 6.0) < 1e-9
|
|
2958
|
+
and abs(max_backoff - 1800.0) < 1e-9
|
|
2959
|
+
)
|
|
2960
|
+
|
|
2125
2961
|
@staticmethod
|
|
2126
2962
|
def _coerce_bool(value: object, *, default: bool = False) -> bool:
|
|
2127
2963
|
if value is None:
|