@dsh-bio/dsh-bio-gem 0.1.3 → 0.1.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +60 -8
- package/docs/ARCHITECTURE.md +145 -116
- package/docs/DECISIONS-2026-09-21.md +76 -0
- package/docs/releases/v0.1.12.md +43 -0
- package/package.json +5 -3
- package/python/benchmark.py +3 -3
- package/python/biomass_tools.py +2 -2
- package/python/bootstrap_carveme.py +259 -0
- package/python/build.py +10 -2
- package/python/coherence.py +159 -0
- package/python/double_knockout.py +1 -1
- package/python/essential_scan.py +1 -1
- package/python/gapfind.py +413 -396
- package/python/gem_ops.py +64 -1
- package/python/l3_fix.py +4 -4
- package/python/ledger.py +1 -1
- package/python/model_card.py +3 -2
- package/python/precursor_scan.py +127 -0
- package/python/quality.py +577 -0
- package/python/sampling.py +269 -0
- package/python/sensitivity.py +2 -2
- package/python/validate.py +435 -409
- package/skills/gem-expert.md +3 -1
- package/src/capabilities.js +152 -0
- package/src/index.js +21 -2
- package/src/integration.js +507 -0
- package/src/jobs.js +5 -21
- package/src/python.js +113 -17
- package/src/tools.js +98 -22
package/README.md
CHANGED
|
@@ -14,12 +14,20 @@ Genome-scale metabolic model builder for dsh: genome in, validated SBML out.
|
|
|
14
14
|
|------|------|------|
|
|
15
15
|
| dsh 引擎 | 0.1.x(`npx -y @deepseek-ai/dsh --version` 可查) | 宿主 |
|
|
16
16
|
| Node.js | ≥ 22.19 或 ≥ 24(见 `package.json` 的 `engines`) | 宿主 |
|
|
17
|
-
| Python | 3.10+,且装 **`cobra`** | 分析/验证/补洞/账本/基准/导出 —— 除 `gem_build` 外的
|
|
17
|
+
| Python | 3.10+,且装 **`cobra`** | 分析/验证/补洞/账本/基准/导出 —— 除 `gem_build` 外的 22 个工具 |
|
|
18
18
|
| `pyrodigal` | 装在同一个 Python 环境(可选但建议) | 裸基因组自动注释兜底(`gem_annotate` / fna 输入) |
|
|
19
19
|
| **CarveMe** | 独立 venv `~/.dsh/dsh-bio-gem/venv-carveme`,含 `carve.exe` + **`diamond.exe`** | `gem_build`(carveme 引擎) |
|
|
20
20
|
| WSL2 + gapseq | 可选,按本机拓扑(见第 4 节) | `gem_build`(gapseq 引擎) |
|
|
21
21
|
|
|
22
|
-
>
|
|
22
|
+
> **Python 环境从哪来(v0.1.4 起)**:解释器探测顺序为
|
|
23
|
+
> `GEM_PYTHON` → **宿主 `dsh-bio-genie` 的自举环境** → `CONDA_PREFIX` → `PATH` 中的 `python`,
|
|
24
|
+
> 且会**逐个探测该解释器能否 `import cobra`**(不盲选)。
|
|
25
|
+
>
|
|
26
|
+
> 因此:**装了 dsh-bio-genie 就无需任何额外配置** —— genie 的自举环境自带 cobra
|
|
27
|
+
> (属它的第一层依赖),gem 直接复用。只有**未装 genie** 时才需要按第 2 步自备解释器。
|
|
28
|
+
>
|
|
29
|
+
> `gem_build`(构建侧)另有重依赖(CarveMe + `diamond`,或 WSL2 + gapseq),见第 3、4 步,
|
|
30
|
+
> 这部分不与 genie 共享环境。
|
|
23
31
|
|
|
24
32
|
### 1. 安装插件
|
|
25
33
|
|
|
@@ -34,9 +42,21 @@ npx -y @deepseek-ai/dsh plugin --profile web add github:moonbowterfly/dsh-bio-ge
|
|
|
34
42
|
npx -y @deepseek-ai/dsh plugin --profile web add ./dsh-bio-gem
|
|
35
43
|
```
|
|
36
44
|
|
|
45
|
+
**方式四:安装到 dsh 桌面端(0.2.0+,推荐)**——桌面端内置 dsh 命令与 pnpm,无需另装 Node/pnpm:
|
|
46
|
+
|
|
47
|
+
1. 先启动一次桌面端(初始化 `desktop` profile),**完全退出应用**;
|
|
48
|
+
2. 用桌面端自带 CLI 安装(Windows 默认安装路径):
|
|
49
|
+
|
|
50
|
+
```powershell
|
|
51
|
+
& "$env:LOCALAPPDATA\Programs\DeepSeek Harness\resources\runtime\cli\bin\dsh.cmd" plugin --profile desktop add @dsh-bio/dsh-bio-gem
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
3. 重新打开桌面端生效(也可直接在桌面端内 **「插件」页**输入包名安装,无需退出应用)。
|
|
55
|
+
|
|
37
56
|
- 本机若已全局安装 dsh CLI,把 `npx -y @deepseek-ai/dsh` 换成 `dsh` 即可。
|
|
38
|
-
- `--profile <name>` 是**必填选项**(不传报 `required option '--profile <name>' not specified`);Web 端固定用 `web`。
|
|
39
|
-
-
|
|
57
|
+
- `--profile <name>` 是**必填选项**(不传报 `required option '--profile <name>' not specified`);Web 端固定用 `web`,桌面端固定用 `desktop`。
|
|
58
|
+
- 安装完**重启对应的 dsh**(web:重新双击启动入口;桌面端:重开应用)。
|
|
59
|
+
- **引擎兼容**:0.1.x 侧经 dsh 0.1.5-rc.2 走廊逐卡走查与实机验证;**0.2.0+(含官方桌面端)已于 2026-10-01 实测**(工具全量注册 + `gem_media_resolve` 真实执行)。
|
|
40
60
|
- 版本刚发布时可能短时间拉不到:registry 首次分发有几分钟延迟,`pnpm` 还可能缓存住 404。遇到 `ERR_PNPM_FETCH_404 ... is not in the npm registry` 时等几分钟重试,或在命令末尾追加 `--registry https://registry.npmjs.org/` 绕过缓存。
|
|
41
61
|
|
|
42
62
|
验证插件层已生效(不用启动服务):
|
|
@@ -45,7 +65,12 @@ npx -y @deepseek-ai/dsh plugin --profile web add ./dsh-bio-gem
|
|
|
45
65
|
npx -y @deepseek-ai/dsh --profile web --dump-config | grep dsh-bio-gem
|
|
46
66
|
```
|
|
47
67
|
|
|
48
|
-
### 2. 准备分析用 Python(cobra
|
|
68
|
+
### 2. 准备分析用 Python(cobra)—— 装了 genie 就跳过
|
|
69
|
+
|
|
70
|
+
**已安装 `@dsh-bio/dsh-bio-genie` 时本节可跳过**:gem 自动复用 genie 的自举环境
|
|
71
|
+
(`$DSH_HOME/dsh-bio-genie/python-env`),其中 cobra 属 genie 的第一层依赖,无需任何配置。
|
|
72
|
+
|
|
73
|
+
未装 genie 时,自备一个装了 cobra 的解释器:
|
|
49
74
|
|
|
50
75
|
```sh
|
|
51
76
|
# uv 建独立 venv 并安装(推荐)
|
|
@@ -53,7 +78,7 @@ uv venv --python 3.11 "$HOME/.dsh/dsh-bio-gem/venv"
|
|
|
53
78
|
uv pip install --python "$HOME/.dsh/dsh-bio-gem/venv/Scripts/python.exe" cobra pyrodigal
|
|
54
79
|
```
|
|
55
80
|
|
|
56
|
-
|
|
81
|
+
用 `GEM_PYTHON` 指向它(**dsh 进程的环境变量,必须在启动 dsh 之前设置**):
|
|
57
82
|
|
|
58
83
|
```bat
|
|
59
84
|
:: cmd(写进启动脚本即可)
|
|
@@ -68,6 +93,10 @@ setx GEM_PYTHON "$env:USERPROFILE\.dsh\dsh-bio-gem\venv\Scripts\python.exe"
|
|
|
68
93
|
$env:GEM_PYTHON = "$env:USERPROFILE\.dsh\dsh-bio-gem\venv\Scripts\python.exe"
|
|
69
94
|
```
|
|
70
95
|
|
|
96
|
+
> 插件**不会盲选**解释器:它按上述顺序逐个探测 `import cobra`,选中第一个可用的并缓存。
|
|
97
|
+
> 若候选全都不含 cobra,工具会显式报 `ModuleNotFoundError: cobra` 并附带候选探测结果,
|
|
98
|
+
> 而不是静默落到一个不可用的解释器上。
|
|
99
|
+
|
|
71
100
|
### 3. 准备 CarveMe(构建引擎)
|
|
72
101
|
|
|
73
102
|
```sh
|
|
@@ -92,7 +121,7 @@ unzip -o diamond.zip diamond.exe -d "$HOME/.dsh/dsh-bio-gem/venv-carveme/Scripts
|
|
|
92
121
|
|
|
93
122
|
### 4.(可选)gapseq 引擎(WSL2)
|
|
94
123
|
|
|
95
|
-
`gem_build` 的 `engine=gapseq` 走 WSL2 桥(`gem_gapseq` 原子四步:setup / launch / status / fetch),质量档耗时 30-60 分钟/模型,非必需——默认的 `engine=carveme` 已能出可验证模型。桥按本机拓扑实现(WSL2 + `/opt/miniforge3` conda 环境 `gapseq` + 本地序列库),换机器需改 `python/gapseq_wsl.py` 顶部常量,故目前**视为实验性可选能力**。没有 WSL2 不影响其余
|
|
124
|
+
`gem_build` 的 `engine=gapseq` 走 WSL2 桥(`gem_gapseq` 原子四步:setup / launch / status / fetch),质量档耗时 30-60 分钟/模型,非必需——默认的 `engine=carveme` 已能出可验证模型。桥按本机拓扑实现(WSL2 + `/opt/miniforge3` conda 环境 `gapseq` + 本地序列库),换机器需改 `python/gapseq_wsl.py` 顶部常量,故目前**视为实验性可选能力**。没有 WSL2 不影响其余 22 个工具与 carveme 构建。
|
|
96
125
|
|
|
97
126
|
### 5. 自检(仓库源码目录内)
|
|
98
127
|
|
|
@@ -101,6 +130,8 @@ unzip -o diamond.zip diamond.exe -d "$HOME/.dsh/dsh-bio-gem/venv-carveme/Scripts
|
|
|
101
130
|
# 断言锚定本机 C58 夹具路径(见 test/smoke.js 顶部常量),换机器先改路径
|
|
102
131
|
GEM_PYTHON=<你的-cobra-python> node test/smoke.js --skip-build # 跳过 ~70s 的 build 单测
|
|
103
132
|
GEM_PYTHON=<你的-cobra-python> node test/smoke.js # 含 build 单测
|
|
133
|
+
# 托管领域扩展的只读 integration 协议(无需 dsh 实例)
|
|
134
|
+
node test/integration.js
|
|
104
135
|
```
|
|
105
136
|
|
|
106
137
|
### 6. 与 dsh-bio-genie 协同
|
|
@@ -114,6 +145,22 @@ GEM_PYTHON=<你的-cobra-python> node test/smoke.js # 含 build
|
|
|
114
145
|
|
|
115
146
|
装好 genie 后,其 agent 常驻 persona 已内置 GEM 能力域路由,「建模型 / 建模 / 补洞」类需求会自动转给 `gem_*` 工具。
|
|
116
147
|
|
|
148
|
+
#### 托管领域扩展集成协议(v0.1.11+)
|
|
149
|
+
|
|
150
|
+
当 gem 与 BioGenie 运行在同一 dsh Web 实例时,gem 提供两个**固定、只读、loopback-only** 的端点:
|
|
151
|
+
|
|
152
|
+
```text
|
|
153
|
+
GET /api/dsh-bio-gem/integration/health
|
|
154
|
+
GET /api/dsh-bio-gem/integration/v1/status
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
- 两端点统一返回 `{ ok: true, value }` 或 `{ ok: false, code, message }`;health 只声明插件身份与协议能力,绝不启动 Python 或写盘。
|
|
158
|
+
- status 返回模型/账本/导出的限量摘要、解释器与构建引擎的只读检查;`state` 仅为 `ready` 或 `degraded`。Python/cobra 仍在进程内短缓存;WSL/gapseq 则采用非阻塞 stale-while-revalidate:首次返回 `available: null` / `probing` 与 `warn`,后台完成后才转为 `ok` 或 `missing`,不会把 status 响应拖到超时。
|
|
159
|
+
- gapseq 成功结果缓存 5 分钟;失败或超时最多缓存 60 秒后自动重试。探测先用固定的 `wsl.exe -l -q` 预检目标发行版,再运行固定只读版本命令;插件在 webServer 出现约 8 秒后后台预热一次,加载期不探测、不阻塞启动。
|
|
160
|
+
- 非 loopback、跨站或 Origin/Host 不一致的请求一律得到 `403`;端点不返回 token、任意命令、任意 URL 或完整日志。修复建议只有受控 `code` + `owner`。
|
|
161
|
+
- **设置入口和五态显示属于 BioGenie 面板**,gem 不注册自己的设置页。BioGenie 结合本地安装探测与上述端点显示 `not-installed` / `legacy` / `installed-unavailable` / `incompatible` / `degraded` / `ready`;旧 gem 仅有文件系统只读兼容视图。
|
|
162
|
+
- 本批不提供 job、安装、删除、配置或其他写 API;这些操作必须等后续的显式用户动作协议。
|
|
163
|
+
|
|
117
164
|
### 7. 卸载
|
|
118
165
|
|
|
119
166
|
```sh
|
|
@@ -128,6 +175,8 @@ npx -y @deepseek-ai/dsh plugin --profile web remove dsh-bio-gem
|
|
|
128
175
|
# 1) install the plugin into the web profile, then restart dsh
|
|
129
176
|
npx -y @deepseek-ai/dsh plugin --profile web add @dsh-bio/dsh-bio-gem
|
|
130
177
|
# (or from source: github:moonbowterfly/dsh-bio-gem)
|
|
178
|
+
# desktop app (0.2.0+): use its bundled CLI with --profile desktop, e.g.
|
|
179
|
+
# & "$env:LOCALAPPDATA\Programs\DeepSeek Harness\resources\runtime\cli\bin\dsh.cmd" plugin --profile desktop add @dsh-bio/dsh-bio-gem
|
|
131
180
|
|
|
132
181
|
# 2) analysis Python needs cobra (+ pyrodigal for the annotation fallback)
|
|
133
182
|
uv venv --python 3.11 "$HOME/.dsh/dsh-bio-gem/venv"
|
|
@@ -145,7 +194,7 @@ unzip -o diamond.zip diamond.exe -d "$HOME/.dsh/dsh-bio-gem/venv-carveme/Scripts
|
|
|
145
194
|
npx -y @deepseek-ai/dsh --profile web --dump-config | grep dsh-bio-gem
|
|
146
195
|
```
|
|
147
196
|
|
|
148
|
-
CarveMe + diamond are required only by `gem_build`; the other
|
|
197
|
+
CarveMe + diamond are required only by `gem_build`; the other 20 tools need nothing but a `cobra`-enabled Python.
|
|
149
198
|
|
|
150
199
|
## 工具(20)
|
|
151
200
|
|
|
@@ -171,6 +220,9 @@ CarveMe + diamond are required only by `gem_build`; the other 19 tools need noth
|
|
|
171
220
|
| `gem_double_knockout` | 双敲 v1 合成致死(GPR 穷尽先验+全扫预算;假设生成声明内置)| ✅ C58: Atu3364↔Atu4682 对应命中 |
|
|
172
221
|
| `gem_enrichment` | 必需基因通路富集(超几何+BH FDR;通路源=SBML groups;无注释诚实兜底)| ✅ C58: 388 通路 55 显著 |
|
|
173
222
|
| `gem_targets` | 靶点清单规范导出(账本三类 -> 锁定 schema CSV/JSON;计数闭合)| ✅ C58: 258 行三类闭合 |
|
|
223
|
+
| `gem_precursor_scan` | 阻塞前体分析(模型为什么不长:基线通量→可生长即返无阻塞;不生长则逐前体移除测试定位阻塞点)| ✅ 2026-09-11 新增 |
|
|
224
|
+
| `gem_quality` | 模型质量报告(gem-qi-v1:blocked/环路(fastcc 方向锥)/元素平衡/孤儿与死端/覆盖/连通性 + 启发式聚合分;分项与 failed_checks 为准)| ✅ C58+AB: qi 67.23 / blocked 1032 / cyclic 289 |
|
|
225
|
+
| `gem_sample` | 通量空间采样(ACHR 默认 / OptGP 大样本;growth_floor_fraction 受限空间;全空间 vs 受限边界声明)| ✅ C58+AB: 全空间 median 0.019 / floor-0.9 min 0.468 |
|
|
174
226
|
|
|
175
227
|
架构/决策见 [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md)、[docs/DECISIONS-2026-08-29.md](docs/DECISIONS-2026-08-29.md)。
|
|
176
228
|
|
package/docs/ARCHITECTURE.md
CHANGED
|
@@ -1,116 +1,145 @@
|
|
|
1
|
-
# dsh-bio-gem — 架构文档(M1 定稿 2026-08-29)
|
|
2
|
-
|
|
3
|
-
## 1. 定位一句话
|
|
4
|
-
|
|
5
|
-
dsh 平台的 **GEM 构建侧插件**:输入细菌全基因组(支持多质粒/多染色体),自动构建→验证→补洞→出报告(标准 SBML + 模型卡),产出后可被 dsh-bio-genie 现有消费工具(FBA/必需性/生产包络线/模型面板)直接加载使用。
|
|
6
|
-
|
|
7
|
-
硬性原则(沿袭 bio-genie):**用户零手动安装、零自愈、通用化(不可本机特化)、结论可溯源**。
|
|
8
|
-
|
|
9
|
-
## 2. 决策记录(为什么这么设计)
|
|
10
|
-
|
|
11
|
-
| 日期 | 决策 | 依据 |
|
|
12
|
-
|---|---|---|
|
|
13
|
-
| 08-28 | 插件名 dsh-bio-gem;资产盘点:消费侧已就绪、补构建侧闭环 | 用户拍板 |
|
|
14
|
-
| 08-29 | 引擎路线:**任务门槛路由**(不是简单 auto);落地节奏 **M1 CarveMe+补洞 → M2 gapseq WSL 桥 → M3 双引擎交叉** | 第三方 GLM 独立评估 + 本机实测(CarveMe AB 不生长=补洞是生存线;WSL 桥显著降级交付风险;Docker 非 WSL 替代)|
|
|
15
|
-
| 08-29 | MVP 工具集:gem_build / gem_validate(G1G2G3 必做,G4 条件、G5 抽检)/ gem_gapfind(L1L2L3)/ gem_gapfill(L1L2 规则自动)/ gem_report(薄版模型卡);**gem_essentiality 不进首版** | 消费侧 bio_gene_knockout 已存在,避免重复实现 |
|
|
16
|
-
| 08-29 | 修正 GLM 建议:弃 μ 判据用 FBA 通量判据;pyrodigal 注释前端降 backlog;测试矩阵首版收敛 C58+2 公开株 | 本机输出口径为 objective_value;默认输入是带注释基因组 |
|
|
17
|
-
|
|
18
|
-
**裁决原则**:GLM 分析质量高但缺本机上下文(输出单位、输入形态、部署面=本机为主的现实),凡冲突处以本机实测与产品原则为准。
|
|
19
|
-
|
|
20
|
-
## 3. 工具契约(
|
|
21
|
-
|
|
22
|
-
| 工具 | Python 层 | 阶段 |
|
|
23
|
-
|---|---|---|
|
|
24
|
-
| gem_build | build.py CLI(CarveMe M9 gapfill;fna 自动注释)| ✅ M1+模块 DONE(C58 63-70s)|
|
|
25
|
-
| gem_validate | op validate(G1-G6 + GATE_REGISTRY)| ✅ M1 DONE |
|
|
26
|
-
| gem_gapfind | op gapfind(L1-L3 分级 + 跨引擎介质归一化)| ✅ M1 DONE |
|
|
27
|
-
| gem_gapfill | op gapfill(L1/L2 规则 + provenance)| ✅ M1 DONE |
|
|
28
|
-
| gem_phenotype | op phenotype_fix(表型回填迭代)| ✅ A3 DONE |
|
|
29
|
-
| gem_essentiality | op essential_scan(FVA 预筛 + 手工敲除;预测自动入账本)| ✅ P0 DONE |
|
|
30
|
-
| gem_annotate | op annotate(官方优先 + pyrodigal)| ✅ P0 DONE |
|
|
31
|
-
| gem_gapseq | op gapseq(WSL 原子四步,可选项)| ✅ 桥全通 |
|
|
32
|
-
| gem_l3_fix | op l3_fix(L3 补洞:L3a 连通性 + L3b 白名单/BiGG;证据分级 + 预算闸门 + G6 回滚)| ✅ B' DONE(C58 Arabinose 0→0.851)|
|
|
33
|
-
| gem_report | op model_info(+ ledger_summary 基率摘要)| ✅ DONE |
|
|
34
|
-
| gem_media_resolve | op media_resolve(介质解析 RPC,消费侧统一入口)| ✅ DONE |
|
|
35
|
-
| gem_biomass | op biomass_inspect / biomass_apply(inspect 组分+对照参考;apply 覆盖表+三联对照+原文件不动回滚)| ✅ Q2 DONE(复位 delta 0.0)|
|
|
36
|
-
| gem_fluxscan | op fluxscan(通量区间制:FVA 区间+pFBA 点值+条件对区间分离判定,overlap=伪影禁止引用)| ✅ 阶段A-M1 DONE(C58 AB 0.519981 / 蔗糖 supplement 0.97077)|
|
|
37
|
-
| gem_sensitivity | op sensitivity(GAM×biomass 22 组合全量+稳定性三分类+单组分漂移;模型卡 robustness v3)| ✅ 阶段A-M2 DONE(基准复现 155)|
|
|
38
|
-
| gem_ledger | op ledger(prediction ledger:list/query/update;幂等追加式账本)| ✅ 阶段A-M3 DONE(C58 155+19 条幂等复跑)|
|
|
39
|
-
| gem_benchmark | op benchmark(通用基准对比:六关并列/生长[介质层两级策略]/biomass 探针/必需性对比含退化护栏/表型/账本回填/md 落盘;model 参数支持 bigg:<id> 下载)| ✅ 阶段B-B1/B2/B3 DONE |
|
|
40
|
-
| gem_secretion | op secretion(可分泌谱:production envelope;边界声明内置;wt<=EPS 退化护栏不登记)| ✅ 阶段C-C1 DONE(C58 85 可分泌)|
|
|
41
|
-
| gem_double_knockout | op double_knockout(双敲 v1:GPR 穷尽先验+全扫 max_pairs 预算;假设声明内置)| ✅ 阶段C-C2 DONE(Atu3364↔Atu4682 对应命中)|
|
|
42
|
-
| gem_enrichment | op enrichment(必需基因通路富集:超几何+BH FDR;无注释 annotation_unavailable 兜底)| ✅ 阶段C-C3 DONE(C58 55 条 FDR 显著)|
|
|
43
|
-
| gem_targets | op targets(靶点规范导出:11 字段锁定 schema;账本计数闭合;引物设计不做)| ✅ 阶段C-C4 DONE(258 行三类闭合)|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
1
|
+
# dsh-bio-gem — 架构文档(M1 定稿 2026-08-29)
|
|
2
|
+
|
|
3
|
+
## 1. 定位一句话
|
|
4
|
+
|
|
5
|
+
dsh 平台的 **GEM 构建侧插件**:输入细菌全基因组(支持多质粒/多染色体),自动构建→验证→补洞→出报告(标准 SBML + 模型卡),产出后可被 dsh-bio-genie 现有消费工具(FBA/必需性/生产包络线/模型面板)直接加载使用。
|
|
6
|
+
|
|
7
|
+
硬性原则(沿袭 bio-genie):**用户零手动安装、零自愈、通用化(不可本机特化)、结论可溯源**。
|
|
8
|
+
|
|
9
|
+
## 2. 决策记录(为什么这么设计)
|
|
10
|
+
|
|
11
|
+
| 日期 | 决策 | 依据 |
|
|
12
|
+
|---|---|---|
|
|
13
|
+
| 08-28 | 插件名 dsh-bio-gem;资产盘点:消费侧已就绪、补构建侧闭环 | 用户拍板 |
|
|
14
|
+
| 08-29 | 引擎路线:**任务门槛路由**(不是简单 auto);落地节奏 **M1 CarveMe+补洞 → M2 gapseq WSL 桥 → M3 双引擎交叉** | 第三方 GLM 独立评估 + 本机实测(CarveMe AB 不生长=补洞是生存线;WSL 桥显著降级交付风险;Docker 非 WSL 替代)|
|
|
15
|
+
| 08-29 | MVP 工具集:gem_build / gem_validate(G1G2G3 必做,G4 条件、G5 抽检)/ gem_gapfind(L1L2L3)/ gem_gapfill(L1L2 规则自动)/ gem_report(薄版模型卡);**gem_essentiality 不进首版** | 消费侧 bio_gene_knockout 已存在,避免重复实现 |
|
|
16
|
+
| 08-29 | 修正 GLM 建议:弃 μ 判据用 FBA 通量判据;pyrodigal 注释前端降 backlog;测试矩阵首版收敛 C58+2 公开株 | 本机输出口径为 objective_value;默认输入是带注释基因组 |
|
|
17
|
+
|
|
18
|
+
**裁决原则**:GLM 分析质量高但缺本机上下文(输出单位、输入形态、部署面=本机为主的现实),凡冲突处以本机实测与产品原则为准。
|
|
19
|
+
|
|
20
|
+
## 3. 工具契约(21 工具 ↔ Python 层;21 op + build CLI)
|
|
21
|
+
|
|
22
|
+
| 工具 | Python 层 | 阶段 |
|
|
23
|
+
|---|---|---|
|
|
24
|
+
| gem_build | build.py CLI(CarveMe M9 gapfill;fna 自动注释)| ✅ M1+模块 DONE(C58 63-70s)|
|
|
25
|
+
| gem_validate | op validate(G1-G6 + GATE_REGISTRY)| ✅ M1 DONE |
|
|
26
|
+
| gem_gapfind | op gapfind(L1-L3 分级 + 跨引擎介质归一化)| ✅ M1 DONE |
|
|
27
|
+
| gem_gapfill | op gapfill(L1/L2 规则 + provenance)| ✅ M1 DONE |
|
|
28
|
+
| gem_phenotype | op phenotype_fix(表型回填迭代)| ✅ A3 DONE |
|
|
29
|
+
| gem_essentiality | op essential_scan(FVA 预筛 + 手工敲除;预测自动入账本)| ✅ P0 DONE |
|
|
30
|
+
| gem_annotate | op annotate(官方优先 + pyrodigal)| ✅ P0 DONE |
|
|
31
|
+
| gem_gapseq | op gapseq(WSL 原子四步,可选项)| ✅ 桥全通 |
|
|
32
|
+
| gem_l3_fix | op l3_fix(L3 补洞:L3a 连通性 + L3b 白名单/BiGG;证据分级 + 预算闸门 + G6 回滚)| ✅ B' DONE(C58 Arabinose 0→0.851)|
|
|
33
|
+
| gem_report | op model_info(+ ledger_summary 基率摘要)| ✅ DONE |
|
|
34
|
+
| gem_media_resolve | op media_resolve(介质解析 RPC,消费侧统一入口)| ✅ DONE |
|
|
35
|
+
| gem_biomass | op biomass_inspect / biomass_apply(inspect 组分+对照参考;apply 覆盖表+三联对照+原文件不动回滚)| ✅ Q2 DONE(复位 delta 0.0)|
|
|
36
|
+
| gem_fluxscan | op fluxscan(通量区间制:FVA 区间+pFBA 点值+条件对区间分离判定,overlap=伪影禁止引用)| ✅ 阶段A-M1 DONE(C58 AB 0.519981 / 蔗糖 supplement 0.97077)|
|
|
37
|
+
| gem_sensitivity | op sensitivity(GAM×biomass 22 组合全量+稳定性三分类+单组分漂移;模型卡 robustness v3)| ✅ 阶段A-M2 DONE(基准复现 155)|
|
|
38
|
+
| gem_ledger | op ledger(prediction ledger:list/query/update;幂等追加式账本)| ✅ 阶段A-M3 DONE(C58 155+19 条幂等复跑)|
|
|
39
|
+
| gem_benchmark | op benchmark(通用基准对比:六关并列/生长[介质层两级策略]/biomass 探针/必需性对比含退化护栏/表型/账本回填/md 落盘;model 参数支持 bigg:<id> 下载)| ✅ 阶段B-B1/B2/B3 DONE |
|
|
40
|
+
| gem_secretion | op secretion(可分泌谱:production envelope;边界声明内置;wt<=EPS 退化护栏不登记)| ✅ 阶段C-C1 DONE(C58 85 可分泌)|
|
|
41
|
+
| gem_double_knockout | op double_knockout(双敲 v1:GPR 穷尽先验+全扫 max_pairs 预算;假设声明内置)| ✅ 阶段C-C2 DONE(Atu3364↔Atu4682 对应命中)|
|
|
42
|
+
| gem_enrichment | op enrichment(必需基因通路富集:超几何+BH FDR;无注释 annotation_unavailable 兜底)| ✅ 阶段C-C3 DONE(C58 55 条 FDR 显著)|
|
|
43
|
+
| gem_targets | op targets(靶点规范导出:11 字段锁定 schema;账本计数闭合;引物设计不做)| ✅ 阶段C-C4 DONE(258 行三类闭合)|
|
|
44
|
+
| gem_precursor_scan | op precursor_scan(阻塞前体分析:基线通量→可生长即返「无阻塞」;不生长则逐前体移除测试定位阻塞点)| ✅ 2026-09-11(E2E 绕道归因产出)|
|
|
45
|
+
|
|
46
|
+
> Python 分发器 `gem_ops.py` 共 **23 个 op**(annotate/benchmark/biomass_apply/biomass_inspect/double_knockout/enrichment/essential_scan/fluxscan/gapfill/gapfind/gapseq/l3_fix/ledger/media_resolve/model_info/phenotype_fix/precursor_scan/quality/sample/secretion/sensitivity/targets/validate);`gem_build` 不经分发器,由 `build.py` CLI 直接调用(长任务,jobs.js 拉起)。
|
|
47
|
+
>
|
|
48
|
+
> **工具数(23)与 op 数(23)的关系**:不等且不是简单的 +1 —— `gem_biomass` 一个工具映射 `biomass_inspect` / `biomass_apply` 两个 op(工具 −1),而 `gem_build` 走 CLI 不占 op(工具 +1),两项相抵故数值相同。核验口径:`len(gem_ops.OPS)` 与 `grep -c 'ctx.tools.register(' src/tools.js`。
|
|
49
|
+
|
|
50
|
+
> **precursor_scan 的判据取舍(勿回退)**:初版曾用「全开交换下逐前体 demand 能否净生产」的**绝对可达性**判据,在教科书模型 e_coli_core 上把 atp_c/accoa_c/nad_c/nadph_c 误报为「结构缺失」(辅因子有循环补给路径,稳态下不净生产 ≠ 网络不能供给),故否决。现行判据为**相对判断**:先测基线通量,可生长即直接返回「无阻塞」;不生长才逐前体做移除测试,由「移除后是否恢复通量」直接定义阻塞点。验证锚:toy 单点阻塞模型(精确命中)、e_coli_core(growable,零误报)、iNX1344_v3(infeasible_or_constrained,与 agent 手工探索结论一致)。
|
|
51
|
+
|
|
52
|
+
> 其余工具层约定:附模型卡统一写入 `python/model_card.py`(lineage/verified_phenotypes/essential_genes/robustness v3)与往返保真自检 `python/roundtrip_check.py`;预测账本 `python/ledger.py`(一个模型一个账本:`~/.dsh/dsh-bio-gem/ledger/<模型名>.jsonl`,按模型 basename 分,显式 ledger_path 可覆盖;无参查询=聚合全局视图;旧全局 predictions.jsonl 已迁移为 legacy)。**生长/通量数值口径(阶段A-M4)**:所有产出生长/通量数值的工具输出均带 `units: mmol/gDW/h` 与单点 FBA 声明;条件间通量对比一律走 gem_fluxscan 区间分离判定(overlap=伪影禁止引用)。
|
|
53
|
+
|
|
54
|
+
## 4. 引擎路线(M1→M2→M3)
|
|
55
|
+
|
|
56
|
+
- **M1(已完成 08-29,C58 实测)**:CarveMe 纯 Windows(独立 venv ~/.dsh/dsh-bio-gem/venv-carveme + diamond PATH 注入)。输入(protein.faa)→ carve -g M9(54s)→ 精确 M9 介质(media_db 提取)G3 PASS(C58 测 0.782)→ 用户目标介质 resolve(跨引擎自然名)→ G3 FAIL 时 L1/L2 规则补洞 → 模型卡。**CarveMe 模型实测:M9 可生长;AB 目标介质 FAIL 且为 L3 内部路径(L1/L2 规则不可修)——诚实报告为已知边界(研究设计既有结论:CarveMe M9 补洞局限)。**
|
|
57
|
+
- **M2(2026-08-29 代码完成,doall 实测进行中)**:gapseq WSL2 桥(`python/gapseq_wsl.py`)。能力探测四件套(wsl/发行版/gapseq 版本/序列库注册 up-to-date——防假已装 UniProt 灾难);新版 wsl.exe 输出 UTF-8(旧版 UTF-16LE,双解码兼容);doall 哨兵文件轮询(30-60min,每 2min 进度 + 日志尾部旁观);产物拷回 → 目标介质验证(AB 自然名)→ L1/L2 补洞闭环 → 模型卡。gem_build `engine` 参数(carveme|gapseq)+ 60min 超时。分发时采用**私有发行版**(wsl --import 自包含 bundle:R+gapseq+序列库 v1.5+哈希校验,版本钉死)。任务分步化(draft/build/transport/fill/adjust 每步落盘 → 断点续跑)待做。
|
|
58
|
+
- **M3**:双引擎交叉验证,产出**分歧清单**(两引擎不一致反应/基因 = 低置信区,需文献/实验校验)而非平均;可选集成 gemsembler(先验证成熟度);所有比对按**反应级等价类**而非基因级(引擎 GPR 粒度不同)。
|
|
59
|
+
|
|
60
|
+
## 5. 验证关卡规格(HANDOFF-03 产品化 + G0)
|
|
61
|
+
|
|
62
|
+
| 关卡 | 内容 | 首版 | 判定线 |
|
|
63
|
+
|---|---|---|---|
|
|
64
|
+
| **G0** | **模型数据质量前置诊断**(`python/coherence.py`):id 体系识别 + biomass 未映射前体 + 方向异常 | ✅ 2026-09-11 | 有未映射前体 → WARN(提示下游结论不可靠);产物侧出现 ATP → FAIL |
|
|
65
|
+
| G1 | 加载统计 + 多复制子 locus_tag 唯一性 + GPR 覆盖 | ✅ | 可加载;无重复 ID;GPR 覆盖率报告 |
|
|
66
|
+
| G2 | 内部反应元素平衡(EX/DM/SK/boundary 排除)| ✅ | C/N/P/S 不平衡=0(FAIL/WARN),H/charge 单独报告;**公式覆盖率是 PASS 的作用域上界**——覆盖率 <90% 时即便被检查部分全平衡也降级 WARN 并给出 `coverage_scope_note`(2026-09-11 修:agent 实测发现覆盖率 68.35% 却判 PASS 是假阳性)|
|
|
67
|
+
| G3 | 生长真实性(声明培养基)| ✅ | 有碳源 objective_value>0;无碳 <1e-6;全关=0;与参照值比值≥99% 判 PASS |
|
|
68
|
+
| G4 | 底物表型对照 | 条件 | 有参照表才跑(内置 C58 39 底物作回归锚),不设阻塞阈值 |
|
|
69
|
+
| G5 | 必需基因抽检(≤30 基因)| 条件 | 有参照集才跑;映射覆盖 <80% 时 SKIP(WARN) |
|
|
70
|
+
| G6 | ATP 泄漏检测(全关交换后 ATP demand 应≈0)| ✅ | leak ≤0.01 判 PASS;ATP 解析走 id→name→formula 三级回退(跨 ID 体系)|
|
|
71
|
+
|
|
72
|
+
**G0 的由来(2026-09-10 E2E 实测)**:MetaCyc 风格 id 的公开模型(iNX1344_v3)上,
|
|
73
|
+
`gem_gapfind` 报 5 个 L3「内部通路缺口」,实为 biomass 前体未映射所致——agent 为逐个
|
|
74
|
+
证伪手写 cobra 代码 18 次。现 `gem_validate` 在 G1 之前输出 `g0`,`gem_gapfind` 返回
|
|
75
|
+
`coherence_warning` + `interpretation_guard`,把该结论前置给 agent。
|
|
76
|
+
|
|
77
|
+
> ⚠️ **G0 判据的取舍(勿回退)**:曾试过「biomass 元素配平」与「前体可达性(demand 逐前体
|
|
78
|
+
> FBA)」两条判据,均在教科书模型 e_coli_core 上误报(把它判 FAIL、把 atp_c/accoa_c 报成
|
|
79
|
+
> 「结构缺失」)故被否决——标准 biomass 方程代表大分子聚合,本就不配平。保留判据的标准是
|
|
80
|
+
> 「问题模型报出真问题 + 标准模型零误报」双向通过。
|
|
81
|
+
|
|
82
|
+
关卡 fail-fast 排序 G0→G1→G3→G2(便宜的先行);gem_validate 保持**无状态**,同 run 可双跑(补洞前后 diff 写进模型卡)。
|
|
83
|
+
|
|
84
|
+
**判据口径**:FBA objective_value(mmol/gDW/h),不用 μ(h⁻¹)——模型输出单位即通量;C58 回归锚:gapseq AB=0.519981;补洞后 CarveMe 目标 ≥0.1 为软目标。
|
|
85
|
+
|
|
86
|
+
## 6. 缺口分级(gapfind/gapfill)
|
|
87
|
+
|
|
88
|
+
- **L1 缺交换**:培养基成分表 vs 模型 EX_ 列表的集合差 → 修复=补 EX_ 反应(完善环境定义,最安全)
|
|
89
|
+
- **L2 缺转运**:e0↔c0 区室连通性(代谢物在胞外存在但无转运反应入胞)→ 修复=补转运(GPR 可空,标注未表征)
|
|
90
|
+
- **L3 内部路径**:底物有交换+转运却无法达中心代谢 → 需文献反应(M1 报告清单,不自动补)
|
|
91
|
+
|
|
92
|
+
已知规律(P1 实测):多数"不能利用某碳源"缺口是 L1/L2 而非 L3。
|
|
93
|
+
**2026-09-11 补充**:L3 清单须与 G0 一起解读——模型数据质量有问题时 L3 多为症状
|
|
94
|
+
(`find_gaps` 返回值已内置 `coherence_warning` 与 `interpretation_guard`)。
|
|
95
|
+
|
|
96
|
+
**防过补四闸门**:分级规则优先于 MILP(M1 不做 MILP);新增反应数封顶(max_add=20);逐条 provenance 打标(来源/原因/是否借自模板);修复后强制重验 G3 + 生长值合理性上限告警(>1.0 时 WARN 过补嫌疑)。
|
|
97
|
+
|
|
98
|
+
## 7. 模型卡(sidecar JSON,与 SBML 同目录同名 .card.json)
|
|
99
|
+
|
|
100
|
+
```
|
|
101
|
+
{ engine, engine_version, db_version, command, started, finished,
|
|
102
|
+
memote_like: {g1..g5}, gapfixes: [{type, reaction, reason, source}],
|
|
103
|
+
growth: {medium, before, after}, mapping_coverage,
|
|
104
|
+
replicons, warnings }
|
|
105
|
+
```
|
|
106
|
+
写盘用 cobra.io.write_sbml_model(cobra 0.32.1 无 Model.save_model——坑位记档)。
|
|
107
|
+
|
|
108
|
+
## 8. 后台任务(M1 基建,约 30% 工程量)
|
|
109
|
+
|
|
110
|
+
job 化 + 进度事件(粒度 ≤5s)+ 分步 checkpoint(每步落盘,可断点续跑)+ 结果可重入。引擎无关,M2 gapseq 直接复用。
|
|
111
|
+
|
|
112
|
+
## 9. 与 bio-genie 衔接
|
|
113
|
+
|
|
114
|
+
- 产出 SBML 落 `~/.dsh/dsh-bio-gem/models/<name>.xml`;模型卡同目录;
|
|
115
|
+
- 协议版 gem 的运行时状态由 gem 自己的 integration API 作为唯一事实源;BioGenie 不再并行直读 models/ledger/exports。仅 `legacy`(gem < 0.1.11)兼容视图允许文件系统摘要兜底,且必须标明只读。
|
|
116
|
+
|
|
117
|
+
### 9.1 托管领域扩展 integration v1(v0.1.11+)
|
|
118
|
+
|
|
119
|
+
- 固定 GET 端点:`/api/dsh-bio-gem/integration/health`(身份/协议协商,零 Python spawn、零写盘)和 `/api/dsh-bio-gem/integration/v1/status`(状态快照)。两者均用 `{ok,value}` / `{ok:false,code,message}` 信封。
|
|
120
|
+
- status 的唯一状态是 `ready` 或 `degraded`;三个稳定检查 ID 为 `python.cobra`、`runtime.carveme`、`runtime.gapseq`。模型、账本、导出仅返回摘要与最多 50 条条目。Python/cobra 维持 60 秒短缓存;WSL/gapseq 是非阻塞 stale-while-revalidate:首次以 `available: null`、`probing: true` 和 check=`warn` 表示后台探测中,缓存过期时先返回旧值并刷新,成功缓存 5 分钟、失败或超时最多缓存 60 秒后自动重试。
|
|
121
|
+
- 所有路由使用与 BioGenie 相同的 socket/Host/sec-fetch-site/Origin 四层 loopback 守卫。回传不包含 token、任意命令、任意 URL 或完整日志;remediation 仅为受控 `code` + `owner`,其中共享 WSL/gapseq 的 owner 是 genie、CarveMe 私有运行时的 owner 是 gem。
|
|
122
|
+
- 静态 Cordis `inject` 只声明 `tools`、`skills`;`webServer` 通过 `ctx.inject(['webServer'], cb)` 动态等待。无 webServer 时仍照常注册 23 个 `gem_*` 工具和 gem-expert skill;服务出现后才注册两条路由,并在约 8 秒后后台预热一次 status 缓存。gapseq 先做 `wsl.exe -l -q` 发行版预检,再用固定只读版本命令;子进程 stdin 使用 pipe 并立即关闭,避免 WSL 因 `stdin=ignore` 慢启动。gem 不注册浏览器设置入口,一级入口和五态 UI 由 BioGenie 唯一拥有。
|
|
123
|
+
- 本批严格只读:不实现 job API、安装/删除、配置 schema、自动修复或跨插件命令执行。
|
|
124
|
+
|
|
125
|
+
## 10. 验收(M1 最小可用判定线)
|
|
126
|
+
|
|
127
|
+
零手动干预下:**基因组进 → 四个消费工具(FBA/必需性/包络线/面板)不经修改即可用的 SBML 出**,且模型在声明培养基上生长为正;C58 端到端演示通过(build→面板可见→FBA 可跑→必需性可跑);模型卡齐全(引擎/版本/补洞记录/验证结果,同输入重跑一致);5-6 Mb 基因组 p95 ≤ 20 min。
|
|
128
|
+
|
|
129
|
+
## 附录 A:性能基准(阶段 A-M6,2026-08-30 本机实测,独占运行)
|
|
130
|
+
|
|
131
|
+
分析 Python 3.13.13 / cobra 0.32.1 / GLPK;C58=gapseq 2485 反应/1084 基因;iNX1344_v4=1441 反应/1344 基因。
|
|
132
|
+
|
|
133
|
+
| 项目 | C58 | iNX1344_v4 |
|
|
134
|
+
|---|---|---|
|
|
135
|
+
| model_info(读模+摘要) | 6.6s | 3.7s |
|
|
136
|
+
| validate G1-G6 | 7.9s(G3 PASS 0.519981) | 3.7s(G3 WARN,介质层不兼容见 M5) |
|
|
137
|
+
| essential_scan 全量(FVA 预筛+手工敲除) | ~50s(FVA 32.3s + 敲除 16.8s,818 候选) | ~30s(FVA 11.9s + 敲除 16.8s,1066 候选) |
|
|
138
|
+
| fluxscan 1 条件(读模+FBA+FVA+pFBA) | ~31s(FVA 24-42s 为主) | ~14s(FVA ~12s) |
|
|
139
|
+
| fluxscan 2 条件 1 对 | 63-72s | 28.5s |
|
|
140
|
+
| fluxscan 3 条件 3 对 | 123.3s | 未跑(介质层不兼容,点值无意义) |
|
|
141
|
+
| sensitivity 22 组合全量(每组合 wt+必需性重扫) | 2094.8s(~35min;grid 22×~95s) | 732.0s(~12min;grid 689s) |
|
|
142
|
+
| 单组分 ±25% 灵敏度 | 75 组分×2=150 次 FBA,54.4s | 47 组分×2=94 次 FBA,7.9s |
|
|
143
|
+
| 必需性漂移 top10(含生长探针) | 522.0s(含 7 刚性对跳过探针) | 33.8s(20/20 全部"不生长跳过") |
|
|
144
|
+
|
|
145
|
+
> 注:FVA 占单条件耗时 ~75%;sensitivity 线性于组合数(每组合 fresh 读模+FVA+敲除循环)。GLPK 对个别扰动 LP 有病态停摆前科,sensitivity 内置 LP_TIMEOUT_S=30 护栏(见 docs/DECISIONS-阶段A.md M2-5)。
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# DECISIONS — 2026-09-21 升级批次(外部评审裁决后 Phase 1)
|
|
2
|
+
|
|
3
|
+
> 本批决策依据:`D:\Program\dsh-plug-develop\21-gem升级-裁决与实施方案.md`(GPT/DS 双评审 + 本机 8 项实测核验)。
|
|
4
|
+
> 记录本批次的**语义演进与架构决策**,供下游与后续批次参考。
|
|
5
|
+
|
|
6
|
+
## D1. growth 单位演进:mmol/gDW/h → 1/h(数值不变)
|
|
7
|
+
|
|
8
|
+
**决策**:growth / growth_rate / wt_growth / before-after 生长 等**比生长量**字段的单位标注由
|
|
9
|
+
`mmol/gDW/h` 改为 `1/h`;反应通量类保持 `mmol/gDW/h`。
|
|
10
|
+
|
|
11
|
+
**依据**(实测 + 社区约定):
|
|
12
|
+
- C58 的 bio1(Bacterial Gram-negative biomass reaction)产物系数 = 1.0 —— biomass 反应已按
|
|
13
|
+
**1 gDW 归一化**;此时其通量数值 = 比生长速率 μ(h⁻¹),这是 COBRA 社区的标准解读
|
|
14
|
+
(biomass flux through a normalized biomass reaction equals the specific growth rate)。
|
|
15
|
+
- 外部评审(GPT)指出原标注 `mmol/gDW/h` 对 biomass 反应在语义上不准确 → 列为 P0。
|
|
16
|
+
- straindesign 官方文档同样以 `growth rates above 0.5/h` 表述(旁证)。
|
|
17
|
+
|
|
18
|
+
**边界**:对**未归一化**的 biomass 反应(产物系数 ≠ 1)growth 应以 mmol/gDW/h 解读——见
|
|
19
|
+
validate 的 units.note 表述。数值本身在任何情况下不变,本决策只纠标注。
|
|
20
|
+
|
|
21
|
+
**影响面**:python/ 12 个模块(23 处)+ src/tools.js(16 处口径文案统一)+ 本文档;
|
|
22
|
+
`model_card.GROWTH_UNITS` 同步演进(旧卡兼容:growth_units 字段照读,数值口径不变)。
|
|
23
|
+
|
|
24
|
+
## D2. 能力单源(capabilities.json → /v1/capabilities → 宿主动态消费)
|
|
25
|
+
|
|
26
|
+
**决策**:工具清单与能力元数据(cost_class / network / mutability / requires)以
|
|
27
|
+
`src/capabilities.js` 的 `TOOLS_MANIFEST` 为**唯一事实源**:
|
|
28
|
+
- integration API 新增 `GET /v1/capabilities`(features 声明 `capabilities`);
|
|
29
|
+
- 宿主 dsh-bio-genie 的 `handleDomainRequest` 在对方声明该 feature 时拉取并透传
|
|
30
|
+
(失败静默降级到静态清单 `GEM_TOOLS`——它已降级为 fallback 视图);
|
|
31
|
+
- 机器门:`test/check-capabilities.mjs`(manifest ↔ 真实注册一致)+
|
|
32
|
+
`test/check-counts.mjs`(文档计数 ↔ manifest 一致)。
|
|
33
|
+
|
|
34
|
+
**背景**:原「工具数变化需同步 ≥12 处」是两评审共同指出的工程债;本决策把它变成
|
|
35
|
+
「单源 + 两道机器门」,文档数字仍手写但有门兜底。
|
|
36
|
+
|
|
37
|
+
## D3. CarveMe 零手动部署(bootstrap_carveme.py)
|
|
38
|
+
|
|
39
|
+
**决策**:`gem_build(engine=carveme)` 首次调用自动完成运行时部署(幂等):
|
|
40
|
+
uv venv(uv 探测链:`GEM_UV` → genie 自举 uv → PATH)→ `uv pip install carveme` →
|
|
41
|
+
下载 GitHub 官方 diamond 二进制(**固定 v2.2.8**,3.4MB)→ deep smoke → manifest 记录。
|
|
42
|
+
|
|
43
|
+
**关键设计**:
|
|
44
|
+
- **快速路径**:`carve.exe + diamond.exe + manifest.json` 齐备时秒过(实测 0.34s,不做子进程冒烟);
|
|
45
|
+
- 部署与复验才做 deep smoke(实测全量部署 45s:venv 31s + diamond 下载数秒 + 冒烟);
|
|
46
|
+
- 下载通道:直连 → 环境代理(HTTPS_PROXY/HTTP_PROXY)→ 失败给可执行指引(含手动放置路径);
|
|
47
|
+
- 这就是 P0「装完插件 ≠ 构建可用」的根治:契约要求用户零手动安装。
|
|
48
|
+
|
|
49
|
+
## D4. gem_sample 的边界设计(全空间 vs 受限)
|
|
50
|
+
|
|
51
|
+
**决策**:默认采样**全 feasible space**(ACHR),但 `boundary` 字段**强制输出**边界声明;
|
|
52
|
+
近最优生长状态必须显式传 `growth_floor_fraction`(如 0.9)。
|
|
53
|
+
|
|
54
|
+
**依据**(本机实测):C58 全空间采样 bio1 max ≈ 0.017 vs FBA 最优 0.7134(差 2 个数量级)——
|
|
55
|
+
全空间均匀分布 ≠ 生物学上有意义的活跃状态;不声明边界就是「做了但没用」的典型。
|
|
56
|
+
|
|
57
|
+
**Windows 约束**:默认 ACHR(无多进程依赖,实测 init ~172s、采样秒级);OptGP 在 Windows
|
|
58
|
+
下实验性——不可用时**显式安全拒绝**(不触发多进程陷阱)。
|
|
59
|
+
|
|
60
|
+
## D5. quality_index(gem-qi-v1)不是 MEMOTE 分数
|
|
61
|
+
|
|
62
|
+
**决策**:`gem_quality` 输出 `quality_index`(0-100 启发式聚合)+ 分项 raw_metrics +
|
|
63
|
+
failed_checks + not_assessable_checks;**禁止**作为单一质量结论引用(notes 内置声明)。
|
|
64
|
+
|
|
65
|
+
**依据**:两评审共识——MEMOTE 的价值在其可分解测试体系;聚合分容易被误用。
|
|
66
|
+
评分规则(写死在 `python/quality.py` 常量):见 WEIGHTS / 阈值常量与 note 输出。
|
|
67
|
+
**不安装 MEMOTE 整体**(PyPI 0.17.0 仅声明兼容到 Py3.11;本机 Py3.13 风险)。
|
|
68
|
+
|
|
69
|
+
## D6. 本批新增工具(2)
|
|
70
|
+
|
|
71
|
+
| 工具 | capability | cost_class | 说明 |
|
|
72
|
+
|---|---|---|---|
|
|
73
|
+
| `gem_quality` | `gem.validate.quality-report` | medium | 质量审计(blocked/环路/平衡/孤儿/覆盖/连通性)|
|
|
74
|
+
| `gem_sample` | `gem.analysis.sampling` | heavy | 通量空间采样(ACHR/OptGP;边界声明)|
|
|
75
|
+
|
|
76
|
+
工具数 21 → 23;op 数 21 → 23。两门(check-capabilities / check-counts)同步更新。
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# @dsh-bio/dsh-bio-gem v0.1.12
|
|
2
|
+
|
|
3
|
+
> **跨版本说明**:npm 上此前 latest 为 0.1.3,本版为 0.1.4–0.1.12 的累积发布(GEM 全链能力 + 一轮审计修复)。
|
|
4
|
+
> 基因组尺度代谢模型(GEM)域插件:全基因组 → 自动构建 → 验证 → 补洞 → 出报告(SBML + 模型卡),供 dsh-bio-genie 宿主消费。
|
|
5
|
+
|
|
6
|
+
## 亮点
|
|
7
|
+
|
|
8
|
+
**21 个 `gem_*` 语义化工具(累积)**:构建(`gem_build`/`gem_gapseq`/`gem_annotate`)、验证与修复(`gem_validate`/`gem_gapfind`/`gem_gapfill`/`gem_phenotype`/`gem_l3_fix`)、分析(`gem_biomass`/`gem_fluxscan`/`gem_sensitivity`/`gem_essentiality`/`gem_double_knockout`/`gem_enrichment`/`gem_secretion`/`gem_precursor_scan`/`gem_targets`)、资产与账本(`gem_media_resolve`/`gem_ledger`/`gem_benchmark`/`gem_report`)。
|
|
9
|
+
|
|
10
|
+
**能力要点**
|
|
11
|
+
- **预测账本**:一个模型一个账本(`~/.dsh/dsh-bio-gem/ledger/<模型>.jsonl`),登记/幂等/坏行容错;退化模型(生长为 0)显式拒绝登记预测。
|
|
12
|
+
- **介质两级策略**:内置完整成分(含金属离子)预设 + 跨引擎解析护栏。
|
|
13
|
+
- **可分泌谱 / 双敲 / 靶点导出**:带边界声明与计数闭合校验(closure),不伪造通路。
|
|
14
|
+
- **域面板**:BioGenie 设置面板「代谢建模」分页(六态 + 修复指引,由宿主托管)。
|
|
15
|
+
|
|
16
|
+
**0.1.12 审计修复轮(本版新增)**
|
|
17
|
+
- `test/smoke.js` 重构:模型资产**多候选解析**(`--assets-root` / `DSH_BIO_GEM_ASSETS` / 新旧位置)——资产迁移后不再硬编码路径崩溃;**缺资产 / 缺账本标记 SKIP 而非失败**(`--require-assets` 供 CI 严格模式);CarveMe 跳过判断移至调用前;子进程非零退出 fail-closed。
|
|
18
|
+
- `npm test` 接线:smoke + integration + optional-injection(真注册验证,此前未纳入任何 npm 入口)。
|
|
19
|
+
|
|
20
|
+
**引擎兼容(2026-09-19)**:经 dsh **0.1.5-rc.2** 走廊逐卡走查(55 张变更卡:零适配命中)与实机验证(工具注册 / 代谢建模面板 / 账本与模型数据)。
|
|
21
|
+
|
|
22
|
+
## 安装
|
|
23
|
+
|
|
24
|
+
```sh
|
|
25
|
+
dsh plugin --profile web add @dsh-bio/dsh-bio-gem
|
|
26
|
+
# 或:npx -y @deepseek-ai/dsh plugin --profile web add @dsh-bio/dsh-bio-gem
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
- 安装后**重启 dsh web**。
|
|
30
|
+
- **Python 环境**:解释器探测顺序 = `GEM_PYTHON` → 宿主 `dsh-bio-genie` 自举环境 → `CONDA_PREFIX` → `PATH`。分析/验证类工具随装随用。
|
|
31
|
+
- ⚠️ **构建侧重依赖(`gem_build` 才需要,不与 genie 共享)**:CarveMe 独立 venv(`~/.dsh/dsh-bio-gem/venv-carveme`)**必须另放 `diamond.exe`**(缺它 carve 不报错、退出码 0、输出为空——README 第 3 节有完整步骤与实测坑);gapseq 引擎走 WSL2 桥(可选,实验性)。
|
|
32
|
+
- **Smoke 说明**:`npm run smoke` 的 C58 回归断言需要模型资产与账本——缺失时对应检查显式 SKIP 并打印原因(新机器不会误报失败)。
|
|
33
|
+
|
|
34
|
+
## 验证口径
|
|
35
|
+
|
|
36
|
+
- `npm test` 全链通过:smoke(45 项,0 失败 0 跳过)/ integration(10 项)/ optional-injection(21 工具真注册)。
|
|
37
|
+
- 回归锚点:C58 模型 1084 基因 / 2492 反应;AB 介质生长 0.519981;账本 522 条闭合导出。
|
|
38
|
+
|
|
39
|
+
## 已知边界(诚实清单)
|
|
40
|
+
|
|
41
|
+
- `gem_build` 的 gapseq 引擎为实验性(WSL2 本机拓扑绑定,30–60 分钟/模型);默认 carveme 引擎已可出可验证模型。
|
|
42
|
+
- CarveMe 运行时需手动准备一次(README 第 3 节)——「装完插件」不等于「构建可用」,分析/验证类能力不受影响。
|
|
43
|
+
- 注释依赖 SBML groups(gapseq 系模型自带);无注释模型按契约返回 `annotation_unavailable` 兜底,不伪造通路。
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dsh-bio/dsh-bio-gem",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.13",
|
|
4
4
|
"description": "基因组尺度代谢模型(GEM)构建插件:输入细菌全基因组(蛋白FASTA,支持多质粒/多染色体),自动构建+验证+补洞+出报告(SBML + 模型卡),供 dsh-bio-genie 消费工具加载使用 | Genome-scale metabolic model builder for dsh",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -39,7 +39,9 @@
|
|
|
39
39
|
}
|
|
40
40
|
},
|
|
41
41
|
"scripts": {
|
|
42
|
-
"smoke": "node test/smoke.js"
|
|
42
|
+
"smoke": "node test/smoke.js",
|
|
43
|
+
"test": "node test/smoke.js --skip-build && node test/integration.js && node --import ./test/register-dsh-tools.mjs test/optional-injection.js && node --import ./test/register-dsh-tools.mjs test/check-capabilities.mjs && node test/check-counts.mjs",
|
|
44
|
+
"test:full": "node test/smoke.js && node test/integration.js && node --import ./test/register-dsh-tools.mjs test/optional-injection.js && node --import ./test/register-dsh-tools.mjs test/check-capabilities.mjs && node test/check-counts.mjs"
|
|
43
45
|
},
|
|
44
46
|
"peerDependencies": {
|
|
45
47
|
"@deepseek-ai/dsh-tools": "*"
|
|
@@ -47,4 +49,4 @@
|
|
|
47
49
|
"peerDependenciesMeta": {
|
|
48
50
|
"@deepseek-ai/dsh-tools": { "optional": true }
|
|
49
51
|
}
|
|
50
|
-
}
|
|
52
|
+
}
|
package/python/benchmark.py
CHANGED
|
@@ -19,7 +19,7 @@ from sensitivity import find_biomass_gam
|
|
|
19
19
|
from validate import Validator
|
|
20
20
|
|
|
21
21
|
EPS = 1e-6
|
|
22
|
-
UNITS_NOTE = "growth=
|
|
22
|
+
UNITS_NOTE = "growth=1/h(比生长速率;biomass 归一化口径,数值 = μ);必需判定=敲除生长<1e-6"
|
|
23
23
|
DEG_MSG = "wt<=EPS:必需性判定恒真(v=0 使全部候选判'必需'),essential 集无生物学意义"
|
|
24
24
|
|
|
25
25
|
|
|
@@ -317,7 +317,7 @@ def write_md(path, out):
|
|
|
317
317
|
L.append("\n## 3. 生长(声明介质,单点 FBA 口径)\n")
|
|
318
318
|
for tag, name in (("a", "A"), ("b", "B")):
|
|
319
319
|
g = out["growth"][tag]
|
|
320
|
-
L.append(f"- **{name}**: growth=**{g['growth']}**
|
|
320
|
+
L.append(f"- **{name}**: growth=**{g['growth']}** 1/h, resolved={g['resolved_exchanges']}, "
|
|
321
321
|
f"boundary_style={g['boundary_style']}, unresolved={g['unresolved']}")
|
|
322
322
|
if g.get("resolved_display"):
|
|
323
323
|
L.append(f" - resolved_display: {g['resolved_display']}")
|
|
@@ -492,7 +492,7 @@ def benchmark(model_a, model_b, medium=None, phenotype_table=None, reference_ess
|
|
|
492
492
|
for tag, path in (("a", model_a), ("b", model_b)):
|
|
493
493
|
wt, resolved, unresolved, preset, bstyle = growth_on(path, medium)
|
|
494
494
|
entry = {"growth": wt, "resolved_exchanges": len(resolved), "unresolved": unresolved,
|
|
495
|
-
"medium_preset": preset, "boundary_style": bstyle, "units": "
|
|
495
|
+
"medium_preset": preset, "boundary_style": bstyle, "units": "1/h",
|
|
496
496
|
"point_value_note": "单点 FBA 值,非解空间硬结论;条件间对比用 gem_fluxscan(区间制)"}
|
|
497
497
|
if bstyle:
|
|
498
498
|
entry["resolved_display"] = [ex_display_name(silent_read_sbml(path), rid)
|