renkin 0.61.0 → 1.0.1

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 CHANGED
@@ -171,9 +171,12 @@ Use `--format mermaid` for GitHub/Notion-compatible flowcharts.
171
171
 
172
172
  ## Current Limitations
173
173
 
174
- ⚠️ Benchmark numbers are under active re-measurement after a validator-accuracy
175
- fix historical 78.0%/95.9%/81.8%(ChEMBL) figures elsewhere in this repo predate
176
- that fix and are invalidated. RENKIN does not predict yields, calibrated
174
+ ⚠️ The 4,903-target v1.0.0 shared-stock comparison is complete: its statistical
175
+ superiority gate passed, but its formal publication gate remains on hold because
176
+ two frozen RENKIN rows failed route-tree integrity. Both failure modes pass a
177
+ targeted v1.0.1-candidate rerun; a full corrected rerun is still required before
178
+ changing the formal verdict. Historical 78.0%/95.9%/81.8%(ChEMBL) figures
179
+ elsewhere in this repo predate validator fixes and are invalidated. RENKIN does not predict yields, calibrated
177
180
  experimental success probabilities, or side reactions, and does not search
178
181
  the literature automatically (`success_probability` is a template-frequency
179
182
  search-ranking score, not a calibrated prediction — see
@@ -411,15 +414,15 @@ for the full acceptance criteria and licensing split.
411
414
  | **LightGBM candidate reranker** | `--reranker-model`/`--reranker-freq-table` (CLI) or `reranker_model_path`/`reranker_freq_table_path` (Python) — opt-in, ordering-only re-ranking via a frozen LightGBM model; never changes which candidates are generated, only their order, and reproduces legacy ordering byte-for-byte when off. Paired 100-target route-search gate: `route_to_configured_stock` 16→20 (+4/-0). `python3 scripts/fetch_reranker_model.py` fetches the frozen model (SHA-256-verified, not bundled in any package — see [Roadmap](#roadmap)) |
412
415
  | **Coverage mode** (opt-in) | `--search-mode coverage --coverage-templates <path>` (CLI) or `search_mode="coverage"`, `coverage_templates_path=...` (Python) — if the default template set finds no route, automatically escalates to a larger, separately loaded template set, cooperatively cancellable via `--coverage-timeout-secs`. Standard-mode output is byte-for-byte unchanged when not used. `python3 scripts/fetch_coverage_templates.py` fetches the frozen 2,000-template Stage-2 set (SHA-256-verified, not bundled in any package, same reasoning as the reranker model — see [Roadmap](#roadmap)) |
413
416
  | **RENKIN Bridge / `audit-route`** | `renkin audit-route route.json [--format auto\|renkin\|aizynthfinder\|syntheseus\|synplanner] [--stock stock.smi] [--output human\|json]` — tool-neutral route audit: structural integrity, stock, and declared-reaction forward-replay validation, each reported independently as `pass`/`fail`/`not_evaluable`, rolled up into a route-level `pass`/`fail`/`partial` verdict. Reads RENKIN-native route JSON (v0.25.0), real AiZynthFinder route JSON — single-target and gzip-compressed batch output, verified against AiZynthFinder 4.3.2, 4.4.0, and 4.4.1 specifically, not claimed for every version (v0.26.0, version matrix widened v0.32.0) — Syntheseus routes via the optional `renkin.syntheseus_exporter`'s `syntheseus-route-v1` interchange schema, since Syntheseus itself has no native route export (v0.30.0) — and real SynPlanner 1.6.0 `write_routes_json` exports directly, no exporter package needed (v0.34.0); `--format auto` detects the input shape and hard-errors rather than guessing on anything ambiguous. [AiZynthFinder walkthrough →](https://kent-tokyo.github.io/renkin/guides/aizynthfinder-audit-demo/) · [Syntheseus walkthrough →](https://kent-tokyo.github.io/renkin/guides/syntheseus-audit-demo/) · [SynPlanner walkthrough →](https://kent-tokyo.github.io/renkin/guides/synplanner-audit-demo/) |
414
- | **Route scoring** | `confidence`, `step_confidence`, `success_probability` (Retro-prob style), `convergency`, `atom_economy`, `route_cost` (`Σ BB cost + steps×0.5`, or actual prices via `--bb-prices`/`--stock`) per step/route — see caveat below the table |
417
+ | **Route scoring & diagnostics** | Separate `confidence`, `success_probability`, cost, feasibility findings, building-block diversity, and template-proxy chemical-idea diversity; no aggregate laboratory-feasibility score is fabricated — see the caveat below and the [diagnostics](docs/guides/route-feasibility-diagnostics.md) / [diversity](docs/guides/route-set-diversity.md) guides |
415
418
  | **Step metadata provenance** | Each step reports `metadata_source`/`metadata_scope` so it's machine-readable whether `conditions`/`reaction_family` came from a rule-author default vs. something more grounded; absent (not fabricated) for extracted templates |
416
419
  | **Pareto multi-objective search** | `--format pareto` returns a Pareto front across `route_cost`/`success_probability`/`steps`; objectives configurable via `--objectives` |
417
- | **Constraint DSL** | `--constraints constraints.json` — element filters, step limits, confidence thresholds, preferred reaction families; enables LLM → RENKIN pipelines |
420
+ | **Constraint DSL** | `--constraints constraints.json` — element/building-block filters, step/cost limits, confidence thresholds, required/avoided/preferred reaction families; enables LLM → RENKIN pipelines |
418
421
  | **Output formats & diagnostics** | `--format json\|tree\|mermaid\|explain\|compare\|compare-json\|pareto`; zero-route JSON includes a `diagnostics` block with `likely_causes`/`suggestions` |
419
422
  | **`renkin-forward` toolkit** | `predict` (rank forward products), `enumerate` (bounded products from one reactant + partner library), `hints` (partner-free retrieval hints, no concrete product), `validate` (forward-verify each retro step) — see the [Forward guides](docs/guides/forward-retrieval-hints.md#predict--enumerate--hints-at-a-glance) |
420
423
  | **`renkin-bench`** | USPTO-50k/PaRoutes evaluation with `--plausibility` (forward-validated composite score), `--failure-taxonomy`, atom-balance checks (`target_MW > Σ precursor_MW`), and multi-stage `cascade` re-runs on unsolved targets — see [Benchmark](#benchmark) |
421
- | **Stock management** | `renkin stock stats\|validate\|coverage` for legacy CSV plus the `vendor_stock` library API for v0.38 CSV/TSV vendor records (SMILES, ID, vendor, price, lead time, availability), explicit exact/parent/stereo/tautomer match modes, and an InChIKey candidate index |
422
- | **MCP server** | `renkin-mcp` exposes 6 tools: `find_routes`, `validate_route`, `explain_route`, `find_pareto_routes`, `plan_with_constraints`, `estimate_diversity` |
424
+ | **Stock management** | `renkin stock stats\|validate\|coverage\|compile`; integrity-checked `.rstock` snapshots avoid reparsing large stocks, while the `vendor_stock` API supports source, price, lead-time, availability, and exact/parent/stereo/tautomer policy |
425
+ | **MCP server** | `renkin-mcp` exposes 7 tools over stdio (`find_routes`, `validate_route`, `explain_route`, `find_pareto_routes`, `plan_with_constraints`, `estimate_diversity`, `diagnose_failure`) and supports the legacy `2024-11-05` and modern `2026-07-28` protocol revisions; see the [MCP guide](docs/guides/mcp.md) |
423
426
  | **`renkin-doctor`** | Environment diagnostic binary — templates, building blocks, Python import, tool versions, data integrity |
424
427
  | **`renkin-kg`** | Reaction knowledge graph builder — bipartite mol↔reaction graphs from routes, GraphML/Cypher export |
425
428
  | **Multi-target** | `pip install renkin` (pre-built wheels, Linux/macOS/Windows) · `npm install renkin` (~500 KB WASM, near-native browser speed) |
@@ -469,6 +472,23 @@ USPTO-50k test set (4,907 molecules, full evaluation):
469
472
 
470
473
  > **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.
471
474
 
475
+ ### Formal v1.0.0 shared-stock comparison (4,903 paired targets)
476
+
477
+ | Arm | Primary route-to-shared-stock successes | Rate |
478
+ |---|---:|---:|
479
+ | RENKIN v1.0.0 | 577 / 4,903 | 11.77% |
480
+ | AiZynthFinder 4.4.1 | 200 / 4,903 | 4.08% |
481
+
482
+ The paired RENKIN-minus-AiZynthFinder difference is **+7.689 percentage
483
+ points**, with paired-bootstrap 95% CI **[+6.812, +8.566]**. This passes the
484
+ pre-registered statistical gate. The formal publication gate is nevertheless
485
+ **HOLD**: two frozen RENKIN rows had no parseable normalized route tree. The
486
+ v1.0.1-candidate fixes make both targeted reruns parseable and stock-terminated,
487
+ but only a fresh full 4,903-target run can change the frozen verdict. This is a
488
+ shared-stock route endpoint, not experimental yield or universal CASP
489
+ superiority. [Protocol and status](docs/benchmark/formal-v1.0-competitor-comparison.md)
490
+ · [frozen report](data/comparison/formal_v1.0/formal_report.md)
491
+
472
492
  ### Corrected baseline (commit `e20dc8c`, 2026-07-22)
473
493
 
474
494
  | Public label | Internal metric | Value |
@@ -557,7 +577,7 @@ The JSON output includes `avg_nodes_expanded`, `avg_confidence`, `avg_convergenc
557
577
  }
558
578
  ```
559
579
 
560
- **Tools** (6):
580
+ **Tools** (7):
561
581
 
562
582
  | Tool | Description |
563
583
  |---|---|
@@ -565,15 +585,20 @@ The JSON output includes `avg_nodes_expanded`, `avg_confidence`, `avg_convergenc
565
585
  | `validate_route` | Forward-validate a retrosynthetic route |
566
586
  | `explain_route` | Human-readable strengths/weaknesses per route |
567
587
  | `find_pareto_routes` | Pareto-front multi-objective route search |
568
- | `plan_with_constraints` | Constraint-DSL planning (element filters, step limits, confidence thresholds) |
588
+ | `plan_with_constraints` | Constraint-DSL planning (element/building-block filters, step/cost limits, confidence thresholds, required/avoided/preferred reaction families) |
569
589
  | `estimate_diversity` | Route diversity and coverage metrics |
590
+ | `diagnose_failure` | Structured explanation of why a search found no route |
570
591
 
571
592
  `find_routes` also accepts `search_mode: "coverage"` with a required
572
593
  `coverage_templates` path. It runs the standard Stage 1 first and escalates
573
594
  to Stage 2 only when Stage 1 finds no route; the response reports the selected
574
595
  stage, timeout status, and per-stage elapsed time.
575
596
 
576
- 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()`, 22 handcrafted rules, including the new graph-based `carbamate_cleavage` rule).
597
+ The server auto-detects `data/building_blocks.smi` and the optional, locally
598
+ generated `data/templates_extracted_5000.smi` in the working directory. It
599
+ falls back to the embedded `DEFAULT_BUILDING_BLOCKS` / `default_rules()`
600
+ defaults if they are not found (152 unique building blocks per
601
+ `ChemEnv::bb_count()`, 23 handcrafted rules).
577
602
 
578
603
  ```bash
579
604
  cargo build --release
@@ -612,7 +637,7 @@ Target SMILES
612
637
  ┌─────────────────────────┐
613
638
  │ chem_env.rs │ ← chematic wrapper
614
639
  │ - SMILES parse │ canonical-SMILES FxHashSet BB lookup (O(1))
615
- │ - 21 built-in + up to 50k via --templates │ fragment sanitization + ring-leak filter
640
+ │ - 23 built-in + up to 50k via --templates │ fragment sanitization + ring-leak filter
616
641
  │ - Building block check │ apply_retro memoization cache
617
642
  └────────────┬────────────┘
618
643
  │ par_iter (rayon / sequential on WASM)
@@ -655,7 +680,8 @@ renkin/ ← Cargo workspace root
655
680
  │ ├── bin/benchmark.rs # renkin-bench binary (--plausibility flag)
656
681
  │ ├── bin/doctor.rs # renkin-doctor diagnostic binary
657
682
  │ ├── bin/fp.rs # renkin-fp ECFP4 fingerprint (nn-scoring feature)
658
- │ ├── bin/mcp.rs # renkin-mcp MCP server (6 tools)
683
+ │ ├── bin/mcp.rs # renkin-mcp stdio launcher
684
+ │ ├── mcp/ # Dual-era protocol + 7 tool handlers
659
685
  │ ├── chem_env.rs # retro rules + BB lookup + template loader
660
686
  │ ├── score.rs # SA Score heuristic + step cost
661
687
  │ ├── search.rs # A* / AND-OR tree engine + beam pruning
@@ -669,7 +695,7 @@ renkin/ ← Cargo workspace root
669
695
  │ └── renkin-kg/ # reaction knowledge graph builder (GraphML / Cypher export)
670
696
  ├── data/
671
697
  │ ├── building_blocks.smi # 402 curated commercial starting materials (loaded/deduplicated count)
672
- │ ├── templates_extracted_5000.smi # 5,000 auto-extracted SMIRKS templates
698
+ │ ├── templates_extracted_500.smi # 500 checked-in auto-extracted SMIRKS templates
673
699
  │ ├── benchmark_targets.smi # internal benchmark set
674
700
  │ └── bench_chunks/ # USPTO-50k per-chunk results
675
701
  ├── scripts/
@@ -713,8 +739,15 @@ see "Earlier milestones" below for older shipped work.
713
739
  ### Next
714
740
 
715
741
  - [x] Graph rule expansion — sulfonamide and carbamate cleavage (one PR per family, with structural and atom-accounting gates; carbamate shipped v0.61.0)
716
- - [ ] Urea cleavage — define and validate an atom-balanced disconnection before adding a default rule
742
+ - [x] Urea cleavage — validated atom-balanced disconnection to isocyanate + amine; implemented locally as the next-version candidate (not published)
717
743
  - [ ] Stock-aware planning (price / hazard / availability re-ranking)
744
+ - [x] Deterministic policy-aware vendor-offer selection (price, lead time,
745
+ availability) for exact private-stock matches
746
+ - [x] Optional local hazard labels and blocked-hazard policy decisions
747
+ - [x] Route-level stock score and deterministic multi-route ranking metadata
748
+ - [x] Constraint DSL route-cost cap (`max_route_cost`) with explicit route-cost semantics
749
+ - [x] Exact canonical building-block exclusion (`avoid_building_blocks`) for private/constrained stock policies
750
+ - [x] Exact canonical building-block requirement (`require_building_blocks`) for house-stock policies
718
751
 
719
752
  <details>
720
753
  <summary>Earlier milestones</summary>
@@ -745,12 +778,12 @@ see [Benchmark](#benchmark) for the corrected historical baseline.
745
778
  - [x] `renkin-doctor` — environment diagnostic binary (templates, BBs, Python, binaries)
746
779
  - [x] Failure diagnostics — zero-route output includes `likely_causes` + `suggestions` JSON block
747
780
  - [x] `--format explain|compare|compare-json` — human-readable and tabular route output
748
- - [x] `renkin stock stats|validate|coverage` — stock CSV management subcommand
781
+ - [x] `renkin stock stats|validate|coverage|compile` — stock inspection plus integrity-checked compiled `.rstock` snapshots
749
782
  - [x] Pareto multi-objective search — `--format pareto`, `--objectives`, `find_pareto_routes` MCP
750
783
  - [x] Constraint DSL — `--constraints JSON`, `plan_with_constraints` MCP tool
751
784
  - [x] `renkin template stats|validate|dedup|explain|coverage` — template quality tools
752
785
  - [x] `renkin-kg` — reaction knowledge graph (bipartite mol↔reaction, GraphML/Cypher export)
753
- - [x] MCP server (`renkin-mcp`) — expanded to 6 tools (`explain_route`, `find_pareto_routes`, `plan_with_constraints`, ...)
786
+ - [x] MCP server (`renkin-mcp`) — 7 tools with legacy `2024-11-05` and modern `2026-07-28` stdio protocol support
754
787
  - [x] Core search engine foundation — SMIRKS retro-reaction rules + fragment sanitization, A\*/AND-OR tree search with closed list + degenerate-route filter, SA Score heuristic + beam search, `rayon` parallel rule application (sequential fallback on WASM), FxHashMap/SmallVec beam frontier/SA-Score-memoization/`Arc<PathNode>` path-sharing perf work
755
788
  - [x] Multi-target packaging — Python bindings (PyO3 + maturin, `pip install renkin`), WASM build (`npm install renkin`), published to crates.io/PyPI/npm with GitHub Actions CI/CD, WASM browser playground + i18n (EN/JA/ZH)
756
789
  - [x] Benchmark CLI (`renkin-bench`) + USPTO-50k evaluation, `--format tree|mermaid` visualization, MkDocs documentation site + GitHub Pages playground
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "kent-tokyo <kent-tokyo@users.noreply.github.com>"
6
6
  ],
7
7
  "description": "Ultra-fast retrosynthesis engine for computer-aided synthesis planning (CASP) — pure Rust, WASM-ready, Python bindings via PyO3",
8
- "version": "0.61.0",
8
+ "version": "1.0.1",
9
9
  "license": "MIT",
10
10
  "repository": {
11
11
  "type": "git",
package/renkin.d.ts CHANGED
@@ -138,6 +138,16 @@ export function find_routes_v4(target: string, depth: number, max_routes: number
138
138
  */
139
139
  export function find_routes_v5(target: string, depth: number, max_routes: number, beam_width: number, avoid_elements: string, require_elements: string, spectator_bond_policy: string, element_accounting_policy: string, beam_diversity_policy: string, beam_diversity_slots: number): string;
140
140
 
141
+ /**
142
+ * Same as [`find_routes_v5`], plus bounded candidate-level diagnostics.
143
+ * `candidate_trace_limit` is an explicit collection cap; `0` collects no
144
+ * records while still returning the aggregate `search_diagnostics` block.
145
+ * The diagnostics are read-only and do not affect route selection. A new
146
+ * export preserves the fail-loud compatibility behavior of the earlier
147
+ * versioned WASM functions.
148
+ */
149
+ export function find_routes_v6(target: string, depth: number, max_routes: number, beam_width: number, avoid_elements: string, require_elements: string, spectator_bond_policy: string, element_accounting_policy: string, beam_diversity_policy: string, beam_diversity_slots: number, candidate_trace_limit: number): string;
150
+
141
151
  /**
142
152
  * Return the crate version string.
143
153
  */
@@ -155,6 +165,7 @@ export interface InitOutput {
155
165
  readonly find_routes_v3: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number, j: number, k: number) => [number, number];
156
166
  readonly find_routes_v4: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number, j: number, k: number, l: number, m: number, n: number) => [number, number];
157
167
  readonly find_routes_v5: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number, j: number, k: number, l: number, m: number, n: number, o: number, p: number) => [number, number];
168
+ readonly find_routes_v6: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number, j: number, k: number, l: number, m: number, n: number, o: number, p: number, q: number) => [number, number];
158
169
  readonly version: () => [number, number];
159
170
  readonly __wbindgen_externrefs: WebAssembly.Table;
160
171
  readonly __wbindgen_malloc: (a: number, b: number) => number;
package/renkin.js CHANGED
@@ -328,6 +328,51 @@ export function find_routes_v5(target, depth, max_routes, beam_width, avoid_elem
328
328
  }
329
329
  }
330
330
 
331
+ /**
332
+ * Same as [`find_routes_v5`], plus bounded candidate-level diagnostics.
333
+ * `candidate_trace_limit` is an explicit collection cap; `0` collects no
334
+ * records while still returning the aggregate `search_diagnostics` block.
335
+ * The diagnostics are read-only and do not affect route selection. A new
336
+ * export preserves the fail-loud compatibility behavior of the earlier
337
+ * versioned WASM functions.
338
+ * @param {string} target
339
+ * @param {number} depth
340
+ * @param {number} max_routes
341
+ * @param {number} beam_width
342
+ * @param {string} avoid_elements
343
+ * @param {string} require_elements
344
+ * @param {string} spectator_bond_policy
345
+ * @param {string} element_accounting_policy
346
+ * @param {string} beam_diversity_policy
347
+ * @param {number} beam_diversity_slots
348
+ * @param {number} candidate_trace_limit
349
+ * @returns {string}
350
+ */
351
+ export function find_routes_v6(target, depth, max_routes, beam_width, avoid_elements, require_elements, spectator_bond_policy, element_accounting_policy, beam_diversity_policy, beam_diversity_slots, candidate_trace_limit) {
352
+ let deferred7_0;
353
+ let deferred7_1;
354
+ try {
355
+ const ptr0 = passStringToWasm0(target, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
356
+ const len0 = WASM_VECTOR_LEN;
357
+ const ptr1 = passStringToWasm0(avoid_elements, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
358
+ const len1 = WASM_VECTOR_LEN;
359
+ const ptr2 = passStringToWasm0(require_elements, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
360
+ const len2 = WASM_VECTOR_LEN;
361
+ const ptr3 = passStringToWasm0(spectator_bond_policy, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
362
+ const len3 = WASM_VECTOR_LEN;
363
+ const ptr4 = passStringToWasm0(element_accounting_policy, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
364
+ const len4 = WASM_VECTOR_LEN;
365
+ const ptr5 = passStringToWasm0(beam_diversity_policy, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
366
+ const len5 = WASM_VECTOR_LEN;
367
+ const ret = wasm.find_routes_v6(ptr0, len0, depth, max_routes, beam_width, ptr1, len1, ptr2, len2, ptr3, len3, ptr4, len4, ptr5, len5, beam_diversity_slots, candidate_trace_limit);
368
+ deferred7_0 = ret[0];
369
+ deferred7_1 = ret[1];
370
+ return getStringFromWasm0(ret[0], ret[1]);
371
+ } finally {
372
+ wasm.__wbindgen_free(deferred7_0, deferred7_1, 1);
373
+ }
374
+ }
375
+
331
376
  /**
332
377
  * Return the crate version string.
333
378
  * @returns {string}
package/renkin_bg.wasm CHANGED
Binary file