|
| 1 | +# CLAUDE.md |
| 2 | + |
| 3 | +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. |
| 4 | + |
| 5 | +## Project Overview |
| 6 | + |
| 7 | +This is a **libEnsemble Script Creator** — a system for generating, running, and iteratively fixing [libEnsemble](https://libensemble.readthedocs.io/) scripts (used for parallel optimization at HPC centers). It has three deployment modes: |
| 8 | + |
| 9 | +1. **MCP Server** (`mcp_server.mjs`) — Node.js server exposing script generation as an MCP tool (used from Cursor IDE or AI agents) |
| 10 | +2. **Agentic Python scripts** (`agentic/`) — LangChain agents that generate scripts via MCP, run them, and auto-fix errors |
| 11 | +3. **Web UI** (`web/`) — Flask backend + HTML/JS frontend for interactive script refinement |
| 12 | + |
| 13 | +## Key Commands |
| 14 | + |
| 15 | +### MCP Server (Node.js) |
| 16 | +```bash |
| 17 | +npm install # Install dependencies |
| 18 | +node mcp_server.mjs # Run MCP server |
| 19 | +``` |
| 20 | + |
| 21 | +### Agentic Agents (Python) |
| 22 | + |
| 23 | +Install dependencies: |
| 24 | +```bash |
| 25 | +pip install langchain langchain-openai mcp openai libensemble scipy mpmath |
| 26 | +``` |
| 27 | + |
| 28 | +Run the primary agent (generate → run → fix): |
| 29 | +```bash |
| 30 | +cd agentic/ |
| 31 | +python libe_agent_with_script_generator.py # Uses DEFAULT_PROMPT |
| 32 | +python libe_agent_with_script_generator.py "Create APOSMM scripts..." |
| 33 | +python libe_agent_with_script_generator.py --prompt-file my_prompt.txt |
| 34 | +python libe_agent_with_script_generator.py --scripts example_scripts/ # Skip generation |
| 35 | +python libe_agent_with_script_generator.py --show-prompts # Debug prompts |
| 36 | +``` |
| 37 | + |
| 38 | +Run the interactive agent (with user chat loop + RAG doc lookup): |
| 39 | +```bash |
| 40 | +# Extra deps for RAG: |
| 41 | +pip install llama-index llama-index-embeddings-huggingface sentence-transformers |
| 42 | + |
| 43 | +export GENERATOR_MCP_SERVER=/path/to/mcp_server.mjs |
| 44 | +export RAG_MCP_SERVER=/path/to/rag/mcp_server.py |
| 45 | +export OPENAI_API_KEY=your_key |
| 46 | + |
| 47 | +python libe_agent_interactive_with_rag.py --interactive |
| 48 | +python libe_agent_interactive_with_rag.py --generate-only # No execution |
| 49 | +python libe_agent_interactive_with_rag.py --scripts dir/ # Review existing |
| 50 | +``` |
| 51 | + |
| 52 | +### Web Interface |
| 53 | +```bash |
| 54 | +cd web/ |
| 55 | +pip install -r requirements.txt |
| 56 | +export OPENAI_API_KEY=your_key |
| 57 | +python server.py # Serves on http://localhost:5000 |
| 58 | +``` |
| 59 | + |
| 60 | +### RAG System |
| 61 | +```bash |
| 62 | +cd rag/ |
| 63 | +pip install llama-index llama-index-embeddings-huggingface sentence-transformers mcp |
| 64 | +python build_index.py # Build vector index from libEnsemble docs (run once) |
| 65 | +python rag_query.py "What generators are available?" |
| 66 | +python test_mcp_server.py # Test the RAG MCP server |
| 67 | +``` |
| 68 | + |
| 69 | +## Architecture |
| 70 | + |
| 71 | +### Script Generation Pipeline |
| 72 | +The MCP server (`mcp_server.mjs`) uses **Mustache templates** (`templates/*.j2` — despite the `.j2` extension, rendered by Mustache in Node.js) and `processTemplateData.js` (shared browser/Node logic) to produce: |
| 73 | +- `run_libe.py` — main libEnsemble runner |
| 74 | +- `simf.py` — simulation function |
| 75 | +- `submit_slurm.sh` / `submit_pbs.sh` — HPC job scripts |
| 76 | + |
| 77 | +Generator configurations are data-driven via `data/generators.json` and `data/generator_specs.json`. |
| 78 | + |
| 79 | +### Agent Workflow |
| 80 | +``` |
| 81 | +User prompt |
| 82 | + → LangChain agent calls MCP tool CreateLibEnsembleScripts |
| 83 | + → Agent refines scripts (second LLM pass) |
| 84 | + → Agent runs scripts via subprocess |
| 85 | + → On failure: optionally queries RAG for doc context, then fixes and reruns |
| 86 | + → All versions saved to generated_scripts/versions/ |
| 87 | +``` |
| 88 | + |
| 89 | +Key constants in agents: |
| 90 | +- `MAX_RETRIES = 2` — retry attempts on script failure |
| 91 | +- `LLM_MODEL` env var (default: `gpt-4o-mini`) — overrides model for all agents |
| 92 | + |
| 93 | +### MCP Protocol Usage |
| 94 | +Agents connect to MCP servers via `stdio_client` (the MCP Python SDK). There are two MCP servers: |
| 95 | +1. `mcp_server.mjs` — exposes `CreateLibEnsembleScripts` tool |
| 96 | +2. `rag/mcp_server.py` — exposes `query_libe_docs`, `query_generator_docs`, etc. |
| 97 | + |
| 98 | +### Environment Variables |
| 99 | +``` |
| 100 | +OPENAI_API_KEY # Required for agents |
| 101 | +OPENAI_BASE_URL # Optional: alternative LLM endpoint (e.g., ALCF inference) |
| 102 | +LLM_MODEL # Optional: model name (default: gpt-4o-mini) |
| 103 | +MCP_SERVER # Path to mcp_server.mjs (used by agents) |
| 104 | +GENERATOR_MCP_SERVER # Path to generator MCP server |
| 105 | +RAG_MCP_SERVER # Path to rag/mcp_server.py |
| 106 | +``` |
| 107 | + |
| 108 | +### Testing |
| 109 | +No automated test suite. Manual testing uses: |
| 110 | +- `agentic/tests/` — test scripts with intentional errors (filename errors, wrong paths, missing try/except, etc.) |
| 111 | +- The six_hump_camel benchmark problem in `six_hump_camel/` as a reference optimization case |
| 112 | + |
| 113 | +To test an agent against a known-error script: |
| 114 | +```bash |
| 115 | +python libe_agent_with_script_generator.py --scripts agentic/tests/scripts_with_errors/ |
| 116 | +``` |
0 commit comments