dsh-molbio-tools 0.19.0 → 0.20.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/CHANGELOG.md +100 -0
- package/README.md +65 -21
- package/align.mjs +28 -0
- package/batch.mjs +185 -0
- package/benchmark/README.md +27 -8
- package/benchmark/sequences.mjs +7 -0
- package/benchmark/tasks/02-primers.json +132 -19
- package/benchmark/tasks/03-restriction.json +113 -29
- package/benchmark/tasks/04-cloning.json +167 -34
- package/benchmark/tasks/05-plasmids.json +172 -29
- package/benchmark/tasks/06-analysis.json +387 -100
- package/benchmark/tasks/09-formats.json +132 -23
- package/benchmark/tools.mjs +28 -2
- package/benchmark/verifications.mjs +17 -1
- package/build/release-preflight.mjs +2 -2
- package/crispr.mjs +392 -78
- package/docs/history.md +10 -0
- package/docs/maintainer.md +8 -6
- package/docs/roadmap.md +22 -8
- package/docs/rules.md +1 -1
- package/docs/workflow.md +7 -7
- package/fastq-qc.mjs +735 -735
- package/index.mjs +573 -36
- package/lib/client.js +665 -86
- package/multiplex.mjs +87 -0
- package/package.json +9 -4
- package/packages/molbio-panel/lib/client.js +665 -86
- package/packages/molbio-panel/package.json +1 -1
- package/preset/molbio-lab/agent.cordis.yml +4 -4
- package/preset/molbio-lab/preset.patch.yml +2 -2
- package/preset/molbio-lab/preset.yml +1 -1
- package/silent-site.mjs +286 -0
- package/snapgene.mjs +17 -1
- package/taqman.mjs +163 -7
- package/test/contract.mjs +14 -0
- package/test/release.mjs +23 -3
- package/test/smoke.mjs +377 -3
- package/benchmark/reports/20260923-142935-suite.json +0 -545
- package/benchmark/reports/20260923-142935-suite.md +0 -30
- package/benchmark/reports/20260923-190149-suite.json +0 -2024
- package/benchmark/reports/20260923-190149-suite.md +0 -235
- package/benchmark/reports/20260923-192913-suite.json +0 -1856
- package/benchmark/reports/20260923-192913-suite.md +0 -158
- package/benchmark/reports/20260923-200212-suite.json +0 -3587
- package/benchmark/reports/20260923-200212-suite.md +0 -163
- package/benchmark/reports/20260923-202830-suite.json +0 -3129
- package/benchmark/reports/20260923-202830-suite.md +0 -99
- package/benchmark/reports/20260923-203856-suite.json +0 -71
- package/benchmark/reports/20260923-203856-suite.md +0 -16
package/benchmark/README.md
CHANGED
|
@@ -76,11 +76,11 @@ Measured, and printed so the answer can be audited:
|
|
|
76
76
|
|
|
77
77
|
```
|
|
78
78
|
$ touch crispr.mjs && node benchmark/run.mjs --list --changed
|
|
79
|
-
1 of
|
|
79
|
+
1 of 61 task(s) selected — --tools molbio_grna_design --changed
|
|
80
80
|
(from --changed; 2 module(s) affected: crispr.mjs, index.mjs)
|
|
81
81
|
|
|
82
82
|
$ touch lib.mjs && node benchmark/run.mjs --list --changed
|
|
83
|
-
55 of
|
|
83
|
+
55 of 61 task(s) selected — --changed (27 module(s) affected: align.mjs, cloning.mjs, …)
|
|
84
84
|
```
|
|
85
85
|
|
|
86
86
|
`lib.mjs` selecting nearly everything is the **correct** answer, not a failure to
|
|
@@ -102,7 +102,7 @@ you changed, so its task runs even if it is full-only.
|
|
|
102
102
|
| `--tools a,b,c` / `primer_*` | the union | you changed a few |
|
|
103
103
|
| `--changed --tools X` | the INTERSECTION | "of what I changed, test X" |
|
|
104
104
|
| (default) | **core** — 14 tasks | a broad smoke of the catalog |
|
|
105
|
-
| `--tier full` | all
|
|
105
|
+
| `--tier full` | all 61, 60/60 tools | before a release |
|
|
106
106
|
|
|
107
107
|
The two `--tools` operators are stated because confusing them is the difference
|
|
108
108
|
between testing what you changed and testing **less** than that: alone it unions,
|
|
@@ -125,7 +125,7 @@ widens to the full suite, with the reason printed.
|
|
|
125
125
|
| a module **only** imported by other modules (`svgio.mjs`) | partial — its importers' tasks |
|
|
126
126
|
| docs, changelog, `test/`, `benchmark/`, config | **`none`: nothing to run** |
|
|
127
127
|
|
|
128
|
-
`none` is deliberately NOT `full`. A documentation commit that triggers
|
|
128
|
+
`none` is deliberately NOT `full`. A documentation commit that triggers 61 model
|
|
129
129
|
calls is how a `--changed` default gets switched off and the full suite goes back
|
|
130
130
|
to running every time — the exact behaviour this option exists to prevent. It is
|
|
131
131
|
only reachable with an explicit `--changed`, so everything else still fails safe,
|
|
@@ -134,7 +134,7 @@ and `test/benchmark-changed.mjs` asserts both directions.
|
|
|
134
134
|
### The part that still runs in full, on purpose
|
|
135
135
|
|
|
136
136
|
A model run with `--changed` or `--tools` first executes the **whole** offline
|
|
137
|
-
gate: all
|
|
137
|
+
gate: all 61 tasks' `where: "tool"` expectations are recomputed against the shipped
|
|
138
138
|
tools (no model, a few hundred milliseconds). That is what makes partial runs safe
|
|
139
139
|
— the expected values are re-proven for the tasks you skipped, so "skipped because
|
|
140
140
|
unchanged" is a checked claim, not a remembered one.
|
|
@@ -168,7 +168,7 @@ asserting whatever the tool happened to emit.
|
|
|
168
168
|
|
|
169
169
|
Two guards make "someone forgot" fail loudly instead of quietly:
|
|
170
170
|
|
|
171
|
-
- `test/benchmark-coverage.mjs` asserts **
|
|
171
|
+
- `test/benchmark-coverage.mjs` asserts **60/60 registered tools are covered by
|
|
172
172
|
at least one task**. Adding a tool without a task is a red build. It also
|
|
173
173
|
asserts the fixtures' premises (the Golden Gate backbone is BsaI-free, the
|
|
174
174
|
mutagenesis template still admits a primer pair), that a `covers` entry names a
|
|
@@ -209,7 +209,7 @@ recorded tool text, and it says so instead of silently scoring empty text).
|
|
|
209
209
|
|
|
210
210
|
## The headless profile (`benchmark/profile.mjs`)
|
|
211
211
|
|
|
212
|
-
The model-facing way to get the
|
|
212
|
+
The model-facing way to get the 60 tools is the **Molecular Biology Lab** agent
|
|
213
213
|
preset. The benchmark cannot use it, and the reason is structural rather than
|
|
214
214
|
configurational — `dsh-headless/lib/index.js` refuses an adoption whose session
|
|
215
215
|
records a preset:
|
|
@@ -368,6 +368,25 @@ These are recorded rather than scored, because each one is a question about the
|
|
|
368
368
|
plugin or the harness, not about the model. The first is a **measured plugin
|
|
369
369
|
defect**.
|
|
370
370
|
|
|
371
|
+
### `molbio_extract_region` advertised `sequence`, but the resolver only read `vector`
|
|
372
|
+
|
|
373
|
+
The 0.20.0 full run (61 tasks) failed `region-extract` on **arguments**: the model
|
|
374
|
+
called `molbio_extract_region` with the parameter the schema advertises
|
|
375
|
+
(`sequence`), and the tool answered "provide either vector (a sequence) or
|
|
376
|
+
vector_path". The schema/reality split was the defect: `resolveVector` read only
|
|
377
|
+
`args.vector`, so `sequence` was silently ignored. **Fixed in 0.20.0** by
|
|
378
|
+
accepting every declared inline alias (`vector`/`sequence`/`reference`), with a
|
|
379
|
+
smoke regression that calls the tool through the advertised `sequence` argument.
|
|
380
|
+
|
|
381
|
+
The same run also showed four **assertion** failures rather than product defects:
|
|
382
|
+
`plasmid-digest` (the model wrote `2,840`, the assertion `2840`),
|
|
383
|
+
`protein-props` (`3,935` vs `3935`), `codon-optimize` (the model said
|
|
384
|
+
`EcoRI-free`, the assertion demanded `no EcoRI`), and `chart-volcano` (the task
|
|
385
|
+
asked for `de.svg`, the assertion pinned `volcano.svg`). `--replay` turns all four
|
|
386
|
+
to PASS; the region-extract live rerun was blocked by the DSH sandbox approval
|
|
387
|
+
for headless subprocesses, so the last measured score is **60/61**, with the
|
|
388
|
+
underlying bug fixed and pinned by smoke.
|
|
389
|
+
|
|
371
390
|
### `molbio_design_primers` prints the forward/reverse roles reversed
|
|
372
391
|
|
|
373
392
|
**Confirmed by direct inspection, not by reading a model's claim.**
|
|
@@ -548,7 +567,7 @@ implementation happens to return for one set of arguments.**
|
|
|
548
567
|
and `args_ok` both true is a *reporting* finding, not a tool bug.
|
|
549
568
|
- **Multimodal hand-off.** `attach_image` is exercised as an argument at most; no
|
|
550
569
|
assertion inspects a decoded PNG (that is `svgpng.mjs` and `contract.mjs`).
|
|
551
|
-
- **Most of the toolset is now covered, but shallowly.**
|
|
570
|
+
- **Most of the toolset is now covered, but shallowly.** 61 tasks touch all 60
|
|
552
571
|
tools; most tools appear in exactly one task, and several appearances are a
|
|
553
572
|
single argument check rather than a full workflow. Breadth is asserted by
|
|
554
573
|
`test/benchmark-coverage.mjs`; depth is not, and cannot be.
|
package/benchmark/sequences.mjs
CHANGED
|
@@ -165,6 +165,13 @@ export const NAMED_SEQUENCES = {
|
|
|
165
165
|
cds: FIXTURES.CDS,
|
|
166
166
|
mutagenesis_template: FIXTURES.MUTAGENESIS_TEMPLATE,
|
|
167
167
|
sanger_read: FIXTURES.SANGER_READ,
|
|
168
|
+
// v0.20.0: the family-geometry fixtures. The Cas12a target is a 5' TTTV PAM
|
|
169
|
+
// followed by a 23 nt protospacer; the Cas13a target is a 28 nt spacer with a
|
|
170
|
+
// 3' H PFS. Keeping them here means the instruction and the offline grader
|
|
171
|
+
// cannot diverge.
|
|
172
|
+
cas12a_target: 'AAAATTTAACGTACGTACGTACGTACGTACGCCCCTTTCGGGGGGGGGGG',
|
|
173
|
+
cas13_target: 'AAAAACGTACGTACGTACGTACGTACGTACGTACCCCCCCCCC',
|
|
174
|
+
silent_cds: 'ATGGCTGAATTCGGTTAAGCTTAA',
|
|
168
175
|
/**
|
|
169
176
|
* The three FASTQ reads the `fastq-qc` task pastes in.
|
|
170
177
|
*
|
|
@@ -12,26 +12,54 @@
|
|
|
12
12
|
"id": "primer-qc",
|
|
13
13
|
"category": "primers",
|
|
14
14
|
"tier": "full",
|
|
15
|
-
"covers": [
|
|
15
|
+
"covers": [
|
|
16
|
+
"molbio_primer_check",
|
|
17
|
+
"molbio_primer_tm"
|
|
18
|
+
],
|
|
16
19
|
"instruction": "I have these two primers already ordered and I want to know whether they are any good together before I run them. Report the Tm of the forward primer, and flag anything structurally worrying about the pair.\n\nForward: ATTACTCCTGCTCTTCCCATAC\nReverse: CACTACTCCTCTGTACGCAC",
|
|
17
20
|
"timeout_ms": 240000,
|
|
18
|
-
"expect_tools": [
|
|
21
|
+
"expect_tools": [
|
|
22
|
+
"molbio_primer_check"
|
|
23
|
+
],
|
|
19
24
|
"assertions": [
|
|
20
|
-
{
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
+
{
|
|
26
|
+
"where": "tool",
|
|
27
|
+
"pattern": "primer1: 22 bp, GC 45\\.45%",
|
|
28
|
+
"note": "the forward primer's own metrics"
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"where": "tool",
|
|
32
|
+
"pattern": "primer2: 20 bp, GC 55%"
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
"where": "tool",
|
|
36
|
+
"pattern": "self-any 7 \\(≤8\\)",
|
|
37
|
+
"note": "the reverse primer's self-complementarity, right at the Primer3 limit"
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
"where": "tool",
|
|
41
|
+
"pattern": "pair \\(dimer\\): score 14",
|
|
42
|
+
"note": "the pair's dimer score"
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
"where": "answer",
|
|
46
|
+
"pattern": "53\\.9|54\\b",
|
|
47
|
+
"note": "the forward primer's Tm, 53.97 °C"
|
|
48
|
+
}
|
|
25
49
|
]
|
|
26
50
|
},
|
|
27
51
|
{
|
|
28
52
|
"id": "taqman-assay",
|
|
29
53
|
"category": "primers",
|
|
30
54
|
"tier": "full",
|
|
31
|
-
"covers": [
|
|
55
|
+
"covers": [
|
|
56
|
+
"molbio_design_taqman"
|
|
57
|
+
],
|
|
32
58
|
"instruction": "Design a TaqMan (5' nuclease) assay on this template. I want primers plus a hydrolysis probe between them, and I want the probe to sit at least a few degrees above the primers in Tm.\n\nTemplate:\n{template:400:7}",
|
|
33
59
|
"timeout_ms": 300000,
|
|
34
|
-
"expect_tools": [
|
|
60
|
+
"expect_tools": [
|
|
61
|
+
"molbio_design_taqman"
|
|
62
|
+
],
|
|
35
63
|
"assertions": [
|
|
36
64
|
{
|
|
37
65
|
"where": "tool",
|
|
@@ -48,21 +76,39 @@
|
|
|
48
76
|
"pattern": "vs the hotter primer",
|
|
49
77
|
"note": "the probe-vs-primer Tm margin, which the tool reports per candidate"
|
|
50
78
|
},
|
|
51
|
-
{
|
|
79
|
+
{
|
|
80
|
+
"where": "answer",
|
|
81
|
+
"pattern": "probe|Probe"
|
|
82
|
+
}
|
|
52
83
|
]
|
|
53
84
|
},
|
|
54
85
|
{
|
|
55
86
|
"id": "intron-qpcr",
|
|
56
87
|
"category": "primers",
|
|
57
88
|
"tier": "full",
|
|
58
|
-
"covers": [
|
|
89
|
+
"covers": [
|
|
90
|
+
"molbio_design_intron_primers"
|
|
91
|
+
],
|
|
59
92
|
"instruction": "I need a qPCR assay that will NOT amplify contaminating genomic DNA. Here is the genomic sequence and the two exon coordinates — design a pair where the forward primer spans the exon-exon junction. Tell me the spliced amplicon size and how far apart the primers sit on the genome.\n\n{seq:intron_genomic}\n\nExons: 1-400 and 701-1100 (1-based).",
|
|
60
93
|
"timeout_ms": 300000,
|
|
61
|
-
"expect_tools": [
|
|
94
|
+
"expect_tools": [
|
|
95
|
+
"molbio_design_intron_primers"
|
|
96
|
+
],
|
|
62
97
|
"assertions": [
|
|
63
|
-
{
|
|
64
|
-
|
|
65
|
-
|
|
98
|
+
{
|
|
99
|
+
"where": "tool",
|
|
100
|
+
"pattern": "forward primer spans an exon-exon junction",
|
|
101
|
+
"note": "the property that makes the assay genomic-DNA-proof"
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
"where": "tool",
|
|
105
|
+
"pattern": "spliced amplicon 320-406 \\(87 bp\\), genomic span 387 bp"
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
"where": "tool",
|
|
109
|
+
"pattern": "junction 12\\+6 bp",
|
|
110
|
+
"note": "bases contributed on each side of the junction"
|
|
111
|
+
},
|
|
66
112
|
{
|
|
67
113
|
"where": "answer",
|
|
68
114
|
"pattern": "splic|junction|genomic|intron|87|387",
|
|
@@ -74,12 +120,19 @@
|
|
|
74
120
|
"id": "multiplex-panel",
|
|
75
121
|
"category": "primers",
|
|
76
122
|
"tier": "full",
|
|
77
|
-
"covers": [
|
|
78
|
-
|
|
123
|
+
"covers": [
|
|
124
|
+
"molbio_multiplex_check"
|
|
125
|
+
],
|
|
126
|
+
"instruction": "I want to run these two primer pairs in the same multiplex tube. The first pair is on target A (template below), the second on target B. Check them against each other and tell me whether they interfere — dimers, unintended annealing, or bands I will not be able to tell apart. Also give me the recommended annealing temperature for the panel and a starting primer concentration for each pair.\n\nTarget A template:\n{template:400:7}\n\nPair A: forward ATTACTCCTGCTCTTCCCATAC (Tm 58.4), reverse CACTACTCCTCTGTACGCAC (Tm 58.9)\nPair B: forward GGGTTTCCCAAATTTGGGCCCA, reverse TTTGGGCCCAAATTTGGGAAAC\nTemplate B:\n{template:400:8}",
|
|
79
127
|
"timeout_ms": 300000,
|
|
80
|
-
"expect_tools": [
|
|
128
|
+
"expect_tools": [
|
|
129
|
+
"molbio_multiplex_check"
|
|
130
|
+
],
|
|
81
131
|
"assertions": [
|
|
82
|
-
{
|
|
132
|
+
{
|
|
133
|
+
"where": "tool",
|
|
134
|
+
"pattern": "multiplex panel: 2 target\\(s\\) on 2 template\\(s\\), 4 primer\\(s\\)"
|
|
135
|
+
},
|
|
83
136
|
{
|
|
84
137
|
"where": "tool",
|
|
85
138
|
"pattern": "primer-primer interactions above the dimer threshold: [0-9]+",
|
|
@@ -94,6 +147,66 @@
|
|
|
94
147
|
"where": "answer",
|
|
95
148
|
"pattern": "dimer|interfere|conflict|anneal",
|
|
96
149
|
"note": "the panel verdict. Note the measured behaviour this task must tolerate: a model that FIRST checks each pair on its own template often finds — correctly — that a pair as written does not amplify at all, and answers that instead. That is a better answer than 'no dimer conflict', not a worse one."
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
"where": "tool",
|
|
153
|
+
"pattern": "annealing temperature: [0-9.]+ °C \\(range [0-9.]+-[0-9.]+ °C\\)",
|
|
154
|
+
"note": "the panel-level annealing recommendation (lowest primer Tm minus the offset)"
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
"where": "tool",
|
|
158
|
+
"pattern": "primer concentration plan \\(nM\\):",
|
|
159
|
+
"note": "the starting primer-concentration plan"
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
"where": "answer",
|
|
163
|
+
"pattern": "anneal|temperature|concentration",
|
|
164
|
+
"note": "the model reports the new planning outputs, not only the dimer verdict"
|
|
165
|
+
}
|
|
166
|
+
]
|
|
167
|
+
},
|
|
168
|
+
{
|
|
169
|
+
"id": "taqman-mgb",
|
|
170
|
+
"category": "primers",
|
|
171
|
+
"tier": "full",
|
|
172
|
+
"covers": [
|
|
173
|
+
"molbio_design_taqman"
|
|
174
|
+
],
|
|
175
|
+
"instruction": "Design a TaqMan assay with an MGB probe on this template. Use an MGB probe, write the ordering sheet to mgb-order.csv, and tell me the probe length and Tm window the designer used, the top-ranked probe, and the 5'/3' modifications on its ordering row.\n\nTemplate:\n{template:400:7}",
|
|
176
|
+
"timeout_ms": 300000,
|
|
177
|
+
"expect_tools": [
|
|
178
|
+
"molbio_design_taqman"
|
|
179
|
+
],
|
|
180
|
+
"assertions": [
|
|
181
|
+
{
|
|
182
|
+
"where": "tool",
|
|
183
|
+
"pattern": "Probe chemistry: TaqMan MGB",
|
|
184
|
+
"note": "the MGB chemistry is selected, not silently the standard one"
|
|
185
|
+
},
|
|
186
|
+
{
|
|
187
|
+
"where": "tool",
|
|
188
|
+
"pattern": "13-20 nt, Tm 48-60",
|
|
189
|
+
"note": "the MGB length/Tm window, on the unmodified NN scale"
|
|
190
|
+
},
|
|
191
|
+
{
|
|
192
|
+
"where": "tool",
|
|
193
|
+
"pattern": "P TTGCTACGCCTGT",
|
|
194
|
+
"note": "the top-ranked MGB probe"
|
|
195
|
+
},
|
|
196
|
+
{
|
|
197
|
+
"where": "tool",
|
|
198
|
+
"pattern": "ordering CSV \\([0-9]+ oligo row\\(s\\)\\) saved to",
|
|
199
|
+
"note": "the ordering sheet was written"
|
|
200
|
+
},
|
|
201
|
+
{
|
|
202
|
+
"where": "tool",
|
|
203
|
+
"pattern": "MGB probes: the reported probe Tm is the unmodified DNA NN estimate",
|
|
204
|
+
"note": "the tool refuses to fabricate a modified Tm"
|
|
205
|
+
},
|
|
206
|
+
{
|
|
207
|
+
"where": "answer",
|
|
208
|
+
"pattern": "MGB|unmodified|modif",
|
|
209
|
+
"note": "the model explains the MGB Tm caveat or the modifications"
|
|
97
210
|
}
|
|
98
211
|
]
|
|
99
212
|
}
|
|
@@ -12,67 +12,144 @@
|
|
|
12
12
|
"id": "plasmid-digest",
|
|
13
13
|
"category": "restriction",
|
|
14
14
|
"tier": "full",
|
|
15
|
-
"covers": [
|
|
15
|
+
"covers": [
|
|
16
|
+
"molbio_restriction_sites"
|
|
17
|
+
],
|
|
16
18
|
"instruction": "I have pUC118.dna in my working directory. Show me the restriction map for EcoRI, HindIII and PvuII on the circular plasmid: where each enzyme cuts, and what fragments each one produces. Then tell me which of the three cuts the plasmid more than once.",
|
|
17
19
|
"timeout_ms": 240000,
|
|
18
|
-
"expect_tools": [
|
|
19
|
-
|
|
20
|
+
"expect_tools": [
|
|
21
|
+
"molbio_restriction_sites"
|
|
22
|
+
],
|
|
23
|
+
"fixtures": {
|
|
24
|
+
"pUC118.dna": "test/fixtures/pUC118.dna"
|
|
25
|
+
},
|
|
20
26
|
"assertions": [
|
|
21
|
-
{
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
{
|
|
27
|
-
|
|
27
|
+
{
|
|
28
|
+
"where": "tool",
|
|
29
|
+
"pattern": "EcoRI \\(G\\^AATTC\\):[\\s\\S]*?cut at 927",
|
|
30
|
+
"note": "EcoRI's single cut on pUC118"
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"where": "tool",
|
|
34
|
+
"pattern": "HindIII \\(A\\^AGCTT\\):[\\s\\S]*?cut at 876"
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
"where": "tool",
|
|
38
|
+
"pattern": "PvuII \\(CAG\\^CTG\\):[\\s\\S]*?cut at 785"
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
"where": "tool",
|
|
42
|
+
"pattern": "PvuII[\\s\\S]*?2 fragment\\(s\\): 2840, 322 bp",
|
|
43
|
+
"note": "PvuII is the double cutter"
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
"where": "answer",
|
|
47
|
+
"pattern": "PvuII"
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
"where": "answer",
|
|
51
|
+
"pattern": "2[,.]?840",
|
|
52
|
+
"note": "the larger PvuII fragment; accepts the thousands separator a human writes"
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
"where": "answer",
|
|
56
|
+
"pattern": "322"
|
|
57
|
+
}
|
|
28
58
|
]
|
|
29
59
|
},
|
|
30
60
|
{
|
|
31
61
|
"id": "double-digest-buffer",
|
|
32
62
|
"category": "restriction",
|
|
33
63
|
"tier": "core",
|
|
34
|
-
"covers": [
|
|
64
|
+
"covers": [
|
|
65
|
+
"molbio_double_digest"
|
|
66
|
+
],
|
|
35
67
|
"instruction": "I have a 512 bp linear construct in the workspace as a sequence I will paste, but simpler: use the sequence below. Cut it with EcoRI and HindIII together. Do these two enzymes share a reaction buffer, and what fragment sizes should I see on the gel?\n\n{seq:construct}",
|
|
36
68
|
"timeout_ms": 240000,
|
|
37
|
-
"expect_tools": [
|
|
69
|
+
"expect_tools": [
|
|
70
|
+
"molbio_double_digest"
|
|
71
|
+
],
|
|
38
72
|
"assertions": [
|
|
39
|
-
{
|
|
73
|
+
{
|
|
74
|
+
"where": "tool",
|
|
75
|
+
"pattern": "shared buffer\\(s\\):[^\\n]*CutSmart",
|
|
76
|
+
"note": "a shared buffer, so a single-tube digest is fine"
|
|
77
|
+
},
|
|
40
78
|
{
|
|
41
79
|
"where": "tool",
|
|
42
80
|
"pattern": "→ 206, 205, 101 bp",
|
|
43
81
|
"note": "THREE fragments, not two: the two site insertions add 6 bp each, so the two sites are 206 bp apart and the digest yields three pieces. This was probed, not reasoned about — the first draft of the fixture documented '200 + 300 bp' and was wrong."
|
|
44
82
|
},
|
|
45
|
-
{
|
|
46
|
-
|
|
47
|
-
|
|
83
|
+
{
|
|
84
|
+
"where": "answer",
|
|
85
|
+
"pattern": "206"
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
"where": "answer",
|
|
89
|
+
"pattern": "205"
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
"where": "answer",
|
|
93
|
+
"pattern": "101"
|
|
94
|
+
}
|
|
48
95
|
]
|
|
49
96
|
},
|
|
50
97
|
{
|
|
51
98
|
"id": "pcr-simulation",
|
|
52
99
|
"category": "pcr",
|
|
53
100
|
"tier": "full",
|
|
54
|
-
"covers": [
|
|
101
|
+
"covers": [
|
|
102
|
+
"molbio_pcr_simulate"
|
|
103
|
+
],
|
|
55
104
|
"instruction": "Check whether this primer pair amplifies the template I am pasting, and tell me the product size and coordinates. Use the forward primer as given and the reverse primer as given — both are written 5' to 3' as I would order them.\n\nTemplate (512 bp):\n{seq:construct}\n\nForward primer: {seq:pcr_forward}\nReverse primer: {seq:pcr_reverse}",
|
|
56
105
|
"timeout_ms": 240000,
|
|
57
|
-
"expect_tools": [
|
|
106
|
+
"expect_tools": [
|
|
107
|
+
"molbio_pcr_simulate"
|
|
108
|
+
],
|
|
58
109
|
"assertions": [
|
|
59
|
-
{
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
{
|
|
64
|
-
|
|
110
|
+
{
|
|
111
|
+
"where": "tool",
|
|
112
|
+
"pattern": "1 product\\(s\\) of 201 bp"
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
"where": "tool",
|
|
116
|
+
"pattern": "201 bp: 101-120 → 282-301",
|
|
117
|
+
"note": "the amplicon's coordinates on the top strand"
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
"where": "tool",
|
|
121
|
+
"pattern": "specific",
|
|
122
|
+
"note": "the tool's verdict word for a single clean product"
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
"where": "answer",
|
|
126
|
+
"pattern": "201"
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
"where": "answer",
|
|
130
|
+
"pattern": "101"
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
"where": "answer",
|
|
134
|
+
"pattern": "301"
|
|
135
|
+
}
|
|
65
136
|
]
|
|
66
137
|
},
|
|
67
138
|
{
|
|
68
139
|
"id": "gel-preview",
|
|
69
140
|
"category": "visualisation",
|
|
70
141
|
"tier": "full",
|
|
71
|
-
"covers": [
|
|
142
|
+
"covers": [
|
|
143
|
+
"molbio_virtual_gel"
|
|
144
|
+
],
|
|
72
145
|
"instruction": "I am running an EcoRI+HindIII double digest of pUC118.dna (full length 3162 bp, in your working directory) on a 1 kb ladder gel. Draw me the expected band pattern, and tell me how many bands I should see and whether the small fragment will be visible.",
|
|
73
146
|
"timeout_ms": 240000,
|
|
74
|
-
"expect_tools": [
|
|
75
|
-
|
|
147
|
+
"expect_tools": [
|
|
148
|
+
"molbio_virtual_gel"
|
|
149
|
+
],
|
|
150
|
+
"fixtures": {
|
|
151
|
+
"pUC118.dna": "test/fixtures/pUC118.dna"
|
|
152
|
+
},
|
|
76
153
|
"assertions": [
|
|
77
154
|
{
|
|
78
155
|
"where": "tool",
|
|
@@ -84,13 +161,20 @@
|
|
|
84
161
|
"pattern": "3111|3\\.1 kb|3\\.1kb|3162 ?- ?51",
|
|
85
162
|
"note": "the backbone fragment. Accepted as the exact size or its conventional `~3.1 kb` shorthand: both are correct, and demanding the digits graded how the model chose to round."
|
|
86
163
|
},
|
|
87
|
-
{
|
|
164
|
+
{
|
|
165
|
+
"where": "answer",
|
|
166
|
+
"pattern": "\\b51\\b",
|
|
167
|
+
"note": "the small fragment's exact size — pinned, because it explains the whole answer"
|
|
168
|
+
},
|
|
88
169
|
{
|
|
89
170
|
"where": "answer",
|
|
90
171
|
"pattern": "1 band|one band|2 band|two band|1 fragment|2 fragment|single .{0,12}band",
|
|
91
172
|
"note": "the band count. The model is EXPECTED to distinguish the two theoretical fragments from the single band a 1 kb-ladder gel actually resolves, so both counts are accepted."
|
|
92
173
|
},
|
|
93
|
-
{
|
|
174
|
+
{
|
|
175
|
+
"where": "answer",
|
|
176
|
+
"pattern": "not visible|too small|will not|won't|below|faint|run off|dye front|below detection"
|
|
177
|
+
}
|
|
94
178
|
]
|
|
95
179
|
}
|
|
96
180
|
]
|