chemgraph-loop / README.md
rockyaaos's picture
README: full dev/ops doc
ae98bf4 verified
|
Raw
History Blame Contribute Delete
5.22 kB
metadata
title: ChemGraph Loop
emoji: πŸ§ͺ
colorFrom: green
colorTo: yellow
sdk: docker
app_port: 7860
pinned: false
license: apache-2.0
short_description: Real agentic chemistry workflow β€” resolve, simulate, verify

ChemGraph Loop

A guarded, natural-language API around the real ChemGraph agent β€” Argonne Leadership Computing Facility's agentic computational-chemistry framework (LangGraph + ASE), running the workflow-correctness hardening by Lu Zhang.

Backs the live demo at sciencesloop.com/agent (frontend = lu-zhang-site/src/components/ChemGraphDemo.astro).

  • GitHub (source): github.com/rockyzl/chemgraph-loop (private)
  • Deploy target: HF Space rockyaaos/chemgraph-loop (Docker, free CPU-basic)
  • Upstream ChemGraph: https://github.com/argonne-lcf/ChemGraph (Apache-2.0)

How it works (request lifecycle)

  1. LLM intent router (llm_parse_query, PRIMARY) β€” one gpt-4o-mini JSON call reads the plain-language question and returns {molecule, task, calculator}, resolving the molecule by ANY name/synonym/formula ("dihydrogen monoxide"/"H2O"/"NH3"/"CO2"/"EtOH"/"benzol" β†’ canonical). It refuses to match derivatives to a parent (dimethoxybenzene β‰  benzene) and emits nearest/note for out-of-scope molecules. keyword_fallback (token match, no regex) runs ONLY if the model call fails. This is intentionally agentic, not a rule engine.
  2. Route by physics cost:
    • energy / dipole = single-point (~12–25 s) β†’ run the real ChemGraph agent LIVE on a canonical, guard-matched query built from the intent.
    • ir / thermo = finite-difference Hessian (too slow for free CPU) β†’ served from precomputed real agent runs in precomputed/ (cached:true, shown as "precomputed real run").
  3. Extract (cg_extract.extract) β†’ unified rich payload: molecule/formula/ smiles, structure.atoms (parsed from molecule.xyz, drives the 3D viewer), steps[] (tool calls + folded detail), task-specific result (energy / dipole vector+magnitude / ir.modes / thermo H,S,G), verified.
  4. Clarification node β€” out-of-scope molecule or an unavailable heavy task returns {clarify:true, message, suggestions:[{label,query}]} (HTTP 200), NOT an error. The frontend renders it as a conversational bubble + chips.

Endpoints

GET  /            β†’ health: molecules, tasks, live_tasks, ir_molecules, thermo_molecules
POST /run  { "query": "IR spectrum of water" }          # natural-language (primary)
POST /run  { "molecule": "water", "calculator": "emt" }  # legacy, energy only

/run returns one of: a rich result payload Β· a clarify payload Β· an error (429 rate limit Β· 504 timeout Β· 500 agent error).

Coverage & reliability (IMPORTANT)

  • energy / dipole: LIVE for all 10 allow-listed molecules (water, methane, ammonia, methanol, ethanol, carbon dioxide, benzene, acetic acid, formaldehyde, hydrogen peroxide).
  • thermochemistry: precomputed for all 10 (thermo uses plain Vibrations; works for large molecules).
  • IR / vibrations: precomputed for ≀4-atom molecules only β€” water, ammonia, carbon dioxide, formaldehyde, hydrogen peroxide. The ASE Infrared intensity step returns empty modes for β‰₯5-atom molecules (methane, methanol, ethanol, acetic acid, benzene all fail β€” confirmed). Do NOT add β‰₯5-atom IR; the clarification node covers them.
  • Guard-matched queries only (single-point / dipole / ir / thermo). "geometry optimization" phrasing makes the agent loop β€” never expose it.
  • Display-layer IR filter: keep modes with cm1 β‰₯ 100 & intensity > 1e-3 (drops spurious near-zero / translation-rotation modes).

Files

File Role
app.py FastAPI: intent router, routing, clarification node, guards (CORS, rate limit, timeout)
cg_extract.py shared payload extractor (structure/steps/results) β€” used by app + precompute
precompute.py offline heavy-task generator: python precompute.py <molecule...>
precomputed/<slug>__<task>.json bundled real agent runs for ir/thermo
Dockerfile CPU torch β†’ pip install .[calculators] β†’ copies wrappers LAST (fast layer-cached rebuilds)
src/ vendored copy of Lu's hardened ChemGraph fork

Deploy / operate

The HF Space builds from its own git; push files with huggingface_hub (~/.local env at /tmp/hfenv/bin/python on Lu's box) β€” upload_file / upload_folder / delete_file each trigger a rebuild (~2–4 min, layer-cached since wrappers copy late). OPENAI_API_KEY is a Space secret.

from huggingface_hub import HfApi
HfApi().upload_file(path_or_fileobj="app.py", path_in_repo="app.py",
                    repo_id="rockyaaos/chemgraph-loop", repo_type="space",
                    commit_message="...")

Add a spectrum/thermo molecule: run precompute.py <name>, validate the IR modes are non-empty & physical (cm1β‰₯100), upload_file the JSON, let the Space rebuild (its _avail(task) picks it up automatically). Only ≀4-atom molecules get valid IR.

CORS allows sciencesloop.com, *.vercel.app, and localhost:4321.