{% set method = params.get('method', 'GFN2-xTB') %}
{% set accuracy = params.get('accuracy', 1.0) %}
{% set etemp = params.get('electronic_temperature', 300) %}
{% if node_type == 'xtb_relax' %}
{% set fmax = params.get('fmax', 0.01) %}
{% set max_steps = params.get('max_steps', 500) %}
#!/usr/bin/env python3
"""xTB relaxation generated by CatGo workflow engine."""
from ase.io import read, write
from ase.optimize import BFGS

atoms = read("POSCAR", format="vasp")

# Try tblite first, fallback to xtb-python
method = "{{ method }}"
try:
    from tblite.ase import TBLite
    calc = TBLite(method=method, accuracy={{ accuracy }}, electronic_temperature={{ etemp }})
except ImportError:
    from xtb.ase.calculator import XTB
    calc = XTB(method=method)

atoms.calc = calc
opt = BFGS(atoms, trajectory="opt.traj", logfile="opt.log")
opt.run(fmax={{ fmax }}, steps={{ max_steps }})

write("CONTCAR", atoms, format="vasp")
print(f"Final energy: {atoms.get_potential_energy():.6f} eV")
{% elif node_type == 'xtb_static' %}
#!/usr/bin/env python3
"""xTB single-point calculation generated by CatGo workflow engine."""
from ase.io import read, write

atoms = read("POSCAR", format="vasp")

# Try tblite first, fallback to xtb-python
method = "{{ method }}"
try:
    from tblite.ase import TBLite
    calc = TBLite(method=method, accuracy={{ accuracy }}, electronic_temperature={{ etemp }})
except ImportError:
    from xtb.ase.calculator import XTB
    calc = XTB(method=method)

atoms.calc = calc
energy = atoms.get_potential_energy()
forces = atoms.get_forces()

write("CONTCAR", atoms, format="vasp")
print(f"Final energy: {energy:.6f} eV")
print(f"Max force: {forces.max():.6f} eV/A")
{% else %}
raise RuntimeError("Unknown xTB node type: {{ node_type }}")
{% endif %}
