From 77f6190f0851a68ecb5581ec150ce6416d1e88ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20M=C3=BCller?= Date: Mon, 27 Apr 2026 21:43:23 +0200 Subject: [PATCH 1/2] Update SKILL.md with additional chemistry functions - QED and SAScore - InChI key - Maximum common substructure --- .claude/skills/chemistry-rdkit/SKILL.md | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/.claude/skills/chemistry-rdkit/SKILL.md b/.claude/skills/chemistry-rdkit/SKILL.md index b5f9cd9e..51afc608 100644 --- a/.claude/skills/chemistry-rdkit/SKILL.md +++ b/.claude/skills/chemistry-rdkit/SKILL.md @@ -36,20 +36,24 @@ metadata: 4. Tanimoto similarity: `DataStructs.TanimotoSimilarity(fp1, fp2)` 5. Use radius=2 (ECFP4 equivalent) as default for most applications 6. For virtual screening, Tanimoto > 0.7 suggests structural similarity +7. To filter for unique structures, use `Chem.MolToInchiKey` ### Substructure Search 1. SMARTS patterns: `pattern = Chem.MolFromSmarts('[OH]')` 2. Check match: `mol.HasSubstructMatch(pattern)` 3. Get all matches: `mol.GetSubstructMatches(pattern)` -4. Common SMARTS: `[#6](=O)[OH]` (carboxylic acid), `[NH2]` (primary amine) -5. Filter compound libraries by functional group presence +5. Common SMARTS: `[#6](=O)[OH]` (carboxylic acid), `[NH2]` (primary amine) +6. Find maximum common substructure with `mcs = rdFMCS.FindMCS(mols)` +7. Filter compound libraries by functional group presence ### Property Calculation Patterns 1. Batch processing: iterate over SDMolSupplier, skip None entries 2. Use `Chem.Descriptors.descList` for all available descriptors 3. For ADMET filtering, calculate Lipinski, Veber, and PAINS filters -4. Generate 3D coordinates: `AllChem.EmbedMolecule(mol, AllChem.ETKDG())` -5. Minimize energy: `AllChem.MMFFOptimizeMolecule(mol)` +4. For general druglikeness, use `Descriptors.qed`, for synthesizability `from SA_Score import sascorer` +5. For `sascorer`, append the contrib path first: `sys.path.append(os.path.join(os.environ['CONDA_PREFIX'],'share','RDKit','Contrib'))` +6. Generate 3D coordinates: `AllChem.EmbedMolecule(mol, AllChem.ETKDG())` +7. Minimize energy: `AllChem.MMFFOptimizeMolecule(mol)` ### Common Pitfalls 1. Always sanitize molecules (default behavior) — disable only when needed From 02c8fe910e4f157436e46df72f139361c8a8d10b Mon Sep 17 00:00:00 2001 From: mrs-researcher Date: Mon, 27 Apr 2026 23:00:42 +0200 Subject: [PATCH 2/2] fix: MiniMax base URL and graceful S2 429 fallback - Fix MiniMax provider: use https://api.minimax.io/anthropic (was api.minimaxi.com/v1 which doesn't support Anthropic Messages endpoint) - Add wire_api=anthropic to minimax preset for correct endpoint routing - S2 (Semantic Scholar): on first 429, skip S2 immediately for that query instead of retrying with backoff. arXiv/OpenAlex can run while S2 cools down, rather than blocking all backends behind S2 retries. --- researchclaw/literature/semantic_scholar.py | 8 ++++++++ researchclaw/llm/__init__.py | 3 ++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/researchclaw/literature/semantic_scholar.py b/researchclaw/literature/semantic_scholar.py index e79e4c7f..5c58ae33 100644 --- a/researchclaw/literature/semantic_scholar.py +++ b/researchclaw/literature/semantic_scholar.py @@ -236,6 +236,14 @@ def _request_with_retry( if exc.code == 429: if _cb_on_429(): return None # breaker tripped + # On first 429, don't retry S2 — fall through to next backend + # immediately so arXiv/OpenAlex can run without waiting. + if attempt == 0: + logger.warning( + "S2 rate-limited (429) on first attempt — " + "skipping S2 for this query, trying next backend" + ) + return None delay = min(2 ** (attempt + 1), _MAX_WAIT_SEC) jitter = random.uniform(0, delay * 0.3) wait = delay + jitter diff --git a/researchclaw/llm/__init__.py b/researchclaw/llm/__init__.py index f51b678d..f0fdba92 100644 --- a/researchclaw/llm/__init__.py +++ b/researchclaw/llm/__init__.py @@ -30,7 +30,8 @@ "base_url": "https://api.novita.ai/openai", }, "minimax": { - "base_url": "https://api.minimaxi.com/v1", + "base_url": "https://api.minimax.io/anthropic", + "wire_api": "anthropic", }, "volcengine": { "base_url": "https://ark.cn-beijing.volces.com/api/v3",