feat: add support for (multi) reaction naming#1
Conversation
Reviewer's GuideIntroduce a new template-grounded reaction-name classification subsystem (ReactionClassifier) with explicit match policies and provenance, add reaction SMILES parsing utilities, and extend enumeration outputs and public types to carry template IDs and richer classification metadata, all backed by comprehensive tests and documentation updates. Sequence diagram for ReactionClassifier.classify workflowsequenceDiagram
participant RC as ReactionClassifier
participant PR as parse_reaction_smiles
participant KG as KeyGenerator
participant AT as apply_templates_to_pair
participant PM as ProductMatcher
participant CR as ClassificationResult
RC->>PR: parse_reaction_smiles(reaction_smiles)
PR-->>RC: ParsedReaction or ReactionParseError
alt invalid_reaction_smiles
RC-->>RC: create ClassificationResult(status=invalid_input)
else valid_parsed
RC->>RC: build candidate_smiles (reactants [+ agents])
RC->>RC: Chem.MolFromSmiles for components
RC->>KG: classify_many(unique_components)
KG-->>RC: KeysResult list
RC->>RC: extract_key_strings for each component
RC->>PM: ProductMatcher(match_policies) [select]
RC->>PM: observed_by_policy(parsed.products)
PM-->>RC: observed_by_policy map
loop for each reactant pair
RC->>AT: apply_templates_to_pair(templates, s1, s2, m1, m2, keys1, keys2, idx1, idx2)
AT-->>RC: TemplateApplication list, diagnostics
RC->>PM: strongest_match(outcome.products, observed_by_policy)
PM-->>RC: MatchType or None
RC-->>RC: build TemplateMatch list
end
RC-->>RC: _dedupe_matches(matches)
RC-->>RC: _aggregate_candidates(matches)
RC-->>RC: _dedupe_diagnostics(diagnostics)
RC-->>RC: _status(candidates, diagnostics)
RC-->>CR: ClassificationResult(status, candidates, diagnostics)
end
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
📝 WalkthroughWalkthroughChangesReaction classification
Estimated code review effort: 4 (Complex) | ~60 minutes Sequence Diagram(s)sequenceDiagram
participant Caller
participant ReactionClassifier
participant ProductMatcher
participant TemplateEngine
Caller->>ReactionClassifier: classify reaction SMILES
ReactionClassifier->>ProductMatcher: normalize observed products
ReactionClassifier->>TemplateEngine: apply compatible templates
TemplateEngine-->>ReactionClassifier: outcomes and diagnostics
ReactionClassifier->>ProductMatcher: select strongest policy match
ReactionClassifier-->>Caller: ClassificationResult
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Hey - I've left some high level feedback:
- The global
RDLogger.DisableLog("rdApp.*")inclassifier.pysilences all RDKit logging for the entire process; consider scoping this (or making it caller‑configurable) so library users can still opt into RDKit diagnostics when needed. - In
ProductMatcher.normalize_seteach call reparses and normalizes all product SMILES; if classification is run at scale, consider caching per-(smiles, policy) normalization results to avoid repeated RDKit work and improve performance.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- The global `RDLogger.DisableLog("rdApp.*")` in `classifier.py` silences all RDKit logging for the entire process; consider scoping this (or making it caller‑configurable) so library users can still opt into RDKit diagnostics when needed.
- In `ProductMatcher.normalize_set` each call reparses and normalizes all product SMILES; if classification is run at scale, consider caching per-(smiles, policy) normalization results to avoid repeated RDKit work and improve performance.Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@CHANGELOG.md`:
- Around line 15-17: Update the changelog entry’s classification type
description to call ReactionOutcome and TemplateApplication public types,
matching their re-exported status in smartreact.__init__ and __all__; remove the
misleading “internal” wording while preserving the rest of the list.
In `@src/smartreact/matching.py`:
- Line 187: Reorder the entries in the module-level __all__ declaration
alphabetically to satisfy Ruff RUF022, preserving the same exported symbols:
DEFAULT_POLICIES, POLICY_ORDER, and ProductMatcher.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: b296ed8f-31d3-4a25-bfde-00959831883c
📒 Files selected for processing (15)
CHANGELOG.mdREADME.mdsrc/smartreact/__init__.pysrc/smartreact/classifier.pysrc/smartreact/engine.pysrc/smartreact/enumerator.pysrc/smartreact/matching.pysrc/smartreact/reaction_smiles.pysrc/smartreact/types.pytests/conftest.pytests/test_classifier.pytests/test_engine.pytests/test_enumerator.pytests/test_matching.pytests/test_reaction_smiles.py
| - Public classification types: `ClassificationResult`, `ReactionCandidate`, | ||
| `TemplateMatch`, `ClassificationDiagnostic`, plus outcome-preserving internal | ||
| types `ReactionOutcome` and `TemplateApplication`. |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Use “public” rather than “internal” for re-exported types.
Lines [15]-[17] describe ReactionOutcome and TemplateApplication as internal, but src/smartreact/__init__.py imports both and lists them in __all__. Update the changelog wording so users are not misled about their supported import surface.
Proposed wording
- plus outcome-preserving internal
+ plus outcome-preserving public📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| - Public classification types: `ClassificationResult`, `ReactionCandidate`, | |
| `TemplateMatch`, `ClassificationDiagnostic`, plus outcome-preserving internal | |
| types `ReactionOutcome` and `TemplateApplication`. | |
| - Public classification types: `ClassificationResult`, `ReactionCandidate`, | |
| `TemplateMatch`, `ClassificationDiagnostic`, plus outcome-preserving public | |
| types `ReactionOutcome` and `TemplateApplication`. |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@CHANGELOG.md` around lines 15 - 17, Update the changelog entry’s
classification type description to call ReactionOutcome and TemplateApplication
public types, matching their re-exported status in smartreact.__init__ and
__all__; remove the misleading “internal” wording while preserving the rest of
the list.
| return None | ||
|
|
||
|
|
||
| __all__ = ["ProductMatcher", "POLICY_ORDER", "DEFAULT_POLICIES"] |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
__all__ is not sorted (RUF022). Ruff flags this and it is autofixable; reorder to avoid a lint failure.
🧹 Proposed fix
-__all__ = ["ProductMatcher", "POLICY_ORDER", "DEFAULT_POLICIES"]
+__all__ = ["DEFAULT_POLICIES", "POLICY_ORDER", "ProductMatcher"]📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| __all__ = ["ProductMatcher", "POLICY_ORDER", "DEFAULT_POLICIES"] | |
| __all__ = ["DEFAULT_POLICIES", "POLICY_ORDER", "ProductMatcher"] |
🧰 Tools
🪛 Ruff (0.15.21)
[warning] 187-187: __all__ is not sorted
Apply an isort-style sorting to __all__
(RUF022)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/smartreact/matching.py` at line 187, Reorder the entries in the
module-level __all__ declaration alphabetically to satisfy Ruff RUF022,
preserving the same exported symbols: DEFAULT_POLICIES, POLICY_ORDER, and
ProductMatcher.
Source: Linters/SAST tools
Summary by Sourcery
Introduce template-grounded reaction-name classification and template provenance support across the library.
New Features:
Enhancements:
Documentation:
Tests:
Summary by CodeRabbit
template_idand reactant index evidence.