renkin 0.1.1 → 0.18.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.
Files changed (3) hide show
  1. package/README.md +550 -73
  2. package/package.json +5 -2
  3. package/renkin_bg.wasm +0 -0
package/README.md CHANGED
@@ -1,17 +1,23 @@
1
- # RENKIN — **R**etrosynthetic **E**xploration **N**etwork for **K**nowledge-**I**nformed **N**avigation
1
+ # RENKIN — Retrosynthesis Engine for Knowledge-Informed Navigation
2
2
 
3
3
  > **Computer-Aided Synthesis Planning (CASP) · Pure Rust · WebAssembly · Python**
4
4
  > Named after 錬金 (れんきん, *renkin*) — Japanese for alchemy: just as alchemists transformed base metals into gold, RENKIN transforms target molecules back into cheap starting materials.
5
5
 
6
- [![CI](https://github.com/kent-tokyo/renkin/actions/workflows/ci.yml/badge.svg)](https://github.com/kent-tokyo/renkin/actions/workflows/ci.yml)
7
- [![Crates.io](https://img.shields.io/crates/v/renkin)](https://crates.io/crates/renkin)
8
- [![PyPI](https://img.shields.io/pypi/v/renkin)](https://pypi.org/project/renkin/)
9
- [![npm](https://img.shields.io/npm/v/renkin)](https://www.npmjs.com/package/renkin)
10
- [![License: MIT](https://img.shields.io/badge/license-MIT-blue)](LICENSE)
11
- [![WASM](https://img.shields.io/badge/WASM-ready-brightgreen)](https://kent-tokyo.github.io/renkin/playground/)
12
- [![Pure Rust](https://img.shields.io/badge/Pure-Rust-orange?logo=rust)](https://www.rust-lang.org)
6
+ <p>
7
+ <a href="https://github.com/kent-tokyo/renkin/actions/workflows/ci.yml"><img alt="CI" src="https://github.com/kent-tokyo/renkin/actions/workflows/ci.yml/badge.svg?branch=master"></a>
8
+ <a href="https://github.com/kent-tokyo/renkin/actions/workflows/docs.yml"><img alt="Docs" src="https://github.com/kent-tokyo/renkin/actions/workflows/docs.yml/badge.svg?branch=master"></a>
9
+ </p>
13
10
 
14
- [日本語版 README](./README_ja.md) · [**Documentation**](https://kent-tokyo.github.io/renkin/) · [**Live Demo →**](https://kent-tokyo.github.io/renkin/playground/)
11
+ <p>
12
+ <a href="https://crates.io/crates/renkin"><img alt="Crates.io" src="https://img.shields.io/crates/v/renkin.svg"></a>
13
+ <a href="https://docs.rs/renkin"><img alt="docs.rs" src="https://docs.rs/renkin/badge.svg"></a>
14
+ <a href="https://pypi.org/project/renkin/"><img alt="PyPI" src="https://img.shields.io/pypi/v/renkin.svg"></a>
15
+ <a href="https://pypi.org/project/renkin/"><img alt="Python" src="https://img.shields.io/pypi/pyversions/renkin.svg"></a>
16
+ <a href="https://www.npmjs.com/package/renkin"><img alt="npm" src="https://img.shields.io/npm/v/renkin.svg"></a>
17
+ <a href="LICENSE"><img alt="License: MIT" src="https://img.shields.io/badge/license-MIT-blue.svg"></a>
18
+ </p>
19
+
20
+ [日本語版 README](./README_ja.md) · [中文版 README](./README_zh.md) · [**Documentation**](https://kent-tokyo.github.io/renkin/) · [**Live Demo →**](https://kent-tokyo.github.io/renkin/playground/)
15
21
 
16
22
  ---
17
23
 
@@ -19,10 +25,7 @@
19
25
 
20
26
  RENKIN is an open-source **retrosynthesis engine** for **computer-aided synthesis planning (CASP)** that automatically discovers optimal chemical reaction routes from a target molecule back to cheap, commercially available starting materials.
21
27
 
22
- Built entirely in Rust with the [`chematic`](https://docs.rs/chematic/) cheminformatics crate. Zero C/C++ dependencies.
23
-
24
- **[→ Try the Live Playground](https://kent-tokyo.github.io/renkin/playground/)** — runs entirely in WebAssembly, no installation needed.
25
- **[→ Full Documentation](https://kent-tokyo.github.io/renkin/)** — API reference, examples, benchmark.
28
+ Built entirely in Rust with the [`chematic`](https://docs.rs/chematic/) cheminformatics crate zero C/C++ dependencies, `#![forbid(unsafe_code)]` throughout. One codebase compiles to a native CLI, a Rust library, Python wheels (PyO3), and a WebAssembly module that runs entirely client-side in the browser.
26
29
 
27
30
  ---
28
31
 
@@ -36,15 +39,24 @@ npm install renkin # JavaScript / Node.js
36
39
 
37
40
  ---
38
41
 
42
+ ## Live Playground
43
+
44
+ **[→ Try it now](https://kent-tokyo.github.io/renkin/playground/)** — runs entirely in WebAssembly: no installation, no server, no network calls.
45
+
46
+ ---
47
+
39
48
  ## Quick Start
40
49
 
41
50
  ```python
51
+ import json
42
52
  import renkin
43
53
 
44
- result = renkin.find_routes(
45
- "CC(=O)Oc1ccccc1C(=O)O", # Aspirin
46
- depth=5,
47
- max_routes=3,
54
+ result = json.loads(
55
+ renkin.find_routes(
56
+ target="CC(=O)Oc1ccccc1C(=O)O", # Aspirin
57
+ depth=5,
58
+ max_routes=3,
59
+ )
48
60
  )
49
61
 
50
62
  for route in result["routes"]:
@@ -60,26 +72,303 @@ const result = JSON.parse(find_routes("CC(=O)Oc1ccccc1C(=O)O", 5, 3, 0));
60
72
 
61
73
  ```bash
62
74
  ./target/release/renkin --target "CC(=O)Oc1ccccc1C(=O)O" --depth 5 \
63
- --templates data/templates_extracted.smi
75
+ --templates data/templates_extracted_5000.smi --format tree
76
+ ```
77
+
78
+ ```text
79
+ Target: CC(=O)Oc1ccccc1C(=O)O
80
+ Routes found: 3
81
+
82
+ Route 1 [score=1.02, depth=1]
83
+ OC(=O)c1ccccc1OC(=O)C
84
+ └── [extracted_169]
85
+ ├── OC(=O)C ✓ BB
86
+ └── [OH]c1ccccc1C(=O)O ✓ BB
87
+
88
+ Route 2 [score=1.02, depth=1]
89
+ OC(=O)c1ccccc1OC(=O)C
90
+ └── [extracted_145]
91
+ ├── CC(=O)Cl ✓ BB
92
+ └── [OH]c1ccccc1C(=O)O ✓ BB
93
+
94
+ Route 3 [score=1.03, depth=1]
95
+ OC(=O)c1ccccc1OC(=O)C
96
+ └── [extracted_238]
97
+ ├── c1cccc(c1O)C(O)=O ✓ BB
98
+ └── C([OH])(=O)C ✓ BB
64
99
  ```
65
100
 
101
+ Use `--format mermaid` for GitHub/Notion-compatible flowcharts.
102
+
103
+ [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/kent-tokyo/renkin/blob/master/examples/renkin_quickstart.ipynb)
104
+
105
+ ---
106
+
107
+ ## Current Limitations
108
+
109
+ ⚠️ Benchmark numbers are under active re-measurement after a validator-accuracy
110
+ fix — historical 78.0%/95.9%/81.8%(ChEMBL) figures elsewhere in this repo predate
111
+ that fix and are invalidated. RENKIN does not predict yields, calibrated
112
+ experimental success probabilities, or side reactions, and does not search
113
+ the literature automatically (`success_probability` is a template-frequency
114
+ search-ranking score, not a calibrated prediction — see
115
+ [Benchmark](https://kent-tokyo.github.io/renkin/benchmark/) for the current
116
+ corrected numbers, full methodology, and known limitations).
117
+
118
+ ---
119
+
120
+ ## Why RENKIN?
121
+
122
+ RENKIN is designed as a Rust-native synthesis planning stack:
123
+
124
+ | | |
125
+ |---|---|
126
+ | **Fast** | A\* / AND-OR tree search with beam search and template frequency weighting |
127
+ | **Portable** | Native CLI · Python wheels · npm/WASM · browser playground — one codebase |
128
+ | **Explainable** | Per-step `confidence`, `atom_economy`, `route_cost`, and `procedure_hint` |
129
+ | **Verifiable** | `renkin-forward` validates each retrosynthetic step by forward-applying templates |
130
+ | **Benchmarkable** | USPTO-50k, PaRoutes-style evaluation, route diversity, and atom balance checks |
131
+ | **Agent-ready** | MCP server exposes routes and validation to Claude Desktop and AI agents |
132
+
133
+ ---
134
+
135
+ ## Constraint-based Search
136
+
137
+ Restrict routes by the element composition of their building blocks.
138
+
139
+ **Default search** — all 5 routes for biphenyl:
140
+
141
+ ```bash
142
+ renkin --target "c1ccc(-c2ccccc2)cc1" --templates data/templates_extracted_5000.smi --format tree
143
+ ```
144
+
145
+ ```text
146
+ Routes found: 5
147
+ Route 1 [score=1.00, depth=1] c1ccccc1Br + c1c(B(O)O)cccc1
148
+ Route 2 [score=1.03, depth=1] c1ccccc1Br + c1c(B(O)O)cccc1
149
+ Route 3 [score=1.06, depth=1] c1cc(Cl)ccc1 + c1c(B(O)O)cccc1
150
+ Route 4 [score=1.08, depth=1] c1(I)ccccc1 + c1c(B(O)O)cccc1
151
+ Route 5 [score=1.08, depth=1] c1ccccc1Br + c1(B2OC(C(C)(C)O2)(C)C)ccccc1
152
+ ```
153
+
154
+ **Constrained search** — boronic-acid coupling, no Br or I starting materials:
155
+
156
+ ```bash
157
+ renkin --target "c1ccc(-c2ccccc2)cc1" --templates data/templates_extracted_5000.smi \
158
+ --require-elements "B" --avoid-elements "Br,I" --format tree
159
+ ```
160
+
161
+ ```text
162
+ Routes found: 1
163
+
164
+ Route 1 [score=1.06, depth=1]
165
+ c1ccccc1-c2ccccc2
166
+ └── [extracted_398]
167
+ ├── c1cc(Cl)ccc1 ✓ BB
168
+ └── c1c(B(O)O)cccc1 ✓ BB
169
+ ```
170
+
171
+ Constraints compose freely and are enforced in two layers:
172
+ - `--avoid-elements` **prunes expansions during search** when a BB precursor contains a forbidden element (no dead-end nodes added to the heap).
173
+ - A final route-level post-filter is still applied for correctness.
174
+ - `--require-elements` is a route-level post-filter only.
175
+
176
+ Add `--verbose` to print search statistics (nodes expanded, elapsed time) to stderr. Performance counters are available in native builds only; disabled in WASM.
177
+
178
+ ---
179
+
180
+ ## Template Evidence Metadata
181
+
182
+ Extracted templates only have a positional display name (`extracted_{i}`) that
183
+ changes whenever the source `.smi` file is reordered or re-extracted, so
184
+ external knowledge (a DOI, a reported yield, a known side reaction) can't be
185
+ durably attached to one. Every template — hand-crafted and extracted — now
186
+ has a stable `template_id` instead:
187
+
188
+ - Hand-crafted rules: `rule:<rule_name>` (e.g. `rule:suzuki_retro`).
189
+ - Extracted templates: `smirks-sha256:<hex>` — the SHA-256 hex digest of the
190
+ *trimmed* SMIRKS string. Independent of file position, load order, and
191
+ count; purely syntactic (no SMIRKS canonicalization — a semantically
192
+ equivalent SMIRKS written differently gets a different ID).
193
+
194
+ Run `renkin template ids <file.smi>` to list every template's `template_id`,
195
+ display name, SMIRKS, and weight (TSV by default, `--format json` for JSON) —
196
+ use this to look up the IDs you need when authoring a sidecar file.
197
+
198
+ Attach curated evidence with `--template-metadata sidecar.json` (also
199
+ available in Python as `find_routes(..., template_metadata_path=...)`),
200
+ keyed by `template_id`:
201
+
202
+ ```json
203
+ {
204
+ "schema_version": 1,
205
+ "templates": {
206
+ "smirks-sha256:ef8778a2888469d619c52cce7e74f6848e101049050dd1b765b78f32e3c94498": {
207
+ "references": [
208
+ { "id": "ref-1", "kind": "doi", "identifier": "10.xxxx/example" }
209
+ ],
210
+ "condition_candidates": [
211
+ {
212
+ "catalysts": ["Pd(PPh3)4"],
213
+ "bases": ["K2CO3"],
214
+ "solvents": ["EtOH", "water"],
215
+ "temperature_c": { "min": 75.0, "max": 85.0 },
216
+ "source": "literature",
217
+ "scope": "template",
218
+ "reference_ids": ["ref-1"]
219
+ }
220
+ ],
221
+ "reported_yields": [
222
+ {
223
+ "percentage": { "min": 72.0, "max": 81.0 },
224
+ "basis": "isolated",
225
+ "source": "literature",
226
+ "scope": "template",
227
+ "reference_ids": ["ref-1"]
228
+ }
229
+ ],
230
+ "warnings": [
231
+ {
232
+ "code": "possible_protodeboronation",
233
+ "severity": "medium",
234
+ "message": "Protodeboronation has been reported under prolonged aqueous heating.",
235
+ "source": "literature",
236
+ "scope": "template",
237
+ "reference_ids": ["ref-1"]
238
+ }
239
+ ]
240
+ }
241
+ }
242
+ }
243
+ ```
244
+
245
+ A matching step gets an `evidence` field with `condition_candidates`,
246
+ `reported_yields`, `references`, and `warnings`; steps whose template has no
247
+ sidecar entry get no `evidence` key at all. The sidecar is loaded and
248
+ validated (schema version, duplicate/dangling reference IDs, yield range,
249
+ range `min <= max`, non-empty DOI/patent identifiers) **before search
250
+ starts** — malformed metadata is a hard error, and a `template_id` in the
251
+ sidecar that matches no loaded rule prints a warning rather than failing
252
+ silently.
253
+
254
+ **What this is not:**
255
+ - `reported_yields` is a curated record of what was reported externally —
256
+ **not a RENKIN prediction**. `step_confidence`/`success_probability` are
257
+ unaffected and keep meaning template-frequency-derived search-ranking
258
+ scores, not experimental success rates.
259
+ - `warnings` reflects only what's explicitly present in the sidecar you
260
+ supply — **not** automatic side-reaction detection.
261
+ - Templates without a matching sidecar entry get no fabricated evidence.
262
+ Nothing is invented for missing data.
263
+
264
+ Yield/success prediction and automatic literature search are explicitly out
265
+ of scope for this phase — tracked as future work in
266
+ [#41](https://github.com/kent-tokyo/renkin/issues/41).
267
+
268
+ ### Substrate-specific examples (`schema_version: 2`)
269
+
270
+ Everything above is *template-level*: it applies to every step using that
271
+ template, regardless of the actual molecule. `schema_version: 2` adds
272
+ `examples` — a per-template array where each entry is one curated record of
273
+ *this exact reaction*, keyed by `target_smiles`/`precursor_smiles`:
274
+
275
+ ```json
276
+ {
277
+ "schema_version": 2,
278
+ "templates": {
279
+ "smirks-sha256:...": {
280
+ "references": [{ "id": "ref-1", "kind": "doi", "identifier": "10.xxxx/example" }],
281
+ "examples": [{
282
+ "id": "ex-1",
283
+ "target_smiles": "c1ccc(-c2ccccc2)cc1",
284
+ "precursor_smiles": ["Brc1ccccc1", "c1ccccc1"],
285
+ "conditions": { "catalysts": ["Pd(PPh3)4"], "solvents": ["EtOH"], "source": "literature", "scope": "substrate_specific", "reference_ids": ["ref-1"] },
286
+ "reported_yield": { "percentage": 78.0, "basis": "isolated", "source": "literature", "scope": "substrate_specific", "reference_ids": ["ref-1"] },
287
+ "reference_ids": ["ref-1"]
288
+ }]
289
+ }
290
+ }
291
+ }
292
+ ```
293
+
294
+ `examples` requires `schema_version: 2` (a hard error under `1`); under
295
+ `schema_version: 2`, reported yields must live under `examples[].reported_yield`
296
+ too — a non-empty template-level `reported_yields` is a hard error there (it
297
+ stays allowed under `schema_version: 1`), so a substrate-specific number can't
298
+ leak onto every step using that template. Every condition/yield/warning
299
+ nested inside an example must be scoped `substrate_specific`.
300
+
301
+ A route step's `evidence.examples` are **resolved**, not just copied from the
302
+ sidecar: matched against that step by canonical target SMILES plus the
303
+ canonical, order-independent precursor set (reordering `precursor_smiles` in
304
+ the sidecar changes nothing), with every exact-substrate match kept and
305
+ same-template-different-substrate precedents capped at 3. Each resolved entry
306
+ carries a `match_kind` (`exact_substrate`/`template_only`) in the JSON itself,
307
+ plus a `template_examples_total` count — so JSON/Python consumers, not just
308
+ `--format explain`, can tell "evidence for this exact reaction" apart from
309
+ "literature precedent for a different substrate." `--format explain` shows
310
+ exact-substrate matches first, each labeled either `Exact substrate example:`
311
+ or *"different substrate; not a prediction"*, with `conditions`/
312
+ `reported_yield`/`warnings` each showing their own cited references directly
313
+ underneath (deduplicated when the same reference backs more than one part of
314
+ an example). See [Reaction Evidence guide](docs/guides/reaction-evidence.md#substrate-specific-examples-schema_version-2)
315
+ for full matching/validation semantics.
316
+
66
317
  ---
67
318
 
68
319
  ## Key Features
69
320
 
70
321
  | Feature | Detail |
71
322
  |---|---|
72
- | **Pure Rust** | Zero C/C++ dependenciescross-platform with `cargo build` alone |
73
- | **A\* / AND-OR Tree Search** | Retro\*-equivalent algorithm, proven more efficient than MCTS |
74
- | **SA Score heuristic** | Admissible h = Σ(1 + 0.5·(sa−1)/9) guides toward accessible precursors |
75
- | **Beam search** | `--beam-width N` for memory-bounded exploration |
76
- | **314 reaction rules** | 31 hand-crafted + 283 auto-extracted from USPTO-50k via rdchiral |
77
- | **Auto template extraction** | `scripts/extract_templates.py` — rdchiral + chematic-compatible simplification |
78
- | **Graph-based biaryl cleavage** | Bridge-bond DFS for correct Suzuki disconnection |
323
+ | **Pure Safe Rust** | `#![forbid(unsafe_code)]` on all crates compiler-enforced, zero C/C++ dependencies |
324
+ | **A\* / AND-OR Tree Search** | Retro\*-equivalent algorithm with pluggable heuristics (`MoleculeValueEstimator`, `ReactionPrior`) |
325
+ | **Up to 50k reaction templates** | Auto-extracted from USPTO-50k/MIT via rdchiral; frequency-weighted priority; `--templates` for custom sets |
326
+ | **Route scoring** | `confidence`, `step_confidence`, `success_probability` (Retro-prob style), `convergency`, `atom_economy` per step — see caveat below the table |
327
+ | **Step metadata provenance** | Each step reports `metadata_source`/`metadata_scope` (e.g. `handcrafted_default`/`reaction_family`) so it's machine-readable whether `conditions`/`reaction_family` came from a rule-author default vs. something more grounded; absent for extracted templates, since nothing is fabricated for them. |
328
+ | **Stable template IDs + evidence sidecar** | Every template gets a stable `template_id` — `rule:<name>` for hand-crafted rules, `smirks-sha256:<hex>` for extracted templates (independent of file order/position/count). Attach curated DOIs/patents, reported conditions, reported yields, and known side-reaction warnings via a `--template-metadata sidecar.json` file keyed by `template_id`; matching steps get an `evidence` field, everything else stays untouched see [Template evidence metadata](#template-evidence-metadata) below. `schema_version: 2` sidecars can additionally attach `examples` — curated records tied to one exact target/precursor set, matched by canonical SMILES and surfaced first in `--format explain`. Run `renkin template ids <file.smi>` to list stable IDs for authoring a sidecar. Automatic yield/success prediction and literature search remain out of scope ([#41](https://github.com/kent-tokyo/renkin/issues/41)). |
329
+ | **Route cost scoring** | `route_cost = Σ(BB cost) + steps×0.5`; actual prices via `--bb-prices CSV` or `--stock stock.csv` |
330
+ | **Pareto multi-objective search** | `--format pareto` returns a Pareto front across `route_cost`, `success_probability`, `steps`, etc.; objectives configurable via `--objectives cost:min,success_probability:max,steps:min` |
331
+ | **Constraint DSL** | `--constraints constraints.json` — JSON-driven synthesis planning: element filters, step limits, confidence thresholds, preferred reaction families; enables LLM → RENKIN pipeline |
332
+ | **Output formats** | `--format json` · `tree` · `mermaid` · `explain` (human-readable per-route analysis) · `compare` (side-by-side table) · `compare-json` · `pareto` |
333
+ | **Failure diagnostics** | Zero-route JSON output includes `diagnostics` block with `likely_causes` and `suggestions` |
334
+ | **Forward validation** | `renkin-forward validate` verifies each step by applying templates forward; accepts `--route-json` or stdin |
335
+ | **Plausibility report** | `renkin-bench --plausibility` — forward-validates best routes and reports composite plausibility score |
336
+ | **PaRoutes benchmark** | `renkin-bench --input-format paroutes` for multi-step ground-truth evaluation with `depth_delta` and `route_diversity` |
337
+ | **Atom balance check** | `renkin-bench` flags steps where `target_MW > Σ precursor_MW` (CompleteRXN reference) |
338
+ | **Stock CSV management** | `renkin stock stats\|validate\|coverage` — inspect and validate stock CSV files with SMILES, name, vendor, price, hazard fields |
339
+ | **Template quality tools** | `renkin template stats\|validate\|dedup\|explain\|coverage\|ids` — inspect SMIRKS template sets: frequency distribution, validity, duplicates, per-template lookup, coverage rate, stable template IDs |
340
+ | **MCP server** | `renkin-mcp` exposes 6 tools: `find_routes`, `validate_route`, `explain_route`, `find_pareto_routes`, `plan_with_constraints`, `estimate_diversity` |
341
+ | **`renkin-doctor`** | Environment diagnostic binary — checks templates, building blocks, Python import, tool versions, and data integrity |
342
+ | **`renkin-kg`** | Reaction knowledge graph builder — constructs bipartite mol↔reaction graphs from routes; exports to GraphML or Cypher |
343
+ | **Beam search** | `--beam-width N` for memory-bounded exploration; `SmallVec<[FEntry; 6]>` stack-allocated frontier |
79
344
  | **Parallel rule application** | `rayon` on non-WASM; sequential fallback on wasm32 |
345
+ | **tract-onnx NN scorer** | Pure Rust ONNX inference (no C++ dep) — optional `--scorer` flag for Phase B template relevance scoring |
346
+ | **`building_blocks` in JSON** | Each route includes the leaf starting-material SMILES — no manual step parsing needed |
347
+ | **Tetrahedral stereo @/@@** | Full stereochemistry support via chematic 0.4.16 |
80
348
  | **Python** | `pip install renkin` — pre-built wheels for Linux/macOS/Windows |
81
349
  | **WASM** | ~500 KB bundle — runs in the browser at near-native speed |
82
- | **463 building blocks** | Aryl halides, boronic acids, heterocycles, amines, acids, amino acids |
350
+ | **402 building blocks** | Aryl halides, boronic acids, heterocycles, amines, acids, amino acids (`data/building_blocks.smi`, unique compounds actually loaded — see Benchmark section) |
351
+
352
+ > **`step_confidence`/`success_probability` are not yields or measured success rates.**
353
+ > They're template-frequency-derived search-ranking scores (`rule_weight / max_rule_weight`,
354
+ > multiplied across a route's steps) used to order candidate disconnections during search —
355
+ > not a calibrated probability of experimental success, and not an expected isolated yield.
356
+ > Route-level experimental yield/success-rate reporting is not implemented.
357
+
358
+ ---
359
+
360
+ ## Pipeline Examples
361
+
362
+ ```bash
363
+ # Route cost scoring with commercial prices
364
+ renkin -t "Cc1ccc(-c2ccccc2)cc1" --bb-prices data/prices.csv --format json
365
+
366
+ # Forward validation — pipe find_routes output directly
367
+ renkin -t "CC(=O)Oc1ccccc1C(=O)O" --format json | renkin-forward validate
368
+
369
+ # Faster template retrieval with bond-center index (~24% speedup)
370
+ renkin -t "c1ccc(NC(=O)c2ccccc2)cc1" --templates data/templates_extracted_5000.smi --bond-index
371
+ ```
83
372
 
84
373
  ---
85
374
 
@@ -87,20 +376,65 @@ const result = JSON.parse(find_routes("CC(=O)Oc1ccccc1C(=O)O", 5, 3, 0));
87
376
 
88
377
  USPTO-50k test set (4,907 molecules, full evaluation):
89
378
 
90
- | Config | Solved | Rate | BBs | Rules | depth |
91
- |---|---|---|---|---|---|
92
- | v0.1.0 initial | 366/4907 | 7.5% | 463 | 31 | 3 |
93
- | + auto templates (top-300) | 1363/4907 | 27.8% | 463 | 222 | 3 |
94
- | + depth=5, top-500 templates | **2315/4907** | **47.2%** | 463 | 314 | 5 |
379
+ > **Evaluation definition**: A molecule is *solved* if `find_routes` returns at least one route whose leaf precursors are all in the building block set, within depth=5 and beam=100. Ground-truth reactants from USPTO-50k are **not** checked — any commercially accessible route counts.
95
380
 
96
- Surpasses ASKCOS (41%) and reaches AiZynthFinder lower bound (45%) with only 463 curated BBs.
97
- Competitor reference: AiZynthFinder 45–53% (depth≤5, 6M BBs, 50k templates).
98
- [Full benchmark details →](https://kent-tokyo.github.io/renkin/benchmark/)
381
+ ### Corrected baseline (commit `e20dc8c`, 2026-07-22)
382
+
383
+ | Public label | Internal metric | Value |
384
+ |---|---|---|
385
+ | Search-to-stock rate | `raw_solved_rate` | **20.09%** (986/4,907) |
386
+ | Atom-balance-filtered rate | `atom_balanced_solved_rate` | **15.41%** (756/4,907) — subset of search-to-stock |
387
+ | Current-validator-confirmed rate | `provenance_validated_solved_rate` | **0.88%** (43/4,907) — subset of atom-balance-filtered |
388
+
389
+ 402 building blocks (unique compounds actually loaded from `data/building_blocks.smi` — see below), 5,000 extracted templates, 28 handcrafted rules, depth=5, beam=100. These three rates are a nested series over the same 4,907 targets, not independent numbers, and none is an experimentally-verified synthesis success rate or a human-chemist-reviewed route-accuracy figure. `provenance_validated_solved_rate` is not a measured chemical-accuracy rate and not a proven lower bound on correctness — it only counts routes the current validator can positively confirm, and an unknown fraction of "invalid" verdicts may be validator false negatives rather than real chemistry or route errors (the split is unmeasured). Full methodology, per-rule breakdown, and reproduction command: [`tasks/phase31_final_remeasurement_run.md`](https://github.com/kent-tokyo/renkin/blob/master/tasks/phase31_final_remeasurement_run.md) · [Full benchmark details →](https://kent-tokyo.github.io/renkin/benchmark/)
390
+
391
+ ### Historical progression (pre-fix, invalidated — see notice above)
392
+
393
+ ⚠️ The figures in this subsection (78.0% single-pass, 95.9% cascade, 81.8% ChEMBL OOD) predate the 31.11/31.12 fixes, are invalidated, and have not been re-measured. Kept for continuity only — do not cite as current performance.
394
+
395
+ > **Evaluation note**: All numbers use the standard USPTO-50k train/test split (same corpus). Templates are extracted from the training set and evaluated on the test set. Numbers reflect performance within the USPTO-50k domain; out-of-distribution generalization was separately evaluated via ChEMBL approved drugs (**81.8%**, 409/500, also not re-measured).
396
+
397
+ | Config | Solved | Rate | BBs | Templates | depth | beam | ms/mol |
398
+ |---|---|---|---|---|---|---|---|
399
+ | v0.1.0 initial | 366/4907 | 7.5% | 463 | 31 | 3 | 50 | — |
400
+ | + auto templates (top-300) | 1363/4907 | 27.8% | 463 | 222 | 3 | 50 | — |
401
+ | + depth=5, top-500 templates | 2315/4907 | 47.2% | 463 | 314 | 5 | 50 | — |
402
+ | + beam=100 | 2688/4907 | 54.8%* | 463 | 314 | 5 | 100 | — |
403
+ | + Phase A (template freq. weighting) | 3540/4907 | 72.1%† | 463 | 314 | 5 | 100 | — |
404
+ | + 5,000 templates, 480 BBs | 3826/4907 | 78.0% | 480 | 5,000 | 5 | 100 | 2,775 |
405
+ | Phase A unlimited (beam=0) | 3832/4907 | 78.1% | 480 | 5,000 | 5 | 0 | — |
406
+ | Phase B (NN scorer, tract-onnx) | 3826/4907 | 78.0% | 480 | 5,000 | 5 | 100 | 3,394 |
407
+ | **+ diaryl sulfone rule, 509 BBs** | **3826/4907** | **78.0%** | **509** | **5,000** | **5** | **100** | **≈2,800** |
408
+ | Cascade (stage2: depth=7, beam=300 on unsolved) | 4705/4907 | **95.9%** | 509 | 5,000 | 7 | 300 | — |
409
+
410
+ \* 29/50 chunks, previous binary
411
+ † 50/50 chunks — **72.1%** (3,540/4,907) confirmed
412
+ BB counts in this historical table (463/480/509) are as originally documented at each point in time — legacy documentation values, not re-verified against `ChemEnv::bb_count()`. The corrected-baseline section above uses the actually-loaded count (402) for the current `data/building_blocks.smi`.
413
+
414
+ *Note: LocalRetro (53.4%) and GLG (58.0%) report single-step top-1 prediction accuracy — a different metric, not directly comparable.*
415
+
416
+ > **Benchmark scope note**: USPTO-50k is used here as a *standardized sanity benchmark*, not as proof of broad real-world synthesis performance. The corpus covers a narrow slice of reaction space (primarily C–C and C–N bond formations common in pharmaceutical synthesis), and reaction types with sparse USPTO representation are systematically underserved. Out-of-distribution performance on ChEMBL approved drugs (**81.8%**, 409/500, pre-fix, not re-measured) suggested the rule set generalizes beyond the test corpus, but neither historical number should be interpreted as a guarantee of route quality on arbitrary targets.
417
+
418
+ ### PaRoutes compatibility
419
+
420
+ RENKIN is compatible with the [PaRoutes](https://github.com/AstraZeneca/PaRoutes) multi-step benchmark. Download their stock compounds and target molecules, then pass them directly:
421
+
422
+ ```bash
423
+ renkin-bench \
424
+ --input paroutes_n1_targets.smi \
425
+ --building-blocks paroutes_stock.smi \
426
+ --templates data/templates_extracted_5000.smi \
427
+ --depth 5 --beam-width 100
428
+ ```
429
+
430
+ The JSON output includes `avg_nodes_expanded`, `avg_confidence`, `avg_convergency`, and `avg_success_prob` (Retro-prob style) alongside the standard solved/success_rate metrics.
99
431
 
100
432
  ---
101
433
 
102
434
  ## Competitive Landscape
103
435
 
436
+ ⚠️ RENKIN's row below uses the corrected `raw_solved_rate` (20.09%, see notice near the top of this README) — the 95.9% cascade figure some earlier versions of this table cited is invalidated and not re-measured; it is not included here.
437
+
104
438
  | Tool | Language | License | WASM | Zero-dep | Algorithm | Template source | Stock |
105
439
  |---|---|---|---|---|---|---|---|
106
440
  | **ASKCOS** | Python | CC BY-NC | No | No (Docker, 64 GB) | MCTS + A\* | USPTO (ML) | ZINC |
@@ -108,31 +442,90 @@ Competitor reference: AiZynthFinder 45–53% (depth≤5, 6M BBs, 50k templates).
108
442
  | **SYNTHIA** | Closed | Proprietary | No | No | SMARTS + AND/OR | Manual curated | Sigma-Aldrich |
109
443
  | **IBM RXN** | Closed | Cloud SaaS | No | No | Transformer | USPTO | — |
110
444
  | **Retro\*** | Python | MIT | No | No (unmaintained) | A\* + AND/OR | USPTO (ML) | eMolecules |
111
- | **★ RENKIN** | **Rust** | **MIT** | **Yes** | **Yes** | **A\* + AND/OR** | Hand-curated + rdchiral (314) | 463+ |
445
+ | **★ RENKIN** | **Rust** | **MIT** | **Yes** | **Yes** | **A\* + AND/OR** | Hand-curated + rdchiral (5k default; 50k via `--templates`) | 402+ |
446
+
447
+ `raw_solved_rate` is the closest available RENKIN metric to the published route-finding success rates of the other planners above, but the figures are not directly comparable — stock size, template library, target set, search budget, and route-quality checks all differ across systems, and this table does not establish RENKIN as better or worse than the alternatives.
448
+
449
+ **RENKIN's goal**: match state-of-the-art accuracy using only curated rules and auto-extracted SMIRKS templates — no GPU, no training data, no black boxes. Under RENKIN's benchmark setting (corrected baseline, commit `e20dc8c`, 2026-07-22), it reaches **20.09%** `raw_solved_rate` (986/4,907) single-pass — see the Benchmark section above for the full nested-metric series and why the stricter `provenance_validated_solved_rate` (0.88%) is not RENKIN's measured or bounded correctness rate. RENKIN runs anywhere: browser, CLI, Python — single `cargo build`.
450
+
451
+ > ⚠️ The table above lists tools under different evaluation conditions. No matched-condition experiment against other tools has been performed.
452
+
453
+ ---
454
+
455
+ ## MCP Server
456
+
457
+ `renkin-mcp` exposes retrosynthesis as an MCP tool so AI agents (Claude, etc.) can call it directly.
458
+
459
+ **Setup** — add to `claude_desktop_config.json`:
460
+
461
+ ```json
462
+ {
463
+ "mcpServers": {
464
+ "renkin": { "command": "/path/to/renkin-mcp" }
465
+ }
466
+ }
467
+ ```
112
468
 
113
- **RENKIN's goal**: match or exceed neural-network-based tools using only curated rules and auto-extracted SMIRKS templates — no GPU, no training data, no black boxes. At 47.2% USPTO-50k (surpassing ASKCOS and reaching AiZynthFinder's lower bound), RENKIN demonstrates that a transparent, rule-based engine in pure Rust can compete with deep-learning approaches. And it runs anywhere: browser, CLI, Python — single `cargo build`.
469
+ **Tools** (6):
470
+
471
+ | Tool | Description |
472
+ |---|---|
473
+ | `find_routes` | Retrosynthesis: SMILES → routes with scoring |
474
+ | `validate_route` | Forward-validate a retrosynthetic route |
475
+ | `explain_route` | Human-readable strengths/weaknesses per route |
476
+ | `find_pareto_routes` | Pareto-front multi-objective route search |
477
+ | `plan_with_constraints` | Constraint-DSL planning (element filters, step limits, confidence thresholds) |
478
+ | `estimate_diversity` | Route diversity and coverage metrics |
479
+
480
+ The server auto-detects `data/building_blocks.smi` and `data/templates_extracted_5000.smi` in the working directory. Falls back to the embedded `DEFAULT_BUILDING_BLOCKS` / `default_rules()` defaults if not found (152 unique building blocks per `ChemEnv::bb_count()`, 28 handcrafted rules — verified 2026-07-22; a "509-BB / 20-rule" figure was previously documented here without verification).
481
+
482
+ ```bash
483
+ cargo build --release
484
+ # binary: target/release/renkin-mcp
485
+ ```
114
486
 
115
487
  ---
116
488
 
117
489
  ## Architecture
118
490
 
491
+ ### Workspace scope
492
+
493
+ ```
494
+ ┌──────────────────────────────────────────────────────────────────┐
495
+ │ renkin workspace (this repository) │
496
+ │ │
497
+ │ renkin (retrosynthesis) renkin-forward │
498
+ │ ────────────────────── ───────────────────────────── │
499
+ │ target → precursors reactants → products │
500
+ │ A* / AND-OR search template-based forward │
501
+ │ route scoring & constraints (validates retro routes) │
502
+ │ │ │ │
503
+ │ └──────────────────┬─────────────────┘ │
504
+ │ ▼ │
505
+ │ chematic (molecular representation, │
506
+ │ SMILES, substructure matching, reaction SMARTS) │
507
+ └──────────────────────────────────────────────────────────────────┘
508
+ ```
509
+
510
+ ### Internal data flow (renkin crate)
511
+
119
512
  ```
120
513
  Target SMILES
121
514
 
122
515
 
123
516
  ┌─────────────────────────┐
124
517
  │ chem_env.rs │ ← chematic wrapper
125
- │ - SMILES parse │ canonical-SMILES HashSet BB lookup (O(1))
126
- │ - 314 retro rules │ fragment sanitization + ring-leak filter
127
- │ - Building block check │ VF2 fallback for small sets
518
+ │ - SMILES parse │ canonical-SMILES FxHashSet BB lookup (O(1))
519
+ │ - 20 built-in + up to 50k via --templates │ fragment sanitization + ring-leak filter
520
+ │ - Building block check │ apply_retro memoization cache
128
521
  └────────────┬────────────┘
129
522
  │ par_iter (rayon / sequential on WASM)
130
523
 
131
524
  ┌─────────────────────────┐
132
525
  │ search.rs │ ← A* / AND-OR Tree Search
133
- │ - Priority queue │ SA Score heuristic
134
- │ - Closed list │ beam search pruning
135
- │ - Degenerate filter
526
+ │ - Priority queue │ SA Score heuristic + memoization
527
+ │ - Closed list │ beam search (SmallVec frontier)
528
+ │ - Arc<PathNode> paths O(1) path sharing per child
136
529
  └────────────┬────────────┘
137
530
 
138
531
 
@@ -140,6 +533,13 @@ Target SMILES
140
533
  │ score.rs │ ← Heuristic / Cost Function
141
534
  │ - SA Score (chematic) │ h = Σ(1 + 0.5·(sa−1)/9)
142
535
  │ - MW step cost │ g = Σ(1 + total_mw/2000)
536
+ └────────────┬────────────┘
537
+
538
+
539
+ ┌─────────────────────────┐ (optional)
540
+ │ scorer.rs │ ← Phase B: NN Template Scorer
541
+ │ - tract-onnx │ Pure Rust ONNX inference
542
+ │ - --scorer flag │ molecule-specific template ranking
143
543
  └────────────┬────────────┘
144
544
 
145
545
 
@@ -151,22 +551,29 @@ Target SMILES
151
551
  ## Project Structure
152
552
 
153
553
  ```
154
- renkin/
554
+ renkin/ ← Cargo workspace root
155
555
  ├── Cargo.toml
156
- ├── src/
157
- │ ├── lib.rs # public library
158
- │ ├── main.rs # CLI binary (--templates flag)
159
- │ ├── bin/benchmark.rs # renkin-bench binary (--templates flag)
160
- │ ├── chem_env.rs # 314 retro rules, BB check, template loader
161
- │ ├── score.rs # SA Score heuristic + step cost
162
- │ ├── search.rs # A* / AND-OR tree engine + beam pruning
163
- │ ├── python.rs # PyO3 bindings (--features python)
164
- └── wasm.rs # wasm-bindgen bindings (cfg = wasm32)
556
+ ├── src/ ← renkin crate (retrosynthesis)
557
+ │ ├── lib.rs # public library
558
+ │ ├── main.rs # CLI binary (--templates, --template-metadata, --scorer, --constraints, --objectives flags)
559
+ │ ├── bin/benchmark.rs # renkin-bench binary (--plausibility flag)
560
+ │ ├── bin/doctor.rs # renkin-doctor diagnostic binary
561
+ │ ├── bin/fp.rs # renkin-fp ECFP4 fingerprint (nn-scoring feature)
562
+ │ ├── bin/mcp.rs # renkin-mcp MCP server (6 tools)
563
+ │ ├── chem_env.rs # retro rules + BB lookup + template loader
564
+ ├── score.rs # SA Score heuristic + step cost
565
+ │ ├── search.rs # A* / AND-OR tree engine + beam pruning
566
+ │ ├── scorer.rs # Phase B: tract-onnx NN template scorer
567
+ │ ├── python.rs # PyO3 bindings (--features python)
568
+ │ └── wasm.rs # wasm-bindgen bindings (cfg = wasm32)
569
+ ├── crates/ ← sibling crates
570
+ │ ├── renkin-forward/ # forward reaction prediction (reactants → products)
571
+ │ └── renkin-kg/ # reaction knowledge graph builder (GraphML / Cypher export)
165
572
  ├── data/
166
- │ ├── building_blocks.smi # 463 curated commercial starting materials
167
- │ ├── templates_extracted.smi # 283 auto-extracted SMIRKS templates (top-500)
168
- │ ├── benchmark_targets.smi # internal benchmark set
169
- │ └── bench_chunks/ # USPTO-50k per-chunk results
573
+ │ ├── building_blocks.smi # 402 curated commercial starting materials (loaded/deduplicated count)
574
+ │ ├── templates_extracted_5000.smi # 5,000 auto-extracted SMIRKS templates
575
+ │ ├── benchmark_targets.smi # internal benchmark set
576
+ │ └── bench_chunks/ # USPTO-50k per-chunk results
170
577
  ├── scripts/
171
578
  │ ├── extract_templates.py # rdchiral template extraction pipeline
172
579
  │ └── run_benchmark_chunks.sh # resumable chunked benchmark runner
@@ -178,23 +585,89 @@ renkin/
178
585
 
179
586
  ## Roadmap
180
587
 
181
- - [x] **Phase 1** — SMIRKS retro-reaction rules + fragment sanitization
182
- - [x] **Phase 2** — A\* / AND-OR tree search, closed list, degenerate-route filter
183
- - [x] **Phase 3** SA Score heuristic + beam search
184
- - [x] **Phase 4**Parallel rule application (rayon; sequential fallback on WASM)
185
- - [x] **Phase 5**Python bindings (PyO3 + maturin) · `pip install renkin`
186
- - [x] **Phase 6**WASM build · `npm install renkin`
187
- - [x] **Phase 7**Benchmark CLI (`renkin-bench`) + initial USPTO-50k evaluation
188
- - [x] **Phase 8**Unit tests · rules 31 · building blocks 463
189
- - [x] **Phase 9** WASM browser playground + i18n (EN/JA/ZH)
190
- - [x] **Phase 10** — Graph-based biaryl cleavage · O(1) canonical-SMILES BB index
191
- - [x] **Phase 11** — Published to crates.io / PyPI / npm · GitHub Actions CI/CD
192
- - [x] **Phase 12** — MkDocs documentation site · GitHub Pages playground
193
- - [x] **Phase 13** — Formal USPTO-50k benchmark: **7.5%** (depth=3, 31 rules)
194
- - [x] **Phase 14** Auto template extraction (rdchiral): **27.8%** (depth=3, 222 rules)
195
- - [x] **Phase 17** chematic 0.4.12: Bug #13 (BFS leakage) + Bug #14 (canonical SMILES) fixed
196
- - [ ] **Phase 15** — Stereochemistry support (CIP SMIRKS)
197
- - [ ] **Phase 16** — Large-scale building block DB integration
588
+ ### Recently shipped
589
+
590
+ - [x] Stable `template_id` (`rule:<name>` / `smirks-sha256:<hex>`) + `--template-metadata` evidence sidecar + `renkin template ids` ([#41](https://github.com/kent-tokyo/renkin/issues/41) phase 1)
591
+ - [x] Substrate-specific `examples` (`schema_version: 2`) per-step exact-substrate vs. same-template-different-substrate resolution, surfaced in `--format explain` and as `match_kind` in JSON ([#41](https://github.com/kent-tokyo/renkin/issues/41) phase 2)
592
+ - [x] `renkin-bench cascade`multi-stage search (fast defaults → hard cases re-run deeper); only unsolved targets propagate to later stages. **78.0% → 95.9%** on USPTO-50k
593
+ - [x] `renkin-bench --failure-taxonomy`classify unsolved targets by cause (beam limit / depth limit / template gap / stock near-miss)
594
+ - [x] Graph-based ester cleavage BFS-leakage-free `R-C(=O)-O-R' RCOOH + R'OH`
595
+ - [x] `--top-templates N`frequency-rank filter: use the top-N most frequent templates for speed / less noise
596
+ - [x] `raw / validated / practical` solved-rate metrics (`--plausibility --practical-max-steps N`)
597
+ - [x] Retro cache hit-rate in `SearchStats` + `--verbose`
598
+
599
+ ### In progress
600
+
601
+ - [ ] Template retrieval index (element bitmask + bond-center prefilter) for the 50k template set
602
+ - [ ] Calibrated route confidence (map `success_probability` to empirical solve rate)
603
+
604
+ ### Next
605
+
606
+ - [ ] Graph rule expansion — sulfonamide / carbamate / urea cleavage (one PR per family, each with benchmark delta)
607
+ - [ ] Stock-aware planning (price / hazard / availability re-ranking)
608
+
609
+ <details>
610
+ <summary>Earlier milestones</summary>
611
+
612
+ - [x] Route cost scoring — `route_cost` field + `--bb-prices path.csv` / `--stock stock.csv`
613
+ - [x] Cargo workspace — `crates/renkin-forward/` + `crates/renkin-kg/`
614
+ - [x] `renkin-forward predict` / `validate` — forward prediction + route validation (stdin-pipe friendly)
615
+ - [x] `renkin-doctor` — environment diagnostic binary (templates, BBs, Python, binaries)
616
+ - [x] Failure diagnostics — zero-route output includes `likely_causes` + `suggestions` JSON block
617
+ - [x] `--format explain|compare|compare-json` — human-readable and tabular route output
618
+ - [x] `renkin stock stats|validate|coverage` — stock CSV management subcommand
619
+ - [x] Pareto multi-objective search — `--format pareto`, `--objectives`, `find_pareto_routes` MCP
620
+ - [x] Constraint DSL — `--constraints JSON`, `plan_with_constraints` MCP tool
621
+ - [x] `renkin template stats|validate|dedup|explain|coverage` — template quality tools
622
+ - [x] `renkin-kg` — reaction knowledge graph (bipartite mol↔reaction, GraphML/Cypher export)
623
+ - [x] MCP server expanded to 6 tools (`explain_route`, `find_pareto_routes`, `plan_with_constraints`)
624
+ - [x] SMIRKS retro-reaction rules + fragment sanitization
625
+ - [x] A\* / AND-OR tree search, closed list, degenerate-route filter
626
+ - [x] SA Score heuristic + beam search
627
+ - [x] Parallel rule application (rayon; sequential fallback on WASM)
628
+ - [x] Python bindings (PyO3 + maturin) · `pip install renkin`
629
+ - [x] WASM build · `npm install renkin`
630
+ - [x] Benchmark CLI (`renkin-bench`) + USPTO-50k evaluation
631
+ - [x] WASM browser playground + i18n (EN/JA/ZH)
632
+ - [x] Graph-based biaryl cleavage · O(1) canonical-SMILES BB index
633
+ - [x] Published to crates.io / PyPI / npm · GitHub Actions CI/CD
634
+ - [x] MkDocs documentation site · GitHub Pages playground
635
+ - [x] Auto template extraction (rdchiral): **27.8%** → **78.0%** USPTO-50k
636
+ - [x] Tetrahedral stereo @/@@ + E/Z double-bond stereo
637
+ - [x] Template frequency weighting (Phase A): **72.1%** USPTO-50k
638
+ - [x] FxHashMap · SmallVec beam frontier · SA Score memoization · Arc<PathNode> path sharing
639
+ - [x] 5,000 extracted templates + 509 BBs: **78.0%** USPTO-50k (3,826/4,907 ✅)
640
+ - [x] NN template scorer via `--scorer` flag (tract-onnx, Pure Rust ONNX)
641
+ - [x] `--format tree|mermaid` route visualization
642
+ - [x] Constraint-based search: `--avoid-elements`, `--require-elements`
643
+ - [x] `--verbose` search statistics to stderr
644
+ - [x] MCP server (`renkin-mcp`) — AI agents call retrosynthesis directly
645
+ - [x] `#![forbid(unsafe_code)]` — compiler-enforced Pure Safe Rust
646
+
647
+ </details>
648
+
649
+ ---
650
+
651
+ ## Citation
652
+
653
+ If you use RENKIN in academic work, please cite:
654
+
655
+ ```bibtex
656
+ @software{renkin2026,
657
+ author = {kent-tokyo},
658
+ title = {{RENKIN}: Retrosynthesis Engine for Knowledge-Informed Navigation},
659
+ year = {2026},
660
+ url = {https://github.com/kent-tokyo/renkin/releases/tag/v0.18.0},
661
+ version = {0.18.0},
662
+ license = {MIT}
663
+ }
664
+ ```
665
+
666
+ ---
667
+
668
+ ## Security
669
+
670
+ Report vulnerabilities via [GitHub Private vulnerability reporting](https://github.com/kent-tokyo/renkin/security/advisories/new). See [SECURITY.md](SECURITY.md).
198
671
 
199
672
  ---
200
673
 
@@ -205,3 +678,7 @@ MIT
205
678
  ---
206
679
 
207
680
  *GitHub Topics: `retrosynthesis` `cheminformatics` `wasm` `rust` `drug-discovery` `casp` `synthesis-planning` `computational-chemistry`*
681
+
682
+ ---
683
+
684
+ If RENKIN saves you time, a GitHub star helps others discover it.
package/package.json CHANGED
@@ -1,8 +1,11 @@
1
1
  {
2
2
  "name": "renkin",
3
3
  "type": "module",
4
+ "collaborators": [
5
+ "kent-tokyo <kent-tokyo@users.noreply.github.com>"
6
+ ],
4
7
  "description": "Ultra-fast retrosynthesis engine for computer-aided synthesis planning (CASP) — pure Rust, WASM-ready, Python bindings via PyO3",
5
- "version": "0.1.1",
8
+ "version": "0.18.0",
6
9
  "license": "MIT",
7
10
  "repository": {
8
11
  "type": "git",
@@ -26,4 +29,4 @@
26
29
  "wasm",
27
30
  "drug-discovery"
28
31
  ]
29
- }
32
+ }
package/renkin_bg.wasm CHANGED
Binary file