CAD_AI turns natural-language prompts ("create a wheel with 6 spokes") into Onshape FeatureScript that compiles and produces editable parametric geometry. It uses Groq-hosted models with retrieval grounding, a generate → test → fix loop, and deterministic fallbacks so a request always returns usable FeatureScript.
- Install dependencies:
npm install
- Create
.envwith at least one Groq API key (GROQ_API_KEY, optionallyGROQ_API_KEY2..9for rotation). Supabase keys are optional — without them the app runs on local knowledge files only. - Start the server:
npm start
- Or test generation directly from the command line (no server needed):
npm run test:e2e -- "Create a coffee mug with a handle"
- Dimension extraction — a fast model parses the prompt into shape +
dimensions (
extractDimsin ai.js). - Retrieval — the prompt is matched against local knowledge rows, Omni-CAD caption summaries (data/cadDatasetSummaries.json, data/captionGeometryPairs.json), indexed FeatureScript docs (docs/fs_reference/), and one compile-verified code example from data/fs_examples/.
- Generate → Test → Fix loop — up to 3 candidates; each is sanitized and
validated locally, and any blocking errors are fed back into the next
attempt (
runGenerateTestFixLoop). Truncated responses are auto-closed and recovered instead of discarded. - Repair / recovery / fallback — failing candidates go through an AI
repair pass; if everything fails,
buildGuaranteedFeatureScriptreturns a deterministic parametric part so the user never gets nothing.
| Path | Purpose |
|---|---|
| ai.js | Core pipeline: prompts, generation loop, sanitizer, validator, fallbacks |
| server.js | Express API entry point (npm start) |
| learning.js | Retrieval, FS-doc indexing, Supabase memory, adaptive reranker |
| adaptiveNetwork.js | Small neural reranker used by learning.js |
| Auth.js | Auth middleware + Supabase auth routes |
| data/fs_examples/ | Compile-verified FeatureScript examples injected into prompts; manifest.json maps keywords → example |
| data/ | Knowledge rows, dataset summaries, caption pairs, failure corpus |
| docs/fs_reference/ | FeatureScript documentation indexed at server start |
| docs/research_summaries/ | Research-note context loaded into prompts |
| scripts/ | Test, import, and extraction utilities |
| public/ | Web UI served by the Express server |
| supabase/ | Database migrations |
| Command | What it does |
|---|---|
npm run test:validator |
Offline regression: templates/examples must validate clean; known-bad code must be flagged. Run after touching the sanitizer, validator, or examples. |
npm run test:e2e -- "prompt" |
Full pipeline against real Groq keys; prints generation mode, validation status, and the code |
npm run test:guaranteed |
Checks the deterministic fallback produces valid FeatureScript |
- Write a new example in
data/fs_examples/<name>.fs— complete FeatureScript 2931 file, one exporteddefineFeature, editablepreconditionparameters. - Add an entry to
data/fs_examples/manifest.jsonwith the keywords a user prompt would contain. - Run
npm run test:validator— the example must validate clean with zero sanitizer changes before it ships.
Good sources for new examples: your own generations that compiled correctly in Onshape, and the official FeatureScript library reference.
- Patterns use
opPattern+rotationAround/transformarrays —opPatternCircular/opPatternLineardo not exist. - String concatenation is
~, not+. Arrays grow withappend(), have no.length. isLengthparameters already carry units — never multiply by* inchin the body.- Holes = same-sketch inner circles (
qSketchRegion(id, true)) or extrude +opBooleanSUBTRACTION. - Named everyday objects must be decomposed into components (pen = barrel + tip + clip), never one stretched primitive.
GROQ_GENERATION_MODEL/GROQ_MODEL/GROQ_FALLBACK_MODEL— model routing; free-tier TPM limits are handled by automatic completion-budget shrinking and key rotation inchat().USE_VALIDATED_TEMPLATES=true— keep enabled; injects the validated structural template directive.CAD_CANDIDATE_COUNT,CAD_REPAIR_ATTEMPTS— loop sizing.