Changelog¶
Pre-1.0 Compatibility Policy¶
RetroCast is still pre-1.0.0. Until 1.0.0, we will make breaking changes to the core schema or workflows whenever we see a compelling reason to do so. We'll try to keep some sane deprecation schedule unless it incurs a significant complexity cost.
Practically speaking, you should treat 2-raw (or wherever you store the raw planner outputs) as the source of truth and 3-processed, 4-scored, 5-results as regenerable.
For most use cases, this should not be a problem since the full pipeline of ingest, score, and analyze is decently fast. If you are using (or planning to use) RetroCast in production pipelines that will handle large volumes of data, please feel free to get in touch.
v0.7.0 (in development, not yet released on PyPi)¶
v0.7.0 updates RetroCast to new schema design, check that page for the full mental model.
Highlights¶
- Promoted the schema-2 models, adapters, workflow, metrics, IO, and CLI into the main
retrocastpackage. - Replaced the old prediction-wrapper path with
Candidate, which preserves either a successfulRouteor aFailureRecordfor benchmark accounting. - Split the workflow around the schema-2 path:
adapt -> collect -> score -> analyze. - Kept route-local node ids derived from tree position rather than serialized into
MoleculeorReactionobjects. - Added route signatures for full-route, prefix-depth, reaction, and subtree comparison.
- Implemented Solv-N scoring: Tier-N route validity plus task-constraint satisfaction.
Migration Notes¶
This is a hard pre-1.0 schema break. Processed, scored, and result artifacts produced by older schema-1 workflows should be regenerated from raw planner payloads.
v0.6.0¶
v0.6.0 makes RetroCast more useful as a general route-standardization library, not only as a benchmark runner. The main design change is the split between adapting provider output into canonical predictions and collecting those predictions onto benchmark targets for scoring.
For the full machine-generated change list, see the GitHub comparison after the release tag is published: v0.5.3...v0.6.0.
Highlights¶
- Added
PredictedRoute, an envelope around canonicalRoutechemistry for provider-level rank, score, confidence, source row, and metadata. - Split adaptation from benchmark collection with
adapt_provider_output(...),adapt_target_keyed_provider_output(...), andcollect_benchmark_predictions(...). - Kept
retrocast ingestas the project-mode convenience command for the common raw-output-to-benchmark-routes workflow. - Added route-corpus IO and CLI support for streamable prediction artifacts such as
.jsonl.gz. - Added support for flat LLM completion corpora with
<synthesis_step>XML blocks. - Added new adapter coverage, including MolBuilder, and renamed public adapter classes/slugs toward canonical planner names.
- Added stable error codes for adapter, IO, CLI, and workflow boundaries, with ingest failure counts persisted into manifests.
- Added PaRoutes training-set release utilities and hosted dataset loaders.
- Improved release packaging so PyPI releases build from the release tag, support intentional dev releases, and use Hatchling/Hatch VCS for dynamic versions.
Adapter Workflow Split¶
Earlier versions centered the public workflow on ingest, which did two jobs at once:
- standardize raw planner output into canonical
Routeobjects - collect those routes onto benchmark targets and write
routes.json.gz
That shape worked for benchmark runs, but it made RetroCast feel less like a general route-standardization library. In v0.6.0, standardization and benchmark collection are separate library workflows. ingest still exists as the one-command wrapper that runs both.
| Before v0.6.0 | v0.6.0 replacement | Why |
|---|---|---|
adapt_single_route(raw, target, adapter_name) |
adapt_route(raw_route, adapter) |
The one-route API no longer requires target context when the raw route carries its own target. |
adapt_routes(raw, target, adapter_name) |
adapt_provider_output(raw_provider_output, adapter) |
Standardization can now handle one provider output without benchmark target context. |
retrocast ingest as the main way to adapt benchmark predictions |
retrocast adapt then retrocast collect for ad-hoc use |
Exposes standardization and benchmark collection as separate steps. |
retrocast ingest for project-mode benchmark runs |
still retrocast ingest |
Project mode keeps the one-command convenience wrapper. |
Route.rank |
PredictedRoute.rank during provider-output adaptation, list order in scoring inputs |
Keeps canonical Route free of benchmark/list-position metadata while preserving provider rank. |
Provider-output adaptation APIs now return PredictedRoute, an envelope around canonical Route chemistry. It carries provider-level metadata such as rank, score, confidence, and source row provenance. adapt_route(...) remains the single-payload chemistry API and returns Route | None; use adapt_prediction(...) when you explicitly want a one-off prediction envelope.
Scoring artifacts remain benchmark-keyed dict[target_id, list[Route]] so existing evaluation semantics stay stable. Prediction manifest content_hash values are now order-sensitive within each target because route list order is the ranking signal. Re-exported manifests can therefore differ from older manifests even when the route structures are otherwise identical.
Deprecations¶
The v0.6.0 compatibility layer intentionally warns instead of removing the old names immediately. These surfaces are scheduled for removal in v0.9.0:
- legacy adapter slugs such as
aizynth,dms, anddreamretro - legacy adapter class aliases such as
AizynthAdapter,DMSAdapter, andDreamRetroAdapter - target-local adaptation helpers
adapt_single_route(...)andadapt_routes(...)
See the deprecation schedule for the canonical removal plan.
Migration¶
For one raw route-like payload:
from retrocast import adapt_route
from retrocast.adapters import DirectMultiStepAdapter
adapter = DirectMultiStepAdapter()
route = adapt_route(raw_route, adapter)
For one raw prediction payload where you want an envelope:
from retrocast import adapt_prediction
from retrocast.adapters import DirectMultiStepAdapter
adapter = DirectMultiStepAdapter()
prediction = adapt_prediction(raw_route, adapter, rank=1)
For one raw provider output containing one or many routes:
from retrocast import adapt_provider_output
from retrocast.adapters import AiZynthFinderAdapter
adapter = AiZynthFinderAdapter()
predictions = adapt_provider_output(raw_provider_output, adapter)
For raw output already keyed by target ID or target SMILES:
from retrocast import adapt_target_keyed_provider_output, load_benchmark
from retrocast.adapters import AiZynthFinderAdapter
benchmark = load_benchmark("benchmark.json.gz")
adapter = AiZynthFinderAdapter()
predictions = adapt_target_keyed_provider_output(raw_mapping, benchmark, adapter)
To produce benchmark-keyed routes for scoring:
from retrocast import collect_benchmark_predictions
collected = collect_benchmark_predictions(predictions, benchmark)
routes_by_target = collected.routes_by_target
Ad-hoc CLI users can now run the two steps explicitly:
retrocast adapt \
--input raw_predictions.json.gz \
--adapter aizynthfinder \
--input-kind provider-output \
--output route-corpus.jsonl.gz
retrocast collect \
--input route-corpus.jsonl.gz \
--benchmark benchmark.json.gz \
--output routes.json.gz
Project-mode users can keep using retrocast ingest.