Spaces:
Running
Running
noahlee1234 commited on
Commit ·
e071228
1
Parent(s): 0f4cba0
feat: store generated code in DB by default and disable GLB storage upload
Browse files- apps/cad-worker/README.md +2 -0
- apps/cad-worker/main.py +10 -1
- apps/gradio-demo/README.md +1 -0
- apps/gradio-demo/app/main.py +17 -1
apps/cad-worker/README.md
CHANGED
|
@@ -37,6 +37,8 @@ OPENROUTER_REFERER=https://huggingface.co/spaces/noahtheboa/naturalcad # option
|
|
| 37 |
OPENROUTER_TITLE=NaturalCAD # optional
|
| 38 |
NATURALCAD_LOG_CODE=false # optional, default false
|
| 39 |
NATURALCAD_INCLUDE_CODE_IN_RESPONSE=false # optional, default false
|
|
|
|
|
|
|
| 40 |
```
|
| 41 |
|
| 42 |
Also required for uploads/logging:
|
|
|
|
| 37 |
OPENROUTER_TITLE=NaturalCAD # optional
|
| 38 |
NATURALCAD_LOG_CODE=false # optional, default false
|
| 39 |
NATURALCAD_INCLUDE_CODE_IN_RESPONSE=false # optional, default false
|
| 40 |
+
NATURALCAD_STORE_CODE=true # optional, default true (stores generated code in DB)
|
| 41 |
+
NATURALCAD_STORE_GLB=false # optional, default false (skip GLB upload to storage)
|
| 42 |
```
|
| 43 |
|
| 44 |
Also required for uploads/logging:
|
apps/cad-worker/main.py
CHANGED
|
@@ -308,12 +308,19 @@ def _log_job_to_supabase(
|
|
| 308 |
"mode": mode,
|
| 309 |
"output_type": output_type,
|
| 310 |
}
|
|
|
|
|
|
|
|
|
|
| 311 |
if error:
|
| 312 |
payload["error_text"] = error
|
| 313 |
|
| 314 |
try:
|
| 315 |
with httpx.Client() as client:
|
| 316 |
resp = client.post(endpoint, json=payload, headers=headers)
|
|
|
|
|
|
|
|
|
|
|
|
|
| 317 |
if resp.status_code >= 400:
|
| 318 |
print(f"DB log failed for job {job_id}: {resp.text}")
|
| 319 |
else:
|
|
@@ -555,6 +562,7 @@ def generate_cad(prompt: str, mode: str = "part", output_type: str = "3d_solid")
|
|
| 555 |
openrouter_model = os.environ.get("OPENROUTER_MODEL", "anthropic/claude-opus-4.7")
|
| 556 |
log_generated_code = os.environ.get("NATURALCAD_LOG_CODE", "false").strip().lower() in {"1", "true", "yes", "on"}
|
| 557 |
include_code_in_response = os.environ.get("NATURALCAD_INCLUDE_CODE_IN_RESPONSE", "false").strip().lower() in {"1", "true", "yes", "on"}
|
|
|
|
| 558 |
|
| 559 |
mode_hint = _MODE_HINTS.get(mode, _MODE_HINTS["part"])
|
| 560 |
output_rule = _OUTPUT_RULES.get(output_type, _OUTPUT_RULES["3d_solid"])
|
|
@@ -751,8 +759,9 @@ def generate_cad(prompt: str, mode: str = "part", output_type: str = "3d_solid")
|
|
| 751 |
file_pairs = [
|
| 752 |
("stl", stl_path, "model/stl"),
|
| 753 |
("step", step_path, "application/octet-stream"),
|
| 754 |
-
("glb", glb_path, "model/gltf-binary"),
|
| 755 |
]
|
|
|
|
|
|
|
| 756 |
for fmt, file_path, content_type in file_pairs:
|
| 757 |
if not file_path or not file_path.exists():
|
| 758 |
continue
|
|
|
|
| 308 |
"mode": mode,
|
| 309 |
"output_type": output_type,
|
| 310 |
}
|
| 311 |
+
store_code = os.environ.get("NATURALCAD_STORE_CODE", "true").strip().lower() in {"1", "true", "yes", "on"}
|
| 312 |
+
if store_code and generated_code:
|
| 313 |
+
payload["generated_code"] = generated_code
|
| 314 |
if error:
|
| 315 |
payload["error_text"] = error
|
| 316 |
|
| 317 |
try:
|
| 318 |
with httpx.Client() as client:
|
| 319 |
resp = client.post(endpoint, json=payload, headers=headers)
|
| 320 |
+
if resp.status_code >= 400 and "generated_code" in payload:
|
| 321 |
+
# Backward-compat fallback for schemas that do not yet have generated_code.
|
| 322 |
+
payload.pop("generated_code", None)
|
| 323 |
+
resp = client.post(endpoint, json=payload, headers=headers)
|
| 324 |
if resp.status_code >= 400:
|
| 325 |
print(f"DB log failed for job {job_id}: {resp.text}")
|
| 326 |
else:
|
|
|
|
| 562 |
openrouter_model = os.environ.get("OPENROUTER_MODEL", "anthropic/claude-opus-4.7")
|
| 563 |
log_generated_code = os.environ.get("NATURALCAD_LOG_CODE", "false").strip().lower() in {"1", "true", "yes", "on"}
|
| 564 |
include_code_in_response = os.environ.get("NATURALCAD_INCLUDE_CODE_IN_RESPONSE", "false").strip().lower() in {"1", "true", "yes", "on"}
|
| 565 |
+
store_glb = os.environ.get("NATURALCAD_STORE_GLB", "false").strip().lower() in {"1", "true", "yes", "on"}
|
| 566 |
|
| 567 |
mode_hint = _MODE_HINTS.get(mode, _MODE_HINTS["part"])
|
| 568 |
output_rule = _OUTPUT_RULES.get(output_type, _OUTPUT_RULES["3d_solid"])
|
|
|
|
| 759 |
file_pairs = [
|
| 760 |
("stl", stl_path, "model/stl"),
|
| 761 |
("step", step_path, "application/octet-stream"),
|
|
|
|
| 762 |
]
|
| 763 |
+
if store_glb:
|
| 764 |
+
file_pairs.append(("glb", glb_path, "model/gltf-binary"))
|
| 765 |
for fmt, file_path, content_type in file_pairs:
|
| 766 |
if not file_path or not file_path.exists():
|
| 767 |
continue
|
apps/gradio-demo/README.md
CHANGED
|
@@ -16,6 +16,7 @@ Gradio prototype for NaturalCAD, a public natural-language CAD modeler built on
|
|
| 16 |
- Run build123d geometry and see a GLB preview in the browser
|
| 17 |
- Download STL and STEP exports
|
| 18 |
- Upload generated STL/STEP artifacts to backend storage when backend is configured
|
|
|
|
| 19 |
- View backend + execution logs
|
| 20 |
- Lightweight run logging for MVP testing data (`artifacts/logs/runs.jsonl`)
|
| 21 |
|
|
|
|
| 16 |
- Run build123d geometry and see a GLB preview in the browser
|
| 17 |
- Download STL and STEP exports
|
| 18 |
- Upload generated STL/STEP artifacts to backend storage when backend is configured
|
| 19 |
+
- If backend omits GLB storage, the UI can generate a local GLB preview from STL for viewing
|
| 20 |
- View backend + execution logs
|
| 21 |
- Lightweight run logging for MVP testing data (`artifacts/logs/runs.jsonl`)
|
| 22 |
|
apps/gradio-demo/app/main.py
CHANGED
|
@@ -552,7 +552,23 @@ def generate_from_prompt(prompt: str, mode: str, output_type: str):
|
|
| 552 |
except Exception as e:
|
| 553 |
print(f"DEBUG: STEP download failed: {e}")
|
| 554 |
step_file = None
|
| 555 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 556 |
if SHOW_GENERATED_CODE:
|
| 557 |
combined_logs = f"Generated build123d code:\n\n{code}\n\n"
|
| 558 |
else:
|
|
|
|
| 552 |
except Exception as e:
|
| 553 |
print(f"DEBUG: STEP download failed: {e}")
|
| 554 |
step_file = None
|
| 555 |
+
|
| 556 |
+
if not glb_file and stl_file:
|
| 557 |
+
try:
|
| 558 |
+
mesh = trimesh.load_mesh(str(stl_file), force="mesh")
|
| 559 |
+
mesh.apply_transform([
|
| 560 |
+
[1, 0, 0, 0],
|
| 561 |
+
[0, 0, 1, 0],
|
| 562 |
+
[0, -1, 0, 0],
|
| 563 |
+
[0, 0, 0, 1],
|
| 564 |
+
], False)
|
| 565 |
+
glb_path = run_dir / f"{run_id}.glb"
|
| 566 |
+
mesh.export(str(glb_path))
|
| 567 |
+
glb_file = str(glb_path)
|
| 568 |
+
print(f"DEBUG: Generated local GLB from STL at {glb_file}")
|
| 569 |
+
except Exception as e:
|
| 570 |
+
print(f"DEBUG: Local GLB generation failed: {e}")
|
| 571 |
+
|
| 572 |
if SHOW_GENERATED_CODE:
|
| 573 |
combined_logs = f"Generated build123d code:\n\n{code}\n\n"
|
| 574 |
else:
|